(#12357) Add ability to display an error message from validate_re
I've seen a number of times the following error displayed to the end user: validate_re(): "" does not match "^true$|^false$" at /p/t/f.pp:40 This is an absolutely horrific error message. I'm to blame for it. Users stumble over this quite often and they shouldn't have to go read the code to sort out what's happening. This patch makes an effort to fix the problem by adding a third, optional, argument to validate_re(). This third argument will be the message thrown back in the exception which will be displayed to the end user. This sets the stage for nicer error messages coming from modules we write. This patch is backwards compatible but is a new feature.
This commit is contained in:
parent
898ff80fa7
commit
41b07232e4
2 changed files with 90 additions and 5 deletions
|
@ -1,5 +1,4 @@
|
|||
module Puppet::Parser::Functions
|
||||
|
||||
newfunction(:validate_re, :doc => <<-'ENDHEREDOC') do |args|
|
||||
Perform simple validation of a string against one or more regular
|
||||
expressions. The first argument of this function should be a string to
|
||||
|
@ -8,6 +7,9 @@ module Puppet::Parser::Functions
|
|||
of the regular expressions match the string passed in, 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.
|
||||
|
||||
The following strings will validate against the regular expressions:
|
||||
|
||||
validate_re('one', '^one$')
|
||||
|
@ -17,17 +19,20 @@ module Puppet::Parser::Functions
|
|||
|
||||
validate_re('one', [ '^two', '^three' ])
|
||||
|
||||
A helpful error message can be returned like this:
|
||||
|
||||
validate_re($::puppetversion, '^2.7', 'The $puppetversion fact value does not match 2.7')
|
||||
|
||||
ENDHEREDOC
|
||||
if args.length != 2 then
|
||||
raise Puppet::ParseError, ("validate_re(): wrong number of arguments (#{args.length}; must be 2)")
|
||||
if (args.length < 2) or (args.length > 3) then
|
||||
raise Puppet::ParseError, ("validate_re(): wrong number of arguments (#{args.length}; must be 2 or 3)")
|
||||
end
|
||||
|
||||
msg = "validate_re(): #{args[0].inspect} does not match #{args[1].inspect}"
|
||||
msg = args[2] || "validate_re(): #{args[0].inspect} does not match #{args[1].inspect}"
|
||||
|
||||
raise Puppet::ParseError, (msg) unless args[1].any? do |re_str|
|
||||
args[0] =~ Regexp.compile(re_str)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
|
80
spec/unit/puppet/parser/functions/validate_re_spec.rb
Normal file
80
spec/unit/puppet/parser/functions/validate_re_spec.rb
Normal file
|
@ -0,0 +1,80 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Puppet::Parser::Functions.function(:validate_re) do
|
||||
before :all do
|
||||
Puppet::Parser::Functions.autoloader.loadall
|
||||
end
|
||||
|
||||
let(:scope) do
|
||||
scope = Puppet::Parser::Scope.new
|
||||
end
|
||||
|
||||
# The subject of these examplres is the method itself.
|
||||
subject do
|
||||
scope.method :function_validate_re
|
||||
end
|
||||
|
||||
context 'Using Puppet::Parser::Scope.new' do
|
||||
|
||||
describe 'Garbage inputs' do
|
||||
inputs = [
|
||||
[ nil ],
|
||||
[ [ nil ] ],
|
||||
[ { 'foo' => 'bar' } ],
|
||||
[ { } ],
|
||||
[ '' ],
|
||||
[ "one", "one", "MSG to User", "4th arg" ],
|
||||
]
|
||||
|
||||
inputs.each do |input|
|
||||
it "validate_re(#{input.inspect}) should fail" do
|
||||
expect { subject.call [input] }.to raise_error Puppet::ParseError
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'Valid inputs' do
|
||||
inputs = [
|
||||
[ '/full/path/to/something', '^/full' ],
|
||||
[ '/full/path/to/something', 'full' ],
|
||||
[ '/full/path/to/something', ['full', 'absent'] ],
|
||||
[ '/full/path/to/something', ['full', 'absent'], 'Message to the user' ],
|
||||
]
|
||||
|
||||
inputs.each do |input|
|
||||
it "validate_re(#{input.inspect}) should not fail" do
|
||||
expect { subject.call input }.not_to raise_error
|
||||
end
|
||||
end
|
||||
end
|
||||
describe "Valid inputs which should raise an exception without a message" do
|
||||
# The intent here is to make sure valid inputs raise exceptions when they
|
||||
# don't specify an error message to display. This is the behvior in
|
||||
# 2.2.x and prior.
|
||||
inputs = [
|
||||
[ "hello", [ "bye", "later", "adios" ] ],
|
||||
[ "greetings", "salutations" ],
|
||||
]
|
||||
|
||||
inputs.each do |input|
|
||||
it "validate_re(#{input.inspect}) should fail" do
|
||||
expect { subject.call input }.to raise_error /validate_re.*?does not match/
|
||||
end
|
||||
end
|
||||
end
|
||||
describe "Nicer Error Messages" do
|
||||
# The intent here is to make sure the function returns the 3rd argument
|
||||
# in the exception thrown
|
||||
inputs = [
|
||||
[ "hello", [ "bye", "later", "adios" ], "MSG to User" ],
|
||||
[ "greetings", "salutations", "Error, greetings does not match salutations" ],
|
||||
]
|
||||
|
||||
inputs.each do |input|
|
||||
it "validate_re(#{input.inspect}) should fail" do
|
||||
expect { subject.call input }.to raise_error /#{input[2]}/
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue