From 6e7e69fe203e042b28aacb01301c338d55448c5f Mon Sep 17 00:00:00 2001 From: tphoney Date: Wed, 3 Aug 2016 17:06:25 +0100 Subject: (modules-3533) deprecation for 3.x number function --- .fixtures.yml | 1 + Gemfile | 4 +++- Rakefile | 6 ++++- lib/puppet/parser/functions/deprecation.rb | 15 ++++++++++++ lib/puppet/parser/functions/is_float.rb | 2 ++ lib/puppet/parser/functions/is_integer.rb | 2 ++ lib/puppet/parser/functions/is_numeric.rb | 4 ++-- lib/puppet/parser/functions/validate_integer.rb | 2 ++ lib/puppet/parser/functions/validate_numeric.rb | 2 ++ spec/aliases/float_spec.rb | 28 ++++++++++++++++++++++ spec/aliases/integer_spec.rb | 28 ++++++++++++++++++++++ spec/aliases/numeric_spec.rb | 32 +++++++++++++++++++++++++ spec/fixtures/modules/test/manifests/float.pp | 8 +++++++ spec/fixtures/modules/test/manifests/integer.pp | 8 +++++++ spec/fixtures/modules/test/manifests/numeric.pp | 8 +++++++ spec/functions/deprecation_spec.rb | 18 +++++++------- spec/functions/is_float_spec.rb | 7 ++++++ spec/functions/is_integer_spec.rb | 7 ++++++ spec/functions/is_numeric_spec.rb | 7 ++++++ spec/functions/validate_integer_spec.rb | 6 +++++ spec/functions/validate_numeric_spec.rb | 6 +++++ types/compat/float.pp | 19 +++++++++++++++ types/compat/integer.pp | 23 ++++++++++++++++++ types/compat/numeric.pp | 23 ++++++++++++++++++ 24 files changed, 254 insertions(+), 12 deletions(-) create mode 100644 lib/puppet/parser/functions/deprecation.rb create mode 100644 spec/aliases/float_spec.rb create mode 100644 spec/aliases/integer_spec.rb create mode 100644 spec/aliases/numeric_spec.rb create mode 100644 spec/fixtures/modules/test/manifests/float.pp create mode 100644 spec/fixtures/modules/test/manifests/integer.pp create mode 100644 spec/fixtures/modules/test/manifests/numeric.pp create mode 100644 types/compat/float.pp create mode 100644 types/compat/integer.pp create mode 100644 types/compat/numeric.pp diff --git a/.fixtures.yml b/.fixtures.yml index 37b7377..a28e653 100644 --- a/.fixtures.yml +++ b/.fixtures.yml @@ -1,3 +1,4 @@ fixtures: symlinks: stdlib: "#{source_dir}" + test: "#{source_dir}/spec/fixtures/test" diff --git a/Gemfile b/Gemfile index c7da908..0fc6c18 100644 --- a/Gemfile +++ b/Gemfile @@ -16,7 +16,7 @@ group :development, :unit_tests do gem 'metadata-json-lint', :require => false gem 'puppet_facts', :require => false gem 'puppet-blacksmith', '>= 3.4.0', :require => false - gem 'puppetlabs_spec_helper', :require => false + gem 'puppetlabs_spec_helper', :git => 'git://github.com/puppetlabs/puppetlabs_spec_helper.git', :ref => '157a7fd', :require => false gem 'rspec-puppet', '>= 2.3.2', :require => false gem 'simplecov', :require => false end @@ -32,6 +32,8 @@ end # json_pure 2.0.2 added a requirement on ruby >= 2. We pin to json_pure 2.0.1 # if using ruby 1.x gem 'json_pure', '<=2.0.1', :require => false if RUBY_VERSION =~ /^1\./ +# rubocop 0.42.0 requires ruby >=2 +gem 'rubocop', '0.41.2', :require => false if RUBY_VERSION =~ /^1\./ gem 'facter', *location_for(ENV['FACTER_GEM_VERSION']) gem 'puppet', *location_for(ENV['PUPPET_GEM_VERSION']) diff --git a/Rakefile b/Rakefile index 8906d23..47a671e 100644 --- a/Rakefile +++ b/Rakefile @@ -8,7 +8,11 @@ PuppetLint.configuration.send('disable_140chars') PuppetLint.configuration.send('disable_class_inherits_from_params_class') PuppetLint.configuration.send('disable_documentation') PuppetLint.configuration.send('disable_single_quote_string_with_variables') -PuppetLint.configuration.ignore_paths = ["spec/**/*.pp", "pkg/**/*.pp", "bundle/**/*", "vendor/**/*"] +PuppetLint.configuration.ignore_paths = ["spec/**/*.pp", "pkg/**/*.pp", "bundle/**/*", "vendor/**/*", "types/**/*"] + +if Puppet.version.to_f < 4.0 + PuppetSyntax.exclude_paths << "types/**/*" +end desc 'Generate pooler nodesets' task :gen_nodeset do diff --git a/lib/puppet/parser/functions/deprecation.rb b/lib/puppet/parser/functions/deprecation.rb new file mode 100644 index 0000000..5d74984 --- /dev/null +++ b/lib/puppet/parser/functions/deprecation.rb @@ -0,0 +1,15 @@ +module Puppet::Parser::Functions + newfunction(:deprecation, :type => :rvalue, :doc => <<-EOS + Function to print deprecation warnings (this is the 3.X version of it), The uniqueness key - can appear once. The msg is the message text including any positional information that is formatted by the user/caller of the method.). +EOS + ) do |arguments| + + raise(Puppet::ParseError, "deprecation: Wrong number of arguments " + + "given (#{arguments.size} for 2)") unless arguments.size == 2 + + key = arguments[0] + message = arguments[1] + + warn("deprecation. #{key}. #{message}") + end +end diff --git a/lib/puppet/parser/functions/is_float.rb b/lib/puppet/parser/functions/is_float.rb index a2da943..5233e40 100644 --- a/lib/puppet/parser/functions/is_float.rb +++ b/lib/puppet/parser/functions/is_float.rb @@ -8,6 +8,8 @@ Returns true if the variable passed to this function is a float. EOS ) do |arguments| + function_deprecation([:puppet_3_type_check, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Float. There is further documentation for validate_legacy function in the README.']) + if (arguments.size != 1) then raise(Puppet::ParseError, "is_float(): Wrong number of arguments "+ "given #{arguments.size} for 1") diff --git a/lib/puppet/parser/functions/is_integer.rb b/lib/puppet/parser/functions/is_integer.rb index c03d28d..e04fd1f 100644 --- a/lib/puppet/parser/functions/is_integer.rb +++ b/lib/puppet/parser/functions/is_integer.rb @@ -13,6 +13,8 @@ If given any other argument `false` is returned. EOS ) do |arguments| + function_deprecation([:is_integer, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Integer. There is further documentation for validate_legacy function in the README.']) + if (arguments.size != 1) then raise(Puppet::ParseError, "is_integer(): Wrong number of arguments "+ "given #{arguments.size} for 1") diff --git a/lib/puppet/parser/functions/is_numeric.rb b/lib/puppet/parser/functions/is_numeric.rb index e7e1d2a..2bdd353 100644 --- a/lib/puppet/parser/functions/is_numeric.rb +++ b/lib/puppet/parser/functions/is_numeric.rb @@ -24,6 +24,8 @@ Valid examples: EOS ) do |arguments| + function_deprecation([:puppet_3_type_check, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Numeric. There is further documentation for validate_legacy function in the README.']) + if (arguments.size != 1) then raise(Puppet::ParseError, "is_numeric(): Wrong number of arguments "+ "given #{arguments.size} for 1") @@ -71,5 +73,3 @@ Valid examples: end end end - -# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/validate_integer.rb b/lib/puppet/parser/functions/validate_integer.rb index a950916..f52e053 100644 --- a/lib/puppet/parser/functions/validate_integer.rb +++ b/lib/puppet/parser/functions/validate_integer.rb @@ -53,6 +53,8 @@ module Puppet::Parser::Functions ENDHEREDOC + function_deprecation([:puppet_3_type_check, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Integer. There is further documentation for validate_legacy function in the README.']) + # tell the user we need at least one, and optionally up to two other parameters raise Puppet::ParseError, "validate_integer(): Wrong number of arguments; must be 1, 2 or 3, got #{args.length}" unless args.length > 0 and args.length < 4 diff --git a/lib/puppet/parser/functions/validate_numeric.rb b/lib/puppet/parser/functions/validate_numeric.rb index 3a14443..6b55f49 100644 --- a/lib/puppet/parser/functions/validate_numeric.rb +++ b/lib/puppet/parser/functions/validate_numeric.rb @@ -15,6 +15,8 @@ module Puppet::Parser::Functions ENDHEREDOC + function_deprecation([:puppet_3_type_check, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Numeric. There is further documentation for validate_legacy function in the README.']) + # tell the user we need at least one, and optionally up to two other parameters raise Puppet::ParseError, "validate_numeric(): Wrong number of arguments; must be 1, 2 or 3, got #{args.length}" unless args.length > 0 and args.length < 4 diff --git a/spec/aliases/float_spec.rb b/spec/aliases/float_spec.rb new file mode 100644 index 0000000..be31e43 --- /dev/null +++ b/spec/aliases/float_spec.rb @@ -0,0 +1,28 @@ +require 'spec_helper' + +if Puppet.version.to_f >= 4.0 + describe 'test::float', type: :class do + describe 'accepts floats' do + [ + 3.7, + '3.7', + -3.7, + '-342.2315e-12', + ].each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile } + end + end + end + + describe 'rejects other values' do + [ true, 'true', false, 'false', 'iAmAString', '1test', '1 test', 'test 1', 'test 1 test', {}, { 'key' => 'value' }, { 1=> 2 }, '', :undef , 'x', 3, '3', -3, '-3'].each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile.and_raise_error(/parameter 'value' expects a value of type Float or Pattern(\[.*\]+)?/) } + end + end + end + end +end diff --git a/spec/aliases/integer_spec.rb b/spec/aliases/integer_spec.rb new file mode 100644 index 0000000..fbc8c19 --- /dev/null +++ b/spec/aliases/integer_spec.rb @@ -0,0 +1,28 @@ +require 'spec_helper' + +if Puppet.version.to_f >= 4.0 + describe 'test::integer', type: :class do + describe 'accepts integers' do + [ + 3, + '3', + -3, + '-3', + ].each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile } + end + end + end + + describe 'rejects other values' do + [ true, 'true', false, 'false', 'iAmAString', '1test', '1 test', 'test 1', 'test 1 test', {}, { 'key' => 'value' }, { 1=> 2 }, '', :undef , 'x', 3.7, '3.7',-3.7, '-342.2315e-12' ].each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile.and_raise_error(/parameter 'value' expects a value of type Integer, Pattern(\[.*\]+)?, or Array/) } + end + end + end + end +end diff --git a/spec/aliases/numeric_spec.rb b/spec/aliases/numeric_spec.rb new file mode 100644 index 0000000..9afe4ed --- /dev/null +++ b/spec/aliases/numeric_spec.rb @@ -0,0 +1,32 @@ +require 'spec_helper' + +if Puppet.version.to_f >= 4.0 + describe 'test::numeric', type: :class do + describe 'accepts numerics' do + [ + 3, + '3', + -3, + '-3', + 3.7, + '3.7', + -3.7, + '-342.2315e-12', + ].each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile } + end + end + end + + describe 'rejects other values' do + [ true, 'true', false, 'false', 'iAmAString', '1test', '1 test', 'test 1', 'test 1 test', {}, { 'key' => 'value' }, { 1=> 2 }, '', :undef , 'x' ].each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile.and_raise_error(/parameter 'value' expects a value of type Numeric, Pattern(\[.*\]+)?, or Array/) } + end + end + end + end +end diff --git a/spec/fixtures/modules/test/manifests/float.pp b/spec/fixtures/modules/test/manifests/float.pp new file mode 100644 index 0000000..03a603d --- /dev/null +++ b/spec/fixtures/modules/test/manifests/float.pp @@ -0,0 +1,8 @@ +# Class to test the Stdlib::Compat::Float type alias +class test::float( + Stdlib::Compat::Float $value, + ) { + + notice("Success") + +} diff --git a/spec/fixtures/modules/test/manifests/integer.pp b/spec/fixtures/modules/test/manifests/integer.pp new file mode 100644 index 0000000..a4f26df --- /dev/null +++ b/spec/fixtures/modules/test/manifests/integer.pp @@ -0,0 +1,8 @@ +# Class to test the Stdlib::Compat::Integer type alias +class test::integer( + Stdlib::Compat::Integer $value, + ) { + + notice("Success") + +} diff --git a/spec/fixtures/modules/test/manifests/numeric.pp b/spec/fixtures/modules/test/manifests/numeric.pp new file mode 100644 index 0000000..2657ebc --- /dev/null +++ b/spec/fixtures/modules/test/manifests/numeric.pp @@ -0,0 +1,8 @@ +# Class to test the Stdlib::Compat::Numeric type alias +class test::numeric( + Stdlib::Compat::Numeric $value, + ) { + + notice("Success") + +} diff --git a/spec/functions/deprecation_spec.rb b/spec/functions/deprecation_spec.rb index bbabe48..a596e24 100644 --- a/spec/functions/deprecation_spec.rb +++ b/spec/functions/deprecation_spec.rb @@ -1,13 +1,5 @@ require 'spec_helper' -if ENV["FUTURE_PARSER"] == 'yes' - describe 'deprecation' do - pending 'teach rspec-puppet to load future-only functions under 3.7.5' do - it { is_expected.not_to eq(nil) } - end - end -end - if Puppet.version.to_f >= 4.0 describe 'deprecation' do before(:each) { @@ -48,4 +40,14 @@ if Puppet.version.to_f >= 4.0 Puppet.settings[:strict] = :warning } end +else + describe 'deprecation' do + it { is_expected.not_to eq(nil) } + it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + + it 'should display a single warning' do + scope.expects(:warn).with(includes('heelo')) + is_expected.to run.with_params('key', 'heelo') + end + end end diff --git a/spec/functions/is_float_spec.rb b/spec/functions/is_float_spec.rb index ffff971..267d9c6 100755 --- a/spec/functions/is_float_spec.rb +++ b/spec/functions/is_float_spec.rb @@ -2,6 +2,13 @@ require 'spec_helper' describe 'is_float' do it { is_expected.not_to eq(nil) } + + # Checking for deprecation warning + it 'should display a single deprecation' do + scope.expects(:warn).with(includes('This method is deprecated')) + is_expected.to run.with_params(3) + end + it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } it { is_expected.to run.with_params(0.1, 0.2).and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } diff --git a/spec/functions/is_integer_spec.rb b/spec/functions/is_integer_spec.rb index 67263c1..49550c7 100755 --- a/spec/functions/is_integer_spec.rb +++ b/spec/functions/is_integer_spec.rb @@ -2,6 +2,13 @@ require 'spec_helper' describe 'is_integer' do it { is_expected.not_to eq(nil) } + + # Checking for deprecation warning + it 'should display a single deprecation' do + scope.expects(:warn).with(includes('This method is deprecated')) + is_expected.to run.with_params(3) + end + it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } it { is_expected.to run.with_params(1, 2).and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } diff --git a/spec/functions/is_numeric_spec.rb b/spec/functions/is_numeric_spec.rb index d0f5a6e..b7de051 100755 --- a/spec/functions/is_numeric_spec.rb +++ b/spec/functions/is_numeric_spec.rb @@ -2,6 +2,13 @@ require 'spec_helper' describe 'is_numeric' do it { is_expected.not_to eq(nil) } + + # Checking for deprecation warning + it 'should display a single deprecation' do + scope.expects(:warn).with(includes('This method is deprecated')) + is_expected.to run.with_params(3) + end + it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } it { is_expected.to run.with_params(1, 2).and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } diff --git a/spec/functions/validate_integer_spec.rb b/spec/functions/validate_integer_spec.rb index 4c0a9d7..0eeab1e 100755 --- a/spec/functions/validate_integer_spec.rb +++ b/spec/functions/validate_integer_spec.rb @@ -1,6 +1,12 @@ require 'spec_helper' describe 'validate_integer' do + # Checking for deprecation warning + it 'should display a single deprecation' do + scope.expects(:warn).with(includes('This method is deprecated')) + is_expected.to run.with_params(3) + end + describe 'signature validation' do it { is_expected.not_to eq(nil) } it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } diff --git a/spec/functions/validate_numeric_spec.rb b/spec/functions/validate_numeric_spec.rb index 9b8eb0e..2e5561e 100755 --- a/spec/functions/validate_numeric_spec.rb +++ b/spec/functions/validate_numeric_spec.rb @@ -1,6 +1,12 @@ require 'spec_helper' describe 'validate_numeric' do + # Checking for deprecation warning + it 'should display a single deprecation' do + scope.expects(:warn).with(includes('This method is deprecated')) + is_expected.to run.with_params(3) + end + describe 'signature validation' do it { is_expected.not_to eq(nil) } it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } diff --git a/types/compat/float.pp b/types/compat/float.pp new file mode 100644 index 0000000..7f98bd2 --- /dev/null +++ b/types/compat/float.pp @@ -0,0 +1,19 @@ +# Emulate the is_float function +# The regex is what's currently used in is_float +# To keep your development moving forward, you can also add a deprecation warning using the Integer type: +# +# ```class example($value) { validate_float($value,) }``` +# +# would turn into +# +# ``` +# class example(Stdlib::Compat::Float $value) { +# validate_float($value, 10, 0) +# assert_type(Integer[0, 10], $value) |$expected, $actual| { +# warning("The 'value' parameter for the 'ntp' class has type ${actual}, but should be ${expected}.") +# } +# } +# ``` +# +# This allows you to find all places where a consumers of your code call it with unexpected values. +type Stdlib::Compat::Float = Variant[Float, Pattern[/^-?(?:(?:[1-9]\d*)|0)(?:\.\d+)(?:[eE]-?\d+)?$/]] diff --git a/types/compat/integer.pp b/types/compat/integer.pp new file mode 100644 index 0000000..e5cadb6 --- /dev/null +++ b/types/compat/integer.pp @@ -0,0 +1,23 @@ +# Emulate the is_integer and validate_integer functions +# The regex is what's currently used in is_integer +# validate_numeric also allows range checking, which cannot be mapped to the string parsing inside the function. +# For full backwards compatibility, you will need to keep the validate_numeric call around to catch everything. +# To keep your development moving forward, you can also add a deprecation warning using the Integer type: +# +# ```class example($value) { validate_integer($value, 10, 0) }``` +# +# would turn into +# +# ``` +# class example(Stdlib::Compat::Integer $value) { +# validate_numeric($value, 10, 0) +# assert_type(Integer[0, 10], $value) |$expected, $actual| { +# warning("The 'value' parameter for the 'ntp' class has type ${actual}, but should be ${expected}.") +# } +# } +# ``` +# +# > Note that you need to use Variant[Integer[0, 10], Float[0, 10]] if you want to match both integers and floating point numbers. +# +# This allows you to find all places where a consumers of your code call it with unexpected values. +type Stdlib::Compat::Integer = Variant[Integer, Pattern[/^-?(?:(?:[1-9]\d*)|0)$/], Array[Variant[Integer, Pattern[/^-?(?:(?:[1-9]\d*)|0)$/]]]] diff --git a/types/compat/numeric.pp b/types/compat/numeric.pp new file mode 100644 index 0000000..5bfc3d3 --- /dev/null +++ b/types/compat/numeric.pp @@ -0,0 +1,23 @@ +# Emulate the is_numeric and validate_numeric functions +# The regex is what's currently used in is_numeric +# validate_numeric also allows range checking, which cannot be mapped to the string parsing inside the function. +# For full backwards compatibility, you will need to keep the validate_numeric call around to catch everything. +# To keep your development moving forward, you can also add a deprecation warning using the Integer type: +# +# ```class example($value) { validate_numeric($value, 10, 0) }``` +# +# would turn into +# +# ``` +# class example(Stdlib::Compat::Numeric $value) { +# validate_numeric($value, 10, 0) +# assert_type(Integer[0, 10], $value) |$expected, $actual| { +# warning("The 'value' parameter for the 'ntp' class has type ${actual}, but should be ${expected}.") +# } +# } +# ``` +# +# > Note that you need to use Variant[Integer[0, 10], Float[0, 10]] if you want to match both integers and floating point numbers. +# +# This allows you to find all places where a consumers of your code call it with unexpected values. +type Stdlib::Compat::Numeric = Variant[Numeric, Pattern[/^-?(?:(?:[1-9]\d*)|0)(?:\.\d+)?(?:[eE]-?\d+)?$/], Array[Variant[Numeric, Pattern[/^-?(?:(?:[1-9]\d*)|0)(?:\.\d+)?(?:[eE]-?\d+)?$/]]]] -- cgit v1.2.3