cp: Improve tty flashing on progress updates

- Instead of rewriting the entire line every time only clear and write
the parts that changed.
- Hide the cursor while writing progress

Both these things make the progress updates significantly easier to
read.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
This commit is contained in:
Brian Goff 2023-03-29 23:47:50 +00:00
parent f27927d934
commit ccae6e9299
1 changed files with 16 additions and 4 deletions

View File

@ -58,16 +58,24 @@ type copyProgressPrinter struct {
func (pt *copyProgressPrinter) Read(p []byte) (int, error) { func (pt *copyProgressPrinter) Read(p []byte) (int, error) {
n, err := pt.ReadCloser.Read(p) n, err := pt.ReadCloser.Read(p)
if n > 0 { if n > 0 {
isFirst := *pt.total == 0
*pt.total += float64(n) *pt.total += float64(n)
if pt.isTerm { if pt.isTerm {
fmt.Fprint(pt.writer, aec.Restore) var header string
fmt.Fprint(pt.writer, aec.EraseLine(aec.EraseModes.All))
if pt.toContainer { if pt.toContainer {
fmt.Fprintln(pt.writer, "Copying to container - "+units.HumanSize(*pt.total)) header = "Copying to container - "
} else { } else {
fmt.Fprintln(pt.writer, "Copying from container - "+units.HumanSize(*pt.total)) header = "Copying from container - "
} }
if isFirst {
fmt.Fprint(pt.writer, aec.Restore)
fmt.Fprint(pt.writer, aec.EraseLine(aec.EraseModes.All))
fmt.Fprint(pt.writer, header)
}
fmt.Fprint(pt.writer, aec.Column(uint(len(header)+1)))
fmt.Fprint(pt.writer, aec.EraseLine(aec.EraseModes.Tail))
fmt.Fprint(pt.writer, units.HumanSize(*pt.total))
} }
} }
@ -239,6 +247,7 @@ func copyFromContainer(ctx context.Context, dockerCli command.Cli, copyConfig cp
} }
if stderrIsTerm { if stderrIsTerm {
fmt.Fprint(dockerCli.Err(), aec.Hide)
fmt.Fprint(dockerCli.Err(), aec.Save) fmt.Fprint(dockerCli.Err(), aec.Save)
fmt.Fprintln(dockerCli.Err(), "Preparing to copy...") fmt.Fprintln(dockerCli.Err(), "Preparing to copy...")
} }
@ -246,6 +255,7 @@ func copyFromContainer(ctx context.Context, dockerCli command.Cli, copyConfig cp
if stderrIsTerm { if stderrIsTerm {
fmt.Fprint(dockerCli.Err(), aec.Restore) fmt.Fprint(dockerCli.Err(), aec.Restore)
fmt.Fprint(dockerCli.Err(), aec.EraseLine(aec.EraseModes.All)) fmt.Fprint(dockerCli.Err(), aec.EraseLine(aec.EraseModes.All))
fmt.Fprint(dockerCli.Err(), aec.Show)
} }
fmt.Fprintln(dockerCli.Err(), "Successfully copied", units.HumanSize(copiedSize), "to", dstPath) fmt.Fprintln(dockerCli.Err(), "Successfully copied", units.HumanSize(copiedSize), "to", dstPath)
@ -369,6 +379,7 @@ func copyToContainer(ctx context.Context, dockerCli command.Cli, copyConfig cpCo
} }
if stderrIsTerm { if stderrIsTerm {
fmt.Fprint(dockerCli.Err(), aec.Hide)
fmt.Fprint(dockerCli.Err(), aec.Save) fmt.Fprint(dockerCli.Err(), aec.Save)
fmt.Fprintln(dockerCli.Err(), "Preparing to copy...") fmt.Fprintln(dockerCli.Err(), "Preparing to copy...")
} }
@ -376,6 +387,7 @@ func copyToContainer(ctx context.Context, dockerCli command.Cli, copyConfig cpCo
if stderrIsTerm { if stderrIsTerm {
fmt.Fprint(dockerCli.Err(), aec.Restore) fmt.Fprint(dockerCli.Err(), aec.Restore)
fmt.Fprint(dockerCli.Err(), aec.EraseLine(aec.EraseModes.All)) fmt.Fprint(dockerCli.Err(), aec.EraseLine(aec.EraseModes.All))
fmt.Fprint(dockerCli.Err(), aec.Show)
} }
fmt.Fprintln(dockerCli.Err(), "Successfully copied", units.HumanSize(copiedSize), "to", copyConfig.container+":"+dstInfo.Path) fmt.Fprintln(dockerCli.Err(), "Successfully copied", units.HumanSize(copiedSize), "to", copyConfig.container+":"+dstInfo.Path)