puppetlabs/puppet — pull request #310 by nicklewis (2012-01-06 23:59:27+00:00)
Title: Fix stage inheritance between multiple included classes 

Commit 656eff8 introduced a regression whereby stages would only
propagate from a class to its direct descendants, and no further. This
means if a class A includes B which includes C, the stage specified for
class A would only be used for A and B, and would omit C.

This was due to a logic error around the recursive nature of class
evaluation. We would evaluate the outermost class, and while doing so,
would evaluate its children, and etc. The step after evaluate was to set
up the stage relationship, which would then happen in reverse order
(C and then B and then A) as the stack was unwound. This meant that C
would try to set its stage, see that it had no specified stage, and try
to use its parent's stage (B). B also had no specified stage,
so C fell back to main. The next step in the stack, however, was to set
B's stage, which would then be inherited from A.

The purpose for the breaking change was to move stage setup after
parameters were set, so that defaults could be used to set stage. So now
we move stage setup back a bit in processing, between parameter setup and
actual evaluation of the contained code (which is the step which will
eventually evaluate the children). This achieves the desired effect of
setting stages after parameters, but also correctly sets stages in
top-down order, allowing them to cascade naturally.

Included in this is a small change during compiler setup to add the
Settings class to the catalog *before* evaluate_code is called. This is
because evaluate_code will now add the class to the main stage, which
requires the resource know about its catalog. Since Settings is never
really executed on the agent in a meaningful way, adding it to stage
main has no practical effect, so this is a safe change.