Aleksei-bird 7c9c708c92 Первый фикс
Пачки некоторых позиций увеличены
2024-03-01 20:54:33 +03:00

138 lines
4.1 KiB
Lua

--- Mod migration and version comparison functions.
--- ```lua
--- local flib_migration = require("__flib__/migration")
--- ```
--- @class flib_migration
local flib_migration = {}
local string = string
local table = table
local version_pattern = "%d+"
local version_format = "%02d"
--- Normalize version strings for easy comparison.
---
--- ### Examples
---
--- ```lua
--- migration.format_version("1.10.1234", "%04d")
--- migration.format_version("3", "%02d")
--- ```
--- @param version string
--- @param format string? default: `%02d`
--- @return string?
function flib_migration.format_version(version, format)
if version then
format = format or version_format
local tbl = {}
for v in string.gmatch(version, version_pattern) do
tbl[#tbl + 1] = string.format(format, v)
end
if next(tbl) then
return table.concat(tbl, ".")
end
end
return nil
end
--- Check if current_version is newer than old_version.
--- @param old_version string
--- @param current_version string
--- @param format string? default: `%02d`
--- @return boolean?
function flib_migration.is_newer_version(old_version, current_version, format)
local v1 = flib_migration.format_version(old_version, format)
local v2 = flib_migration.format_version(current_version, format)
if v1 and v2 then
if v2 > v1 then
return true
end
return false
end
return nil
end
--- Run migrations against the given version.
--- @param old_version string
--- @param migrations MigrationsTable
--- @param format? string default: `%02d`
--- @param ... any All additional arguments will be passed to each function within `migrations`.
function flib_migration.run(old_version, migrations, format, ...)
local migrate = false
for version, func in pairs(migrations) do
if migrate or flib_migration.is_newer_version(old_version, version, format) then
migrate = true
func(...)
end
end
end
--- Determine if migrations need to be run for this mod, then run them if needed.
---
--- ### Examples
---
--- ```lua
--- script.on_configuration_changed(function(e)
--- if migration.on_config_changed(e, migrations) then
--- -- Run generic (non-init) migrations
--- rebuild_prototype_data()
--- end
--- end
--- ```
--- @param e ConfigurationChangedData
--- @param migrations? MigrationsTable
--- @param mod_name? string The mod to check against. Defaults to the current mod.
--- @param ... any All additional arguments will be passed to each function within `migrations`.
--- @return boolean run_generic_micrations
function flib_migration.on_config_changed(e, migrations, mod_name, ...)
local changes = e.mod_changes[mod_name or script.mod_name]
local old_version = changes and changes.old_version
if old_version or not changes then
if migrations then
flib_migration.run(old_version, migrations, nil, ...)
end
return true
end
return false
end
--- Handle on_configuration_changed with the given generic and version-specific migrations. Will override any existing
--- on_configuration_changed event handler. Both arguments are optional.
--- @param version_migrations MigrationsTable?
--- @param generic_handler fun(e: ConfigurationChangedData)?
function flib_migration.handle_on_configuration_changed(version_migrations, generic_handler)
script.on_configuration_changed(function(e)
if flib_migration.on_config_changed(e, version_migrations) and generic_handler then
generic_handler(e)
end
end)
end
return flib_migration
--- Migration code to run for specific mod version. A given function will run if the previous mod version is less
--- than the given version.
---
--- # Example
---
--- ```lua
--- {
--- ["1.0.1"] = function()
--- global.foo = nil
--- for _, player_table in pairs(global.players) do
--- player_table.bar = "Lorem ipsum"
--- end
--- end,
--- ["1.0.7"] = function()
--- global.bar = {}
--- end
--- ["1.1.0"] = function(arg)
--- global.foo = arg
--- end
--- }
--- ```
---
--- If the mod is upgraded from 1.0.4 to 1.1.0, then the migrations for 1.0.7 and 1.1.0 will be run.
--- @alias MigrationsTable table<string, fun(...: any)>