Skip to content

(MODULES-1473) Deprecate type() function for new parser #382

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 8, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .fixtures.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fixtures:
symlinks:
stdlib: "#{source_dir}"
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -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'"
Expand Down
7 changes: 6 additions & 1 deletion README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -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"].

Expand Down
17 changes: 17 additions & 0 deletions lib/puppet/functions/type_of.rb
Original file line number Diff line number Diff line change
@@ -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") }
#
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can add this as well:

@example how to compare against a 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") }

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure.

# 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.
#
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can also add:

Also 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
43 changes: 6 additions & 37 deletions lib/puppet/parser/functions/type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
51 changes: 51 additions & 0 deletions lib/puppet/parser/functions/type3x.rb
Original file line number Diff line number Diff line change
@@ -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 changes: 43 additions & 0 deletions spec/functions/type3x_spec.rb
Original file line number Diff line number Diff line change
@@ -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
5 changes: 3 additions & 2 deletions spec/functions/type_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@
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
Expand Down
33 changes: 33 additions & 0 deletions spec/unit/puppet/functions/type_of_spec.rb
Original file line number Diff line number Diff line change
@@ -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