mirror of
https://github.com/hashicorp/vagrant.git
synced 2026-06-08 16:26:25 -04:00
Merge pull request #13648 from chrisroberts/pwsh-selection
Prefer pwsh executable over powershell excutable
This commit is contained in:
commit
387f5ba87d
3 changed files with 90 additions and 17 deletions
|
|
@ -19,7 +19,7 @@ module Vagrant
|
|||
# Number of seconds to wait while attempting to get powershell version
|
||||
DEFAULT_VERSION_DETECTION_TIMEOUT = 30
|
||||
# Names of the powershell executable
|
||||
POWERSHELL_NAMES = ["powershell", "pwsh"].map(&:freeze).freeze
|
||||
POWERSHELL_NAMES = ["pwsh", "powershell"].map(&:freeze).freeze
|
||||
# Paths to powershell executable
|
||||
POWERSHELL_PATHS = [
|
||||
"%SYSTEMROOT%/System32/WindowsPowerShell/v1.0",
|
||||
|
|
@ -33,11 +33,29 @@ module Vagrant
|
|||
# @return [String|nil] a powershell executable, depending on environment
|
||||
def self.executable
|
||||
if !defined?(@_powershell_executable)
|
||||
prefer_name = ENV["VAGRANT_PREFERRED_POWERSHELL"].to_s.sub(".exe", "")
|
||||
if !POWERSHELL_NAMES.include?(prefer_name)
|
||||
prefer_name = POWERSHELL_NAMES.first
|
||||
end
|
||||
|
||||
LOGGER.debug("preferred powershell executable name: #{prefer_name}")
|
||||
|
||||
# First start with detecting executable on configured path
|
||||
POWERSHELL_NAMES.detect do |psh|
|
||||
return @_powershell_executable = psh if Which.which(psh)
|
||||
psh += ".exe"
|
||||
return @_powershell_executable = psh if Which.which(psh)
|
||||
found_shells = Hash.new.tap do |found|
|
||||
POWERSHELL_NAMES.each do |psh|
|
||||
psh_path = Which.which(psh)
|
||||
psh_path = Which.which(psh + ".exe") if !psh_path
|
||||
next if !psh_path
|
||||
|
||||
LOGGER.debug("detected powershell for #{psh.inspect} - #{psh_path}")
|
||||
found[psh] = psh_path
|
||||
end
|
||||
end
|
||||
|
||||
# Done if preferred shell was found
|
||||
if found_shells.key?(prefer_name)
|
||||
LOGGER.debug("using preferred powershell #{prefer_name.inspect} - #{found_shells[prefer_name]}")
|
||||
return @_powershell_executable = found_shells[prefer_name]
|
||||
end
|
||||
|
||||
# Now attempt with paths
|
||||
|
|
@ -48,17 +66,29 @@ module Vagrant
|
|||
|
||||
paths.each do |psh_path|
|
||||
POWERSHELL_NAMES.each do |psh|
|
||||
next if found_shells.key?(psh)
|
||||
|
||||
path = File.join(psh_path, psh)
|
||||
return @_powershell_executable = path if Which.which(path)
|
||||
|
||||
path += ".exe"
|
||||
return @_powershell_executable = path if Which.which(path)
|
||||
|
||||
# Finally test the msys2 style path
|
||||
path = path.sub(/^([A-Za-z]):/, "/mnt/\\1")
|
||||
return @_powershell_executable = path if Which.which(path)
|
||||
[path, "#{path}.exe", path.sub(/^([A-Za-z]):/, "/mnt/\\1")].each do |full_path|
|
||||
if File.executable?(full_path)
|
||||
found_shells[psh] = full_path
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Done if preferred shell was found
|
||||
if found_shells.key?(prefer_name)
|
||||
LOGGER.debug("using preferred powershell #{prefer_name.inspect} - #{found_shells[prefer_name]}")
|
||||
return @_powershell_executable = found_shells[prefer_name]
|
||||
end
|
||||
|
||||
# Iterate names and return first found
|
||||
POWERSHELL_NAMES.each do |psh|
|
||||
LOGGER.debug("using powershell #{prefer_name.inspect} - #{found_shells[prefer_name]}")
|
||||
return @_powershell_executable = found_shells[psh] if found_shells.key?(psh)
|
||||
end
|
||||
end
|
||||
@_powershell_executable
|
||||
end
|
||||
|
|
@ -94,6 +124,7 @@ module Vagrant
|
|||
"-NoProfile",
|
||||
"-NonInteractive",
|
||||
"-ExecutionPolicy", "Bypass",
|
||||
"-Command",
|
||||
"#{env}&('#{path}')",
|
||||
args
|
||||
].flatten
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ describe Vagrant::Util::PowerShell do
|
|||
|
||||
describe ".executable" do
|
||||
before do
|
||||
allow(ENV).to receive(:[]).with("VAGRANT_PREFERRED_POWERSHELL").and_return(nil)
|
||||
allow(Vagrant::Util::Which).to receive(:which).and_return(nil)
|
||||
allow(Vagrant::Util::Subprocess).to receive(:execute) do |*args|
|
||||
Vagrant::Util::Subprocess::Result.new(0, args.last.sub("echo ", ""), "")
|
||||
|
|
@ -57,7 +58,7 @@ describe Vagrant::Util::PowerShell do
|
|||
|
||||
context "when powershell found in PATH" do
|
||||
before{ expect(Vagrant::Util::Which).to receive(:which).
|
||||
with("powershell").and_return(true) }
|
||||
with("powershell").and_return("powershell") }
|
||||
|
||||
it "should return powershell string" do
|
||||
expect(described_class.executable).to eq("powershell")
|
||||
|
|
@ -66,7 +67,7 @@ describe Vagrant::Util::PowerShell do
|
|||
|
||||
context "when pwsh found in PATH" do
|
||||
before { expect(Vagrant::Util::Which).to receive(:which).
|
||||
with("pwsh").and_return(true) }
|
||||
with("pwsh").and_return("pwsh") }
|
||||
|
||||
it "should return pwsh string" do
|
||||
expect(described_class.executable).to eq("pwsh")
|
||||
|
|
@ -74,6 +75,8 @@ describe Vagrant::Util::PowerShell do
|
|||
end
|
||||
|
||||
context "when not found in PATH" do
|
||||
before { allow(File).to receive(:executable?) }
|
||||
|
||||
it "should return nil" do
|
||||
expect(described_class.executable).to be_nil
|
||||
end
|
||||
|
|
@ -85,15 +88,46 @@ describe Vagrant::Util::PowerShell do
|
|||
|
||||
it "should return powershell.exe when found" do
|
||||
expect(Vagrant::Util::Which).to receive(:which).
|
||||
with("powershell.exe").and_return(true)
|
||||
with("powershell.exe").and_return("powershell.exe")
|
||||
expect(described_class.executable).to eq("powershell.exe")
|
||||
end
|
||||
|
||||
it "should check for powershell with full path" do
|
||||
expect(Vagrant::Util::Which).to receive(:which).with(/WindowsPowerShell\/v1.0\/powershell.exe/)
|
||||
expect(File).to receive(:executable?).with(/WindowsPowerShell\/v1.0\/powershell.exe/)
|
||||
described_class.executable
|
||||
end
|
||||
end
|
||||
|
||||
context "powershell preference" do
|
||||
before do
|
||||
allow(Vagrant::Util::Which).to receive(:which)
|
||||
allow(File).to receive(:executable?)
|
||||
end
|
||||
|
||||
it "should prefer pwsh found on in the PATH" do
|
||||
expect(Vagrant::Util::Which).to receive(:which).with("pwsh.exe").and_return("pwsh.exe")
|
||||
expect(described_class.executable).to eq("pwsh.exe")
|
||||
end
|
||||
|
||||
it "should use powershell.exe when found on PATH and pwsh.exe is not" do
|
||||
expect(Vagrant::Util::Which).to receive(:which).with("pwsh.exe").and_return("powershell.exe")
|
||||
expect(described_class.executable).to eq("powershell.exe")
|
||||
end
|
||||
|
||||
it "should prefer powershell.exe when env var is set and powershell.exe and pwsh.exe are on PATH" do
|
||||
expect(ENV).to receive(:[]).with("VAGRANT_PREFERRED_POWERSHELL").and_return("powershell")
|
||||
expect(Vagrant::Util::Which).to receive(:which).with("pwsh.exe").and_return("pwsh.exe")
|
||||
expect(Vagrant::Util::Which).to receive(:which).with("powershell.exe").and_return("powershell.exe")
|
||||
expect(described_class.executable).to eq("powershell.exe")
|
||||
end
|
||||
|
||||
it "should use pwsh.exe when env var is set to powershell but only pwsh.exe is avaialble" do
|
||||
expect(ENV).to receive(:[]).with("VAGRANT_PREFERRED_POWERSHELL").and_return("powershell")
|
||||
expect(Vagrant::Util::Which).to receive(:which).with("pwsh.exe").and_return("pwsh.exe")
|
||||
expect(Vagrant::Util::Which).to receive(:which).with("powershell.exe").and_return(nil)
|
||||
expect(described_class.executable).to eq("pwsh.exe")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe ".available?" do
|
||||
|
|
|
|||
|
|
@ -268,6 +268,14 @@ detection.
|
|||
When setting this environment variable, its value will be in seconds. By default,
|
||||
it will use 30 seconds as a timeout.
|
||||
|
||||
## `VAGRANT_PREFERRED_POWERSHELL`
|
||||
|
||||
When executing PowerShell commands, Vagrant will prefer to use `pwsh.exe`
|
||||
over `powershell.exe` by default. This environment variable can be used to
|
||||
modify this preference and make Vagrant prefer `powershell.exe`. The value
|
||||
set in this environment variable are any supported PowerShell executables
|
||||
which currently are: `powershell` and `pwsh`.
|
||||
|
||||
## `VAGRANT_PREFERRED_PROVIDERS`
|
||||
|
||||
This configures providers that Vagrant should prefer.
|
||||
|
|
|
|||
Loading…
Reference in a new issue