aboutsummaryrefslogtreecommitdiffstats
path: root/lua/mason-core
diff options
context:
space:
mode:
authorWilliam Boman <william@redwill.se>2022-09-17 22:35:38 +0200
committerGitHub <noreply@github.com>2022-09-17 22:35:38 +0200
commitd7eb2eeec566da6cfd1c61b1d7aa6fc592d1b296 (patch)
tree5f5ae4c7b55a90e9522fbaa4a04a1c5ccbafd0d8 /lua/mason-core
parentfeat(editorconfig-checker): use the pre-packaged ec (#434) (diff)
downloadmason-d7eb2eeec566da6cfd1c61b1d7aa6fc592d1b296.tar
mason-d7eb2eeec566da6cfd1c61b1d7aa6fc592d1b296.tar.gz
mason-d7eb2eeec566da6cfd1c61b1d7aa6fc592d1b296.tar.bz2
mason-d7eb2eeec566da6cfd1c61b1d7aa6fc592d1b296.tar.lz
mason-d7eb2eeec566da6cfd1c61b1d7aa6fc592d1b296.tar.xz
mason-d7eb2eeec566da6cfd1c61b1d7aa6fc592d1b296.tar.zst
mason-d7eb2eeec566da6cfd1c61b1d7aa6fc592d1b296.zip
feat: more competent platform detection (#436)
Diffstat (limited to 'lua/mason-core')
-rw-r--r--lua/mason-core/fetch.lua2
-rw-r--r--lua/mason-core/installer/context.lua2
-rw-r--r--lua/mason-core/managers/github/init.lua8
-rw-r--r--lua/mason-core/managers/go/init.lua2
-rw-r--r--lua/mason-core/managers/pip3/init.lua6
-rw-r--r--lua/mason-core/managers/std/init.lua2
-rw-r--r--lua/mason-core/platform.lua110
-rw-r--r--lua/mason-core/spawn.lua12
8 files changed, 90 insertions, 54 deletions
diff --git a/lua/mason-core/fetch.lua b/lua/mason-core/fetch.lua
index f58dcd8d..e19040cb 100644
--- a/lua/mason-core/fetch.lua
+++ b/lua/mason-core/fetch.lua
@@ -33,7 +33,7 @@ local function fetch(url, opts)
local platform_specific = Result.failure()
- if platform.is_win then
+ if platform.is.win then
local header_entries = _.join(
", ",
_.map(function(pair)
diff --git a/lua/mason-core/installer/context.lua b/lua/mason-core/installer/context.lua
index 50850219..b6cc24e5 100644
--- a/lua/mason-core/installer/context.lua
+++ b/lua/mason-core/installer/context.lua
@@ -177,7 +177,7 @@ function InstallContext:promote_cwd()
-- 1. Unlink any existing installation
self.handle.package:unlink()
-- 2. Prepare for renaming cwd to destination
- if platform.is_unix then
+ if platform.is.unix then
-- Some Unix systems will raise an error when renaming a directory to a destination that does not already exist.
fs.async.mkdir(install_path)
end
diff --git a/lua/mason-core/managers/github/init.lua b/lua/mason-core/managers/github/init.lua
index a3cbd103..ebf98164 100644
--- a/lua/mason-core/managers/github/init.lua
+++ b/lua/mason-core/managers/github/init.lua
@@ -86,10 +86,10 @@ function M.release_file(opts)
end
if not asset_file then
error(
- ("Could not find which release file to download.\nMost likely the current operating system, architecture (%s), or libc (%s) is not supported."):format(
- platform.arch,
- platform.get_libc()
- ),
+ (
+ "Could not find which release file to download.\n"
+ .. "Most likely the current operating system or architecture is not supported (%s_%s)."
+ ):format(platform.sysname, platform.arch),
0
)
end
diff --git a/lua/mason-core/managers/go/init.lua b/lua/mason-core/managers/go/init.lua
index ffa2b6b0..e1831d0f 100644
--- a/lua/mason-core/managers/go/init.lua
+++ b/lua/mason-core/managers/go/init.lua
@@ -124,7 +124,7 @@ function M.get_installed_primary_package_version(receipt, install_dir)
.go({
"version",
"-m",
- platform.is_win and ("%s.exe"):format(executable) or executable,
+ platform.is.win and ("%s.exe"):format(executable) or executable,
cwd = install_dir,
})
:map_catching(function(result)
diff --git a/lua/mason-core/managers/pip3/init.lua b/lua/mason-core/managers/pip3/init.lua
index 078f4c3d..ace0b7db 100644
--- a/lua/mason-core/managers/pip3/init.lua
+++ b/lua/mason-core/managers/pip3/init.lua
@@ -12,7 +12,7 @@ local VENV_DIR = "venv"
local M = {}
local create_bin_path = _.compose(path.concat, function(executable)
- return _.append(executable, { VENV_DIR, platform.is_win and "Scripts" or "bin" })
+ return _.append(executable, { VENV_DIR, platform.is.win and "Scripts" or "bin" })
end, _.if_else(_.always(platform.is.win), _.format "%s.exe", _.identity))
---@param packages string[]
@@ -44,7 +44,7 @@ function M.install(packages)
pkgs[1] = ("%s==%s"):format(pkgs[1], version)
end)
- local executables = platform.is_win and _.list_not_nil(vim.g.python3_host_prog, "python", "python3")
+ local executables = platform.is.win and _.list_not_nil(vim.g.python3_host_prog, "python", "python3")
or _.list_not_nil(vim.g.python3_host_prog, "python3", "python")
-- pip3 will hardcode the full path to venv executables, so we need to promote cwd to make sure pip uses the final destination path.
@@ -161,7 +161,7 @@ end
---@param install_dir string
function M.venv_path(install_dir)
- return path.concat { install_dir, VENV_DIR, platform.is_win and "Scripts" or "bin" }
+ return path.concat { install_dir, VENV_DIR, platform.is.win and "Scripts" or "bin" }
end
return M
diff --git a/lua/mason-core/managers/std/init.lua b/lua/mason-core/managers/std/init.lua
index ea55654a..9e029664 100644
--- a/lua/mason-core/managers/std/init.lua
+++ b/lua/mason-core/managers/std/init.lua
@@ -157,7 +157,7 @@ end
---@param flags string The chmod flag to apply.
---@param files string[] A list of relative paths to apply the chmod on.
function M.chmod(flags, files)
- if platform.is_unix then
+ if platform.is.unix then
local ctx = installer.context()
ctx.spawn.chmod { flags, files }
end
diff --git a/lua/mason-core/platform.lua b/lua/mason-core/platform.lua
index 15ebdd47..f1a25666 100644
--- a/lua/mason-core/platform.lua
+++ b/lua/mason-core/platform.lua
@@ -1,4 +1,4 @@
-local fun = require "mason-core.functional.function"
+local _ = require "mason-core.functional"
local M = {}
@@ -21,28 +21,83 @@ local arch_aliases = {
}
M.arch = arch_aliases[uname.machine] or uname.machine
+M.sysname = uname.sysname
-M.is_win = vim.fn.has "win32" == 1
-M.is_unix = vim.fn.has "unix" == 1
-M.is_mac = vim.fn.has "mac" == 1
-M.is_linux = not M.is_mac and M.is_unix
+M.is_headless = #vim.api.nvim_list_uis() == 0
--- PATH separator
-M.path_sep = M.is_win and ";" or ":"
+-- @return string @The libc found on the system, musl or glibc (glibc if ldd is not found)
+local get_libc = _.lazy(function()
+ local _, _, libc_exit_code = os.execute "ldd --version 2>&1 | grep -q musl"
+ if libc_exit_code == 0 then
+ return "musl"
+ else
+ return "glibc"
+ end
+end)
-M.is_headless = #vim.api.nvim_list_uis() == 0
+-- Most of the code that calls into these functions executes outside of the main event loop, where API/fn functions are
+-- disabled. We evaluate these immediately here to avoid issues with main loop synchronization.
+local cached_features = {
+ ["win"] = vim.fn.has "win32",
+ ["win32"] = vim.fn.has "win32",
+ ["win64"] = vim.fn.has "win64",
+ ["mac"] = vim.fn.has "mac",
+ ["unix"] = vim.fn.has "unix",
+ ["linux"] = vim.fn.has "linux",
+}
+
+---@type fun(env: string): boolean
+local check_env = _.memoize(_.cond {
+ {
+ _.equals "musl",
+ function()
+ return get_libc() == "musl"
+ end,
+ },
+ {
+ _.equals "gnu",
+ function()
+ return get_libc() == "glibc"
+ end,
+ },
+ { _.equals "openbsd", _.always(uname.sysname == "OpenBSD") },
+ { _.T, _.F },
+})
+
+---Table that allows for checking whether the provided targets apply to the current system.
+---Each key is a target tuple consisting of at most 3 targets, in the following order:
+--- 1) OS (e.g. linux, unix, mac, win) - Mandatory
+--- 2) Architecture (e.g. arm64, x64) - Optional
+--- 3) Environment (e.g. gnu, musl, openbsd) - Optional
+---Each target is separated by a "_" character, like so: "linux_x64_musl".
+---@type table<string, boolean>
+M.is = setmetatable({}, {
+ __index = function(__, key)
+ local os, arch, env = unpack(vim.split(key, "_", { plain = true }))
+ if not cached_features[os] or cached_features[os] ~= 1 then
+ return false
+ end
+ if arch and arch ~= M.arch then
+ return false
+ end
+ if env and not check_env(env) then
+ return false
+ end
+ return true
+ end,
+})
---@generic T
---@param platform_table table<Platform, T>
---@return T
local function get_by_platform(platform_table)
- if M.is_mac then
+ if M.is.mac then
return platform_table.mac or platform_table.unix
- elseif M.is_linux then
+ elseif M.is.linux then
return platform_table.linux or platform_table.unix
- elseif M.is_unix then
+ elseif M.is.unix then
return platform_table.unix
- elseif M.is_win then
+ elseif M.is.win then
return platform_table.win
else
return nil
@@ -59,7 +114,7 @@ function M.when(cases)
end
---@type async fun(): table
-M.os_distribution = fun.lazy(function()
+M.os_distribution = _.lazy(function()
local Result = require "mason-core.result"
---Parses the provided contents of an /etc/\*-release file and identifies the Linux distribution.
@@ -122,8 +177,8 @@ M.os_distribution = fun.lazy(function()
end)
---@type async fun(): Result<string>
-M.get_homebrew_prefix = fun.lazy(function()
- assert(M.is_mac, "Can only locate Homebrew installation on Mac systems.")
+M.get_homebrew_prefix = _.lazy(function()
+ assert(M.is.mac, "Can only locate Homebrew installation on Mac systems.")
local spawn = require "mason-core.spawn"
return spawn
.brew({ "--prefix" })
@@ -135,31 +190,9 @@ M.get_homebrew_prefix = fun.lazy(function()
end)
end)
--- @return string @The libc found on the system, musl or glibc (glibc if ldd is not found)
-M.get_libc = fun.lazy(function()
- local _, _, libc_exit_code = os.execute "ldd --version 2>&1 | grep -q musl"
- if libc_exit_code == 0 then
- return "musl"
- else
- return "glibc"
- end
-end)
-
----@type table<string, boolean>
-M.is = setmetatable({}, {
- __index = function(_, key)
- local platform, arch = unpack(vim.split(key, "_", { plain = true }))
- if arch and M.arch ~= arch then
- return false
- end
- return M["is_" .. platform] == true
- end,
-})
-
---@async
function M.get_node_version()
local spawn = require "mason-core.spawn"
- local _ = require "mason-core.functional"
return spawn.node({ "--version" }):map(function(result)
-- Parses output such as "v16.3.1" into major, minor, patch
@@ -168,4 +201,7 @@ function M.get_node_version()
end)
end
+-- PATH separator
+M.path_sep = M.is.win and ";" or ":"
+
return M
diff --git a/lua/mason-core/spawn.lua b/lua/mason-core/spawn.lua
index dfd63e83..fd01c97a 100644
--- a/lua/mason-core/spawn.lua
+++ b/lua/mason-core/spawn.lua
@@ -9,13 +9,13 @@ local log = require "mason-core.log"
---@type JobSpawn
local spawn = {
_aliases = {
- npm = platform.is_win and "npm.cmd" or "npm",
- gem = platform.is_win and "gem.cmd" or "gem",
- composer = platform.is_win and "composer.bat" or "composer",
- gradlew = platform.is_win and "gradlew.bat" or "gradlew",
+ npm = platform.is.win and "npm.cmd" or "npm",
+ gem = platform.is.win and "gem.cmd" or "gem",
+ composer = platform.is.win and "composer.bat" or "composer",
+ gradlew = platform.is.win and "gradlew.bat" or "gradlew",
-- for hererocks installations
- luarocks = (platform.is_win and vim.fn.executable "luarocks.bat" == 1) and "luarocks.bat" or "luarocks",
- rebar3 = platform.is_win and "rebar3.cmd" or "rebar3",
+ luarocks = (platform.is.win and vim.fn.executable "luarocks.bat" == 1) and "luarocks.bat" or "luarocks",
+ rebar3 = platform.is.win and "rebar3.cmd" or "rebar3",
},
_flatten_cmd_args = _.compose(_.filter(_.complement(_.equals(vim.NIL))), _.flatten),
}