From d7eb2eeec566da6cfd1c61b1d7aa6fc592d1b296 Mon Sep 17 00:00:00 2001 From: William Boman Date: Sat, 17 Sep 2022 22:35:38 +0200 Subject: [PATCH] feat: more competent platform detection (#436) --- lua/mason-core/fetch.lua | 2 +- lua/mason-core/installer/context.lua | 2 +- lua/mason-core/managers/github/init.lua | 8 +- lua/mason-core/managers/go/init.lua | 2 +- lua/mason-core/managers/pip3/init.lua | 6 +- lua/mason-core/managers/std/init.lua | 2 +- lua/mason-core/platform.lua | 110 ++++++++++++------ lua/mason-core/spawn.lua | 12 +- lua/mason-registry/cbfmt/init.lua | 11 +- lua/mason-registry/clojure-lsp/init.lua | 9 +- .../editorconfig-checker/init.lua | 2 + lua/mason-registry/erlang-ls/init.lua | 2 +- lua/mason-registry/ltex-ls/init.lua | 9 +- lua/mason-registry/prosemd-lsp/init.lua | 8 +- lua/mason-registry/rust-analyzer/init.lua | 21 +--- lua/mason-registry/solidity/init.lua | 2 +- lua/mason-registry/tectonic/init.lua | 4 +- lua/mason/health/init.lua | 6 +- tests/mason-core/installer/context_spec.lua | 8 +- tests/mason-core/installer/linker_spec.lua | 8 +- tests/mason-core/platform_spec.lua | 57 ++++++--- 21 files changed, 164 insertions(+), 127 deletions(-) diff --git a/lua/mason-core/fetch.lua b/lua/mason-core/fetch.lua index f58dcd8d1..e19040cb3 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 50850219e..b6cc24e57 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 a3cbd103c..ebf98164c 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 ffa2b6b05..e1831d0fe 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 078f4c3d8..ace0b7dba 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 ea55654a2..9e0296647 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 15ebdd477..f1a25666a 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 +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 ---@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 -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 -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 dfd63e83d..fd01c97a2 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), } diff --git a/lua/mason-registry/cbfmt/init.lua b/lua/mason-registry/cbfmt/init.lua index 442f0a0cd..1fda9ce74 100644 --- a/lua/mason-registry/cbfmt/init.lua +++ b/lua/mason-registry/cbfmt/init.lua @@ -18,17 +18,10 @@ return Pkg.new { ---@async ---@param ctx InstallContext install = function(ctx) - local libc = platform.get_libc() - local asset_file = coalesce( when(platform.is.mac, "cbfmt_macos-x86_64_%s.tar.gz"), - when( - platform.is.linux_x64, - coalesce( - when(libc == "glibc", "cbfmt_linux-x86_64_%s.tar.gz"), - when(libc == "musl", "cbfmt_linux-x86_64-musl_%s.tar.gz") - ) - ), + when(platform.is.linux_x64_gnu, "cbfmt_linux-x86_64_%s.tar.gz"), + when(platform.is.linux_x64_musl, "cbfmt_linux-x86_64-musl_%s.tar.gz"), when(platform.is.win_x64, "cbfmt_windows-x86_64-msvc_%s.zip") ) diff --git a/lua/mason-registry/clojure-lsp/init.lua b/lua/mason-registry/clojure-lsp/init.lua index e330b6bbf..81f59143a 100644 --- a/lua/mason-registry/clojure-lsp/init.lua +++ b/lua/mason-registry/clojure-lsp/init.lua @@ -21,13 +21,10 @@ return Pkg.new { asset_file = coalesce( when(platform.is.mac_arm64, "clojure-lsp-native-macos-aarch64.zip"), when(platform.is.mac_x64, "clojure-lsp-native-macos-amd64.zip"), - when( - platform.is.linux_x64 and platform.get_libc() == "musl", - "clojure-lsp-native-static-linux-amd64.zip" - ), - when(platform.is.linux_x64 and platform.get_libc() == "glibc", "clojure-lsp-native-linux-amd64.zip"), + when(platform.is.linux_x64_musl, "clojure-lsp-native-static-linux-amd64.zip"), + when(platform.is.linux_x64_gnu, "clojure-lsp-native-linux-amd64.zip"), when(platform.is.linux_arm64, "clojure-lsp-native-linux-aarch64.zip"), - when(platform.is_win, "clojure-lsp-native-windows-amd64.zip") + when(platform.is.win_x64, "clojure-lsp-native-windows-amd64.zip") ), }) .with_receipt() diff --git a/lua/mason-registry/editorconfig-checker/init.lua b/lua/mason-registry/editorconfig-checker/init.lua index f92791282..e74416216 100644 --- a/lua/mason-registry/editorconfig-checker/init.lua +++ b/lua/mason-registry/editorconfig-checker/init.lua @@ -18,6 +18,8 @@ return Pkg.new { asset_file = coalesce( when(platform.is.mac_arm64, "ec-darwin-arm64.tar.gz"), when(platform.is.mac_x64, "ec-darwin-amd64.tar.gz"), + when(platform.is.linux_x64_openbsd, "ec-openbsd-amd64.tar.gz"), + when(platform.is.linux_arm64_openbsd, "ec-openbsd-arm64.tar.gz"), when(platform.is.linux_arm64, "ec-linux-arm64.tar.gz"), when(platform.is.linux_x64, "ec-linux-amd64.tar.gz"), when(platform.is.win_x86, "ec-windows-386.tar.gz"), diff --git a/lua/mason-registry/erlang-ls/init.lua b/lua/mason-registry/erlang-ls/init.lua index 53e808f91..839f59871 100644 --- a/lua/mason-registry/erlang-ls/init.lua +++ b/lua/mason-registry/erlang-ls/init.lua @@ -7,7 +7,7 @@ local github = require "mason-core.managers.github" local Optional = require "mason-core.optional" local path = require "mason-core.path" -local rebar3 = platform.is_win and "rebar3.cmd" or "rebar3" +local rebar3 = platform.is.win and "rebar3.cmd" or "rebar3" return Pkg.new { name = "erlang-ls", diff --git a/lua/mason-registry/ltex-ls/init.lua b/lua/mason-registry/ltex-ls/init.lua index 032445bcb..e2cace829 100644 --- a/lua/mason-registry/ltex-ls/init.lua +++ b/lua/mason-registry/ltex-ls/init.lua @@ -18,10 +18,10 @@ local function download_platform_dependent() repo = repo, asset_file = function(version) local target = coalesce( - when(platform.is_mac, "ltex-ls-%s-mac-x64.tar.gz"), - when(platform.is_linux, "ltex-ls-%s-linux-x64.tar.gz") + when(platform.is.mac, "ltex-ls-%s-mac-x64.tar.gz"), + when(platform.is.linux_x64, "ltex-ls-%s-linux-x64.tar.gz") ) - return target:format(version) + return target and target:format(version) end, } end, @@ -29,7 +29,8 @@ local function download_platform_dependent() return github.unzip_release_file { repo = repo, asset_file = function(version) - return ("ltex-ls-%s-windows-x64.zip"):format(version) + local target = coalesce(when(platform.is.win_x64, "ltex-ls-%s-windows-x64.zip")) + return target and target:format(version) end, } end, diff --git a/lua/mason-registry/prosemd-lsp/init.lua b/lua/mason-registry/prosemd-lsp/init.lua index 33f28abac..4e4f7b8e4 100644 --- a/lua/mason-registry/prosemd-lsp/init.lua +++ b/lua/mason-registry/prosemd-lsp/init.lua @@ -18,11 +18,11 @@ return Pkg.new { github .download_release_file({ repo = "kitten/prosemd-lsp", - out_file = platform.is_win and "prosemd-lsp.exe" or "prosemd-lsp", + out_file = platform.is.win and "prosemd-lsp.exe" or "prosemd-lsp", asset_file = coalesce( - when(platform.is_mac, "prosemd-lsp-macos"), - when(platform.is_linux and platform.arch == "x64", "prosemd-lsp-linux"), - when(platform.is_win and platform.arch == "x64", "prosemd-lsp-windows.exe") + when(platform.is.mac, "prosemd-lsp-macos"), + when(platform.is.linux_x64_gnu, "prosemd-lsp-linux"), + when(platform.is.win_x64, "prosemd-lsp-windows.exe") ), }) .with_receipt() diff --git a/lua/mason-registry/rust-analyzer/init.lua b/lua/mason-registry/rust-analyzer/init.lua index 39b259956..6b25461ae 100644 --- a/lua/mason-registry/rust-analyzer/init.lua +++ b/lua/mason-registry/rust-analyzer/init.lua @@ -18,27 +18,12 @@ return Pkg.new { ---@async ---@param ctx InstallContext install = function(ctx) - local libc = platform.get_libc() - local asset_file = coalesce( when(platform.is.mac_arm64, "rust-analyzer-aarch64-apple-darwin.gz"), when(platform.is.mac_x64, "rust-analyzer-x86_64-apple-darwin.gz"), - when( - platform.is.linux, - coalesce( - when( - libc == "glibc", - coalesce( - when(platform.arch == "arm64", "rust-analyzer-aarch64-unknown-linux-gnu.gz"), - when(platform.arch == "x64", "rust-analyzer-x86_64-unknown-linux-gnu.gz") - ) - ), - when( - libc == "musl", - coalesce(when(platform.arch == "x64", "rust-analyzer-x86_64-unknown-linux-musl.gz")) - ) - ) - ), + when(platform.is.linux_x64_gnu, "rust-analyzer-x86_64-unknown-linux-gnu.gz"), + when(platform.is.linux_arm64_gnu, "rust-analyzer-aarch64-unknown-linux-gnu.gz"), + when(platform.is.linux_x64_musl, "rust-analyzer-x86_64-unknown-linux-musl.gz"), when(platform.is.win_arm64, "rust-analyzer-aarch64-pc-windows-msvc.gz"), when(platform.is.win_x64, "rust-analyzer-x86_64-pc-windows-msvc.gz") ) diff --git a/lua/mason-registry/solidity/init.lua b/lua/mason-registry/solidity/init.lua index 9340684c9..d3b0385c7 100644 --- a/lua/mason-registry/solidity/init.lua +++ b/lua/mason-registry/solidity/init.lua @@ -18,7 +18,7 @@ return Pkg.new { github .download_release_file({ repo = "ethereum/solidity", - out_file = platform.is_win and "solc.exe" or "solc", + out_file = platform.is.win and "solc.exe" or "solc", asset_file = coalesce( when(platform.is.mac, "solc-macos"), when(platform.is.linux, "solc-static-linux"), diff --git a/lua/mason-registry/tectonic/init.lua b/lua/mason-registry/tectonic/init.lua index 760b92971..2a3e05fff 100644 --- a/lua/mason-registry/tectonic/init.lua +++ b/lua/mason-registry/tectonic/init.lua @@ -28,11 +28,11 @@ return Pkg.new { asset_file = coalesce( when(platform.is.mac, format_release_file "tectonic-%s-x86_64-apple-darwin.tar.gz"), when( - platform.is.linux_x64 and platform.get_libc() == "glibc", + platform.is.linux_x64_gnu, format_release_file "tectonic-%s-x86_64-unknown-linux-gnu.tar.gz" ), when( - platform.is.linux_x64 and platform.get_libc() == "musl", + platform.is.linux_x64_musl, format_release_file "tectonic-%s-x86_64-unknown-linux-musl.tar.gz" ), when( diff --git a/lua/mason/health/init.lua b/lua/mason/health/init.lua index e19e5c8d3..3dc325f91 100644 --- a/lua/mason/health/init.lua +++ b/lua/mason/health/init.lua @@ -213,11 +213,11 @@ function M.check() cmd = "gzip", args = { "--version" }, name = "gzip", - use_stderr = platform.is_mac, -- Apple gzip prints version string to stderr + use_stderr = platform.is.mac, -- Apple gzip prints version string to stderr }, 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 + -- 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 } if platform.is.unix then diff --git a/tests/mason-core/installer/context_spec.lua b/tests/mason-core/installer/context_spec.lua index 2523d33e2..516aa7d23 100644 --- a/tests/mason-core/installer/context_spec.lua +++ b/tests/mason-core/installer/context_spec.lua @@ -36,10 +36,10 @@ exec bash -c 'echo $GREETING' "$@"]] end) it("should write shell exec wrapper on Windows", function() - platform.is_mac = false - platform.is_unix = false - platform.is_linux = false - platform.is_win = true + platform.is.mac = false + platform.is.unix = false + platform.is.linux = false + platform.is.win = true local handle = InstallHandleGenerator "dummy" local ctx = InstallContextGenerator(handle) stub(ctx.fs, "write_file") diff --git a/tests/mason-core/installer/linker_spec.lua b/tests/mason-core/installer/linker_spec.lua index 71b7f7fee..cc14294b5 100644 --- a/tests/mason-core/installer/linker_spec.lua +++ b/tests/mason-core/installer/linker_spec.lua @@ -64,10 +64,10 @@ describe("installer", function() it( "should write executable wrapper on Windows", async_test(function() - platform.is_mac = false - platform.is_linux = false - platform.is_unix = false - platform.is_win = true + platform.is.mac = false + platform.is.linux = false + platform.is.unix = false + platform.is.win = true local dummy = registry.get_package "dummy" stub(fs.async, "file_exists") diff --git a/tests/mason-core/platform_spec.lua b/tests/mason-core/platform_spec.lua index 2c9d20358..7559e1ce8 100644 --- a/tests/mason-core/platform_spec.lua +++ b/tests/mason-core/platform_spec.lua @@ -8,13 +8,24 @@ describe("platform", function() return require "mason-core.platform" end - local function stub_mac(arch) - arch = arch or "x86_64" - stub(vim.fn, "has") + local function stub_uname(uname) stub(vim.loop, "os_uname") - vim.loop.os_uname.returns { machine = arch } + vim.loop.os_uname.returns(uname) + end + + ---@param libc string + local function stub_libc(libc) + stub(os, "execute") + local exit_code = libc == "musl" and 0 or 1 + -- selene: allow(incorrect_standard_library_use) + os.execute.on_call_with("ldd --version 2>&1 | grep -q musl").returns(nil, nil, exit_code) + end + + local function stub_mac() + stub(vim.fn, "has") vim.fn.has.on_call_with("mac").returns(1) vim.fn.has.on_call_with("unix").returns(1) + vim.fn.has.on_call_with("linux").returns(0) vim.fn.has.on_call_with(match._).returns(0) end @@ -22,6 +33,7 @@ describe("platform", function() stub(vim.fn, "has") vim.fn.has.on_call_with("mac").returns(0) vim.fn.has.on_call_with("unix").returns(1) + vim.fn.has.on_call_with("linux").returns(1) vim.fn.has.on_call_with(match._).returns(0) end @@ -32,7 +44,8 @@ describe("platform", function() end it("should be able to detect platform and arch", function() - stub_mac "arm64" + stub_mac() + stub_uname { machine = "aarch64" } assert.is_true(platform().is.mac_arm64) assert.is_false(platform().is.mac_x64) assert.is_false(platform().is.nothing) @@ -40,40 +53,50 @@ describe("platform", function() it("should be able to detect macos", function() stub_mac() - assert.is_true(platform().is_mac) assert.is_true(platform().is.mac) - assert.is_true(platform().is_unix) assert.is_true(platform().is.unix) - assert.is_false(platform().is_linux) assert.is_false(platform().is.linux) - assert.is_false(platform().is_win) assert.is_false(platform().is.win) end) it("should be able to detect linux", function() stub_linux() - assert.is_false(platform().is_mac) assert.is_false(platform().is.mac) - assert.is_true(platform().is_unix) assert.is_true(platform().is.unix) - assert.is_true(platform().is_linux) assert.is_true(platform().is.linux) - assert.is_false(platform().is_win) assert.is_false(platform().is.win) end) it("should be able to detect windows", function() stub_windows() - assert.is_false(platform().is_mac) assert.is_false(platform().is.mac) - assert.is_false(platform().is_unix) assert.is_false(platform().is.unix) - assert.is_false(platform().is_linux) assert.is_false(platform().is.linux) - assert.is_true(platform().is_win) assert.is_true(platform().is.win) end) + it("should be able to detect correct triple based on libc", function() + stub_linux() + stub_uname { machine = "aarch64" } + stub_libc "musl" + assert.is_false(platform().is.linux_x64_musl) + assert.is_false(platform().is.linux_x64_gnu) + assert.is_true(platform().is.linux_arm64_musl) + assert.is_false(platform().is.linux_arm64_gnu) + assert.is_false(platform().is.linux_arm64_gnu) + end) + + it("should be able to detect correct triple based on sysname", function() + stub_linux() + stub_uname { machine = "aarch64", sysname = "OpenBSD" } + stub_libc "musl" + assert.is_false(platform().is.linux_x64_musl) + assert.is_false(platform().is.linux_x64_gnu) + assert.is_false(platform().is.linux_arm64_gnu) + assert.is_false(platform().is.linux_arm64_gnu) + assert.is_true(platform().is.linux_arm64_openbsd) + end) + it("should run correct case on linux", function() local unix = spy.new() local win = spy.new()