aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/lua
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/lua')
-rw-r--r--scripts/lua/mason-scripts/markdown.lua93
-rw-r--r--scripts/lua/mason-scripts/mason/generate.lua2
-rw-r--r--scripts/lua/mason-scripts/mason/generate_package_index.lua44
-rw-r--r--scripts/lua/mason-scripts/templates/PACKAGES.template.md11
-rw-r--r--scripts/lua/mason-scripts/templates/package-section.template.md19
-rw-r--r--scripts/lua/mason-scripts/templates/parse_commit.lua16
-rw-r--r--scripts/lua/mason-scripts/utils.lua30
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