(PUP-2692) Cache function info with the functions

The Puppet::Parser::Functions code used to hold onto two different sets
of information about the loaded functions: a hash of environment name to
environment module, and a hash of *environment* to a hash of function
name to function information. It was assumed that the
Puppet::Node::Environment class was written to properly work as a hash
key since it implemented both hash() and ==(). This assumption being
true would have meant that different instances for the same environment
would be the same key and the second hash above would not grow beyond a
reasonable size for the number of environments.

It turns out that to be a proper hash key a class must implement hash()
and eql?() (not ==()). Because Puppet::Node::Environment didn't do this
the hash of function information would just continually grow when
directory environments with an environment_timeout != unlimited was in
use. This is because the Puppet::Node::Environment instance would be
periodically thrown out by the Puppet::Environments::Cached loader and
be recreated, but the Puppet::Parser::Functions hash would hold onto the
old instance.

The fix for this here is to consolidate all of the function information
into a single structure. The function modules now have a few methods to
get the function metadata instead of it being stored separately. This is
completely backwards compatible and does not conflict with any existing
uses of the environment modules since the new methods are on the module
itself and will not be part of the mixin.
(PUP-2692) Correctly implement environment equality

This fixes environment equality to make it work as a hash key. It also
adds tests around this functionality.
Merge pull request #2714 from zaphod42/issue/stable/pup-2692-memory-leak-in-master

(PUP-2692) Fix memory leak in directory environments
(maint) Update file mode for future parser

The future parser preserves number literals as actual numbers. This
causes problems for modes on file resources because 640 is the decimal
number 640 and not the octal 640.
(maint) Stop leaking file handles

File.new(f) results in a file handle being used. The test manifest in
this case ended up leaking file handles which caused the master to run
out of file handles while serving a request. This lead to a consistent
failure on the first thread requesting the catalog where the error
reported was:

  Could not autoload puppet/type/notify: no such file to load -- /usr/lib/ruby/site_ruby/1.8/puppet/type/notify.rb

The error was misleading. The underlying problem was not an ENOENT, but
an EMFILE (Too many open files). By switching to File.read(f) the
manifest will no longer leak file handles.
Merge remote-tracking branch 'upstream/stable'

* upstream/stable:
  (maint) Stop leaking file handles
  (maint) Update file mode for future parser
  (PUP-2692) Correctly implement environment equality
  (PUP-2692) Cache function info with the functions
(PUP-2577) Fix version comparison for OS X >= 10.10
Merge pull request #2726 from kylog/issue/pup-2577/osx-version-compare-fix

(PUP-2577) Fix version comparison for OS X >= 10.10
(PUP-2583) mode attribute of file type does not behave like chmod when given X

When changing permissions with puppet file type and using symbolic permissions e.g: g+rX, puppet consideres everything as directory. Which is wrong, because you can specify different set of permissions for directory and file (triggered by case of the letter you use).

Problem originates in ruby && and "and" operator precedence. Which was incorrectly used in this case.
(PUP-2583) Add example to test for +X mode changes in file types.

Adding an example to test applying mode +X to files.  For files, a mode
change of +X changes the requested executable bit only if there is
already an executable bit set in the permissions.
(maint) Remove unnecessary setting of modulepath from face help spec

The integration spec checking help output for the faces was setting
modulepath directly in the body of an RSpec context block.  This caused
modulepath to be set on test file load.  Normally, this is not an issue,
since most specs are not sensitive to the Puppet modulepath setting, and
the test_helper clears all settings in its after_each_test hook.
However, a recent run of specs on Solaris master just happened to run
with the very first spec being sensitive to modulepath
(spec/integration/directory_environments_spec.rb) which then failed.
Fortunately, the current version of puppet no longer requires this early
setting of modulepath for the documentation spec to run, so I'm just
removing it here.
Merge branch 'pr/2728'

* pr/2728:
  (PUP-2583) Add example to test for +X mode changes in file types.
  (PUP-2583) mode attribute of file type does not behave like chmod when given X

This closes GH-2728.