diff options
| author | ruki <[email protected]> | 2022-06-01 08:30:56 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2022-06-01 08:30:56 +0800 |
| commit | 1191707104f898c5a530cfcb7a342dd164e8dca0 (patch) | |
| tree | 1929fb0530a21660b8cd99ef2b7c59d08e4ff402 | |
| parent | a440640d2dc3f32dd31beb0e800dab1b1568ff0c (diff) | |
| parent | 7ea0b12202f5f0596ad2b2363cd75021643c0d4f (diff) | |
Merge pull request #2418 from xmake-io/fetch
Improve to fetch packages
| -rw-r--r-- | xmake/modules/private/action/require/impl/install_packages.lua | 124 |
1 files changed, 106 insertions, 18 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..b45e56b1a 100644 --- a/xmake/modules/private/action/require/impl/install_packages.lua +++ b/xmake/modules/private/action/require/impl/install_packages.lua @@ -256,6 +256,107 @@ function _show_upgraded_packages(packages) cprint("${bright}%d packages are upgraded!", upgraded_count) end +-- fetch packages +function _fetch_packages(packages_fetch, installdeps) + + -- 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") + + -- do fetch + local packages_fetching = {} + local packages_pending = table.copy(packages_fetch) + local working_count = 0 + local fetching_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_ready = nil + for _, dep in pairs(installdeps[tostring(pkg)]) do + local fetched = packages_fetched[tostring(dep)] + if fetched == false then + ready = false + dep_not_ready = 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_ready then + raise("package(%s): cannot be fetched, there are dependencies(%s) that cannot be fetched!", pkg:displayname(), dep_not_ready:displayname()) + elseif #packages_pending == 1 then + raise("package(%s): cannot be fetched!", 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 fetching_count > 0 do + scheduler.co_yield() + end + end + fetching_count = fetching_count + 1 + + -- fetch this package + packages_fetching[index] = instance + local oldenvs = os.getenvs() + instance:envs_enter() + instance:fetch() + os.setenvs(oldenvs) + + -- 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 + + -- next + parallelize = true + fetching_count = fetching_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) @@ -550,28 +651,15 @@ function main(requires, opt) local term_mode_stdout = tty.term_mode("stdout") -- fetch and register packages (with system) from local first - runjobs("fetch_packages", function (index) - local instance = packages[index] + local packages_fetch = {} + for _, instance in ipairs(packages) do 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) + table.insert(packages_fetch, instance) 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 - - end, {total = #packages, - comax = (option.get("verbose") or option.get("diagnosis")) and 1 or 4, - isolate = true}) + end + _fetch_packages(packages_fetch, installdeps) -- register all installed root packages to local cache register_packages(packages) |
