Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F90639177
PhutilConsoleProgressBar.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Sun, Nov 3, 12:00
Size
3 KB
Mime Type
text/x-php
Expires
Tue, Nov 5, 12:00 (2 d)
Engine
blob
Format
Raw Data
Handle
22113162
Attached To
rPHU libphutil
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
;
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
update
(
$work
)
{
$this
->
done
+=
$work
;
$this
->
redraw
();
return
$this
;
}
private
function
redraw
()
{
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
;
}
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
);
}
public
function
done
(
$clean_exit
=
true
)
{
$console
=
$this
->
getConsole
();
if
(
$this
->
drawn
)
{
$this
->
eraseLine
();
if
(
$clean_exit
)
{
$console
->
writeErr
(
"%s
\n
"
,
'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
);
}
}
Event Timeline
Log In to Comment