diff options
| author | ruki <[email protected]> | 2020-05-27 12:30:04 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2020-05-27 12:30:04 +0800 |
| commit | 4fc3548931420eb7918b03bffecacbc36b4574cd (patch) | |
| tree | f624fdaba3a131d716a32509244c43492d17de59 | |
| parent | 29a19271875e045a85cc672c79b160fc1165c11a (diff) | |
| parent | fe8e6ea390531932439ba772b2ac434f38e8a2bd (diff) | |
Merge pull request #803 from OpportunityLiu/dev
A better progress indicator
| -rw-r--r-- | tests/modules/scheduler/runjobs.lua | 2 | ||||
| -rw-r--r-- | xmake/actions/require/impl/package.lua | 16 | ||||
| -rw-r--r-- | xmake/actions/update/main.lua | 4 | ||||
| -rw-r--r-- | xmake/modules/private/async/runjobs.lua | 58 | ||||
| -rw-r--r-- | xmake/modules/private/utils/progress.lua | 91 | ||||
| -rw-r--r-- | xmake/plugins/repo/main.lua | 2 |
6 files changed, 128 insertions, 45 deletions
diff --git a/tests/modules/scheduler/runjobs.lua b/tests/modules/scheduler/runjobs.lua index 29befa5d0..958a158e2 100644 --- a/tests/modules/scheduler/runjobs.lua +++ b/tests/modules/scheduler/runjobs.lua @@ -45,7 +45,7 @@ function main() printf("testing .. ") runjobs("test", function () os.sleep(10000) - end, {showtips = true}) + end, {progress = true}) print("ok") end diff --git a/xmake/actions/require/impl/package.lua b/xmake/actions/require/impl/package.lua index e8d8cc92e..4293377b3 100644 --- a/xmake/actions/require/impl/package.lua +++ b/xmake/actions/require/impl/package.lua @@ -25,6 +25,7 @@ import("core.base.global") import("core.base.hashset") import("core.base.scheduler") import("private.async.runjobs") +import("private.utils.progress") import("lib.detect.cache", {alias = "detectcache"}) import("core.project.project") import("core.package.package", {alias = "core_package"}) @@ -532,11 +533,10 @@ end function _install_packages(packages_install, packages_download) -- we need hide wait characters if is not a tty - local show_wait = io.isatty() + local show_wait = io.isatty() -- do install - local waitindex = 0 - local waitchars = {'\\', '-', '/', '|'} + local progress_helper = show_wait and progress.new() or nil local packages_installing = {} local packages_downloading = {} local packages_pending = table.copy(packages_install) @@ -635,11 +635,8 @@ function _install_packages(packages_install, packages_download) -- do not print progress info if be verbose if option.get("verbose") or not show_wait then - return + return end - - -- update waitchar index - waitindex = ((waitindex + 1) % #waitchars) -- make installing and downloading packages list local installing = {} @@ -680,6 +677,7 @@ function _install_packages(packages_install, packages_download) end -- trace + progress_helper:clear() utils.clearline() cprintf("${yellow} => ") if #downloading > 0 then @@ -688,8 +686,8 @@ function _install_packages(packages_install, packages_download) if #installing > 0 then cprintf("%sinstalling ${magenta}%s", #downloading > 0 and ", " or "", table.concat(installing, ", ")) end - cprintf(" .. %s%s", tips and ("${dim}" .. tips .. "${clear} ") or "", waitchars[waitindex + 1]) - io.flush() + cprintf(" .. %s", tips and ("${dim}" .. tips .. "${clear} ") or "") + progress_helper:write() end, exit = function(errors) if errors then utils.clearline() diff --git a/xmake/actions/update/main.lua b/xmake/actions/update/main.lua index e7b204f75..c947288fe 100644 --- a/xmake/actions/update/main.lua +++ b/xmake/actions/update/main.lua @@ -198,7 +198,7 @@ function _install(sourcedir) if option.get("verbose") then install_task() else - runjobs("update/install", install_task, {showtips = true}) + runjobs("update/install", install_task, {progress = true}) end end @@ -390,7 +390,7 @@ function main() if option.get("verbose") then download_task() else - runjobs("update/download", download_task, {showtips = true}) + runjobs("update/download", download_task, {progress = true}) end -- leave environment diff --git a/xmake/modules/private/async/runjobs.lua b/xmake/modules/private/async/runjobs.lua index 2b848bde5..cd130e6c9 100644 --- a/xmake/modules/private/async/runjobs.lua +++ b/xmake/modules/private/async/runjobs.lua @@ -20,31 +20,24 @@ -- imports import("core.base.scheduler") +import("private.utils.progress") -- print back characters function _print_backchars(backnum) if backnum > 0 then - local str = "" - for i = 1, backnum do - str = str .. '\b' - end - for i = 1, backnum do - str = str .. ' ' - end - for i = 1, backnum do - str = str .. '\b' - end + local str = ('\b'):rep(backnum) .. (' '):rep(backnum) .. ('\b'):rep(backnum) if #str > 0 then printf(str) end end end --- asynchronous run jobs +-- asynchronous run jobs -- --- e.g. +-- e.g. -- runjobs("test", function (index) print("hello") end, {total = 100, comax = 6, timeout = 1000, timer = function (running_jobs_indices) end}) --- runjobs("test", function () os.sleep(10000) end, {showtips = true}) +-- runjobs("test", function () os.sleep(10000) end, { progress = true }) +-- runjobs("test", function () os.sleep(10000) end, { progress = { chars = {'/','\'} } }) -- see module private.utils.progress -- -- local jobs = jobpool.new() -- local root = jobs:addjob("job/root", function (idx, total) @@ -71,10 +64,14 @@ function main(name, jobs, opt) assert(jobs, "runjobs: no jobs!") -- show waiting tips? - local waitindex = 0 - local waitchars = opt.waitchars or {'\\', '-', '/', '|'} + local showprogress = io.isatty() and (opt.progress or opt.showtips) -- we need hide wait characters if is not a tty + local progress_helper local backnum = 0 - local showtips = io.isatty() and opt.showtips -- we need hide wait characters if is not a tty + if showprogress then + local opt = nil + if type(showprogress) == 'table' then opt = showprogress end + progress_helper = progress.new(nil, opt) + end -- run timer local stop = false @@ -88,17 +85,13 @@ function main(name, jobs, opt) end end end) - elseif showtips then + elseif showprogress then scheduler.co_start_named(name .. "/tips", function () while not stop do os.sleep(timeout) if not stop then - -- print back characters - _print_backchars(backnum) - -- show waitchars - waitindex = ((waitindex + 1) % #waitchars) local tips = nil local waitobjs = scheduler.co_group_waitobjs(group_name) if waitobjs:size() > 0 then @@ -121,14 +114,16 @@ function main(name, jobs, opt) tips = string.format("(%d/%s)", waitobjs:size(), names) end end + + -- print back characters + progress_helper:clear() + _print_backchars(backnum) + if tips then - cprintf("${dim}%s${clear} %s", tips, waitchars[waitindex + 1]) - backnum = #tips + 2 - else - printf(waitchars[waitindex + 1]) - backnum = 1 + cprintf("${dim}%s${clear} ", tips) + backnum = #tips + 1 end - io.flush() + progress_helper:write() end end end) @@ -198,10 +193,9 @@ function main(name, jobs, opt) stop = true -- remove wait charactor - if showtips then + if showprogress then _print_backchars(backnum) - print("") - io.flush() + progress_helper:stop() end -- do exit callback @@ -235,9 +229,9 @@ function main(name, jobs, opt) stop = true -- remove wait charactor - if showtips then + if showprogress then _print_backchars(backnum) - io.flush() + progress_helper:stop() end -- do exit callback diff --git a/xmake/modules/private/utils/progress.lua b/xmake/modules/private/utils/progress.lua new file mode 100644 index 000000000..f95baa088 --- /dev/null +++ b/xmake/modules/private/utils/progress.lua @@ -0,0 +1,91 @@ +--!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-2020, TBOOX Open Source Group. +-- +-- @author OpportunityLiu +-- @file progress.lua +-- + +-- imports +import('core.base.object') + +-- print back characters +function _make_clearchars(backnum) + if backnum > 0 then + return ('\b'):rep(backnum) .. (' '):rep(backnum) .. ('\b'):rep(backnum) + end + return '' +end + +-- define module +local process = process or object { _init = { "_RUNNING", "_INDEX", "_STREAM", "_OPT", "_CLEAR" } } + +-- stop the progress indicator, clear written frames +function process:stop() + if self._RUNNING ~= 0 then + self:clear() + self._RUNNING = 0 + self._INDEX = 0 + end +end + +function process:_clear() + if self._RUNNING == 1 then + self._STREAM:write(self._CLEAR) + self._RUNNING = 2 + return true + end +end + +-- clear previous frame of the progress indicator +function process:clear() + if self:_clear() then + self._STREAM:flush() + end +end + +-- write next frame of the progress indicator +function process:write() + local chars = self._OPT.chars[self._INDEX % #self._OPT.chars + 1] + self:_clear() + self._STREAM:write(chars) + self._STREAM:flush() + self._INDEX = self._INDEX + 1 + self._RUNNING = 1 +end + +-- check if the progress indicator is running +function process:running() + return self._RUNNING and true or false +end + +-- build a progress indicator +-- @params stream - stream to write to, will use io.stdout if not provided +-- @params opt - options +-- - chars - an array of chars for progress indicator +-- - width - width of progress indicator, will use #opt.chars[0] if not provided +function new(stream, opt) + + -- set default values + stream = stream or io.stdout + opt = opt or {} + if opt.chars == nil or #opt.chars == 0 then + opt.chars = {'⢎⠀', '⢆⡀', '⢄⡠', '⢀⡰','⠀⡱', '⠈⠱', '⠊⠑', '⠎⠁'} + opt.width = 2 + end + opt.width = opt.width or #opt.chars[1] + + return process { _OPT = opt, _STREAM = stream, _RUNNING = 0, _INDEX = 0, _CLEAR = _make_clearchars(opt.width) } +end
\ No newline at end of file diff --git a/xmake/plugins/repo/main.lua b/xmake/plugins/repo/main.lua index e873d0f64..94aab3b11 100644 --- a/xmake/plugins/repo/main.lua +++ b/xmake/plugins/repo/main.lua @@ -133,7 +133,7 @@ function _update() if option.get("verbose") then task() else - runjobs("update repo", task, {showtips = true}) + runjobs("update repo", task, {progress = true}) end -- leave environment |
