forked from puppetlabs/puppet
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement newlookupvar() to replace dynamic scope
lookupvar() is shifted to oldlookupvar() and newlookupvar() is added. An intermediary lookupvar() function will query both and if the answer varies then it will throw a deprecation warning for dynamic scoping. The intermediary and old lookup functions may be removed at a later date, thus completing the transition. A test case has been introduced to detect dynamic scoping and the deprecation warning. Slight modifications to the spec test scoping objects were made to bring them more in line with the real world. All scope tests pass. When oldlookupvar is replaced, the deprecated dynamic scoping test case will fail and all other scope test cases will pass.
- Loading branch information
Showing
3 changed files
with
43 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
|
@@ -222,27 +222,58 @@ def qualified_scope(classname) | ||
|
|
||
private :qualified_scope | private :qualified_scope | ||
|
|
||
# Look up a variable. The simplest value search we do. | # Look up a variable with traditional scoping and then with new scoping. If | ||
# the answers differ then print a deprecation warning. | |||
def lookupvar(name, options = {}) | def lookupvar(name, options = {}) | ||
oldval = oldlookupvar(name,options) | |||
newval = newlookupvar(name,options) | |||
if oldval and newval and newval != oldval | |||
location = (options[:file] && options[:line]) ? " at #{options[:file]}:#{options[:line]}" : '' | |||
Puppet.deprecation_warning "Dynamic lookup of $#{name}#{location} is deprecated. Support will be removed in a later version of Puppet. Use a fully-qualified variable name (e.g., $classname::variable) or parameterized classes." | |||
end | |||
oldval | |||
end | |||
|
|||
# Look up a variable. The simplest value search we do. | |||
def newlookupvar(name, options = {}) | |||
# Save the originating scope for the request | |||
options[:origin] = self unless options[:origin] | |||
This comment has been minimized.
Sorry, something went wrong. |
|||
table = ephemeral?(name) ? @ephemeral.last : @symtable | |||
if name =~ /^(.*)::(.+)$/ | |||
begin | |||
qualified_scope($1).newlookupvar($2,options.merge({:origin => nil})) | |||
rescue RuntimeError => e | |||
location = (options[:file] && options[:line]) ? " at #{options[:file]}:#{options[:line]}" : '' | |||
warning "Could not look up qualified variable '#{name}'; #{e.message}#{location}" | |||
:undefined | |||
end | |||
# If the value is present and either we are top/node scope or originating scope... | |||
elsif (ephemeral_include?(name) or table.include?(name)) and (compiler and self == compiler.topscope or (self.resource and self.resource.type == "Node") or self == options[:origin]) | |||
This comment has been minimized.
Sorry, something went wrong.
nicklewis
|
|||
table[name] | |||
elsif parent | |||
parent.newlookupvar(name,options) | |||
else | |||
:undefined | |||
end | |||
end | |||
|
|||
# Look up a variable. The simplest value search we do. | |||
def oldlookupvar(name, options = {}) | |||
table = ephemeral?(name) ? @ephemeral.last : @symtable | table = ephemeral?(name) ? @ephemeral.last : @symtable | ||
# If the variable is qualified, then find the specified scope and look the variable up there instead. | # If the variable is qualified, then find the specified scope and look the variable up there instead. | ||
if name =~ /^(.*)::(.+)$/ | if name =~ /^(.*)::(.+)$/ | ||
begin | begin | ||
qualified_scope($1).lookupvar($2,options) | qualified_scope($1).oldlookupvar($2,options) | ||
rescue RuntimeError => e | rescue RuntimeError => e | ||
location = (options[:file] && options[:line]) ? " at #{options[:file]}:#{options[:line]}" : '' | location = (options[:file] && options[:line]) ? " at #{options[:file]}:#{options[:line]}" : '' | ||
warning "Could not look up qualified variable '#{name}'; #{e.message}#{location}" | warning "Could not look up qualified variable '#{name}'; #{e.message}#{location}" | ||
:undefined | :undefined | ||
end | end | ||
elsif ephemeral_include?(name) or table.include?(name) | elsif ephemeral_include?(name) or table.include?(name) | ||
# We can't use "if table[name]" here because the value might be false | # We can't use "if table[name]" here because the value might be false | ||
if options[:dynamic] and self != compiler.topscope | |||
location = (options[:file] && options[:line]) ? " at #{options[:file]}:#{options[:line]}" : '' | |||
Puppet.deprecation_warning "Dynamic lookup of $#{name}#{location} is deprecated. Support will be removed in Puppet 2.8. Use a fully-qualified variable name (e.g., $classname::variable) or parameterized classes." | |||
end | |||
table[name] | table[name] | ||
elsif parent | elsif parent | ||
parent.lookupvar(name,options.merge(:dynamic => (dynamic || options[:dynamic]))) | parent.oldlookupvar(name,options.merge(:dynamic => (dynamic || options[:dynamic]))) | ||
else | else | ||
:undefined | :undefined | ||
end | end | ||
|
@@ -374,7 +405,7 @@ def unset_ephemeral_var(level=:all) | ||
|
|
||
# check if name exists in one of the ephemeral scope. | # check if name exists in one of the ephemeral scope. | ||
def ephemeral_include?(name) | def ephemeral_include?(name) | ||
@ephemeral.reverse.each do |eph| | @ephemeral.reverse_each do |eph| | ||
return true if eph.include?(name) | return true if eph.include?(name) | ||
end | end | ||
false | false | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This can just be
options[:origin] ||= self
.