summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSaikari <[email protected]>2026-07-11 02:01:17 +0300
committerruki <[email protected]>2026-07-30 10:17:31 +0800
commit20127575d8f48d9b286021c779bdd85090273c39 (patch)
tree3304028349444b27824787b7eb16c731a739c980
parenta12319420f9ba033b51f48761c28c30f863312c3 (diff)
fix: distinguish between plugin and package names to avoid conflicts
-rw-r--r--xmake/core/package/package.lua4
-rw-r--r--xmake/modules/private/action/require/impl/utils/plugins.lua15
-rw-r--r--xmake/modules/private/xrepo/quick_search/cache.lua17
-rw-r--r--xmake/modules/private/xrepo/quick_search/completion.lua7
4 files changed, 33 insertions, 10 deletions
diff --git a/xmake/core/package/package.lua b/xmake/core/package/package.lua
index af11ec649..46858b51b 100644
--- a/xmake/core/package/package.lua
+++ b/xmake/core/package/package.lua
@@ -1715,6 +1715,10 @@ function _instance:buildhash()
if label then
str = str .. label
end
+ -- we need to distinguish the install directories of the plugin and package with the same name
+ if self:is_plugin() then
+ str = str .. "plugin"
+ end
if configs then
-- with old vs_runtime configs
diff --git a/xmake/modules/private/action/require/impl/utils/plugins.lua b/xmake/modules/private/action/require/impl/utils/plugins.lua
index 9cd7c5d86..f7d4d305f 100644
--- a/xmake/modules/private/action/require/impl/utils/plugins.lua
+++ b/xmake/modules/private/action/require/impl/utils/plugins.lua
@@ -33,11 +33,20 @@ function register(package)
assert(os.isfile(path.join(installdir, "xmake.lua")),
"plugin(%s): xmake.lua not found in the installed files, it should be installed with `os.cp(\"*\", package:installdir())`!", package:name())
local dir = plugindir(package:name())
- os.tryrm(dir)
- os.cp(installdir, dir)
+ -- we copy it to the temporary directory first and then swap it,
+ -- so the previous plugin will not be lost if copying fails. e.g. disk full
+ --
+ -- we cannot use the sibling directory, e.g. `plugins/<name>.tmp`,
+ -- because the task loader will load all plugins from `plugins/*/xmake.lua`
+ local tmpdir = path.join(path.directory(dir), ".tmp", package:name())
+ os.tryrm(tmpdir)
+ os.cp(installdir, tmpdir)
-- remove the install logs, they do not belong to the plugin,
-- but we keep manifest.txt to show the plugin version and description. e.g. `xmake plugin --list`
- os.tryrm(path.join(dir, "logs"))
+ os.tryrm(path.join(tmpdir, "logs"))
+ -- replace the previous plugin only after the new one is fully ready
+ os.tryrm(dir)
+ os.mv(tmpdir, dir)
vprint("register plugin(%s) to %s", package:name(), dir)
end
diff --git a/xmake/modules/private/xrepo/quick_search/cache.lua b/xmake/modules/private/xrepo/quick_search/cache.lua
index ee0eacc67..8edfce584 100644
--- a/xmake/modules/private/xrepo/quick_search/cache.lua
+++ b/xmake/modules/private/xrepo/quick_search/cache.lua
@@ -36,22 +36,23 @@ function _list_package_dirs()
local subdirname = path.basename(path.directory(dir))
if #subdirname == 1 then -- ignore l/luajit/port/xmake.lua
local packagename = path.filename(dir)
- if not unique[packagename] then
+ if not unique["package\0" .. packagename] then
table.insert(packageinfos, {name = packagename, repo = repo, packagedir = dir})
- unique[packagename] = true
+ unique["package\0" .. packagename] = true
end
end
end
-- find the plugin package directories, e.g. plugins/hello/xmake.lua, plugins/h/hello/xmake.lua
+ -- the plugin and package can share the same name, so we should not dedupe them with each other
for _, file in ipairs(table.join(os.files(path.join(repo:directory(), "plugins", "*", "xmake.lua")),
os.files(path.join(repo:directory(), "plugins", "*", "*", "xmake.lua")))) do
local dir = path.directory(file)
local subdirname = path.basename(path.directory(dir))
if subdirname == "plugins" or #subdirname == 1 then
local packagename = path.filename(dir)
- if not unique[packagename] then
+ if not unique["plugin\0" .. packagename] then
table.insert(packageinfos, {name = packagename, repo = repo, packagedir = dir})
- unique[packagename] = true
+ unique["plugin\0" .. packagename] = true
end
end
end
@@ -70,7 +71,8 @@ end
function update()
for _, packageinfo in ipairs(_list_package_dirs()) do
local package = core_package.load_from_repository(packageinfo.name, packageinfo.packagedir, {repo = packageinfo.repo})
- cache:set(packageinfo.name, {
+ -- we add the kind to the cache key to avoid the key collision between the plugin and package with the same name
+ cache:set(packageinfo.name .. "\0" .. (package:kind() or "library"), {
reponame = package:repo() and package:repo():name(),
description = package:description(),
versions = package:versions(),
@@ -97,7 +99,10 @@ function find(name, opt)
_init()
opt = opt or {}
local list_result = {}
- for packagename, packagedata in pairs(cache:data()) do
+ for key, packagedata in pairs(cache:data()) do
+ -- strip the kind from the cache key, e.g. `zlib\0library`
+ -- and it is also compatible with the old cache data without the kind
+ local packagename = key:split("\0", {plain = true})[1]
local found = false
if opt.prefix then
found = packagename:startswith(name)
diff --git a/xmake/modules/private/xrepo/quick_search/completion.lua b/xmake/modules/private/xrepo/quick_search/completion.lua
index 449a988ea..a78ec2817 100644
--- a/xmake/modules/private/xrepo/quick_search/completion.lua
+++ b/xmake/modules/private/xrepo/quick_search/completion.lua
@@ -22,10 +22,15 @@ import("private.xrepo.quick_search.cache")
-- complete xrepo packages
function _xmake_package_complete(complete, opt)
+ local unique = {}
local candidates = {}
local found = cache.find(complete, {prefix = true})
for _, candidate in ipairs(found) do
- table.insert(candidates, {value = candidate.name, description = candidate.data.description})
+ -- the plugin and package can share the same name, we need to remove the duplicates
+ if not unique[candidate.name] then
+ table.insert(candidates, {value = candidate.name, description = candidate.data.description})
+ unique[candidate.name] = true
+ end
end
return candidates
end