Skip to content

Commit

Permalink
Feature: allow run key to be a table of mixed types of hook (#364)
Browse files Browse the repository at this point in the history
* Feature: allow run key to be a table of mixed types of hook

* Update docs
  • Loading branch information
wbthomason authored Jun 13, 2021
1 parent 8703b28 commit df0f740
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 44 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ use {
tag = string, -- Specifies a git tag to use
commit = string, -- Specifies a git commit to use
lock = boolean, -- Skip this plugin in updates/syncs
run = string or function, -- Post-update/install hook. See "update/install hooks".
run = string, function, or table, -- Post-update/install hook. See "update/install hooks".
requires = string or list, -- Specifies plugin dependencies. See "dependencies".
rocks = string or list, -- Specifies Luarocks dependencies for the plugin
config = string or function, -- Specifies code to run after this plugin is loaded.
Expand Down Expand Up @@ -411,13 +411,13 @@ provide a location string for the name of the plugin.
You may specify operations to be run after successful installs/updates of a plugin with the `run`
key. This key may either be a Lua function, which will be called with the `plugin` table for this
plugin (containing the information passed to `use` as well as output from the installation/update
commands, the installation path of the plugin, etc.), or a string.
commands, the installation path of the plugin, etc.), a string, or a table of functions and strings.

If `run` is a string, then either:
If an element of `run` is a string, then either:

1. If the first character of `run` is ":", it is treated as a Neovim command and executed.
2. Otherwise, `run` is treated as a shell command and run in the installation directory of the
plugin via `$SHELL -c 'cd <plugin dir> && <run>'`.
plugin via `$SHELL -c '<run>'`.

#### Dependencies

Expand Down
19 changes: 13 additions & 6 deletions doc/packer.txt
Original file line number Diff line number Diff line change
Expand Up @@ -282,11 +282,18 @@ you still need to provide a location string for the name of the plugin.

POST-UPDATE HOOKS *packer-plugin-hooks*
You may specify operations to be run after successful installs/updates of a
plugin with the `run` key in a plugin specification. This key may either be a
Lua function, which will be called with the `plugin` table for this plugin
(containing the information passed to |packer.use()| as well as output from
the installation/update commands, the installation path of the plugin, etc.),
or a string.
plugin with the `run` key. This key may either be a Lua function, which will be
called with the `plugin` table for this plugin (containing the information
passed to `use` as well as output from the installation/update commands, the
installation path of the plugin, etc.), a string, or a table of functions and
strings.

If an element of `run` is a string, then either:

1. If the first character of `run` is ":", it is treated as a Neovim command and
executed.
2. Otherwise, `run` is treated as a shell command and run in the installation
directory of the plugin via `$SHELL -c '<run>'`.

DEPENDENCIES *packer-plugin-dependencies*
Plugins may specify dependencies via the `requires` key in their specification
Expand Down Expand Up @@ -538,7 +545,7 @@ invoked as follows:
tag = string, -- Specifies a git tag to use
commit = string, -- Specifies a git commit to use
lock = boolean, -- Skip this plugin in updates/syncs
run = string or function, -- Post-update/install hook. See |packer-plugin-hooks|
run = string, function, or table -- Post-update/install hook. See |packer-plugin-hooks|
requires = string or list -- Specifies plugin dependencies. See |packer-plugin-dependencies|
config = string or function, -- Specifies code to run after this plugin is loaded.
rocks = string or list, -- Specifies Luarocks dependencies for the plugin
Expand Down
79 changes: 45 additions & 34 deletions lua/packer/plugin_utils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -173,45 +173,56 @@ plugin_utils.post_update_hook = function(plugin, disp)
local plugin_name = util.get_plugin_full_name(plugin)
return a.sync(function()
if plugin.run or not plugin.opt then
await(vim.schedule)
await(a.main)
plugin_utils.load_plugin(plugin)
end

if plugin.run then
disp:task_update(plugin_name, 'running post update hook...')
if type(plugin.run) == 'function' then
if pcall(plugin.run, plugin) then
return result.ok()
else
return result.err({msg = 'Error running post update hook'})
end
elseif type(plugin.run) == 'string' then
if string.sub(plugin.run, 1, 1) == ':' then
await(a.main)
vim.cmd(string.sub(plugin.run, 2))
return result.ok()
if type(plugin.run) ~= 'table' then plugin.run = {plugin.run} end
disp:task_update(plugin_name, 'running post update hooks...')
for _, task in ipairs(plugin.run) do
if type(task) == 'function' then
local success, err = pcall(task, plugin)
if success then
return result.ok()
else
return result.err({msg = 'Error running post update hook: ' .. vim.inspect(err)})
end
elseif type(task) == 'string' then
if string.sub(task, 1, 1) == ':' then
await(a.main)
vim.cmd(string.sub(task, 2))
return result.ok()
else
local hook_output = {err = {}, output = {}}
local hook_callbacks = {
stderr = jobs.logging_callback(hook_output.err, hook_output.output, nil, disp,
plugin_name),
stdout = jobs.logging_callback(hook_output.err, hook_output.output, nil, disp,
plugin_name)
}
local cmd = {os.getenv('SHELL') or vim.o.shell, '-c', task}
return
await(jobs.run(cmd, {capture_output = hook_callbacks, cwd = plugin.install_path})):map_err(
function(err)
return {
msg = string.format('Error running post update hook: %s',
table.concat(hook_output.output, '\n')),
data = err
}
end)
end
else
local hook_output = {err = {}, output = {}}
local hook_callbacks = {
stderr = jobs.logging_callback(hook_output.err, hook_output.output, nil, disp,
plugin_name),
stdout = jobs.logging_callback(hook_output.err, hook_output.output, nil, disp,
plugin_name)
}
local cmd = {os.getenv('SHELL') or vim.o.shell, '-c', plugin.run}
return
await(jobs.run(cmd, {capture_output = hook_callbacks, cwd = plugin.install_path})):map_err(
function(err)
return {
msg = string.format('Error running post update hook: %s',
table.concat(hook_output.output, '\n')),
data = err
}
end)
-- TODO/NOTE: This case should also capture output in case of error. The minor difficulty is
-- what to do if the plugin's run table (i.e. this case) already specifies output handling.

return await(jobs.run(task)):map_err(function(err)
return {
msg = string.format('Error running post update hook: %s', vim.inspect(err)),
data = err
}
end)
end
else
-- TODO/NOTE: This case should also capture output in case of error. The minor difficulty is
-- what to do if the plugin's run table (i.e. this case) already specifies output handling.
return await(jobs.run(plugin.run))
end
else
return result.ok()
Expand Down

0 comments on commit df0f740

Please sign in to comment.