pattern_patch 0.5.5 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8f6f40628b47488df4f90cfa6a5b50d081920599c96d010fd74885dad790e0b8
4
- data.tar.gz: f0cb442292000db601602c3e8540a6989b87c99efbc43aa8736ca5331cb51cc3
3
+ metadata.gz: 9e20771a9100042d880f37afca70c6bf547b167777a8c58a342a637e62fd36ed
4
+ data.tar.gz: f357bd192396f04a8a6757e6ab2736244d12e32679420bb80691836b77235961
5
5
  SHA512:
6
- metadata.gz: 6f0267701568351d0fb97de38756fa62c8ffb1700784ba0ebaed121e19d544600565f5f58eb76ce1ae3fd1cca76c23547963133cba9989590d74008ef924d569
7
- data.tar.gz: cb8c146fc40df297a83d2579e8dc8580fd5c959d75934fc2e0354c6edea87f8aa370a538dc4aa1833dfa2ad9505c59d34151737576025b53612e113eec98d73a
6
+ metadata.gz: 5183c3381e5fcc3e5b4da29832ed62bd66471c23eee239839441f89592c5fe07535e066e9575cee6ec9fa565dce9efe8e608664ed33700bc70daec051ae9a49a
7
+ data.tar.gz: 77cf6f4416a96a82c205b5fc8747323b2ad1ad12f39babc0dcc0b5eef01e887362dd7b509627c38d47c11f03606172613b2e7c51b7d2799497e46765d8c90881
@@ -0,0 +1,16 @@
1
+ class Hash
2
+ # #transform_keys not available in 2.3
3
+ def symbolize_keys
4
+ each_with_object({}) do |ary, hash|
5
+ key, value = *ary
6
+ hash[key.to_sym] = value
7
+ end
8
+ end
9
+
10
+ def symbolize_keys!
11
+ hash = symbolize_keys
12
+ clear
13
+ hash.each { |k, v| self[k] = v }
14
+ nil
15
+ end
16
+ end
@@ -1 +1,2 @@
1
- require "pattern_patch/core_ext/string"
1
+ require 'pattern_patch/core_ext/hash'
2
+ require 'pattern_patch/core_ext/string'
@@ -1,6 +1,7 @@
1
- require "active_support/core_ext/hash"
2
- require "erb"
3
- require "yaml"
1
+ require 'erb'
2
+ require 'yaml'
3
+ require_relative 'core_ext/hash'
4
+ require_relative 'renderer'
4
5
 
5
6
  module PatternPatch
6
7
  # The PatternPatch::Patch class defines a patch as an operation that
@@ -116,7 +117,7 @@ module PatternPatch
116
117
 
117
118
  # Applies the patch to one or more files. ERB is processed in the text
118
119
  # field, whether it comes from a text_file or not. Pass a Binding to
119
- # ERB using the :binding option. Pass the :offset option to specify a
120
+ # ERB using the :binding option or a Hash of locals. Pass the :offset option to specify a
120
121
  # starting offset, in characters, from the beginning of the file.
121
122
  #
122
123
  # @param files [Array, String] One or more file paths to which to apply the patch.
@@ -125,6 +126,7 @@ module PatternPatch
125
126
  # @option options [Integer] :offset (0) Offset in characters
126
127
  # @option options [Object, nil] :safe_level (PatternPatch.safe_level) A valid value for $SAFE for use with ERb
127
128
  # @option options [String] :trim_mode (PatternPatch.trim_mode) A valid ERb trim mode
129
+ # @option options [Hash] :locals A Hash of local variables for rendering the template
128
130
  # @raise [ArgumentError] In case of invalid mode (other than :append, :prepend, :replace)
129
131
  def apply(files, options = {})
130
132
  offset = options[:offset] || 0
@@ -133,7 +135,16 @@ module PatternPatch
133
135
  safe_level = options[:safe_level] || PatternPatch.safe_level
134
136
  trim_mode = options[:trim_mode] || PatternPatch.trim_mode
