class Puppet::Pops::Validation::Checker4_0

A Validator validates a model.

Validation is performed on each model element in isolation. Each method should validate the model element's state but not validate its referenced/contained elements except to check their validity in their respective role. The intent is to drive the validation with a tree iterator that visits all elements in a model.

TODO: Add validation of multiplicities - this is a general validation that can be checked for all

Model objects via their metamodel. (I.e an extra call to multiplicity check in polymorph check).
This is however mostly valuable when validating model to model transformations, and is therefore T.B.D

Constants

BAD_MODULE_FILE
FUTURE_RESERVED_WORDS
NO_NAMESPACE
NO_PATH
RESERVED_PARAMETERS
RESERVED_TYPE_NAMES

Attributes

acceptor[R]
migration_checker[R]

Public Class Methods

check_visitor() click to toggle source
   # File lib/puppet/pops/validation/checker4_0.rb
24 def self.check_visitor
25   # Class instance variable rather than Class variable because methods visited
26   # may be overridden in subclass
27   @check_visitor ||= Visitor.new(nil, 'check', 0, 0)
28 end
new(diagnostics_producer) click to toggle source

Initializes the validator with a diagnostics producer. This object must respond to `:will_accept?` and `:accept`.

   # File lib/puppet/pops/validation/checker4_0.rb
33 def initialize(diagnostics_producer)
34   super()
35   @@rvalue_visitor      ||= Visitor.new(nil, "rvalue", 0, 0)
36   @@hostname_visitor    ||= Visitor.new(nil, "hostname", 1, 2)
37   @@assignment_visitor  ||= Visitor.new(nil, "assign", 0, 1)
38   @@query_visitor       ||= Visitor.new(nil, "query", 0, 0)
39   @@relation_visitor    ||= Visitor.new(nil, "relation", 0, 0)
40   @@idem_visitor        ||= Visitor.new(nil, "idem", 0, 0)
41 
42   @check_visitor = self.class.check_visitor
43   @acceptor = diagnostics_producer
44 
45   # Use null migration checker unless given in context
46   @migration_checker = (Puppet.lookup(:migration_checker) { Migration::MigrationChecker.new() })
47 end

Public Instance Methods

assign(o, via_index = false) click to toggle source

Checks the LHS of an assignment (is it assignable?). If args is true, assignment via index is checked.

    # File lib/puppet/pops/validation/checker4_0.rb
124 def assign(o, via_index = false)
125   @@assignment_visitor.visit_this_1(self, o, via_index)
126 end
assign_AccessExpression(o, via_index) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
165 def assign_AccessExpression(o, via_index)
166   # Are indexed assignments allowed at all ? $x[x] = '...'
167   if acceptor.will_accept? Issues::ILLEGAL_INDEXED_ASSIGNMENT
168     acceptor.accept(Issues::ILLEGAL_INDEXED_ASSIGNMENT, o)
169   else
170     # Then the left expression must be assignable-via-index
171     assign(o.left_expr, true)
172   end
173 end
assign_LiteralList(o, via_index) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
175 def assign_LiteralList(o, via_index)
176   o.values.each {|x| assign(x) }
177 end
assign_Object(o, via_index) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
179 def assign_Object(o, via_index)
180   # Can not assign to anything else (differentiate if this is via index or not)
181   # i.e. 10 = 'hello' vs. 10['x'] = 'hello' (the root is reported as being in error in both cases)
182   #
183   acceptor.accept(via_index ? Issues::ILLEGAL_ASSIGNMENT_VIA_INDEX : Issues::ILLEGAL_ASSIGNMENT, o)
184 end
assign_VariableExpression(o, via_index) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
149 def assign_VariableExpression(o, via_index)
150   varname_string = varname_to_s(o.expr)
151   if varname_string =~ Patterns::NUMERIC_VAR_NAME
152     acceptor.accept(Issues::ILLEGAL_NUMERIC_ASSIGNMENT, o, :varname => varname_string)
153   end
154   # Can not assign to something in another namespace (i.e. a '::' in the name is not legal)
155   if acceptor.will_accept? Issues::CROSS_SCOPE_ASSIGNMENT
156     if varname_string =~ /::/
157       acceptor.accept(Issues::CROSS_SCOPE_ASSIGNMENT, o, :name => varname_string)
158     end
159   end
160 
161   # TODO: Could scan for reassignment of the same variable if done earlier in the same container
162   #       Or if assigning to a parameter (more work).
163 end
check(o) click to toggle source

Performs regular validity check

   # File lib/puppet/pops/validation/checker4_0.rb
