Skip to content

Commit

Permalink
fix(powershell): use pwsh if available (#782)
Browse files Browse the repository at this point in the history
  • Loading branch information
williamboman committed Dec 21, 2022
1 parent dd04b41 commit 8240d7d
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 7 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ The _minimum_ recommended requirements are:

- neovim `>= 0.7.0`
- For Unix systems: `git(1)`, `curl(1)` or `wget(1)`, `unzip(1)`, `tar(1)`, `gzip(1)`
- For Windows systems: powershell, git, tar, and [7zip][7zip] or [peazip][peazip] or [archiver][archiver] or [winzip][winzip] or [WinRAR][winrar]
- For Windows systems: pwsh or powershell, git, tar, and [7zip][7zip] or [peazip][peazip] or [archiver][archiver] or [winzip][winzip] or [WinRAR][winrar]

Note that `mason.nvim` will regularly shell out to external package managers, such as `cargo` and `npm`. Depending on
your personal usage, some of these will also need to be installed. Refer to `:checkhealth mason` for a full list.
Expand Down
4 changes: 2 additions & 2 deletions doc/mason.txt
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ perfect substitutes). The _minimum_ recommended requirements are:
- neovim `>= 0.7.0`
- For Unix systems: `git(1)`, `curl(1)` or `wget(1)`, `unzip(1)`, `tar(1)`,
`gzip(1)`
- For Windows systems: powershell, git, tar, and 7zip or peazip or archiver
or winzip or WinRAR
- For Windows systems: pwsh or powershell, git, tar, and 7zip or peazip or
archiver or winzip or WinRAR

Note that Mason will regularly shell out to external package managers,
such as `cargo` and `npm`. Depending on your personal usage, some of these
Expand Down
6 changes: 4 additions & 2 deletions lua/mason-core/managers/powershell/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,16 @@ local PWSHOPT = {
security_protocol = [[ [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; ]],
}

local powershell = vim.fn.executable "pwsh" == 1 and "pwsh" or "powershell"

---@param script string
---@param opts JobSpawnOpts?
---@param custom_spawn JobSpawn?
function M.script(script, opts, custom_spawn)
opts = opts or {}
---@type JobSpawn
local spawner = custom_spawn or spawn
return spawner.powershell(vim.tbl_extend("keep", {
return spawner[powershell](vim.tbl_extend("keep", {
"-NoProfile",
on_spawn = function(_, stdio)
local stdin = stdio[1]
Expand All @@ -35,7 +37,7 @@ function M.command(command, opts, custom_spawn)
opts = opts or {}
---@type JobSpawn
local spawner = custom_spawn or spawn
return spawner.powershell(vim.tbl_extend("keep", {
return spawner[powershell](vim.tbl_extend("keep", {
"-NoProfile",
"-Command",
PWSHOPT.progress_preference .. PWSHOPT.security_protocol .. command,
Expand Down
12 changes: 10 additions & 2 deletions lua/mason/health/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -221,8 +221,16 @@ function M.check()
relaxed = platform.is.win,
},
check { cmd = "tar", args = { "--version" }, name = "tar" },
-- when(platform.is.win, check { cmd = "powershell.exe", args = { "-Version" }, name = "PowerShell" }), -- TODO fix me
-- when(platform.is.win, check { cmd = "cmd.exe", args = { "-Version" }, name = "cmd" }) -- TODO fix me
check {
cmd = "pwsh",
args = {
"-NoProfile",
"-Command",
[[$PSVersionTable.PSVersion, $PSVersionTable.OS, $PSVersionTable.Platform -join " "]],
},
name = "pwsh",
relaxed = not platform.is.win,
},
}

if platform.is.unix then
Expand Down
97 changes: 97 additions & 0 deletions tests/mason-core/managers/powershell_spec.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
local stub = require "luassert.stub"
local spy = require "luassert.spy"
local match = require "luassert.match"
local mock = require "luassert.mock"
local spawn = require "mason-core.spawn"

describe("powershell manager", function()
local function powershell()
package.loaded["mason-core.managers.powershell"] = nil
return require "mason-core.managers.powershell"
end

it("should use pwsh if available", function()
stub(spawn, "pwsh", function() end)
stub(spawn, "powershell", function() end)
stub(vim.fn, "executable")
vim.fn.executable.on_call_with("pwsh").returns(1)

powershell().command "echo 'Is this bash?'"

assert.spy(spawn.pwsh).was_called(1)
assert.spy(spawn.powershell).was_called(0)
end)

it(
"should use powershell if pwsh is not availble",
async_test(function()
stub(spawn, "pwsh", function() end)
stub(spawn, "powershell", function() end)
stub(vim.fn, "executable")
vim.fn.executable.on_call_with("pwsh").returns(0)

powershell().command "echo 'Is this bash?'"

assert.spy(spawn.pwsh).was_called(0)
assert.spy(spawn.powershell).was_called(1)
end)
)

it("should use the provided spawner for commands", function()
spy.on(spawn, "pwsh")
local custom_spawn = mock.new { pwsh = mockx.just_runs }
stub(vim.fn, "executable")
vim.fn.executable.on_call_with("pwsh").returns(1)
powershell().command("echo 'Is this bash?'", {}, custom_spawn)

assert.spy(spawn.pwsh).was_called(0)
assert.spy(custom_spawn.pwsh).was_called(1)
end)

it("should use the provided spawner scripts", function()
spy.on(spawn, "pwsh")
local custom_spawn = mock.new { pwsh = mockx.just_runs }
stub(vim.fn, "executable")
vim.fn.executable.on_call_with("pwsh").returns(1)
powershell().script("echo 'Is this bash?'", {}, custom_spawn)

assert.spy(spawn.pwsh).was_called(0)
assert.spy(custom_spawn.pwsh).was_called(1)
end)

it("should provide default powershell options via script stdin", function()
local stdin = mock.new { write = mockx.just_runs, close = mockx.just_runs }
stub(spawn, "pwsh", function(args)
args.on_spawn(nil, { stdin })
end)
stub(vim.fn, "executable")
vim.fn.executable.on_call_with("pwsh").returns(1)

powershell().script "echo 'Is this bash?'"

assert.spy(spawn.pwsh).was_called(1)
assert.spy(stdin.write).was_called(3)
assert.spy(stdin.write).was_called_with(match.is_ref(stdin), " $ProgressPreference = 'SilentlyContinue'; ")
assert
.spy(stdin.write)
.was_called_with(match.is_ref(stdin), " [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; ")
assert.spy(stdin.write).was_called_with(match.is_ref(stdin), "echo 'Is this bash?'")
assert.spy(stdin.close).was_called(1)
end)

it("should provide default powershell options via command interface", function()
stub(spawn, "pwsh", function() end)
stub(vim.fn, "executable")
vim.fn.executable.on_call_with("pwsh").returns(1)

powershell().command "echo 'Is this bash?'"

assert.spy(spawn.pwsh).was_called(1)
vim.pretty_print(spawn.pwsh)
assert.spy(spawn.pwsh).was_called_with(match.tbl_containing {
"-NoProfile",
"-Command",
" $ProgressPreference = 'SilentlyContinue'; [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; echo 'Is this bash?'",
})
end)
end)

0 comments on commit 8240d7d

Please sign in to comment.