diff options
| author | Saikari <[email protected]> | 2026-07-11 02:01:17 +0300 |
|---|---|---|
| committer | ruki <[email protected]> | 2026-07-30 10:17:31 +0800 |
| commit | 20127575d8f48d9b286021c779bdd85090273c39 (patch) | |
| tree | 3304028349444b27824787b7eb16c731a739c980 | |
| parent | a12319420f9ba033b51f48761c28c30f863312c3 (diff) | |
fix: distinguish between plugin and package names to avoid conflicts
| -rw-r--r-- | xmake/core/package/package.lua | 4 | ||||
| -rw-r--r-- | xmake/modules/private/action/require/impl/utils/plugins.lua | 15 | ||||
| -rw-r--r-- | xmake/modules/private/xrepo/quick_search/cache.lua | 17 | ||||
| -rw-r--r-- | xmake/modules/private/xrepo/quick_search/completion.lua | 7 |
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 |
