diff options
| author | ruki <[email protected]> | 2024-11-29 23:50:04 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2024-11-29 23:50:04 +0800 |
| commit | 78f2f9b858a5acede19b35608a193364bda1f738 (patch) | |
| tree | 15ca822556a635c3aacecf4157e0227a78730d5a | |
| parent | 603de8819bbc4234a12035f7b9d5748362ec9aa0 (diff) | |
check verison conflicts
| -rw-r--r-- | tests/projects/package/compatibility/deps_with_version/xmake.lua | 8 | ||||
| -rw-r--r-- | xmake/modules/private/action/require/impl/package.lua | 100 |
2 files changed, 79 insertions, 29 deletions
diff --git a/tests/projects/package/compatibility/deps_with_version/xmake.lua b/tests/projects/package/compatibility/deps_with_version/xmake.lua index e937c1384..b6ba830c3 100644 --- a/tests/projects/package/compatibility/deps_with_version/xmake.lua +++ b/tests/projects/package/compatibility/deps_with_version/xmake.lua @@ -5,11 +5,17 @@ package_end() package("bar") add_deps("zlib 1.2.x") +-- add_deps("libpng dev") + on_install(function () end) +package_end() + +package("zoo") + add_deps("libpng master") on_install(function () end) package_end() package("test") - add_deps("foo", "bar") + add_deps("foo", "bar", "zoo") on_install(function () end) package_end() diff --git a/xmake/modules/private/action/require/impl/package.lua b/xmake/modules/private/action/require/impl/package.lua index 0e4513a98..b3cc69e87 100644 --- a/xmake/modules/private/action/require/impl/package.lua +++ b/xmake/modules/private/action/require/impl/package.lua @@ -1011,6 +1011,7 @@ function _load_package(packagename, requireinfo, opt) local version, source = _select_package_version(package, requireinfo, locked_requireinfo) if version then package:version_set(version, source) + package:data_set("__locked_requireinfo", locked_requireinfo) end -- get package key @@ -1176,10 +1177,69 @@ function _get_parents_str(package) end end +-- get package compatibility info +function _get_package_compatinfo(package) + local compatinfo = {name = package:name()} + if package:data("__locked_requireinfo") then + compatinfo.locked = true + compatinfo.versions = hashset.from(table.wrap(package:version_str())) + return compatinfo + end + + -- get compatible version range + local requireinfo = package:requireinfo() + local require_version = requireinfo.version + if require_version then + compatinfo.require_version = require_version + if semver.is_valid(require_version) or semver.is_valid_range(require_version) then + local versions = hashset.new() + for _, version in ipairs(package:versions()) do + if semver.satisfies(version, require_version) then + versions:insert(version) + end + end + compatinfo.versions = versions + elseif require_version == "latest" then + compatinfo.versions = hashset.from(table.wrap(package:versions())) + else + compatinfo.versions = hashset.from(table.wrap(require_version)) + end + else + compatinfo.versions = hashset.from(table.wrap(package:versions())) + end + return compatinfo +end + -- check and resolve package conflicts -function _check_and_resolve_package_conflicts(package1, package2) - print(package1:version_str(), package2:version_str()) - print(package1:requireinfo(), package2:requireinfo()) +function _check_and_resolve_package_depconflicts_impl(package, name, deps) + + -- compute versions intersection + local versions + for _, dep in ipairs(deps) do + local compatinfo = _get_package_compatinfo(dep) + assert(compatinfo.versions) + + if versions then + for version in versions:items() do + if not compatinfo.versions:has(version) then + versions:remove(version) + end + end + else + versions = compatinfo.versions + end + end + + if not versions or versions:empty() then + print("package(%s): add_deps(%s, ...)", package:name(), name) + for idx, dep in ipairs(deps) do + local key = _get_packagekey(dep:name(), dep:requireinfo()) + cprint(" ${color.warning}->${clear} %s %s ${dim}%s", + dep:displayname(), dep:version_str() or "", get_configs_str(dep)) + end + raise("package(%s): conflict version dependencies!", name) + end + print(name, versions) end -- check and resolve dependencies conflicts @@ -1197,34 +1257,18 @@ end -- cannot be detected at present and can only be resolved by the user -- function _check_and_resolve_package_depconflicts(package) - print("_check_and_resole_package_depconflicts ..") - --[[ - local packagekeys = {} - for _, dep in ipairs(package:librarydeps()) do - local key = _get_packagekey(dep:name(), dep:requireinfo()) - local prevkey = packagekeys[dep:name()] - if prevkey then - assert(key == prevkey, "package(%s): conflict dependencies with package(%s) in %s!", key, prevkey, package:name()) - else - packagekeys[dep:name()] = key - end - end]] - local same_packages = {} + local some_packagedeps = {} for _, dep in ipairs(package:librarydeps()) do - local packages = same_packages[dep:name()] - if packages == nil then - packages = {} - same_packages[dep:name()] = packages + local deps = some_packagedeps[dep:name()] + if deps == nil then + deps = {} + some_packagedeps[dep:name()] = deps end - table.insert(packages, dep) + table.insert(deps, dep) end - for name, packages in pairs(same_packages) do - if #packages > 1 then - for i = 1, #packages do - for j = i + 1, #packages do - _check_and_resolve_package_conflicts(packages[i], packages[j]) - end - end + for name, deps in pairs(some_packagedeps) do + if #deps > 1 then + _check_and_resolve_package_depconflicts_impl(package, name, deps) end end end |
