Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lua/mason-core/installer/context.lua
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ function InstallContext:promote_cwd()
end

---@param rel_path string The relative path from the current working directory to change cwd to. Will only restore to the initial cwd after execution of fn (if provided).
---@param fn async (fun())? The function to run in the context of the given path.
---@param fn async (fun(): any)? The function to run in the context of the given path.
function InstallContext:chdir(rel_path, fn)
local old_cwd = self.cwd:get()
self.cwd:set(path.concat { old_cwd, rel_path })
Expand Down
48 changes: 0 additions & 48 deletions lua/mason-core/installer/managers/build.lua

This file was deleted.

126 changes: 126 additions & 0 deletions lua/mason-core/installer/managers/common.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
local Result = require "mason-core.result"
local _ = require "mason-core.functional"
local a = require "mason-core.async"
local async_uv = require "mason-core.async.uv"
local installer = require "mason-core.installer"
local log = require "mason-core.log"
local platform = require "mason-core.platform"
local powershell = require "mason-core.managers.powershell"
local std = require "mason-core.installer.managers.std"

local M = {}

---@class DownloadItem
---@field download_url string
---@field out_file string

---@class FileDownloadSpec
---@field file string | string[]

local get_source_file = _.compose(_.head, _.split ":")
local get_outfile = _.compose(_.last, _.split ":")

---Normalizes file paths from e.g. "file:out-dir/" to "out-dir/file".
---@param file string
local function normalize_file_path(file)
local source_file = get_source_file(file)
local new_path = get_outfile(file)

-- a dir expression (e.g. "libexec/")
if _.matches("/$", new_path) then
return new_path .. source_file
end
return new_path
end

---@generic T : FileDownloadSpec
---@type fun(download: T): T
M.normalize_files = _.evolve {
file = _.cond {
{ _.is "string", normalize_file_path },
{ _.T, _.map(normalize_file_path) },
},
}

---@param download FileDownloadSpec
---@param url_generator fun(file: string): string
---@return DownloadItem[]
function M.parse_downloads(download, url_generator)
local files = download.file
if type(files) == "string" then
files = { files }
end

return _.map(function(file)
local source_file = get_source_file(file)
local out_file = normalize_file_path(file)
return {
download_url = url_generator(source_file),
out_file = out_file,
}
end, files)
end

---@async
---@param ctx InstallContext
---@param downloads DownloadItem[]
---@nodiscard
function M.download_files(ctx, downloads)
return Result.try(function(try)
for __, download in ipairs(downloads) do
a.scheduler()
local out_dir = vim.fn.fnamemodify(download.out_file, ":h")
local out_file = vim.fn.fnamemodify(download.out_file, ":t")
if out_dir ~= "." then
try(Result.pcall(function()
ctx.fs:mkdirp(out_dir)
end))
end
try(ctx:chdir(out_dir, function()
return Result.try(function(try)
try(std.download_file(download.download_url, out_file))
try(std.unpack(out_file))
end)
end))
end
end)
end

---@class BuildInstruction
---@field target? Platform | Platform[]
---@field run string
---@field staged? boolean
---@field env? table<string, string>

---@async
---@param build BuildInstruction
---@return Result
---@nodiscard
function M.run_build_instruction(build)
log.fmt_debug("build: run %s", build)
local ctx = installer.context()
if build.staged == false then
ctx:promote_cwd()
end
return platform.when {
unix = function()
return ctx.spawn.bash {
on_spawn = a.scope(function(_, stdio)
local stdin = stdio[1]
async_uv.write(stdin, "set -euxo pipefail;\n")
async_uv.write(stdin, build.run)
async_uv.shutdown(stdin)
async_uv.close(stdin)
end),
env = build.env,
}
end,
win = function()
return powershell.command(build.run, {
env = build.env,
}, ctx.spawn)
end,
}
end

