diff options
| author | ruki <[email protected]> | 2022-05-31 09:12:57 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2022-05-31 09:12:57 +0800 |
| commit | adbb0c42854524f252a9e994d2cf7d69743cdb53 (patch) | |
| tree | e56f6330bad3ff91d0dd6224b103a87539f27dc2 | |
| parent | 64c41bd8ef06038cebdbbf39a85da51d69e718e7 (diff) | |
improve fetch
| -rw-r--r-- | xmake/modules/private/action/require/impl/install_packages.lua | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/xmake/modules/private/action/require/impl/install_packages.lua b/xmake/modules/private/action/require/impl/install_packages.lua index 787dd90b2..fa58edfeb 100644 --- a/xmake/modules/private/action/require/impl/install_packages.lua +++ b/xmake/modules/private/action/require/impl/install_packages.lua @@ -256,6 +256,120 @@ function _show_upgraded_packages(packages) cprint("${bright}%d packages are upgraded!", upgraded_count) end +-- fetch packages +function _fetch_packages(packages_fetch, installdeps) + + -- we need hide wait characters if is not a tty + local show_wait = io.isatty() + + -- init installed packages + local packages_fetched = {} + for _, instance in ipairs(packages_fetch) do + packages_fetched[tostring(instance)] = false + end + + -- save terminal mode for stdout, @see https://github.com/xmake-io/xmake/issues/1924 + local term_mode_stdout = tty.term_mode("stdout") + + --[[ + runjobs("fetch_packages", function (index) + local instance = packages[index] + if instance and (instance:is_fetchonly() or + not option.get("force") or + (option.get("shallow") and not instance:is_toplevel())) then + local oldenvs = os.getenvs() + instance:envs_enter() + instance:fetch() + os.setenvs(oldenvs) + end + + -- fix terminal mode to avoid some subprocess to change it + -- + -- @see https://github.com/xmake-io/xmake/issues/1924 + -- https://github.com/xmake-io/xmake/issues/2329 + if term_mode_stdout ~= tty.term_mode("stdout") then + tty.term_mode("stdout", term_mode_stdout) + end +]] + + -- do install + local packages_fetching = {} + local packages_pending = table.copy(packages_fetch) + local working_count = 0 + local installing_count = 0 + local parallelize = true + runjobs("fetch_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 fetched? we fetch it now + local ready = true + local dep_not_found = nil + for _, dep in pairs(installdeps[tostring(pkg)]) do + local fetched = packages_fetched[tostring(dep)] + if fetched == false or (fetched == nil and not dep:exists() and not dep:is_optional()) then + ready = false + dep_not_found = dep + break + end + end + + -- get a package with the ready status + if ready then + instance = pkg + table.remove(packages_pending, idx) + break + elseif working_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 + + -- update working count + working_count = working_count + 1 + + -- disable parallelize? + if not instance:is_parallelize() then + parallelize = false + end + if not parallelize then + while installing_count > 0 do + scheduler.co_yield() + end + end + installing_count = installing_count + 1 + + -- install this package + packages_fetching[index] = instance + + + -- next + parallelize = true + installing_count = installing_count - 1 + packages_fetching[index] = nil + packages_fetched[tostring(instance)] = true + + -- update working count + working_count = working_count - 1 + end + packages_fetching[index] = nil + + end, {total = #packages_fetch, + comax = (option.get("verbose") or option.get("diagnosis")) and 1 or 4, + isolate = true}) +end + -- install packages function _install_packages(packages_install, packages_download, installdeps) |
