(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.
This commit is contained in:
parent
4700f16e82
commit
7c8ae311ca
9 changed files with 163 additions and 40 deletions
3
.fixtures.yml
Normal file
3
.fixtures.yml
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
fixtures:
|
||||||
|
symlinks:
|
||||||
|
stdlib: "#{source_dir}"
|
|
@ -1,4 +1,5 @@
|
||||||
---
|
---
|
||||||
|
sudo: false
|
||||||
language: ruby
|
language: ruby
|
||||||
bundler_args: --without system_tests
|
bundler_args: --without system_tests
|
||||||
script: "bundle exec rake validate && bundle exec rake lint && bundle exec rake spec SPEC_OPTS='--color --format documentation'"
|
script: "bundle exec rake validate && bundle exec rake lint && bundle exec rake spec SPEC_OPTS='--color --format documentation'"
|
||||||
|
|
|
@ -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.
|
* `to_bytes`: Converts the argument into bytes, for example 4 kB becomes 4096.
|
||||||
Takes a single string value as an argument. *Type*: rvalue
|
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"].
|
* `union`: This function returns a union of two arrays. For example, `union(["a","b","c"],["b","c","d"])` returns ["a","b","c","d"].
|
||||||
|
|
||||||
|
|
17
lib/puppet/functions/type_of.rb
Normal file
17
lib/puppet/functions/type_of.rb
Normal file
|
@ -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
|
|
@ -4,46 +4,15 @@
|
||||||
|
|
||||||
module Puppet::Parser::Functions
|
module Puppet::Parser::Functions
|
||||||
newfunction(:type, :type => :rvalue, :doc => <<-EOS
|
newfunction(:type, :type => :rvalue, :doc => <<-EOS
|
||||||
Returns the type when passed a variable. Type can be one of:
|
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.
|
||||||
|
|
||||||
* string
|
|
||||||
* array
|
|
||||||
* hash
|
|
||||||
* float
|
|
||||||
* integer
|
|
||||||
* boolean
|
|
||||||
EOS
|
EOS
|
||||||
) do |arguments|
|
) do |args|
|
||||||
|
|
||||||
raise(Puppet::ParseError, "type(): Wrong number of arguments " +
|
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.")
|
||||||
"given (#{arguments.size} for 1)") if arguments.size < 1
|
if ! Puppet::Parser::Functions.autoloader.loaded?(:type3x)
|
||||||
|
Puppet::Parser::Functions.autoloader.load(:type3x)
|
||||||
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
|
end
|
||||||
|
function_type3x(args + [false])
|
||||||
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
51
lib/puppet/parser/functions/type3x.rb
Normal file
51
lib/puppet/parser/functions/type3x.rb
Normal file
|
@ -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 :
|
43
spec/functions/type3x_spec.rb
Normal file
43
spec/functions/type3x_spec.rb
Normal file
|
@ -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
|
|
@ -7,8 +7,9 @@ describe "the type function" do
|
||||||
expect(Puppet::Parser::Functions.function("type")).to eq("function_type")
|
expect(Puppet::Parser::Functions.function("type")).to eq("function_type")
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should raise a ParseError if there is less than 1 arguments" do
|
it "should give a deprecation warning when called" do
|
||||||
expect { scope.function_type([]) }.to( raise_error(Puppet::ParseError))
|
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
|
end
|
||||||
|
|
||||||
it "should return string when given a string" do
|
it "should return string when given a string" do
|
||||||
|
|
33
spec/unit/puppet/functions/type_of_spec.rb
Normal file
33
spec/unit/puppet/functions/type_of_spec.rb
Normal file
|
@ -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
|
Loading…
Reference in a new issue