(#8954) Split out cygwin path and ensure bin exists

This commit splits out the msys2 and cygwin path functions for
expanding a path with the cygpath tool. It also ensures that the tool
itself exists when the Which class is called so that it doesn't attempt
to escape slashes on nil.
This commit is contained in:
Brian Cain 2017-09-13 15:10:55 -07:00
parent 7bb3bd702e
commit 3c9e1c9d84
2 changed files with 52 additions and 12 deletions

View File

@ -98,21 +98,20 @@ module Vagrant
end end
# This takes any path and converts it from a Windows path to a # This takes any path and converts it from a Windows path to a
# Cygwin or msys style path. # Cygwin style path.
# #
# @param [String] path # @param [String] path
# @return [String] # @return [String]
def cygwin_path(path) def cygwin_path(path)
begin begin
# We have to revert to the old env
# path here, otherwise it looks like
# msys2 ends up using the wrong cygpath
# binary and ends up with a `/cygdrive`
# when it doesn't exist in msys2
original_path_env = ENV['PATH']
ENV['PATH'] = ENV['VAGRANT_OLD_ENV_PATH']
cygpath = Vagrant::Util::Which.which("cygpath") cygpath = Vagrant::Util::Which.which("cygpath")
cygpath.gsub!("/", '\\') if cygpath.nil?
# If Which can't find it, just attempt to invoke it directly
cygpath = "cygpath"
else
cygpath.gsub!("/", '\\')
end
process = Subprocess.execute( process = Subprocess.execute(
cygpath, "-u", "-a", path.to_s) cygpath, "-u", "-a", path.to_s)
return process.stdout.chomp return process.stdout.chomp
@ -125,14 +124,29 @@ module Vagrant
"--norc", "--norc",
"-c", "cd #{Shellwords.escape(path)} && pwd") "-c", "cd #{Shellwords.escape(path)} && pwd")
return process.stdout.chomp return process.stdout.chomp
end
end
# This takes any path and converts it from a Windows path to a
# msys style path.
#
# @param [String] path
# @return [String]
def msys_path(path)
begin
# We have to revert to the old env
# path here, otherwise it looks like
# msys2 ends up using the wrong cygpath
# binary and ends up with a `/cygdrive`
# when it doesn't exist in msys2
original_path_env = ENV['PATH']
ENV['PATH'] = ENV['VAGRANT_OLD_ENV_PATH']
cygwin_path(path)
ensure ensure
ENV['PATH'] = original_path_env ENV['PATH'] = original_path_env
end end
end end
# Identical to cygwin_path for now
alias_method :msys_path, :cygwin_path
# This takes any path and converts it to a full-length Windows # This takes any path and converts it to a full-length Windows
# path on Windows machines in Cygwin. # path on Windows machines in Cygwin.
# #

View File

@ -22,10 +22,36 @@ describe Vagrant::Util::Platform do
allow(Vagrant::Util::Which).to receive(:which).and_return("C:/msys2/cygpath") allow(Vagrant::Util::Which).to receive(:which).and_return("C:/msys2/cygpath")
allow(Vagrant::Util::Subprocess).to receive(:execute).and_return(subprocess_result) allow(Vagrant::Util::Subprocess).to receive(:execute).and_return(subprocess_result)
expect(Vagrant::Util::Subprocess).to receive(:execute).with("C:\\msys2\\cygpath", "-u", "-a", "C:\\msys2\\home\\vagrant")
expect(subject.cygwin_path(path)).to eq("/home/vagrant") expect(subject.cygwin_path(path)).to eq("/home/vagrant")
end end
end end
describe "#msys_path" do
let(:updated_path) { "/home/vagrant" }
let(:subprocess_result) do
double("subprocess_result").tap do |result|
allow(result).to receive(:exit_code).and_return(0)
allow(result).to receive(:stdout).and_return(updated_path)
end
end
let(:old_path) { "/old/path/bin:/usr/local/bin:/usr/bin" }
it "takes a windows path and returns a formatted path" do
path = ENV["PATH"]
allow(Vagrant::Util::Which).to receive(:which).and_return("C:/msys2/cygpath")
allow(Vagrant::Util::Subprocess).to receive(:execute).and_return(subprocess_result)
allow(ENV).to receive(:[]).with("PATH").and_return(path)
allow(ENV).to receive(:[]).with("VAGRANT_OLD_ENV_PATH").and_return(old_path)
expect(Vagrant::Util::Subprocess).to receive(:execute).with("C:\\msys2\\cygpath", "-u", "-a", path)
expect(subject.msys_path(path)).to eq("/home/vagrant")
expect(ENV["PATH"]).to eq(path)
end
end
describe "#cygwin?" do describe "#cygwin?" do
before do before do
allow(subject).to receive(:platform).and_return("test") allow(subject).to receive(:platform).and_return("test")