diff options
| author | William Boman <william@redwill.se> | 2023-10-11 16:31:50 +0200 |
|---|---|---|
| committer | William Boman <william@redwill.se> | 2025-02-19 09:22:40 +0100 |
| commit | 047ec18da56ad8f331e5c6bc7417dc5a9a6e71cc (patch) | |
| tree | c50c22cd05d3605fc5a1e8eb902ffeb11e339697 /lua/mason-core/installer/compiler/compilers | |
| parent | refactor(receipt): change receipt structure and remove old builder APIs (#1521) (diff) | |
| download | mason-047ec18da56ad8f331e5c6bc7417dc5a9a6e71cc.tar mason-047ec18da56ad8f331e5c6bc7417dc5a9a6e71cc.tar.gz mason-047ec18da56ad8f331e5c6bc7417dc5a9a6e71cc.tar.bz2 mason-047ec18da56ad8f331e5c6bc7417dc5a9a6e71cc.tar.lz mason-047ec18da56ad8f331e5c6bc7417dc5a9a6e71cc.tar.xz mason-047ec18da56ad8f331e5c6bc7417dc5a9a6e71cc.tar.zst mason-047ec18da56ad8f331e5c6bc7417dc5a9a6e71cc.zip | |
refactor!: refactor installer internals and add new Package class methods (#1523)
This contains the following changes:
1) `Package:install()` now accepts a second, optional, callback argument which is called when installation finishes
(successfully or not).
2) Adds a `Package:is_installing()` method.
This contains the following breaking changes:
1) `Package:install()` will now error when called while an installation is already ongoing. Use the new
`Package:is_installing()` method to check whether an installation is already running.
This also refactors large portions of the tests by removing test globals, removing async_test, and adding the
`mason-test` Lua module instead. Test helpers via globals are problematic to work with due to not being detected through
tools like the Lua language server without additional configuration. This has been replaced with a Lua module
`mason-test`. `async_test` has also been removed in favour of explicitly making use of the `mason-core.async` API. These
changes stands for a significant portion of the diff.
Diffstat (limited to 'lua/mason-core/installer/compiler/compilers')
17 files changed, 843 insertions, 0 deletions
diff --git a/lua/mason-core/installer/compiler/compilers/cargo.lua b/lua/mason-core/installer/compiler/compilers/cargo.lua new file mode 100644 index 00000000..e0f281c5 --- /dev/null +++ b/lua/mason-core/installer/compiler/compilers/cargo.lua @@ -0,0 +1,85 @@ +local Result = require "mason-core.result" +local _ = require "mason-core.functional" +local providers = require "mason-core.providers" +local util = require "mason-core.installer.compiler.util" + +local M = {} + +---@class CargoSource : RegistryPackageSource +---@field supported_platforms? string[] + +---@param source CargoSource +---@param purl Purl +function M.parse(source, purl) + return Result.try(function(try) + if source.supported_platforms then + try(util.ensure_valid_platform(source.supported_platforms)) + end + + local repository_url = _.path({ "qualifiers", "repository_url" }, purl) + + local git + if repository_url then + git = { + url = repository_url, + rev = _.path({ "qualifiers", "rev" }, purl) == "true", + } + end + + ---@type string? + local features = _.path({ "qualifiers", "features" }, purl) + local locked = _.path({ "qualifiers", "locked" }, purl) + + ---@class ParsedCargoSource : ParsedPackageSource + local parsed_source = { + crate = purl.name, + version = purl.version, + features = features, + locked = locked ~= "false", + git = git, + } + return parsed_source + end) +end + +---@async +---@param ctx InstallContext +---@param source ParsedCargoSource +function M.install(ctx, source) + local cargo = require "mason-core.installer.managers.cargo" + + return cargo.install(source.crate, source.version, { + git = source.git, + features = source.features, + locked = source.locked, + }) +end + +---@async +---@param purl Purl +function M.get_versions(purl) + ---@type string? + local repository_url = _.path({ "qualifiers", "repository_url" }, purl) + local rev = _.path({ "qualifiers", "rev" }, purl) + if repository_url then + if rev == "true" then + -- When ?rev=true we're targeting a commit SHA. It's not feasible to retrieve all commit SHAs for a + -- repository so we fail instead. + return Result.failure "Unable to retrieve commit SHAs." + end + + ---@type Result? + local git_tags = _.cond { + { + _.matches "github.com/(.+)", + _.compose(providers.github.get_all_tags, _.head, _.match "github.com/(.+)"), + }, + }(repository_url) + if git_tags then + return git_tags + end + end + return providers.crates.get_all_versions(purl.name) +end + +return M diff --git a/lua/mason-core/installer/compiler/compilers/composer.lua b/lua/mason-core/installer/compiler/compilers/composer.lua new file mode 100644 index 00000000..259512a2 --- /dev/null +++ b/lua/mason-core/installer/compiler/compilers/composer.lua @@ -0,0 +1,33 @@ +local Result = require "mason-core.result" +local providers = require "mason-core.providers" +local util = require "mason-core.installer.compiler.util" + +local M = {} + +---@param source RegistryPackageSource +---@param purl Purl +function M.parse(source, purl) + ---@class ParsedComposerSource : ParsedPackageSource + local parsed_source = { + package = ("%s/%s"):format(purl.namespace, purl.name), + version = purl.version, + } + + return Result.success(parsed_source) +end + +---@async +---@param ctx InstallContext +---@param source ParsedComposerSource +function M.install(ctx, source) + local composer = require "mason-core.installer.managers.composer" + return composer.install(source.package, source.version) +end + +---@async +---@param purl Purl +function M.get_versions(purl) + return providers.packagist.get_all_versions(("%s/%s"):format(purl.namespace, purl.name)) +end + +return M diff --git a/lua/mason-core/installer/compiler/compilers/gem.lua b/lua/mason-core/installer/compiler/compilers/gem.lua new file mode 100644 index 00000000..7a343eec --- /dev/null +++ b/lua/mason-core/installer/compiler/compilers/gem.lua @@ -0,0 +1,46 @@ +local Result = require "mason-core.result" +local _ = require "mason-core.functional" +local providers = require "mason-core.providers" +local util = require "mason-core.installer.compiler.util" + +local M = {} + +---@class GemSource : RegistryPackageSource +---@field supported_platforms? string[] +---@field extra_packages? string[] + +---@param source GemSource +---@param purl Purl +function M.parse(source, purl) + return Result.try(function(try) + if source.supported_platforms then + try(util.ensure_valid_platform(source.supported_platforms)) + end + + ---@class ParsedGemSource : ParsedPackageSource + local parsed_source = { + package = purl.name, + version = purl.version, + extra_packages = source.extra_packages, + } + return parsed_source + end) +end + +---@async +---@param ctx InstallContext +---@param source ParsedGemSource +function M.install(ctx, source) + local gem = require "mason-core.installer.managers.gem" + return gem.install(source.package, source.version, { + extra_packages = source.extra_packages, + }) +end + +---@async +---@param purl Purl +function M.get_versions(purl) + return providers.rubygems.get_all_versions(purl.name) +end + +return M diff --git a/lua/mason-core/installer/compiler/compilers/generic/build.lua b/lua/mason-core/installer/compiler/compilers/generic/build.lua new file mode 100644 index 00000000..df97a118 --- /dev/null +++ b/lua/mason-core/installer/compiler/compilers/generic/build.lua @@ -0,0 +1,40 @@ +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.compiler.expr" +local util = require "mason-core.installer.compiler.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)) + + 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 common.run_build_instruction(source.build) +end + +return M diff --git a/lua/mason-core/installer/compiler/compilers/generic/download.lua b/lua/mason-core/installer/compiler/compilers/generic/download.lua new file mode 100644 index 00000000..37e54d96 --- /dev/null +++ b/lua/mason-core/installer/compiler/compilers/generic/download.lua @@ -0,0 +1,52 @@ +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.compiler.expr" +local util = require "mason-core.installer.compiler.util" + +local M = {} + +---@class GenericDownload +---@field target (Platform | Platform[])? +---@field files table<string, string> + +---@class GenericDownloadSource : RegistryPackageSource +---@field download GenericDownload | GenericDownload[] + +---@param source GenericDownloadSource +---@param purl Purl +---@param opts PackageInstallOpts +function M.parse(source, purl, opts) + return Result.try(function(try) + 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) +end + +---@async +---@param ctx InstallContext +---@param source ParsedGenericDownloadSource +function M.install(ctx, source) + return common.download_files(ctx, source.downloads) +end + +return M diff --git a/lua/mason-core/installer/compiler/compilers/generic/init.lua b/lua/mason-core/installer/compiler/compilers/generic/init.lua new file mode 100644 index 00000000..8206883f --- /dev/null +++ b/lua/mason-core/installer/compiler/compilers/generic/init.lua @@ -0,0 +1,42 @@ +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.compiler.compilers.generic.download").parse(source, purl, opts) + elseif source.build then + source = source --[[@as GenericBuildSource]] + return require("mason-core.installer.compiler.compilers.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.compiler.compilers.generic.download").install(ctx, source) + elseif source.build then + source = source --[[@as ParsedGenericBuildSource]] + return require("mason-core.installer.compiler.compilers.generic.build").install(ctx, source) + else + return Result.failure "Unknown source type." + end +end + +---@async +---@param purl Purl +function M.get_versions(purl) + return Result.failure "Unimplemented." +end + +return M diff --git a/lua/mason-core/installer/compiler/compilers/github/build.lua b/lua/mason-core/installer/compiler/compilers/github/build.lua new file mode 100644 index 00000000..22f3e3cc --- /dev/null +++ b/lua/mason-core/installer/compiler/compilers/github/build.lua @@ -0,0 +1,51 @@ +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.compiler.expr" +local util = require "mason-core.installer.compiler.util" + +local M = {} + +---@class GitHubBuildSource : RegistryPackageSource +---@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 BuildInstruction + local build_instruction = try(util.coalesce_by_target(source.build, opts)) + + 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, + repo = ("https://github.com/%s/%s.git"):format(purl.namespace, purl.name), + rev = purl.version, + } + return parsed_source + end) +end + +---@async +---@param ctx InstallContext +---@param source ParsedGitHubBuildSource +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(common.run_build_instruction(source.build)) + end) +end + +return M diff --git a/lua/mason-core/installer/compiler/compilers/github/init.lua b/lua/mason-core/installer/compiler/compilers/github/init.lua new file mode 100644 index 00000000..d8646975 --- /dev/null +++ b/lua/mason-core/installer/compiler/compilers/github/init.lua @@ -0,0 +1,49 @@ +local Result = require "mason-core.result" + +local M = {} + +---@param source GitHubReleaseSource | GitHubBuildSource +---@param purl Purl +---@param opts PackageInstallOpts +function M.parse(source, purl, opts) + if source.asset then + source = source --[[@as GitHubReleaseSource]] + return require("mason-core.installer.compiler.compilers.github.release").parse(source, purl, opts) + elseif source.build then + source = source --[[@as GitHubBuildSource]] + return require("mason-core.installer.compiler.compilers.github.build").parse(source, purl, opts) + else + return Result.failure "Unknown source type." + end +end + +---@async +---@param ctx InstallContext +---@param source ParsedGitHubReleaseSource | ParsedGitHubBuildSource +function M.install(ctx, source, purl) + if source.asset then + source = source--[[@as ParsedGitHubReleaseSource]] + return require("mason-core.installer.compiler.compilers.github.release").install(ctx, source) + elseif source.build then + source = source--[[@as ParsedGitHubBuildSource]] + return require("mason-core.installer.compiler.compilers.github.build").install(ctx, source) + else + return Result.failure "Unknown source type." + end +end + +---@async +---@param purl Purl +---@param source GitHubReleaseSource | GitHubBuildSource +function M.get_versions(purl, source) + if source.asset then + return require("mason-core.installer.compiler.compilers.github.release").get_versions(purl) + elseif source.build then + -- We can't yet reliably determine the true source (release, tag, commit, etc.) for "build" sources. + return Result.failure "Unimplemented." + else + return Result.failure "Unknown source type." + end +end + +return M diff --git a/lua/mason-core/installer/compiler/compilers/github/release.lua b/lua/mason-core/installer/compiler/compilers/github/release.lua new file mode 100644 index 00000000..39f7d862 --- /dev/null +++ b/lua/mason-core/installer/compiler/compilers/github/release.lua @@ -0,0 +1,57 @@ +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.compiler.expr" +local providers = require "mason-core.providers" +local settings = require "mason.settings" +local util = require "mason-core.installer.compiler.util" + +---@class GitHubReleaseSourceAsset : FileDownloadSpec +---@field target? Platform | Platform[] + +---@class GitHubReleaseSource : RegistryPackageSource +---@field asset GitHubReleaseSourceAsset | GitHubReleaseSourceAsset[] + +local M = {} + +---@param source GitHubReleaseSource +---@param purl Purl +---@param opts PackageInstallOpts +function M.parse(source, purl, opts) + return Result.try(function(try) + local expr_ctx = { version = purl.version } + ---@type GitHubReleaseSourceAsset + local asset = try(util.coalesce_by_target(try(expr.tbl_interpolate(source.asset, expr_ctx)), opts)) + + local downloads = common.parse_downloads(asset, function(file) + return settings.current.github.download_url_template:format( + ("%s/%s"):format(purl.namespace, purl.name), + purl.version, + file + ) + end) + + ---@class ParsedGitHubReleaseSource : ParsedPackageSource + local parsed_source = { + repo = ("%s/%s"):format(purl.namespace, purl.name), + asset = common.normalize_files(asset), + downloads = downloads, + } + return parsed_source + end) +end + +---@async +---@param ctx InstallContext +---@param source ParsedGitHubReleaseSource +function M.install(ctx, source) + return common.download_files(ctx, source.downloads) +end + +---@async +---@param purl Purl +function M.get_versions(purl) + return providers.github.get_all_release_versions(("%s/%s"):format(purl.namespace, purl.name)) +end + +return M diff --git a/lua/mason-core/installer/compiler/compilers/golang.lua b/lua/mason-core/installer/compiler/compilers/golang.lua new file mode 100644 index 00000000..01807088 --- /dev/null +++ b/lua/mason-core/installer/compiler/compilers/golang.lua @@ -0,0 +1,50 @@ +local Result = require "mason-core.result" +local _ = require "mason-core.functional" +local providers = require "mason-core.providers" +local util = require "mason-core.installer.compiler.util" + +local M = {} + +---@param purl Purl +local function get_package_name(purl) + if purl.subpath then + return ("%s/%s/%s"):format(purl.namespace, purl.name, purl.subpath) + else + return ("%s/%s"):format(purl.namespace, purl.name) + end +end + +---@class GolangSource : RegistryPackageSource +---@field extra_packages? string[] + +---@param source GolangSource +---@param purl Purl +function M.parse(source, purl) + ---@class ParsedGolangSource : ParsedPackageSource + local parsed_source = { + package = get_package_name(purl), + version = purl.version, + extra_packages = source.extra_packages, + } + + return Result.success(parsed_source) +end + +---@async +---@param ctx InstallContext +---@param source ParsedGolangSource +function M.install(ctx, source) + local golang = require "mason-core.installer.managers.golang" + + return golang.install(source.package, source.version, { + extra_packages = source.extra_packages, + }) +end + +---@async +---@param purl Purl +function M.get_versions(purl) + return providers.golang.get_all_versions(("%s/%s"):format(purl.namespace, purl.name)) +end + +return M diff --git a/lua/mason-core/installer/compiler/compilers/luarocks.lua b/lua/mason-core/installer/compiler/compilers/luarocks.lua new file mode 100644 index 00000000..356857c0 --- /dev/null +++ b/lua/mason-core/installer/compiler/compilers/luarocks.lua @@ -0,0 +1,51 @@ +local Result = require "mason-core.result" +local _ = require "mason-core.functional" + +local M = {} + +---@param purl Purl +local function parse_package_name(purl) + if purl.namespace then + return ("%s/%s"):format(purl.namespace, purl.name) + else + return purl.name + end +end + +local parse_server = _.path { "qualifiers", "repository_url" } +local parse_dev = _.compose(_.equals "true", _.path { "qualifiers", "dev" }) + +---@param source RegistryPackageSource +---@param purl Purl +function M.parse(source, purl) + ---@class ParsedLuaRocksSource : ParsedPackageSource + local parsed_source = { + package = parse_package_name(purl), + version = purl.version, + ---@type string? + server = parse_server(purl), + ---@type boolean? + dev = parse_dev(purl), + } + + return Result.success(parsed_source) +end + +---@async +---@param ctx InstallContext +---@param source ParsedLuaRocksSource +function M.install(ctx, source) + local luarocks = require "mason-core.installer.managers.luarocks" + return luarocks.install(source.package, source.version, { + server = source.server, + dev = source.dev, + }) +end + +---@async +---@param purl Purl +function M.get_versions(purl) + return Result.failure "Unimplemented." +end + +return M diff --git a/lua/mason-core/installer/compiler/compilers/mason.lua b/lua/mason-core/installer/compiler/compilers/mason.lua new file mode 100644 index 00000000..3490ebaa --- /dev/null +++ b/lua/mason-core/installer/compiler/compilers/mason.lua @@ -0,0 +1,43 @@ +local Result = require "mason-core.result" +local _ = require "mason-core.functional" + +local M = {} + +---@param source RegistryPackageSource +---@param purl Purl +function M.parse(source, purl) + if type(source.install) ~= "function" and type((getmetatable(source.install) or {}).__call) ~= "function" then + return Result.failure "source.install is not a function." + end + + ---@class ParsedMasonSource : ParsedPackageSource + local parsed_source = { + purl = purl, + ---@type async fun(ctx: InstallContext, purl: Purl) + install = source.install, + } + + return Result.success(parsed_source) +end + +---@async +---@param ctx InstallContext +---@param source ParsedMasonSource +function M.install(ctx, source) + ctx.spawn.strict_mode = true + return Result.pcall(source.install, ctx, source.purl) + :on_success(function() + ctx.spawn.strict_mode = false + end) + :on_failure(function() + ctx.spawn.strict_mode = false + end) +end + +---@async +---@param purl Purl +function M.get_versions(purl) + return Result.failure "Unimplemented." +end + +return M diff --git a/lua/mason-core/installer/compiler/compilers/npm.lua b/lua/mason-core/installer/compiler/compilers/npm.lua new file mode 100644 index 00000000..e8489fe8 --- /dev/null +++ b/lua/mason-core/installer/compiler/compilers/npm.lua @@ -0,0 +1,52 @@ +local Result = require "mason-core.result" +local _ = require "mason-core.functional" +local providers = require "mason-core.providers" + +---@param purl Purl +local function purl_to_npm(purl) + if purl.namespace then + return ("%s/%s"):format(purl.namespace, purl.name) + else + return purl.name + end +end + +local M = {} + +---@class NpmSource : RegistryPackageSource +---@field extra_packages? string[] + +---@param source NpmSource +---@param purl Purl +function M.parse(source, purl) + ---@class ParsedNpmSource : ParsedPackageSource + local parsed_source = { + package = purl_to_npm(purl), + version = purl.version, + extra_packages = source.extra_packages, + } + + return Result.success(parsed_source) +end + +---@async +---@param ctx InstallContext +---@param source ParsedNpmSource +function M.install(ctx, source) + local npm = require "mason-core.installer.managers.npm" + + return Result.try(function(try) + try(npm.init()) + try(npm.install(source.package, source.version, { + extra_packages = source.extra_packages, + })) + end) +end + +---@async +---@param purl Purl +function M.get_versions(purl) + return providers.npm.get_all_versions(purl_to_npm(purl)) +end + +return M diff --git a/lua/mason-core/installer/compiler/compilers/nuget.lua b/lua/mason-core/installer/compiler/compilers/nuget.lua new file mode 100644 index 00000000..370c7b95 --- /dev/null +++ b/lua/mason-core/installer/compiler/compilers/nuget.lua @@ -0,0 +1,31 @@ +local Result = require "mason-core.result" + +local M = {} + +---@param source RegistryPackageSource +---@param purl Purl +function M.parse(source, purl) + ---@class ParsedNugetSource : ParsedPackageSource + local parsed_source = { + package = purl.name, + version = purl.version, + } + + return Result.success(parsed_source) +end + +---@async +---@param ctx InstallContext +---@param source ParsedNugetSource +function M.install(ctx, source) + local nuget = require "mason-core.installer.managers.nuget" + return nuget.install(source.package, source.version) +end + +---@async +---@param purl Purl +function M.get_versions(purl) + return Result.failure "Unimplemented." +end + +return M diff --git a/lua/mason-core/installer/compiler/compilers/opam.lua b/lua/mason-core/installer/compiler/compilers/opam.lua new file mode 100644 index 00000000..276686ae --- /dev/null +++ b/lua/mason-core/installer/compiler/compilers/opam.lua @@ -0,0 +1,31 @@ +local Result = require "mason-core.result" + +local M = {} + +---@param source RegistryPackageSource +---@param purl Purl +function M.parse(source, purl) + ---@class ParsedOpamSource : ParsedPackageSource + local parsed_source = { + package = purl.name, + version = purl.version, + } + + return Result.success(parsed_source) +end + +---@async +---@param ctx InstallContext +---@param source ParsedOpamSource +function M.install(ctx, source) + local opam = require "mason-core.installer.managers.opam" + return opam.install(source.package, source.version) +end + +---@async +---@param purl Purl +function M.get_versions(purl) + return Result.failure "Unimplemented." +end + +return M diff --git a/lua/mason-core/installer/compiler/compilers/openvsx.lua b/lua/mason-core/installer/compiler/compilers/openvsx.lua new file mode 100644 index 00000000..bf31e2f9 --- /dev/null +++ b/lua/mason-core/installer/compiler/compilers/openvsx.lua @@ -0,0 +1,64 @@ +local Result = require "mason-core.result" +local common = require "mason-core.installer.managers.common" +local expr = require "mason-core.installer.compiler.expr" +local providers = require "mason-core.providers" +local util = require "mason-core.installer.compiler.util" + +local M = {} + +---@class OpenVSXSourceDownload : FileDownloadSpec +---@field target? Platform | Platform[] +---@field target_platform? string + +---@class OpenVSXSource : RegistryPackageSource +---@field download OpenVSXSourceDownload | OpenVSXSourceDownload[] + +---@param source OpenVSXSource +---@param purl Purl +---@param opts PackageInstallOpts +function M.parse(source, purl, opts) + return Result.try(function(try) + local expr_ctx = { version = purl.version } + ---@type OpenVSXSourceDownload + local download = try(util.coalesce_by_target(try(expr.tbl_interpolate(source.download, expr_ctx)), opts)) + + local downloads = common.parse_downloads(download, function(file) + if download.target_platform then + return ("https://open-vsx.org/api/%s/%s/%s/%s/file/%s"):format( + purl.namespace, + purl.name, + download.target_platform, + purl.version, + file + ) + else + return ("https://open-vsx.org/api/%s/%s/%s/file/%s"):format( + purl.namespace, + purl.name, + purl.version, + file + ) + end + end) + + ---@class ParsedOpenVSXSource : ParsedPackageSource + local parsed_source = { + download = common.normalize_files(download), + downloads = downloads, + } + return parsed_source + end) +end + +---@param ctx InstallContext +---@param source ParsedOpenVSXSource +function M.install(ctx, source) + return common.download_files(ctx, source.downloads) +end + +---@param purl Purl +function M.get_versions(purl) + return providers.openvsx.get_all_versions(purl.namespace, purl.name) +end + +return M diff --git a/lua/mason-core/installer/compiler/compilers/pypi.lua b/lua/mason-core/installer/compiler/compilers/pypi.lua new file mode 100644 index 00000000..c44fcfe1 --- /dev/null +++ b/lua/mason-core/installer/compiler/compilers/pypi.lua @@ -0,0 +1,66 @@ +local Result = require "mason-core.result" +local _ = require "mason-core.functional" +local providers = require "mason-core.providers" +local settings = require "mason.settings" +local util = require "mason-core.installer.compiler.util" + +local M = {} + +---@class PypiSource : RegistryPackageSource +---@field extra_packages? string[] +---@field supported_platforms? string[] + +---@param source PypiSource +---@param purl Purl +function M.parse(source, purl) + return Result.try(function(try) + if source.supported_platforms then + try(util.ensure_valid_platform(source.supported_platforms)) + end + + ---@class ParsedPypiSource : ParsedPackageSource + local parsed_source = { + package = purl.name, + version = purl.version --[[ @as string ]], + extra = _.path({ "qualifiers", "extra" }, purl), + extra_packages = source.extra_packages, + pip = { + upgrade = settings.current.pip.upgrade_pip, + extra_args = settings.current.pip.install_args, + }, + } + + return parsed_source + end) +end + +---@async +---@param ctx InstallContext +---@param source ParsedPypiSource +function M.install(ctx, source) + local pypi = require "mason-core.installer.managers.pypi" + + return Result.try(function(try) + try(pypi.init { + package = { + name = source.package, + version = source.version, + }, + upgrade_pip = source.pip.upgrade, + install_extra_args = source.pip.extra_args, + }) + try(pypi.install(source.package, source.version, { + extra = source.extra, + extra_packages = source.extra_packages, + install_extra_args = source.pip.extra_args, + })) + end) +end + +---@async +---@param purl Purl +function M.get_versions(purl) + return providers.pypi.get_all_versions(purl.name) +end + +return M |
