summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2026-08-14 23:42:13 +0800
committerruki <[email protected]>2026-08-14 23:42:13 +0800
commit46141dbac176444bd1ed114ea419d4bb8e6d2e13 (patch)
tree5bb62ecf325bd4d42bcedd2440a35dddada97c57
parenta79cf74f920c088528d66a67a59b3d8eaa1d4f7a (diff)
update lock and version
-rw-r--r--xmake/actions/addon/main.lua50
-rw-r--r--xmake/actions/addon/xmake.lua5
-rw-r--r--xmake/core/package/addon.lua178
-rw-r--r--xmake/core/project/addons.lua36
-rw-r--r--xmake/core/project/project.lua24
-rw-r--r--xmake/core/sandbox/modules/import/core/package/addon.lua5
-rw-r--r--xmake/core/sandbox/modules/import/core/project/addons.lua11
-rw-r--r--xmake/modules/private/action/require/impl/actions/install.lua4
-rw-r--r--xmake/modules/private/addons/main.lua56
9 files changed, 293 insertions, 76 deletions
diff --git a/xmake/actions/addon/main.lua b/xmake/actions/addon/main.lua
index 7af106c05..6a4bd06ca 100644
--- a/xmake/actions/addon/main.lua
+++ b/xmake/actions/addon/main.lua
@@ -226,10 +226,36 @@ end
-- remove the given installed addons
function _remove()
- local names = assert(option.get("addons"), "please specify the addon name to be removed!")
+ local names = option.get("addons")
+
+ -- remove all the installed addons? e.g. xmake addon --remove --all
+ --
+ -- @note we remove them one by one, so we can also remove the symlinks safely,
+ -- and the dependencies between them do not matter, they are all removed
+ --
+ if option.get("all") then
+ names = table.keys(addon.addons())
+ if #names == 0 then
+ cprint("${color.warning}no installed addons!")
+ return
+ end
+ for _, name in ipairs(names) do
+ addon.remove(name, {force = true})
+ cprint("${color.success}remove ${bright}%s${clear} ok!", name)
+ end
+ return
+ end
+
+ assert(names, "please specify the addon name to be removed!")
_xrepo("remove", names)
end
+-- upgrade the addons which the current project declares in its `xmake-addons.lua`
+function _upgrade()
+ import("private.addons", {alias = "install_addons"})
+ install_addons(os.projectdir(), {upgrade = true})
+end
+
-- search the addons from the repositories
function _search()
local patterns = assert(option.get("addons"), "please specify the addon name pattern to be searched!")
@@ -243,8 +269,12 @@ end
--
function _collect_installed_addons()
local entries = {}
- for name, addoninfo in pairs(addon.rescan()) do
+ for name, addoninfo in pairs(addon.addons()) do
+ -- an addon can be installed with several versions, we show the active one,
+ -- the projects can lock the other ones, @see core/project/addons.lua
+ local versions = addon.versions(name)
table.insert(entries, {name = name, version = addoninfo.version,
+ versions = #versions > 1 and versions or nil,
description = addoninfo.description, payloads = addoninfo.payloads})
end
table.sort(entries, function (a, b) return a.name < b.name end)
@@ -285,7 +315,11 @@ function _list()
if #installed > 0 then
for _, entry in ipairs(installed) do
exclude[entry.name] = true
- _print_addon(entry, string.format(" ${dim}(%s)${clear}", table.concat(entry.payloads, ", ")))
+ local suffix = string.format(" ${dim}(%s)${clear}", table.concat(entry.payloads, ", "))
+ if entry.versions then
+ suffix = suffix .. string.format(" ${dim}[installed: %s]${clear}", table.concat(entry.versions, ", "))
+ end
+ _print_addon(entry, suffix)
end
else
print(" (none)")
@@ -308,22 +342,16 @@ function _list()
end
end
--- clear all installed addons
-function _clear()
- addon.clear()
- cprint("${color.success}clear all installed addons ok!")
-end
-
function main()
if option.get("install") then
_install()
elseif option.get("remove") then
_remove()
+ elseif option.get("upgrade") then
+ _upgrade()
elseif option.get("list") then
_list()
elseif option.get("search") then
_search()
- elseif option.get("clear") then
- _clear()
end
end
diff --git a/xmake/actions/addon/xmake.lua b/xmake/actions/addon/xmake.lua
index 3c814cc6d..a0266aa4f 100644
--- a/xmake/actions/addon/xmake.lua
+++ b/xmake/actions/addon/xmake.lua
@@ -29,7 +29,8 @@ task("addon")
{'r', "remove", "k", nil, "Remove the given installed addons."},
{'s', "search", "k", nil, "Search the addons from the repositories."},
{'l', "list", "k", nil, "List all installed addons."},
- {'c', "clear", "k", nil, "Clear all installed addons."},
+ {'u', "upgrade", "k", nil, "Upgrade the addons which the current project declares."},
+ {nil, "all", "k", nil, "Remove all installed addons, e.g. xmake addon --remove --all"},
{'f', "force", "k", nil, "Force to remove the addons, even if they are depended on by the others."},
{nil, "addons", "vs", nil, "The addon paths, urls or names.",
"e.g.",
@@ -40,6 +41,8 @@ task("addon")
" $ xmake addon --install xmake-repo@serial-monitor",
" $ xmake addon --install serial-monitor",
" $ xmake addon --remove serial-monitor",
+ " $ xmake addon --remove --all",
+ " $ xmake addon --upgrade",
" $ xmake addon --search serial",
" $ xmake addon --list"}
}
diff --git a/xmake/core/package/addon.lua b/xmake/core/package/addon.lua
index 6d56205fd..33eb22e03 100644
--- a/xmake/core/package/addon.lua
+++ b/xmake/core/package/addon.lua
@@ -70,15 +70,16 @@ function addon._registryfile()
return path.join(addon.installdir(), "addons.conf")
end
--- save the given addons to the registry file
-function addon._save(addons)
- addon._ADDONS = addons
+-- save the given registry to the registry file
+function addon._save(registry)
+ addon._REGISTRY = registry
+ addon._ADDONS = nil
local registryfile = addon._registryfile()
-- we need not create an empty registry file if no addons are installed
- if next(addons) == nil and not os.isfile(registryfile) then
+ if next(registry) == nil and not os.isfile(registryfile) then
return
end
- local ok, errors = io.save(registryfile, addons)
+ local ok, errors = io.save(registryfile, registry)
if not ok then
utils.warning(errors)
end
@@ -182,10 +183,15 @@ end
function addon._parents(name)
local dirname = addon.dirname(name)
local parents
- for otherdirname, addoninfo in pairs(addon.addons()) do
- if otherdirname ~= dirname and table.contains(addoninfo.deps or {}, dirname) then
- parents = parents or {}
- table.insert(parents, otherdirname)
+ for otherdirname, entry in pairs(addon._registry()) do
+ if otherdirname ~= dirname then
+ for _, addoninfo in pairs(entry.versions or {}) do
+ if table.contains(addoninfo.deps or {}, dirname) then
+ parents = parents or {}
+ table.insert(parents, otherdirname)
+ break
+ end
+ end
end
end
if parents then
@@ -194,14 +200,26 @@ function addon._parents(name)
return parents
end
--- unregister the given addon
-function addon._unregister(name)
+-- unregister the given addon or only one of its versions
+function addon._unregister(name, version)
local dirname = addon.dirname(name)
- local addons = addon.addons()
- if addons[dirname] then
- addons[dirname] = nil
- addon._save(addons)
+ local registry = addon._registry()
+ local entry = registry[dirname]
+ if entry == nil then
+ return
end
+ if version then
+ entry.versions[version] = nil
+ if entry.active == version then
+ entry.active = next(entry.versions)
+ end
+ if next(entry.versions) == nil then
+ registry[dirname] = nil
+ end
+ else
+ registry[dirname] = nil
+ end
+ addon._save(registry)
end
-- get the apis of the addon manifest
@@ -400,7 +418,64 @@ function addon.resolve_reference(reference, sep, kind, opt)
return {dir = payloaddir, name = name, addon = addonname}
end
--- get all installed addons
+-- get the registry of the installed addons
+--
+-- an addon can be installed with several versions at the same time, e.g. the projects
+-- may lock the different versions of it, so we save all of them
+--
+-- @return the registry, e.g. {["esp32"] = {active = "1.0.3", versions = {["1.0.3"] = {...}}}}
+--
+function addon._registry(opt)
+ local registry = addon._REGISTRY
+ if opt and opt.force then
+ registry = nil
+ end
+ if registry == nil then
+ registry = {}
+ local registryfile = addon._registryfile()
+ if os.isfile(registryfile) then
+ registry = io.load(registryfile) or {}
+ end
+ -- migrate the old registry, it only saved one version for each addon
+ for dirname, addoninfo in pairs(registry) do
+ if addoninfo.versions == nil then
+ registry[dirname] = {active = addoninfo.version,
+ versions = {[addoninfo.version] = addoninfo}}
+ end
+ end
+ addon._REGISTRY = registry
+ addon._ADDONS = nil
+ end
+ return registry
+end
+
+-- pin the active version of the given addon for this process
+--
+-- @note a project locks the versions of its addons, so we need to activate them
+-- when we load it, @see core/project/addons.lua
+--
+function addon.pin(name, version)
+ local pinned = addon._PINNED
+ if pinned == nil then
+ pinned = {}
+ addon._PINNED = pinned
+ end
+ pinned[addon.dirname(name)] = version
+ addon._ADDONS = nil
+end
+
+-- get all the installed versions of the given addon, e.g. {"1.0.2", "1.0.3"}
+function addon.versions(name)
+ local versions = {}
+ local addoninfo = addon._registry()[addon.dirname(name)]
+ for version, _ in pairs(addoninfo and addoninfo.versions or {}) do
+ table.insert(versions, version)
+ end
+ table.sort(versions)
+ return versions
+end
+
+-- get all installed addons, only the active version of each addon
--
-- @param opt the options, e.g. {force = true}, we need it to reload the registry
-- if the addons have been installed by another process
@@ -408,15 +483,20 @@ end
-- @return the addons table, e.g. {["hello-world"] = {version = "latest", payloads = {"plugins"}}}
--
function addon.addons(opt)
- local addons = addon._ADDONS
if opt and opt.force then
- addons = nil
+ addon._registry({force = true})
end
+ local addons = addon._ADDONS
if addons == nil then
addons = {}
- local registryfile = addon._registryfile()
- if os.isfile(registryfile) then
- addons = io.load(registryfile) or {}
+ local pinned = addon._PINNED or {}
+ for dirname, addoninfo in pairs(addon._registry()) do
+ -- the project may lock another version of it, @see addon.pin
+ local version = pinned[dirname] or addoninfo.active
+ local versioninfo = addoninfo.versions and addoninfo.versions[version]
+ if versioninfo then
+ addons[dirname] = versioninfo
+ end
end
addon._ADDONS = addons
end
@@ -592,6 +672,8 @@ function addon.register(name, version, opt)
name = name ~= dirname and name or nil,
description = opt.description,
deps = opt.deps,
+ -- where it comes from, e.g. {url = ..., commit = ..., branch = ...}
+ repo = opt.repo,
-- the deps which the addon itself declares in its manifest, they are
-- recorded whenever this addon has one, so that the repositories can
-- check that the manifest and the package recipe are kept in sync
@@ -608,9 +690,17 @@ function addon.register(name, version, opt)
return false, errors
end
- local addons = addon.addons()
- addons[dirname] = addoninfo
- addon._save(addons)
+ -- we can install several versions of an addon at the same time,
+ -- and the version which we install now is always the active one
+ local registry = addon._registry()
+ local entry = registry[dirname]
+ if entry == nil or entry.versions == nil then
+ entry = {versions = {}}
+ registry[dirname] = entry
+ end
+ entry.versions[version] = addoninfo
+ entry.active = version
+ addon._save(registry)
return true
end
@@ -662,6 +752,7 @@ end
-- e.g. the addons which a project declares, @see core/project/project.lua
--
function addon.reload()
+ addon._REGISTRY = nil
addon._ADDONS = nil
addon._MANIFESTS = nil
addon._GLOBALMODULES = nil
@@ -672,16 +763,17 @@ end
-- it's only used to repair the registry file, e.g. the user removed some addon directories manually
--
function addon.rescan()
- local oldaddons = addon.addons()
- local addons = {}
+ local oldregistry = addon._registry()
+ local registry = {}
for _, versiondir in ipairs(os.dirs(path.join(addon.installdir(), "*", "*"))) do
local payloads = addon.payloads_of(versiondir)
if #payloads > 0 then
local dirname = path.filename(path.directory(versiondir))
local version = path.filename(versiondir)
- local oldaddoninfo = oldaddons[dirname]
+ local oldentry = oldregistry[dirname]
+ local oldaddoninfo = oldentry and oldentry.versions and oldentry.versions[version]
local description, deps
- if oldaddoninfo and oldaddoninfo.version == version then
+ if oldaddoninfo then
-- we need to keep them, we cannot get them from the installed payloads
description = oldaddoninfo.description
deps = oldaddoninfo.deps
@@ -696,24 +788,22 @@ function addon.rescan()
description = manifest.description or description
end
end
- addons[dirname] = {version = version, name = name or (oldaddoninfo and oldaddoninfo.name),
- description = description, deps = deps, payloads = payloads,
- plugins = addon._plugins_of(versiondir), templates = addon._templates_of(versiondir)}
+ local entry = registry[dirname]
+ if entry == nil then
+ entry = {versions = {}}
+ registry[dirname] = entry
+ end
+ entry.versions[version] = {version = version, name = name or (oldaddoninfo and oldaddoninfo.name),
+ description = description, deps = deps, payloads = payloads,
+ plugins = addon._plugins_of(versiondir), templates = addon._templates_of(versiondir)}
+ -- we keep the active version if it's still installed, otherwise we use the last one
+ if entry.active == nil or (oldentry and oldentry.active == version) then
+ entry.active = version
+ end
end
end
- addon._save(addons)
- return addons
-end
-
--- clear all installed addons
-function addon.clear()
- local installdir = addon.installdir()
- if os.isdir(installdir) then
- os.rmdir(installdir)
- end
- addon._ADDONS = {}
- addon._MANIFESTS = nil
- addon._GLOBALMODULES = nil
+ addon._save(registry)
+ return addon.addons()
end
-- return module
diff --git a/xmake/core/project/addons.lua b/xmake/core/project/addons.lua
index 994d52ec0..21fb9fbcf 100644
--- a/xmake/core/project/addons.lua
+++ b/xmake/core/project/addons.lua
@@ -26,7 +26,8 @@ local os = require("base/os")
local io = require("base/io")
local path = require("base/path")
local table = require("base/table")
-local addon = require("package/addon")
+local semver = require("base/semver")
+local addon = require("package/addon")
-- the file which declares the addons of a project, e.g. <projectdir>/xmake-addons.lua
--
@@ -36,6 +37,7 @@ local addon = require("package/addon")
-- e.g.
-- add_addons("esp32-devel 1.0.x")
-- add_addons("serial-tools", {optional = true})
+-- add_repositories("myrepo [email protected]:me/myrepo.git")
--
function addons.filename()
return "xmake-addons.lua"
@@ -63,6 +65,8 @@ function addons.apis()
return {
values = {
"add_addons"
+ -- the repositories which provide them, e.g. add_repositories("myrepo [email protected]:me/myrepo.git")
+ , "add_repositories"
}
}
end
@@ -116,7 +120,8 @@ function addons.load(projectdir)
end
local addonsinfo = {addons = table.wrap(rootinfo:get("addons")),
- addons_extra = rootinfo:extraconf("addons")}
+ addons_extra = rootinfo:extraconf("addons"),
+ repositories = table.wrap(rootinfo:get("repositories"))}
-- check the declared addons
local declared = {}
@@ -147,6 +152,29 @@ function addons.load(projectdir)
return addonsinfo
end
+-- split the given declaration, e.g. "esp32-devel 1.0.x" -> "esp32-devel", "1.0.x"
+function addons.requirename(requirestr)
+ local splitinfo = requirestr:split("%s")
+ return splitinfo[1], splitinfo[2]
+end
+
+-- is the locked version still valid for the given declaration?
+--
+-- @note the declaration is authoritative, the lock only pins a version inside it,
+-- so we need to resolve it again if the user has changed the declared version
+--
+function addons.locked_valid(requirestr, lockinfo)
+ if not lockinfo or not lockinfo.version then
+ return false
+ end
+ local _, version = addons.requirename(requirestr)
+ if version then
+ -- @note we can only compare the semantic versions, e.g. the local addons are always `latest`
+ return semver.parse(lockinfo.version) ~= nil and semver.satisfies(lockinfo.version, version)
+ end
+ return true
+end
+
-- get the locked addons, e.g. {["esp32-devel"] = {version = "1.0.3"}}
function addons.locked(projectdir)
local lockfile = addons.lockfile(projectdir)
@@ -171,9 +199,9 @@ function addons.satisfied(addonsinfo, projectdir)
end
local installed = addon.addons()
for _, requirestr in ipairs(addonsinfo.addons) do
- local name = requirestr:split("%s")[1]
+ local name = addons.requirename(requirestr)
local lockinfo = locked[name]
- if not lockinfo then
+ if not addons.locked_valid(requirestr, lockinfo) then
return false
end
local addoninfo = installed[addon.dirname(name)]
diff --git a/xmake/core/project/project.lua b/xmake/core/project/project.lua
index db269eda9..924ac8f9e 100644
--- a/xmake/core/project/project.lua
+++ b/xmake/core/project/project.lua
@@ -244,18 +244,37 @@ function project._install_addons()
return project._ADDONS_OK, project._ADDONS_ERRORS
end
+-- activate the addon versions which this project locks
+--
+-- @note an addon can be installed with several versions at the same time, the other
+-- projects may lock the other versions of it, @see core/package/addon.lua
+--
+function project._pin_addons()
+ for name, lockinfo in pairs(addons.locked() or {}) do
+ if lockinfo.version then
+ addon.pin(name, lockinfo.version)
+ end
+ end
+end
+
-- do install the addons which this project declares
function project._do_install_addons()
if os.getenv("XMAKE_SKIP_ADDONS") then
return true
end
- -- this project declares nothing? or they have been installed already
+ -- this project declares nothing?
local addonsinfo, errors = addons.load()
if errors then
return false, errors
end
- if not addonsinfo or #addonsinfo.addons == 0 or addons.satisfied(addonsinfo) then
+ if not addonsinfo or #addonsinfo.addons == 0 then
+ return true
+ end
+
+ -- they have been installed already?
+ project._pin_addons()
+ if addons.satisfied(addonsinfo) then
return true
end
@@ -287,6 +306,7 @@ function project._do_install_addons()
-- we have loaded the registry and its caches before installing them, so we need to reload it
addon.reload()
+ project._pin_addons()
rule.clear()
task.clear()
return true
diff --git a/xmake/core/sandbox/modules/import/core/package/addon.lua b/xmake/core/sandbox/modules/import/core/package/addon.lua
index b297347c6..89cd60866 100644
--- a/xmake/core/sandbox/modules/import/core/package/addon.lua
+++ b/xmake/core/sandbox/modules/import/core/package/addon.lua
@@ -35,9 +35,12 @@ sandbox_core_package_addon.payloadinfos = addon.payloadinfos
sandbox_core_package_addon.payloads_of = addon.payloads_of
sandbox_core_package_addon.payloadroot = addon.payloadroot
sandbox_core_package_addon.addons = addon.addons
+sandbox_core_package_addon.versions = addon.versions
+sandbox_core_package_addon._registry = addon._registry
+sandbox_core_package_addon._registryfile = addon._registryfile
+sandbox_core_package_addon.pin = addon.pin
sandbox_core_package_addon.addondir = addon.addondir
sandbox_core_package_addon.rescan = addon.rescan
-sandbox_core_package_addon.clear = addon.clear
-- get the manifest of the given addon directory, e.g. <sourcedir>/addon.lua
--
diff --git a/xmake/core/sandbox/modules/import/core/project/addons.lua b/xmake/core/sandbox/modules/import/core/project/addons.lua
index 9e866bd06..0c3ad438c 100644
--- a/xmake/core/sandbox/modules/import/core/project/addons.lua
+++ b/xmake/core/sandbox/modules/import/core/project/addons.lua
@@ -26,10 +26,13 @@ local addons = require("project/addons")
local raise = require("sandbox/modules/raise")
-- inherit some builtin interfaces
-sandbox_core_project_addons.file = addons.file
-sandbox_core_project_addons.lockfile = addons.lockfile
-sandbox_core_project_addons.locked = addons.locked
-sandbox_core_project_addons.satisfied = addons.satisfied
+sandbox_core_project_addons.file = addons.file
+sandbox_core_project_addons.filename = addons.filename
+sandbox_core_project_addons.lockfile = addons.lockfile
+sandbox_core_project_addons.locked = addons.locked
+sandbox_core_project_addons.locked_valid = addons.locked_valid
+sandbox_core_project_addons.requirename = addons.requirename
+sandbox_core_project_addons.satisfied = addons.satisfied
-- load the declared addons of the given project directory
--
diff --git a/xmake/modules/private/action/require/impl/actions/install.lua b/xmake/modules/private/action/require/impl/actions/install.lua
index 65750c1bc..1a2e389b3 100644
--- a/xmake/modules/private/action/require/impl/actions/install.lua
+++ b/xmake/modules/private/action/require/impl/actions/install.lua
@@ -318,8 +318,12 @@ function _register_addon(package)
end
end
+ -- we also record where it comes from, so that the projects can lock it,
+ -- @see xmake/modules/private/addons/main.lua
+ local repo = package:repo()
addon.register(package:name(), package:version_str() or "latest",
{description = description, deps = deps,
+ repo = repo and {url = repo:url(), commit = repo:commit(), branch = repo:branch()} or nil,
manifest_deps = manifest and manifest.deps or nil,
globalmodules = manifest and #manifest.globalmodules > 0 and manifest.globalmodules or nil})
end
diff --git a/xmake/modules/private/addons/main.lua b/xmake/modules/private/addons/main.lua
index 43a623e20..1cdc2191d 100644
--- a/xmake/modules/private/addons/main.lua
+++ b/xmake/modules/private/addons/main.lua
@@ -28,15 +28,15 @@ local LOCKVERSION = "1.0"
-- get the requires of the declared addons
--
--- @note we always install the locked versions, the declared versions are only used
--- to resolve them when there is no lock yet, @see _lock_addons
+-- @note we install the locked versions, but the declaration is authoritative, so we
+-- resolve them again if the user has changed it or upgrades them
--
function _get_requires(addonsinfo, locked)
local requires = {}
for _, requirestr in ipairs(addonsinfo.addons) do
- local name = requirestr:split("%s")[1]
+ local name = addons.requirename(requirestr)
local lockinfo = locked and locked[name]
- if lockinfo and lockinfo.version then
+ if addons.locked_valid(requirestr, lockinfo) then
requirestr = name .. " " .. lockinfo.version
end
table.insert(requires, requirestr)
@@ -51,13 +51,20 @@ end
--
function _lock_addons(projectdir, addonsinfo)
local lockinfo = {}
+ local locked = addons.locked(projectdir) or {}
-- @note we need to reload the registry, they have been installed by another process
local installed = addon.addons({force = true})
for _, requirestr in ipairs(addonsinfo.addons) do
- local name = requirestr:split("%s")[1]
+ local name = addons.requirename(requirestr)
local addoninfo = installed[addon.dirname(name)]
if addoninfo then
- lockinfo[name] = {version = addoninfo.version}
+ local oldversion = locked[name] and locked[name].version
+ if oldversion and oldversion ~= addoninfo.version then
+ cprint("${color.success}upgrade ${bright}%s${clear}: %s -> %s", name, oldversion, addoninfo.version)
+ end
+ -- we lock the repository too, so that the other users get it from the same source,
+ -- @see xmake/modules/private/action/require/impl/lock_packages.lua
+ lockinfo[name] = {version = addoninfo.version, repo = addoninfo.repo}
end
end
lockinfo.__meta__ = {version = LOCKVERSION}
@@ -69,23 +76,54 @@ end
-- @note we are called from a sub-process, the project cannot be loaded until its
-- addons are installed, @see core/project/project.lua
--
-function main(projectdir)
+function main(projectdir, opt)
+ opt = opt or {}
projectdir = projectdir or os.projectdir()
local addonsinfo = addons.load(projectdir)
if not addonsinfo or #addonsinfo.addons == 0 then
return
end
+ -- upgrade them? we need to resolve the declared versions again
+ local locked = not opt.upgrade and addons.locked(projectdir) or nil
+
-- install them with xrepo, it installs the packages in its own working directory,
-- so we need not a project here
local argv = {"lua", "private.xrepo", "install", "--addon"}
+
+ -- this project declares its own repositories? we pass them to xrepo,
+ -- they are only used by this installation, we do not register them globally
+ local rcfile
+ if #addonsinfo.repositories > 0 then
+ rcfile = os.tmpfile() .. ".lua"
+ local file = io.open(rcfile, "w")
+ for _, repo in ipairs(addonsinfo.repositories) do
+ file:print("add_repositories(%q)", repo)
+ end
+ file:close()
+ table.insert(argv, "--includes=" .. rcfile)
+ end
+
for _, name in ipairs({"yes", "verbose", "diagnosis"}) do
if option.get(name) then
table.insert(argv, "--" .. name)
end
end
- table.join2(argv, _get_requires(addonsinfo, addons.locked(projectdir)))
- os.execv(os.programfile(), argv)
+ table.join2(argv, _get_requires(addonsinfo, locked))
+ try
+ {
+ function ()
+ os.execv(os.programfile(), argv)
+ end,
+ finally
+ {
+ function ()
+ if rcfile then
+ os.tryrm(rcfile)
+ end
+ end
+ }
+ }
-- and lock them, so that the other users get the same versions
_lock_addons(projectdir, addonsinfo)