(Maint) Stop changing internals of object during test

Previously the test depended on the internal implementation of
CommandLine (specifically the @args instance var) to control the test.
This makes the test very brittle. This changes it to use the public
interface of CommandLine.
(#7316) Use the public API for initializing settings

Previously the Puppet::Util::CommandLine code would use unpublished APIs
for initializing the application. Although this worked, it caused at
least two problems.
  1) The command line code was tied to the internals of puppet
  2) The public API could not actually be used for achieving what the
  command line code did

This commit changes the Puppet::Util::CommandLine class to start using
the public API of Puppet.initialize_settings for initializing puppet.
This required adding a new parameter to initialize_settings so that the
command line arguments could be passed in. It also required removing the
restriction that application_defaults can only be initialized once,
since the public behavior of the initialize_settings method is to
initialize both global and application settings at once.
(#7316) Load puppet/util as early as possible

Previously the puppet/util code was only loaded after the system had
been running. This pattern of loading has sometimes lead to bad
dependency cycles that have gone undetected. This moves the loading to
be earlier so that we can catch those kinds of problems if they come up.
(#7316) Do not try to require the application

The previous behavior of the CommandLine trying to load the application
is unneeded and duplicates what the Puppet::Application.find method
does. There is no need to do it. This commit removes CommandLine trying
to require the application.
(Maint) Remove distracting comments

The comments did nothing to elucidate the code. Removing them puts the
code closer together and easier to follow.
(#7316) Reorder subcommand handling logic

The previous logic for handling subcommands was a mixture of negation
and unless which made it hard to follow. This untangles it by nesting
the conditions in a more natural manner.
(Maint) Extract classes to handle different subcommand types

Previously the logic about how to find and execute the different kinds
of subcommands were all tied together in a single conditional structure.
This made it harder to isolate the different styles. This commit
extracts them out into individual classes for execution and a single
method to decide which execution class is needed for the given
subcommand.
(Maint) Remove unused instance variables
(#7316) Clarify parameters to construct a CommandLine

This adds documentation around the parameters that are to be passed to a
CommandLine constructor. It turns out that one of them is unused and so
the tests around it being special are removed and the documentation
states that it is unused.
(Maint) Pass the commandline as the application

Previously the :application_object that was passed to the plugin system
was actually the CommandLine. The refactoring around how to execute the
subcommands accidentally changed it to the subcommand instance because
of a missed reference to self. This changes it back to passing the
command line instance to the plugin system.

This maintains the old behavior even though it does not seem right that
the :application_object is actually the CommandLine.
(Maint) Simplify logic to find subcommand name

The previous logic around figuring out the subcommand name duplicated a
check for options and had an implicit check for an empty list of
arguments. This makes it more straightforward.
(Maint) Separate discovery of subcommand name from args

The discovery of subcommand and args was tied together. This separates
them and should make the rules around the subcommand name and the
arguments to that command a little clearer and independent of eachother.
(#7316) Document API used by CommandLine

This commit adds documentation to the methods and classes used by
CommandLine in order to bootstrap puppet, load an application, and
execute it.
(Maint) Create a mutation preserving wrapper for CommandLine

When the CommandLine class was changed to parse its options difference
and no longer hold onto a reference to the discovered options the
application option parsing code stopped working correctly because it
depended on being able to modify those values and have CommandLine hold
onto the modifications. This behavior caught be by surprise and took a
long time to track down where that occurred.

This commit preserves both the new behavior of CommandLine and the old
behavior of Application by creating a wrapper that can hold onto the
values from CommandLine in a manner that Application can modify, which
creates a separation between the two classes.
(#7316) Allow specifying the run_mode when initializing_settings

The previous interface for initializing the settings of puppet did not
allow for selecting the run mode, which is a very important aspect of
getting the right settings.

The mode to initialize the settings to is now a parameter to the
initializing_settings method and so users of puppet as a library should
be able to use it to initialize things in the manner they would like.