aboutsummaryrefslogtreecommitdiffstats
path: root/lua/mason-core/installer/managers
diff options
context:
space:
mode:
Diffstat (limited to 'lua/mason-core/installer/managers')
-rw-r--r--lua/mason-core/installer/managers/build.lua48
-rw-r--r--lua/mason-core/installer/managers/common.lua126
2 files changed, 126 insertions, 48 deletions
diff --git a/lua/mason-core/installer/managers/build.lua b/lua/mason-core/installer/managers/build.lua
deleted file mode 100644
index a1549a28..00000000
--- a/lua/mason-core/installer/managers/build.lua
+++ /dev/null
@@ -1,48 +0,0 @@
-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 M = {}
-
----@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)
- 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
diff --git a/lua/mason-core/installer/managers/common.lua b/lua/mason-core/installer/managers/common.lua
new file mode 100644
index 00000000..c730a3aa
--- /dev/null
+++ b/lua/mason-core/installer/managers/common.lua
@@ -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