From 0d11bde5073d2976e9f5d9625757a7a71ddab6c4 Mon Sep 17 00:00:00 2001 From: Mathias Klette Date: Fri, 10 Oct 2014 22:54:22 +0200 Subject: ensure_resource: be more verbose in debug mode helps discovering duplication issues, especially when figthing boolean vs. string arguments --- lib/puppet/parser/functions/ensure_resource.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/puppet/parser/functions/ensure_resource.rb b/lib/puppet/parser/functions/ensure_resource.rb index 05e5593..1ba6a44 100644 --- a/lib/puppet/parser/functions/ensure_resource.rb +++ b/lib/puppet/parser/functions/ensure_resource.rb @@ -36,8 +36,9 @@ ENDOFDOC items.each do |item| Puppet::Parser::Functions.function(:defined_with_params) if function_defined_with_params(["#{type}[#{item}]", params]) - Puppet.debug("Resource #{type}[#{item}] not created because it already exists") + Puppet.debug("Resource #{type}[#{item}] with params #{params} not created because it already exists") else + Puppet.debug("Create new resource #{type}[#{item}] with params #{params}") Puppet::Parser::Functions.function(:create_resources) function_create_resources([type.capitalize, { item => params }]) end -- cgit v1.2.3 From b492115252ad381c4316b9ea85d8894ce348c4a7 Mon Sep 17 00:00:00 2001 From: jbondpdx Date: Thu, 20 Nov 2014 15:20:37 -0800 Subject: FM-1523: Added module summary to metadata.json --- metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/metadata.json b/metadata.json index 186166d..1a82f36 100644 --- a/metadata.json +++ b/metadata.json @@ -2,7 +2,7 @@ "name": "puppetlabs-stdlib", "version": "4.4.0", "author": "puppetlabs", - "summary": "Puppet Module Standard Library", + "summary": "Standard library of resources for Puppet modules.", "license": "Apache 2.0", "source": "git://github.com/puppetlabs/puppetlabs-stdlib", "project_page": "https://github.com/puppetlabs/puppetlabs-stdlib", -- cgit v1.2.3 From 89995e4db0eacf55260cf5ca85e715e2e45dfce5 Mon Sep 17 00:00:00 2001 From: Oliver Bertuch Date: Tue, 25 Nov 2014 12:45:23 +0100 Subject: Allow array of pathes in validate_absolute_path --- README.markdown | 49 +++++++++-------- .../parser/functions/validate_absolute_path.rb | 61 +++++++++++++--------- spec/functions/validate_absolute_path_spec.rb | 38 ++++++++++---- 3 files changed, 94 insertions(+), 54 deletions(-) diff --git a/README.markdown b/README.markdown index 78839c6..957be9b 100644 --- a/README.markdown +++ b/README.markdown @@ -461,27 +461,34 @@ You can also use this with arrays. For example, `unique(["a","a","b","b","c","c" * `uriescape`: Urlencodes a string or array of strings. Requires either a single string or an array as an input. *Type*: rvalue -* `validate_absolute_path`: Validate that the string represents an absolute path in the filesystem. This function works for Windows and Unix-style paths. - The following values will pass: - - ``` - $my_path = "C:/Program Files (x86)/Puppet Labs/Puppet" - validate_absolute_path($my_path) - $my_path2 = "/var/lib/puppet" - validate_absolute_path($my_path2) - ``` - - The following values will fail, causing compilation to abort: - - ``` - validate_absolute_path(true) - validate_absolute_path([ 'var/lib/puppet', '/var/foo' ]) - validate_absolute_path([ '/var/lib/puppet', 'var/foo' ]) - $undefined = undef - validate_absolute_path($undefined) - ``` - - *Type*: statement +* `validate_absolute_path`: Validate the string represents an absolute path in the filesystem. This function works for Windows and Unix style paths. + + The following values will pass: + + ``` + $my_path = 'C:/Program Files (x86)/Puppet Labs/Puppet' + validate_absolute_path($my_path) + $my_path2 = '/var/lib/puppet' + validate_absolute_path($my_path2) + $my_path3 = ['C:/Program Files (x86)/Puppet Labs/Puppet','C:/Program Files/Puppet Labs/Puppet'] + validate_absolute_path($my_path3) + $my_path4 = ['/var/lib/puppet','/usr/share/puppet'] + validate_absolute_path($my_path4) + ``` + + The following values will fail, causing compilation to abort: + + ``` + validate_absolute_path(true) + validate_absolute_path('../var/lib/puppet') + validate_absolute_path('var/lib/puppet') + validate_absolute_path([ 'var/lib/puppet', '/var/foo' ]) + validate_absolute_path([ '/var/lib/puppet', 'var/foo' ]) + $undefined = undef + validate_absolute_path($undefined) + ``` + + *Type*: statement * `validate_array`: Validate that all passed values are array data structures. Abort catalog compilation if any value fails this check. diff --git a/lib/puppet/parser/functions/validate_absolute_path.rb b/lib/puppet/parser/functions/validate_absolute_path.rb index fe27974..b696680 100644 --- a/lib/puppet/parser/functions/validate_absolute_path.rb +++ b/lib/puppet/parser/functions/validate_absolute_path.rb @@ -5,15 +5,20 @@ module Puppet::Parser::Functions The following values will pass: - $my_path = "C:/Program Files (x86)/Puppet Labs/Puppet" + $my_path = 'C:/Program Files (x86)/Puppet Labs/Puppet' validate_absolute_path($my_path) - $my_path2 = "/var/lib/puppet" + $my_path2 = '/var/lib/puppet' validate_absolute_path($my_path2) - + $my_path3 = ['C:/Program Files (x86)/Puppet Labs/Puppet','C:/Program Files/Puppet Labs/Puppet'] + validate_absolute_path($my_path3) + $my_path4 = ['/var/lib/puppet','/usr/share/puppet'] + validate_absolute_path($my_path4) The following values will fail, causing compilation to abort: validate_absolute_path(true) + validate_absolute_path('../var/lib/puppet') + validate_absolute_path('var/lib/puppet') validate_absolute_path([ 'var/lib/puppet', '/var/foo' ]) validate_absolute_path([ '/var/lib/puppet', 'var/foo' ]) $undefined = undef @@ -28,28 +33,36 @@ module Puppet::Parser::Functions end args.each do |arg| - # This logic was borrowed from - # [lib/puppet/file_serving/base.rb](https://github.com/puppetlabs/puppet/blob/master/lib/puppet/file_serving/base.rb) - - # Puppet 2.7 and beyond will have Puppet::Util.absolute_path? Fall back to a back-ported implementation otherwise. - if Puppet::Util.respond_to?(:absolute_path?) then - unless Puppet::Util.absolute_path?(arg, :posix) or Puppet::Util.absolute_path?(arg, :windows) - raise Puppet::ParseError, ("#{arg.inspect} is not an absolute path.") + # put arg to candidate var to be able to replace it + candidates = arg + # if arg is just a string with a path to test, convert it to an array + # to avoid test code duplication + unless arg.is_a?(Array) then + candidates = Array.new(1,arg) + end + # iterate over all pathes within the candidates array + candidates.each do |path| + # This logic was borrowed from + # [lib/puppet/file_serving/base.rb](https://github.com/puppetlabs/puppet/blob/master/lib/puppet/file_serving/base.rb) + # Puppet 2.7 and beyond will have Puppet::Util.absolute_path? Fall back to a back-ported implementation otherwise. + if Puppet::Util.respond_to?(:absolute_path?) then + unless Puppet::Util.absolute_path?(path, :posix) or Puppet::Util.absolute_path?(path, :windows) + raise Puppet::ParseError, ("#{path.inspect} is not an absolute path.") + end + else + # This code back-ported from 2.7.x's lib/puppet/util.rb Puppet::Util.absolute_path? + # Determine in a platform-specific way whether a path is absolute. This + # defaults to the local platform if none is specified. + # Escape once for the string literal, and once for the regex. + slash = '[\\\\/]' + name = '[^\\\\/]+' + regexes = { + :windows => %r!^(([A-Z]:#{slash})|(#{slash}#{slash}#{name}#{slash}#{name})|(#{slash}#{slash}\?#{slash}#{name}))!i, + :posix => %r!^/!, + } + rval = (!!(path =~ regexes[:posix])) || (!!(path =~ regexes[:windows])) + rval or raise Puppet::ParseError, ("#{path.inspect} is not an absolute path.") end - else - # This code back-ported from 2.7.x's lib/puppet/util.rb Puppet::Util.absolute_path? - # Determine in a platform-specific way whether a path is absolute. This - # defaults to the local platform if none is specified. - # Escape once for the string literal, and once for the regex. - slash = '[\\\\/]' - name = '[^\\\\/]+' - regexes = { - :windows => %r!^(([A-Z]:#{slash})|(#{slash}#{slash}#{name}#{slash}#{name})|(#{slash}#{slash}\?#{slash}#{name}))!i, - :posix => %r!^/!, - } - - rval = (!!(arg =~ regexes[:posix])) || (!!(arg =~ regexes[:windows])) - rval or raise Puppet::ParseError, ("#{arg.inspect} is not an absolute path.") end end end diff --git a/spec/functions/validate_absolute_path_spec.rb b/spec/functions/validate_absolute_path_spec.rb index 342ae84..36c836b 100755 --- a/spec/functions/validate_absolute_path_spec.rb +++ b/spec/functions/validate_absolute_path_spec.rb @@ -39,6 +39,11 @@ describe Puppet::Parser::Functions.function(:validate_absolute_path) do expect { subject.call [path] }.not_to raise_error end end + valid_paths do + it "validate_absolute_path(#{valid_paths.inspect}) should not fail" do + expect { subject.call [valid_paths] }.not_to raise_error + end + end end context "Puppet without mocking" do @@ -47,6 +52,11 @@ describe Puppet::Parser::Functions.function(:validate_absolute_path) do expect { subject.call [path] }.not_to raise_error end end + valid_paths do + it "validate_absolute_path(#{valid_paths.inspect}) should not fail" do + expect { subject.call [valid_paths] }.not_to raise_error + end + end end end @@ -55,6 +65,7 @@ describe Puppet::Parser::Functions.function(:validate_absolute_path) do [ nil, [ nil ], + [ nil, nil ], { 'foo' => 'bar' }, { }, '', @@ -66,19 +77,28 @@ describe Puppet::Parser::Functions.function(:validate_absolute_path) do end context 'Relative paths' do - %w{ - relative1 - . - .. - ./foo - ../foo - etc/puppetlabs/puppet - opt/puppet/bin - }.each do |path| + def self.rel_paths + %w{ + relative1 + . + .. + ./foo + ../foo + etc/puppetlabs/puppet + opt/puppet/bin + } + end + rel_paths.each do |path| it "validate_absolute_path(#{path.inspect}) should fail" do expect { subject.call [path] }.to raise_error Puppet::ParseError end end + rel_paths do + it "validate_absolute_path(#{rel_paths.inspect}) should fail" do + expect { subject.call [rel_paths] }.to raise_error Puppet::ParseError + end + end end end end + -- cgit v1.2.3 From 22bfa50cb9db0b724ac261cd242bfe3575e2cfcf Mon Sep 17 00:00:00 2001 From: jbondpdx Date: Thu, 20 Nov 2014 15:20:37 -0800 Subject: FM-1523: Added module summary to metadata.json --- metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/metadata.json b/metadata.json index f049cfb..6bdf82d 100644 --- a/metadata.json +++ b/metadata.json @@ -2,7 +2,7 @@ "name": "puppetlabs-stdlib", "version": "4.4.0", "author": "puppetlabs", - "summary": "Puppet Module Standard Library", + "summary": "Standard library of resources for Puppet modules.", "license": "Apache 2.0", "source": "git://github.com/puppetlabs/puppetlabs-stdlib", "project_page": "https://github.com/puppetlabs/puppetlabs-stdlib", -- cgit v1.2.3 From 294b8b572dfeb14555c40737eed2491e7837ef29 Mon Sep 17 00:00:00 2001 From: jbondpdx Date: Tue, 25 Nov 2014 11:32:12 -0800 Subject: Added a note that stdlib no longer ships with PE 3.7+ Users didn't realize we stopped shipping stdlib module with PE. I added this information to the stdlib readme. --- README.markdown | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.markdown b/README.markdown index 78839c6..b7824ff 100644 --- a/README.markdown +++ b/README.markdown @@ -27,6 +27,8 @@ modules. Puppet modules make heavy use of this standard library. The stdlib modu * Defined resource types * Types * Providers + +> *Note:* As of version 3.7, Puppet Enterprise no longer includes the stdlib module. If you're running Puppet Enterprise, you should install the most recent release of stdlib for compatibility with Puppet modules. ##Setup @@ -676,6 +678,8 @@ of the regular expressions match the string passed in, compilation aborts with a ##Limitations +As of Puppet Enterprise version 3.7, the stdlib module is no longer included in PE. PE users should install the most recent release of stdlib for compatibility with Puppet modules. + ###Version Compatibility Versions | Puppet 2.6 | Puppet 2.7 | Puppet 3.x | Puppet 4.x | -- cgit v1.2.3 From ed192a04648db7786d072bef23ed72849115d9de Mon Sep 17 00:00:00 2001 From: Peter Souter Date: Thu, 4 Dec 2014 14:12:55 +0000 Subject: (MODULES-444) Add specs for new behaviour `concat` can now take multiple arguments --- spec/functions/concat_spec.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/spec/functions/concat_spec.rb b/spec/functions/concat_spec.rb index 49cb2ad..4a18cd9 100755 --- a/spec/functions/concat_spec.rb +++ b/spec/functions/concat_spec.rb @@ -32,4 +32,14 @@ describe "the concat function" do result = scope.function_concat([array_original,['4','5','6']]) array_original.should(eq(['1','2','3'])) end + + it "should be able to concat multiple arrays" do + result = scope.function_concat([['1','2','3'],['4','5','6'],['7','8','9']]) + expect(result).to(eq(['1','2','3','4','5','6','7','8','9'])) + end + + it "should be able to concat mix of primitives and arrays to a final array" do + result = scope.function_concat([['1','2','3'],'4',['5','6','7']]) + expect(result).to(eq(['1','2','3','4','5','6','7'])) + end end -- cgit v1.2.3 From 7c570f75a5b88b1eb057bce3f7c4cad9cac83496 Mon Sep 17 00:00:00 2001 From: Peter Souter Date: Thu, 4 Dec 2014 14:15:03 +0000 Subject: (MODULES-444) Acceptance test for primitives `concat` should be able to concat arrays and primitives --- spec/acceptance/concat_spec.rb | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/spec/acceptance/concat_spec.rb b/spec/acceptance/concat_spec.rb index 7bda365..0d5e831 100755 --- a/spec/acceptance/concat_spec.rb +++ b/spec/acceptance/concat_spec.rb @@ -12,6 +12,17 @@ describe 'concat function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('oper } EOS + apply_manifest(pp, :catch_failures => true) + end + it 'should concat arrays and primitives to array' do + pp = <<-EOS + $output = concat(['1','2','3'],'4','5','6',['7','8','9']) + validate_array($output) + if size($output) != 9 { + fail("${output} should have 9 elements.") + } + EOS + apply_manifest(pp, :catch_failures => true) end end -- cgit v1.2.3 From 5e49c504580bf06353c841c51f1319a5bda893a8 Mon Sep 17 00:00:00 2001 From: Peter Souter Date: Thu, 4 Dec 2014 14:15:33 +0000 Subject: (MODULES-444) Acceptance for multiple arrays Acceptance test to take multiple arrays for concatenation --- spec/acceptance/concat_spec.rb | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/spec/acceptance/concat_spec.rb b/spec/acceptance/concat_spec.rb index 0d5e831..caf2f7d 100755 --- a/spec/acceptance/concat_spec.rb +++ b/spec/acceptance/concat_spec.rb @@ -23,6 +23,17 @@ describe 'concat function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('oper } EOS + apply_manifest(pp, :catch_failures => true) + end + it 'should concat multiple arrays to one' do + pp = <<-EOS + $output = concat(['1','2','3'],['4','5','6'],['7','8','9']) + validate_array($output) + if size($output) != 6 { + fail("${output} should have 9 elements.") + } + EOS + apply_manifest(pp, :catch_failures => true) end end -- cgit v1.2.3 From 7a1c4a6d9e4123a59fa85be18bd1b86ed5539b56 Mon Sep 17 00:00:00 2001 From: Peter Souter Date: Thu, 4 Dec 2014 14:27:38 +0000 Subject: (MODULES-444) Change test to > 2 arguments Also add extra test for just 1 argument --- spec/functions/concat_spec.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spec/functions/concat_spec.rb b/spec/functions/concat_spec.rb index 4a18cd9..d443c4b 100755 --- a/spec/functions/concat_spec.rb +++ b/spec/functions/concat_spec.rb @@ -4,8 +4,9 @@ require 'spec_helper' describe "the concat function" do let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - it "should raise a ParseError if the client does not provide two arguments" do + it "should raise a ParseError if the client does not provide at least two arguments" do expect { scope.function_concat([]) }.to(raise_error(Puppet::ParseError)) + expect { scope.function_concat([[1]]) }.to(raise_error(Puppet::ParseError)) end it "should raise a ParseError if the first parameter is not an array" do -- cgit v1.2.3 From 368c97f08046696d453afca6e1f8001b5bfc88a5 Mon Sep 17 00:00:00 2001 From: Peter Souter Date: Thu, 4 Dec 2014 14:27:55 +0000 Subject: (MODULES-444) - Check for accepting > 2 args --- spec/functions/concat_spec.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/spec/functions/concat_spec.rb b/spec/functions/concat_spec.rb index d443c4b..49fa6bb 100755 --- a/spec/functions/concat_spec.rb +++ b/spec/functions/concat_spec.rb @@ -13,6 +13,10 @@ describe "the concat function" do expect { scope.function_concat([1, []])}.to(raise_error(Puppet::ParseError)) end + it "should not raise a ParseError if the client provides more than two arguments" do + expect { scope.function_concat([[1],[2],[3]]) }.not_to raise_error + end + it "should be able to concat an array" do result = scope.function_concat([['1','2','3'],['4','5','6']]) expect(result).to(eq(['1','2','3','4','5','6'])) -- cgit v1.2.3 From 75a6186512b0d4d02593453fcc9ffe5e1b253107 Mon Sep 17 00:00:00 2001 From: Peter Souter Date: Thu, 4 Dec 2014 14:32:23 +0000 Subject: (MODULES-444) Update docs with new functionality --- lib/puppet/parser/functions/concat.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/puppet/parser/functions/concat.rb b/lib/puppet/parser/functions/concat.rb index 0d35b07..4b53f59 100644 --- a/lib/puppet/parser/functions/concat.rb +++ b/lib/puppet/parser/functions/concat.rb @@ -4,15 +4,15 @@ module Puppet::Parser::Functions newfunction(:concat, :type => :rvalue, :doc => <<-EOS -Appends the contents of array 2 onto array 1. +Appends the contents of multiple arrays into array 1. *Example:* - concat(['1','2','3'],['4','5','6']) + concat(['1','2','3'],['4','5','6'],['7','8','9']) Would result in: - ['1','2','3','4','5','6'] + ['1','2','3','4','5','6','7','8','9'] EOS ) do |arguments| -- cgit v1.2.3 From 594c2dd38dc35a4f458ce511be9b7dd875915b44 Mon Sep 17 00:00:00 2001 From: Peter Souter Date: Thu, 4 Dec 2014 14:33:23 +0000 Subject: (MODULES-444) Change argument restriction to < 2 --- lib/puppet/parser/functions/concat.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/puppet/parser/functions/concat.rb b/lib/puppet/parser/functions/concat.rb index 4b53f59..8400f7b 100644 --- a/lib/puppet/parser/functions/concat.rb +++ b/lib/puppet/parser/functions/concat.rb @@ -16,9 +16,9 @@ Would result in: EOS ) do |arguments| - # Check that 2 arguments have been given ... + # Check that more than 2 arguments have been given ... raise(Puppet::ParseError, "concat(): Wrong number of arguments " + - "given (#{arguments.size} for 2)") if arguments.size != 2 + "given (#{arguments.size} for < 2)") if arguments.size < 2 a = arguments[0] b = arguments[1] -- cgit v1.2.3 From 84bd98645f248a1dc3e0ed791e3af6f2ba9996fa Mon Sep 17 00:00:00 2001 From: Peter Souter Date: Thu, 4 Dec 2014 14:34:25 +0000 Subject: (MODULES-444) - Real meat of the change This is the core change, we now go through the array and add it to the first element, instead of just two arguments. --- lib/puppet/parser/functions/concat.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/puppet/parser/functions/concat.rb b/lib/puppet/parser/functions/concat.rb index 8400f7b..618e62d 100644 --- a/lib/puppet/parser/functions/concat.rb +++ b/lib/puppet/parser/functions/concat.rb @@ -21,14 +21,18 @@ Would result in: "given (#{arguments.size} for < 2)") if arguments.size < 2 a = arguments[0] - b = arguments[1] # Check that the first parameter is an array unless a.is_a?(Array) raise(Puppet::ParseError, 'concat(): Requires array to work with') end - result = a + Array(b) + result = a + arguments.shift + + arguments.each do |x| + result = result + Array(x) + end return result end -- cgit v1.2.3 From ef3d42f7bbdf95b21f46e580de309298cad300ea Mon Sep 17 00:00:00 2001 From: Rob Fugina Date: Mon, 17 Nov 2014 16:01:42 -0600 Subject: Added basename() based on Ruby's File.basename Based on dirname code. Includes RSpec tests and docs. --- README.markdown | 7 ++++ lib/puppet/parser/functions/basename.rb | 34 ++++++++++++++++ spec/unit/puppet/parser/functions/basename_spec.rb | 46 ++++++++++++++++++++++ 3 files changed, 87 insertions(+) create mode 100644 lib/puppet/parser/functions/basename.rb create mode 100755 spec/unit/puppet/parser/functions/basename_spec.rb diff --git a/README.markdown b/README.markdown index 78839c6..67ef313 100644 --- a/README.markdown +++ b/README.markdown @@ -84,6 +84,13 @@ If you want to use a standardized set of run stages for Puppet, `include stdlib` Requires an action ('encode', 'decode') and either a plain or base64-encoded string. *Type*: rvalue +* `basename`: Returns the `basename` of a path (optionally stripping an extension). For example: + * ('/path/to/a/file.ext') returns 'file.ext' + * ('relative/path/file.ext') returns 'file.ext' + * ('/path/to/a/file.ext', '.ext') returns 'file' + + *Type*: rvalue + * `bool2num`: Converts a boolean to a number. Converts values: * 'false', 'f', '0', 'n', and 'no' to 0. * 'true', 't', '1', 'y', and 'yes' to 1. diff --git a/lib/puppet/parser/functions/basename.rb b/lib/puppet/parser/functions/basename.rb new file mode 100644 index 0000000..f7e4438 --- /dev/null +++ b/lib/puppet/parser/functions/basename.rb @@ -0,0 +1,34 @@ +module Puppet::Parser::Functions + newfunction(:basename, :type => :rvalue, :doc => <<-EOS + Strips directory (and optional suffix) from a filename + EOS + ) do |arguments| + + if arguments.size < 1 then + raise(Puppet::ParseError, "basename(): No arguments given") + elsif arguments.size > 2 then + raise(Puppet::ParseError, "basename(): Too many arguments given (#{arguments.size})") + else + + unless arguments[0].is_a?(String) + raise(Puppet::ParseError, 'basename(): Requires string as first argument') + end + + if arguments.size == 1 then + rv = File.basename(arguments[0]) + elsif arguments.size == 2 then + + unless arguments[1].is_a?(String) + raise(Puppet::ParseError, 'basename(): Requires string as second argument') + end + + rv = File.basename(arguments[0], arguments[1]) + end + + end + + return rv + end +end + +# vim: set ts=2 sw=2 et : diff --git a/spec/unit/puppet/parser/functions/basename_spec.rb b/spec/unit/puppet/parser/functions/basename_spec.rb new file mode 100755 index 0000000..8a2d0dc --- /dev/null +++ b/spec/unit/puppet/parser/functions/basename_spec.rb @@ -0,0 +1,46 @@ +#! /usr/bin/env ruby -S rspec +require 'spec_helper' + +describe "the basename function" do + let(:scope) { PuppetlabsSpec::PuppetInternals.scope } + + it "should exist" do + Puppet::Parser::Functions.function("basename").should == "function_basename" + end + + it "should raise a ParseError if there is less than 1 argument" do + lambda { scope.function_basename([]) }.should( raise_error(Puppet::ParseError)) + end + + it "should raise a ParseError if there are more than 2 arguments" do + lambda { scope.function_basename(['a', 'b', 'c']) }.should( raise_error(Puppet::ParseError)) + end + + it "should return basename for an absolute path" do + result = scope.function_basename(['/path/to/a/file.ext']) + result.should(eq('file.ext')) + end + + it "should return basename for a relative path" do + result = scope.function_basename(['path/to/a/file.ext']) + result.should(eq('file.ext')) + end + + it "should strip extention when extension specified (absolute path)" do + result = scope.function_basename(['/path/to/a/file.ext', '.ext']) + result.should(eq('file')) + end + + it "should strip extention when extension specified (relative path)" do + result = scope.function_basename(['path/to/a/file.ext', '.ext']) + result.should(eq('file')) + end + + it "should complain about non-string first argument" do + lambda { scope.function_basename([[]]) }.should( raise_error(Puppet::ParseError)) + end + + it "should complain about non-string second argument" do + lambda { scope.function_basename(['/path/to/a/file.ext', []]) }.should( raise_error(Puppet::ParseError)) + end +end -- cgit v1.2.3 From 165caa8be195590bfd445b87db5fe2d0227d99ad Mon Sep 17 00:00:00 2001 From: Peter Souter Date: Tue, 9 Dec 2014 14:20:31 +0000 Subject: (MODULES-1582) Initial spike for % placeholder This simply `gsub`'s the file path into where the % placeholder is. --- lib/puppet/parser/functions/validate_cmd.rb | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/lib/puppet/parser/functions/validate_cmd.rb b/lib/puppet/parser/functions/validate_cmd.rb index c6136a5..7290265 100644 --- a/lib/puppet/parser/functions/validate_cmd.rb +++ b/lib/puppet/parser/functions/validate_cmd.rb @@ -6,9 +6,9 @@ module Puppet::Parser::Functions Perform validation of a string with an external command. The first argument of this function should be a string to test, and the second argument should be a path to a test command - taking a file as last argument. If the command, launched against - a tempfile containing the passed string, returns a non-null value, - compilation will abort with a parse error. + taking a % as a placeholder for the file path (will default to the end). + If the command, launched against a tempfile containing the passed string, + returns a non-null value, compilation will abort with a parse error. If a third argument is specified, this will be the error message raised and seen by the user. @@ -17,8 +17,12 @@ module Puppet::Parser::Functions Example: + # Defaults to end of path validate_cmd($sudoerscontent, '/usr/sbin/visudo -c -f', 'Visudo failed to validate sudoers content') + # % as file location + validate_cmd($haproxycontent, '/usr/sbin/haproxy -f % -c', 'Haproxy failed to validate config content') + ENDHEREDOC if (args.length < 2) or (args.length > 3) then raise Puppet::ParseError, ("validate_cmd(): wrong number of arguments (#{args.length}; must be 2 or 3)") @@ -34,10 +38,17 @@ module Puppet::Parser::Functions begin tmpfile.write(content) tmpfile.close + + if checkscript.include?('%') + check_with_correct_location = checkscript.gsub(/%/,tmpfile.path) + else + check_with_correct_location = "#{checkscript} #{tmpfile.path}" + end + if Puppet::Util::Execution.respond_to?('execute') - Puppet::Util::Execution.execute("#{checkscript} #{tmpfile.path}") + Puppet::Util::Execution.execute(check_with_correct_location) else - Puppet::Util.execute("#{checkscript} #{tmpfile.path}") + Puppet::Util.execute(check_with_correct_location) end rescue Puppet::ExecutionFailure => detail msg += "\n#{detail}" -- cgit v1.2.3 From cc8b147b5df539d1261508ed5c711a744d8584af Mon Sep 17 00:00:00 2001 From: Peter Souter Date: Tue, 9 Dec 2014 14:42:31 +0000 Subject: (MODULES-1582) Specs for the new % placeholder These specs are pretty much the same as the originals, but now check that the output has the correct replacement for file location --- spec/functions/validate_cmd_spec.rb | 81 +++++++++++++++++++++++++++---------- 1 file changed, 59 insertions(+), 22 deletions(-) diff --git a/spec/functions/validate_cmd_spec.rb b/spec/functions/validate_cmd_spec.rb index a6e68df..7cb9782 100755 --- a/spec/functions/validate_cmd_spec.rb +++ b/spec/functions/validate_cmd_spec.rb @@ -12,37 +12,74 @@ describe Puppet::Parser::Functions.function(:validate_cmd) do scope.method(function_name) end - describe "with an explicit failure message" do - it "prints the failure message on error" do - expect { - subject.call ['', '/bin/false', 'failure message!'] - }.to raise_error Puppet::ParseError, /failure message!/ + context 'with no % placeholder' do + describe "with an explicit failure message" do + it "prints the failure message on error" do + expect { + subject.call ['', '/bin/false', 'failure message!'] + }.to raise_error Puppet::ParseError, /failure message!/ + end end - end - describe "on validation failure" do - it "includes the command error output" do - expect { - subject.call ['', "#{TOUCHEXE} /cant/touch/this"] - }.to raise_error Puppet::ParseError, /(cannot touch|o such file or)/ + describe "on validation failure" do + it "includes the command error output" do + expect { + subject.call ['', "#{TOUCHEXE} /cant/touch/this"] + }.to raise_error Puppet::ParseError, /(cannot touch|o such file or)/ + end + + it "includes the command return value" do + expect { + subject.call ['', '/cant/run/this'] + }.to raise_error Puppet::ParseError, /returned 1\b/ + end end - it "includes the command return value" do - expect { - subject.call ['', '/cant/run/this'] - }.to raise_error Puppet::ParseError, /returned 1\b/ + describe "when performing actual validation" do + it "can positively validate file content" do + expect { subject.call ["non-empty", "#{TESTEXE} -s"] }.to_not raise_error + end + + it "can negatively validate file content" do + expect { + subject.call ["", "#{TESTEXE} -s"] + }.to raise_error Puppet::ParseError, /failed to validate.*test -s/ + end end end - describe "when performing actual validation" do - it "can positively validate file content" do - expect { subject.call ["non-empty", "#{TESTEXE} -s"] }.to_not raise_error + context 'with % placeholder' do + describe "with an explicit failure message" do + it "prints the failure message on error" do + expect { + subject.call ['', '/bin/false % -f', 'failure message!'] + }.to raise_error Puppet::ParseError, /failure message!/ + end end + describe "on validation failure" do + it "includes the command error output" do + expect { + subject.call ['', "#{TOUCHEXE} /cant/touch/this"] + }.to raise_error Puppet::ParseError, /(cannot touch|o such file or)/ + end + + it "includes the command return value" do + expect { + subject.call ['', '/cant/run/this % -z'] + }.to raise_error Puppet::ParseError, /Execution of '\/cant\/run\/this .+ -z' returned 1/ + end + end + + describe "when performing actual validation" do + it "can positively validate file content" do + expect { subject.call ["non-empty", "#{TESTEXE} -s %"] }.to_not raise_error + end - it "can negatively validate file content" do - expect { - subject.call ["", "#{TESTEXE} -s"] - }.to raise_error Puppet::ParseError, /failed to validate.*test -s/ + it "can negatively validate file content" do + expect { + subject.call ["", "#{TESTEXE} -s %"] + }.to raise_error Puppet::ParseError, /failed to validate.*test -s/ + end end end end -- cgit v1.2.3 From b3d007f1daa9bd7c8c02f372494df3a6e6ff6acf Mon Sep 17 00:00:00 2001 From: Peter Souter Date: Thu, 18 Dec 2014 23:08:13 +0000 Subject: (MODULES-1582) Improve % detection Avoids any validate commands that have %'s in them other than "... % ..." --- lib/puppet/parser/functions/validate_cmd.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/puppet/parser/functions/validate_cmd.rb b/lib/puppet/parser/functions/validate_cmd.rb index 7290265..5df3c60 100644 --- a/lib/puppet/parser/functions/validate_cmd.rb +++ b/lib/puppet/parser/functions/validate_cmd.rb @@ -39,7 +39,7 @@ module Puppet::Parser::Functions tmpfile.write(content) tmpfile.close - if checkscript.include?('%') + if checkscript =~ /\s%(\s|$)/ check_with_correct_location = checkscript.gsub(/%/,tmpfile.path) else check_with_correct_location = "#{checkscript} #{tmpfile.path}" -- cgit v1.2.3 From 31a6d894107f8f2ef4e0aec081f505d153e6297c Mon Sep 17 00:00:00 2001 From: Morgan Haskel Date: Thu, 18 Dec 2014 16:20:02 -0800 Subject: Fix bad check in test --- spec/acceptance/concat_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/acceptance/concat_spec.rb b/spec/acceptance/concat_spec.rb index caf2f7d..06b649f 100755 --- a/spec/acceptance/concat_spec.rb +++ b/spec/acceptance/concat_spec.rb @@ -29,7 +29,7 @@ describe 'concat function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('oper pp = <<-EOS $output = concat(['1','2','3'],['4','5','6'],['7','8','9']) validate_array($output) - if size($output) != 6 { + if size($output) != 9 { fail("${output} should have 9 elements.") } EOS -- cgit v1.2.3 From 8ec6f8dbfdaaa4b34030cbe1f4764c42c629240e Mon Sep 17 00:00:00 2001 From: Travis Fields Date: Fri, 19 Dec 2014 10:26:01 -0800 Subject: MODULES-1606 add ability to pass array to delete for items to delete --- lib/puppet/parser/functions/delete.rb | 24 ++++++++++++------------ spec/functions/delete_spec.rb | 31 ++++++++++++++++++------------- 2 files changed, 30 insertions(+), 25 deletions(-) diff --git a/lib/puppet/parser/functions/delete.rb b/lib/puppet/parser/functions/delete.rb index d03a293..a1e39ed 100644 --- a/lib/puppet/parser/functions/delete.rb +++ b/lib/puppet/parser/functions/delete.rb @@ -19,25 +19,25 @@ string, or key from a hash. delete('abracadabra', 'bra') Would return: 'acada' - EOS + EOS ) do |arguments| if (arguments.size != 2) then raise(Puppet::ParseError, "delete(): Wrong number of arguments "+ - "given #{arguments.size} for 2.") + "given #{arguments.size} for 2.") end collection = arguments[0].dup - item = arguments[1] - - case collection - when Array, Hash - collection.delete item - when String - collection.gsub! item, '' - else - raise(TypeError, "delete(): First argument must be an Array, " + - "String, or Hash. Given an argument of class #{collection.class}.") + Array(arguments[1]).each do |item| + case collection + when Array, Hash + collection.delete item + when String + collection.gsub! item, '' + else + raise(TypeError, "delete(): First argument must be an Array, " + + "String, or Hash. Given an argument of class #{collection.class}.") + end end collection end diff --git a/spec/functions/delete_spec.rb b/spec/functions/delete_spec.rb index 39b3176..c8edd78 100755 --- a/spec/functions/delete_spec.rb +++ b/spec/functions/delete_spec.rb @@ -9,48 +9,53 @@ describe "the delete function" do end it "should raise a ParseError if there are fewer than 2 arguments" do - expect { scope.function_delete([]) }.to( raise_error(Puppet::ParseError)) + expect { scope.function_delete([]) }.to(raise_error(Puppet::ParseError)) end it "should raise a ParseError if there are greater than 2 arguments" do - expect { scope.function_delete([[], 'foo', 'bar']) }.to( raise_error(Puppet::ParseError)) + expect { scope.function_delete([[], 'foo', 'bar']) }.to(raise_error(Puppet::ParseError)) end it "should raise a TypeError if a number is passed as the first argument" do - expect { scope.function_delete([1, 'bar']) }.to( raise_error(TypeError)) + expect { scope.function_delete([1, 'bar']) }.to(raise_error(TypeError)) end it "should delete all instances of an element from an array" do - result = scope.function_delete([['a','b','c','b'],'b']) - expect(result).to(eq(['a','c'])) + result = scope.function_delete([['a', 'b', 'c', 'b'], 'b']) + expect(result).to(eq(['a', 'c'])) end it "should delete all instances of a substring from a string" do - result = scope.function_delete(['foobarbabarz','bar']) + result = scope.function_delete(['foobarbabarz', 'bar']) expect(result).to(eq('foobaz')) end it "should delete a key from a hash" do - result = scope.function_delete([{ 'a' => 1, 'b' => 2, 'c' => 3 },'b']) - expect(result).to(eq({ 'a' => 1, 'c' => 3 })) + result = scope.function_delete([{'a' => 1, 'b' => 2, 'c' => 3}, 'b']) + expect(result).to(eq({'a' => 1, 'c' => 3})) + end + + it 'should accept an array of items to delete' do + result = scope.function_delete([{'a' => 1, 'b' => 2, 'c' => 3}, ['b', 'c']]) + expect(result).to(eq({'a' => 1})) end it "should not change origin array passed as argument" do - origin_array = ['a','b','c','d'] + origin_array = ['a', 'b', 'c', 'd'] result = scope.function_delete([origin_array, 'b']) - expect(origin_array).to(eq(['a','b','c','d'])) + expect(origin_array).to(eq(['a', 'b', 'c', 'd'])) end it "should not change the origin string passed as argument" do origin_string = 'foobarbabarz' - result = scope.function_delete([origin_string,'bar']) + result = scope.function_delete([origin_string, 'bar']) expect(origin_string).to(eq('foobarbabarz')) end it "should not change origin hash passed as argument" do - origin_hash = { 'a' => 1, 'b' => 2, 'c' => 3 } + origin_hash = {'a' => 1, 'b' => 2, 'c' => 3} result = scope.function_delete([origin_hash, 'b']) - expect(origin_hash).to(eq({ 'a' => 1, 'b' => 2, 'c' => 3 })) + expect(origin_hash).to(eq({'a' => 1, 'b' => 2, 'c' => 3})) end end -- cgit v1.2.3 From f6e20d20684f315d746e99ff554a0bdc714f96a3 Mon Sep 17 00:00:00 2001 From: Travis Fields Date: Fri, 19 Dec 2014 10:41:07 -0800 Subject: Update docs to reflect new behavior of delete function taking array in second argument --- README.markdown | 74 +++++++++++++++++------------------ lib/puppet/parser/functions/delete.rb | 3 ++ 2 files changed, 40 insertions(+), 37 deletions(-) diff --git a/README.markdown b/README.markdown index c4022c5..0c7b80a 100644 --- a/README.markdown +++ b/README.markdown @@ -14,7 +14,7 @@ ##Overview -Adds a standard library of resources for Puppet modules. +Adds a standard library of resources for Puppet modules. ##Module Description @@ -27,22 +27,22 @@ modules. Puppet modules make heavy use of this standard library. The stdlib modu * Defined resource types * Types * Providers - + > *Note:* As of version 3.7, Puppet Enterprise no longer includes the stdlib module. If you're running Puppet Enterprise, you should install the most recent release of stdlib for compatibility with Puppet modules. ##Setup -Installing the stdlib module adds the functions, facts, and resources of this standard library to Puppet. +Installing the stdlib module adds the functions, facts, and resources of this standard library to Puppet. ##Usage -After you've installed stdlib, all of its functions, facts, and resources are available for module use or development. +After you've installed stdlib, all of its functions, facts, and resources are available for module use or development. -If you want to use a standardized set of run stages for Puppet, `include stdlib` in your manifest. +If you want to use a standardized set of run stages for Puppet, `include stdlib` in your manifest. ## Reference -### Classes +### Classes #### Public Classes @@ -75,11 +75,11 @@ If you want to use a standardized set of run stages for Puppet, `include stdlib` class { java: stage => 'runtime' } } ``` - + ### Resources -* `file_line`: This resource ensures that a given line, including whitespace at the beginning and end, is contained within a file. If the line is not contained in the given file, Puppet will add the line. Multiple resources can be declared to manage multiple lines in the same file. You can also use match to replace existing lines. - +* `file_line`: This resource ensures that a given line, including whitespace at the beginning and end, is contained within a file. If the line is not contained in the given file, Puppet will add the line. Multiple resources can be declared to manage multiple lines in the same file. You can also use match to replace existing lines. + ``` file_line { 'sudo_rule': path => '/etc/sudoers', @@ -90,7 +90,7 @@ If you want to use a standardized set of run stages for Puppet, `include stdlib` line => '%sudonopw ALL=(ALL) NOPASSWD: ALL', } ``` - + * `after`: Specify the line after which Puppet will add any new lines. (Existing lines are added in place.) Optional. * `ensure`: Ensures whether the resource is present. Valid values are 'present', 'absent'. * `line`: The line to be added to the file located by the `path` parameter. @@ -98,7 +98,7 @@ If you want to use a standardized set of run stages for Puppet, `include stdlib` * `multiple`: Determine if match can change multiple lines. Valid values are 'true', 'false'. Optional. * `name`: An arbitrary name used as the identity of the resource. * `path`: The file in which Puppet will ensure the line specified by the line parameter. - + ### Functions * `abs`: Returns the absolute value of a number; for example, '-34.56' becomes '34.56'. Takes a single integer and float value as an argument. *Type*: rvalue @@ -144,11 +144,11 @@ strings; for example, 'hello\n' becomes 'hello'. Requires a single string or arr user { 'dan': ensure => present, } } ``` - + *Type*: rvalue * `delete`: 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'. *Type*: rvalue +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} *Type*: rvalue * `delete_at`: Deletes a determined indexed value from an array. For example, `delete_at(['a','b','c'], 1)` returns ['a','c']. *Type*: rvalue @@ -252,7 +252,7 @@ returns the value of the resource's parameter. For example, the following code r has_interface_with("macaddress", "x:x:x:x:x:x") has_interface_with("ipaddress", "127.0.0.1") => true ``` - + If no kind is given, then the presence of the interface is checked: ``` @@ -278,7 +278,7 @@ returns the value of the resource's parameter. For example, the following code r notice('this will be printed') } ``` - + *Type*: rvalue * `hash`: This function converts an array into a hash. For example, `hash(['a',1,'b',2,'c',3])` returns {'a'=>1,'b'=>2,'c'=>3}. *Type*: rvalue @@ -330,7 +330,7 @@ returns the value of the resource's parameter. For example, the following code r * `merge`: Merges two or more hashes together and returns the resulting hash. *Example*: - + ``` $hash1 = {'one' => 1, 'two' => 2} $hash2 = {'two' => 'dos', 'three' => 'tres'} @@ -338,7 +338,7 @@ returns the value of the resource's parameter. For example, the following code r # The resulting hash is equivalent to: # $merged_hash = {'one' => 1, 'two' => 'dos', 'three' => 'tres'} ``` - + When there is a duplicate key, the key in the rightmost hash "wins." *Type*: rvalue * `min`: Returns the lowest value of all arguments. Requires at least one argument. *Type*: rvalue @@ -354,7 +354,7 @@ returns the value of the resource's parameter. For example, the following code r ``` $real_jenkins_version = pick($::jenkins_version, '1.449') ``` - + *Type*: rvalue * `prefix`: This function applies a prefix to all elements in an array. For example, `prefix(['a','b','c'], 'p')` returns ['pa','pb','pc']. *Type*: rvalue @@ -366,9 +366,9 @@ Calling the class or definition from outside the current module will fail. For e ``` Class foo::bar is private ``` - + You can specify the error message you want to use: - + ``` private("You're not supposed to do that!") ``` @@ -377,8 +377,8 @@ Calling the class or definition from outside the current module will fail. For e * `range`: When given range in the form of '(start, stop)', `range` extrapolates a range as an array. For example, `range("0", "9")` returns [0,1,2,3,4,5,6,7,8,9]. Zero-padded strings are converted to integers automatically, so `range("00", "09")` returns [0,1,2,3,4,5,6,7,8,9]. - Non-integer strings are accepted; `range("a", "c")` returns ["a","b","c"], and `range("host01", "host10")` returns ["host01", "host02", ..., "host09", "host10"]. - + Non-integer strings are accepted; `range("a", "c")` returns ["a","b","c"], and `range("host01", "host10")` returns ["host01", "host02", ..., "host09", "host10"]. + *Type*: rvalue * `reject`: This function searches through an array and rejects all elements that match the provided regular expression. For example, `reject(['aaa','bbb','ccc','aaaddd'], 'aaa')` returns ['bbb','ccc']. *Type*: rvalue @@ -403,7 +403,7 @@ manifests as a valid password attribute. *Type*: rvalue * `strftime`: This function returns formatted time. For example, `strftime("%s")` returns the time since epoch, and `strftime("%Y=%m-%d")` returns the date. *Type*: rvalue *Format:* - + * `%a`: The abbreviated weekday name ('Sun') * `%A`: The full weekday name ('Sunday') * `%b`: The abbreviated month name ('Jan') @@ -501,9 +501,9 @@ You can also use this with arrays. For example, `unique(["a","a","b","b","c","c" validate_absolute_path($undefined) ``` - *Type*: statement + *Type*: statement -* `validate_array`: Validate that all passed values are array data structures. Abort catalog compilation if any value fails this check. +* `validate_array`: Validate that all passed values are array data structures. Abort catalog compilation if any value fails this check. The following values will pass: @@ -533,13 +533,13 @@ The first argument of this function should be the string to test, and the second ``` validate_augeas($passwdcontent, 'Passwd.lns', ['$file/foo']) ``` - + To ensure that no users use the '/bin/barsh' shell: ``` validate_augeas($passwdcontent, 'Passwd.lns', ['$file/*[shell="/bin/barsh"]'] ``` - + You can pass a fourth argument as the error message raised and shown to the user: ``` @@ -551,13 +551,13 @@ The first argument of this function should be the string to test, and the second * `validate_bool`: Validate that all passed values are either true or false. Abort catalog compilation if any value fails this check. The following values will pass: - + ``` $iamtrue = true validate_bool(true) validate_bool(true, true, false, $iamtrue) ``` - + The following values will fail, causing compilation to abort: ``` @@ -576,7 +576,7 @@ The first argument of this function should be the string to test, and the second ``` validate_cmd($sudoerscontent, '/usr/sbin/visudo -c -f', 'Visudo failed to validate sudoers content') ``` - + *Type*: statement * `validate_hash`: Validates that all passed values are hash data structures. Abort catalog compilation if any value fails this check. @@ -596,7 +596,7 @@ The first argument of this function should be the string to test, and the second $undefined = undef validate_hash($undefined) ``` - + *Type*: statement * `validate_re`: Performs simple validation of a string against one or more regular expressions. The first argument of this function should be the string to @@ -619,8 +619,8 @@ of the regular expressions match the string passed in, compilation aborts with a validate_re('one', [ '^two', '^three' ]) ``` - To set the error message: - + To set the error message: + ``` validate_re($::puppetversion, '^2.7', 'The $puppetversion fact value does not match 2.7') ``` @@ -630,19 +630,19 @@ of the regular expressions match the string passed in, compilation aborts with a * `validate_slength`: Validates that the first argument is a string (or an array of strings), and is less than or equal to the length of the second argument. It fails if the first argument is not a string or array of strings, or if arg 2 is not convertable to a number. The following values pass: - + ``` validate_slength("discombobulate",17) validate_slength(["discombobulate","moo"],17) ``` - + The following values fail: ``` validate_slength("discombobulate",1) validate_slength(["discombobulate","thermometer"],5) ``` - + *Type*: statement * `validate_string`: Validates that all passed values are string data structures. Aborts catalog compilation if any value fails this check. @@ -700,7 +700,7 @@ As of Puppet Enterprise version 3.7, the stdlib module is no longer included in ###Version Compatibility -Versions | Puppet 2.6 | Puppet 2.7 | Puppet 3.x | Puppet 4.x | +Versions | Puppet 2.6 | Puppet 2.7 | Puppet 3.x | Puppet 4.x | :---------------|:-----:|:---:|:---:|:----: **stdlib 2.x** | **yes** | **yes** | no | no **stdlib 3.x** | no | **yes** | **yes** | no diff --git a/lib/puppet/parser/functions/delete.rb b/lib/puppet/parser/functions/delete.rb index a1e39ed..f548b44 100644 --- a/lib/puppet/parser/functions/delete.rb +++ b/lib/puppet/parser/functions/delete.rb @@ -17,6 +17,9 @@ string, or key from a hash. delete({'a'=>1,'b'=>2,'c'=>3}, 'b') Would return: {'a'=>1,'c'=>3} + delete({'a'=>1,'b'=>2,'c'=>3}, ['b','c']) + Would return: {'a'=>1} + delete('abracadabra', 'bra') Would return: 'acada' EOS -- cgit v1.2.3 From c125a0899435b26f7823bdf3793b4aeb27f4a707 Mon Sep 17 00:00:00 2001 From: Peter Souter Date: Fri, 19 Dec 2014 11:52:11 +0000 Subject: README fixes for recent merges * (MODULES-444) Update README for concat changes * (MODULES-1582) Update `validate_cmd` readme * Plus some Whitespace fixes --- README.markdown | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/README.markdown b/README.markdown index 0c7b80a..689660e 100644 --- a/README.markdown +++ b/README.markdown @@ -129,7 +129,9 @@ strings; for example, 'hello\n' becomes 'hello'. Requires a single string or arr * `chop`: Returns a new string with the last character removed. If the string ends with '\r\n', both characters are removed. Applying `chop` to an empty string returns an empty string. If you want to merely remove record separators, then you should use the `chomp` function. Requires a string or an array of strings as input. *Type*: rvalue -* `concat`: Appends the contents of array 2 onto array 1. For example, `concat(['1','2','3'],'4')` results in: ['1','2','3','4']. *Type*: rvalue +* `concat`: Appends the contents of multiple arrays onto array 1. For example: + * `concat(['1','2','3'],'4')` results in: ['1','2','3','4']. + * `concat(['1','2','3'],'4',['5','6','7'])` results in: ['1','2','3','4','5','6','7']. * `count`: Takes an array as first argument and an optional second argument. Count the number of elements in array that matches second argument. If called with only an array, it counts the number of elements that are **not** nil/undef. *Type*: rvalue @@ -569,13 +571,18 @@ The first argument of this function should be the string to test, and the second *Type*: statement -* `validate_cmd`: Performs validation of a string with an external command. The first argument of this function should be the string to test, and the second argument should be the path to a test command taking a file as last argument. If the command, launched against a tempfile containing the passed string, returns a non-null value, compilation aborts with a parse error. +* `validate_cmd`: Performs validation of a string with an external command. The first argument of this function should be a string to test, and the second argument should be a path to a test command taking a % as a placeholder for the file path (will default to the end of the command if no % placeholder given). If the command, launched against a tempfile containing the passed string, returns a non-null value, compilation will abort with a parse error. - You can pass a third argument as the error message raised and shown to the user: +If a third argument is specified, this will be the error message raised and seen by the user. ``` + # Defaults to end of path validate_cmd($sudoerscontent, '/usr/sbin/visudo -c -f', 'Visudo failed to validate sudoers content') ``` + ``` + # % as file location + validate_cmd($haproxycontent, '/usr/sbin/haproxy -f % -c', 'Haproxy failed to validate config content') + ``` *Type*: statement -- cgit v1.2.3 From 9077bfef1e3313b7cd7f89cfec95132466730325 Mon Sep 17 00:00:00 2001 From: Colleen Murphy Date: Mon, 29 Dec 2014 10:41:22 -0800 Subject: Add IntelliJ files to the ignore list --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index b5b7a00..b5db85e 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,5 @@ spec/fixtures/ .vagrant/ .bundle/ coverage/ +.idea/ +*.iml -- cgit v1.2.3 From 7c8ae311cade65e84df1054779a039ff906e630c Mon Sep 17 00:00:00 2001 From: Hunter Haugen Date: Mon, 15 Dec 2014 16:11:10 -0800 Subject: (MODULES-1473) Deprecate type() function for new parser The `type()` function will cease to work on the new parser because 'type' is a reserved keyword. The `type3x()` function may be used to continue similar functionality, but will be deprecated in favor of the built-in typing system. The `type_of()` function has been included to introspect types in the new parser. --- .fixtures.yml | 3 ++ .travis.yml | 1 + README.markdown | 7 +++- lib/puppet/functions/type_of.rb | 17 ++++++++++ lib/puppet/parser/functions/type.rb | 43 ++++--------------------- lib/puppet/parser/functions/type3x.rb | 51 ++++++++++++++++++++++++++++++ spec/functions/type3x_spec.rb | 43 +++++++++++++++++++++++++ spec/functions/type_spec.rb | 5 +-- spec/unit/puppet/functions/type_of_spec.rb | 33 +++++++++++++++++++ 9 files changed, 163 insertions(+), 40 deletions(-) create mode 100644 .fixtures.yml create mode 100644 lib/puppet/functions/type_of.rb create mode 100644 lib/puppet/parser/functions/type3x.rb create mode 100644 spec/functions/type3x_spec.rb create mode 100644 spec/unit/puppet/functions/type_of_spec.rb diff --git a/.fixtures.yml b/.fixtures.yml new file mode 100644 index 0000000..37b7377 --- /dev/null +++ b/.fixtures.yml @@ -0,0 +1,3 @@ +fixtures: + symlinks: + stdlib: "#{source_dir}" diff --git a/.travis.yml b/.travis.yml index f531306..503e184 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,5 @@ --- +sudo: false language: ruby bundler_args: --without system_tests script: "bundle exec rake validate && bundle exec rake lint && bundle exec rake spec SPEC_OPTS='--color --format documentation'" diff --git a/README.markdown b/README.markdown index 689660e..e9a1f4e 100644 --- a/README.markdown +++ b/README.markdown @@ -464,7 +464,12 @@ manifests as a valid password attribute. *Type*: rvalue * `to_bytes`: Converts the argument into bytes, for example 4 kB becomes 4096. Takes a single string value as an argument. *Type*: rvalue -* `type`: Returns the type when passed a variable. Type can be a string, array, hash, float, integer, or boolean. *Type*: rvalue +* `type3x`: Returns a string description of the type when passed a value. Type can be a string, array, hash, float, integer, or boolean. This function will be removed when puppet 3 support is dropped and the new type system may be used. *Type*: rvalue + +* `type_of`: Returns the literal type when passed a value. Requires the new + parser. Useful for comparison of types with `<=` such as in `if + type_of($some_value) <= Array[String] { ... }` (which is equivalent to `if + $some_value =~ Array[String] { ... }`) *Type*: rvalue * `union`: This function returns a union of two arrays. For example, `union(["a","b","c"],["b","c","d"])` returns ["a","b","c","d"]. diff --git a/lib/puppet/functions/type_of.rb b/lib/puppet/functions/type_of.rb new file mode 100644 index 0000000..02cdd4d --- /dev/null +++ b/lib/puppet/functions/type_of.rb @@ -0,0 +1,17 @@ +# Returns the type when passed a value. +# +# @example how to compare values' types +# # compare the types of two values +# if type_of($first_value) != type_of($second_value) { fail("first_value and second_value are different types") } +# @example how to compare against an abstract type +# unless type_of($first_value) <= Numeric { fail("first_value must be Numeric") } +# unless type_of{$first_value) <= Collection[1] { fail("first_value must be an Array or Hash, and contain at least one element") } +# +# See the documentation for "The Puppet Type System" for more information about types. +# See the `assert_type()` function for flexible ways to assert the type of a value. +# +Puppet::Functions.create_function(:type_of) do + def type_of(value) + Puppet::Pops::Types::TypeCalculator.infer_set(value) + end +end diff --git a/lib/puppet/parser/functions/type.rb b/lib/puppet/parser/functions/type.rb index 8d85f11..016529b 100644 --- a/lib/puppet/parser/functions/type.rb +++ b/lib/puppet/parser/functions/type.rb @@ -4,46 +4,15 @@ module Puppet::Parser::Functions newfunction(:type, :type => :rvalue, :doc => <<-EOS -Returns the type when passed a variable. Type can be one of: - -* string -* array -* hash -* float -* integer -* boolean + DEPRECATED: This function will cease to function on Puppet 4; please use type3x() before upgrading to puppet 4 for backwards-compatibility, or migrate to the new parser's typing system. EOS - ) do |arguments| - - raise(Puppet::ParseError, "type(): Wrong number of arguments " + - "given (#{arguments.size} for 1)") if arguments.size < 1 - - value = arguments[0] - - klass = value.class - - if not [TrueClass, FalseClass, Array, Bignum, Fixnum, Float, Hash, String].include?(klass) - raise(Puppet::ParseError, 'type(): Unknown type') - end - - klass = klass.to_s # Ugly ... + ) do |args| - # We note that Integer is the parent to Bignum and Fixnum ... - result = case klass - when /^(?:Big|Fix)num$/ then 'integer' - when /^(?:True|False)Class$/ then 'boolean' - else klass + warning("type() DEPRECATED: This function will cease to function on Puppet 4; please use type3x() before upgrading to puppet 4 for backwards-compatibility, or migrate to the new parser's typing system.") + if ! Puppet::Parser::Functions.autoloader.loaded?(:type3x) + Puppet::Parser::Functions.autoloader.load(:type3x) end - - if result == "String" then - if value == value.to_i.to_s then - result = "Integer" - elsif value == value.to_f.to_s then - result = "Float" - end - end - - return result.downcase + function_type3x(args + [false]) end end diff --git a/lib/puppet/parser/functions/type3x.rb b/lib/puppet/parser/functions/type3x.rb new file mode 100644 index 0000000..0800b4a --- /dev/null +++ b/lib/puppet/parser/functions/type3x.rb @@ -0,0 +1,51 @@ +# +# type3x.rb +# + +module Puppet::Parser::Functions + newfunction(:type3x, :type => :rvalue, :doc => <<-EOS +DEPRECATED: This function will be removed when puppet 3 support is dropped; please migrate to the new parser's typing system. + +Returns the type when passed a value. Type can be one of: + +* string +* array +* hash +* float +* integer +* boolean + EOS + ) do |args| + raise(Puppet::ParseError, "type3x(): Wrong number of arguments " + + "given (#{args.size} for 1)") if args.size < 1 + + value = args[0] + + klass = value.class + + if not [TrueClass, FalseClass, Array, Bignum, Fixnum, Float, Hash, String].include?(klass) + raise(Puppet::ParseError, 'type3x(): Unknown type') + end + + klass = klass.to_s # Ugly ... + + # We note that Integer is the parent to Bignum and Fixnum ... + result = case klass + when /^(?:Big|Fix)num$/ then 'integer' + when /^(?:True|False)Class$/ then 'boolean' + else klass + end + + if result == "String" then + if value == value.to_i.to_s then + result = "Integer" + elsif value == value.to_f.to_s then + result = "Float" + end + end + + return result.downcase + end +end + +# vim: set ts=2 sw=2 et : diff --git a/spec/functions/type3x_spec.rb b/spec/functions/type3x_spec.rb new file mode 100644 index 0000000..d21236a --- /dev/null +++ b/spec/functions/type3x_spec.rb @@ -0,0 +1,43 @@ +#! /usr/bin/env ruby -S rspec +require 'spec_helper' + +describe "the type3x function" do + let(:scope) { PuppetlabsSpec::PuppetInternals.scope } + it "should exist" do + expect(Puppet::Parser::Functions.function("type3x")).to eq("function_type3x") + end + + it "should raise a ParseError if there is less than 1 arguments" do + expect { scope.function_type3x([]) }.to( raise_error(Puppet::ParseError)) + end + + it "should return string when given a string" do + result = scope.function_type3x(["aaabbbbcccc"]) + expect(result).to(eq('string')) + end + + it "should return array when given an array" do + result = scope.function_type3x([["aaabbbbcccc","asdf"]]) + expect(result).to(eq('array')) + end + + it "should return hash when given a hash" do + result = scope.function_type3x([{"a"=>1,"b"=>2}]) + expect(result).to(eq('hash')) + end + + it "should return integer when given an integer" do + result = scope.function_type3x(["1"]) + expect(result).to(eq('integer')) + end + + it "should return float when given a float" do + result = scope.function_type3x(["1.34"]) + expect(result).to(eq('float')) + end + + it "should return boolean when given a boolean" do + result = scope.function_type3x([true]) + expect(result).to(eq('boolean')) + end +end diff --git a/spec/functions/type_spec.rb b/spec/functions/type_spec.rb index 9dfe9d7..b683fcf 100755 --- a/spec/functions/type_spec.rb +++ b/spec/functions/type_spec.rb @@ -7,8 +7,9 @@ describe "the type function" do expect(Puppet::Parser::Functions.function("type")).to eq("function_type") end - it "should raise a ParseError if there is less than 1 arguments" do - expect { scope.function_type([]) }.to( raise_error(Puppet::ParseError)) + it "should give a deprecation warning when called" do + scope.expects(:warning).with("type() DEPRECATED: This function will cease to function on Puppet 4; please use type3x() before upgrading to puppet 4 for backwards-compatibility, or migrate to the new parser's typing system.") + scope.function_type(["aoeu"]) end it "should return string when given a string" do diff --git a/spec/unit/puppet/functions/type_of_spec.rb b/spec/unit/puppet/functions/type_of_spec.rb new file mode 100644 index 0000000..8afb624 --- /dev/null +++ b/spec/unit/puppet/functions/type_of_spec.rb @@ -0,0 +1,33 @@ +#! /usr/bin/env ruby -S rspec + +require 'spec_helper' + +if ENV["FUTURE_PARSER"] == 'yes' or Puppet.version >= "4" + require 'puppet/pops' + require 'puppet/loaders' + + describe 'the type_of function' do + before(:all) do + loaders = Puppet::Pops::Loaders.new(Puppet::Node::Environment.create(:testing, [File.join(fixtures, "modules")])) + Puppet.push_context({:loaders => loaders}, "test-examples") + end + + after(:all) do + Puppet::Pops::Loaders.clear + Puppet::pop_context() + end + + let(:func) do + # Load the function from the environment modulepath's modules (ie, fixtures) + Puppet.lookup(:loaders).private_environment_loader.load(:function, 'type_of') + end + + it 'gives the type of a string' do + expect(func.call({}, 'hello world')).to be_kind_of(Puppet::Pops::Types::PStringType) + end + + it 'gives the type of an integer' do + expect(func.call({}, 5)).to be_kind_of(Puppet::Pops::Types::PIntegerType) + end + end +end -- cgit v1.2.3 From b11311ad65c925c074e6a0b34d8182b70c570225 Mon Sep 17 00:00:00 2001 From: Travis Fields Date: Fri, 9 Jan 2015 14:09:03 -0800 Subject: FM-2130 Move cache file to non temp directory --- lib/facter/facter_dot_d.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/facter/facter_dot_d.rb b/lib/facter/facter_dot_d.rb index 2c096b0..b058437 100644 --- a/lib/facter/facter_dot_d.rb +++ b/lib/facter/facter_dot_d.rb @@ -15,7 +15,7 @@ class Facter::Util::DotD require 'yaml' - def initialize(dir="/etc/facts.d", cache_file="/tmp/facts_cache.yml") + def initialize(dir="/etc/facts.d", cache_file=File.join(Puppet[:libdir], "facts_dot_d.cache")) @dir = dir @cache_file = cache_file @cache = nil @@ -23,7 +23,7 @@ class Facter::Util::DotD end def entries - Dir.entries(@dir).reject{|f| f =~ /^\.|\.ttl$/}.sort.map {|f| File.join(@dir, f) } + Dir.entries(@dir).reject { |f| f =~ /^\.|\.ttl$/ }.sort.map { |f| File.join(@dir, f) } rescue [] end @@ -113,7 +113,7 @@ class Facter::Util::DotD def cache_save! cache = load_cache - File.open(@cache_file, "w", 0600) {|f| f.write(YAML.dump(cache)) } + File.open(@cache_file, "w", 0600) { |f| f.write(YAML.dump(cache)) } rescue end -- cgit v1.2.3