135
137
 
136
- patch_text = ERB.new(text, safe_level, trim_mode).result options[:binding]
138
+ locals = options[:locals]
139
+
140
+ raise ArgumentError, ':binding is incompatible with :locals' if options[:binding] && locals
141
+
142
+ renderer = Renderer.new text, safe_level, trim_mode
143
+ if locals.nil?
144
+ patch_text = renderer.render options[:binding]
145
+ else
146
+ patch_text = renderer.render locals
147
+ end
137
148
 
138
149
  files.each do |path|
139
150
  modified = Utilities.apply_patch File.read(path),
@@ -148,7 +159,7 @@ module PatternPatch
148
159
 
149
160
  # Reverse the effect of a patch on one or more files. ERB is processed in the text
150
161
  # field, whether it comes from a text_file or not. Pass a Binding to
151
- # ERB using the :binding option. Pass the :offset option to specify a
162
+ # ERB using the :binding option or a Hash of locals. Pass the :offset option to specify a
152
163
  # starting offset, in characters, from the beginning of the file.
153
164
  #
154
165
  # @param files [Array, String] One or more file paths to which to apply the patch.
@@ -157,6 +168,7 @@ module PatternPatch
157
168
  # @option options [Integer] :offset (0) Offset in characters
158
169
  # @option options [Object, nil] :safe_level (PatternPatch.safe_level) A valid value for $SAFE for use with ERb
159
170
  # @option options [String] :trim_mode (PatternPatch.trim_mode) A valid ERb trim mode
171
+ # @option options [Hash] :locals A Hash of local variables for rendering the template
160
172
  # @raise [ArgumentError] In case of invalid mode (other than :append or :prepend)
161
173
  def revert(files, options = {})
162
174
  offset = options[:offset] || 0
@@ -165,7 +177,16 @@ module PatternPatch
165
177
  safe_level = options[:safe_level] || PatternPatch.safe_level
166
178
  trim_mode = options[:trim_mode] || PatternPatch.trim_mode
167
179
 
168
- patch_text = ERB.new(text, safe_level, trim_mode).result options[:binding]
180
+ locals = options[:locals]
181
+
182
+ raise ArgumentError, ':binding is incompatible with :locals' if options[:binding] && locals
183
+
184
+ renderer = Renderer.new text, safe_level, trim_mode
185
+ if locals.nil?
186
+ patch_text = renderer.render options[:binding]
187
+ else
188
+ patch_text = renderer.render locals
189
+ end
169
190
 
170
191
  files.each do |path|
171
192
  modified = Utilities.revert_patch File.read(path),
