leftovers 0.7.0 → 0.8.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 (88) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +13 -0
  3. data/README.md +1 -0
  4. data/docs/Configuration.md +20 -57
  5. data/docs/Custom-Precompilers.md +38 -0
  6. data/lib/config/actionpack.yml +5 -3
  7. data/lib/config/haml.yml +4 -2
  8. data/lib/config/ruby.yml +4 -15
  9. data/lib/config/slim.yml +4 -2
  10. data/lib/leftovers/cli.rb +5 -0
  11. data/lib/leftovers/collector.rb +2 -1
  12. data/lib/leftovers/config.rb +2 -18
  13. data/lib/leftovers/config_loader/argument_position_schema.rb +2 -2
  14. data/lib/leftovers/config_loader/attribute.rb +36 -10
  15. data/lib/leftovers/config_loader/built_in_precompiler_schema.rb +13 -0
  16. data/lib/leftovers/config_loader/document_schema.rb +32 -5
  17. data/lib/leftovers/config_loader/has_argument_schema.rb +2 -2
  18. data/lib/leftovers/config_loader/has_value_schema.rb +2 -2
  19. data/lib/leftovers/config_loader/inherit_schema_attributes.rb +22 -0
  20. data/lib/leftovers/config_loader/keep_test_only_schema.rb +2 -2
  21. data/lib/leftovers/config_loader/object_schema.rb +33 -105
  22. data/lib/leftovers/config_loader/precompile_schema.rb +12 -0
  23. data/lib/leftovers/config_loader/precompiler_schema.rb +11 -0
  24. data/lib/leftovers/config_loader/privacy_processor_schema.rb +0 -2
  25. data/lib/leftovers/config_loader/require_schema.rb +3 -3
  26. data/lib/leftovers/config_loader/schema.rb +2 -0
  27. data/lib/leftovers/config_loader/string_pattern_schema.rb +2 -2
  28. data/lib/leftovers/config_loader/string_value_processor_schema.rb +2 -2
  29. data/lib/leftovers/config_loader/transform_schema.rb +4 -6
  30. data/lib/leftovers/config_loader/value_matcher_schema.rb +2 -2
  31. data/lib/leftovers/config_loader/value_or_array_schema.rb +5 -3
  32. data/lib/leftovers/config_loader/value_or_object_schema.rb +40 -0
  33. data/lib/leftovers/config_loader/value_processor_schema.rb +2 -2
  34. data/lib/leftovers/config_loader.rb +5 -1
  35. data/lib/leftovers/file.rb +7 -53
  36. data/lib/leftovers/file_collector/comments_processor.rb +57 -0
  37. data/lib/leftovers/file_collector/node_processor.rb +131 -0
  38. data/lib/leftovers/file_collector.rb +42 -203
  39. data/lib/leftovers/matcher_builders/and_not.rb +7 -5
  40. data/lib/leftovers/matcher_builders/name.rb +18 -17
  41. data/lib/leftovers/matcher_builders/node.rb +48 -34
  42. data/lib/leftovers/matcher_builders/node_has_argument.rb +48 -52
  43. data/lib/leftovers/matcher_builders/node_has_keyword_argument.rb +13 -10
  44. data/lib/leftovers/matcher_builders/node_has_positional_argument.rb +29 -15
  45. data/lib/leftovers/matcher_builders/node_type.rb +1 -1
  46. data/lib/leftovers/matcher_builders/node_value.rb +27 -22
  47. data/lib/leftovers/matcher_builders/or.rb +50 -50
  48. data/lib/leftovers/matcher_builders/string_pattern.rb +1 -1
  49. data/lib/leftovers/merged_config.rb +3 -23
  50. data/lib/leftovers/precompilers/erb.rb +22 -0
  51. data/lib/leftovers/precompilers/haml.rb +15 -0
  52. data/lib/leftovers/precompilers/json.rb +27 -0
  53. data/lib/leftovers/precompilers/precompiler.rb +28 -0
  54. data/lib/leftovers/precompilers/slim.rb +15 -0
  55. data/lib/leftovers/precompilers/yaml.rb +75 -0
  56. data/lib/leftovers/precompilers.rb +50 -0
  57. data/lib/leftovers/processor_builders/action.rb +48 -39
  58. data/lib/leftovers/processor_builders/add_prefix.rb +1 -1
  59. data/lib/leftovers/processor_builders/add_suffix.rb +1 -1
  60. data/lib/leftovers/processor_builders/argument.rb +8 -11
  61. data/lib/leftovers/processor_builders/dynamic.rb +5 -5
  62. data/lib/leftovers/processor_builders/each.rb +2 -2
  63. data/lib/leftovers/processor_builders/each_action.rb +33 -33
  64. data/lib/leftovers/processor_builders/each_dynamic.rb +4 -8
  65. data/lib/leftovers/processor_builders/each_for_definition_set.rb +25 -21
  66. data/lib/leftovers/processor_builders/keyword.rb +3 -4
  67. data/lib/leftovers/processor_builders/transform.rb +2 -2
  68. data/lib/leftovers/processor_builders/transform_chain.rb +16 -8
  69. data/lib/leftovers/processor_builders/transform_set.rb +32 -28
  70. data/lib/leftovers/rake_task.rb +1 -1
  71. data/lib/leftovers/value_processors/add_dynamic_prefix.rb +3 -10
  72. data/lib/leftovers/value_processors/add_dynamic_suffix.rb +3 -10
  73. data/lib/leftovers/value_processors/each.rb +1 -1
  74. data/lib/leftovers/value_processors/each_for_definition_set.rb +2 -5
  75. data/lib/leftovers/value_processors/each_keyword.rb +1 -1
  76. data/lib/leftovers/value_processors/each_keyword_argument.rb +1 -1
  77. data/lib/leftovers/value_processors/each_positional_argument.rb +2 -1
  78. data/lib/leftovers/value_processors/keyword.rb +3 -7
  79. data/lib/leftovers/value_processors/keyword_argument.rb +2 -6
  80. data/lib/leftovers/value_processors/split.rb +2 -2
  81. data/lib/leftovers/version.rb +1 -1
  82. data/lib/leftovers.rb +41 -6
  83. metadata +17 -7
  84. data/lib/leftovers/erb.rb +0 -20
  85. data/lib/leftovers/haml.rb +0 -21
  86. data/lib/leftovers/json.rb +0 -28
  87. data/lib/leftovers/slim.rb +0 -21
  88. data/lib/leftovers/yaml.rb +0 -73
