Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add select script tests #4793

Merged
merged 4 commits into from
Mar 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 111 additions & 0 deletions tests/modules/private/select_script/test.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import("private.core.base.select_script")

function _match_pattern(pattern, opt)
pattern = pattern:gsub("([%+%.%-%^%$%(%)%%])", "%%%1")
pattern = pattern:gsub("%*", "\001")
pattern = pattern:gsub("\001", ".*")
return select_script({[pattern] = true}, opt) == true
end

function test_plat_only(t)
t:require(_match_pattern("*", {plat = "macosx"}))
t:require(_match_pattern("macosx", {plat = "macosx"}))
t:require(_match_pattern("macosx,linux", {plat = "macosx"}))
t:require(_match_pattern("mac*", {plat = "macosx"}))
t:require_not(_match_pattern("macosx", {plat = "linux"}))
t:require_not(_match_pattern("linux", {plat = "macosx"}))
t:require_not(_match_pattern("!macosx", {plat = "macosx"}))
t:require_not(_match_pattern("!mac*", {plat = "macosx"}))
t:require(_match_pattern("!macosx", {plat = "linux"}))
t:require(_match_pattern("!mac*", {plat = "linux"}))
end

function test_plat_arch(t)
t:require(_match_pattern("*|x86_64", {plat = "macosx", arch = "x86_64"}))
t:require(_match_pattern("macosx|x86_64", {plat = "macosx", arch = "x86_64"}))
t:require(_match_pattern("macosx|x86_64,linux|x86_64", {plat = "macosx", arch = "x86_64"}))
t:require(_match_pattern("macosx|x86_*", {plat = "macosx", arch = "x86_64"}))
t:require_not(_match_pattern("macosx|x86_64", {plat = "linux", arch = "x86_64"}))
t:require_not(_match_pattern("macosx|i386", {plat = "macosx", arch = "x86_64"}))
t:require_not(_match_pattern("!macosx|x86_64", {plat = "macosx", arch = "x86_64"}))
t:require_not(_match_pattern("!mac*|x86_64", {plat = "macosx", arch = "x86_64"}))
t:require(_match_pattern("!macosx|x86_64", {plat = "linux", arch = "x86_64"}))
t:require(_match_pattern("!mac*|x86_64", {plat = "linux", arch = "x86_64"}))
t:require(_match_pattern("macosx|!i386", {plat = "macosx", arch = "x86_64"}))
t:require(_match_pattern("!macosx|!i386", {plat = "linux", arch = "x86_64"}))
t:require(_match_pattern("windows|!x86", {plat = "windows", arch = "x64"}))
t:require_not(_match_pattern("windows|!x86", {plat = "android", arch = "arm64-v8a"}))
t:require(_match_pattern("macosx|native", {plat = "macosx", arch = "x86_64", subarch = "x86_64"}))
t:require(_match_pattern("macosx|!native", {plat = "macosx", arch = "arm64", subarch = "x86_64"}))
t:require_not(_match_pattern("macosx|!native", {plat = "macosx", arch = "x86_64", subarch = "x86_64"}))
t:require_not(_match_pattern("windows|native", {plat = "macosx", arch = "x86_64", subarch = "x86_64"}))
end

function test_subhost_only(t)
t:require(_match_pattern("@*", {subhost = "macosx"}))
t:require(_match_pattern("@macosx", {subhost = "macosx"}))
t:require(_match_pattern("@macosx,@linux", {subhost = "macosx"}))
t:require(_match_pattern("@mac*", {subhost = "macosx"}))
t:require_not(_match_pattern("@macosx", {subhost = "linux"}))
t:require_not(_match_pattern("@linux", {subhost = "macosx"}))
t:require_not(_match_pattern("@!macosx", {subhost = "macosx"}))
t:require_not(_match_pattern("@!mac*", {subhost = "macosx"}))
t:require(_match_pattern("@!macosx", {subhost = "linux"}))
t:require(_match_pattern("@!mac*", {subhost = "linux"}))
end

function test_subhost_subarch(t)
t:require(_match_pattern("@*|x86_64", {subhost = "macosx", subarch = "x86_64"}))
t:require(_match_pattern("@macosx|x86_64", {subhost = "macosx", subarch = "x86_64"}))
t:require(_match_pattern("@macosx|x86_64,@linux|x86_64", {subhost = "macosx", subarch = "x86_64"}))
t:require(_match_pattern("@macosx|x86_*", {subhost = "macosx", subarch = "x86_64"}))
t:require_not(_match_pattern("@macosx|x86_64", {subhost = "linux", subarch = "x86_64"}))
t:require_not(_match_pattern("@macosx|i386", {subhost = "macosx", subarch = "x86_64"}))
t:require_not(_match_pattern("@!macosx|x86_64", {subhost = "macosx", subarch = "x86_64"}))
t:require_not(_match_pattern("@!mac*|x86_64", {subhost = "macosx", subarch = "x86_64"}))
t:require(_match_pattern("@!macosx|x86_64", {subhost = "linux", subarch = "x86_64"}))
t:require(_match_pattern("@!mac*|x86_64", {subhost = "linux", subarch = "x86_64"}))
t:require(_match_pattern("@macosx|!i386", {subhost = "macosx", subarch = "x86_64"}))
t:require(_match_pattern("@!macosx|!i386", {subhost = "linux", subarch = "x86_64"}))
t:require(_match_pattern("@windows|!x86", {subhost = "windows", subarch = "x64"}))
t:require_not(_match_pattern("@windows|!x86", {subhost = "android", subarch = "arm64-v8a"}))
t:require(_match_pattern("@macosx|native", {subhost = "macosx", subarch = "x86_64"}))
t:require(_match_pattern("@macosx|native", {subhost = "macosx", subarch = "arm64"}))
t:require_not(_match_pattern("@macosx|!native", {subhost = "macosx", subarch = "x86_64"}))
t:require_not(_match_pattern("@windows|native", {subhost = "macosx", subarch = "x86_64"}))
end