@@ -0,0 +1,62 @@
1
+ require_relative 'core_ext/hash'
2
+ require 'rubygems'
3
+
4
+ module PatternPatch
5
+ # Provides a fairly clean binding for resolving locals in Ruby < 2.5.
6
+ # All locals become method calls in the binding passed to ERB. A separate
7
+ # class (instead of a Module, e.g.) means minimal clutter in the set of
8
+ # methods available to the binding.
9
+ class Renderer
10
+ class << self
11
+ def is_ruby3?
12
+ version = Gem::Version.new RUBY_VERSION
13
+ requirement = Gem::Requirement.new '>= 3'
14
+ requirement =~ version
15
+ end
16
+ end
17
+
18
+ def initialize(text, safe_level = nil, trim_mode = nil)
19
+ if self.class.is_ruby3?
20
+ @template = ERB.new text, trim_mode: trim_mode
21
+ else
22
+ @template = ERB.new text, safe_level, trim_mode
23
+ end
24
+ @locals = {}
25
+ end
26
+
27
+ # Render an ERB template with a binding or locals.
28
+ # renderer = Renderer.new template_text
29
+ # result = renderer.render binding
30
+ # result = renderer.render a: 'foo', b: 1
31
+ # @param locals_or_binding [Hash, Binding] a Hash of locals or a Binding
32
+ # @return the result of rendering the template
33
+ # @raise ArgumentError for invalid locals
34
+ def render(locals_or_binding = {})
35
+ # Pass a Binding this way.
36
+ return @template.result(locals_or_binding) unless locals_or_binding.kind_of?(Hash)
37
+
38
+ @locals = locals_or_binding.symbolize_keys
39
+ # Any local that corresponds to a method name in this class is invalid
40
+ # because it cannot trigger method_missing. The same goes for
41
+ # locals_or_binding, the only local variable.
42
+ # Avoid new methods and local variables, which will be visible in the binding.
43
+ # Could validate only for Ruby < 2.5, but better to be consistent.
44
+ if @locals.any? { |l| respond_to?(l) || l == :locals_or_binding }
45
+ raise ArgumentError, "Invalid locals: #{@locals.select { |l| respond_to?(l) || l == :locals_or_binding }.map(&:to_str).join ', '}"
46
+ end
47
+
48
+ if @template.respond_to? :result_with_hash
49
+ # ERB#result_with_hash requires Ruby 2.5.
50
+ @template.result_with_hash locals_or_binding
51
+ else
52
+ @template.result binding
53
+ end
54
+ end
55
+
56
+ def method_missing(method_sym, *args, &block)
57
+ return super unless @locals.key?(method_sym)
58
+
59
+ @locals[method_sym]
60
+ end
61
+ end
62
+ end
@@ -29,6 +29,7 @@ module PatternPatch
29
29
 
30
30
  contents = "#{matches.pre_match}#{patched_pattern}#{matches.post_match}"
31
31
  break unless global
32
+
32
33
  search_position = matches.pre_match.length + patched_pattern.length
33
34
  end
34
35
  contents
@@ -71,6 +72,7 @@ module PatternPatch
71
72
  reverted_text = matches[0].sub(text.apply_matches(matches), '')
72
73
  contents = "#{matches.pre_match}#{reverted_text}#{matches.post_match}"
73
74
  break unless global
75
+
74
76
  search_position = matches.pre_match.length + reverted_text.length
75
77
  end
76
78
 
@@ -1,3 +1,3 @@
1
1
  module PatternPatch
2
- VERSION = "0.5.5"
2
+ VERSION = "1.1.0"
3
3
  end
data/lib/pattern_patch.rb CHANGED
@@ -46,9 +46,36 @@ module PatternPatch
46
46
  # @raise [ConfigurationError] If patch_dir is nil or is not a valid directory path
47
47
  def patch(name)
48
48
  raise ConfigurationError, "patch_dir has not been set" if patch_dir.nil?
49
- raise ConfigurationError, "patch_dir is not a directory" unless Dir.exist?(patch_dir)
49
+ raise ConfigurationError, "patch_dir #{patch_dir} is not a directory" unless Dir.exist?(patch_dir)
50
+
50
51
  Patch.from_yaml File.join(patch_dir, "#{name}.yml")
51
52
  end
53
+
54
+ # Useful to configure PatternPatch without using the class
55
+ # (PatternPatch.patch_dir=), ivar (@patch_dir) or explicit
56
+ # setter (self.patch_dir=).
57
+ #
58
+ # include PatternPatch::Methods
59
+ # patch_config do |c|
60
+ # c.patch_dir = 'lib/assets/patches'
61
+ # c.trim_mode = '<>'
62
+ # end
63
+ #
64
+ # or
65
+ #
66
+ # include PatternPatch::Methods
67
+ # patch_config.patch_dir = 'lib/assets/patches'
68
+ # patch_config.trim_mode = '<>'
69
+ #
70
+ # @yield self if block_given?
71
+ # @return self or return value of block
72
+ def patch_config(&block)
73
+ if block_given?
74
+ yield self
75
+ else
76
+ self
77
+ end
78
+ end
52
79
  end
53
80
 
54
81
  class << self
