diff --git a/Gemfile.lock b/Gemfile.lock index a4a1919..4aee02f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,8 @@ PATH remote: . specs: - fastlane-plugin-patch (0.4.0) + fastlane-plugin-patch (0.4.1) + pattern_patch GEM remote: https://rubygems.org/ @@ -106,6 +107,7 @@ GEM parallel (1.12.0) parser (2.4.0.0) ast (~> 2.2) + pattern_patch (0.1.0) plist (3.3.0) powerpack (0.1.1) pry (0.10.4) diff --git a/fastlane-plugin-patch.gemspec b/fastlane-plugin-patch.gemspec index 5a2c6f0..928cd4e 100644 --- a/fastlane-plugin-patch.gemspec +++ b/fastlane-plugin-patch.gemspec @@ -18,6 +18,8 @@ Gem::Specification.new do |spec| spec.test_files = spec.files.grep(%r{^(test|spec|features)/}) spec.require_paths = ['lib'] + spec.add_dependency 'pattern_patch' + spec.add_development_dependency 'pry' spec.add_development_dependency 'bundler' spec.add_development_dependency 'rspec' diff --git a/lib/fastlane/plugin/patch/actions/apply_patch_action.rb b/lib/fastlane/plugin/patch/actions/apply_patch_action.rb index 17f9158..3eb4fc5 100644 --- a/lib/fastlane/plugin/patch/actions/apply_patch_action.rb +++ b/lib/fastlane/plugin/patch/actions/apply_patch_action.rb @@ -34,12 +34,12 @@ def self.run(params) files.each do |file| modified_contents = File.open(file, "r") do |f| - helper.apply_patch f.read, - params[:regexp], - params[:text], - params[:global], - params[:mode], - params[:offset] + PatternPatch::Utilities.apply_patch f.read, + params[:regexp], + params[:text], + params[:global], + params[:mode], + params[:offset] end File.open(file, "w") { |f| f.write modified_contents } diff --git a/lib/fastlane/plugin/patch/actions/patch_action.rb b/lib/fastlane/plugin/patch/actions/patch_action.rb index b218d73..1f6a972 100644 --- a/lib/fastlane/plugin/patch/actions/patch_action.rb +++ b/lib/fastlane/plugin/patch/actions/patch_action.rb @@ -1,3 +1,4 @@ +require 'pattern_patch' require 'yaml' module Fastlane @@ -35,19 +36,19 @@ def self.run(params) files.each do |file| modified_contents = File.open(file, "r") do |f| if params[:revert] - helper.revert_patch f.read, - params[:regexp], - params[:text], - params[:global], - params[:mode], - params[:offset] + PatternPatch::Utilities.revert_patch f.read, + params[:regexp], + params[:text], + params[:global], + params[:mode], + params[:offset] else - helper.apply_patch f.read, - params[:regexp], - params[:text], - params[:global], - params[:mode], - params[:offset] + PatternPatch::Utilities.apply_patch f.read, + params[:regexp], + params[:text], + params[:global], + params[:mode], + params[:offset] end end diff --git a/lib/fastlane/plugin/patch/actions/revert_patch_action.rb b/lib/fastlane/plugin/patch/actions/revert_patch_action.rb index 05b3a0b..62cf822 100644 --- a/lib/fastlane/plugin/patch/actions/revert_patch_action.rb +++ b/lib/fastlane/plugin/patch/actions/revert_patch_action.rb @@ -1,3 +1,4 @@ +require 'pattern_patch' require 'yaml' module Fastlane @@ -34,12 +35,12 @@ def self.run(params) files.each do |file| modified_contents = File.open(file, "r") do |f| - helper.revert_patch f.read, - params[:regexp], - params[:text], - params[:global], - params[:mode], - params[:offset] + PatternPatch::Utilities.revert_patch f.read, + params[:regexp], + params[:text], + params[:global], + params[:mode], + params[:offset] end File.open(file, "w") { |f| f.write modified_contents } diff --git a/lib/fastlane/plugin/patch/helper/patch_helper.rb b/lib/fastlane/plugin/patch/helper/patch_helper.rb index 67c302d..b5a813d 100644 --- a/lib/fastlane/plugin/patch/helper/patch_helper.rb +++ b/lib/fastlane/plugin/patch/helper/patch_helper.rb @@ -1,108 +1,7 @@ -class String - # Replace capture group references in self with appropriate - # data from matches. Modifies the receiver. The receiver - # need not match the matches.regexp. - # - # :matches: A MatchData object returned by Regexp#match - def apply_matches!(matches) - search_position = 0 - while (m = /\\(\d+)/.match(self, search_position)) - capture_group = m[1].to_i - search_position = index m[0] - gsub! m[0], matches[capture_group] - search_position += matches[capture_group].length - end - nil - end - - # Return a copy of the receiver with capture group references - # in self replaced by appropriate data from matches. The receiver - # need not match the matches.regexp. - # - # :matches: A MatchData object returned by Regexp#match - def apply_matches(matches) - string = clone - string.apply_matches! matches - string - end -end - module Fastlane module Helper class PatchHelper class << self - # Add the specified text after the specified pattern. - # Returns a modified copy of the string. - # - # :contents: A string to modify, e.g. the contents of a file - # :regexp: A regular expression specifying a pattern to be matched - # :text: Text to be appended to the specified pattern - # :global: Boolean flag. If true, patch all occurrences of the regex. - # :mode: :append, :prepend or :replace to specify how to apply the patch - # :offset: Starting position for matching - def apply_patch(contents, regexp, text, global, mode, offset) - search_position = offset - while (matches = regexp.match(contents, search_position)) - patched_pattern = - case mode - when :append - "#{matches[0]}#{text.apply_matches matches}" - when :prepend - "#{text.apply_matches matches}#{matches[0]}" - when :replace - matches[0].sub regexp, text - else - raise ArgumentError, "Invalid mode argument. Specify :append, :prepend or :replace." - end - - contents = "#{matches.pre_match}#{patched_pattern}#{matches.post_match}" - break unless global - search_position = matches.pre_match.length + patched_pattern.length - end - contents - end - - # Reverts a patch. Use the same arguments that were supplied to apply_patch. - # The mode argument can only be :append or :prepend. Patches using :replace - # cannot be reverted. - # Returns a modified copy of the string. - # - # :contents: A string to modify, e.g. the contents of a file - # :regexp: A regular expression specifying a pattern to be matched - # :text: Text to be appended to the specified pattern - # :global: Boolean flag. If true, patch all occurrences of the regex. - # :mode: :append or :prepend. :replace patches cannot be reverted automatically. - # :offset: Starting position for matching - def revert_patch(contents, regexp, text, global, mode, offset) - search_position = offset - regexp_string = regexp.to_s - - patched_regexp = - case mode - when :append - /#{regexp_string}#{text}/m - when :prepend - # TODO: Capture groups aren't currently revertible in :prepend mode. - # This patched regexp can turn into something like /\1.*(\d+)/. - # The capture group reference cannot occur in the regexp before definition - # of the group. This would have to be transformed to something like - # /(\d+).*\1/. Patch reversion is probably not a major use case right - # now, so ignore for the moment. - /#{text}#{regexp_string}/m - else - raise ArgumentError, "Invalid mode argument. Specify :append or :prepend." - end - - while (matches = patched_regexp.match(contents, search_position)) - reverted_text = matches[0].sub(text.apply_matches(matches), '') - contents = "#{matches.pre_match}#{reverted_text}#{matches.post_match}" - break unless global - search_position = matches.pre_match.length + reverted_text.length - end - - contents - end - def files_from_params(params) case params[:files] when Array diff --git a/lib/fastlane/plugin/patch/version.rb b/lib/fastlane/plugin/patch/version.rb index 430ac50..1394e52 100644 --- a/lib/fastlane/plugin/patch/version.rb +++ b/lib/fastlane/plugin/patch/version.rb @@ -1,5 +1,5 @@ module Fastlane module Patch - VERSION = "0.4.0" + VERSION = "0.4.1" end end diff --git a/spec/patch_helper_spec.rb b/spec/patch_helper_spec.rb index 880ecbe..65644f1 100644 --- a/spec/patch_helper_spec.rb +++ b/spec/patch_helper_spec.rb @@ -1,180 +1,6 @@ -describe String do - describe '#apply_matches!' do - it 'applies match data to an unrelated string' do - text = '\1 abc' - matches = /(\d+)/.match "123" - text.apply_matches! matches - expect(text).to eq "123 abc" - end - - it 'handles repeated instances of the same capture group' do - text = '\1 \1 abc' - matches = /(\d+)/.match "123" - text.apply_matches! matches - expect(text).to eq "123 123 abc" - end - - it 'replaces multiple capture groups' do - text = '\1 \2 abc' - matches = /(\d+)(.*)/.match "123xyz" - text.apply_matches! matches - expect(text).to eq "123 xyz abc" - end - end - - describe '#apply_matches' do - it 'returns clone.apply_matches!' do - text = '\1 \2 abc' - matches = /(\d+)(.*)/.match "123xyz" - new_text = text.apply_matches matches - expect(new_text).to eq "123 xyz abc" - expect(text).to eq '\1 \2 abc' - end - end -end - describe Fastlane::Helper::PatchHelper do let (:helper) { Fastlane::Helper::PatchHelper } - describe 'apply_patch' do - describe 'modes' do - it 'inserts text after a pattern in :append mode' do - original = 'alpha beta gamma' - modified = helper.apply_patch original, /beta/, ' beta and a half', false, :append, 0 - expect(modified).to eq 'alpha beta beta and a half gamma' - end - - it 'inserts text before a pattern in :prepend mode' do - original = 'alpha beta gamma' - modified = helper.apply_patch original, /beta/, 'alpha and a half ', false, :prepend, 0 - expect(modified).to eq 'alpha alpha and a half beta gamma' - end - - it 'replaces a pattern with text in :replace mode' do - original = 'alpha beta gamma' - modified = helper.apply_patch original, /beta/, 'two', false, :replace, 0 - expect(modified).to eq 'alpha two gamma' - end - - it 'recognizes capture groups in :replace mode' do - original = 'alpha beta gamma' - modified = helper.apply_patch original, /(beta)/, '\1 two', false, :replace, 0 - expect(modified).to eq 'alpha beta two gamma' - end - - it 'recognizes capture groups in :append mode' do - original = 'alpha beta gamma' - modified = helper.apply_patch original, /(beta)/, ' \1 and a half', false, :append, 0 - expect(modified).to eq 'alpha beta beta and a half gamma' - end - - it 'recognizes capture groups in :prepend mode' do - original = 'alpha beta gamma' - modified = helper.apply_patch original, /(beta)/, '\1 and a half ', false, :prepend, 0 - expect(modified).to eq 'alpha beta and a half beta gamma' - end - - it 'raises for any other mode' do - original = 'alpha beta gamma' - expect do - helper.apply_patch original, /beta/, ' beta and a half', false, :add_somewhere_i_dont_know_where, 0 - end.to raise_error ArgumentError - end - end - - describe 'line endings' do - it 'handles things at the end of a line' do - original = "alpha\nbeta\ngamma\n" - modified = helper.apply_patch original, /beta$/, "\nbeta and a half", false, :append, 0 - expect(modified).to eq "alpha\nbeta\nbeta and a half\ngamma\n" - end - - it 'handles things at the beginning of a line' do - original = "alpha\nbeta\ngamma\n" - modified = helper.apply_patch original, /^beta/, "alpha and a half\n", false, :prepend, 0 - expect(modified).to eq "alpha\nalpha and a half\nbeta\ngamma\n" - end - end - - describe 'global flag' do - it 'appends globally' do - original = 'alpha alpha alpha' - modified = helper.apply_patch original, /alpha/, ' alpha and a half', true, :append, 0 - expect(modified).to eq 'alpha alpha and a half alpha alpha and a half alpha alpha and a half' - end - - it 'prepends globally' do - original = 'alpha alpha alpha' - modified = helper.apply_patch original, /alpha/, 'alpha and a half ', true, :prepend, 0 - expect(modified).to eq 'alpha and a half alpha alpha and a half alpha alpha and a half alpha' - end - end - end - - describe 'revert_patch' do - describe 'modes' do - it 'removes a patch applied in :append mode' do - original = 'alpha beta beta and a half gamma' - modified = helper.revert_patch original, /beta/, ' beta and a half', false, :append, 0 - expect(modified).to eq 'alpha beta gamma' - end - - it 'reverts a patch applied in :prepend mode' do - original = 'alpha alpha and a half beta gamma' - modified = helper.revert_patch original, /beta/, 'alpha and a half ', false, :prepend, 0 - expect(modified).to eq 'alpha beta gamma' - end - - it 'recognizes capture groups in :append mode' do - original = 'alpha beta beta and a half gamma' - modified = helper.revert_patch original, /(beta)/, ' \1 and a half', false, :append, 0 - expect(modified).to eq 'alpha beta gamma' - end - - it 'recognizes capture groups in :prepend mode' do - pending 'not working with prepend atm' - original = 'alpha beta and a half beta gamma' - modified = helper.revert_patch original, /(beta)/, '\1 and a half ', false, :prepend, 0 - expect(modified).to eq 'alpha beta gamma' - end - - it 'raises if :replace mode specified' do - original = 'alpha two gamma' - expect do - helper.revert_patch original, /beta/, 'two', false, :replace, 0 - end.to raise_error ArgumentError - end - end - - describe 'line endings' do - it 'handles things at the end of a line' do - original = "alpha\nbeta\nbeta and a half\ngamma\n" - modified = helper.revert_patch original, /beta$/, "\nbeta and a half", false, :append, 0 - expect(modified).to eq "alpha\nbeta\ngamma\n" - end - - it 'handles things at the beginning of a line' do - original = "alpha\nalpha and a half\nbeta\ngamma\n" - modified = helper.revert_patch original, /^beta/, "alpha and a half\n", false, :prepend, 0 - expect(modified).to eq "alpha\nbeta\ngamma\n" - end - end - - describe 'global flag' do - it 'reverts :append patches globally' do - original = 'alpha alpha and a half alpha alpha and a half alpha alpha and a half' - modified = helper.revert_patch original, /alpha/, ' alpha and a half', true, :append, 0 - expect(modified).to eq 'alpha alpha alpha' - end - - it 'reverts :prepend patches globally' do - original = 'alpha and a half alpha alpha and a half alpha alpha and a half alpha' - modified = helper.revert_patch original, /alpha/, 'alpha and a half ', true, :prepend, 0 - expect(modified).to eq 'alpha alpha alpha' - end - end - end - describe 'files_from_params' do it 'returns an array of strings when an array is passed' do expect(helper.files_from_params(files: [:a, :b, :c])).to eq %w{a b c}