function test_plat_subhost(t)
t:require(_match_pattern("*@macosx", {plat = "macosx", subhost = "macosx"}))
t:require(_match_pattern("android@macosx", {plat = "android", subhost = "macosx"}))
t:require(_match_pattern("android@macosx,linux", {plat = "android", subhost = "linux"}))
t:require(_match_pattern("android@mac*", {plat = "android", subhost = "macosx"}))
t:require(_match_pattern("android@!macosx", {plat = "android", subhost = "linux"}))
t:require_not(_match_pattern("!android@macosx", {plat = "android", subhost = "macosx"}))
t:require(_match_pattern("!iphon*@macosx", {plat = "linux", subhost = "macosx"}))
end

function test_plat_arch_subhost(t)
t:require(_match_pattern("*|x86_64@macosx", {plat = "macosx", subhost = "macosx", arch = "x86_64"}))
t:require(_match_pattern("android|arm64-v8a@macosx", {plat = "android", subhost = "macosx", arch = "arm64-v8a"}))
t:require(_match_pattern("android|x86_64@macosx,linux", {plat = "android", subhost = "linux", arch = "x86_64"}))
t:require(_match_pattern("android|x86_64@mac*", {plat = "android", subhost = "macosx", arch = "x86_64"}))
t:require(_match_pattern("android|x86_64@!macosx", {plat = "android", subhost = "linux", arch = "x86_64"}))
t:require_not(_match_pattern("!android|x86_64@macosx", {plat = "android", subhost = "macosx", arch = "x86_64"}))
t:require(_match_pattern("!iphon*|x86_64@macosx", {plat = "linux", subhost = "macosx", arch = "x86_64"}))
t:require(_match_pattern("iphon*|arm64@macosx", {plat = "iphoneos", subhost = "macosx", arch = "arm64"}))
t:require_not(_match_pattern("iphon*|arm64@macosx", {plat = "iphoneos", subhost = "linux", arch = "arm64"}))
end

function test_plat_arch_subhost_subarch(t)
t:require(_match_pattern("*|x86_64@macosx|x86_64", {plat = "macosx", subhost = "macosx", arch = "x86_64", subarch = "x86_64"}))
t:require(_match_pattern("android|arm64-v8a@macosx|x86_64", {plat = "android", subhost = "macosx", arch = "arm64-v8a", subarch = "x86_64"}))
t:require(_match_pattern("android|x86_64@macosx|x86_64,linux|x86_64", {plat = "android", subhost = "linux", arch = "x86_64", subarch = "x86_64"}))
t:require(_match_pattern("android|x86_64@mac*|x86_64", {plat = "android", subhost = "macosx", arch = "x86_64", subarch = "x86_64"}))
t:require(_match_pattern("android|x86_64@!macosx|x86_64", {plat = "android", subhost = "linux", arch = "x86_64", subarch = "x86_64"}))
t:require_not(_match_pattern("!android|x86_64@macosx|x86_64", {plat = "android", subhost = "macosx", arch = "x86_64", subarch = "x86_64"}))
t:require(_match_pattern("!iphon*|x86_64@macosx|x86_64", {plat = "linux", subhost = "macosx", arch = "x86_64", subarch = "x86_64"}))
t:require(_match_pattern("iphon*|arm64@macosx|x86_64", {plat = "iphoneos", subhost = "macosx", arch = "arm64", subarch = "x86_64"}))
t:require_not(_match_pattern("iphon*|arm64@macosx|x86_64", {plat = "iphoneos", subhost = "linux", arch = "arm64", subarch = "x86_64"}))
t:require(_match_pattern("android|native@macosx|x86_64", {plat = "android", subhost = "macosx", arch = "x86_64", subarch = "x86_64"}))
end
79 changes: 52 additions & 27 deletions xmake/core/base/private/select_script.lua
Original file line number Diff line number Diff line change
Expand Up @@ -23,32 +23,53 @@ local table = require("base/table")
local utils = require("base/utils")

