diff options
Diffstat (limited to 'scripts')
| -rw-r--r-- | scripts/lua/mason-scripts/markdown.lua | 93 | ||||
| -rw-r--r-- | scripts/lua/mason-scripts/mason/generate.lua | 2 | ||||
| -rw-r--r-- | scripts/lua/mason-scripts/mason/generate_package_index.lua | 44 | ||||
| -rw-r--r-- | scripts/lua/mason-scripts/templates/PACKAGES.template.md | 11 | ||||
| -rw-r--r-- | scripts/lua/mason-scripts/templates/package-section.template.md | 19 | ||||
| -rw-r--r-- | scripts/lua/mason-scripts/templates/parse_commit.lua | 16 | ||||
| -rw-r--r-- | scripts/lua/mason-scripts/utils.lua | 30 |
7 files changed, 205 insertions, 10 deletions
diff --git a/scripts/lua/mason-scripts/markdown.lua b/scripts/lua/mason-scripts/markdown.lua new file mode 100644 index 00000000..bc20fe3f --- /dev/null +++ b/scripts/lua/mason-scripts/markdown.lua @@ -0,0 +1,93 @@ +local path = require "mason-core.path" +local _ = require "mason-core.functional" +local script_utils = require "mason-scripts.utils" +local fs = require "mason-core.fs" + +local M = {} + +---Direct context access syntax (e.g. "{{ value }}" or "{{ nested.value }}") +---@param context table<string, any> +---@param str string +local prop_interpolate = _.curryN(function(context, str) + return _.gsub("{{%s?([%w_%.0-9]+)%s?}}", function(key) + return vim.tbl_get(context, unpack(_.split("%.", key))) + end, str) +end, 2) + +local TEMPLATE_GLOBALS = { + _ = _, + url = function(url) + return ("[%s](%s)"):format(url, url) + end, + link = function(heading) + -- TODO turn heading into valid string, not needed for now + return ("[%s](#%s)"):format(heading, heading) + end, + list = _.compose(_.join "\n", _.map(_.format "- %s")), + join = _.curryN(function(items, delim) + return _.join(delim, items) + end, 2), + each = _.curryN(function(items, format) + local formatter = _.cond { + { _.is "function", _.identity }, + { + _.is "string", + function(template) + return function(item) + return prop_interpolate({ it = item }, template) + end + end, + }, + }(format) + return _.map(formatter, items) + end, 2), + render_each = _.curryN(function(items, template_file) + return _.map(M.render(template_file), items) + end, 2), +} + +---Expression syntax (e.g. "{% "hello world" %}" or "{% join({"One", "Two"}), "\n" %}") +---@param context table<string, any> +---@param str string +local expr_interpolate = _.curryN(function(context, str) + return _.gsub( + [[{%%%s?([%w%-_%.0-9%(%)%[%]%s%+%*,"/\|=%{%}]+)%s?%%}]], -- giggity + function(expr) + local eval_result = + setfenv(loadstring(("return %s"):format(expr)), setmetatable(TEMPLATE_GLOBALS, { __index = context }))() + + if type(eval_result) == "table" then + -- expressions may return tables for convenience reasons + return _.join("", eval_result) + else + return eval_result + end + end, + str + ) +end, 2) + +local header_interpolate = _.curryN(function(context, str) + return _.gsub([[{#%s?([%w%s_%-%.0-9/"]+)%s?#}]], function(header) + setfenv(loadstring(header), { + include = function(file) + local mod = require(("mason-scripts.templates.%s"):format(file)) + for k, v in pairs(mod) do + context[k] = v + end + end, + })() + return "" + end, str) +end, 2) + +---@param template_file string +---@param context table<string, string> +M.render = _.curryN(function(template_file, context) + local template = fs.sync.read_file(script_utils.rel_path(path.concat { "templates", template_file })) + local interpolate = _.compose(prop_interpolate(context), expr_interpolate(context), header_interpolate(context)) + local formatted_template = interpolate(template) + return formatted_template +end, 2) + +return M diff --git a/scripts/lua/mason-scripts/mason/generate.lua b/scripts/lua/mason-scripts/mason/generate.lua index 92fb4737..3c771785 100644 --- a/scripts/lua/mason-scripts/mason/generate.lua +++ b/scripts/lua/mason-scripts/mason/generate.lua @@ -1,7 +1,6 @@ local a = require "mason-core.async" local path = require "mason-core.path" local _ = require "mason-core.functional" -local registry = require "mason-registry" local script_utils = require "mason-scripts.utils" local MASON_DIR = path.concat { vim.loop.cwd(), "lua", "mason" } @@ -9,6 +8,7 @@ local MASON_REGISTRY_DIR = path.concat { vim.loop.cwd(), "lua", "mason-registry" ---@async local function create_language_map() + local registry = require "mason-registry" print "Creating language map…" local indexed_languages = {} local language_map = {} diff --git a/scripts/lua/mason-scripts/mason/generate_package_index.lua b/scripts/lua/mason-scripts/mason/generate_package_index.lua new file mode 100644 index 00000000..a05b67b6 --- /dev/null +++ b/scripts/lua/mason-scripts/mason/generate_package_index.lua @@ -0,0 +1,44 @@ +local a = require "mason-core.async" +local control = require "mason-core.async.control" +local path = require "mason-core.path" +local _ = require "mason-core.functional" +local script_utils = require "mason-scripts.utils" +local markdown = require "mason-scripts.markdown" +local spawn = require "mason-core.spawn" + +local Semaphore = control.Semaphore + +---@async +local function create_markdown_index() + local registry = require "mason-registry" + print "Creating markdown index…" + local packages = _.sort_by(_.prop "name", registry.get_all_packages()) + local sem = Semaphore.new(10) + + a.wait_all(_.map(function(pkg) + return function() + local permit = sem:acquire() + local history = spawn.git { + "log", + "--format=%h\t%cd\t%an\t%s", + "--date=short", + "--", + path.concat { "lua", "mason-registry", pkg.name, "init.lua" }, + } + permit:forget() + pkg.history = _.split("\n", _.trim(history:get_or_throw().stdout)) + end + end, packages)) + + script_utils.write_file( + "PACKAGES.md", + markdown.render("PACKAGES.template.md", { + ["last_updated"] = os.date "!%c", + ["packages"] = packages, + }) + ) +end + +a.run_blocking(function() + create_markdown_index() +end) diff --git a/scripts/lua/mason-scripts/templates/PACKAGES.template.md b/scripts/lua/mason-scripts/templates/PACKAGES.template.md new file mode 100644 index 00000000..c0b38280 --- /dev/null +++ b/scripts/lua/mason-scripts/templates/PACKAGES.template.md @@ -0,0 +1,11 @@ +# Mason Package Index +> `:Mason` + +{% list(each(packages, _.compose(link, _.prop("name")))) %} + +{% render_each(packages) "./package-section.template.md" %} +--- +<sub><sup> +Last updated: {% last_updated %}<br/> +[https://github.com/williamboman/mason.nvim](https://github.com/williamboman/mason.nvim) +</sup></sub> diff --git a/scripts/lua/mason-scripts/templates/package-section.template.md b/scripts/lua/mason-scripts/templates/package-section.template.md new file mode 100644 index 00000000..b71882f2 --- /dev/null +++ b/scripts/lua/mason-scripts/templates/package-section.template.md @@ -0,0 +1,19 @@ +{# include "parse_commit" #} + +# {{ name }} + +> {{ spec.desc }} + +Homepage: {% url(spec.homepage) %} +Languages: {% join(spec.languages) ", " %} +Categories: {% join(spec.categories) ", " %} + +<details> + <summary>History:</summary> + +{% list(each(history, parse_commit)) %} +</details> + +``` +:MasonInstall {{ name }} +``` diff --git a/scripts/lua/mason-scripts/templates/parse_commit.lua b/scripts/lua/mason-scripts/templates/parse_commit.lua new file mode 100644 index 00000000..2f7e7358 --- /dev/null +++ b/scripts/lua/mason-scripts/templates/parse_commit.lua @@ -0,0 +1,16 @@ +local _ = require "mason-core.functional" + +local linkify = _.gsub([[#(%d+)]], function(issue) + return ("[#%d](https://github.com/williamboman/mason.nvim/issues/%d)"):format(issue, issue) +end) + +return { + parse_commit = function(commit_str) + local commit = + _.compose(_.zip_table { "sha", "commit_date", "author_name", "subject" }, _.split "\t")(commit_str) + + return (_.dedent [[ + [`%s`](https://github.com/williamboman/mason.nvim/commit/%s) %s - %s by %s + ]]):format(commit.sha, commit.sha, commit.commit_date, linkify(commit.subject), commit.author_name) + end, +} diff --git a/scripts/lua/mason-scripts/utils.lua b/scripts/lua/mason-scripts/utils.lua index 771d419a..e29a9364 100644 --- a/scripts/lua/mason-scripts/utils.lua +++ b/scripts/lua/mason-scripts/utils.lua @@ -1,3 +1,5 @@ +local _ = require "mason-core.functional" +local Path = require "mason-core.path" local fs = require "mason-core.fs" local M = {} @@ -7,15 +9,25 @@ local M = {} ---@param contents string ---@param flags string function M.write_file(path, contents, flags) - fs.async.write_file( - path, - table.concat({ - "-- THIS FILE IS GENERATED. DO NOT EDIT MANUALLY.", - "-- stylua: ignore start", - contents, - }, "\n"), - flags - ) + local header = _.cond { + { _.matches "%.md$", _.always { "<!--- THIS FILE IS GENERATED. DO NOT EDIT MANUALLY. -->" } }, + { + _.matches "%.lua$", + _.always { + "-- THIS FILE IS GENERATED. DO NOT EDIT MANUALLY.", + "-- stylua: ignore start", + }, + }, + { _.T, _.always { "// THIS FILE IS GENERATED. DO NOT EDIT MANUALLY." } }, + }(path) + fs.async.write_file(path, _.join("\n", _.concat(header, { contents })), flags) +end + +---@param path string +---@return string +function M.rel_path(path) + local script_path = debug.getinfo(2, "S").source:sub(2):match "(.*/)" + return Path.concat { script_path, path } end return M |
