(#13678) Convert command to absolute paths before executing

The former behaviour of facter is to allow passing commands to
Facter::Util::Resolution.exec where the executable is not an absolute
pathname. To check if the executable is present on the system facter would
then run %{which commandname}. As a result we end up with two shell
invocations just to run a single command.

The fix now tries to convert the executable of the command into an
absolute pathname so we can easiliy check with the File.executable?
method if we can try to run the command.

The two methods `which` and `absolute_path?` are adopted from puppet
which claim to run on both windows and unix systems. This is great
because we do not have to distinct between the platforms in the exec
method anymore.
(#13678) Add RDoc documentation for new methods

The refactor on #13678 introduced new methods:

    Facter::Util::Resolution::search_paths
    Facter::Util::Resolution::which
    Facter::Util::Resolution::absolute_path?
    Facter::Util::Resolution::expand_command

Add documentation for those.
(#13678) Add more unit tests for new methods

There is currently one bug in `expand_command` shown by a test marked as
pending:

When `expand_command` is run with e.g. "foo.exe" `expand_command` tries to
replace the binary foo.exe with a full path to foo. If foo is now found
in a path that contains spaces, `expand_command` doesn't escape these.

So `expand_command('foo.exe /a')` might return `C:\My Tools\foo.exe /a` when
it probably should return `"C:\My Tools\foo.exe" /a`
(#13678) Fix quoting in expand_command

If the expand_command method is called with a commandline where the
binary is not specified with as an absolute pathname, expand_command
will determine the absolute pathname by calling the `which` method. The
full pathname to the binary may include spaces (especially on windows).

Since expand_command should return a commandline that is ready to be run by
the shell it has to add quotes around the binary if the pathname contains
spaces.
(#13678) Fix spec failures on windows

Facter now tries to expand commands before running them. As a sideeffect
we can no longer run shell-builtins directly since facter is not able to
find it in the filesystem. This broke a few spec tests that assumed we
can run "echo foo" on both unix and windows.

The fix now explicitly calls the shell (cmd.exe) to run the echo
builtin. On Unix we already have a native echo (most likely /bin/echo).

Note: The former implementation did allow windows builtins but did not
allow unix buildins because the former implementation used `which` to
check if we can run a command on unix and `which` does not work on
builtins.
maint: Add shared context for specs to imitate windows or posix

Add "windows" and "posix" shared contexts to rspec. The shared context
was borrowed from the puppet codebase. If you give :as_platform =>
:posix or :as_platform => :windows as an argument to a describe block or
a context block, it will stub is_windows, File::SEPARATOR, and
File::ALT_SEPARATOR. In addition to puppets shared_context it will also
stub File::PATH_SEPARATOR
(#13678) Extend spec tests for expand_command

The spec tests for expand_command and exec were restructured to make use
of the new shared_beviour :as_platform to have more accurate tests and
were also restructured to reduce code duplication.

These reveal a few open issues:

* on windows, facter should continue to support shell buildins which is
  currently not the case
* on unix, facter should quote binaries that are found in a path with
  spaces in single quotes, not double quotes
* on windows, we trusted File.join('C:','Windows') to return C:\Windows
  which is not the case. File.join uses File::SEPARATOR ('/' on windows)
  and not File::ALT_SEPARATOR ('\' on windows).

The issues will be addressed in a following commit
(#13678) Join PATHs correctly on windows

On windows File.join joins with the File::SEPARATOR which is '/' on
windows. While a lot of the windows API and the ruby filetests allow
/ as a separator we should use File::ALT_SEPARATOR ('\' on windows) to
create pathnames on windows
(#13678) Single quote paths on unix with spaces

If we want to execute a command foo which is found in a path with spaces
we have to quote the path in order to be able to pass the command to the
shell.

Instead of using double quotes we should use single quotes on unix. On
windows only double quotes are valid
(#13678) Allow passing shell built-ins to exec method on windows

The former exec method tried to run the command on windows no matter
wether it could be found on the filesystem or not. This allowed end
users to run shell-builtins with the exec method.

The new exec method always tried to expand the binary first and returned
nil if the binary was not found. This commit now restores the old
behaviour on windows: Even if we fail to expand the command, we will try
to run the command in the exact same way as it was passed to the exec
method in case it is indeed a shell built-in. But we will now raise a
deprecation warning.

Reason for deprecating this "even if we cannot find it, just run it"
behaviour: We may want to predetermine the paths where facter tries to find
binaries in the future. A fall back behaviour may then lead to strange
results. Most built-ins can be expressed in pure ruby anyways.
(#13678) Add filename extension on absolute paths on windows

Running Facter::Util::Resolution.exec calls
Facter::Util::Resolution.which to get the absolute pathname to a binary.
If passing a relative path, puppet will check different search paths and
different filename extensions (like .com, .exe) to find the absolute
path on windows machines

For absolute paths the former behaviour was to just return true if the
path is a valid path to an executable, so "C:\Windows\System32\netsh"
was treated as invalid because it misses the correct extension
(netsh.exe) which caused the ipaddress6 fact to fail.

Change the behaviour of Facter::Util::Resolution.which to also try out
the different filename extensions if an absolute path is used.
(#13678) Remove deprecation msg triggerd by the ipaddress6 fact

Facter::Util::Resolution.exec tries to get the expanded path to the
binary by calling Facter::Util::Resolution.which. This works for
relative commands (if the command is found in PATH). If the binary
describes an absolute path on windows but lacks a filename extension
Facter::Util::Resolution.which will also try to find the correct
extension, so the final binary passes a File.executable? check.

However, this behaviour (passing an absolute path but omit the
extension) is marked as deprecated.

Remove every occurence of Facter::Util::Resolution.exec where a binary
is passed without the correct filename extension.