Make mod-version follow semver (#1036)

* Make mod-version follow semver
  Now plugins can optionally specify the minor and patch version they 
support.
  If no minor or patch version is specified, it's considered 0.
  Plugins are only loaded if they have the same major version and a 
  smaller or equal minor+patch version.
* Add modversion to logging and plugin mismatch nagview

---------

Co-authored-by: Jefferson González <jgmdev@gmail.com>
This commit is contained in:
Guldoman 2023-02-02 01:28:21 +01:00 committed by George Sokianos
parent ab3d6004a1
commit 57cd4e2949
2 changed files with 46 additions and 11 deletions

View File

@ -673,6 +673,9 @@ end
function core.init() function core.init()
core.log_items = {}
core.log_quiet("Lite XL version %s - mod-version %s", VERSION, MOD_VERSION_STRING)
command = require "core.command" command = require "core.command"
keymap = require "core.keymap" keymap = require "core.keymap"
dirwatch = require "core.dirwatch" dirwatch = require "core.dirwatch"
@ -726,7 +729,6 @@ function core.init()
core.frame_start = 0 core.frame_start = 0
core.clip_rect_stack = {{ 0,0,0,0 }} core.clip_rect_stack = {{ 0,0,0,0 }}
core.log_items = {}
core.docs = {} core.docs = {}
core.cursor_clipboard = {} core.cursor_clipboard = {}
core.cursor_clipboard_whole_line = {} core.cursor_clipboard_whole_line = {}
@ -824,15 +826,19 @@ function core.init()
local msg = {} local msg = {}
for _, entry in pairs(plugins_refuse_list) do for _, entry in pairs(plugins_refuse_list) do
if #entry.plugins > 0 then if #entry.plugins > 0 then
msg[#msg + 1] = string.format("Plugins from directory \"%s\":\n%s", common.home_encode(entry.dir), table.concat(entry.plugins, "\n")) local msg_list = {}
for _, p in pairs(entry.plugins) do
table.insert(msg_list, string.format("%s[%s]", p.file, p.version_string))
end
msg[#msg + 1] = string.format("Plugins from directory \"%s\":\n%s", common.home_encode(entry.dir), table.concat(msg_list, "\n"))
end end
end end
core.nag_view:show( core.nag_view:show(
"Refused Plugins", "Refused Plugins",
string.format( string.format(
"Some plugins are not loaded due to version mismatch.\n\n%s.\n\n" .. "Some plugins are not loaded due to version mismatch. Expected version %s.\n\n%s.\n\n" ..
"Please download a recent version from https://github.com/lite-xl/lite-xl-plugins.", "Please download a recent version from https://github.com/lite-xl/lite-xl-plugins.",
table.concat(msg, ".\n\n")), MOD_VERSION_STRING, table.concat(msg, ".\n\n")),
opt, function(item) opt, function(item)
if item.text == "Exit" then os.exit(1) end if item.text == "Exit" then os.exit(1) end
end) end)
@ -921,6 +927,8 @@ function core.restart()
end end
local mod_version_regex =
regex.compile([[--.*mod-version:(\d+)(?:\.(\d+))?(?:\.(\d+))?(?:$|\s)]])
local function get_plugin_details(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
@ -932,17 +940,32 @@ local function get_plugin_details(filename)
if not f then return false end if not f then return false end
local priority = false local priority = false
local version_match = false local version_match = false
local major, minor, patch
for line in f:lines() do for line in f:lines() do
if not version_match then if not version_match then
local mod_version = line:match('%-%-.*%f[%a]mod%-version%s*:%s*(%d+)') local _major, _minor, _patch = mod_version_regex:match(line)
if mod_version then if _major then
version_match = (mod_version == MOD_VERSION) _major = tonumber(_major) or 0
_minor = tonumber(_minor) or 0
_patch = tonumber(_patch) or 0
major, minor, patch = _major, _minor, _patch
version_match = major == MOD_VERSION_MAJOR
if version_match then
version_match = minor <= MOD_VERSION_MINOR
end
if version_match then
version_match = patch <= MOD_VERSION_PATCH
end
end end
end end
if not priority then if not priority then
priority = line:match('%-%-.*%f[%a]priority%s*:%s*(%d+)') priority = line:match('%-%-.*%f[%a]priority%s*:%s*(%d+)')
if priority then priority = tonumber(priority) end if priority then priority = tonumber(priority) end
end end
if version_match then if version_match then
break break
end end
@ -950,6 +973,7 @@ local function get_plugin_details(filename)
f:close() f:close()
return true, { return true, {
version_match = version_match, version_match = version_match,
version = major and {major, minor, patch} or {},
priority = priority or 100 priority = priority or 100
} }
end end
@ -985,6 +1009,8 @@ function core.load_plugins()
plugin.dir = dir plugin.dir = dir
plugin.priority = details and details.priority or 100 plugin.priority = details and details.priority or 100
plugin.version_match = details and details.version_match or false plugin.version_match = details and details.version_match or false
plugin.version = details and details.version or {}
plugin.version_string = #plugin.version > 0 and table.concat(plugin.version, ".") or "unknown"
end end
-- sort by priority or name for plugins that have same priority -- sort by priority or name for plugins that have same priority
@ -1000,21 +1026,27 @@ function core.load_plugins()
if plugin.valid then if plugin.valid then
if not config.skip_plugins_version and not plugin.version_match then if not config.skip_plugins_version and not plugin.version_match then
core.log_quiet( core.log_quiet(
"Version mismatch for plugin %q from %s", "Version mismatch for plugin %q[%s] from %s",
plugin.name, plugin.name,
plugin.version_string,
plugin.dir plugin.dir
) )
local rlist = plugin.dir:find(USERDIR, 1, true) == 1 local rlist = plugin.dir:find(USERDIR, 1, true) == 1
and 'userdir' or 'datadir' and 'userdir' or 'datadir'
local list = refused_list[rlist].plugins local list = refused_list[rlist].plugins
table.insert(list, plugin.file) table.insert(list, plugin)
elseif config.plugins[plugin.name] ~= false then elseif config.plugins[plugin.name] ~= false then
local start = system.get_time() local start = system.get_time()
local ok, loaded_plugin = core.try(require, "plugins." .. plugin.name) local ok, loaded_plugin = core.try(require, "plugins." .. plugin.name)
if ok then if ok then
local plugin_version = ""
if plugin.version_string ~= MOD_VERSION_STRING then
plugin_version = "["..plugin.version_string.."]"
end
core.log_quiet( core.log_quiet(
"Loaded plugin %q from %s in %.1fms", "Loaded plugin %q%s from %s in %.1fms",
plugin.name, plugin.name,
plugin_version,
plugin.dir, plugin.dir,
(system.get_time() - start) * 1000 (system.get_time() - start) * 1000
) )

View File

@ -1,6 +1,9 @@
-- this file is used by lite-xl to setup the Lua environment when starting -- this file is used by lite-xl to setup the Lua environment when starting
VERSION = "@PROJECT_VERSION@" VERSION = "@PROJECT_VERSION@"
MOD_VERSION = "3" MOD_VERSION_MAJOR = 3
MOD_VERSION_MINOR = 0
MOD_VERSION_PATCH = 0
MOD_VERSION_STRING = string.format("%d.%d.%d", MOD_VERSION_MAJOR, MOD_VERSION_MINOR, MOD_VERSION_PATCH)
SCALE = tonumber(os.getenv("LITE_SCALE") or os.getenv("GDK_SCALE") or os.getenv("QT_SCALE_FACTOR")) or SCALE SCALE = tonumber(os.getenv("LITE_SCALE") or os.getenv("GDK_SCALE") or os.getenv("QT_SCALE_FACTOR")) or SCALE
PATHSEP = package.config:sub(1, 1) PATHSEP = package.config:sub(1, 1)