Compare commits
2 Commits
91a587380d
...
7a007b7046
| Author | SHA1 | Date | |
|---|---|---|---|
| 7a007b7046 | |||
| aa54adf108 |
@@ -1,3 +1,10 @@
|
||||
# xmake
|
||||
|
||||
xmake包仓库
|
||||
xmake包仓库
|
||||
|
||||
|
||||
# 测试包
|
||||
|
||||
```sh
|
||||
xmake l ./scripts/test.lua -v -D "sioclient 3.1.0"
|
||||
```
|
||||
48
packages/s/sioclient/xmake.lua
Normal file
48
packages/s/sioclient/xmake.lua
Normal file
@@ -0,0 +1,48 @@
|
||||
package("sioclient")
|
||||
set_homepage("https://github.com/socketio/socket.io-client-cpp")
|
||||
set_description("C++11 implementation of Socket.IO client")
|
||||
set_license("MIT")
|
||||
|
||||
add_urls("https://github.com/socketio/socket.io-client-cpp/archive/refs/tags/$(version).tar.gz")
|
||||
|
||||
add_versions("3.1.0","f54dd36b8e5618d028c7c42f0c1a83a0d3a58f9239cf4b770f6b02b925909597")
|
||||
add_versions("3.0.0","6c11383eaea837d3dc4183d31f8d27f5ce08b3987f4903708983044115ebd95a")
|
||||
add_versions("2.1.0","f5bd6260403dd6c62c6dbf97ca848f5db69908edbdc0a365e28be06cdd2a44f8")
|
||||
|
||||
add_deps("rapidjson")
|
||||
add_deps("websocketpp")
|
||||
add_deps("asio")
|
||||
add_deps("openssl3")
|
||||
|
||||
on_install(function (package)
|
||||
local ver = package:version_str()
|
||||
|
||||
local content = string.format([[
|
||||
add_rules("mode.debug", "mode.release")
|
||||
add_requires("rapidjson")
|
||||
add_requires("websocketpp")
|
||||
add_requires("asio")
|
||||
add_requires("openssl3")
|
||||
target("sioclient")
|
||||
set_kind("$(kind)")
|
||||
set_languages("cxx11")
|
||||
add_files("src/*.cpp")
|
||||
add_files("src/internal/*.cpp")
|
||||
add_headerfiles("src/internal/*.h")
|
||||
add_headerfiles("src/*.h")
|
||||
add_packages("rapidjson", "websocketpp", "asio", "openssl3")
|
||||
add_defines("VERSION=%s")
|
||||
]], ver)
|
||||
|
||||
io.writefile("xmake.lua", content)
|
||||
import("package.tools.xmake").install(package)
|
||||
end)
|
||||
|
||||
on_test(function (package)
|
||||
assert(package:check_cxxsnippets({test = [[
|
||||
void test() {
|
||||
sio::client h;
|
||||
h.socket();
|
||||
}
|
||||
]]}, {includes = {"sio_client.h"}, configs = {languages = "cxx11"}}))
|
||||
end)
|
||||
36
scripts/automerge.lua
Normal file
36
scripts/automerge.lua
Normal file
@@ -0,0 +1,36 @@
|
||||
|
||||
function _get_autoupdate_pr_list()
|
||||
local result = {}
|
||||
local list = os.iorun("gh pr list --label auto-update --state open -R xmake-io/xmake-repo")
|
||||
if list then
|
||||
for _, line in ipairs(list:split("\n")) do
|
||||
if line:find("Auto-update", 1, true) then
|
||||
local id = line:match("(%d+)%s+Auto%-update")
|
||||
if id then
|
||||
table.insert(result, {id = id, title = line})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
function _check_pr_passed(id)
|
||||
local ok = os.vexecv("gh", {"pr", "checks", id, "-R", "xmake-io/xmake-repo"}, {try = true})
|
||||
if ok == 0 then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
function main()
|
||||
local pr_list = _get_autoupdate_pr_list()
|
||||
for _, info in ipairs(pr_list) do
|
||||
local id = info.id
|
||||
local title = info.title
|
||||
print("checking %s ...", title)
|
||||
if _check_pr_passed(id) then
|
||||
print("pull/%d passed, it will be merged next.", id)
|
||||
os.vexec("gh pr merge %d --squash -d -R xmake-io/xmake-repo", id)
|
||||
end
|
||||
end
|
||||
end
|
||||
158
scripts/autoupdate.lua
Normal file
158
scripts/autoupdate.lua
Normal file
@@ -0,0 +1,158 @@
|
||||
import("core.package.package")
|
||||
import("core.base.semver")
|
||||
import("core.base.hashset")
|
||||
import("devel.git")
|
||||
import("packages", {alias = "packages_util"})
|
||||
|
||||
function _load_package(packagename, packagedir, packagefile)
|
||||
local funcinfo = debug.getinfo(package.load_from_repository)
|
||||
if funcinfo and funcinfo.nparams == 3 then -- >= 2.7.8
|
||||
return package.load_from_repository(packagename, packagedir, {packagefile = packagefile})
|
||||
else
|
||||
-- deprecated
|
||||
return package.load_from_repository(packagename, nil, packagedir, packagefile)
|
||||
end
|
||||
end
|
||||
|
||||
function _get_all_packages(pattern)
|
||||
local packages = _g.packages
|
||||
if not packages then
|
||||
packages = {}
|
||||
for _, packagedir in ipairs(os.dirs(path.join("packages", "*", "*"))) do
|
||||
local packagename = path.filename(packagedir)
|
||||
if not pattern or packagename:match(pattern) then
|
||||
local packagefile = path.join(packagedir, "xmake.lua")
|
||||
local instance = _load_package(packagename, packagedir, packagefile)
|
||||
local basename = instance:get("base")
|
||||
if instance and basename then
|
||||
local basedir = path.join("packages", basename:sub(1, 1):lower(), basename:lower())
|
||||
local basefile = path.join(basedir, "xmake.lua")
|
||||
instance._BASE = _load_package(basename, basedir, basefile)
|
||||
end
|
||||
if instance then
|
||||
table.insert(packages, instance)
|
||||
end
|
||||
end
|
||||
end
|
||||
_g.packages = packages
|
||||
end
|
||||
return packages
|
||||
end
|
||||
|
||||
function _is_pending(instance, version)
|
||||
local branch = "autoupdate-" .. instance:name() .. "-" .. version
|
||||
local repourl = "git@github.com:xmake-io/xmake-repo.git"
|
||||
local is_pending = false
|
||||
local remote_branches = os.iorun("git ls-remote --head %s", repourl)
|
||||
if remote_branches then
|
||||
for _, remote_branch in ipairs(remote_branches:split("\n")) do
|
||||
remote_branch = remote_branch:split("%s")[2]
|
||||
if remote_branch == "refs/heads/" .. branch then
|
||||
is_pending = true
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
return is_pending
|
||||
end
|
||||
|
||||
function _update_version(instance, version, shasum)
|
||||
local branch = "autoupdate-" .. instance:name() .. "-" .. version
|
||||
local branch_current = os.iorun("git branch --show-current"):trim()
|
||||
local repourl = "git@github.com:xmake-io/xmake-repo.git"
|
||||
os.vexec("git reset --hard HEAD")
|
||||
os.vexec("git clean -fdx")
|
||||
os.execv("git", {"branch", "-D", branch}, {try = true})
|
||||
os.vexec("git checkout dev")
|
||||
os.vexec("git pull %s dev", repourl)
|
||||
os.vexec("git branch %s", branch)
|
||||
os.vexec("git checkout %s", branch)
|
||||
local inserted = false
|
||||
local scriptfile = path.join(instance:scriptdir(), "xmake.lua")
|
||||
local version_current
|
||||
if os.isfile(scriptfile) then
|
||||
io.gsub(scriptfile, "add_versions%(\"(.-)\",%s+\"(.-)\"%)", function (v, h)
|
||||
if not version_current or semver.compare(v, version_current) > 0 then
|
||||
version_current = v
|
||||
end
|
||||
if not inserted then
|
||||
inserted = true
|
||||
return string.format('add_versions("%s", "%s")\n add_versions("%s", "%s")', version, shasum, v, h)
|
||||
end
|
||||
end)
|
||||
end
|
||||
if not inserted then
|
||||
local versionfiles = instance:get("versionfiles")
|
||||
if versionfiles then
|
||||
for _, versionfile in ipairs(table.wrap(versionfiles)) do
|
||||
if not os.isfile(versionfile) then
|
||||
versionfile = path.join(instance:scriptdir(), versionfile)
|
||||
end
|
||||
if os.isfile(versionfile) then
|
||||
io.insert(versionfile, 1, string.format("%s %s", version, shasum))
|
||||
inserted = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if inserted then
|
||||
local body = string.format("New version of %s detected (package version: %s, last github version: %s)",
|
||||
instance:name(), version_current, version)
|
||||
os.vexec("git add .")
|
||||
os.vexec("git commit -a -m \"Update %s to %s\"", instance:name(), version)
|
||||
os.vexec("git push %s %s:%s", repourl, branch, branch)
|
||||
os.vexec("gh pr create --label \"auto-update\" --title \"Auto-update %s to %s\" --body \"%s\" -R xmake-io/xmake-repo -B dev -H %s",
|
||||
instance:name(), version, body, branch)
|
||||
end
|
||||
os.vexec("git reset --hard HEAD")
|
||||
os.vexec("git checkout %s", branch_current)
|
||||
end
|
||||
|
||||
function _report_issue(instance)
|
||||
local package_name = instance:name()
|
||||
local curr_open_issue = os.iorun("gh issue list --label \"help wanted\" --label \"auto-update\" --search \"in:title [auto-update] %s requires manual handling\" -R xmake-io/xmake-repo --json number",
|
||||
package_name)
|
||||
if curr_open_issue == "[]\n" then
|
||||
local body = string.format("Failed to get tags of %s, which may be due to changes in repository visibility.",
|
||||
package_name)
|
||||
local title = "[auto-update] " .. package_name .. " requires manual handling."
|
||||
os.vexec("gh issue create --title \"%s\" --body \"%s\" --label \"help wanted,auto-update\" -R xmake-io/xmake-repo",
|
||||
title, body)
|
||||
else
|
||||
print("Found a known open issue #%s for package %s", curr_open_issue:trim(), package_name)
|
||||
end
|
||||
end
|
||||
|
||||
function main(pattern)
|
||||
local count = 0
|
||||
local maxcount = 5
|
||||
local instances = _get_all_packages(pattern)
|
||||
if #instances < maxcount then
|
||||
maxcount = #instances
|
||||
end
|
||||
math.randomseed(os.time())
|
||||
while count < maxcount and #instances > 0 do
|
||||
local idx = math.random(#instances)
|
||||
local instance = instances[idx]
|
||||
local checkupdate_filepath = path.join(instance:scriptdir(), "checkupdate.lua")
|
||||
if not os.isfile(checkupdate_filepath) then
|
||||
checkupdate_filepath = path.join(os.scriptdir(), "checkupdate.lua")
|
||||
end
|
||||
local updated = false
|
||||
if os.isfile(checkupdate_filepath) then
|
||||
local checkupdate = import("checkupdate", {rootdir = path.directory(checkupdate_filepath), anonymous = true})
|
||||
local version, shasum = checkupdate(instance)
|
||||
if version == false then
|
||||
_report_issue(instance)
|
||||
elseif version and shasum and not _is_pending(instance, version) then
|
||||
cprint("package(%s): new version ${bright}%s${clear} found, shasum: ${bright}%s", instance:name(), version, shasum)
|
||||
_update_version(instance, version, shasum)
|
||||
updated = true
|
||||
end
|
||||
end
|
||||
if updated then
|
||||
count = count + 1
|
||||
end
|
||||
table.remove(instances, idx)
|
||||
end
|
||||
end
|
||||
169
scripts/build_artifacts.lua
Normal file
169
scripts/build_artifacts.lua
Normal file
@@ -0,0 +1,169 @@
|
||||
import("core.package.package")
|
||||
import("core.base.semver")
|
||||
import("core.base.hashset")
|
||||
import("packages", {alias = "packages_util"})
|
||||
|
||||
-- load package
|
||||
function _load_package(packagename, packagedir, packagefile)
|
||||
local funcinfo = debug.getinfo(package.load_from_repository)
|
||||
if funcinfo and funcinfo.nparams == 3 then -- >= 2.7.8
|
||||
return package.load_from_repository(packagename, packagedir, {packagefile = packagefile})
|
||||
else
|
||||
-- deprecated
|
||||
return package.load_from_repository(packagename, nil, packagedir, packagefile)
|
||||
end
|
||||
end
|
||||
|
||||
function _need_artifact(instance)
|
||||
return (not instance:is_headeronly()) and (packages_util.is_supported(instance, "windows", "x64") or packages_util.is_supported(instance, "windows", "x86"))
|
||||
end
|
||||
|
||||
function _build_artifacts(name, versions)
|
||||
local buildinfo = {name = name, versions = versions}
|
||||
print(buildinfo)
|
||||
os.tryrm("build-artifacts")
|
||||
os.exec("git clone git@github.com:xmake-mirror/build-artifacts.git -b build")
|
||||
local oldir = os.cd("build-artifacts")
|
||||
local trycount = 0
|
||||
while trycount < 2 do
|
||||
local ok = try
|
||||
{
|
||||
function ()
|
||||
io.save("build.txt", buildinfo)
|
||||
os.exec("git add -A")
|
||||
os.exec("git commit -a -m \"autobuild %s by xmake-repo/ci\"", name)
|
||||
os.exec("git push origin build")
|
||||
return true
|
||||
end,
|
||||
catch
|
||||
{
|
||||
function ()
|
||||
os.exec("git reset --hard HEAD^")
|
||||
os.exec("git pull origin build")
|
||||
end
|
||||
}
|
||||
}
|
||||
if ok then
|
||||
break
|
||||
end
|
||||
trycount = trycount + 1
|
||||
end
|
||||
assert(trycount < 2)
|
||||
os.cd(oldir)
|
||||
end
|
||||
|
||||
function _get_latest_modified_packages()
|
||||
print("find latest modified packages ..")
|
||||
local instances = {}
|
||||
local files = os.iorun("git diff --name-only HEAD^")
|
||||
for _, file in ipairs(files:split('\n')) do
|
||||
file = file:trim()
|
||||
if file:find("packages", 1, true) and path.filename(file) == "xmake.lua" then
|
||||
assert(file == file:lower(), "%s must be lower case!", file)
|
||||
local packagedir = path.directory(file)
|
||||
local packagename = path.filename(packagedir)
|
||||
if #path.filename(path.directory(packagedir)) == 1 then
|
||||
local instance = _load_package(packagename, packagedir, file)
|
||||
if instance and _need_artifact(instance) then
|
||||
table.insert(instances, instance)
|
||||
print(" > %s", instance:name())
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
print("%d found", #instances)
|
||||
return instances
|
||||
end
|
||||
|
||||
function _get_all_packages()
|
||||
local packages = _g.packages
|
||||
if not packages then
|
||||
packages = {}
|
||||
for _, packagedir in ipairs(os.dirs(path.join("packages", "*", "*"))) do
|
||||
local packagename = path.filename(packagedir)
|
||||
local packagefile = path.join(packagedir, "xmake.lua")
|
||||
local instance = _load_package(packagename, packagedir, packagefile)
|
||||
local basename = instance:get("base")
|
||||
if instance and basename then
|
||||
local basedir = path.join("packages", basename:sub(1, 1):lower(), basename:lower())
|
||||
local basefile = path.join(basedir, "xmake.lua")
|
||||
instance._BASE = _load_package(basename, basedir, basefile)
|
||||
end
|
||||
if instance and _need_artifact(instance) then
|
||||
table.insert(packages, instance)
|
||||
end
|
||||
end
|
||||
_g.packages = packages
|
||||
end
|
||||
return packages
|
||||
end
|
||||
|
||||
function _get_packagerefs_of(instance)
|
||||
local packagerefs = {}
|
||||
if instance:is_library() then
|
||||
local packages = _get_all_packages()
|
||||
for _, packageref in ipairs(packages) do
|
||||
local deps = packageref:get("deps")
|
||||
if deps and table.contains(table.wrap(deps), instance:name()) then
|
||||
table.insert(packagerefs, packageref)
|
||||
end
|
||||
end
|
||||
end
|
||||
return packagerefs
|
||||
end
|
||||
|
||||
function _get_packagerefs_in_latest_24h()
|
||||
print("find packagerefs in latest 24h ..")
|
||||
local instances = {}
|
||||
local list = os.iorun("git log --since=\"24 hours ago\" --oneline")
|
||||
local lines = list:split('\n')
|
||||
if #lines > 0 then
|
||||
local line = lines[#lines]
|
||||
local commit = line:split(" ")[1]
|
||||
if commit and #commit == 8 then
|
||||
local files = os.iorun("git diff --name-only " .. commit .. "^")
|
||||
for _, file in ipairs(files:split('\n')) do
|
||||
file = file:trim()
|
||||
if file:find("packages", 1, true) and path.filename(file) == "xmake.lua" then
|
||||
assert(file == file:lower(), "%s must be lower case!", file)
|
||||
local packagedir = path.directory(file)
|
||||
local packagename = path.filename(packagedir)
|
||||
if #path.filename(path.directory(packagedir)) == 1 then
|
||||
local instance = _load_package(packagename, packagedir, file)
|
||||
if instance and _need_artifact(instance) then
|
||||
table.insert(instances, instance)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
local packagerefs = hashset.new()
|
||||
for _, instance in ipairs(instances) do
|
||||
print("%s: ", instance:name())
|
||||
for _, packageref in ipairs(_get_packagerefs_of(instance)) do
|
||||
packagerefs:insert(packageref)
|
||||
print(" -> %s", packageref:name())
|
||||
end
|
||||
end
|
||||
local result = {}
|
||||
for _, packageref in packagerefs:keys() do
|
||||
if #result < 24 then
|
||||
table.insert(result, packageref)
|
||||
end
|
||||
end
|
||||
print("%d found", #result)
|
||||
return result
|
||||
end
|
||||
|
||||
function main(updaterefs)
|
||||
local instances = updaterefs and _get_packagerefs_in_latest_24h() or _get_latest_modified_packages()
|
||||
for _, instance in ipairs(instances) do
|
||||
local versions = instance:versions()
|
||||
if versions and #versions > 0 then
|
||||
table.sort(versions, function (a, b) return semver.compare(a, b) > 0 end)
|
||||
local version_latest = versions[1]
|
||||
_build_artifacts(instance:name(), table.wrap(version_latest))
|
||||
end
|
||||
end
|
||||
end
|
||||
135
scripts/checkupdate.lua
Normal file
135
scripts/checkupdate.lua
Normal file
@@ -0,0 +1,135 @@
|
||||
import("core.base.semver")
|
||||
import("net.http")
|
||||
import("devel.git")
|
||||
import("private.action.require.impl.utils.filter")
|
||||
|
||||
function shasum_of(package, url, version)
|
||||
local shasum
|
||||
local tmpfile = os.tmpfile()
|
||||
package:version_set(version)
|
||||
url = filter.handle(url, package)
|
||||
local ok = try { function() http.download(url, tmpfile); return true end }
|
||||
if ok and os.isfile(tmpfile) and os.filesize(tmpfile) > 1024 then
|
||||
shasum = hash.sha256(tmpfile)
|
||||
end
|
||||
os.tryrm(tmpfile)
|
||||
return shasum
|
||||
end
|
||||
|
||||
function _is_valid_version(version)
|
||||
if not semver.is_valid(version) then
|
||||
return false
|
||||
end
|
||||
local v = semver.new(version)
|
||||
local prerelease = v:prerelease()
|
||||
if prerelease and #prerelease > 0 then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function _get_version_and_shasum(package, url, version_latest)
|
||||
if version_latest then
|
||||
local has_prefix_v = false
|
||||
for _, version in ipairs(package:versions()) do
|
||||
if version:startswith("v") then
|
||||
has_prefix_v = true
|
||||
end
|
||||
if semver.compare(version, version_latest) >= 0 then
|
||||
version_latest = nil
|
||||
break
|
||||
end
|
||||
end
|
||||
if version_latest then
|
||||
if has_prefix_v and not version_latest:startswith("v") then
|
||||
version_latest = "v" .. version_latest
|
||||
elseif not has_prefix_v and version_latest:startswith("v") then
|
||||
version_latest = version_latest:sub(2)
|
||||
end
|
||||
end
|
||||
end
|
||||
if version_latest then
|
||||
local shasum = shasum_of(package, url, version_latest)
|
||||
if shasum then
|
||||
return version_latest, shasum
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function _check_version_from_github_tags(package, url)
|
||||
local repourl = url:match("https://github%.com/.-/.-/")
|
||||
if repourl then
|
||||
print("checking version from github tags %s ..", repourl)
|
||||
local version_latest
|
||||
local tags = try {function() return git.tags(repourl) end}
|
||||
if not tags then
|
||||
return false -- failed to get tags
|
||||
end
|
||||
for _, tag in ipairs(tags) do
|
||||
if _is_valid_version(tag) and (not version_latest or semver.compare(tag, version_latest) > 0) then
|
||||
version_latest = tag
|
||||
end
|
||||
end
|
||||
if version_latest then
|
||||
return _get_version_and_shasum(package, url, version_latest)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function _check_version_from_github_releases(package, url)
|
||||
local repourl = url:match("https://github%.com/.-/.-/")
|
||||
if repourl then
|
||||
print("checking version from github releases %s ..", repourl)
|
||||
local list = try {function() return os.iorunv("gh", {"release", "list", "--exclude-drafts", "--exclude-pre-releases", "-R", repourl}) end}
|
||||
if not list then
|
||||
list = try {function() return os.iorunv("gh", {"release", "list", "-R", repourl}) end}
|
||||
end
|
||||
if not list then
|
||||
return false -- failed to get tags
|
||||
end
|
||||
if list then
|
||||
local version_latest
|
||||
for _, line in ipairs(list:split("\n")) do
|
||||
local splitinfo = line:split("%s+")
|
||||
local release = splitinfo[1]
|
||||
local version = splitinfo[#splitinfo - 1]
|
||||
if not version or not _is_valid_version(version) and _is_valid_version(release) then
|
||||
version = release
|
||||
end
|
||||
if version and _is_valid_version(version) then
|
||||
version_latest = version
|
||||
break
|
||||
end
|
||||
end
|
||||
if version_latest then
|
||||
return _get_version_and_shasum(package, url, version_latest)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function _version_is_behind_conditions(package)
|
||||
local scriptfile = path.join(package:scriptdir(), "xmake.lua")
|
||||
local file = io.open(scriptfile)
|
||||
for line in file:lines() do
|
||||
local pos = line:find("add_versions", 1, true) or line:find("add_versionfiles", 1, true)
|
||||
if pos and pos > 5 then
|
||||
return true
|
||||
end
|
||||
end
|
||||
file:close()
|
||||
end
|
||||
|
||||
function main(package)
|
||||
local checkers = {
|
||||
["https://github%.com/.-/.-/archive/refs/tags/.*"] = _check_version_from_github_tags,
|
||||
["https://github%.com/.-/.-/releases/download/.*"] = _check_version_from_github_releases
|
||||
}
|
||||
for _, url in ipairs(package:urls()) do
|
||||
for pattern, checker in pairs(checkers) do
|
||||
if url:match(pattern) and not _version_is_behind_conditions(package) then
|
||||
return checker(package, url)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
14
scripts/list.lua
Normal file
14
scripts/list.lua
Normal file
@@ -0,0 +1,14 @@
|
||||
import("packages")
|
||||
|
||||
function main(...)
|
||||
for plat, pkgs in pairs(packages()) do
|
||||
cprint("${magenta}%s${clear}:", plat)
|
||||
for _, pkg in ipairs(pkgs) do
|
||||
if pkg.generic then
|
||||
cprint(" ${yellow}->${clear} %s", pkg.name)
|
||||
else
|
||||
cprint(" ${yellow}->${clear} %s (%s)", pkg.name, table.concat(pkg.archs, ", "))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
297
scripts/new.lua
Normal file
297
scripts/new.lua
Normal file
@@ -0,0 +1,297 @@
|
||||
import("core.base.option")
|
||||
import("core.base.semver")
|
||||
import("core.base.json")
|
||||
import("core.base.hashset")
|
||||
import("lib.detect.find_tool")
|
||||
import("lib.detect.find_file")
|
||||
import("net.http")
|
||||
import("devel.git")
|
||||
import("utils.archive")
|
||||
|
||||
local options = {
|
||||
{nil, "repo", "v", nil, "Set repository name.",
|
||||
"e.g. ",
|
||||
" - github:xmake-io/xmake",
|
||||
" - gitlab:xmake-io/xmake"}
|
||||
}
|
||||
|
||||
-- function to get Gitlab data
|
||||
function get_gitlab_data(reponame)
|
||||
local glab = assert(find_tool("glab"), "glab not found!")
|
||||
local host = os.iorunv(glab.program, {"config", "get", "host"}):trim()
|
||||
local graphql_query = 'query={ project(fullPath: "' .. reponame .. '") { description webUrl sshUrlToRepo name } }'
|
||||
local repoinfo = os.iorunv(glab.program, {"api", "graphql", "-f", graphql_query})
|
||||
|
||||
local data = {}
|
||||
if repoinfo then
|
||||
repoinfo = json.decode(repoinfo)
|
||||
if repoinfo.data and repoinfo.data.project then
|
||||
-- extract required data and restructure it
|
||||
local project_data = repoinfo.data.project
|
||||
data = {
|
||||
description = project_data.description,
|
||||
homepageUrl = project_data.webUrl,
|
||||
licenseInfo = "MIT", -- NOTE: Find a way to get the project license in gitlab
|
||||
url = project_data.webUrl,
|
||||
sshUrl = project_data.sshUrlToRepo,
|
||||
name = project_data.name,
|
||||
}
|
||||
repoinfo.data.project = data
|
||||
end
|
||||
end
|
||||
return {host = host, data = data}
|
||||
end
|
||||
|
||||
local function get_github_data(reponame)
|
||||
local gh = assert(find_tool("gh"), "gh not found!")
|
||||
local host = "github.com"
|
||||
local data = os.iorunv(gh.program, {
|
||||
"repo",
|
||||
"view",
|
||||
reponame,
|
||||
"--json",
|
||||
"description,homepageUrl,licenseInfo,url,sshUrl,name,latestRelease",
|
||||
})
|
||||
if data then
|
||||
data = json.decode(data)
|
||||
end
|
||||
return {data = data, host = host}
|
||||
end
|
||||
|
||||
local function get_license_spdx_id(key)
|
||||
local licenses = {
|
||||
["apache-2.0"] = "Apache-2.0",
|
||||
["lgpl-2.0"] = "LGPL-2.0",
|
||||
["lgpl-2.1"] = "LGPL-2.1",
|
||||
["agpl-3.0"] = "AGPL-3.0",
|
||||
["bsd-2-clause"] = "BSD-2-Clause",
|
||||
["bsd-3-clause"] = "BSD-3-Clause",
|
||||
["bsl-1.0"] = "BSL-1.0",
|
||||
["cc0-1.0"] = "CC0-1.0",
|
||||
["epl-2.0"] = "EPL-2.0",
|
||||
["gpl-2.0"] = "GPL-2.0",
|
||||
["gpl-3.0"] = "GPL-3.0",
|
||||
["mpl-2.0"] = "MPL-2.0",
|
||||
zlib = "zlib",
|
||||
mit = "MIT",
|
||||
}
|
||||
local license = licenses[key]
|
||||
if license then
|
||||
return license
|
||||
end
|
||||
|
||||
local url = string.format("https://api.github.com/licenses/%s", key)
|
||||
local tmpfile = os.tmpfile({ramdisk = false})
|
||||
local ok = try { function () http.download(url, tmpfile); return true end }
|
||||
if not ok then
|
||||
os.tryrm(tmpfile)
|
||||
return nil
|
||||
end
|
||||
local license_detail = json.loadfile(tmpfile)
|
||||
license = license_detail["spdx_id"]
|
||||
os.tryrm(tmpfile)
|
||||
return license
|
||||
end
|
||||
|
||||
function generate_package(reponame, get_data)
|
||||
local repo_data = get_data(reponame)
|
||||
local data = repo_data.data
|
||||
local host = repo_data.host
|
||||
|
||||
-- generate package header
|
||||
local packagename = assert(data.name, "package name not found!"):lower()
|
||||
local packagefile = path.join("packages", string.sub(packagename, 1, 1), packagename, "xmake.lua")
|
||||
local file = io.open(packagefile, "w")
|
||||
|
||||
-- define package and homepage
|
||||
file:print('package("%s")', packagename)
|
||||
local homepage = data.homepageUrl and data.homepageUrl ~= "" and data.homepageUrl or data.url
|
||||
if homepage then
|
||||
file:print(' set_homepage("%s")', homepage)
|
||||
end
|
||||
|
||||
local description = data.description or ("The " .. packagename .. " package")
|
||||
file:print(' set_description("%s")', description)
|
||||
|
||||
-- define license if available
|
||||
if type(data.licenseInfo) == "table" and data.licenseInfo.key then
|
||||
local license = get_license_spdx_id(data.licenseInfo.key)
|
||||
if license then
|
||||
file:print(' set_license("%s")', license)
|
||||
end
|
||||
end
|
||||
file:print("")
|
||||
|
||||
-- define package URLs and versions
|
||||
local repodir
|
||||
local has_xmake, has_cmake, has_meson, has_bazel, has_autoconf, need_autogen
|
||||
local latest_release = data.latestRelease
|
||||
|
||||
if type(latest_release) == "table" then
|
||||
local url = string.format("https://%s/%s/archive/refs/tags/%s.tar.gz", host, reponame, latest_release.tagName)
|
||||
local giturl = string.format("https://%s/%s.git", host, reponame)
|
||||
local tmpfile = os.tmpfile({ramdisk = false}) .. ".tar.gz"
|
||||
repodir = tmpfile .. ".dir"
|
||||
|
||||
file:write(' add_urls("https://' .. host .. '/' .. reponame .. '/archive/refs/tags/$(version).tar.gz",\n')
|
||||
file:print(' "%s")\n', giturl)
|
||||
|
||||
print("downloading %s", url)
|
||||
http.download(url, tmpfile)
|
||||
|
||||
file:print(' add_versions("%s", "%s")', latest_release.tagName, hash.sha256(tmpfile))
|
||||
archive.extract(tmpfile, repodir)
|
||||
os.rm(tmpfile)
|
||||
else
|
||||
local giturl = string.format("https://%s/%s.git", host, reponame)
|
||||
repodir = os.tmpfile({ ramdisk = false })
|
||||
|
||||
file:print(' add_urls("%s")', giturl)
|
||||
|
||||
print("downloading %s", giturl)
|
||||
git.clone(giturl, { outputdir = repodir, depth = 1 })
|
||||
|
||||
local commit = git.lastcommit({ repodir = repodir })
|
||||
local version = try {
|
||||
function()
|
||||
return os.iorunv("git", {
|
||||
"log",
|
||||
"-1",
|
||||
"--date=format:%Y.%m.%d",
|
||||
"--format=%ad",
|
||||
}, { curdir = repodir })
|
||||
end
|
||||
}
|
||||
if version then
|
||||
file:print(' add_versions("%s", "%s")', version:trim(), commit)
|
||||
end
|
||||
end
|
||||
|
||||
local build_systems = {
|
||||
["xmake.lua"] = {
|
||||
deps = {},
|
||||
priority = 1,
|
||||
install = function(configs, package)
|
||||
return ([=[
|
||||
io.writefile("xmake.lua", [[
|
||||
add_rules("mode.release", "mode.debug")
|
||||
target("%s")
|
||||
set_kind("$(kind)")
|
||||
add_files("src/*.c")
|
||||
add_headerfiles("src/(*.h)")
|
||||
]])
|
||||
import("package.tools.xmake").install(package)]=]):format(packagename)
|
||||
end,
|
||||
},
|
||||
["CMakeLists.txt"] = {
|
||||
deps = {"cmake"},
|
||||
priority = 2,
|
||||
install = function(configs, package)
|
||||
return [[
|
||||
table.insert(configs, "-DCMAKE_BUILD_TYPE=" .. (package:is_debug() and "Debug" or "Release"))
|
||||
table.insert(configs, "-DBUILD_SHARED_LIBS=" .. (package:config("shared") and "ON" or "OFF"))
|
||||
import("package.tools.cmake").install(package, configs)]]
|
||||
end,
|
||||
},
|
||||
["configure,configure.ac,autogen.sh"] = {
|
||||
deps = {"autoconf", "automake", "libtool"},
|
||||
priority = 3,
|
||||
install = function(configs, package)
|
||||
return [[
|
||||
table.insert(configs, "--enable-shared=" .. (package:config("shared") and "yes" or "no"))
|
||||
if package:is_debug() then
|
||||
table.insert(configs, "--enable-debug")
|
||||
end
|
||||
import("package.tools.autoconf").install(package, configs)]]
|
||||
end,
|
||||
},
|
||||
["meson.build"] = {
|
||||
deps = {"meson", "ninja"},
|
||||
priority = 4,
|
||||
install = function(configs, package)
|
||||
return [[
|
||||
table.insert(configs, "-Ddefault_library=" .. (package:config("shared") and "shared" or "static"))
|
||||
import("package.tools.meson").install(package, configs)]]
|
||||
end,
|
||||
},
|
||||
["BUILD,BUILD.bazel"] = {
|
||||
deps = {"bazel"},
|
||||
priority = 5,
|
||||
install = function(configs, package)
|
||||
return [[
|
||||
import("package.tools.bazel").install(package, configs)]]
|
||||
end,
|
||||
}
|
||||
}
|
||||
|
||||
-- detect build system
|
||||
local build_system_detected = {}
|
||||
if repodir then
|
||||
local files = os.files(path.join(repodir, "*")) or {}
|
||||
table.join2(files, os.files(path.join(repodir, "*", "*")))
|
||||
for _, file in ipairs(files) do
|
||||
local filename = path.filename(file)
|
||||
for k, v in pairs(build_systems) do
|
||||
local filenames = hashset.from(k:split(","))
|
||||
if filenames:has(filename) then
|
||||
table.insert(build_system_detected, v)
|
||||
end
|
||||
end
|
||||
end
|
||||
os.rm(repodir)
|
||||
end
|
||||
local build_system
|
||||
if #build_system_detected > 0 then
|
||||
table.sort(build_system_detected, function (a, b) return a.priority < b.priority end)
|
||||
build_system = build_system_detected[1]
|
||||
end
|
||||
if not build_system then
|
||||
build_system = build_systems["xmake.lua"]
|
||||
end
|
||||
|
||||
-- add dependencies
|
||||
if build_system then
|
||||
local deps = table.wrap(build_system.deps)
|
||||
if deps and #deps > 0 then
|
||||
file:print('')
|
||||
file:print(' add_deps("' .. table.concat(deps, '", "') .. '")')
|
||||
end
|
||||
end
|
||||
|
||||
-- generate install scripts
|
||||
file:print('')
|
||||
file:print(' on_install(function (package)')
|
||||
file:print(' local configs = {}')
|
||||
if build_system then
|
||||
file:print(build_system.install(configs, package))
|
||||
end
|
||||
file:print(' end)')
|
||||
|
||||
-- generate test scripts
|
||||
file:print('')
|
||||
file:print(' on_test(function (package)')
|
||||
file:print(' assert(package:has_cfuncs("foo", {includes = "foo.h"}))')
|
||||
file:print(' end)')
|
||||
file:close()
|
||||
|
||||
io.cat(packagefile)
|
||||
cprint("${bright}%s generated!", packagefile)
|
||||
end
|
||||
|
||||
function main(...)
|
||||
local opt = option.parse(table.pack(...), options, "New a package.", "", "Usage: xmake l scripts/new.lua [options]")
|
||||
local repo = assert(opt.repo, "repository name must be set!")
|
||||
local reponame = repo:sub(8)
|
||||
|
||||
if repo:startswith("github:") then
|
||||
generate_package(reponame, get_github_data)
|
||||
return
|
||||
end
|
||||
|
||||
if repo:startswith("gitlab:") then
|
||||
generate_package(reponame, get_gitlab_data)
|
||||
return
|
||||
end
|
||||
|
||||
raise("unsupported repository source. only 'github' and 'gitlab' are supported.")
|
||||
end
|
||||
71
scripts/packages.lua
Normal file
71
scripts/packages.lua
Normal file
@@ -0,0 +1,71 @@
|
||||
-- imports
|
||||
import("core.package.package")
|
||||
import("core.platform.platform")
|
||||
import("private.core.base.select_script")
|
||||
|
||||
-- is supported platform and architecture?
|
||||
function is_supported(instance, plat, arch, opt)
|
||||
opt = opt or {}
|
||||
if instance:is_template() then
|
||||
return false
|
||||
end
|
||||
|
||||
local script = instance:get(instance:is_fetchonly() and "fetch" or "install")
|
||||
if not select_script(script, {plat = plat, arch = arch}) then
|
||||
if opt.native and select_script(script, {
|
||||
plat = plat, arch = arch, subhost = plat, subarch = arch}) then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
-- load package
|
||||
function _load_package(packagename, packagedir, packagefile)
|
||||
local funcinfo = debug.getinfo(package.load_from_repository)
|
||||
if funcinfo and funcinfo.nparams == 3 then -- >= 2.7.8
|
||||
return package.load_from_repository(packagename, packagedir, {packagefile = packagefile})
|
||||
else
|
||||
-- deprecated
|
||||
return package.load_from_repository(packagename, nil, packagedir, packagefile)
|
||||
end
|
||||
end
|
||||
|
||||
-- the main entry
|
||||
function main(opt)
|
||||
opt = opt or {}
|
||||
local packages = {}
|
||||
for _, packagedir in ipairs(os.dirs(path.join("packages", "*", "*"))) do
|
||||
local packagename = path.filename(packagedir)
|
||||
local packagefile = path.join(packagedir, "xmake.lua")
|
||||
local instance = _load_package(packagename, packagedir, packagefile)
|
||||
local basename = instance:get("base")
|
||||
if instance and basename then
|
||||
local basedir = path.join("packages", basename:sub(1, 1):lower(), basename:lower())
|
||||
local basefile = path.join(basedir, "xmake.lua")
|
||||
instance._BASE = _load_package(basename, basedir, basefile)
|
||||
end
|
||||
if instance then
|
||||
for _, plat in ipairs({"windows", "linux", "macosx", "iphoneos", "android", "mingw", "msys", "bsd", "wasm", "cross"}) do
|
||||
local archs = platform.archs(plat)
|
||||
if archs then
|
||||
local package_archs = {}
|
||||
for _, arch in ipairs(archs) do
|
||||
if is_supported(instance, plat, arch, opt) then
|
||||
table.insert(package_archs, arch)
|
||||
end
|
||||
end
|
||||
if #package_archs > 0 then
|
||||
packages[plat] = packages[plat] or {}
|
||||
table.insert(packages[plat], {name = instance:name(), instance = instance, archs = package_archs, generic = #package_archs == #archs})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
for _, packages_plat in pairs(packages) do
|
||||
table.sort(packages_plat, function(a, b) return a.name < b.name end)
|
||||
end
|
||||
return packages
|
||||
end
|
||||
16
scripts/sync.lua
Normal file
16
scripts/sync.lua
Normal file
@@ -0,0 +1,16 @@
|
||||
import("core.base.option")
|
||||
|
||||
function main()
|
||||
print("update xmake-repo ..")
|
||||
os.exec("git clone git@github.com:xmake-io/xmake-repo.git -b dev --recurse-submodules")
|
||||
os.cd("xmake-repo")
|
||||
os.exec("git push git@gitlab.com:tboox/xmake-repo.git dev")
|
||||
os.exec("git push git@gitee.com:tboox/xmake-repo.git dev")
|
||||
os.exec("git push git@gitcode.com:xmake-io/xmake-repo.git dev")
|
||||
os.exec("git checkout master")
|
||||
os.exec("git merge dev")
|
||||
os.exec("git push git@github.com:xmake-io/xmake-repo.git master")
|
||||
os.exec("git push git@gitlab.com:tboox/xmake-repo.git master")
|
||||
os.exec("git push git@gitee.com:tboox/xmake-repo.git master")
|
||||
os.exec("git push git@gitcode.com:xmake-io/xmake-repo.git master")
|
||||
end
|
||||
397
scripts/test.lua
Normal file
397
scripts/test.lua
Normal file
@@ -0,0 +1,397 @@
|
||||
-- imports
|
||||
import("core.base.option")
|
||||
import("core.platform.platform")
|
||||
import("core.package.package", {alias = "core_package"})
|
||||
import("packages", {alias = "get_packages"})
|
||||
|
||||
-- the options
|
||||
local options =
|
||||
{
|
||||
{'v', "verbose", "k", nil, "Enable verbose information." }
|
||||
, {'D', "diagnosis", "k", nil, "Enable diagnosis information." }
|
||||
, {nil, "shallow", "k", nil, "Only install the root packages." }
|
||||
, {'k', "kind", "kv", nil, "Enable static/shared library." }
|
||||
, {'p', "plat", "kv", nil, "Set the given platform." }
|
||||
, {'a', "arch", "kv", nil, "Set the given architecture." }
|
||||
, {'m', "mode", "kv", nil, "Set the given mode." }
|
||||
, {'j', "jobs", "kv", nil, "Set the build jobs." }
|
||||
, {'f', "configs", "kv", nil, "Set the configs." }
|
||||
, {'d', "debugdir", "kv", nil, "Set the debug source directory." }
|
||||
, {nil, "policies", "kv", nil, "Set the policies." }
|
||||
, {nil, "fetch", "k", nil, "Fetch package only." }
|
||||
, {nil, "precompiled", "k", nil, "Attemp to install the precompiled package." }
|
||||
, {nil, "remote", "k", nil, "Test package on the remote server." }
|
||||
, {nil, "linkjobs", "kv", nil, "Set the link jobs." }
|
||||
, {nil, "cflags", "kv", nil, "Set the cflags." }
|
||||
, {nil, "cxxflags", "kv", nil, "Set the cxxflags." }
|
||||
, {nil, "ldflags", "kv", nil, "Set the ldflags." }
|
||||
, {nil, "ndk", "kv", nil, "Set the Android NDK directory." }
|
||||
, {nil, "ndk_sdkver", "kv", nil, "Set the Android NDK platform sdk version." }
|
||||
, {nil, "sdk", "kv", nil, "Set the SDK directory of cross toolchain." }
|
||||
, {nil, "vs", "kv", nil, "Set the VS Compiler version." }
|
||||
, {nil, "vs_sdkver", "kv", nil, "Set the Windows SDK version." }
|
||||
, {nil, "vs_toolset", "kv", nil, "Set the Windows Toolset version." }
|
||||
, {nil, "vs_runtime", "kv", nil, "Set the VS Runtime library (deprecated)." }
|
||||
, {nil, "runtimes", "kv", nil, "Set the Runtime libraries." }
|
||||
, {nil, "xcode_sdkver", "kv", nil, "The SDK Version for Xcode" }
|
||||
, {nil, "target_minver", "kv", nil, "The Target Minimal Version" }
|
||||
, {nil, "appledev", "kv", nil, "The Apple Device Type" }
|
||||
, {nil, "mingw", "kv", nil, "Set the MingW directory." }
|
||||
, {nil, "toolchain", "kv", nil, "Set the toolchain name." }
|
||||
, {nil, "toolchain_host", "kv", nil, "Set the host toolchain name." }
|
||||
, {nil, "packages", "vs", nil, "The package list." }
|
||||
}
|
||||
|
||||
-- check package is supported?
|
||||
function _check_package_is_supported()
|
||||
for _, names in pairs(core_package.apis()) do
|
||||
for _, name in ipairs(names) do
|
||||
if type(name) == "string" and name == "package.on_check" then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- config packages
|
||||
function _config_packages(argv, packages)
|
||||
local config_argv = {"f", "-c"}
|
||||
if argv.verbose then
|
||||
table.insert(config_argv, "-v")
|
||||
end
|
||||
if argv.diagnosis then
|
||||
table.insert(config_argv, "-D")
|
||||
end
|
||||
if argv.plat then
|
||||
table.insert(config_argv, "--plat=" .. argv.plat)
|
||||
end
|
||||
if argv.arch then
|
||||
table.insert(config_argv, "--arch=" .. argv.arch)
|
||||
end
|
||||
if argv.mode then
|
||||
table.insert(config_argv, "--mode=" .. argv.mode)
|
||||
end
|
||||
if argv.policies then
|
||||
table.insert(config_argv, "--policies=" .. argv.policies)
|
||||
end
|
||||
if argv.ndk then
|
||||
table.insert(config_argv, "--ndk=" .. argv.ndk)
|
||||
end
|
||||
if argv.sdk then
|
||||
table.insert(config_argv, "--sdk=" .. argv.sdk)
|
||||
end
|
||||
if argv.ndk_sdkver then
|
||||
table.insert(config_argv, "--ndk_sdkver=" .. argv.ndk_sdkver)
|
||||
end
|
||||
if argv.vs then
|
||||
table.insert(config_argv, "--vs=" .. argv.vs)
|
||||
end
|
||||
if argv.vs_sdkver then
|
||||
table.insert(config_argv, "--vs_sdkver=" .. argv.vs_sdkver)
|
||||
end
|
||||
if argv.vs_toolset then
|
||||
table.insert(config_argv, "--vs_toolset=" .. argv.vs_toolset)
|
||||
end
|
||||
local runtimes = argv.runtimes or argv.vs_runtime
|
||||
if runtimes then
|
||||
if is_host("windows") then
|
||||
table.insert(config_argv, "--vs_runtime=" .. runtimes)
|
||||
else
|
||||
table.insert(config_argv, "--runtimes=" .. runtimes)
|
||||
end
|
||||
end
|
||||
if argv.xcode_sdkver then
|
||||
table.insert(config_argv, "--xcode_sdkver=" .. argv.xcode_sdkver)
|
||||
end
|
||||
if argv.target_minver then
|
||||
table.insert(config_argv, "--target_minver=" .. argv.target_minver)
|
||||
end
|
||||
if argv.appledev then
|
||||
table.insert(config_argv, "--appledev=" .. argv.appledev)
|
||||
end
|
||||
if argv.mingw then
|
||||
table.insert(config_argv, "--mingw=" .. argv.mingw)
|
||||
end
|
||||
if argv.toolchain then
|
||||
table.insert(config_argv, "--toolchain=" .. argv.toolchain)
|
||||
end
|
||||
if argv.toolchain_host then
|
||||
table.insert(config_argv, "--toolchain_host=" .. argv.toolchain_host)
|
||||
end
|
||||
if argv.cflags then
|
||||
table.insert(config_argv, "--cflags=" .. argv.cflags)
|
||||
end
|
||||
if argv.cxxflags then
|
||||
table.insert(config_argv, "--cxxflags=" .. argv.cxxflags)
|
||||
end
|
||||
if argv.ldflags then
|
||||
table.insert(config_argv, "--ldflags=" .. argv.ldflags)
|
||||
end
|
||||
os.vexecv(os.programfile(), config_argv)
|
||||
end
|
||||
|
||||
-- get extra string
|
||||
function _get_extra_str(argv)
|
||||
local extra = {}
|
||||
if argv.mode == "debug" then
|
||||
extra.debug = true
|
||||
end
|
||||
-- Some packages set shared=true as default, so we need to force set
|
||||
-- shared=false to test static build.
|
||||
extra.configs = extra.configs or {}
|
||||
extra.configs.shared = argv.kind == "shared"
|
||||
local configs = argv.configs
|
||||
if configs then
|
||||
extra.system = false
|
||||
extra.configs = extra.configs or {}
|
||||
local extra_configs, errors = ("{" .. configs .. "}"):deserialize()
|
||||
if extra_configs then
|
||||
table.join2(extra.configs, extra_configs)
|
||||
else
|
||||
raise(errors)
|
||||
end
|
||||
end
|
||||
return string.serialize(extra, {indent = false, strip = true})
|
||||
end
|
||||
|
||||
-- load packages
|
||||
function _load_packages(argv, packages)
|
||||
_config_packages(argv, packages)
|
||||
local info_argv = {"require", "-f", "-y", "--info"}
|
||||
if argv.verbose then
|
||||
table.insert(info_argv, "-v")
|
||||
end
|
||||
if argv.diagnosis then
|
||||
table.insert(info_argv, "-D")
|
||||
end
|
||||
local extra_str = _get_extra_str(argv)
|
||||
table.insert(info_argv, "--extra=" .. extra_str)
|
||||
|
||||
-- call `xrepo info` to test on_load
|
||||
if #packages > 0 then
|
||||
print("testing to load packages ...")
|
||||
print(" > if it causes errors, please remove assert/raise() to on_check.")
|
||||
os.vexecv(os.programfile(), table.join(info_argv, packages))
|
||||
end
|
||||
end
|
||||
|
||||
-- require packages
|
||||
function _require_packages(argv, packages)
|
||||
_config_packages(argv, packages)
|
||||
local require_argv = {"require", "-f", "-y"}
|
||||
local check_argv = {"require", "-f", "-y", "--check"}
|
||||
if not argv.precompiled then
|
||||
table.insert(require_argv, "--build")
|
||||
end
|
||||
if argv.verbose then
|
||||
table.insert(require_argv, "-v")
|
||||
table.insert(check_argv, "-v")
|
||||
end
|
||||
if argv.diagnosis then
|
||||
table.insert(require_argv, "-D")
|
||||
table.insert(check_argv, "-D")
|
||||
end
|
||||
local is_debug = false
|
||||
if argv.debugdir then
|
||||
is_debug = true
|
||||
table.insert(require_argv, "--debugdir=" .. argv.debugdir)
|
||||
end
|
||||
if argv.shallow or is_debug then
|
||||
table.insert(require_argv, "--shallow")
|
||||
end
|
||||
if argv.jobs then
|
||||
table.insert(require_argv, "--jobs=" .. argv.jobs)
|
||||
end
|
||||
if argv.linkjobs then
|
||||
table.insert(require_argv, "--linkjobs=" .. argv.linkjobs)
|
||||
end
|
||||
if argv.fetch then
|
||||
table.insert(require_argv, "--fetch")
|
||||
end
|
||||
local extra_str = _get_extra_str(argv)
|
||||
table.insert(require_argv, "--extra=" .. extra_str)
|
||||
table.insert(check_argv, "--extra=" .. extra_str)
|
||||
|
||||
-- test on_check
|
||||
local install_packages = {}
|
||||
if _check_package_is_supported() then
|
||||
print("testing to check packages ...")
|
||||
for _, package in ipairs(packages) do
|
||||
local ok = os.vexecv(os.programfile(), table.join(check_argv, package), {try = true})
|
||||
if ok == 0 then
|
||||
table.insert(install_packages, package)
|
||||
end
|
||||
end
|
||||
else
|
||||
install_packages = packages
|
||||
end
|
||||
|
||||
-- test installation
|
||||
if #install_packages > 0 then
|
||||
print("testing to install packages ...")
|
||||
os.vexecv(os.programfile(), table.join(require_argv, install_packages))
|
||||
else
|
||||
print("no testable packages on %s or you're using lower version xmake!", argv.plat or os.subhost())
|
||||
end
|
||||
end
|
||||
|
||||
-- the given package is supported?
|
||||
function _package_is_supported(argv, packagename)
|
||||
local packages = get_packages()
|
||||
if packages then
|
||||
local plat = argv.plat or os.subhost()
|
||||
local packages_plat = packages[plat]
|
||||
for _, package in ipairs(packages_plat) do
|
||||
if package and packagename:split("%s+")[1] == package.name then
|
||||
local arch = argv.arch
|
||||
if not arch and plat ~= os.subhost() then
|
||||
arch = table.wrap(platform.archs(plat))[1]
|
||||
end
|
||||
if not arch then
|
||||
arch = os.subarch()
|
||||
end
|
||||
for _, package_arch in ipairs(package.archs) do
|
||||
print(package_arch, package.archs)
|
||||
if arch == package_arch then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function append_package_version(packages, line)
|
||||
local version = line:match("add_versions%(\"(.-)\"") or line:match("package:add%(\"versions\",%s*\"(.-)\"")
|
||||
if version then
|
||||
if version:find(":", 1, true) then
|
||||
version = version:split(":")[2]
|
||||
end
|
||||
if #packages > 0 and version then
|
||||
local lastpackage = packages[#packages]
|
||||
local splitinfo = lastpackage:split("%s+")
|
||||
table.insert(packages, splitinfo[1] .. " " .. version)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function get_modified_packages()
|
||||
local new_packages = {}
|
||||
local old_packages = {}
|
||||
local diff = os.iorun("git --no-pager diff HEAD^")
|
||||
for _, line in ipairs(diff:split("\n")) do
|
||||
if line:startswith("+++ b/") then
|
||||
local file = line:sub(7)
|
||||
if file:startswith("packages") then
|
||||
assert(file == file:lower(), "%s must be lower case!", file)
|
||||
local package = file:match("packages/%w/(%S-)/")
|
||||
table.insert(new_packages, package)
|
||||
table.insert(old_packages, package)
|
||||
end
|
||||
elseif line:startswith("+") and (line:find("add_versions", 1, true) or line:find("package:add(\"versions\"", 1, true)) then
|
||||
append_package_version(new_packages, line)
|
||||
elseif line:startswith("-") and (line:find("add_versions", 1, true) or line:find("package:add(\"versions\"", 1, true)) then
|
||||
append_package_version(old_packages, line)
|
||||
end
|
||||
end
|
||||
if #old_packages > 0 then
|
||||
table.remove_if(old_packages, function (_, package)
|
||||
local splitinfo = package:split("%s+")
|
||||
return #splitinfo == 1
|
||||
end)
|
||||
table.remove_if(new_packages, function (_, package)
|
||||
return table.contains(old_packages, package)
|
||||
end)
|
||||
-- {
|
||||
-- "pkgname", <-- remove this
|
||||
-- "pkgname pkgver"
|
||||
-- }
|
||||
for i = #new_packages - 1, 1, -1 do
|
||||
if new_packages[i + 1]:startswith(new_packages[i] .. " ") then
|
||||
table.remove(new_packages, i)
|
||||
end
|
||||
end
|
||||
end
|
||||
return table.unique(new_packages)
|
||||
end
|
||||
|
||||
-- @see https://github.com/xmake-io/xmake-repo/issues/6940
|
||||
function _lock_packages(packages)
|
||||
local locked_packages = {}
|
||||
for _, package in ipairs(packages) do
|
||||
if table.contains(locked_packages, package) then
|
||||
raise("package(%s) has been locked, please do not submit it, @see https://github.com/xmake-io/xmake-repo/issues/6940", package)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- the main entry
|
||||
function main(...)
|
||||
|
||||
-- parse arguments
|
||||
local argv = option.parse({...}, options, "Test all the given or changed packages.")
|
||||
|
||||
-- get packages
|
||||
local packages = argv.packages or {}
|
||||
if #packages == 0 then
|
||||
packages = get_modified_packages()
|
||||
end
|
||||
if #packages == 0 then
|
||||
table.insert(packages, "tbox dev")
|
||||
end
|
||||
|
||||
-- prepare test project
|
||||
local repodir = os.curdir()
|
||||
local workdir = path.join(os.tmpdir(), "xmake-repo")
|
||||
print(packages)
|
||||
os.setenv("XMAKE_STATS", "false")
|
||||
if not os.isfile(path.join(workdir, "test", "xmake.lua")) then
|
||||
os.tryrm(workdir)
|
||||
os.mkdir(workdir)
|
||||
os.cd(workdir)
|
||||
os.execv(os.programfile(), {"create", "test"})
|
||||
else
|
||||
os.cd(workdir)
|
||||
end
|
||||
os.cd("test")
|
||||
print(os.curdir())
|
||||
-- do action for remote?
|
||||
if os.isdir("xmake-repo") then
|
||||
os.execv(os.programfile(), {"service", "--disconnect"})
|
||||
end
|
||||
if argv.remote then
|
||||
os.tryrm("xmake-repo")
|
||||
os.cp(path.join(repodir, "packages"), "xmake-repo/packages")
|
||||
os.execv(os.programfile(), {"service", "--connect"})
|
||||
repodir = "xmake-repo"
|
||||
end
|
||||
os.execv(os.programfile(), {"repo", "--add", "local-repo", repodir})
|
||||
os.execv(os.programfile(), {"repo", "-l"})
|
||||
|
||||
local packages_original = table.clone(packages)
|
||||
|
||||
-- load packages
|
||||
_load_packages(argv, packages_original)
|
||||
|
||||
local old_dir = os.cd(repodir)
|
||||
-- remove unsupported packages
|
||||
for idx, package in irpairs(packages) do
|
||||
assert(package == package:lower(), "package(%s) must be lower case!", package)
|
||||
if not _package_is_supported(argv, package) then
|
||||
table.remove(packages, idx)
|
||||
end
|
||||
end
|
||||
os.cd(old_dir)
|
||||
|
||||
-- no testable packages
|
||||
if #packages == 0 then
|
||||
print("no testable packages on %s!", argv.plat or os.subhost())
|
||||
return
|
||||
end
|
||||
|
||||
-- lock packages
|
||||
-- _lock_packages(packages)
|
||||
|
||||
-- require packages
|
||||
_require_packages(argv, packages)
|
||||
end
|
||||
Reference in New Issue
Block a user