metadata CHANGED
@@ -1,155 +1,147 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pattern_patch
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.5
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jimmy Dee
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-12-29 00:00:00.000000000 Z
11
+ date: 2022-12-06 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: activesupport
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ~>
18
- - !ruby/object:Gem::Version
19
- version: '4.2'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ~>
25
- - !ruby/object:Gem::Version
26
- version: '4.2'
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: bundler
29
15
  requirement: !ruby/object:Gem::Requirement
30
16
  requirements:
31
- - - '>='
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '1.16'
20
+ - - "<"
32
21
  - !ruby/object:Gem::Version
33
- version: '0'
22
+ version: '3'
34
23
  type: :development
35
24
  prerelease: false
36
25
  version_requirements: !ruby/object:Gem::Requirement
37
26
  requirements:
38
- - - '>='
27
+ - - ">="
39
28
  - !ruby/object:Gem::Version
40
- version: '0'
29
+ version: '1.16'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '3'
41
33
  - !ruby/object:Gem::Dependency
42
34
  name: pry
43
35
  requirement: !ruby/object:Gem::Requirement
44
36
  requirements:
45
- - - '>='
37
+ - - "~>"
46
38
  - !ruby/object:Gem::Version
47
- version: '0'
39
+ version: '0.12'
48
40
  type: :development
49
41
  prerelease: false
50
42
  version_requirements: !ruby/object:Gem::Requirement
51
43
  requirements:
52
- - - '>='
44
+ - - "~>"
53
45
  - !ruby/object:Gem::Version
54
- version: '0'
46
+ version: '0.12'
55
47
  - !ruby/object:Gem::Dependency
56
48
  name: rake
57
49
  requirement: !ruby/object:Gem::Requirement
58
50
  requirements:
59
- - - '>='
51
+ - - "~>"
60
52
  - !ruby/object:Gem::Version
61
- version: '0'
53
+ version: '12.3'
62
54
  type: :development
63
55
  prerelease: false
64
56
  version_requirements: !ruby/object:Gem::Requirement
65
57
  requirements:
66
- - - '>='
58
+ - - "~>"
67
59
  - !ruby/object:Gem::Version
68
- version: '0'
60
+ version: '12.3'
69
61
  - !ruby/object:Gem::Dependency
70
62
  name: rspec
71
63
  requirement: !ruby/object:Gem::Requirement
72
64
  requirements:
73
- - - '>='
65
+ - - "~>"
74
66
  - !ruby/object:Gem::Version
75
- version: '0'
67
+ version: '3.8'
76
68
  type: :development
77
69
  prerelease: false
78
70
  version_requirements: !ruby/object:Gem::Requirement
79
71
  requirements:
80
- - - '>='
72
+ - - "~>"
81
73
  - !ruby/object:Gem::Version
82
- version: '0'
74
+ version: '3.8'
83
75
  - !ruby/object:Gem::Dependency
84
- name: rspec-simplecov
76
+ name: rspec_junit_formatter
85
77
  requirement: !ruby/object:Gem::Requirement
86
78
  requirements:
87
- - - '>='
79
+ - - "~>"
88
80
  - !ruby/object:Gem::Version
89
- version: '0'
81
+ version: '0.4'
90
82
  type: :development
91
83
  prerelease: false
92
84
  version_requirements: !ruby/object:Gem::Requirement
93
85
  requirements:
94
- - - '>='
86
+ - - "~>"
95
87
  - !ruby/object:Gem::Version
96
- version: '0'
88
+ version: '0.4'
97
89
  - !ruby/object:Gem::Dependency
98
- name: rspec_junit_formatter
90
+ name: rspec-simplecov
99
91
  requirement: !ruby/object:Gem::Requirement
100
92
  requirements:
101
- - - '>='
93
+ - - "~>"
102
94
  - !ruby/object:Gem::Version
103
- version: '0'
95
+ version: '0.2'
104
96
  type: :development
105
97
  prerelease: false
106
98
  version_requirements: !ruby/object:Gem::Requirement
