leftovers 0.7.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
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