diff options
| author | William Boman <william@redwill.se> | 2024-01-25 22:02:00 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-01-25 22:02:00 +0100 |
| commit | dcd0ea30ccfc7d47e879878d1270d6847a519181 (patch) | |
| tree | 43fb3692488fbf2539780bc5c43b136d8635d3ed /lua | |
| parent | fix(golang): fix fetching package versions for packages containing subpath sp... (diff) | |
| download | mason-dcd0ea30ccfc7d47e879878d1270d6847a519181.tar mason-dcd0ea30ccfc7d47e879878d1270d6847a519181.tar.gz mason-dcd0ea30ccfc7d47e879878d1270d6847a519181.tar.bz2 mason-dcd0ea30ccfc7d47e879878d1270d6847a519181.tar.lz mason-dcd0ea30ccfc7d47e879878d1270d6847a519181.tar.xz mason-dcd0ea30ccfc7d47e879878d1270d6847a519181.tar.zst mason-dcd0ea30ccfc7d47e879878d1270d6847a519181.zip | |
feat(pypi): attempt more python3 candidates (#1608)
Diffstat (limited to 'lua')
| -rw-r--r-- | lua/mason-core/installer/managers/pypi.lua | 71 |
1 files changed, 59 insertions, 12 deletions
diff --git a/lua/mason-core/installer/managers/pypi.lua b/lua/mason-core/installer/managers/pypi.lua index 7c0e5bb9..bda8925e 100644 --- a/lua/mason-core/installer/managers/pypi.lua +++ b/lua/mason-core/installer/managers/pypi.lua @@ -6,18 +6,71 @@ local installer = require "mason-core.installer" local log = require "mason-core.log" local path = require "mason-core.path" local platform = require "mason-core.platform" +local semver = require "mason-core.semver" +local spawn = require "mason-core.spawn" local M = {} local VENV_DIR = "venv" +local is_executable = _.compose(_.equals(1), vim.fn.executable) + +---@async +---@param candidates string[] +local function resolve_python3(candidates) + a.scheduler() + local available_candidates = _.filter(is_executable, candidates) + for __, candidate in ipairs(available_candidates) do + ---@type string + local version_output = spawn[candidate]({ "--version" }):map(_.prop "stdout"):get_or_else "" + local ok, version = pcall(semver.new, version_output:match "Python (3%.%d+.%d+)") + if ok then + return { executable = candidate, version = version } + end + end + return nil +end + +---@param min_version? Semver +local function get_versioned_candidates(min_version) + return _.filter_map(function(pair) + local version, executable = unpack(pair) + if not min_version or version > min_version then + return Optional.of(executable) + else + return Optional.empty() + end + end, { + { semver.new "3.12.0", "python3.12" }, + { semver.new "3.11.0", "python3.11" }, + { semver.new "3.10.0", "python3.10" }, + { semver.new "3.9.0", "python3.9" }, + { semver.new "3.8.0", "python3.8" }, + { semver.new "3.7.0", "python3.7" }, + { semver.new "3.6.0", "python3.6" }, + }) +end + ---@async ----@param py_executables string[] -local function create_venv(py_executables) +local function create_venv() + local stock_candidates = platform.is.win and { "python", "python3" } or { "python3", "python" } + local stock_target = resolve_python3(stock_candidates) + local _ = stock_target and log.fmt_debug("Resolved stock python3 installation version %s", stock_target.version) + local versioned_candidates = get_versioned_candidates(stock_target and stock_target.version) + log.debug("Resolving versioned python3 candidates", versioned_candidates) + local target = resolve_python3(versioned_candidates) or stock_target local ctx = installer.context() - return Optional.of_nilable(_.find_first(function(executable) - return ctx.spawn[executable]({ "-m", "venv", VENV_DIR }):is_success() - end, py_executables)):ok_or "Failed to create python3 virtual environment." + if not target then + ctx.stdio_sink.stderr( + ("Unable to find python3 installation. Tried the following candidates: %s.\n"):format( + _.join(", ", _.concat(stock_candidates, versioned_candidates)) + ) + ) + return Result.failure "Failed to find python3 installation." + end + log.fmt_debug("Found python3 installation version=%s, executable=%s", target.version, target.executable) + ctx.stdio_sink.stdout "Creating virtual environment…\n" + return ctx.spawn[target.executable] { "-m", "venv", VENV_DIR } end ---@param ctx InstallContext @@ -70,15 +123,9 @@ function M.init(opts) log.fmt_debug("pypi: init", opts) local ctx = installer.context() - a.scheduler() - - local executables = platform.is.win and { "python", "python3" } or { "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. ctx:promote_cwd() - - ctx.stdio_sink.stdout "Creating virtual environment…\n" - try(create_venv(executables)) + try(create_venv()) if opts.upgrade_pip then ctx.stdio_sink.stdout "Upgrading pip inside the virtual environment…\n" |