@@ -10,14 +10,11 @@ module Leftovers
10
10
  end
11
11
 
12
12
  def process(str, node, method_node)
13
- definitions = @then_processors.map do |then_processor|
13
+ definitions = Leftovers.map_or_self(@then_processors) do |then_processor|
14
14
  then_processor.process(str, node, method_node)
15
15
  end
16
16
 
17
- definitions.flatten!
18
- definitions.compact!
19
-
20
- return definitions.first if definitions.length <= 1
17
+ return definitions unless definitions.is_a?(Array)
21
18
 
22
19
  ::Leftovers::DefinitionNodeSet.new(definitions)
23
20
  end
@@ -13,7 +13,7 @@ module Leftovers
13
13
  kwargs = node.kwargs
14
14
  return unless kwargs
15
15
 
16
- kwargs.children.map do |pair|
16
+ Leftovers.map_or_self(kwargs.children) do |pair|
17
17
  next unless pair.type == :pair
18
18
 
19
19
  argument_node = pair.first
@@ -13,7 +13,7 @@ module Leftovers
13
13
  kwargs = node.kwargs
14
14
  return unless kwargs
15
15
 
16
- kwargs.children.map do |pair|
16
+ Leftovers.map_or_self(kwargs.children) do |pair|
17
17
  next unless pair.type == :pair
18
18
 
19
19
  argument_node = pair.second
@@ -11,9 +11,10 @@ module Leftovers
11
11
 
