summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2021-02-13 00:39:27 +0800
committerruki <[email protected]>2021-02-13 00:39:27 +0800
commit5d26d21e31b9ba443208f1f027b5ac8b6cdc44df (patch)
tree94eab07b083797ef561102759679a1893cee0511
parente66d6878040a80e6512db851750185b8ab35b127 (diff)
split impl.package
-rw-r--r--xmake/modules/private/action/require/export.lua4
-rw-r--r--xmake/modules/private/action/require/impl/export_packages.lua52
-rw-r--r--xmake/modules/private/action/require/impl/install_packages.lua393
-rw-r--r--xmake/modules/private/action/require/impl/package.lua448
-rw-r--r--xmake/modules/private/action/require/impl/register_packages.lua125
-rw-r--r--xmake/modules/private/action/require/impl/search_packages.lua50
-rw-r--r--xmake/modules/private/action/require/impl/uninstall_packages.lua47
-rw-r--r--xmake/modules/private/action/require/install.lua4
-rw-r--r--xmake/modules/private/action/require/search.lua4
-rw-r--r--xmake/modules/private/action/require/uninstall.lua4
10 files changed, 675 insertions, 456 deletions
diff --git a/xmake/modules/private/action/require/export.lua b/xmake/modules/private/action/require/export.lua
index 218a669c6..ef1ecf011 100644
--- a/xmake/modules/private/action/require/export.lua
+++ b/xmake/modules/private/action/require/export.lua
@@ -21,9 +21,9 @@
-- imports
import("core.base.task")
import("core.base.option")
-import("private.action.require.impl.package")
import("private.action.require.impl.repository")
import("private.action.require.impl.environment")
+import("private.action.require.impl.export_packages")
import("private.action.require.impl.utils.get_requires")
-- export the given packages
@@ -46,7 +46,7 @@ function main(requires_raw)
-- export packages
local exportdir = option.get("exportdir")
- local packages = package.export_packages(requires, {requires_extra = requires_extra, exportdir = exportdir})
+ local packages = export_packages(requires, {requires_extra = requires_extra, exportdir = exportdir})
for _, instance in ipairs(packages) do
print("export: %s%s ok!", instance:name(), instance:version_str() and ("-" .. instance:version_str()) or "")
end
diff --git a/xmake/modules/private/action/require/impl/export_packages.lua b/xmake/modules/private/action/require/impl/export_packages.lua
new file mode 100644
index 000000000..a169a163f
--- /dev/null
+++ b/xmake/modules/private/action/require/impl/export_packages.lua
@@ -0,0 +1,52 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file export_packages.lua
+--
+
+-- imports
+import("private.action.require.impl.package")
+
+-- export packages
+function main(requires, opt)
+
+ -- init options
+ opt = opt or {}
+
+ -- get the export directory
+ local exportdir = assert(opt.exportdir)
+
+ -- export all packages
+ local packages = {}
+ for _, instance in ipairs(package.load_packages(requires, opt)) do
+
+ -- get the exported name
+ local name = instance:name():lower():gsub("::", "_")
+ if instance:version_str() then
+ name = name .. "_" .. instance:version_str()
+ end
+ name = name .. "_" .. instance:buildhash()
+
+ -- export this package
+ if instance:fetch() then
+ os.cp(instance:installdir(), path.join(exportdir, name))
+ table.insert(packages, instance)
+ end
+ end
+ return packages
+end
+
diff --git a/xmake/modules/private/action/require/impl/install_packages.lua b/xmake/modules/private/action/require/impl/install_packages.lua
new file mode 100644
index 000000000..295c3bbbd
--- /dev/null
+++ b/xmake/modules/private/action/require/impl/install_packages.lua
@@ -0,0 +1,393 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file install_packages.lua
+--
+
+-- imports
+import("core.base.option")
+import("core.base.hashset")
+import("core.base.scheduler")
+import("core.base.tty")
+import("private.async.runjobs")
+import("private.utils.progress")
+import("actions.install", {alias = "action_install"})
+import("actions.download", {alias = "action_download"})
+import("net.fasturl")
+import("private.action.require.impl.package")
+
+-- sort packages urls
+function _sort_packages_urls(packages)
+
+ -- add all urls to fasturl and prepare to sort them together
+ for _, instance in pairs(packages) do
+ fasturl.add(instance:urls())
+ end
+
+ -- sort and update urls
+ for _, instance in pairs(packages) do
+ instance:urls_set(fasturl.sort(instance:urls()))
+ end
+end
+
+-- get package parents string
+function _get_package_parents_str(instance)
+ local parents = instance:parents()
+ if parents then
+ local parentnames = {}
+ for _, parent in pairs(parents) do
+ table.insert(parentnames, parent:displayname())
+ end
+ if #parentnames == 0 then
+ return
+ end
+ return table.concat(parentnames, ",")
+ end
+end
+
+-- get package configs string
+function _get_package_configs_str(instance)
+ local configs = {}
+ if instance:optional() then
+ table.insert(configs, "optional")
+ end
+ local requireinfo = instance:requireinfo()
+ if requireinfo then
+ for k, v in pairs(requireinfo.configs) do
+ if type(v) == "boolean" then
+ table.insert(configs, k .. ":" .. (v and "y" or "n"))
+ else
+ table.insert(configs, k .. ":" .. v)
+ end
+ end
+ end
+ local parents_str = _get_package_parents_str(instance)
+ if parents_str then
+ table.insert(configs, "from:" .. parents_str)
+ end
+ local configs_str = #configs > 0 and "[" .. table.concat(configs, ", ") .. "]" or ""
+ local limitwidth = os.getwinsize().width * 2 / 3
+ if #configs_str > limitwidth then
+ configs_str = configs_str:sub(1, limitwidth) .. " ..)"
+ end
+ return configs_str
+end
+
+-- get user confirm
+function _get_confirm(packages)
+
+ -- no confirmed packages?
+ if #packages == 0 then
+ return true
+ end
+
+ -- get confirm
+ local confirm = utils.confirm({default = true, description = function ()
+
+ -- get packages for each repositories
+ local packages_repo = {}
+ local packages_group = {}
+ for _, instance in ipairs(packages) do
+ -- achive packages by repository
+ local reponame = instance:repo() and instance:repo():name() or (instance:isSys() and "system" or "")
+ if instance:is3rd() then
+ reponame = instance:name():lower():split("::")[1]
+ end
+ packages_repo[reponame] = packages_repo[reponame] or {}
+ table.insert(packages_repo[reponame], instance)
+
+ -- achive packages by group
+ local group = instance:group()
+ if group then
+ packages_group[group] = packages_group[group] or {}
+ table.insert(packages_group[group], instance)
+ end
+ end
+
+ -- show tips
+ cprint("${bright color.warning}note: ${clear}try installing these packages (pass -y to skip confirm)?")
+ for reponame, packages in pairs(packages_repo) do
+ if reponame ~= "" then
+ print("in %s:", reponame)
+ end
+ local packages_showed = {}
+ for _, instance in ipairs(packages) do
+ if not packages_showed[tostring(instance)] then
+ local group = instance:group()
+ if group and packages_group[group] and #packages_group[group] > 1 then
+ for idx, package_in_group in ipairs(packages_group[group]) do
+ cprint(" ${yellow}%s${clear} %s %s ${dim}%s", idx == 1 and "->" or " or", package_in_group:displayname(), package_in_group:version_str() or "", _get_package_configs_str(package_in_group))
+ packages_showed[tostring(package_in_group)] = true
+ end
+ packages_group[group] = nil
+ else
+ cprint(" ${yellow}->${clear} %s %s ${dim}%s", instance:displayname(), instance:version_str() or "", _get_package_configs_str(instance))
+ packages_showed[tostring(instance)] = true
+ end
+ end
+ end
+ end
+ end})
+ return confirm
+end
+
+-- install packages
+function _install_packages(packages_install, packages_download)
+
+ -- we need hide wait characters if is not a tty
+ local show_wait = io.isatty()
+
+ -- do install
+ local progress_helper = show_wait and progress.new() or nil
+ local packages_installing = {}
+ local packages_downloading = {}
+ local packages_pending = table.copy(packages_install)
+ local packages_in_group = {}
+ local installing_count = 0
+ local parallelize = true
+ runjobs("install_packages", function (index)
+
+ -- fetch a new package
+ local instance = nil
+ while instance == nil and #packages_pending > 0 do
+ for idx, pkg in ipairs(packages_pending) do
+
+ -- all dependences has been installed? we install it now
+ local ready = true
+ local dep_not_found = nil
+ for _, dep in ipairs(pkg:orderdeps()) do
+ if not dep:exists() then
+ ready = false
+ dep_not_found = dep
+ break
+ end
+ end
+ local group = pkg:group()
+ if ready and group then
+ -- this group has been installed? skip it
+ local group_status = packages_in_group[group]
+ if group_status == 1 then
+ table.remove(packages_pending, idx)
+ break
+ -- this group is installing? wait it
+ elseif group_status == 0 then
+ ready = false
+ end
+ end
+
+ -- get a package with the ready status
+ if ready then
+ instance = pkg
+ table.remove(packages_pending, idx)
+ break
+ elseif installing_count == 0 then
+ if #packages_pending == 1 and dep_not_found then
+ raise("package(%s): cannot be installed, there are dependencies(%s) that cannot be installed!", pkg:displayname(), dep_not_found:displayname())
+ elseif #packages_pending == 1 then
+ raise("package(%s): cannot be installed!", pkg:displayname())
+ end
+ end
+ end
+ if instance == nil and #packages_pending > 0 then
+ scheduler.co_yield()
+ end
+ end
+ if instance then
+
+ -- only install the first package in same group
+ local group = instance:group()
+ if not group or not packages_in_group[group] then
+
+ -- disable parallelize?
+ if not instance:parallelize() then
+ parallelize = false
+ end
+ if not parallelize then
+ while installing_count > 0 do
+ scheduler.co_yield()
+ end
+ end
+ installing_count = installing_count + 1
+
+ -- mark this group as 'installing'
+ if group then
+ packages_in_group[group] = 0
+ end
+
+ -- download this package first
+ local downloaded = true
+ if packages_download[tostring(instance)] then
+ packages_downloading[index] =instance
+ downloaded = action_download(instance)
+ packages_downloading[index] = nil
+ end
+
+ -- install this package
+ packages_installing[index] =instance
+ if downloaded then
+ action_install(instance)
+ end
+ packages_installing[index] = nil
+
+ -- mark this group as 'installed' or 'failed'
+ if group then
+ packages_in_group[group] = instance:exists() and 1 or -1
+ end
+
+ -- enable parallelize
+ parallelize = true
+ installing_count = installing_count - 1
+ end
+ end
+ packages_installing[index] = nil
+ packages_downloading[index] = nil
+
+ end, {total = #packages_install, comax = (option.get("verbose") or option.get("diagnosis")) and 1 or 4, on_timer = function (running_jobs_indices)
+
+ -- do not print progress info if be verbose
+ if option.get("verbose") or not show_wait then
+ return
+ end
+
+ -- make installing and downloading packages list
+ local installing = {}
+ local downloading = {}
+ for _, index in ipairs(running_jobs_indices) do
+ local instance = packages_installing[index]
+ if instance then
+ table.insert(installing, instance:displayname())
+ end
+ local instance = packages_downloading[index]
+ if instance then
+ table.insert(downloading, instance:displayname())
+ end
+ end
+
+ -- get waitobjs tips
+ local tips = nil
+ local waitobjs = scheduler.co_group_waitobjs("install_packages")
+ if waitobjs:size() > 0 then
+ local names = {}
+ for _, obj in waitobjs:keys() do
+ if obj:otype() == scheduler.OT_PROC then
+ table.insert(names, obj:name())
+ elseif obj:otype() == scheduler.OT_SOCK then
+ table.insert(names, "sock")
+ elseif obj:otype() == scheduler.OT_PIPE then
+ table.insert(names, "pipe")
+ end
+ end
+ names = table.unique(names)
+ if #names > 0 then
+ names = table.concat(names, ",")
+ if #names > 16 then
+ names = names:sub(1, 16) .. ".."
+ end
+ tips = string.format("(%d/%s)", waitobjs:size(), names)
+ end
+ end
+
+ -- trace
+ progress_helper:clear()
+ tty.erase_line_to_start().cr()
+ cprintf("${yellow} => ")
+ if #downloading > 0 then
+ cprintf("downloading ${magenta}%s", table.concat(downloading, ", "))
+ end
+ if #installing > 0 then
+ cprintf("%sinstalling ${magenta}%s", #downloading > 0 and ", " or "", table.concat(installing, ", "))
+ end
+ cprintf(" .. %s", tips and ("${dim}" .. tips .. "${clear} ") or "")
+ progress_helper:write()
+ end, exit = function(errors)
+ if errors then
+ tty.erase_line_to_start().cr()
+ io.flush()
+ end
+ end})
+end
+
+-- install packages
+function main(requires, opt)
+
+ -- init options
+ opt = opt or {}
+
+ -- load packages
+ local packages = package.load_packages(requires, opt)
+
+ -- fetch packages (with system) from local first
+ runjobs("fetch_packages", function (index)
+ local instance = packages[index]
+ if instance and (not option.get("force") or (option.get("shallow") and instance:parents())) then
+ instance:envs_enter()
+ instance:fetch()
+ instance:envs_leave()
+ end
+ end, {total = #packages})
+
+ -- filter packages
+ local packages_install = {}
+ local packages_download = {}
+ local packages_unsupported = {}
+ for _, instance in ipairs(packages) do
+ if not instance:exists() then
+ if instance:supported() then
+ if #instance:urls() > 0 then
+ packages_download[tostring(instance)] =instance
+ end
+ table.insert(packages_install, instance)
+ elseif not instance:optional() then
+ table.insert(packages_unsupported, instance)
+ end
+ end
+ end
+
+ -- exists unsupported packages?
+ if #packages_unsupported > 0 then
+ -- show tips
+ cprint("${bright color.warning}note: ${clear}the following packages are unsupported for $(plat)/$(arch)!")
+ for _, instance in ipairs(packages_unsupported) do
+ print(" -> %s %s", instance:displayname(), instance:version_str() or "")
+ end
+ raise()
+ end
+
+ -- get user confirm
+ if not _get_confirm(packages_install) then
+ local packages_must = {}
+ for _, instance in ipairs(packages_install) do
+ if not instance:optional() then
+ table.insert(packages_must, instance:displayname())
+ end
+ end
+ if #packages_must > 0 then
+ raise("packages(%s): must be installed!", table.concat(packages_must, ", "))
+ else
+ -- continue other actions
+ return
+ end
+ end
+
+ -- sort package urls
+ _sort_packages_urls(packages_download)
+
+ -- install all required packages from repositories
+ _install_packages(packages_install, packages_download)
+ return packages
+end
+
diff --git a/xmake/modules/private/action/require/impl/package.lua b/xmake/modules/private/action/require/impl/package.lua
index a3d69a982..38a3991b4 100644
--- a/xmake/modules/private/action/require/impl/package.lua
+++ b/xmake/modules/private/action/require/impl/package.lua
@@ -22,19 +22,12 @@
import("core.base.semver")
import("core.base.option")
import("core.base.global")
-import("core.base.hashset")
-import("core.base.scheduler")
-import("core.base.tty")
import("private.async.runjobs")
import("private.utils.progress")
import("core.cache.memcache")
-import("core.cache.localcache")
import("core.project.project")
import("core.package.package", {alias = "core_package"})
-import("actions.install", {alias = "action_install"})
-import("actions.download", {alias = "action_download"})
import("devel.git")
-import("net.fasturl")
import("private.action.require.impl.repository")
-- get memcache
@@ -192,19 +185,6 @@ function _load_package_from_repository(packagename, reponame)
end
end
--- search packages from repositories
-function _search_packages(name)
-
- local packages = {}
- for _, packageinfo in ipairs(repository.searchdirs(name)) do
- local package = core_package.load_from_repository(packageinfo.name, packageinfo.repo, packageinfo.packagedir)
- if package then
- table.insert(packages, package)
- end
- end
- return packages
-end
-
-- sort package deps
--
-- e.g.
@@ -645,297 +625,6 @@ function _load_packages(requires, opt)
return packages
end
--- sort packages urls
-function _sort_packages_urls(packages)
-
- -- add all urls to fasturl and prepare to sort them together
- for _, package in pairs(packages) do
- fasturl.add(package:urls())
- end
-
- -- sort and update urls
- for _, package in pairs(packages) do
- package:urls_set(fasturl.sort(package:urls()))
- end
-end
-
--- get package parents string
-function _get_package_parents_str(package)
- local parents = package:parents()
- if parents then
- local parentnames = {}
- for _, parent in pairs(parents) do
- table.insert(parentnames, parent:displayname())
- end
- if #parentnames == 0 then
- return
- end
- return table.concat(parentnames, ",")
- end
-end
-
--- get package configs string
-function _get_package_configs_str(package)
- local configs = {}
- if package:optional() then
- table.insert(configs, "optional")
- end
- local requireinfo = package:requireinfo()
- if requireinfo then
- for k, v in pairs(requireinfo.configs) do
- if type(v) == "boolean" then
- table.insert(configs, k .. ":" .. (v and "y" or "n"))
- else
- table.insert(configs, k .. ":" .. v)
- end
- end
- end
- local parents_str = _get_package_parents_str(package)
- if parents_str then
- table.insert(configs, "from:" .. parents_str)
- end
- local configs_str = #configs > 0 and "[" .. table.concat(configs, ", ") .. "]" or ""
- local limitwidth = os.getwinsize().width * 2 / 3
- if #configs_str > limitwidth then
- configs_str = configs_str:sub(1, limitwidth) .. " ..)"
- end
- return configs_str
-end
-
--- get user confirm
-function _get_confirm(packages)
-
- -- no confirmed packages?
- if #packages == 0 then
- return true
- end
-
- -- get confirm
- local confirm = utils.confirm({default = true, description = function ()
-
- -- get packages for each repositories
- local packages_repo = {}
- local packages_group = {}
- for _, package in ipairs(packages) do
- -- achive packages by repository
- local reponame = package:repo() and package:repo():name() or (package:isSys() and "system" or "")
- if package:is3rd() then
- reponame = package:name():lower():split("::")[1]
- end
- packages_repo[reponame] = packages_repo[reponame] or {}
- table.insert(packages_repo[reponame], package)
-
- -- achive packages by group
- local group = package:group()
- if group then
- packages_group[group] = packages_group[group] or {}
- table.insert(packages_group[group], package)
- end
- end
-
- -- show tips
- cprint("${bright color.warning}note: ${clear}try installing these packages (pass -y to skip confirm)?")
- for reponame, packages in pairs(packages_repo) do
- if reponame ~= "" then
- print("in %s:", reponame)
- end
- local packages_showed = {}
- for _, package in ipairs(packages) do
- if not packages_showed[tostring(package)] then
- local group = package:group()
- if group and packages_group[group] and #packages_group[group] > 1 then
- for idx, package_in_group in ipairs(packages_group[group]) do
- cprint(" ${yellow}%s${clear} %s %s ${dim}%s", idx == 1 and "->" or " or", package_in_group:displayname(), package_in_group:version_str() or "", _get_package_configs_str(package_in_group))
- packages_showed[tostring(package_in_group)] = true
- end
- packages_group[group] = nil
- else
- cprint(" ${yellow}->${clear} %s %s ${dim}%s", package:displayname(), package:version_str() or "", _get_package_configs_str(package))
- packages_showed[tostring(package)] = true
- end
- end
- end
- end
- end})
- return confirm
-end
-
--- install packages
-function _install_packages(packages_install, packages_download)
-
- -- we need hide wait characters if is not a tty
- local show_wait = io.isatty()
-
- -- do install
- local progress_helper = show_wait and progress.new() or nil
- local packages_installing = {}
- local packages_downloading = {}
- local packages_pending = table.copy(packages_install)
- local packages_in_group = {}
- local installing_count = 0
- local parallelize = true
- runjobs("install_packages", function (index)
-
- -- fetch a new package
- local package = nil
- while package == nil and #packages_pending > 0 do
- for idx, pkg in ipairs(packages_pending) do
-
- -- all dependences has been installed? we install it now
- local ready = true
- local dep_not_found = nil
- for _, dep in ipairs(pkg:orderdeps()) do
- if not dep:exists() then
- ready = false
- dep_not_found = dep
- break
- end
- end
- local group = pkg:group()
- if ready and group then
- -- this group has been installed? skip it
- local group_status = packages_in_group[group]
- if group_status == 1 then
- table.remove(packages_pending, idx)
- break
- -- this group is installing? wait it
- elseif group_status == 0 then
- ready = false
- end
- end
-
- -- get a package with the ready status
- if ready then
- package = pkg
- table.remove(packages_pending, idx)
- break
- elseif installing_count == 0 then
- if #packages_pending == 1 and dep_not_found then
- raise("package(%s): cannot be installed, there are dependencies(%s) that cannot be installed!", pkg:displayname(), dep_not_found:displayname())
- elseif #packages_pending == 1 then
- raise("package(%s): cannot be installed!", pkg:displayname())
- end
- end
- end
- if package == nil and #packages_pending > 0 then
- scheduler.co_yield()
- end
- end
- if package then
-
- -- only install the first package in same group
- local group = package:group()
- if not group or not packages_in_group[group] then
-
- -- disable parallelize?
- if not package:parallelize() then
- parallelize = false
- end
- if not parallelize then
- while installing_count > 0 do
- scheduler.co_yield()
- end
- end
- installing_count = installing_count + 1
-
- -- mark this group as 'installing'
- if group then
- packages_in_group[group] = 0
- end
-
- -- download this package first
- local downloaded = true
- if packages_download[tostring(package)] then
- packages_downloading[index] = package
- downloaded = action_download(package)
- packages_downloading[index] = nil
- end
-
- -- install this package
- packages_installing[index] = package
- if downloaded then
- action_install(package)
- end
- packages_installing[index] = nil
-
- -- mark this group as 'installed' or 'failed'
- if group then
- packages_in_group[group] = package:exists() and 1 or -1
- end
-
- -- enable parallelize
- parallelize = true
- installing_count = installing_count - 1
- end
- end
- packages_installing[index] = nil
- packages_downloading[index] = nil
-
- end, {total = #packages_install, comax = (option.get("verbose") or option.get("diagnosis")) and 1 or 4, on_timer = function (running_jobs_indices)
-
- -- do not print progress info if be verbose
- if option.get("verbose") or not show_wait then
- return
- end
-
- -- make installing and downloading packages list
- local installing = {}
- local downloading = {}
- for _, index in ipairs(running_jobs_indices) do
- local package = packages_installing[index]
- if package then
- table.insert(installing, package:displayname())
- end
- local package = packages_downloading[index]
- if package then
- table.insert(downloading, package:displayname())
- end
- end
-
- -- get waitobjs tips
- local tips = nil
- local waitobjs = scheduler.co_group_waitobjs("install_packages")
- if waitobjs:size() > 0 then
- local names = {}
- for _, obj in waitobjs:keys() do
- if obj:otype() == scheduler.OT_PROC then
- table.insert(names, obj:name())
- elseif obj:otype() == scheduler.OT_SOCK then
- table.insert(names, "sock")
- elseif obj:otype() == scheduler.OT_PIPE then
- table.insert(names, "pipe")
- end
- end
- names = table.unique(names)
- if #names > 0 then
- names = table.concat(names, ",")
- if #names > 16 then
- names = names:sub(1, 16) .. ".."
- end
- tips = string.format("(%d/%s)", waitobjs:size(), names)
- end
- end
-
- -- trace
- progress_helper:clear()
- tty.erase_line_to_start().cr()
- cprintf("${yellow} => ")
- if #downloading > 0 then
- cprintf("downloading ${magenta}%s", table.concat(downloading, ", "))
- end
- if #installing > 0 then
- cprintf("%sinstalling ${magenta}%s", #downloading > 0 and ", " or "", table.concat(installing, ", "))
- end
- cprintf(" .. %s", tips and ("${dim}" .. tips .. "${clear} ") or "")
- progress_helper:write()
- end, exit = function(errors)
- if errors then
- tty.erase_line_to_start().cr()
- io.flush()
- end
- end})
-end
-
-- the cache directory
function cachedir()
return path.join(global.directory(), "cache", "packages")
@@ -967,140 +656,3 @@ function load_packages(requires, opt)
return packages
end
--- install packages
-function install_packages(requires, opt)
-
- -- init options
- opt = opt or {}
-
- -- load packages
- local packages = load_packages(requires, opt)
-
- -- fetch packages (with system) from local first
- runjobs("fetch_packages", function (index)
- local package = packages[index]
- if package and (not option.get("force") or (option.get("shallow") and package:parents())) then
- package:envs_enter()
- package:fetch()
- package:envs_leave()
- end
- end, {total = #packages})
-
- -- filter packages
- local packages_install = {}
- local packages_download = {}
- local packages_unsupported = {}
- for _, package in ipairs(packages) do
- if not package:exists() then
- if package:supported() then
- if #package:urls() > 0 then
- packages_download[tostring(package)] = package
- end
- table.insert(packages_install, package)
- elseif not package:optional() then
- table.insert(packages_unsupported, package)
- end
- end
- end
-
- -- exists unsupported packages?
- if #packages_unsupported > 0 then
- -- show tips
- cprint("${bright color.warning}note: ${clear}the following packages are unsupported for $(plat)/$(arch)!")
- for _, package in ipairs(packages_unsupported) do
- print(" -> %s %s", package:displayname(), package:version_str() or "")
- end
- raise()
- end
-
- -- get user confirm
- if not _get_confirm(packages_install) then
- local packages_must = {}
- for _, package in ipairs(packages_install) do
- if not package:optional() then
- table.insert(packages_must, package:displayname())
- end
- end
- if #packages_must > 0 then
- raise("packages(%s): must be installed!", table.concat(packages_must, ", "))
- else
- -- continue other actions
- return
- end
- end
-
- -- sort package urls
- _sort_packages_urls(packages_download)
-
- -- install all required packages from repositories
- _install_packages(packages_install, packages_download)
-
- -- ok
- return packages
-end
-
--- uninstall packages
-function uninstall_packages(requires, opt)
-
- -- init options
- opt = opt or {}
-
- -- do not remove dependent packages
- opt.nodeps = true
-
- -- clear the local cache
- localcache.clear()
-
- -- remove all packages
- local packages = {}
- for _, instance in ipairs(load_packages(requires, opt)) do
- if os.isfile(instance:manifest_file()) then
- table.insert(packages, instance)
- end
- os.tryrm(instance:installdir())
- end
- return packages
-end
-
--- export packages
-function export_packages(requires, opt)
-
- -- init options
- opt = opt or {}
-
- -- get the export directory
- local exportdir = assert(opt.exportdir)
-
- -- export all packages
- local packages = {}
- for _, instance in ipairs(load_packages(requires, opt)) do
-
- -- get the exported name
- local name = instance:name():lower():gsub("::", "_")
- if instance:version_str() then
- name = name .. "_" .. instance:version_str()
- end
- name = name .. "_" .. instance:buildhash()
-
- -- export this package
- if instance:fetch() then
- os.cp(instance:installdir(), path.join(exportdir, name))
- table.insert(packages, instance)
- end
- end
- return packages
-end
-
--- search packages
-function search_packages(names)
-
- -- search all names
- local results = {}
- for _, name in ipairs(names) do
- local packages = _search_packages(name)
- if packages then
- results[name] = packages
- end
- end
- return results
-end
diff --git a/xmake/modules/private/action/require/impl/register_packages.lua b/xmake/modules/private/action/require/impl/register_packages.lua
new file mode 100644
index 000000000..d0128cf16
--- /dev/null
+++ b/xmake/modules/private/action/require/impl/register_packages.lua
@@ -0,0 +1,125 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file register_packages.lua
+--
+
+-- imports
+import("core.project.project")
+
+-- register required package environments
+-- envs: bin path for *.dll, program ..
+function _register_required_package_envs(instance, envs)
+ for name, values in pairs(instance:envs()) do
+ if name == "PATH" or name == "LD_LIBRARY_PATH" or name == "DYLD_LIBRARY_PATH" then
+ for _, value in ipairs(values) do
+ envs[name] = envs[name] or {}
+ if path.is_absolute(value) then
+ table.insert(envs[name], value)
+ else
+ table.insert(envs[name], path.join(instance:installdir(), value))
+ end
+ end
+ else
+ envs[name] = envs[name] or {}
+ table.join2(envs[name], values)
+ end
+ end
+end
+
+-- register required package libraries
+-- libs: includedirs, links, linkdirs ...
+function _register_required_package_libs(instance, required_package, is_deps)
+ if instance:is_library() then
+ local fetchinfo = instance:fetch()
+ if fetchinfo then
+ fetchinfo.name = nil
+ if is_deps then
+ -- we need only reserve license for root package
+ --
+ -- @note the license compatibility between the root package and
+ -- its dependent packages is guaranteed by the root package itself
+ --
+ fetchinfo.license = nil
+
+ -- we need only some infos for root package
+ fetchinfo.version = nil
+ fetchinfo.static = nil
+ fetchinfo.shared = nil
+ end
+ required_package:add(fetchinfo)
+ end
+ end
+end
+
+-- register the base info of required package
+function _register_required_package_base(instance, required_package)
+ if not instance:isSys() and not instance:is3rd() then
+ required_package:set("__installdir", instance:installdir())
+ end
+end
+
+-- register the required local package
+function _register_required_package(instance, required_package)
+
+ -- disable it if this package is missing
+ if not instance:exists() then
+ required_package:enable(false)
+ else
+ -- clear require info first
+ required_package:clear()
+
+ -- add packages info with all dependencies
+ local envs = {}
+ _register_required_package_base(instance, required_package)
+ _register_required_package_libs(instance, required_package)
+ _register_required_package_envs(instance, envs)
+ local orderdeps = instance:orderdeps()
+ if orderdeps then
+ local total = #orderdeps
+ for idx, _ in ipairs(orderdeps) do
+ local dep = orderdeps[total + 1 - idx]
+ if dep then
+ _register_required_package_libs(dep, required_package, true)
+ _register_required_package_envs(dep, envs)
+ end
+ end
+ end
+ if #table.keys(envs) > 0 then
+ required_package:add({envs = envs})
+ end
+
+ -- enable this require info
+ required_package:enable(true)
+ end
+
+ -- save this require info and flush the whole cache file
+ required_package:save()
+end
+
+-- register all required local packages
+function main(packages)
+ for _, instance in ipairs(packages) do
+ if not instance:parents() then
+ local required_package = project.required_package(instance:alias() or instance:name())
+ if required_package then
+ _register_required_package(instance, required_package)
+ end
+ end
+ end
+end
+
diff --git a/xmake/modules/private/action/require/impl/search_packages.lua b/xmake/modules/private/action/require/impl/search_packages.lua
new file mode 100644
index 000000000..49183a6cc
--- /dev/null
+++ b/xmake/modules/private/action/require/impl/search_packages.lua
@@ -0,0 +1,50 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file search_packages.lua
+--
+
+-- imports
+import("core.package.package", {alias = "core_package"})
+import("private.action.require.impl.repository")
+
+-- search packages from repositories
+function _search_packages(name)
+
+ local packages = {}
+ for _, packageinfo in ipairs(repository.searchdirs(name)) do
+ local package = core_package.load_from_repository(packageinfo.name, packageinfo.repo, packageinfo.packagedir)
+ if package then
+ table.insert(packages, package)
+ end
+ end
+ return packages
+end
+
+-- search packages
+function main(names)
+
+ -- search all names
+ local results = {}
+ for _, name in ipairs(names) do
+ local packages = _search_packages(name)
+ if packages then
+ results[name] = packages
+ end
+ end
+ return results
+end
diff --git a/xmake/modules/private/action/require/impl/uninstall_packages.lua b/xmake/modules/private/action/require/impl/uninstall_packages.lua
new file mode 100644
index 000000000..a5185f868
--- /dev/null
+++ b/xmake/modules/private/action/require/impl/uninstall_packages.lua
@@ -0,0 +1,47 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file uninstall_packages.lua
+--
+
+-- imports
+import("core.cache.localcache")
+import("private.action.require.impl.package")
+
+-- uninstall packages
+function main(requires, opt)
+
+ -- init options
+ opt = opt or {}
+
+ -- do not remove dependent packages
+ opt.nodeps = true
+
+ -- clear the local cache
+ localcache.clear()
+
+ -- remove all packages
+ local packages = {}
+ for _, instance in ipairs(package.load_packages(requires, opt)) do
+ if os.isfile(instance:manifest_file()) then
+ table.insert(packages, instance)
+ end
+ os.tryrm(instance:installdir())
+ end
+ return packages
+end
+
diff --git a/xmake/modules/private/action/require/install.lua b/xmake/modules/private/action/require/install.lua
index f7be8b9b9..ae65772e6 100644
--- a/xmake/modules/private/action/require/install.lua
+++ b/xmake/modules/private/action/require/install.lua
@@ -23,9 +23,9 @@ import("core.base.option")
import("core.base.task")
import("core.project.project")
import("lib.detect.find_tool")
-import("private.action.require.impl.package")
import("private.action.require.impl.repository")
import("private.action.require.impl.environment")
+import("private.action.require.impl.install_packages")
import("private.action.require.impl.utils.get_requires")
-- register required package environments
@@ -195,7 +195,7 @@ function main(requires_raw)
-- install packages
environment.enter()
- local packages = package.install_packages(requires, {requires_extra = requires_extra})
+ local packages = install_packages(requires, {requires_extra = requires_extra})
if packages then
-- check missing packages
diff --git a/xmake/modules/private/action/require/search.lua b/xmake/modules/private/action/require/search.lua
index 2637e6c36..7f76650b5 100644
--- a/xmake/modules/private/action/require/search.lua
+++ b/xmake/modules/private/action/require/search.lua
@@ -21,9 +21,9 @@
-- imports
import("core.base.task")
import("private.action.require.impl.utils.filter")
-import("private.action.require.impl.package")
import("private.action.require.impl.repository")
import("private.action.require.impl.environment")
+import("private.action.require.impl.search_packages")
-- search the given packages
function main(names)
@@ -45,7 +45,7 @@ function main(names)
print("The package names:")
-- search packages
- for name, packages in pairs(package.search_packages(names)) do
+ for name, packages in pairs(search_packages(names)) do
if #packages > 0 then
-- show name
diff --git a/xmake/modules/private/action/require/uninstall.lua b/xmake/modules/private/action/require/uninstall.lua
index 2d690614b..b3c2d1bce 100644
--- a/xmake/modules/private/action/require/uninstall.lua
+++ b/xmake/modules/private/action/require/uninstall.lua
@@ -21,9 +21,9 @@
-- imports
import("core.base.task")
import("core.base.option")
-import("private.action.require.impl.package")
import("private.action.require.impl.repository")
import("private.action.require.impl.environment")
+import("private.action.require.impl.uninstall_packages")
import("private.action.require.impl.utils.get_requires")
-- uninstall the given packages
@@ -45,7 +45,7 @@ function main(requires_raw)
end
-- uninstall packages
- local packages = package.uninstall_packages(requires, {requires_extra = requires_extra})
+ local packages = uninstall_packages(requires, {requires_extra = requires_extra})
for _, instance in ipairs(packages) do
print("uninstall: %s%s ok!", instance:name(), instance:version_str() and ("-" .. instance:version_str()) or "")
end