From dd71c0288052dd3a96e730ff198f5c0a8d640946 Mon Sep 17 00:00:00 2001 From: Joseph Yaworski Date: Wed, 11 May 2016 13:21:24 -0400 Subject: Add a delete_regex function To maintain backwards compatibility, add a delete_regex function instead of modifying delete itself. --- README.markdown | 12 +++++-- lib/puppet/parser/functions/delete.rb | 8 +---- lib/puppet/parser/functions/delete_regex.rb | 45 ++++++++++++++++++++++++ spec/functions/delete_regex_spec.rb | 54 +++++++++++++++++++++++++++++ spec/functions/delete_spec.rb | 3 -- 5 files changed, 110 insertions(+), 12 deletions(-) create mode 100644 lib/puppet/parser/functions/delete_regex.rb create mode 100755 spec/functions/delete_regex_spec.rb diff --git a/README.markdown b/README.markdown index 6a64b79..373b08c 100644 --- a/README.markdown +++ b/README.markdown @@ -263,9 +263,9 @@ Takes a resource reference and an optional hash of attributes. Returns 'true' if #### `delete` -Deletes all instances of a given element from an array, substring from a string, or key from a hash. Arrays and hashes may also match on regular expressions by providing a full regular expression. +Deletes all instances of a given element from an array, substring from a string, or key from a hash. -For example, `delete(['a','b','c','b'], 'b')` returns ['a','c']; `delete('abracadabra', 'bra')` returns 'acada'. `delete({'a' => 1,'b' => 2,'c' => 3},['b','c'])` returns {'a'=> 1}, `delete(['abf', 'ab', 'ac'], '^ab.*')` returns ['ac']. `delete(['ab', 'b'], 'b')` returns ['ab']. +For example, `delete(['a','b','c','b'], 'b')` returns ['a','c']; `delete('abracadabra', 'bra')` returns 'acada'. `delete({'a' => 1,'b' => 2,'c' => 3},['b','c'])` returns {'a'=> 1}, `delete(['ab', 'b'], 'b')` returns ['ab']. *Type*: rvalue. @@ -273,6 +273,14 @@ For example, `delete(['a','b','c','b'], 'b')` returns ['a','c']; `delete('abraca Deletes a determined indexed value from an array. For example, `delete_at(['a','b','c'], 1)` returns ['a','c']. *Type*: rvalue. +#### `delete_regex` + +Deletes all instances of a given element from an array or hash that match a provided regular expression. A string will be treated as a one-item array. + +For example, `delete_regex(['a','b','c','b'], 'b')` returns ['a','c']; `delete_regex({'a' => 1,'b' => 2,'c' => 3},['b','c'])` returns {'a'=> 1}, `delete_regex(['abf', 'ab', 'ac'], '^ab.*')` returns ['ac']. `delete_regex(['ab', 'b'], 'b')` returns ['ab']. + +*Type*: rvalue. + #### `delete_values` Deletes all instances of a given value from a hash. For example, `delete_values({'a'=>'A','b'=>'B','c'=>'C','B'=>'D'}, 'B')` returns {'a'=>'A','c'=>'C','B'=>'D'} *Type*: rvalue. diff --git a/lib/puppet/parser/functions/delete.rb b/lib/puppet/parser/functions/delete.rb index 814e1ad..466c55c 100644 --- a/lib/puppet/parser/functions/delete.rb +++ b/lib/puppet/parser/functions/delete.rb @@ -20,12 +20,6 @@ string, or key from a hash. delete('abracadabra', 'bra') Would return: 'acada' - - delete(['abracadabra'], '^.*bra.*$') - Would return: [] - - delete(['abracadabra'], '^.*jimbob.*$') - Would return: ['abracadabra'] EOS ) do |arguments| @@ -36,7 +30,7 @@ string, or key from a hash. Array(arguments[1]).each do |item| case collection when Array, Hash - collection.reject! { |coll_item| (coll_item =~ %r{\b#{item}\b}) } + collection.delete item when String collection.gsub! item, '' else diff --git a/lib/puppet/parser/functions/delete_regex.rb b/lib/puppet/parser/functions/delete_regex.rb new file mode 100644 index 0000000..d72b3e9 --- /dev/null +++ b/lib/puppet/parser/functions/delete_regex.rb @@ -0,0 +1,45 @@ +# +# delete_regex.rb +# + +module Puppet::Parser::Functions + newfunction(:delete_regex, :type => :rvalue, :doc => <<-EOS +deletes all instances of a given element that match a regular expression +from an array or key from a hash. Multiple regular expressions are assumed +to be matched as an OR. + +*Examples:* + + delete_regex(['a','b','c','b'], 'b') + Would return: ['a','c'] + + delete_regex(['a','b','c','b'], ['b', 'c']) + Would return: ['a'] + + delete_regex({'a'=>1,'b'=>2,'c'=>3}, 'b') + Would return: {'a'=>1,'c'=>3} + + delete_regex({'a'=>1,'b'=>2,'c'=>3}, '^a$') + Would return: {'b'=>2,'c'=>3} + + EOS + ) do |arguments| + + raise(Puppet::ParseError, "delete_regex(): Wrong number of arguments "+ + "given #{arguments.size} for 2") unless arguments.size == 2 + + collection = arguments[0].dup + Array(arguments[1]).each do |item| + case collection + when Array, Hash, String + collection.reject! { |coll_item| (coll_item =~ %r{\b#{item}\b}) } + else + raise(TypeError, "delete_regex(): First argument must be an Array, " + + "Hash, or String. Given an argument of class #{collection.class}.") + end + end + collection + end +end + +# vim: set ts=2 sw=2 et : diff --git a/spec/functions/delete_regex_spec.rb b/spec/functions/delete_regex_spec.rb new file mode 100755 index 0000000..f27a946 --- /dev/null +++ b/spec/functions/delete_regex_spec.rb @@ -0,0 +1,54 @@ +require 'spec_helper' + +describe 'delete_regex' do + it { is_expected.not_to eq(nil) } + it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params([]).and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params([], 'two') } + it { is_expected.to run.with_params({}, 'two') } + it { is_expected.to run.with_params([], 'two', 'three').and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params([], 'two', 'three', 'four').and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params(1, 'two').and_raise_error(TypeError) } + + describe 'deleting from an array' do + it { is_expected.to run.with_params([], '').and_return([]) } + it { is_expected.to run.with_params([], 'two').and_return([]) } + it { is_expected.to run.with_params(['two'], 'two').and_return([]) } + it { is_expected.to run.with_params(['two', 'two'], 'two').and_return([]) } + it { is_expected.to run.with_params(['one', 'two', 'three'], '^t.*').and_return(['one']) } + it { is_expected.to run.with_params(['ab', 'b', 'c', 'b'], 'b').and_return(['ab', 'c']) } + it { is_expected.to run.with_params(['one', 'two', 'three'], 'four').and_return(['one', 'two', 'three']) } + it { is_expected.to run.with_params(['one', 'two', 'three'], 'e').and_return(['one', 'two', 'three']) } + it { is_expected.to run.with_params(['one', 'two', 'three'], 'two').and_return(['one', 'three']) } + it { is_expected.to run.with_params(['two', 'one', 'two', 'three', 'two'], 'two').and_return(['one', 'three']) } + it { is_expected.to run.with_params(['abracadabra'], 'abr').and_return(['abracadabra']) } + it { is_expected.to run.with_params(['abracadabra'], '^.*jimbob.*$').and_return(['abracadabra']) } + end + + describe 'deleting from an array' do + it { is_expected.to run.with_params({}, '').and_return({}) } + it { is_expected.to run.with_params({}, 'key').and_return({}) } + it { is_expected.to run.with_params({'key' => 'value'}, 'key').and_return({}) } + it { is_expected.to run \ + .with_params({'key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3'}, 'key2') \ + .and_return( {'key1' => 'value1', 'key3' => 'value3'}) + } + it { is_expected.to run \ + .with_params({'key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3'}, ['key1', 'key2']) \ + .and_return( {'key3' => 'value3'}) + } + end + + it "should leave the original array intact" do + argument1 = ['one','two','three'] + original1 = argument1.dup + subject.call([argument1,'two']) + expect(argument1).to eq(original1) + end + it "should leave the original hash intact" do + argument1 = {'key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3'} + original1 = argument1.dup + subject.call([argument1,'key2']) + expect(argument1).to eq(original1) + end +end diff --git a/spec/functions/delete_spec.rb b/spec/functions/delete_spec.rb index fd2a8ad..b44accf 100755 --- a/spec/functions/delete_spec.rb +++ b/spec/functions/delete_spec.rb @@ -13,15 +13,12 @@ describe 'delete' do it { is_expected.to run.with_params([], 'two').and_return([]) } it { is_expected.to run.with_params(['two'], 'two').and_return([]) } it { is_expected.to run.with_params(['two', 'two'], 'two').and_return([]) } - it { is_expected.to run.with_params(['one', 'two', 'three'], '^t.*').and_return(['one']) } it { is_expected.to run.with_params(['ab', 'b', 'c', 'b'], 'b').and_return(['ab', 'c']) } it { is_expected.to run.with_params(['one', 'two', 'three'], 'four').and_return(['one', 'two', 'three']) } it { is_expected.to run.with_params(['one', 'two', 'three'], 'e').and_return(['one', 'two', 'three']) } it { is_expected.to run.with_params(['one', 'two', 'three'], 'two').and_return(['one', 'three']) } it { is_expected.to run.with_params(['two', 'one', 'two', 'three', 'two'], 'two').and_return(['one', 'three']) } it { is_expected.to run.with_params(['one', 'two', 'three', 'two'], ['one', 'two']).and_return(['three']) } - it { is_expected.to run.with_params(['abracadabra'], 'abr').and_return(['abracadabra']) } - it { is_expected.to run.with_params(['abracadabra'], '^.*jimbob.*$').and_return(['abracadabra']) } end describe 'deleting from a string' do -- cgit v1.2.3