12
12
  def process(_str, node, method_node)
13
13
  positional_arguments = node.positional_arguments
14
+
14
15
  return unless positional_arguments
15
16
 
16
- positional_arguments.map do |argument_node|
17
+ Leftovers.map_or_self(positional_arguments) do |argument_node|
17
18
  str = argument_node.to_s if argument_node.string_or_symbol_or_def?
18
19
 
19
20
  @then_processor.process(str, argument_node, method_node)
@@ -14,18 +14,14 @@ module Leftovers
14
14
  kwargs = node.kwargs
15
15
  return unless kwargs
16
16
 
17
- result = []
18
-
19
- kwargs.children.each do |pair|
17
+ Leftovers.map_or_self(kwargs.children) do |pair|
20
18
  next unless @matcher === pair
21
19
 
22
20
  argument_node = pair.first
23
- str = argument_node.to_s
21
+ str = argument_node.to_s if argument_node.string_or_symbol?
24
22
 
25
- result << @then_processor.process(str, argument_node, method_node)
23
+ @then_processor.process(str, argument_node, method_node)
26
24
  end
27
-
28
- result
29
25
  end
30
26
  end
31
27
  end
@@ -14,18 +14,14 @@ module Leftovers
14
14
  kwargs = node.kwargs
15
15
  return unless kwargs
16
16
 
17
- result = []
18
-
19
- kwargs.children.each do |pair|
17
+ Leftovers.map_or_self(kwargs.children) do |pair|
20
18
  next unless @matcher === pair
21
19
 
22
20
  argument_node = pair.second
23
21
  str = argument_node.to_s if argument_node.string_or_symbol?
24
22
 
25
- result << @then_processor.process(str, argument_node, method_node)
23
+ @then_processor.process(str, argument_node, method_node)
26
24
  end
27
-
28
- result
29
25
  end
30
26
  end
31
27
  end
@@ -13,8 +13,8 @@ module Leftovers
13
13
  def process(str, node, method_node)
14
14
  return unless str
15
15
 
16
- str.split(@split_on).map do |substring|
17
- @then_processor.process(substring, node, method_node)
16
+ Leftovers.map_or_self(str.split(@split_on)) do |sub_str|
17
+ @then_processor.process(sub_str, node, method_node)
18
18
  end
19
19
  end
20
20
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Leftovers
4
- VERSION = '0.7.0'
4
+ VERSION = '0.8.0'
5
5
  end
data/lib/leftovers.rb CHANGED
@@ -1,7 +1,28 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'parser'
4
+ require 'parser/current' # to get the error message early and once.
5
+
3
6
  module Leftovers # rubocop:disable Metrics/ModuleLength
4
7
  class Error < ::StandardError; end
8
+ class UnexpectedCase < Error; end
9
+
10
+ class PrecompileError < Error
11
+ attr_reader :line, :column
12
+
13
+ def initialize(message, line: nil, column: nil)
14
+ @line = line
15
+ @column = column
16
+ super(message)
17
+ end
18
+
19
+ def warn(path:)
20
+ line_column = ":#{line}#{":#{column}" if column}" if line
21
+ klass = cause ? cause.class : self.class
22
+
23
+ Leftovers.warn "#{klass}: #{path}#{line_column} #{message}"
24
+ end
25
+ end
5
26
 
6
27
  autoload(:AST, "#{__dir__}/leftovers/ast")
7
28
  autoload(:CLI, "#{__dir__}/leftovers/cli")
@@ -13,21 +34,17 @@ module Leftovers # rubocop:disable Metrics/ModuleLength
13
34
  autoload(:DefinitionNodeSet, "#{__dir__}/leftovers/definition_node_set")
14
35
  autoload(:DefinitionSet, "#{__dir__}/leftovers/definition_set")
15
36
  autoload(:DefinitionToAdd, "#{__dir__}/leftovers/definition_to_add")
16
- autoload(:ERB, "#{__dir__}/leftovers/erb")
17
37
  autoload(:FileCollector, "#{__dir__}/leftovers/file_collector")
