Skip to content

Commit

Permalink
feat(powershell): set $ErrorActionPreference = "Stop"; (#807)
Browse files Browse the repository at this point in the history
Also write to stdin pipe asynchronously.
  • Loading branch information
williamboman committed Dec 26, 2022
1 parent 5f6a3a3 commit e3d469e
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 20 deletions.
26 changes: 15 additions & 11 deletions lua/mason-core/managers/powershell/init.lua
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
local a = require "mason-core.async"
local spawn = require "mason-core.spawn"
local process = require "mason-core.process"

Expand All @@ -6,32 +7,35 @@ local M = {}
local PWSHOPT = {
progress_preference = [[ $ProgressPreference = 'SilentlyContinue'; ]], -- https://stackoverflow.com/a/63301751
security_protocol = [[ [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; ]],
error_action_preference = [[ $ErrorActionPreference = "Stop"; ]],
}

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

---@param script string
---@param opts JobSpawnOpts?
---@param opts SpawnArgs?
---@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", {
"-NoProfile",
on_spawn = function(_, stdio)
on_spawn = a.scope(function(_, stdio)
local stdin = stdio[1]
stdin:write(PWSHOPT.progress_preference)
stdin:write(PWSHOPT.security_protocol)
stdin:write(script)
stdin:close()
end,
local write = a.promisify(vim.loop.write)
write(stdin, PWSHOPT.error_action_preference)
write(stdin, PWSHOPT.progress_preference)
write(stdin, PWSHOPT.security_protocol)
write(stdin, script)
stdin:shutdown()
end),
env_raw = process.graft_env(opts.env or {}, { "PSMODULEPATH" }),
}, opts) --[[@as JobSpawnOpts]])
}, opts))
end

---@param command string
---@param opts JobSpawnOpts?
---@param opts SpawnArgs?
---@param custom_spawn JobSpawn?
function M.command(command, opts, custom_spawn)
opts = opts or {}
Expand All @@ -40,9 +44,9 @@ function M.command(command, opts, custom_spawn)
return spawner[powershell](vim.tbl_extend("keep", {
"-NoProfile",
"-Command",
PWSHOPT.progress_preference .. PWSHOPT.security_protocol .. command,
PWSHOPT.error_action_preference .. PWSHOPT.progress_preference .. PWSHOPT.security_protocol .. command,
env_raw = process.graft_env(opts.env or {}, { "PSMODULEPATH" }),
}, opts) --[[@as JobSpawnOpts]])
}, opts))
end

return M
27 changes: 18 additions & 9 deletions tests/mason-core/managers/powershell_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -60,23 +60,33 @@ describe("powershell manager", function()
end)

it("should provide default powershell options via script stdin", function()
local stdin = mock.new { write = mockx.just_runs, close = mockx.just_runs }
local stdin = mock.new { shutdown = mockx.just_runs }
stub(spawn, "pwsh", function(args)
args.on_spawn(nil, { stdin })
end)
stub(vim.fn, "executable")
stub(vim.loop, "write", function(_, _, callback)
callback()
end)
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(vim.loop.write).was_called(4)
assert
.spy(vim.loop.write)
.was_called_with(match.is_ref(stdin), [[ $ErrorActionPreference = "Stop"; ]], match.is_function())
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)
.spy(vim.loop.write)
.was_called_with(match.is_ref(stdin), " $ProgressPreference = 'SilentlyContinue'; ", match.is_function())
assert.spy(vim.loop.write).was_called_with(
match.is_ref(stdin),
" [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; ",
match.is_function()
)
assert.spy(vim.loop.write).was_called_with(match.is_ref(stdin), "echo 'Is this bash?'", match.is_function())
assert.spy(stdin.shutdown).was_called(1)
end)

it("should provide default powershell options via command interface", function()
Expand All @@ -87,11 +97,10 @@ describe("powershell manager", function()
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?'",
[[ $ErrorActionPreference = "Stop"; $ProgressPreference = 'SilentlyContinue'; [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; echo 'Is this bash?']],
})
end)
end)

0 comments on commit e3d469e

Please sign in to comment.