Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F2894841
PhutilConsoleProgressBar.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Advanced/Developer...
View Handle
View Hovercard
Size
4 KB
Referenced Files
None
Subscribers
None
PhutilConsoleProgressBar.php
View Options
<?php
/**
* Show a progress bar on the console. Usage:
*
* // Create a progress bar, and configure the total amount of work that
* // needs to be done.
* $bar = id(new PhutilConsoleProgressBar())
* ->setTotal(count($stuff));
*
* // As you complete the work, update the progress bar.
* foreach ($stuff as $thing) {
* do_stuff($thing);
* $bar->update(1);
* }
*
* // When complete, mark the work done to clear the bar.
* $bar->done();
*
* The progress bar attempts to account for various special cases, notably:
*
* - If stderr is not a TTY, the bar will not be drawn (for example, if
* it is being piped to a log file).
* - If the Phutil log output is enabled (usually because `--trace` was
* specified), the bar will not be drawn.
* - The bar will be resized to the width of the console if possible.
*
*/
final
class
PhutilConsoleProgressBar
extends
Phobject
{
private
$work
;
private
$done
;
private
$drawn
;
private
$console
;
private
$finished
;
private
$lastUpdate
;
private
$quiet
=
false
;
public
function
setConsole
(
PhutilConsole
$console
)
{
$this
->
console
=
$console
;
return
$this
;
}
private
function
getConsole
(
)
{
if
(
$this
->
console
)
{
return
$this
->
console
;
}
return
PhutilConsole
::
getConsole
(
)
;
}
public
function
setTotal
(
$work
)
{
$this
->
work
=
$work
;
$this
->
redraw
(
)
;
return
$this
;
}
public
function
setQuiet
(
$quiet
)
{
$this
->
quiet
=
$quiet
;
return
$this
;
}
public
function
update
(
$work
)
{
$this
->
done
+=
$work
;
$this
->
redraw
(
)
;
return
$this
;
}
private
function
redraw
(
)
{
if
(
$this
->
lastUpdate
+
0.1
>
microtime
(
true
)
)
{
// We redrew the bar very recently; skip this update.
return
$this
;
}
return
$this
->
draw
(
)
;
}
/**
* Explicitly redraw the bar.
*
* Normally, the progress bar is automatically redrawn periodically, but
* you may want to force it to draw.
*
* For example, we force a draw after pre-filling the bar when resuming
* large file uploads in `arc upload`. Otherwise, the bar may sit at 0%
* until the first chunk completes.
*/
public
function
draw
(
)
{
if
(
$this
->
quiet
)
{
return
;
}
if
(
$this
->
finished
)
{
return
;
}
if
(
!
$this
->
work
)
{
// There's no work to be done, so don't draw the bar.
return
;
}
$console
=
$this
->
getConsole
(
)
;
if
(
$console
->
isErrATTY
(
)
===
false
)
{
return
;
}
if
(
$console
->
isLogEnabled
(
)
)
{
return
;
}
// Width of the stuff other than the progress bar itself.
$chrome_width
=
strlen
(
'[] 100.0% '
)
;
$char_width
=
$this
->
getWidth
(
)
;
if
(
$char_width
<
$chrome_width
)
{
return
;
}
$this
->
lastUpdate
=
microtime
(
true
)
;
if
(
!
$this
->
drawn
)
{
$this
->
drawn
=
true
;
}
$percent
=
$this
->
done
/
$this
->
work
;
$max_width
=
$char_width
-
$chrome_width
;
$bar_width
=
$percent
*
$max_width
;
$bar_int
=
floor
(
$bar_width
)
;
$bar_frac
=
$bar_width
-
$bar_int
;
$frac_map
=
array
(
''
,
'-'
,
'~'
,
)
;
$frac_char
=
$frac_map
[
floor
(
$bar_frac
*
count
(
$frac_map
)
)
]
;
$pattern
=
"[%-{$max_width}.{$max_width}s] % 5s%%"
;
$out
=
sprintf
(
$pattern
,
str_repeat
(
'='
,
$bar_int
)
.
$frac_char
,
sprintf
(
'%.1f'
,
100
*
$percent
)
)
;
$this
->
eraseLine
(
)
;
$console
->
writeErr
(
'%s'
,
$out
)
;
return
$this
;
}
public
function
done
(
$clean_exit
=
true
)
{
$console
=
$this
->
getConsole
(
)
;
if
(
$this
->
drawn
)
{
$this
->
eraseLine
(
)
;
if
(
$clean_exit
)
{
$console
->
writeErr
(
"%s\n"
,
pht
(
'Done.'
)
)
;
}
}
$this
->
finished
=
true
;
}
private
function
eraseLine
(
)
{
$string
=
str_repeat
(
' '
,
$this
->
getWidth
(
)
)
;
$console
=
$this
->
getConsole
(
)
;
$console
->
writeErr
(
"\r%s\r"
,
$string
)
;
}
private
function
getWidth
(
)
{
$console
=
$this
->
getConsole
(
)
;
$width
=
$console
->
getErrCols
(
)
;
return
min
(
nonempty
(
$width
,
78
)
,
78
)
;
}
public
function
__destruct
(
)
{
$this
->
done
(
$clean_exit
=
false
)
;
}
}
File Metadata
Details
Attached
Mime Type
text/x-php
Expires
Sun, Jan 19, 20:34 (1 w, 5 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1113075
Default Alt Text
PhutilConsoleProgressBar.php (4 KB)
Attached To
Mode
rARC Arcanist
Attached
Detach File
Event Timeline
Log In to Comment