18
38
  autoload(:FileList, "#{__dir__}/leftovers/file_list")
19
39
  autoload(:File, "#{__dir__}/leftovers/file")
20
- autoload(:Haml, "#{__dir__}/leftovers/haml")
21
- autoload(:YAML, "#{__dir__}/leftovers/yaml")
22
- autoload(:JSON, "#{__dir__}/leftovers/json")
23
40
  autoload(:MatcherBuilders, "#{__dir__}/leftovers/matcher_builders")
24
41
  autoload(:Matchers, "#{__dir__}/leftovers/matchers")
25
42
  autoload(:MergedConfig, "#{__dir__}/leftovers/merged_config")
26
43
  autoload(:Parser, "#{__dir__}/leftovers/parser")
44
+ autoload(:Precompilers, "#{__dir__}/leftovers/precompilers")
27
45
  autoload(:ProcessorBuilders, "#{__dir__}/leftovers/processor_builders")
28
46
  autoload(:RakeTask, "#{__dir__}/leftovers/rake_task")
29
47
  autoload(:Reporter, "#{__dir__}/leftovers/reporter")
30
- autoload(:Slim, "#{__dir__}/leftovers/slim")
31
48
  autoload(:TodoReporter, "#{__dir__}/leftovers/todo_reporter")
32
49
  autoload(:DynamicProcessors, "#{__dir__}/leftovers/dynamic_processors")
33
50
  autoload(:ValueProcessors, "#{__dir__}/leftovers/value_processors")
@@ -146,11 +163,29 @@ module Leftovers # rubocop:disable Metrics/ModuleLength
146
163
 
147
164
  case value
148
165
  when nil then nil
149
- when Array then value.each { |i| each_or_self(i, &block) }
166
+ when Array then value.each(&block)
167
+ else yield(value)
168
+ end
169
+ end
170
+
171
+ def map_or_self(value, &block)
172
+ # return enum_for(__method__, value) unless block
173
+
174
+ case value
175
+ when nil then nil
176
+ when Array then unwrap_array(value.flat_map(&block).compact)
150
177
  else yield(value)
151
178
  end
152
179
  end
153
180
 
181
+ def unwrap_array(array)
182
+ if array.length <= 1
183
+ array.first
184
+ else
185
+ array
186
+ end
187
+ end
188
+
154
189
  private
155
190
 
156
191
  def try_require_cache(requirable)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: leftovers
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dana Sherson
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-02-23 00:00:00.000000000 Z
11
+ date: 2022-02-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -317,6 +317,7 @@ files:
317
317
  - LICENSE.txt
318
318
  - README.md
319
319
  - docs/Configuration.md
320
+ - docs/Custom-Precompilers.md
320
321
  - exe/leftovers
321
322
  - leftovers.gemspec
322
323
  - lib/.DS_Store
@@ -364,13 +365,17 @@ files:
364
365
  - lib/leftovers/config_loader/argument_position_schema.rb
365
366
  - lib/leftovers/config_loader/argumentless_transform_schema.rb
366
367
  - lib/leftovers/config_loader/attribute.rb
368
+ - lib/leftovers/config_loader/built_in_precompiler_schema.rb
367
369
  - lib/leftovers/config_loader/document_schema.rb
368
370
  - lib/leftovers/config_loader/dynamic_schema.rb
369
371
  - lib/leftovers/config_loader/has_argument_schema.rb
370
372
  - lib/leftovers/config_loader/has_value_schema.rb
373
+ - lib/leftovers/config_loader/inherit_schema_attributes.rb
371
374
  - lib/leftovers/config_loader/keep_test_only_schema.rb
372
375
  - lib/leftovers/config_loader/node.rb
373
376
  - lib/leftovers/config_loader/object_schema.rb
377
+ - lib/leftovers/config_loader/precompile_schema.rb
378
+ - lib/leftovers/config_loader/precompiler_schema.rb
374
379
  - lib/leftovers/config_loader/privacy_processor_schema.rb
