Merge pull request #980 from jgmdev/PR/plugins-load-priority

plugins: add load priority support with '--priority:###' closes #978
This commit is contained in:
Jefferson González 2022-05-31 11:18:37 -04:00 committed by GitHub
commit c62cf5ce8c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 75 additions and 27 deletions

View File

@ -859,7 +859,7 @@ function core.restart()
end end
local function check_plugin_version(filename) local function get_plugin_details(filename)
local info = system.get_file_info(filename) local info = system.get_file_info(filename)
if info ~= nil and info.type == "dir" then if info ~= nil and info.type == "dir" then
filename = filename .. "/init.lua" filename = filename .. "/init.lua"
@ -868,12 +868,13 @@ local function check_plugin_version(filename)
if not info or not filename:match("%.lua$") then return false end if not info or not filename:match("%.lua$") then return false end
local f = io.open(filename, "r") local f = io.open(filename, "r")
if not f then return false end if not f then return false end
local priority = false
local version_match = false local version_match = false
for line in f:lines() do for line in f:lines() do
if not version_match then
local mod_version = line:match('%-%-.*%f[%a]mod%-version%s*:%s*(%d+)') local mod_version = line:match('%-%-.*%f[%a]mod%-version%s*:%s*(%d+)')
if mod_version then if mod_version then
version_match = (mod_version == MOD_VERSION) version_match = (mod_version == MOD_VERSION)
break
end end
-- The following pattern is used for backward compatibility only -- The following pattern is used for backward compatibility only
-- Future versions will look only at the mod-version tag. -- Future versions will look only at the mod-version tag.
@ -881,11 +882,21 @@ local function check_plugin_version(filename)
if version then if version then
-- we consider the version tag 2.0 equivalent to mod-version:2 -- we consider the version tag 2.0 equivalent to mod-version:2
version_match = (version == '2.0' and MOD_VERSION == "2") version_match = (version == '2.0' and MOD_VERSION == "2")
end
end
if not priority then
priority = line:match('%-%-.*%f[%a]priority%s*:%s*(%d+)')
if priority then priority = tonumber(priority) end
end
if version_match then
break break
end end
end end
f:close() f:close()
return true, version_match return true, {
version_match = version_match,
priority = priority or 100
}
end end
@ -899,33 +910,70 @@ function core.load_plugins()
for _, root_dir in ipairs {DATADIR, USERDIR} do for _, root_dir in ipairs {DATADIR, USERDIR} do
local plugin_dir = root_dir .. "/plugins" local plugin_dir = root_dir .. "/plugins"
for _, filename in ipairs(system.list_dir(plugin_dir) or {}) do for _, filename in ipairs(system.list_dir(plugin_dir) or {}) do
if not files[filename] then table.insert(ordered, filename) end if not files[filename] then
files[filename] = plugin_dir -- user plugins will always replace system plugins table.insert(
ordered, {file = filename}
)
end
-- user plugins will always replace system plugins
files[filename] = plugin_dir
end end
end end
table.sort(ordered)
for _, plugin in ipairs(ordered) do
local dir = files[plugin.file]
local name = plugin.file:match("(.-)%.lua$") or plugin.file
local is_lua_file, details = get_plugin_details(dir .. '/' .. plugin.file)
plugin.valid = is_lua_file
plugin.name = name
plugin.dir = dir
plugin.priority = details and details.priority or 100
plugin.version_match = details and details.version_match or false
end
-- sort by priority or name for plugins that have same priority
table.sort(ordered, function(a, b)
if a.priority ~= b.priority then
return a.priority < b.priority
end
return a.name < b.name
end)
local load_start = system.get_time() local load_start = system.get_time()
for _, filename in ipairs(ordered) do for _, plugin in ipairs(ordered) do
local plugin_dir, basename = files[filename], filename:match("(.-)%.lua$") or filename if plugin.valid then
local is_lua_file, version_match = check_plugin_version(plugin_dir .. '/' .. filename) if not config.skip_plugins_version and not plugin.version_match then
if is_lua_file then core.log_quiet(
if not config.skip_plugins_version and not version_match then "Version mismatch for plugin %q from %s",
core.log_quiet("Version mismatch for plugin %q from %s", basename, plugin_dir) plugin.name,
local list = refused_list[plugin_dir:find(USERDIR, 1, true) == 1 and 'userdir' or 'datadir'].plugins plugin.dir
table.insert(list, filename) )
elseif config.plugins[basename] ~= false then local rlist = plugin.dir:find(USERDIR, 1, true) == 1
and 'userdir' or 'datadir'
local list = refused_list[rlist].plugins
table.insert(list, plugin.file)
elseif config.plugins[plugin.name] ~= false then
local start = system.get_time() local start = system.get_time()
local ok = core.try(require, "plugins." .. basename) local ok = core.try(require, "plugins." .. plugin.name)
if ok then core.log_quiet("Loaded plugin %q from %s in %.1fms", basename, plugin_dir, (system.get_time() - start)*1000) end if ok then
core.log_quiet(
"Loaded plugin %q from %s in %.1fms",
plugin.name,
plugin.dir,
(system.get_time() - start) * 1000
)
end
if not ok then if not ok then
no_errors = false no_errors = false
end end
end end
end end
end end
core.log_quiet("Loaded all plugins in %.1fms", (system.get_time() - load_start)*1000) core.log_quiet(
"Loaded all plugins in %.1fms",
(system.get_time() - load_start) * 1000
)
return no_errors, refused_list return no_errors, refused_list
end end