summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2020-05-27 12:30:04 +0800
committerGitHub <[email protected]>2020-05-27 12:30:04 +0800
commit4fc3548931420eb7918b03bffecacbc36b4574cd (patch)
treef624fdaba3a131d716a32509244c43492d17de59
parent29a19271875e045a85cc672c79b160fc1165c11a (diff)
parentfe8e6ea390531932439ba772b2ac434f38e8a2bd (diff)
Merge pull request #803 from OpportunityLiu/dev
A better progress indicator
-rw-r--r--tests/modules/scheduler/runjobs.lua2
-rw-r--r--xmake/actions/require/impl/package.lua16
-rw-r--r--xmake/actions/update/main.lua4
-rw-r--r--xmake/modules/private/async/runjobs.lua58
-rw-r--r--xmake/modules/private/utils/progress.lua91
-rw-r--r--xmake/plugins/repo/main.lua2
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