Prior to this commit, if a box some how got on disk that had an
incorrect or invalid version number that did not match Gem::Version,
Vagrant would throw an exception when attempting to generate a list of
the boxes on disk. This commit fixes that by looking at the version from
the path generated, and shows a warning to the user about the box and
skips it from the list so they at least know about the problematic box
and can still get a list of boxes.
This is required since Gem::Version will mangle pre-release version
numbers.
To get around this, we keep a mapping of
`Gem::Version.to_s => versiondir.`
This allows us to properly sort by version when picking a box while
still returning pristine versiondirs when required.
The docs for Ruby say Pathname#rmtree will recursively delete, but
apparently that is a lie, at least on Windows (see GH-7496). Switch to
using FileUtils to ensure the directory is deleted.
Fixes GH-7496
Without this change, the version string may be mutated when passed through
Gem::Version.new(version).to_s before being used to construct the box
directory. This is a problem when using prerelease version numbers because,
for example, it will look for "~/.vagrant.d/boxes/1.0.0.pre.alpha.1" when it
should be looking for "~/.vagrant.d/boxes/1.0.0-alpha.1".
Now we have different providers, but the error message didn't tell
anything about it. Suppose I want to remove one of my boxes:
vagrant box remove opscode-ubuntu-12.04 vritualbox
There is a typo in provider name. The error message is:
Box 'opscode-ubuntu-12.04' could not be found.
Therefore I need to double check the box name, and only than I will see
the typo.
This commit make the error message looks like this:
Box 'opscode-ubuntu-12.04' with 'vritualbox' provider could not be
found.
The Dir.mkdir statement fails on Windows if src and dest
reside on different partitions. Files are therefore copied
one-by-one. The #6715 workaround is not needed anymore.