(#7749) Reduce weird scope cycles when bootstrapping settings

This commit is a first step towards cleaning up the way that settings
are loaded when puppet is bootstrapped.

A major symptom of the old load order was that if you do a 'require "puppet"'
too early in your code, everything will break because the defaults will
be screwed up.

This commit does not represent an ideal (or probably even a 'good') solution,
it just tweaks a few things in order to make a more meaningful cleanup
possible.

Specifically:

* Makes the ":mutable_defaults" class of settings more sticky, so that they
  are actually used when interpolating settings
* Simplify resolution of run modes for legacy application names; previous
  implementation required *ALL* available apps to actually be fully parsed
  and loaded in order to resolve these, and that introduced some challenging
  bootstrap dependency cycles.
Add lib_trollop.rb, an alternative implementation of an option / cli parser
(#7749) Parse command line args and config file before loading app/face

This commit is mostly focused on solving the following chicken-and-egg
problem: the way the code worked before, the command_line class would
try to load an app before doing any parsing of the cli args or the
puppet config file.  However, we want to support being able to load apps
and faces from the libdir... and if your libdir is in a non-standard
location, which you've specified via the command line or config file, then
the command_line class would fail to find any apps that were in your
libdir and exit before it ever even looked at the cli args or the config
file.

To get around this, and to prepare for supporting the ability to run
faces without an application stub, we needed to move the parsing of
the cli args and config file to an earlier point in the lifecycle.

The major changes in this commit are:

* Move the initial parsing of the cli args and the config file out of
application.rb and into command_line.rb so that they happen before
puppet tries to locate apps/faces.

* Remove all of the "should_parse_config" and "should_not_parse_config"
options and tests from the various apps.  These are not relevant any
longer because we always need to parse the config file to make sure
we know where the libdir is before we try to load faces / apps.

* Introduce a new option parser implementation, to supplement and
perhaps eventually replace our use of the Ruby stdlib OptionParser.
The stdlib OptionParser has some very undesirable behaviors that
are not configurable; the new PuppetOptionParser is a wrapper
around an open source parser called "trollop"; it maintains the
same API that OptionParser exposes, but gives us complete control
over what is happening behind the scenes.

Conflicts:

	spec/unit/util/command_line_spec.rb
(#7749) Improvements to handling settings, bootstrapping puppet

Major changes include:

* support multiple config files (/etc/puppet, ~/.puppet).  we no longer
use "run_mode" to determine the location of the config file.
* remove all references to application run_mode/state from defaults
* make the typing of settings a little more strict
* create a new setting type for directories, to make us a little less vulnerable to the terrible matching algorithm in FileSetting
(#7749) get rid of "set_run_mode" method in Application class

The "set_run_mode" method in the Application class made it a little
too easy to do dangerous / scary things to the main application
state during run time.  Get rid of this method and provide slightly
more controlled ways to accomplish the necessary goals.
(#7749) get rid of $puppet_application_name and $puppet_application_mode globals

This state is now handled via instance variables in the Settings class.
(#7749) rename "Settings#setdefaults" to "define_settings"

This is just to clarify the intent of the code, mostly in defaults.rb.
The old signature still exists, but prints a deprecation warning.
(#7749) doc / tests cleanup
Merge pull request #571 from puppetlabs/integration/master/7749-bootstrapping-puppet

(#7749) improve bootstrapping puppet to support pluginsync apps.
Add comment with URL of upstream pull request for trollop

Submitted a patch to the upstream trollop library, in hopes
that these changes will get included and we won't have our
own custom fork of the project.  Added this to the comments
for visibility.
Merge pull request #590 from cprice-puppet/cleanup/master/trollop_pull_request

Add comment with URL of upstream pull request for trollop
Add a feature to detect RDoc 1.0.1 being present on the system.

In practice the Puppet manifest documentation generator only works with the
version of RDoc that ships with Ruby 1.8 - version 1.0.1, which was identical
in 1.8.5 ad 1.8.7.

Previously, because it was a core library, we just assumed it was present; now
we need to test conditionally for it being there *and* the correct version.

That allows us to have a nicer failure mode as we work through rdoc use, to
clearly indicate to users which version we have.  As we support newer
versions, additional features can better identify what is available.

Signed-off-by: Daniel Pittman <daniel@puppetlabs.com>
Fix 4-space indentation in puppet/util/rdoc.rb

There are no functional changes to this commit, just whitespace changes.

Signed-off-by: Daniel Pittman <daniel@puppetlabs.com>
Document and cleanly fail when unsupported RDoc is used.

Update the documentation and code to fail cleanly when a supported version of
RDoc is not available.

This does not yet tackle loading an RDoc version specific implementation of
the process, only a clean failure when we can't cope.  In future this should
be replaced by some dynamic loading process based on the supported RDoc
version, if we retain the tool.

Signed-off-by: Daniel Pittman <daniel@puppetlabs.com>
Ruby 1.9.3 is strict about block argument counts.

Unlike earlier versions, Ruby 1.9 is strict about matching argument counts in
blocks with their uses.

Signed-off-by: Daniel Pittman <daniel@puppetlabs.com>
Ruby 1.9.3 has a different error when `require` fails.

The text of the error message when load fails has changed, resulting in the
test failing.  This adapts that to catch the different versions, allowing this
to pass in all cases.

Signed-off-by: Daniel Pittman <daniel@puppetlabs.com>
Simplify a YAML report test to work with Ruby 1.9

The order of invocation of local method definition and the parent `inherited`
hook changed between 1.8 and 1.9, resulting in the hack that works around a
development check in this test stopping working.

None of that ceremony is actually needed, though, since we can totally just
use an instance of the actual class we are testing.

Signed-off-by: Daniel Pittman <daniel@puppetlabs.com>
Don't cache check for `cdrom` source in the apt provider.

Ruby 1.9 warned about access to a class variable in providers, because their
semantics are almost never what users expect.

However, the use of a class variable in the apt provider was very strange: it
wanted to check if a cdrom source was specified, and fail if it was present,
to avoid a situation where apt would prompt for a CD to be inserted and hang
forever.

Since that is just as much a problem on the second package install as on the
first, it makes much more sense to perform this sanity check and fail before
every install - and the overall cost is relatively low.

Signed-off-by: Daniel Pittman <daniel@puppetlabs.com>
Avoid class level variables, as they are not helpful.

Ruby 1.9.3 highlights some of the strange and confusing problems around class
level variables in Ruby; they tend to look and behave much more like global
state than people imagine, and lead down the road to trouble.

This migrates away from them to other mechanisms better fitted to solving the
problem in the Ruby language - and, typically, in ways that are much more
portable between the different Ruby interpreter implementations.

Signed-off-by: Daniel Pittman <daniel@puppetlabs.com>
Revert "Disable replace_file on Windows"

This reverts commit 4272d1f7674911c15da3ff6516d5827646a6bda6.

To quote:

    Our current approach of setting owner/mode in the Puppet way risks
    losing any extra permissions beyond owner/group/everyone, which is
    significant enough that it is better to simply not support this
    operation until we have a better solution. replace_file isn't used in
    any code which actually runs on Windows at the moment, so this is
    a benign change.

...except that it isn't so benign as all that: various other parts of the code
open-code the same method, poorly, and with various different bugs.  They will
all, without question, lose permissions in exactly the same way on Windows.

At least by routing them through a central path we can start to unify their
behaviour and get to a place where fixing one point in the code fixes all the
faulty permission transfers that we previously had.

We win an overall net reduction in bug count, and an increase in
predictability of bugs, from this change.