-- match pattern, matched mode: plat|arch, excluded mode: !plat|arch
function _match_pattern(pattern, plat, arch, excluded)
-- support native arch, e.g. macosx|native
-- @see https://github.com/xmake-io/xmake/issues/4657
if pattern:find("native", 1, true) then
local splitinfo = pattern:split("|")
local pattern_plat = splitinfo[1]
local pattern_arch = splitinfo[2]
if pattern_arch and pattern_plat:trim("!") == os.subhost() then
pattern_arch = pattern_arch:gsub("native", os.subarch())
pattern = pattern_plat .. "|" .. pattern_arch
function _match_pattern(pattern, plat, arch, opt)
opt = opt or {}
local excluded = opt.excluded
local subhost = opt.subhost or os.subhost()
local subarch = opt.subarch or os.subarch()
local splitinfo = pattern:split("|", {strict = true, plain = true})
local pattern_plat = splitinfo[1]
local pattern_arch = splitinfo[2]
if pattern_plat and #pattern_plat > 0 then
local matched = false
local is_excluded_pattern = pattern_plat:find('!', 1, true)
if excluded and is_excluded_pattern then
matched = not ('!' .. plat):match('^' .. pattern_plat .. '$')
elseif not is_excluded_pattern then
matched = plat:match('^' .. pattern_plat .. '$')
end
if not matched then
return false
end
end
if pattern_arch and #pattern_arch > 0 then
-- support native arch, e.g. macosx|native
-- @see https://github.com/xmake-io/xmake/issues/4657
pattern_arch = pattern_arch:gsub("native", subarch)

local matched = false
local is_excluded_pattern = pattern_arch:find('!', 1, true)
if excluded and is_excluded_pattern then
matched = not ('!' .. arch):match('^' .. pattern_arch .. '$')
elseif not is_excluded_pattern then
matched = arch:match('^' .. pattern_arch .. '$')
end
if not matched then
return false
end
end
local is_excluded_pattern = pattern:find('!', 1, true)
if excluded and is_excluded_pattern then
return not ('!' .. plat .. '|' .. arch):match('^' .. pattern .. '$') and
not (plat .. '|!' .. arch):match('^' .. pattern .. '$') and
not ('!' .. plat):match('^' .. pattern .. '$')
elseif not is_excluded_pattern then
return (plat .. '|' .. arch):match('^' .. pattern .. '$') or plat:match('^' .. pattern .. '$')
if not pattern_plat and not pattern_arch then
os.raise("invalid script pattern: %s", pattern)
end
return true
end


-- match patterns
function _match_patterns(patterns, plat, arch, excluded)
function _match_patterns(patterns, plat, arch, opt)
for _, pattern in ipairs(patterns) do
if _match_pattern(pattern, plat, arch, excluded) then
if _match_pattern(pattern, plat, arch, opt) then
return true
end
end
Expand Down Expand Up @@ -86,7 +107,8 @@ end
-- `!android|armeabi-v7a@!linux|!x86_64`
-- `!linux|*`
--
function _match_script(pattern, plat, arch, excluded)
function _match_script(pattern, opt)
opt = opt or {}
local splitinfo = pattern:split("@", {strict = true, plain = true})
local plat_part = splitinfo[1]
local host_part = splitinfo[2]
Expand All @@ -98,17 +120,21 @@ function _match_script(pattern, plat, arch, excluded)
if host_part and #host_part > 0 then
host_patterns = host_part:split(",", {plain = true})
end
local plat = opt.plat or ""
local arch = opt.arch or ""
local subhost = opt.subhost or os.subhost()
local subarch = opt.subarch or os.subarch()
if plat_patterns and #plat_patterns > 0 then
if _match_patterns(plat_patterns, plat, arch, excluded) then
if _match_patterns(plat_patterns, plat, arch, opt) then
if host_patterns and #host_patterns > 0 and
not _match_patterns(host_patterns, os.subhost(), os.subarch(), excluded) then
not _match_patterns(host_patterns, subhost, subarch, opt) then
return false
end
return true
end
else
if host_patterns and #host_patterns > 0 then
return _match_patterns(host_patterns, os.subhost(), os.subarch(), excluded)
return _match_patterns(host_patterns, subhost, subarch, opt)
end
end
end
Expand All @@ -120,20 +146,19 @@ function select_script(scripts, opt)
if type(scripts) == "function" then
result = scripts
elseif type(scripts) == "table" then
local plat = opt.plat or ""
local arch = opt.arch or ""
local script_matched
for pattern, script in pairs(scripts) do
if not pattern:startswith("__") and _match_script(pattern, plat, arch) then
if not pattern:startswith("__") and _match_script(pattern, opt) then
script_matched = script
break
end
end
if not script_matched then
local scripts_fallback = {}
local patterns_fallback = {}
local excluded_opt = table.join(opt, {excluded = true})
for pattern, script in pairs(scripts) do
if not pattern:startswith("__") and _match_script(pattern, plat, arch, true) then
if not pattern:startswith("__") and _match_script(pattern, excluded_opt) then
table.insert(scripts_fallback, script)
table.insert(patterns_fallback, pattern)
end
Expand Down
Loading