diff options
| author | William Boman <william@redwill.se> | 2023-04-18 10:36:25 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-04-18 10:36:25 +0200 |
| commit | 75e64d20c31f8d032916e3990d568a6e38a9d18b (patch) | |
| tree | e6dbbd462c1b64706dccc38f05a299b8d48c4e56 | |
| parent | refactor(expr): remove redundant core filters and always stringify reduced va... (diff) | |
| download | mason-75e64d20c31f8d032916e3990d568a6e38a9d18b.tar mason-75e64d20c31f8d032916e3990d568a6e38a9d18b.tar.gz mason-75e64d20c31f8d032916e3990d568a6e38a9d18b.tar.bz2 mason-75e64d20c31f8d032916e3990d568a6e38a9d18b.tar.lz mason-75e64d20c31f8d032916e3990d568a6e38a9d18b.tar.xz mason-75e64d20c31f8d032916e3990d568a6e38a9d18b.tar.zst mason-75e64d20c31f8d032916e3990d568a6e38a9d18b.zip | |
feat(installer): add generic build provider (#1228)
15 files changed, 534 insertions, 97 deletions
diff --git a/lua/mason-core/installer/managers/build.lua b/lua/mason-core/installer/managers/build.lua new file mode 100644 index 00000000..a1549a28 --- /dev/null +++ b/lua/mason-core/installer/managers/build.lua @@ -0,0 +1,48 @@ +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/registry/expr.lua b/lua/mason-core/installer/registry/expr.lua index 5dc016eb..2bb3a149 100644 --- a/lua/mason-core/installer/registry/expr.lua +++ b/lua/mason-core/installer/registry/expr.lua @@ -13,15 +13,21 @@ local parse_expr = _.compose( _.split "|" ) ----@param predicate fun(value: string): boolean +---@param predicate (fun(value: string): boolean) | boolean ---@param value string local take_if = _.curryN(function(predicate, value) + if type(predicate) == "boolean" then + predicate = _.always(predicate) + end return predicate(value) and value or nil end, 2) ----@param predicate fun(value: string): boolean +---@param predicate (fun(value: string): boolean) | boolean ---@param value string local take_if_not = _.curryN(function(predicate, value) + if type(predicate) == "boolean" then + predicate = _.always(predicate) + end return (not predicate(value)) and value or nil end, 2) diff --git a/lua/mason-core/installer/registry/init.lua b/lua/mason-core/installer/registry/init.lua index 3ece857d..6c22d227 100644 --- a/lua/mason-core/installer/registry/init.lua +++ b/lua/mason-core/installer/registry/init.lua @@ -132,6 +132,8 @@ function M.parse(spec, opts) source = parsed_source, purl = purl, } + end):on_failure(function(err) + log.debug("Failed to parse spec spec", spec.name, err) end) end diff --git a/lua/mason-core/installer/registry/link.lua b/lua/mason-core/installer/registry/link.lua index 5d6a8f16..2b4027e9 100644 --- a/lua/mason-core/installer/registry/link.lua +++ b/lua/mason-core/installer/registry/link.lua @@ -149,7 +149,13 @@ end local function expand_bin(ctx, spec, purl, source) log.debug("Registering bin links", ctx.package, spec.bin) return Result.try(function(try) - local expr_ctx = { version = purl.version, source = source } + local expr_ctx = { + version = purl.version, + source = source, + is_platform = function(target) + return platform.is[target] + end, + } local bin_table = spec.bin if not bin_table then diff --git a/lua/mason-core/installer/registry/providers/generic/build.lua b/lua/mason-core/installer/registry/providers/generic/build.lua new file mode 100644 index 00000000..6d2769e1 --- /dev/null +++ b/lua/mason-core/installer/registry/providers/generic/build.lua @@ -0,0 +1,40 @@ +local Result = require "mason-core.result" +local _ = require "mason-core.functional" +local build = require "mason-core.installer.managers.build" +local expr = require "mason-core.installer.registry.expr" +local util = require "mason-core.installer.registry.util" + +local M = {} + +---@class GenericBuildSource : RegistryPackageSource +---@field build BuildInstruction | BuildInstruction[] + +---@param source GenericBuildSource +---@param purl Purl +---@param opts PackageInstallOpts +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") + + if build_instruction.env then + local expr_ctx = { version = purl.version, target = build_instruction.target } + build_instruction.env = try(expr.tbl_interpolate(build_instruction.env, expr_ctx)) + end + + ---@class ParsedGenericBuildSource : ParsedPackageSource + local parsed_source = { + build = build_instruction, + } + return parsed_source + end) +end + +---@async +---@param ctx InstallContext +---@param source ParsedGenericBuildSource +function M.install(ctx, source) + return build.run(source.build) +end + +return M diff --git a/lua/mason-core/installer/registry/providers/generic.lua b/lua/mason-core/installer/registry/providers/generic/download.lua index 5f5cb6bf..a7e4d046 100644 --- a/lua/mason-core/installer/registry/providers/generic.lua +++ b/lua/mason-core/installer/registry/providers/generic/download.lua @@ -9,10 +9,10 @@ local M = {} ---@field target (Platform | Platform[])? ---@field files table<string, string> ----@class GenericSource : RegistryPackageSource +---@class GenericDownloadSource : RegistryPackageSource ---@field download GenericDownload | GenericDownload[] ----@param source GenericSource +---@param source GenericDownloadSource ---@param purl Purl ---@param opts PackageInstallOpts function M.parse(source, purl, opts) @@ -23,7 +23,7 @@ function M.parse(source, purl, opts) ---@type { files: table<string, string> } local interpolated_download = try(expr.tbl_interpolate(download, expr_ctx)) - ---@class ParsedGenericSource : ParsedPackageSource + ---@class ParsedGenericDownloadSource : ParsedPackageSource local parsed_source = { download = interpolated_download, } @@ -33,7 +33,7 @@ end ---@async ---@param ctx InstallContext ----@param source ParsedGenericSource +---@param source ParsedGenericDownloadSource function M.install(ctx, source) local std = require "mason-core.installer.managers.std" return Result.try(function(try) diff --git a/lua/mason-core/installer/registry/providers/generic/init.lua b/lua/mason-core/installer/registry/providers/generic/init.lua new file mode 100644 index 00000000..a511471e --- /dev/null +++ b/lua/mason-core/installer/registry/providers/generic/init.lua @@ -0,0 +1,36 @@ +local Result = require "mason-core.result" +local _ = require "mason-core.functional" + +local M = {} + +---@param source GenericDownloadSource | GenericBuildSource +---@param purl Purl +---@param opts PackageInstallOpts +function M.parse(source, purl, opts) + if source.download then + source = source --[[@as GenericDownloadSource]] + return require("mason-core.installer.registry.providers.generic.download").parse(source, purl, opts) + elseif source.build then + source = source --[[@as GenericBuildSource]] + return require("mason-core.installer.registry.providers.generic.build").parse(source, purl, opts) + else + return Result.failure "Unknown source type." + end +end + +---@async +---@param ctx InstallContext +---@param source ParsedGenericDownloadSource | ParsedGenericBuildSource +function M.install(ctx, source) + if source.download then + source = source --[[@as ParsedGenericDownloadSource]] + return require("mason-core.installer.registry.providers.generic.download").install(ctx, source) + elseif source.build then + source = source --[[@as ParsedGenericBuildSource]] + return require("mason-core.installer.registry.providers.generic.build").install(ctx, source) + else + return Result.failure "Unknown source type." + end +end + +return M diff --git a/lua/mason-core/installer/registry/providers/github/build.lua b/lua/mason-core/installer/registry/providers/github/build.lua index e41cac33..bda0b655 100644 --- a/lua/mason-core/installer/registry/providers/github/build.lua +++ b/lua/mason-core/installer/registry/providers/github/build.lua @@ -1,27 +1,32 @@ 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 platform = require "mason-core.platform" +local build = require "mason-core.installer.managers.build" +local expr = require "mason-core.installer.registry.expr" local util = require "mason-core.installer.registry.util" ----@class GitHubBuildInstruction ----@field target? Platform | Platform[] ----@field run string +local M = {} ---@class GitHubBuildSource : RegistryPackageSource ----@field build GitHubBuildInstruction | GitHubBuildInstruction[] - -local M = {} +---@field build BuildInstruction | BuildInstruction[] ---@param source GitHubBuildSource ---@param purl Purl ---@param opts PackageInstallOpts function M.parse(source, purl, opts) return Result.try(function(try) - ---@type { run: string } + ---@type BuildInstruction local build_instruction = try(util.coalesce_by_target(source.build, opts):ok_or "PLATFORM_UNSUPPORTED") + local expr_ctx = { version = purl.version } + + -- TODO: In a few releases of the core registry, r-languageserver reads $MASON_VERSION directly. Remove this + -- some time in the future. + local default_env = { + MASON_VERSION = purl.version, + } + build_instruction.env = + vim.tbl_extend("force", default_env, try(expr.tbl_interpolate(build_instruction.env or {}, expr_ctx))) + ---@class ParsedGitHubBuildSource : ParsedPackageSource local parsed_source = { build = build_instruction, @@ -35,35 +40,11 @@ end ---@async ---@param ctx InstallContext ---@param source ParsedGitHubBuildSource ----@param purl Purl -function M.install(ctx, source, purl) +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(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, source.build.run) - async_uv.shutdown(stdin) - async_uv.close(stdin) - end), - env = { - MASON_VERSION = purl.version, - }, - } - end, - win = function() - local powershell = require "mason-core.managers.powershell" - return powershell.command(source.build.run, { - env = { - MASON_VERSION = purl.version, - }, - }, ctx.spawn) - end, - }) + try(build.run(source.build)) end) end diff --git a/lua/mason-core/installer/registry/providers/github/init.lua b/lua/mason-core/installer/registry/providers/github/init.lua index f5c66d36..41dd893d 100644 --- a/lua/mason-core/installer/registry/providers/github/init.lua +++ b/lua/mason-core/installer/registry/providers/github/init.lua @@ -26,7 +26,7 @@ function M.install(ctx, source, purl) return require("mason-core.installer.registry.providers.github.release").install(ctx, source) elseif source.build then source = source--[[@as ParsedGitHubBuildSource]] - return require("mason-core.installer.registry.providers.github.build").install(ctx, source, purl) + return require("mason-core.installer.registry.providers.github.build").install(ctx, source) else return Result.failure "Unknown source type." end diff --git a/tests/mason-core/installer/managers/build_spec.lua b/tests/mason-core/installer/managers/build_spec.lua new file mode 100644 index 00000000..73dd63c1 --- /dev/null +++ b/tests/mason-core/installer/managers/build_spec.lua @@ -0,0 +1,70 @@ +local Result = require "mason-core.result" +local build = require "mason-core.installer.managers.build" +local installer = require "mason-core.installer" +local match = require "luassert.match" +local mock = require "luassert.mock" +local spy = require "luassert.spy" +local stub = require "luassert.stub" + +describe("build manager", function() + it("should run build instruction", function() + local ctx = create_dummy_context() + local uv = require "mason-core.async.uv" + spy.on(ctx, "promote_cwd") + stub(uv, "write") + stub(uv, "shutdown") + stub(uv, "close") + local stdin = mock.new() + stub( + ctx.spawn, + "bash", ---@param args SpawnArgs + function(args) + args.on_spawn(mock.new(), { stdin }) + return Result.success() + end + ) + + local result = installer.exec_in_context(ctx, function() + return build.run { + run = [[npm install && npm run compile]], + env = { + MASON_VERSION = "2023-03-09", + SOME_VALUE = "here", + }, + } + end) + + assert.is_true(result:is_success()) + assert.spy(ctx.promote_cwd).was_called(0) + assert.spy(ctx.spawn.bash).was_called(1) + assert.spy(ctx.spawn.bash).was_called_with(match.tbl_containing { + on_spawn = match.is_function(), + env = match.same { + MASON_VERSION = "2023-03-09", + SOME_VALUE = "here", + }, + }) + assert.spy(uv.write).was_called(2) + assert.spy(uv.write).was_called_with(stdin, "set -euxo pipefail;\n") + assert.spy(uv.write).was_called_with(stdin, "npm install && npm run compile") + assert.spy(uv.shutdown).was_called_with(stdin) + assert.spy(uv.close).was_called_with(stdin) + end) + + it("should promote cwd if not staged", function() + local ctx = create_dummy_context() + stub(ctx, "promote_cwd") + stub(ctx.spawn, "bash", mockx.returns(Result.success())) + + local result = installer.exec_in_context(ctx, function() + return build.run { + run = "make", + staged = false, + } + end) + + assert.is_true(result:is_success()) + assert.spy(ctx.promote_cwd).was_called(1) + assert.spy(ctx.spawn.bash).was_called(1) + end) +end) diff --git a/tests/mason-core/installer/registry/expr_spec.lua b/tests/mason-core/installer/registry/expr_spec.lua index f17e49ee..93efa6d4 100644 --- a/tests/mason-core/installer/registry/expr_spec.lua +++ b/tests/mason-core/installer/registry/expr_spec.lua @@ -162,6 +162,20 @@ describe("expr filters :: take_if{_not}", function() greeting = "Hello World!", }) ) + + assert.same( + Result.success "", + expr.interpolate("{{ take_if(false, greeting) }}", { + greeting = "Hello World!", + }) + ) + + assert.same( + Result.success "Hello World!", + expr.interpolate("{{ take_if(true, greeting) }}", { + greeting = "Hello World!", + }) + ) end) it("should not take if value matches", function() @@ -185,6 +199,20 @@ describe("expr filters :: take_if{_not}", function() greeting = "Hello World!", }) ) + + assert.same( + Result.success "Hello World!", + expr.interpolate("{{ take_if_not(false, greeting) }}", { + greeting = "Hello World!", + }) + ) + + assert.same( + Result.success "", + expr.interpolate("{{ take_if_not(true, greeting) }}", { + greeting = "Hello World!", + }) + ) end) end) diff --git a/tests/mason-core/installer/registry/providers/generic/build_spec.lua b/tests/mason-core/installer/registry/providers/generic/build_spec.lua new file mode 100644 index 00000000..ccc77ac3 --- /dev/null +++ b/tests/mason-core/installer/registry/providers/generic/build_spec.lua @@ -0,0 +1,143 @@ +local Purl = require "mason-core.purl" +local Result = require "mason-core.result" +local generic = require "mason-core.installer.registry.providers.generic" +local installer = require "mason-core.installer" +local stub = require "luassert.stub" + +---@param overrides Purl +local function purl(overrides) + local purl = Purl.parse("pkg:generic/namespace/name@v1.2.0"):get_or_throw() + if not overrides then + return purl + end + return vim.tbl_deep_extend("force", purl, overrides) +end + +describe("generic provider :: build :: parsing", function() + it("should parse single build target", function() + assert.same( + Result.success { + build = { + run = "make build", + env = { + SOME_VALUE = "here", + }, + }, + }, + generic.parse({ + build = { + run = "make build", + env = { + SOME_VALUE = "here", + }, + }, + }, purl()) + ) + end) + + it("should coalesce build target", function() + assert.same( + Result.success { + build = { + target = "linux_arm64", + run = "make build", + env = { + LINUX = "yes", + }, + }, + }, + generic.parse({ + build = { + { + target = "linux_arm64", + run = "make build", + env = { + LINUX = "yes", + }, + }, + { + target = "win_arm64", + run = "make build", + env = { + WINDOWS = "yes", + }, + }, + }, + }, purl(), { target = "linux_arm64" }) + ) + end) + + it("should interpolate environment", function() + assert.same( + Result.success { + build = { + run = "make build", + env = { + LINUX = "2023-04-18", + }, + }, + }, + generic.parse( + { + build = { + run = "make build", + env = { + LINUX = "{{version}}", + }, + }, + }, + purl { version = "2023-04-18" }, + { + target = "linux_arm64", + } + ) + ) + end) + + it("should check supported platforms", function() + assert.same( + Result.failure "PLATFORM_UNSUPPORTED", + generic.parse( + { + build = { + { + target = "win_arm64", + run = "make build", + env = { + WINDOWS = "yes", + }, + }, + }, + }, + purl(), + { + target = "linux_x64", + } + ) + ) + end) +end) + +describe("generic provider :: build :: installing", function() + it("should install", function() + local ctx = create_dummy_context() + local build = require "mason-core.installer.managers.build" + stub(build, "run", mockx.returns(Result.success())) + + local result = installer.exec_in_context(ctx, function() + return generic.install(ctx, { + build = { + run = "make", + env = { VALUE = "here" }, + }, + }) + end) + + assert.is_true(result:is_success()) + assert.spy(build.run).was_called(1) + assert.spy(build.run).was_called_with { + run = "make", + env = { VALUE = "here" }, + } + end) +end) diff --git a/tests/mason-core/installer/registry/providers/generic_spec.lua b/tests/mason-core/installer/registry/providers/generic/download_spec.lua index 431703b4..1d3583f9 100644 --- a/tests/mason-core/installer/registry/providers/generic_spec.lua +++ b/tests/mason-core/installer/registry/providers/generic/download_spec.lua @@ -13,7 +13,7 @@ local function purl(overrides) return vim.tbl_deep_extend("force", purl, overrides) end -describe("generic provider :: parsing", function() +describe("generic provider :: download :: parsing", function() it("should parse single download target", function() assert.same( Result.success { @@ -63,11 +63,29 @@ describe("generic provider :: parsing", function() end) it("should check supported platforms", function() - assert.same(Result.failure "PLATFORM_UNSUPPORTED", generic.parse({ supported_platforms = { "VIC64" } }, purl())) + assert.same( + Result.failure "PLATFORM_UNSUPPORTED", + generic.parse( + { + download = { + { + target = "win_arm64", + files = { + ["name.tar.gz"] = [[https://getpackage.org/downloads/win-aarch64/{{version | strip_prefix "v"}}/name.tar.gz]], + }, + }, + }, + }, + purl(), + { + target = "linux_arm64", + } + ) + ) end) end) -describe("generic provider :: installing", function() +describe("generic provider :: download :: installing", function() it("should install generic packages", function() local ctx = create_dummy_context() local std = require "mason-core.installer.managers.std" diff --git a/tests/mason-core/installer/registry/providers/github/build_spec.lua b/tests/mason-core/installer/registry/providers/github/build_spec.lua new file mode 100644 index 00000000..b25c26d8 --- /dev/null +++ b/tests/mason-core/installer/registry/providers/github/build_spec.lua @@ -0,0 +1,98 @@ +local Purl = require "mason-core.purl" +local Result = require "mason-core.result" +local github = require "mason-core.installer.registry.providers.github" +local installer = require "mason-core.installer" +local match = require "luassert.match" +local mock = require "luassert.mock" +local stub = require "luassert.stub" + +---@param overrides Purl +local function purl(overrides) + local purl = Purl.parse("pkg:github/namespace/name@2023-03-09"):get_or_throw() + if not overrides then + return purl + end + return vim.tbl_deep_extend("force", purl, overrides) +end + +describe("github provider :: build :: parsing", function() + it("should parse build source", function() + assert.same( + Result.success { + build = { + run = [[npm install && npm run compile]], + env = { MASON_VERSION = "2023-03-09" }, + }, + repo = "https://github.com/namespace/name.git", + rev = "2023-03-09", + }, + github.parse({ + build = { + run = [[npm install && npm run compile]], + }, + }, purl()) + ) + end) + + it("should parse build source with multiple targets", function() + assert.same( + Result.success { + build = { + target = "win_x64", + run = [[npm install]], + env = { MASON_VERSION = "2023-03-09" }, + }, + repo = "https://github.com/namespace/name.git", + rev = "2023-03-09", + }, + github.parse({ + build = { + { + target = "linux_arm64", + run = [[npm install && npm run compile]], + }, + { + target = "win_x64", + run = [[npm install]], + }, + }, + }, purl(), { target = "win_x64" }) + ) + end) +end) + +describe("github provider :: build :: installing", function() + it("should install github build sources", function() + local ctx = create_dummy_context() + local std = require "mason-core.installer.managers.std" + local build = require "mason-core.installer.managers.build" + stub(std, "clone", mockx.returns(Result.success())) + stub(build, "run", mockx.returns(Result.success())) + + local result = installer.exec_in_context(ctx, function() + return github.install(ctx, { + repo = "namespace/name", + rev = "2023-03-09", + build = { + run = [[npm install && npm run compile]], + env = { + MASON_VERSION = "2023-03-09", + SOME_VALUE = "here", + }, + }, + }, purl()) + end) + + assert.is_true(result:is_success()) + assert.spy(std.clone).was_called(1) + assert.spy(std.clone).was_called_with("namespace/name", { rev = "2023-03-09" }) + assert.spy(build.run).was_called(1) + assert.spy(build.run).was_called_with { + run = [[npm install && npm run compile]], + env = { + MASON_VERSION = "2023-03-09", + SOME_VALUE = "here", + }, + } + end) +end) diff --git a/tests/mason-core/installer/registry/providers/github_spec.lua b/tests/mason-core/installer/registry/providers/github/release_spec.lua index 58917f4d..6d0ff5df 100644 --- a/tests/mason-core/installer/registry/providers/github_spec.lua +++ b/tests/mason-core/installer/registry/providers/github/release_spec.lua @@ -3,7 +3,6 @@ local Result = require "mason-core.result" local github = require "mason-core.installer.registry.providers.github" local installer = require "mason-core.installer" local match = require "luassert.match" -local mock = require "luassert.mock" local registry_installer = require "mason-core.installer.registry" local spy = require "luassert.spy" local stub = require "luassert.stub" @@ -17,7 +16,7 @@ local function purl(overrides) return vim.tbl_deep_extend("force", purl, overrides) end -describe("github provider :: parsing", function() +describe("github provider :: release :: parsing", function() it("should parse release asset source", function() assert.same( Result.success { @@ -157,7 +156,10 @@ describe("github provider :: parsing", function() it("should parse build source", function() assert.same( Result.success { - build = { run = [[npm install && npm run compile]] }, + build = { + run = [[npm install && npm run compile]], + env = { MASON_VERSION = "2023-03-09" }, + }, repo = "https://github.com/namespace/name.git", rev = "2023-03-09", }, @@ -172,7 +174,11 @@ describe("github provider :: parsing", function() it("should parse build source with multiple targets", function() assert.same( Result.success { - build = { target = "win_x64", run = [[npm install]] }, + build = { + target = "win_x64", + run = [[npm install]], + env = { MASON_VERSION = "2023-03-09" }, + }, repo = "https://github.com/namespace/name.git", rev = "2023-03-09", }, @@ -261,7 +267,7 @@ describe("github provider :: parsing", function() end) end) -describe("github provider :: installing", function() +describe("github provider :: release :: installing", function() it("should install github release assets", function() local ctx = create_dummy_context() local std = require "mason-core.installer.managers.std" @@ -375,49 +381,4 @@ describe("github provider :: installing", function() assert.same(Result.failure [[Version "1.42.0" is not available.]], result) assert.spy(std.download_file).was_called(0) end) - - it("should install github build sources", function() - local ctx = create_dummy_context() - local std = require "mason-core.installer.managers.std" - local uv = require "mason-core.async.uv" - stub(uv, "write") - stub(uv, "shutdown") - stub(uv, "close") - local stdin = mock.new() - stub(std, "clone", mockx.returns(Result.success())) - stub( - ctx.spawn, - "bash", ---@param args SpawnArgs - function(args) - args.on_spawn(mock.new(), { stdin }) - return Result.success() - end - ) - - local result = installer.exec_in_context(ctx, function() - return github.install(ctx, { - repo = "namespace/name", - rev = "2023-03-09", - build = { - run = [[npm install && npm run compile]], - }, - }, purl { version = "2023-03-09" }) - end) - - assert.is_true(result:is_success()) - assert.spy(std.clone).was_called(1) - assert.spy(std.clone).was_called_with("namespace/name", { rev = "2023-03-09" }) - assert.spy(ctx.spawn.bash).was_called(1) - assert.spy(ctx.spawn.bash).was_called_with(match.tbl_containing { - on_spawn = match.is_function(), - env = match.same { - MASON_VERSION = "2023-03-09", - }, - }) - assert.spy(uv.write).was_called(2) - assert.spy(uv.write).was_called_with(stdin, "set -euxo pipefail;\n") - assert.spy(uv.write).was_called_with(stdin, "npm install && npm run compile") - assert.spy(uv.shutdown).was_called_with(stdin) - assert.spy(uv.close).was_called_with(stdin) - end) end) |
