summaryrefslogtreecommitdiff
path: root/xmake/actions/require/impl/package.lua
diff options
context:
space:
mode:
authorruki <[email protected]>2019-03-22 23:52:08 +0800
committerruki <[email protected]>2019-03-22 17:12:49 +0800
commit6771a6707d884f53a192f8a5a1ed42db299f79a5 (patch)
tree3dee7df8fee33fe7dded6537b613681e9d0a7f7d /xmake/actions/require/impl/package.lua
parent9ed3fd873294466fa927d9dfd38cb43cce1d6dd8 (diff)
improve install packages
Diffstat (limited to 'xmake/actions/require/impl/package.lua')
-rw-r--r--xmake/actions/require/impl/package.lua121
1 files changed, 92 insertions, 29 deletions
diff --git a/xmake/actions/require/impl/package.lua b/xmake/actions/require/impl/package.lua
index 6e277c07b..0595ed8f1 100644
--- a/xmake/actions/require/impl/package.lua
+++ b/xmake/actions/require/impl/package.lua
@@ -439,19 +439,88 @@ function _get_confirm(packages)
return confirm
end
--- download packages
-function _download_packages(packages)
+-- install packages
+function _install_packages(packages_install, packages_download)
local waitindex = 0
local waitchars = {'\\', '|', '/', '-'}
+ local packages_installing = {}
+ local packages_downloading = {}
+ local packages_pending = table.copy(packages_install)
+ local packages_in_group = {}
process.runjobs(function (index)
- local package = packages[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
+ for _, dep in ipairs(pkg:orderdeps()) do
+ if not dep:exists() then
+ ready = false
+ 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
+ end
+ end
+ if package == nil and #packages_pending > 0 then
+ local curdir = os.curdir()
+ coroutine.yield()
+ os.cd(curdir)
+ end
+ end
if package then
- action.download(package)
+
+ -- only install the first package in same group
+ local group = package:group()
+ if not group or not packages_in_group[group] then
+
+ -- mark this group as 'installing'
+ if group then
+ packages_in_group[group] = 0
+ end
+
+ -- download this package first
+ if packages_download[tostring(package)] then
+ packages_downloading[index] = package
+ action.download(package)
+ packages_downloading[index] = nil
+ end
+
+ -- install this package
+ packages_installing[index] = package
+ action.install(package)
+ 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
+ end
end
+ packages_installing[index] = nil
+ packages_downloading[index] = nil
- end, #packages, (option.get("verbose") or option.get("diagnosis")) and 1 or 4, 300, function (indices)
+ end, #packages_install, (option.get("verbose") or option.get("diagnosis")) and 1 or 4, 300, function (indices)
-- do not print progress info if be verbose
if option.get("verbose") then
@@ -461,37 +530,34 @@ function _download_packages(packages)
-- update waitchar index
waitindex = ((waitindex + 1) % #waitchars)
- -- make downloading packages list
+ -- make installing and downloading packages list
+ local installing = {}
local downloading = {}
for _, index in ipairs(indices) do
- local package = packages[index]
+ local package = packages_installing[index]
+ if package then
+ table.insert(installing, package:name())
+ end
+ local package = packages_downloading[index]
if package then
table.insert(downloading, package:name())
end
end
-- trace
- cprintf("\r${yellow} => ${clear}downloading %s .. %s", table.concat(downloading, ", "), waitchars[waitindex + 1])
+ cprintf("\r${yellow} => ${clear}installing %s .. %s", table.concat(installing, ", "), waitchars[waitindex + 1])
+ cprintf("\r${yellow} => ${clear}")
+ if #downloading > 0 then
+ cprintf("downloading ${yellow}%s${clear}", table.concat(downloading, ", "))
+ end
+ if #installing > 0 then
+ cprintf("%sinstalling ${yellow}%s${clear}", #downloading > 0 and ", " or "", table.concat(installing, ", "))
+ end
+ cprintf(" .. %s", waitchars[waitindex + 1])
io.flush()
end)
end
--- install packages
-function _install_packages(packages)
- local installed_in_group = {}
- for _, package in ipairs(packages) do
-
- -- only install the first package in same group
- local group = package:group()
- if not group or not installed_in_group[group] then
- action.install(package)
- if group then
- installed_in_group[group] = true
- end
- end
- end
-end
-
-- the cache directory
function cachedir()
return path.join(global.directory(), "cache", "packages")
@@ -578,7 +644,7 @@ function install_packages(requires, opt)
if (option.get("force") or not package:exists()) and (#package:urls() > 0 or package:script("install")) then
if package:supported() then
if #package:urls() > 0 then
- table.insert(packages_download, package)
+ packages_download[tostring(package)] = package
end
table.insert(packages_install, package)
elseif not package:optional() then
@@ -605,11 +671,8 @@ function install_packages(requires, opt)
-- sort package urls
_sort_packages_urls(packages_download)
- -- download remote packages
- _download_packages(packages_download)
-
-- install all required packages from repositories
- _install_packages(packages_install)
+ _install_packages(packages_install, packages_download)
-- ok
return packages