375
380
  - lib/leftovers/config_loader/privacy_schema.rb
376
381
  - lib/leftovers/config_loader/require_schema.rb
@@ -387,6 +392,7 @@ files:
387
392
  - lib/leftovers/config_loader/true_schema.rb
388
393
  - lib/leftovers/config_loader/value_matcher_schema.rb
389
394
  - lib/leftovers/config_loader/value_or_array_schema.rb
395
+ - lib/leftovers/config_loader/value_or_object_schema.rb
390
396
  - lib/leftovers/config_loader/value_processor_schema.rb
391
397
  - lib/leftovers/config_loader/value_type_schema.rb
392
398
  - lib/leftovers/definition.rb
@@ -402,12 +408,11 @@ files:
402
408
  - lib/leftovers/dynamic_processors/null.rb
403
409
  - lib/leftovers/dynamic_processors/set_default_privacy.rb
404
410
  - lib/leftovers/dynamic_processors/set_privacy.rb
405
- - lib/leftovers/erb.rb
406
411
  - lib/leftovers/file.rb
407
412
  - lib/leftovers/file_collector.rb
413
+ - lib/leftovers/file_collector/comments_processor.rb
414
+ - lib/leftovers/file_collector/node_processor.rb
408
415
  - lib/leftovers/file_list.rb
409
- - lib/leftovers/haml.rb
410
- - lib/leftovers/json.rb
411
416
  - lib/leftovers/matcher_builders.rb
412
417
  - lib/leftovers/matcher_builders/and.rb
413
418
  - lib/leftovers/matcher_builders/and_not.rb
@@ -450,6 +455,13 @@ files:
450
455
  - lib/leftovers/matchers/predicate.rb
451
456
  - lib/leftovers/merged_config.rb
452
457
  - lib/leftovers/parser.rb
458
+ - lib/leftovers/precompilers.rb
459
+ - lib/leftovers/precompilers/erb.rb
460
+ - lib/leftovers/precompilers/haml.rb
461
+ - lib/leftovers/precompilers/json.rb
462
+ - lib/leftovers/precompilers/precompiler.rb
463
+ - lib/leftovers/precompilers/slim.rb
464
+ - lib/leftovers/precompilers/yaml.rb
453
465
  - lib/leftovers/processor_builders.rb
454
466
  - lib/leftovers/processor_builders/action.rb
455
467
  - lib/leftovers/processor_builders/add_prefix.rb
@@ -469,7 +481,6 @@ files:
469
481
  - lib/leftovers/processor_builders/value.rb
470
482
  - lib/leftovers/rake_task.rb
471
483
  - lib/leftovers/reporter.rb
472
- - lib/leftovers/slim.rb
473
484
  - lib/leftovers/todo_reporter.rb
474
485
  - lib/leftovers/value_processors.rb
475
486
  - lib/leftovers/value_processors/add_dynamic_prefix.rb
@@ -507,7 +518,6 @@ files:
507
518
  - lib/leftovers/value_processors/underscore.rb
508
519
  - lib/leftovers/value_processors/upcase.rb
509
520
  - lib/leftovers/version.rb
510
- - lib/leftovers/yaml.rb
511
521
  homepage: http://github.com/robotdana/leftovers
512
522
  licenses:
513
523
  - MIT