107
99
  requirements:
108
- - - '>='
100
+ - - "~>"
109
101
  - !ruby/object:Gem::Version
110
- version: '0'
102
+ version: '0.2'
111
103
  - !ruby/object:Gem::Dependency
112
104
  name: rubocop
113
105
  requirement: !ruby/object:Gem::Requirement
114
106
  requirements:
115
107
  - - '='
116
108
  - !ruby/object:Gem::Version
117
- version: 0.50.0
109
+ version: 1.39.0
118
110
  type: :development
119
111
  prerelease: false
120
112
  version_requirements: !ruby/object:Gem::Requirement
121
113
  requirements:
122
114
  - - '='
123
115
  - !ruby/object:Gem::Version
124
- version: 0.50.0
116
+ version: 1.39.0
125
117
  - !ruby/object:Gem::Dependency
126
118
  name: simplecov
127
119
  requirement: !ruby/object:Gem::Requirement
128
120
  requirements:
129
- - - '>='
121
+ - - "~>"
130
122
  - !ruby/object:Gem::Version
131
- version: '0'
123
+ version: '0.16'
132
124
  type: :development
133
125
  prerelease: false
134
126
  version_requirements: !ruby/object:Gem::Requirement
135
127
  requirements:
136
- - - '>='
128
+ - - "~>"
137
129
  - !ruby/object:Gem::Version
138
- version: '0'
130
+ version: '0.16'
139
131
  - !ruby/object:Gem::Dependency
140
132
  name: yard
141
133
  requirement: !ruby/object:Gem::Requirement
142
134
  requirements:
143
- - - '>='
135
+ - - "~>"
144
136
  - !ruby/object:Gem::Version
145
- version: '0'
137
+ version: '0.9'
146
138
  type: :development
147
139
  prerelease: false
148
140
  version_requirements: !ruby/object:Gem::Requirement
149
141
  requirements:
150
- - - '>='
142
+ - - "~>"
151
143
  - !ruby/object:Gem::Version
152
- version: '0'
144
+ version: '0.9'
153
145
  description: This is a utility gem that identifies positions in any text using regular
154
146
  expressions and then inserts patch text at the specified location or replaces matching
155
147
  text. Many patches can be reverted.
@@ -160,32 +152,34 @@ extra_rdoc_files: []
160
152
  files:
161
153
  - lib/pattern_patch.rb
162
154
  - lib/pattern_patch/core_ext.rb
155
+ - lib/pattern_patch/core_ext/hash.rb
163
156
  - lib/pattern_patch/core_ext/string.rb
164
157
  - lib/pattern_patch/patch.rb
158
+ - lib/pattern_patch/renderer.rb
165
159
  - lib/pattern_patch/utilities.rb
166
160
  - lib/pattern_patch/version.rb
167
161
  homepage: http://github.com/jdee/pattern_patch
168
162
  licenses:
169
163
  - MIT
170
- metadata: {}
171
- post_install_message:
164
+ metadata:
165
+ rubygems_mfa_required: 'true'
166
+ post_install_message:
172
167
  rdoc_options: []
173
168
  require_paths:
174
169
  - lib
175
170
  required_ruby_version: !ruby/object:Gem::Requirement
176
171
  requirements:
177
- - - '>='
172
+ - - ">="
178
173
  - !ruby/object:Gem::Version
179
- version: 2.0.0
174
+ version: 2.3.0
180
175
  required_rubygems_version: !ruby/object:Gem::Requirement
181
176
  requirements:
182
- - - '>='
177
+ - - ">="
183
178
  - !ruby/object:Gem::Version
184
179
  version: '0'
185
180
  requirements: []
186
- rubyforge_project:
187
- rubygems_version: 2.7.4
188
- signing_key:
181
+ rubygems_version: 3.2.33
182
+ signing_key:
189
183
  specification_version: 4
190
184
  summary: Apply and revert pattern-based patches to text files of any kind
191
185
  test_files: []