7 Commits

Author SHA1 Message Date
Samuele Pedroni
f83b1f1560 many: progress bars should use the overridable stdouts (#12047)
making progress bars should take a stdout io.Writer

ToolingStore should carry an overridable stdout

make sure in image, preseed and cmd/snap code the overridable
top-level Stdout is passed along to make progress bars
2022-08-18 11:34:35 +02:00
Maciej Borzecki
476810b31c progress: fix progress bar with multibyte duration units
Some languages may use multibyte characters for duration. In such case, the
width of the progress bar would be incorrectly calculated, making the displayed
label too short.

At runtime this would randomly cause a panic with the translation used a
multibyte characters:

panic: runtime error: slice bounds out of range [80:79] [recovered]
 panic: runtime error: slice bounds out of range [80:79]

goroutine 1 [running]:
main.main.func1()
 github.com/snapcore/snapd/cmd/snap/main.go:477 +0x95
panic(0x561d5f7fac80, 0xc000144280)
 runtime/panic.go:679 +0x1b6
github.com/snapcore/snapd/progress.(*ANSIMeter).Set(0xc000214eb0, 0x41a891a000000000)
 github.com/snapcore/snapd/progress/ansimeter.go:152 +0xa1b
main.waitMixin.wait(0xc0002e42a0, 0x561d5f3e0000, 0xc0001e4488, 0x2, 0x0, 0x0, 0x0)
 github.com/snapcore/snapd/cmd/snap/wait.go:130 +0x700
main.(*cmdInstall).installOne(0xc000359040, 0x7ffcf44c33e4, 0xb, 0x0, 0x0, 0xc00036cba0, 0x561d5f805060, 0x561d5f8693a0)
 github.com/snapcore/snapd/cmd/snap/cmd_snap_op.go:491 +0x316
main.(*cmdInstall).Execute(0xc000359040, 0xc0003787a0, 0x0, 0x2, 0xc000359040, 0x1)
 github.com/snapcore/snapd/cmd/snap/cmd_snap_op.go:596 +0x3d7
github.com/snapcore/snapd/vendor/github.com/jessevdk/go-flags.(*Parser).ParseArgs(0xc000316bd0, 0xc000032190, 0x2, 0x2, 0xc000330330, 0xc0002a5cd0, 0x561d5ee49fbd, 0x561d5f7d08a0, 0xc000330330)
 github.com/snapcore/snapd/vendor/github.com/jessevdk/go-flags/parser.go:333 +0x8e7
github.com/snapcore/snapd/vendor/github.com/jessevdk/go-flags.(*Parser).Parse(...)
 github.com/snapcore/snapd/vendor/github.com/jessevdk/go-flags/parser.go:190
main.run(0xc0002a5de0, 0xe)
 github.com/snapcore/snapd/cmd/snap/main.go:515 +0xa7
main.main()
 github.com/snapcore/snapd/cmd/snap/main.go:482 +0x371

Since we are assuming that terminal can display up to the column number of
runes, fix the length calculation to use slices of runes for all
components (keep in mind that len(string) >= len([]rune)).

Fixes: https://bugs.launchpad.net/ubuntu/+source/snapd/+bug/1876583

Signed-off-by: Maciej Borzecki <maciej.zenon.borzecki@canonical.com>
2020-05-06 13:34:21 +02:00
John R. Lenton
f975cc3fa9 strutil/quantity: new package that exports formatFoo (from progress)
Package progress had some useful formatting functions (originally
taken from github.com/chipaca/quantity), that are more generally
useful. Circular imports mean they can't be in strutil directly
(quantity uses i18n which uses strutil), but strutil/quantity seems
fine to me.
2018-01-28 21:57:05 +00:00
John R. Lenton
5bc568771a progress: switch ansimeter's Spin() to use a spinner
People objected to ansimeter's use of a background throbber, and asked
for a textual spinner instead. I succumb to their wishes.
2018-01-09 12:22:28 +00:00
John R. Lenton
06e83b2e0e add unit tests for ansimeter; some tweaks for quantity corner cases 2017-10-06 13:54:57 +01:00
John R. Lenton
67a6df271f many: add copyright header 2017-09-26 07:02:11 -04:00
John R. Lenton
e67a2c0ddc many: implement our own ANSI-escape-using progress indicator
This introduces a `progress.Meter` written from "scratch" (mostly based on
previous work and experiments I did on IO progress bars and fixed-width
displays). It's called `progress.ANSIMeter`.

We were using a `progress.NullProgress` in situations where we actually didn't
want progress bars but still wanted notifications, so `progress.QuietMeter` is a
`progress.Meter` that does that, and that is returned by
`progress.MakeProgressBar()` when it doesn't think we have an actual terminal.

We were replacing `os.Stdout` to look at the output of progress bars, so I wrote
`progresstest.Meter` that just records what it's told instead of printing it
anywhere, and use it in some places.

I renamed `progress.NullProgress` to `progress.NullMeter`, and added
`progress.Null` as a default `progress.NullMeter`; as it's a `struct{}`, it
doesn't make sense not to use that (we were using `&progress.NullMeter{}` in
many many tests).

`image` was not calling `Finished()` on the progress bar, so I added code for it to
do that both in the sane case and in the case the user `^C`'s out.
2017-09-25 17:36:11 -04:00