Skip to content

Commit

Permalink
fix(std): use gtar if available (#1433)
Browse files Browse the repository at this point in the history
Closes #1415.
  • Loading branch information
maybebyte committed Aug 19, 2023
1 parent e9eb004 commit a51c2d0
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 57 deletions.
21 changes: 17 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ Packages are installed in Neovim's data directory ([`:h standard-path`][help-sta
linked to a single `bin/` directory, which `mason.nvim` will add to Neovim's PATH during setup, allowing seamless access
from Neovim builtins (shell, terminal, etc.) as well as other 3rd party plugins.

For a list of all available packages, see https://mason-registry.dev/registry/list.
For a list of all available packages, see <https://mason-registry.dev/registry/list>.

## How to use installed packages

Expand Down Expand Up @@ -80,8 +80,22 @@ party plugins to further integrate these. The following plugins are recommended:
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: pwsh or powershell, git, tar, and [7zip][7zip] or [peazip][peazip] or [archiver][archiver] or [winzip][winzip] or [WinRAR][winrar]
- For Unix systems:
- `git(1)`
- `curl(1)` or `wget(1)`
- `unzip(1)`
- GNU tar (`tar(1)` or `gtar(1)` depending on platform)
- `gzip(1)`
- For Windows systems:
- pwsh or powershell
- git
- GNU tar
- One of the following:
- [7zip][7zip]
- [peazip][peazip]
- [archiver][archiver]
- [winzip][winzip]
- [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 Expand Up @@ -146,7 +160,6 @@ Refer to the [Wiki](https://github.com/williamboman/mason.nvim/wiki/Extensions)
- `:MasonUninstallAll` - uninstalls all packages
- `:MasonLog` - opens the `mason.nvim` log file in a new tab window


# Registries

Mason's core package registry is located at [mason-org/mason-registry](https://github.com/mason-org/mason-registry).
Expand Down
5 changes: 4 additions & 1 deletion lua/mason-core/installer/managers/std.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
local Result = require "mason-core.result"
local _ = require "mason-core.functional"
local a = require "mason-core.async"
local fetch = require "mason-core.fetch"
local installer = require "mason-core.installer"
local log = require "mason-core.log"
Expand Down Expand Up @@ -108,7 +109,9 @@ end
local function untar(rel_path)
log.fmt_debug("std: untar %s", rel_path)
local ctx = installer.context()
return ctx.spawn.tar({ "--no-same-owner", "-xvf", rel_path }):on_success(function()
a.scheduler()
local tar = vim.fn.executable "gtar" == 1 and "gtar" or "tar"
return ctx.spawn[tar]({ "--no-same-owner", "-xvf", rel_path }):on_success(function()
pcall(function()
ctx.fs:unlink(rel_path)
end)
Expand Down
4 changes: 3 additions & 1 deletion lua/mason/health.lua
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,9 @@ local function check_core_utils()
use_stderr = platform.is.mac, -- Apple gzip prints version string to stderr
relaxed = platform.is.win,
}
check { cmd = "tar", args = { "--version" }, name = "tar" }

local tar = vim.fn.executable "gtar" == 1 and "gtar" or "tar"
check { cmd = tar, args = { "--version" }, name = tar }

if platform.is.unix then
check { cmd = "bash", args = { "--version" }, name = "bash" }
Expand Down
123 changes: 72 additions & 51 deletions tests/mason-core/installer/managers/std_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -14,69 +14,90 @@ describe("std unpack [Unix]", function()
assert.spy(ctx.spawn.gzip).was_called_with { "-d", "file.gz" }
end)

it("should unpack .tar", function()
local ctx = create_dummy_context()
stub(ctx.fs, "unlink")
installer.exec_in_context(ctx, function()
std.unpack "file.tar"
describe("tar", function()
before_each(function()
stub(vim.fn, "executable")
vim.fn.executable.on_call_with("gtar").returns(0)
end)

assert.spy(ctx.spawn.tar).was_called(1)
assert.spy(ctx.spawn.tar).was_called_with { "--no-same-owner", "-xvf", "file.tar" }
assert.spy(ctx.fs.unlink).was_called(1)
assert.spy(ctx.fs.unlink).was_called_with(match.is_ref(ctx.fs), "file.tar")
end)
it("should use gtar if available", function()
local ctx = create_dummy_context()
stub(ctx.fs, "unlink")
stub(vim.fn, "executable")
vim.fn.executable.on_call_with("gtar").returns(1)

it("should unpack .tar.bz2", function()
local ctx = create_dummy_context()
stub(ctx.fs, "unlink")
installer.exec_in_context(ctx, function()
std.unpack "file.tar.bz2"
end)

assert.spy(ctx.spawn.tar).was_called(1)
assert.spy(ctx.spawn.tar).was_called_with { "--no-same-owner", "-xvf", "file.tar.bz2" }
assert.spy(ctx.fs.unlink).was_called(1)
assert.spy(ctx.fs.unlink).was_called_with(match.is_ref(ctx.fs), "file.tar.bz2")
end)
installer.exec_in_context(ctx, function()
std.unpack "file.tar.gz"
end)

it("should unpack .tar.gz", function()
local ctx = create_dummy_context()
stub(ctx.fs, "unlink")
installer.exec_in_context(ctx, function()
std.unpack "file.tar.gz"
assert.spy(ctx.spawn.gtar).was_called(1)
assert.spy(ctx.spawn.gtar).was_called_with { "--no-same-owner", "-xvf", "file.tar.gz" }
end)

assert.spy(ctx.spawn.tar).was_called(1)
assert.spy(ctx.spawn.tar).was_called_with { "--no-same-owner", "-xvf", "file.tar.gz" }
assert.spy(ctx.fs.unlink).was_called(1)
assert.spy(ctx.fs.unlink).was_called_with(match.is_ref(ctx.fs), "file.tar.gz")
end)
it("should unpack .tar", function()
local ctx = create_dummy_context()
stub(ctx.fs, "unlink")
installer.exec_in_context(ctx, function()
std.unpack "file.tar"
end)

assert.spy(ctx.spawn.tar).was_called(1)
assert.spy(ctx.spawn.tar).was_called_with { "--no-same-owner", "-xvf", "file.tar" }
assert.spy(ctx.fs.unlink).was_called(1)
assert.spy(ctx.fs.unlink).was_called_with(match.is_ref(ctx.fs), "file.tar")
end)

it("should unpack .tar.xz", function()
local ctx = create_dummy_context()
stub(ctx.fs, "unlink")
installer.exec_in_context(ctx, function()
std.unpack "file.tar.xz"
it("should unpack .tar.bz2", function()
local ctx = create_dummy_context()
stub(ctx.fs, "unlink")
installer.exec_in_context(ctx, function()
std.unpack "file.tar.bz2"
end)

assert.spy(ctx.spawn.tar).was_called(1)
assert.spy(ctx.spawn.tar).was_called_with { "--no-same-owner", "-xvf", "file.tar.bz2" }
assert.spy(ctx.fs.unlink).was_called(1)
assert.spy(ctx.fs.unlink).was_called_with(match.is_ref(ctx.fs), "file.tar.bz2")
end)

assert.spy(ctx.spawn.tar).was_called(1)
assert.spy(ctx.spawn.tar).was_called_with { "--no-same-owner", "-xvf", "file.tar.xz" }
assert.spy(ctx.fs.unlink).was_called(1)
assert.spy(ctx.fs.unlink).was_called_with(match.is_ref(ctx.fs), "file.tar.xz")
end)
it("should unpack .tar.gz", function()
local ctx = create_dummy_context()
stub(ctx.fs, "unlink")
installer.exec_in_context(ctx, function()
std.unpack "file.tar.gz"
end)

assert.spy(ctx.spawn.tar).was_called(1)
assert.spy(ctx.spawn.tar).was_called_with { "--no-same-owner", "-xvf", "file.tar.gz" }
assert.spy(ctx.fs.unlink).was_called(1)
assert.spy(ctx.fs.unlink).was_called_with(match.is_ref(ctx.fs), "file.tar.gz")
end)

it("should unpack .tar.zst", function()
local ctx = create_dummy_context()
stub(ctx.fs, "unlink")
installer.exec_in_context(ctx, function()
std.unpack "file.tar.zst"
it("should unpack .tar.xz", function()
local ctx = create_dummy_context()
stub(ctx.fs, "unlink")
installer.exec_in_context(ctx, function()
std.unpack "file.tar.xz"
end)

assert.spy(ctx.spawn.tar).was_called(1)
assert.spy(ctx.spawn.tar).was_called_with { "--no-same-owner", "-xvf", "file.tar.xz" }
assert.spy(ctx.fs.unlink).was_called(1)
assert.spy(ctx.fs.unlink).was_called_with(match.is_ref(ctx.fs), "file.tar.xz")
end)

assert.spy(ctx.spawn.tar).was_called(1)
assert.spy(ctx.spawn.tar).was_called_with { "--no-same-owner", "-xvf", "file.tar.zst" }
assert.spy(ctx.fs.unlink).was_called(1)
assert.spy(ctx.fs.unlink).was_called_with(match.is_ref(ctx.fs), "file.tar.zst")
it("should unpack .tar.zst", function()
local ctx = create_dummy_context()
stub(ctx.fs, "unlink")
installer.exec_in_context(ctx, function()
std.unpack "file.tar.zst"
end)

assert.spy(ctx.spawn.tar).was_called(1)
assert.spy(ctx.spawn.tar).was_called_with { "--no-same-owner", "-xvf", "file.tar.zst" }
assert.spy(ctx.fs.unlink).was_called(1)
assert.spy(ctx.fs.unlink).was_called_with(match.is_ref(ctx.fs), "file.tar.zst")
end)
end)

it("should unpack .vsix", function()
Expand Down

0 comments on commit a51c2d0

Please sign in to comment.