return M
1 change: 1 addition & 0 deletions lua/mason-core/installer/registry/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ M.register_provider("luarocks", _.lazy_require "mason-core.installer.registry.pr
M.register_provider("npm", _.lazy_require "mason-core.installer.registry.providers.npm")
M.register_provider("nuget", _.lazy_require "mason-core.installer.registry.providers.nuget")
M.register_provider("opam", _.lazy_require "mason-core.installer.registry.providers.opam")
M.register_provider("openvsx", _.lazy_require "mason-core.installer.registry.providers.openvsx")
M.register_provider("pypi", _.lazy_require "mason-core.installer.registry.providers.pypi")

---@param purl Purl
Expand Down
6 changes: 3 additions & 3 deletions lua/mason-core/installer/registry/providers/generic/build.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
local Result = require "mason-core.result"
local _ = require "mason-core.functional"
local build = require "mason-core.installer.managers.build"
local common = require "mason-core.installer.managers.common"
local expr = require "mason-core.installer.registry.expr"
local util = require "mason-core.installer.registry.util"

Expand All @@ -15,7 +15,7 @@ local M = {}
function M.parse(source, purl, opts)
return Result.try(function(try)
---@type BuildInstruction
local build_instruction = try(util.coalesce_by_target(source.build, opts):ok_or "PLATFORM_UNSUPPORTED")
local build_instruction = try(util.coalesce_by_target(source.build, opts))

if build_instruction.env then
local expr_ctx = { version = purl.version, target = build_instruction.target }
Expand All @@ -34,7 +34,7 @@ end
---@param ctx InstallContext
---@param source ParsedGenericBuildSource
function M.install(ctx, source)
return build.run(source.build)
return common.run_build_instruction(source.build)
end

return M
21 changes: 13 additions & 8 deletions lua/mason-core/installer/registry/providers/generic/download.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 common = require "mason-core.installer.managers.common"
local expr = require "mason-core.installer.registry.expr"
local util = require "mason-core.installer.registry.util"

Expand All @@ -17,15 +18,25 @@ local M = {}
---@param opts PackageInstallOpts
function M.parse(source, purl, opts)
return Result.try(function(try)
local download = try(util.coalesce_by_target(source.download, opts):ok_or "PLATFORM_UNSUPPORTED")
local download = try(util.coalesce_by_target(source.download, opts))

local expr_ctx = { version = purl.version }
---@type { files: table<string, string> }
local interpolated_download = try(expr.tbl_interpolate(download, expr_ctx))

---@type DownloadItem[]
local downloads = _.map(function(pair)
---@type DownloadItem
return {
out_file = pair[1],
download_url = pair[2],
}
end, _.to_pairs(interpolated_download.files))

---@class ParsedGenericDownloadSource : ParsedPackageSource
local parsed_source = {
download = interpolated_download,
downloads = downloads,
}
return parsed_source
end)
Expand All @@ -35,13 +46,7 @@ end
---@param ctx InstallContext
---@param source ParsedGenericDownloadSource
function M.install(ctx, source)
local std = require "mason-core.installer.managers.std"
return Result.try(function(try)
for out_file, url in pairs(source.download.files) do
try(std.download_file(url, out_file))
try(std.unpack(out_file))
end
end)
return common.download_files(ctx, source.downloads)
end

return M
6 changes: 3 additions & 3 deletions lua/mason-core/installer/registry/providers/github/build.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
local Result = require "mason-core.result"
local _ = require "mason-core.functional"
local build = require "mason-core.installer.managers.build"
local common = require "mason-core.installer.managers.common"
local expr = require "mason-core.installer.registry.expr"
local util = require "mason-core.installer.registry.util"

Expand All @@ -15,7 +15,7 @@ local M = {}
function M.parse(source, purl, opts)
return Result.try(function(try)
---@type BuildInstruction
local build_instruction = try(util.coalesce_by_target(source.build, opts):ok_or "PLATFORM_UNSUPPORTED")
local build_instruction = try(util.coalesce_by_target(source.build, opts))

local expr_ctx = { version = purl.version }

Expand Down Expand Up @@ -44,7 +44,7 @@ function M.install(ctx, source)
local std = require "mason-core.installer.managers.std"
return Result.try(function(try)
try(std.clone(source.repo, { rev = source.rev }))
try(build.run(source.build))
try(common.run_build_instruction(source.build))
end)
end

Expand Down
Loading