data/lib/leftovers/erb.rb DELETED
@@ -1,20 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'erb'
4
-
5
- module Leftovers
6
- class ERB < ::ERB::Compiler
7
- def self.precompile(erb, _name)
8
- @compiler ||= new('-')
9
- @compiler.compile(erb).first
10
- end
11
-
12
- def add_insert_cmd(out, content) # leftovers:keep
13
- out.push("\n#{content}\n")
14
- end
15
-
16
- def add_put_cmd(out, _content) # leftovers:keep
17
- out.push("\n")
18
- end
19
- end
20
- end
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Leftovers
4
- module Haml
5
- module_function
6
-
7
- def precompile(file, name)
8
- return '' unless Leftovers.try_require('haml', message: <<~MESSAGE) # rubocop:disable Layout/EmptyLineAfterGuardClause
9
- Skipped parsing #{name.relative_path}, because the haml gem was not available
10
- `gem install haml`
11
- MESSAGE
12
-
13
- begin
14
- ::Haml::Engine.new(file).precompiled
15
- rescue ::Haml::SyntaxError => e
16
- Leftovers.warn "#{e.class}: #{e.message} #{name.relative_path}:#{e.line}"
17
- ''
18
- end
19
- end
20
- end
21
- end
@@ -1,28 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'json'
4
-
5
- module Leftovers
6
- module JSON
7
- class << self
8
- def precompile(json, name)
9
- "__leftovers_document(#{to_ruby_argument(::JSON.parse(json))})"
10
- rescue ::JSON::ParserError => e
11
- Leftovers.warn "#{e.class}: (#{name.relative_path}): #{e.message}"
12
- ''
13
- end
14
-
15
- private
16
-
17
- def to_ruby_argument(value)
18
- ruby = value.inspect
19
- return ruby unless value.is_a?(Array)
20
-
21
- ruby.delete_prefix!('[')
22
- ruby.delete_suffix!(']')
23
-
24
- ruby
25
- end
26
- end
27
- end
28
- end
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Leftovers
4
- module Slim
5
- module_function
6
-
7
- def precompile(file, name)
8
- return '' unless Leftovers.try_require('slim', message: <<~MESSAGE) # rubocop:disable Layout/EmptyLineAfterGuardClause
9
- Skipped parsing #{name.relative_path}, because the slim gem was not available
10
- `gem install slim`
11
- MESSAGE
12
-
13
- begin
14
- ::Slim::Engine.new(file: file).call(file)
15
- rescue ::Slim::Parser::SyntaxError => e
16
- Leftovers.warn "#{e.class}: \"#{e.error}\" #{name.relative_path}:#{e.lineno}:#{e.column}"
17
- ''
18
- end
19
- end
20
- end
21
- end
@@ -1,73 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'yaml'
4
-
5
- module Leftovers
6
- module YAML
7
- class Builder < ::Psych::TreeBuilder
8
- def initialize
9
- @constants = []
10
-
11
- super
12
- end
13
-
14
- def add_constant_for_tag(tag, value = nil)
15
- match = %r{\A!ruby/[^:]*(?::(.*))?\z}.match(tag)
16
- return unless match
17
-
18
- @constants << (match[1] || value)
19
- end
20
-
21
- def start_mapping(_anchor, tag, *rest) # leftovers:keep
22
- add_constant_for_tag(tag)
23
- tag = nil
24
-
25
- super
26
- end
27
-
28
- def start_sequence(_anchor, tag, *rest) # leftovers:keep
29
- add_constant_for_tag(tag)
30
- tag = nil
31
-
32
- super
33
- end
34
-
35
- def scalar(value, _anchor, tag, *rest) # leftovers:keep
36
- add_constant_for_tag(tag, value)
37
- tag = nil
38
-
39
- super
40
- end
41
-
42
- def to_ruby_file
43
- <<~RUBY
44
- __leftovers_document(#{to_ruby_argument(root.to_ruby.first)})
45
- #{@constants.join("\n")}
46
- RUBY
47
- end
48
-
49
- private
50
-
51
- def to_ruby_argument(value)
52
- ruby = value.inspect
53
- return ruby unless value.is_a?(Array)
54
-
55
- ruby.delete_prefix!('[')
56
- ruby.delete_suffix!(']')
57
-
58
- ruby
59
- end
60
- end
61
-
62
- def self.precompile(yaml, name)
63
- builder = ::Leftovers::YAML::Builder.new
64
- parser = ::Psych::Parser.new(builder)
65
- parser.parse(yaml, name.relative_path)
66
-
67
- builder.to_ruby_file
68
- rescue ::Psych::SyntaxError => e
69
- Leftovers.warn "#{e.class}: #{e.message}"
70
- ''
71
- end
72
- end
73
- end