66 def check(o)
67   @check_visitor.visit_this_0(self, o)
68 end
check_AccessExpression(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
195 def check_AccessExpression(o)
196   # Only min range is checked, all other checks are RT checks as they depend on the resulting type
197   # of the LHS.
198   if o.keys.size < 1
199     acceptor.accept(Issues::MISSING_INDEX, o)
200   end
201 end
check_AssignmentExpression(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
203 def check_AssignmentExpression(o)
204   case o.operator
205   when '='
206     assign(o.left_expr)
207     rvalue(o.right_expr)
208   when '+=', '-='
209     acceptor.accept(Issues::APPENDS_DELETES_NO_LONGER_SUPPORTED, o, {:operator => o.operator})
210   else
211     acceptor.accept(Issues::UNSUPPORTED_OPERATOR, o, {:operator => o.operator})
212   end
213 end
check_AttributeOperation(o) click to toggle source

Checks that operation with :+> is contained in a ResourceOverride or Collector.

Parent of an AttributeOperation can be one of:

  • CollectExpression

  • ResourceOverride

  • ResourceBody (ILLEGAL this is a regular resource expression)

  • ResourceDefaults (ILLEGAL)

    # File lib/puppet/pops/validation/checker4_0.rb
223 def check_AttributeOperation(o)
224   if o.operator == '+>'
225     # Append operator use is constrained
226     p = container
227     unless p.is_a?(Model::CollectExpression) || p.is_a?(Model::ResourceOverrideExpression)
228       acceptor.accept(Issues::ILLEGAL_ATTRIBUTE_APPEND, o, {:name=>o.attribute_name, :parent=>p})
229     end
230   end
231   rvalue(o.value_expr)
232 end
check_AttributesOperation(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
234 def check_AttributesOperation(o)
235   # Append operator use is constrained
236   p = container
237   case p
238   when Model::AbstractResource
239   when Model::CollectExpression
240   else
241     # protect against just testing a snippet that has no parent, error message will be a bit strange
242     # but it is not for a real program.
243     parent2 = p.nil? ? o : container(-2)
244     unless parent2.is_a?(Model::AbstractResource)
245       acceptor.accept(Issues::UNSUPPORTED_OPERATOR_IN_CONTEXT, parent2, :operator=>'* =>')
246     end
247   end
248   rvalue(o.expr)
249 end
check_BinaryExpression(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
251 def check_BinaryExpression(o)
252   rvalue(o.left_expr)
253   rvalue(o.right_expr)
254 end
check_BlockExpression(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
265 def check_BlockExpression(o)
266   if resource_without_title?(o)
267     acceptor.accept(Issues::RESOURCE_WITHOUT_TITLE, o, :name => o.statements[0].value)
268   else
269     o.statements[0..-2].each do |statement|
270       if idem(statement)
271         acceptor.accept(Issues::IDEM_EXPRESSION_NOT_LAST, statement)
272         break # only flag the first
273       end
274     end
275   end
276 end
check_CallNamedFunctionExpression(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
278 def check_CallNamedFunctionExpression(o)
279   functor = o.functor_expr
280   if functor.is_a?(Model::QualifiedReference) ||
281     functor.is_a?(Model::AccessExpression) && functor.left_expr.is_a?(Model::QualifiedReference)
282     # ok (a call to a type)
283     return nil
284   end
285   case functor
286   when Model::QualifiedName
287     # ok
288     nil
289   when Model::RenderStringExpression
290     # helpful to point out this easy to make Epp error
291     acceptor.accept(Issues::ILLEGAL_EPP_PARAMETERS, o)
292   else
293     acceptor.accept(Issues::ILLEGAL_EXPRESSION, o.functor_expr, {:feature=>'function name', :container => o})
294   end
295 end
check_CaseExpression(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
319 def check_CaseExpression(o)
320   rvalue(o.test)
321   # There can only be one LiteralDefault case option value
322   found_default = false
323   o.options.each do |option|
324     option.values.each do |value|
325       if value.is_a?(Model::LiteralDefault)
326         # Flag the second default as 'unreachable'
327         acceptor.accept(Issues::DUPLICATE_DEFAULT, value, :container => o) if found_default
328         found_default = true
329       end
330     end
331   end
332 end
check_CaseOption(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
334 def check_CaseOption(o)
335   o.values.each { |v| rvalue(v) }
336 end
check_CollectExpression(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
338 def check_CollectExpression(o)
339   unless o.type_expr.is_a? Model::QualifiedReference
340     acceptor.accept(Issues::ILLEGAL_EXPRESSION, o.type_expr, :feature=> 'type name', :container => o)
341   end
342 end
check_EppExpression(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
297 def check_EppExpression(o)
298   p = container
299   if p.is_a?(Model::LambdaExpression)
300     internal_check_no_capture(p, o)
301     internal_check_parameter_name_uniqueness(p)
302   end
303 end
check_Factory(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
191 def check_Factory(o)
192   check(o.model)
193 end
check_FunctionDefinition(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
460 def check_FunctionDefinition(o)
461   check_NamedDefinition(o)
462   internal_check_return_type(o)
463   internal_check_parameter_name_uniqueness(o)
464 end
check_HeredocExpression(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
305 def check_HeredocExpression(o)
306   # Only syntax check static text in heredoc during validation - dynamic text is validated by the evaluator.
307   expr = o.text_expr
308   if expr.is_a?(Model::LiteralString)
309     assert_external_syntax(nil, expr.value, o.syntax, o.text_expr)
310   end
311 end
check_HostClassDefinition(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
466 def check_HostClassDefinition(o)
467   check_NamedDefinition(o)
468   internal_check_no_capture(o)
469   internal_check_parameter_name_uniqueness(o)
470   internal_check_reserved_params(o)
471   internal_check_no_idem_last(o)
472 end
check_IfExpression(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
684 def check_IfExpression(o)
685   rvalue(o.test)
686 end
check_KeyedEntry(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
688 def check_KeyedEntry(o)
689   rvalue(o.key)
690   rvalue(o.value)
691   # In case there are additional things to forbid than non-rvalues
692   # acceptor.accept(Issues::ILLEGAL_EXPRESSION, o.key, :feature => 'hash key', :container => container)
693 end
check_LambdaExpression(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
695 def check_LambdaExpression(o)
696   internal_check_capture_last(o)
697   internal_check_return_type(o)
698 end
check_LiteralHash(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
711 def check_LiteralHash(o)
712   # the keys of a literal hash may be non-literal expressions. They cannot be checked.
713   unique = Set.new
714   o.entries.each do |entry|
715     catch(:not_literal) do
716       literal_key = literal(entry.key)
717       acceptor.accept(Issues::DUPLICATE_KEY, entry, {:key => literal_key}) if unique.add?(literal_key).nil?
718     end
719   end
720 end
check_LiteralInteger(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
704 def check_LiteralInteger(o)
705   v = o.value
706   if v < MIN_INTEGER || v > MAX_INTEGER
707     acceptor.accept(Issues::NUMERIC_OVERFLOW, o, {:value => v})
708   end
709 end
check_LiteralList(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
700 def check_LiteralList(o)
701   o.values.each {|v| rvalue(v) }
702 end
check_MethodCallExpression(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
313 def check_MethodCallExpression(o)
314   unless o.functor_expr.is_a? Model::QualifiedName
315     acceptor.accept(Issues::ILLEGAL_EXPRESSION, o.functor_expr, :feature => 'function name', :container => o)
316   end
317 end
check_NamedAccessExpression(o) click to toggle source

Only used for function names, grammar should not be able to produce something faulty, but check anyway if model is created programmatically (it will fail in transformation to AST for sure).

    # File lib/puppet/pops/validation/checker4_0.rb
346 def check_NamedAccessExpression(o)
347   name = o.right_expr
348   unless name.is_a? Model::QualifiedName
349     acceptor.accept(Issues::ILLEGAL_EXPRESSION, name, :feature=> 'function name', :container => container)
350   end
351 end
check_NamedDefinition(o) click to toggle source

for 'class', 'define', and function

    # File lib/puppet/pops/validation/checker4_0.rb
389 def check_NamedDefinition(o)
390   top(o)
391   if o.name !~ Patterns::CLASSREF_DECL
392     acceptor.accept(Issues::ILLEGAL_DEFINITION_NAME, o, {:name=>o.name})
393   end
394 
395   internal_check_file_namespace(o)
396   internal_check_reserved_type_name(o, o.name)
397   internal_check_future_reserved_word(o, o.name)
398 end
check_NodeDefinition(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
722 def check_NodeDefinition(o)
723   # Check that hostnames are valid hostnames (or regular expressions)
724   hostname(o.host_matches, o)
725   top(o)
726   violator = ends_with_idem(o.body)
727   if violator
728     acceptor.accept(Issues::IDEM_NOT_ALLOWED_LAST, violator, {:container => o}) unless resource_without_title?(violator)
729   end
730   unless o.parent.nil?
731     acceptor.accept(Issues::ILLEGAL_NODE_INHERITANCE, o.parent)
732   end
733 end
check_Object(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
188 def check_Object(o)
189 end
check_Parameter(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
764 def check_Parameter(o)
765   if o.name =~ /^(?:0x)?[0-9]+$/
766     acceptor.accept(Issues::ILLEGAL_NUMERIC_PARAMETER, o, :name => o.name)
767   end
768 
769   unless o.name =~ Patterns::PARAM_NAME
770     acceptor.accept(Issues::ILLEGAL_PARAM_NAME, o, :name => o.name)
771   end
772   return unless o.value
773 
774   internal_check_illegal_assignment(o.value)
775 end
check_QualifiedName(o) click to toggle source

No checking takes place - all expressions using a QualifiedName need to check. This because the rules are slightly different depending on the container (A variable allows a numeric start, but not other names). This means that (if the lexer/parser so chooses) a QualifiedName can be anything when it represents a Bare Word and evaluates to a String.

    # File lib/puppet/pops/validation/checker4_0.rb
740 def check_QualifiedName(o)
741 end
check_QualifiedReference(o) click to toggle source

Checks that the value is a valid UpperCaseWord (a CLASSREF), and optionally if it contains a hypen. DOH: QualifiedReferences are created with LOWER CASE NAMES at parse time

    # File lib/puppet/pops/validation/checker4_0.rb
745 def check_QualifiedReference(o)
746   # Is this a valid qualified name?
747   if o.cased_value !~ Patterns::CLASSREF_EXT
748     acceptor.accept(Issues::ILLEGAL_CLASSREF, o, {:name=>o.cased_value})
749   end
750 end
check_QueryExpression(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
752 def check_QueryExpression(o)
753   query(o.expr) if o.expr  # is optional
754 end
check_RelationshipExpression(o) click to toggle source

relationship_side: resource

| resourceref
| collection
| variable
| quotedtext
| selector
| casestatement
| hasharrayaccesses
    # File lib/puppet/pops/validation/checker4_0.rb
796 def check_RelationshipExpression(o)
797   relation(o.left_expr)
798   relation(o.right_expr)
799 end
check_ReservedWord(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
837 def check_ReservedWord(o)
838   if o.future
839     acceptor.accept(Issues::FUTURE_RESERVED_WORD, o, :word => o.word)
840   else
841     acceptor.accept(Issues::RESERVED_WORD, o, :word => o.word)
842   end
843 end
check_ResourceBody(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
812 def check_ResourceBody(o)
813   seenUnfolding = false
814   o.operations.each do |ao|
815     if ao.is_a?(Model::AttributesOperation)
816       if seenUnfolding
817         acceptor.accept(Issues::MULTIPLE_ATTRIBUTES_UNFOLD, ao)
818       else
819         seenUnfolding = true
820       end
821     end
822   end
823 end
check_ResourceDefaultsExpression(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
825 def check_ResourceDefaultsExpression(o)
826   if o.form != 'regular'
827     acceptor.accept(Issues::NOT_VIRTUALIZEABLE, o)
828   end
829 end
check_ResourceExpression(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
801 def check_ResourceExpression(o)
802   # The expression for type name cannot be statically checked - this is instead done at runtime
803   # to enable better error message of the result of the expression rather than the static instruction.
804   # (This can be revised as there are static constructs that are illegal, but require updating many
805   # tests that expect the detailed reporting).
806   type_name_expr = o.type_name
807   if o.form && o.form != 'regular' && type_name_expr.is_a?(Model::QualifiedName) && type_name_expr.value == 'class'
808     acceptor.accept(Issues::CLASS_NOT_VIRTUALIZABLE, o)
809   end
810 end
check_ResourceOverrideExpression(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
831 def check_ResourceOverrideExpression(o)
832   if o.form != 'regular'
833     acceptor.accept(Issues::NOT_VIRTUALIZEABLE, o)
834   end
835 end
check_ResourceTypeDefinition(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
474 def check_ResourceTypeDefinition(o)
475   check_NamedDefinition(o)
476   internal_check_no_capture(o)
477   internal_check_parameter_name_uniqueness(o)
478   internal_check_reserved_params(o)
479   internal_check_no_idem_last(o)
480 end
check_SelectorEntry(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
855 def check_SelectorEntry(o)
856   rvalue(o.matching_expr)
857 end
check_SelectorExpression(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
845 def check_SelectorExpression(o)
846   rvalue(o.left_expr)
847   # There can only be one LiteralDefault case option value
848   defaults = o.selectors.select {|v| v.matching_expr.is_a?(Model::LiteralDefault) }
849   unless defaults.size <= 1
850     # Flag the second default as 'unreachable'
851     acceptor.accept(Issues::DUPLICATE_DEFAULT, defaults[1].matching_expr, :container => o)
852   end
853 end
check_TypeAlias(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
400 def check_TypeAlias(o)
401   top(o)
402   if o.name !~ Patterns::CLASSREF_EXT_DECL
403     acceptor.accept(Issues::ILLEGAL_DEFINITION_NAME, o, {:name=>o.name})
404   end
405   internal_check_reserved_type_name(o, o.name)
406   internal_check_type_ref(o, o.type_expr)
407 end
check_TypeDefinition(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
453 def check_TypeDefinition(o)
454   top(o)
455   internal_check_reserved_type_name(o, o.name)
456   # TODO: Check TypeDefinition body. For now, just error out
457   acceptor.accept(Issues::UNSUPPORTED_EXPRESSION, o)
458 end
check_TypeMapping(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
409 def check_TypeMapping(o)
410   top(o)
411   lhs = o.type_expr
412   lhs_type = 0 # Not Runtime
413   if lhs.is_a?(Model::AccessExpression)
414     left = lhs.left_expr
415     if left.is_a?(Model::QualifiedReference) && left.cased_value == 'Runtime'
416       lhs_type = 1 # Runtime
417       keys = lhs.keys
418 
419       # Must be a literal string or pattern replacement
420       lhs_type = 2 if keys.size == 2 && pattern_with_replacement?(keys[1])
421     end
422   end
423 
424   if lhs_type == 0
425     # This is not a TypeMapping. Something other than Runtime[] on LHS
426     acceptor.accept(Issues::UNSUPPORTED_EXPRESSION, o)
427   else
428     rhs = o.mapping_expr
429     if pattern_with_replacement?(rhs)
430       acceptor.accept(Issues::ILLEGAL_SINGLE_TYPE_MAPPING, o) if lhs_type == 1
431     elsif type_ref?(rhs)
432       acceptor.accept(Issues::ILLEGAL_REGEXP_TYPE_MAPPING, o) if lhs_type == 2
433     else
434       acceptor.accept(lhs_type == 1 ? Issues::ILLEGAL_SINGLE_TYPE_MAPPING : Issues::ILLEGAL_REGEXP_TYPE_MAPPING, o)
435     end
436   end
437 end
check_UnaryExpression(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
859 def check_UnaryExpression(o)
860   rvalue(o.expr)
861 end
check_UnlessExpression(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
863 def check_UnlessExpression(o)
864   rvalue(o.test)
865   # TODO: Unless may not have an else part that is an IfExpression (grammar denies this though)
866 end
check_VariableExpression(o) click to toggle source

Checks that variable is either strictly 0, or a non 0 starting decimal number, or a valid VAR_NAME

    # File lib/puppet/pops/validation/checker4_0.rb
869 def check_VariableExpression(o)
870   # The expression must be a qualified name or an integer
871   name_expr = o.expr
872   return if name_expr.is_a?(Model::LiteralInteger)
873   if !name_expr.is_a?(Model::QualifiedName)
874     acceptor.accept(Issues::ILLEGAL_EXPRESSION, o, :feature => 'name', :container => o)
875   else
876     # name must be either a decimal string value, or a valid NAME
877     name = o.expr.value
878     if name[0,1] =~ /[0-9]/
879       unless name =~ Patterns::NUMERIC_VAR_NAME
880         acceptor.accept(Issues::ILLEGAL_NUMERIC_VAR_NAME, o, :name => name)
881       end
882     else
883       unless name =~ Patterns::VAR_NAME
884         acceptor.accept(Issues::ILLEGAL_VAR_NAME, o, :name => name)
885       end
886     end
887   end
888 end
container(index = -1) click to toggle source
   # File lib/puppet/pops/validation/checker4_0.rb
61 def container(index = -1)
62   @path[index]
63 end
dir_to_names(relative_path) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
638 def dir_to_names(relative_path)
639   # Downcasing here because check is case-insensitive
640   path_components = relative_path.to_s.downcase.split(File::SEPARATOR)
641 
642   # Example definition dir: manifests in this path:
643   # <module name>/manifests/<module subdir>/<classfile>.pp
644   dir = path_components[1]
645 
646   # How can we get this result?
647   # If it is not an initial manifest, it must come from a module,
648   # and from the manifests dir there.  This may never get used...
649   return BAD_MODULE_FILE unless dir == 'manifests' || dir == 'functions' || dir == 'types' || dir == 'plans'
650 
651   names = path_components[2 .. -2] # Directories inside module
652   names.unshift(path_components[0]) # Name of the module itself
653 
654   # Do not include name of module init file at top level of module
655   # e.g. <module name>/manifests/init.pp
656   filename = path_components[-1]
657   if !(path_components.length == 3 && filename == 'init.pp')
658     names.push(filename[0 .. -4]) # Remove .pp from filename
659   end
660 
661   names
662 end
ends_with_idem(o) click to toggle source

Returns the last expression in a block, or the expression, if that expression is idem

    # File lib/puppet/pops/validation/checker4_0.rb
138 def ends_with_idem(o)
139   if o.is_a?(Model::BlockExpression)
140     last = o.statements[-1]
141     idem(last) ? last : nil
142   else
143     idem(o) ? o : nil
144   end
145 end
hostname(o, semantic) click to toggle source

Performs check if this is a vaid hostname expression @param single_feature_name [String, nil] the name of a single valued hostname feature of the value's container. e.g. 'parent'

   # File lib/puppet/pops/validation/checker4_0.rb
72 def hostname(o, semantic)
73   @@hostname_visitor.visit_this_1(self, o, semantic)
74 end
hostname_Array(o, semantic) click to toggle source

Transforms Array of host matching expressions into a (Ruby) array of AST::HostName

    # File lib/puppet/pops/validation/checker4_0.rb
893 def hostname_Array(o, semantic)
894   o.each {|x| hostname(x, semantic) }
895 end
hostname_ConcatenatedString(o, semantic) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
911 def hostname_ConcatenatedString(o, semantic)
912   # Puppet 3.1. only accepts a concatenated string without interpolated expressions
913   the_expr = o.segments.index {|s| s.is_a?(Model::TextExpression) }
914   if the_expr
915     acceptor.accept(Issues::ILLEGAL_HOSTNAME_INTERPOLATION, o.segments[the_expr].expr)
916   elsif o.segments.size() != 1
917     # corner case, bad model, concatenation of several plain strings
918     acceptor.accept(Issues::ILLEGAL_HOSTNAME_INTERPOLATION, o)
919   else
920     # corner case, may be ok, but lexer may have replaced with plain string, this is
921     # here if it does not
922     hostname_String(o.segments[0], o.segments[0])
923   end
924 end
hostname_LiteralDefault(o, semantic) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
938 def hostname_LiteralDefault(o, semantic)
939   # always ok
940 end
hostname_LiteralNumber(o, semantic) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
934 def hostname_LiteralNumber(o, semantic)
935   # always ok
936 end
hostname_LiteralRegularExpression(o, semantic) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
942 def hostname_LiteralRegularExpression(o, semantic)
943   # always ok
944 end
hostname_LiteralValue(o, semantic) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
907 def hostname_LiteralValue(o, semantic)
908   hostname_String(o.value.to_s, o)
909 end
hostname_Object(o, semantic) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
946 def hostname_Object(o, semantic)
947   acceptor.accept(Issues::ILLEGAL_EXPRESSION, o, {:feature => 'hostname', :container => semantic})
948 end
hostname_QualifiedName(o, semantic) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
926 def hostname_QualifiedName(o, semantic)
927   hostname_String(o.value.to_s, o)
928 end
hostname_QualifiedReference(o, semantic) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
930 def hostname_QualifiedReference(o, semantic)
931   hostname_String(o.value.to_s, o)
932 end
hostname_String(o, semantic) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
897 def hostname_String(o, semantic)
898   # The 3.x checker only checks for illegal characters - if matching /[^-\w.]/ the name is invalid,
899   # but this allows pathological names like "a..b......c", "----"
900   # TODO: Investigate if more illegal hostnames should be flagged.
901   #
902   if o =~ Patterns::ILLEGAL_HOSTNAME_CHARS
903     acceptor.accept(Issues::ILLEGAL_HOSTNAME_CHARS, semantic, :hostname => o)
904   end
905 end
idem(o) click to toggle source

Checks if the expression has side effect ('idem' is latin for 'the same', here meaning that the evaluation state is known to be unchanged after the expression has been evaluated). The result is not 100% authoritative for negative answers since analysis of function behavior is not possible. @return [Boolean] true if expression is known to have no effect on evaluation state

    # File lib/puppet/pops/validation/checker4_0.rb
133 def idem(o)
134   @@idem_visitor.visit_this_0(self, o)
135 end
idem_AccessExpression(o) click to toggle source
     # File lib/puppet/pops/validation/checker4_0.rb
1035 def idem_AccessExpression(o)
1036   true
1037 end
idem_ApplyExpression(o) click to toggle source

An apply expression exists purely for the side effect of applying a catalog somewhere, so it always has side effects

     # File lib/puppet/pops/validation/checker4_0.rb
1100 def idem_ApplyExpression(o)
1101   false
1102 end
idem_AssignmentExpression(o) click to toggle source
     # File lib/puppet/pops/validation/checker4_0.rb
1052 def idem_AssignmentExpression(o)
1053   # Always side effect
1054   false
1055 end
idem_BinaryExpression(o) click to toggle source
     # File lib/puppet/pops/validation/checker4_0.rb
1039 def idem_BinaryExpression(o)
1040   true
1041 end
idem_BlockExpression(o) click to toggle source
     # File lib/puppet/pops/validation/checker4_0.rb
1075 def idem_BlockExpression(o)
1076   # productive if there is at least one productive expression
1077   ! o.statements.any? {|expr| !idem(expr) }
1078 end
idem_CaseExpression(o) click to toggle source

Case expression is idem, if test, and all options are idem

     # File lib/puppet/pops/validation/checker4_0.rb
1109 def idem_CaseExpression(o)
1110   return false if !idem(o.test)
1111   ! o.options.any? {|opt| !idem(opt) }
1112 end
idem_CaseOption(o) click to toggle source

An option is idem if values and the then_expression are idem

     # File lib/puppet/pops/validation/checker4_0.rb
1115 def idem_CaseOption(o)
1116   return false if o.values.any? { |value| !idem(value) }
1117   idem(o.then_expr)
1118 end
idem_ConcatenatedString(o) click to toggle source

Returns true even though there may be interpolated expressions that have side effect. Report as idem anyway, as it is very bad design to evaluate an interpolated string for its side effect only.

     # File lib/puppet/pops/validation/checker4_0.rb
1083 def idem_ConcatenatedString(o)
1084   true
1085 end
idem_Factory(o) click to toggle source
     # File lib/puppet/pops/validation/checker4_0.rb
1031 def idem_Factory(o)
1032   idem(o.model)
1033 end
idem_HeredocExpression(o) click to toggle source

Heredoc is just a string, but may contain interpolated string (which may have side effects). This is still bad design and should be reported as idem.

     # File lib/puppet/pops/validation/checker4_0.rb
1089 def idem_HeredocExpression(o)
1090   true
1091 end
idem_IfExpression(o) click to toggle source
     # File lib/puppet/pops/validation/checker4_0.rb
1104 def idem_IfExpression(o)
1105   [o.test, o.then_expr, o.else_expr].all? {|e| idem(e) }
1106 end
idem_Literal(o) click to toggle source
     # File lib/puppet/pops/validation/checker4_0.rb
1019 def idem_Literal(o)
1020   true
1021 end
idem_LiteralHash(o) click to toggle source
     # File lib/puppet/pops/validation/checker4_0.rb
1027 def idem_LiteralHash(o)
1028   true
1029 end
idem_LiteralList(o) click to toggle source
     # File lib/puppet/pops/validation/checker4_0.rb
1023 def idem_LiteralList(o)
1024   true
1025 end
idem_MatchExpression(o) click to toggle source
     # File lib/puppet/pops/validation/checker4_0.rb
1043 def idem_MatchExpression(o)
1044   false # can have side effect of setting $n match variables
1045 end
idem_NilClass(o) click to toggle source
     # File lib/puppet/pops/validation/checker4_0.rb
1015 def idem_NilClass(o)
1016   true
1017 end
idem_Nop(o) click to toggle source
     # File lib/puppet/pops/validation/checker4_0.rb
1011 def idem_Nop(o)
1012   true
1013 end
idem_Object(o) click to toggle source
     # File lib/puppet/pops/validation/checker4_0.rb
1007 def idem_Object(o)
1008   false
1009 end
idem_ParenthesizedExpression(o) click to toggle source

Allow (no-effect parentheses) to be used around a productive expression

     # File lib/puppet/pops/validation/checker4_0.rb
1063 def idem_ParenthesizedExpression(o)
1064   idem(o.expr)
1065 end
idem_RelationshipExpression(o) click to toggle source
     # File lib/puppet/pops/validation/checker4_0.rb
1047 def idem_RelationshipExpression(o)
1048   # Always side effect
1049   false
1050 end
idem_RenderExpression(o) click to toggle source
     # File lib/puppet/pops/validation/checker4_0.rb
1067 def idem_RenderExpression(o)
1068   false
1069 end
idem_RenderStringExpression(o) click to toggle source
     # File lib/puppet/pops/validation/checker4_0.rb
1071 def idem_RenderStringExpression(o)
1072   false
1073 end
idem_SelectorExpression(o) click to toggle source

May technically have side effects inside the Selector, but this is bad design - treat as idem

     # File lib/puppet/pops/validation/checker4_0.rb
1094 def idem_SelectorExpression(o)
1095   true
1096 end
idem_UnaryExpression(o) click to toggle source

Handles UnaryMinusExpression, NotExpression, VariableExpression

     # File lib/puppet/pops/validation/checker4_0.rb
1058 def idem_UnaryExpression(o)
1059   true
1060 end
initial_manifest?(path, manifest_setting) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
610 def initial_manifest?(path, manifest_setting)
611   return false if manifest_setting.nil? || manifest_setting == :no_manifest
612 
613   string_path = path.to_s
614 
615   string_path == manifest_setting || string_path.start_with?(manifest_setting)
616 end
internal_check_capture_last(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
503 def internal_check_capture_last(o)
504   accepted_index = o.parameters.size() -1
505   o.parameters.each_with_index do |p, index|
506     if p.captures_rest && index != accepted_index
507       acceptor.accept(Issues::CAPTURES_REST_NOT_LAST, p, {:param_name => p.name})
508     end
509   end
510 end
internal_check_file_namespace(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
536 def internal_check_file_namespace(o)
537   file = o.locator.file
538   return if file.nil? || file == '' #e.g. puppet apply -e '...'
539 
540   file_namespace = namespace_for_file(file)
541   return if file_namespace == NO_NAMESPACE
542 
543   # Downcasing here because check is case-insensitive
544   if file_namespace == BAD_MODULE_FILE || !o.name.downcase.start_with?(file_namespace)
545     acceptor.accept(Issues::ILLEGAL_DEFINITION_LOCATION, o, {:name => o.name, :file => file})
546   end
547 end
internal_check_future_reserved_word(o, name) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
526 def internal_check_future_reserved_word(o, name)
527   if FUTURE_RESERVED_WORDS[name]
528     acceptor.accept(Issues::FUTURE_RESERVED_WORD, o, {:word => name})
529   end
530 end
internal_check_illegal_assignment(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
777 def internal_check_illegal_assignment(o)
778   if o.is_a?(Model::AssignmentExpression)
779     acceptor.accept(Issues::ILLEGAL_ASSIGNMENT_CONTEXT, o)
780   else
781     # recursively check all contents unless it's a lambda expression. A lambda may contain
782     # local assignments
783     o._pcore_contents {|model| internal_check_illegal_assignment(model) } unless o.is_a?(Model::LambdaExpression)
784   end
785 end
internal_check_no_capture(o, container = o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
512 def internal_check_no_capture(o, container = o)
513   o.parameters.each do |p|
514     if p.captures_rest
515       acceptor.accept(Issues::CAPTURES_REST_NOT_SUPPORTED, p, {:container => container, :param_name => p.name})
516     end
517   end
518 end
internal_check_no_idem_last(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
496 def internal_check_no_idem_last(o)
497   violator = ends_with_idem(o.body)
498   if violator
499     acceptor.accept(Issues::IDEM_NOT_ALLOWED_LAST, violator, {:container => o}) unless resource_without_title?(violator)
500   end
501 end
internal_check_parameter_name_uniqueness(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
677 def internal_check_parameter_name_uniqueness(o)
678   unique = Set.new
679   o.parameters.each do |p|
680     acceptor.accept(Issues::DUPLICATE_PARAMETER, p, {:param_name => p.name}) unless unique.add?(p.name)
681   end
682 end
internal_check_reserved_params(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
669 def internal_check_reserved_params(o)
670   o.parameters.each do |p|
671     if RESERVED_PARAMETERS[p.name]
672       acceptor.accept(Issues::RESERVED_PARAMETER, p, {:container => o, :param_name => p.name})
673     end
674   end
675 end
internal_check_reserved_type_name(o, name) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
520 def internal_check_reserved_type_name(o, name)
521   if RESERVED_TYPE_NAMES[name]
522     acceptor.accept(Issues::RESERVED_TYPE_NAME, o, {:name => name})
523   end
524 end
internal_check_return_type(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
482 def internal_check_return_type(o)
483   r = o.return_type
484   internal_check_type_ref(o, r) unless r.nil?
485 end
internal_check_top_construct_in_module(prog) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
549 def internal_check_top_construct_in_module(prog)
550   return unless prog.is_a?(Model::Program) && !prog.body.nil?
551 
552   #Check that this is a module autoloaded file
553   file = prog.locator.file
554   return if file.nil?
555   return if namespace_for_file(file) == NO_NAMESPACE
556 
557   body = prog.body
558   return if prog.body.is_a?(Model::Nop) #Ignore empty or comment-only files
559 
560   if(body.is_a?(Model::BlockExpression))
561     body.statements.each { |s| acceptor.accept(Issues::ILLEGAL_TOP_CONSTRUCT_LOCATION, s) unless valid_top_construct?(s) }
562   else
563     acceptor.accept(Issues::ILLEGAL_TOP_CONSTRUCT_LOCATION, body) unless valid_top_construct?(body)
564   end
565 end
internal_check_type_ref(o, r) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
487 def internal_check_type_ref(o, r)
488   n = r.is_a?(Model::AccessExpression) ? r.left_expr : r
489   if n.is_a? Model::QualifiedReference
490     internal_check_future_reserved_word(r, n.value)
491   else
492     acceptor.accept(Issues::ILLEGAL_EXPRESSION, r, :feature => 'a type reference', :container => o)
493   end
494 end
namespace_for_file(file) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
582 def namespace_for_file(file)
583   env = Puppet.lookup(:current_environment)
584   return NO_NAMESPACE if env.nil?
585 
586   adapter = Puppet::Util::FileNamespaceAdapter.adapt(env)
587 
588   file_namespace = adapter.file_to_namespace[file]
589   return file_namespace unless file_namespace.nil? # No cache entry, so we do the calculation
590 
591   path = Pathname.new(file)
592 
593   return adapter.file_to_namespace[file] = NO_NAMESPACE if path.extname != ".pp"
594 
595   path = path.expand_path
596 
597   return adapter.file_to_namespace[file] = NO_NAMESPACE if initial_manifest?(path, env.manifest)
598 
599   #All auto-loaded files from modules come from a module search path dir
600   relative_path = get_module_relative_path(path, env.full_modulepath)
601 
602   return adapter.file_to_namespace[file] = NO_NAMESPACE if relative_path == NO_PATH
603 
604   #If a file comes from a module, but isn't in the right place, always error
605   names = dir_to_names(relative_path)
606 
607   return adapter.file_to_namespace[file] = (names == BAD_MODULE_FILE ? BAD_MODULE_FILE : names.join("::").freeze)
608 end
pattern_with_replacement?(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
439 def pattern_with_replacement?(o)
440   if o.is_a?(Model::LiteralList)
441     v = o.values
442     v.size == 2 && v[0].is_a?(Model::LiteralRegularExpression) && v[1].is_a?(Model::LiteralString)
443   else
444     false
445   end
446 end
query(o) click to toggle source

Performs check if this is valid as a query

   # File lib/puppet/pops/validation/checker4_0.rb
77 def query(o)
78   @@query_visitor.visit_this_0(self, o)
79 end
query_BooleanExpression(o) click to toggle source

Allows AND, OR, and checks if left/right are allowed in query.

    # File lib/puppet/pops/validation/checker4_0.rb
964 def query_BooleanExpression(o)
965   query o.left_expr
966   query o.right_expr
967 end
query_ComparisonExpression(o) click to toggle source

Puppet AST only allows == and !=

    # File lib/puppet/pops/validation/checker4_0.rb
959 def query_ComparisonExpression(o)
960   acceptor.accept(Issues::ILLEGAL_QUERY_EXPRESSION, o) unless ['==', '!='].include? o.operator
961 end
query_LiteralBoolean(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
981 def query_LiteralBoolean(o); end
query_LiteralNumber(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
977 def query_LiteralNumber(o); end
query_LiteralString(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
979 def query_LiteralString(o); end
query_Object(o) click to toggle source

Anything not explicitly allowed is flagged as error.

    # File lib/puppet/pops/validation/checker4_0.rb
953 def query_Object(o)
954   acceptor.accept(Issues::ILLEGAL_QUERY_EXPRESSION, o)
955 end
query_ParenthesizedExpression(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
969 def query_ParenthesizedExpression(o)
970   query(o.expr)
971 end
query_QualifiedName(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
975 def query_QualifiedName(o); end
query_VariableExpression(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
973 def query_VariableExpression(o); end
relation(o) click to toggle source

Performs check if this is valid as a relationship side

   # File lib/puppet/pops/validation/checker4_0.rb
82 def relation(o)
83   @@relation_visitor.visit_this_0(self, o)
84 end
relation_CollectExpression(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
760 def relation_CollectExpression(o); end
relation_Object(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
756 def relation_Object(o)
757   rvalue(o)
758 end
relation_RelationshipExpression(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
762 def relation_RelationshipExpression(o); end
resource_without_title?(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
256 def resource_without_title?(o)
257   if o.instance_of?(Model::BlockExpression)
258     statements = o.statements
259     statements.length == 2 && statements[0].instance_of?(Model::QualifiedName) && statements[1].instance_of?(Model::LiteralHash)
260   else
261     false
262   end
263 end
rvalue(o) click to toggle source

Performs check if this is valid as a rvalue

   # File lib/puppet/pops/validation/checker4_0.rb
87 def rvalue(o)
88   @@rvalue_visitor.visit_this_0(self, o)
89 end
rvalue_CollectExpression(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
990 def rvalue_CollectExpression(o)
991   acceptor.accept(Issues::NOT_RVALUE, o)
992 end
rvalue_Definition(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
994 def rvalue_Definition(o)
995   acceptor.accept(Issues::NOT_RVALUE, o)
996 end
rvalue_Expression(o) click to toggle source

By default, all expressions are reported as being rvalues Implement specific rvalue checks for those that are not.

    # File lib/puppet/pops/validation/checker4_0.rb
988 def rvalue_Expression(o); end
rvalue_NodeDefinition(o) click to toggle source
     # File lib/puppet/pops/validation/checker4_0.rb
 998 def rvalue_NodeDefinition(o)
 999   acceptor.accept(Issues::NOT_RVALUE, o)
1000 end
rvalue_UnaryExpression(o) click to toggle source
     # File lib/puppet/pops/validation/checker4_0.rb
1002 def rvalue_UnaryExpression(o)
1003   rvalue o.expr
1004 end
top(definition, idx = -1) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
 93 def top(definition, idx = -1)
 94   o = container(idx)
 95   idx -= 1
 96   case o
 97   when NilClass, Model::ApplyExpression, Model::HostClassDefinition, Model::Program
 98     # ok, stop scanning parents
 99   when Model::BlockExpression
100     c = container(idx)
101     if !c.is_a?(Model::Program) &&
102       (definition.is_a?(Model::FunctionDefinition) || definition.is_a?(Model::TypeAlias) || definition.is_a?(Model::TypeDefinition))
103 
104       # not ok. These can never be nested in a block
105       acceptor.accept(Issues::NOT_ABSOLUTE_TOP_LEVEL, definition)
106     else
107       # ok, if this is a block representing the body of a class, or is top level
108       top(definition, idx)
109     end
110   when Model::LambdaExpression
111     # A LambdaExpression is a BlockExpression, and this check is needed to prevent the polymorph method for BlockExpression
112     # to accept a lambda.
113     # A lambda can not iteratively create classes, nodes or defines as the lambda does not have a closure.
114     acceptor.accept(Issues::NOT_TOP_LEVEL, definition)
115   else
116     # fail, reached a container that is not top level
117     acceptor.accept(Issues::NOT_TOP_LEVEL, definition)
118   end
119 end
type_ref?(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
448 def type_ref?(o)
449   o = o.left_expr if o.is_a?(Model::AccessExpression)
450   o.is_a?(Model::QualifiedReference)
451 end
valid_top_construct?(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
567 def valid_top_construct?(o)
568   o.is_a?(Model::Definition) && !o.is_a?(Model::NodeDefinition)
569 end
validate(model) click to toggle source

Validates the entire model by visiting each model element and calling `check`. The result is collected (or acted on immediately) by the configured diagnostic provider/acceptor given when creating this Checker.

   # File lib/puppet/pops/validation/checker4_0.rb
53 def validate(model)
54   # tree iterate the model, and call check for each element
55   @path = []
56   check(model)
57   internal_check_top_construct_in_module(model)
58   model._pcore_all_contents(@path) { |element| check(element) }
59 end
varname_to_s(o) click to toggle source

Produces string part of something named, or nil if not a QualifiedName or QualifiedReference

     # File lib/puppet/pops/validation/checker4_0.rb
1124 def varname_to_s(o)
1125   case o
1126   when Model::QualifiedName
1127     o.value
1128   when Model::QualifiedReference
1129     o.value
1130   else
1131     nil
1132   end
1133 end

Private Instance Methods

get_module_relative_path(file_path, modulepath_directories) click to toggle source

Get the path of file_path relative to the first directory in modulepath_directories that is an ancestor of file_path. Return NO_PATH if none is found.

    # File lib/puppet/pops/validation/checker4_0.rb
621 def get_module_relative_path(file_path, modulepath_directories)
622   clean_file = file_path.cleanpath.to_s
623   parent_path = modulepath_directories.find { |path_dir| is_parent_dir_of(path_dir, clean_file) }
624   return NO_PATH if parent_path.nil?
625 
626   file_path.relative_path_from(Pathname.new(parent_path))
627 end
is_parent_dir_of(parent_dir, child_dir) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
630 def is_parent_dir_of(parent_dir, child_dir)
631   parent_dir_path = Pathname.new(parent_dir)
632   clean_parent = parent_dir_path.cleanpath.to_s + File::SEPARATOR
633 
634   return child_dir.start_with?(clean_parent)
635 end