diff options
| author | William Boman <william@redwill.se> | 2022-07-08 18:34:38 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-07-08 18:34:38 +0200 |
| commit | 976aa4fbee8a070f362cab6f6ec84e9251a90cf9 (patch) | |
| tree | 5e8d9c9c59444a25c7801b8f39763c4ba6e1f76d /lua/mason-core/managers/github/init.lua | |
| parent | feat: add gotests, gomodifytags, impl (#28) (diff) | |
| download | mason-976aa4fbee8a070f362cab6f6ec84e9251a90cf9.tar mason-976aa4fbee8a070f362cab6f6ec84e9251a90cf9.tar.gz mason-976aa4fbee8a070f362cab6f6ec84e9251a90cf9.tar.bz2 mason-976aa4fbee8a070f362cab6f6ec84e9251a90cf9.tar.lz mason-976aa4fbee8a070f362cab6f6ec84e9251a90cf9.tar.xz mason-976aa4fbee8a070f362cab6f6ec84e9251a90cf9.tar.zst mason-976aa4fbee8a070f362cab6f6ec84e9251a90cf9.zip | |
refactor: add mason-schemas and mason-core modules (#29)
* refactor: add mason-schemas and move generated filetype map to mason-lspconfig
* refactor: add mason-core module
Diffstat (limited to 'lua/mason-core/managers/github/init.lua')
| -rw-r--r-- | lua/mason-core/managers/github/init.lua | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/lua/mason-core/managers/github/init.lua b/lua/mason-core/managers/github/init.lua new file mode 100644 index 00000000..55f3600f --- /dev/null +++ b/lua/mason-core/managers/github/init.lua @@ -0,0 +1,171 @@ +local installer = require "mason-core.installer" +local std = require "mason-core.managers.std" +local client = require "mason-core.managers.github.client" +local platform = require "mason-core.platform" +local Result = require "mason-core.result" +local _ = require "mason-core.functional" +local settings = require "mason.settings" + +local M = {} + +---@param repo string +---@param asset_file string +---@param release string +local function with_release_file_receipt(repo, asset_file, release) + return function() + local ctx = installer.context() + ctx.receipt:with_primary_source { + type = "github_release_file", + repo = repo, + file = asset_file, + release = release, + } + end +end + +---@param repo string +---@param tag string +local function with_tag_receipt(repo, tag) + return function() + local ctx = installer.context() + ctx.receipt:with_primary_source { + type = "github_tag", + repo = repo, + tag = tag, + } + end +end + +---@async +---@param opts {repo: string, version: Optional|nil, asset_file: string|fun(release: string):string} +function M.release_file(opts) + local ctx = installer.context() + local release = _.coalesce(opts.version, ctx.requested_version):or_else_get(function() + return client + .fetch_latest_release(opts.repo) + :map(_.prop "tag_name") + :get_or_throw "Failed to fetch latest release from GitHub API. Refer to :h mason-errors-github-api for more information." + end) + ---@type string + local asset_file + if type(opts.asset_file) == "function" then + asset_file = opts.asset_file(release) + else + asset_file = opts.asset_file + end + if not asset_file then + error( + ( + "Could not find which release file to download.\nMost likely the current operating system, architecture (%s), or libc (%s) is not supported." + ):format(platform.arch, platform.get_libc()), + 0 + ) + end + local download_url = settings.current.github.download_url_template:format(opts.repo, release, asset_file) + return { + release = release, + download_url = download_url, + asset_file = asset_file, + with_receipt = with_release_file_receipt(opts.repo, download_url, release), + } +end + +---@async +---@param opts {repo: string, version: Optional|nil} +function M.tag(opts) + local ctx = installer.context() + local tag = _.coalesce(opts.version, ctx.requested_version):or_else_get(function() + return client.fetch_latest_tag(opts.repo):get_or_throw "Failed to fetch latest tag from GitHub API." + end) + + return { + tag = tag, + with_receipt = with_tag_receipt(opts.repo, tag), + } +end + +---@param filename string +---@param processor async fun(opts: table) +local function release_file_processor(filename, processor) + ---@async + ---@param opts {repo: string, asset_file: string|fun(release: string):string} + return function(opts) + local release_file_source = M.release_file(opts) + std.download_file(release_file_source.download_url, filename) + processor(opts) + return release_file_source + end +end + +M.unzip_release_file = release_file_processor("archive.zip", function() + std.unzip("archive.zip", ".") +end) + +M.untarxz_release_file = release_file_processor("archive.tar.xz", function(opts) + std.untarxz("archive.tar.xz", { strip_components = opts.strip_components }) +end) + +M.untargz_release_file = release_file_processor("archive.tar.gz", function(opts) + std.untar("archive.tar.gz", { strip_components = opts.strip_components }) +end) + +---@async +---@param opts {repo: string, out_file:string, asset_file: string|fun(release: string):string} +function M.download_release_file(opts) + local release_file_source = M.release_file(opts) + std.download_file(release_file_source.download_url, assert(opts.out_file, "out_file is required")) + return release_file_source +end + +---@async +---@param opts {repo: string, out_file:string, asset_file: string|fun(release: string):string} +function M.gunzip_release_file(opts) + local release_file_source = M.release_file(opts) + local gzipped_file = ("%s.gz"):format(assert(opts.out_file, "out_file must be specified")) + std.download_file(release_file_source.download_url, gzipped_file) + std.gunzip(gzipped_file) + return release_file_source +end + +---@async +---@param receipt InstallReceipt +function M.check_outdated_primary_package_release(receipt) + local source = receipt.primary_source + if source.type ~= "github_release" and source.type ~= "github_release_file" then + return Result.failure "Receipt does not have a primary source of type (github_release|github_release_file)." + end + return client.fetch_latest_release(source.repo, { tag_name_pattern = source.tag_name_pattern }):map_catching( + ---@param latest_release GitHubRelease + function(latest_release) + if source.release ~= latest_release.tag_name then + return { + name = source.repo, + current_version = source.release, + latest_version = latest_release.tag_name, + } + end + error "Primary package is not outdated." + end + ) +end + +---@async +---@param receipt InstallReceipt +function M.check_outdated_primary_package_tag(receipt) + local source = receipt.primary_source + if source.type ~= "github_tag" then + return Result.failure "Receipt does not have a primary source of type github_tag." + end + return client.fetch_latest_tag(source.repo):map_catching(function(latest_tag) + if source.tag ~= latest_tag then + return { + name = source.repo, + current_version = source.tag, + latest_version = latest_tag, + } + end + error "Primary package is not outdated." + end) +end + +return M |
