Coder Social home page Coder Social logo

schollz / progressbar Goto Github PK

View Code? Open in Web Editor NEW
3.8K 24.0 212.0 1.23 MB

A really basic thread-safe progress bar for Golang applications

Home Page: https://pkg.go.dev/github.com/schollz/progressbar/v3?tab=doc

License: MIT License

Go 100.00%
progress-bar golang progressbar library command-line go terminal hacktoberfest

progressbar's Introduction

progressbar

CI go report card coverage godocs

A very simple thread-safe progress bar which should work on every OS without problems. I needed a progressbar for croc and everything I tried had problems, so I made another one. In order to be OS agnostic I do not plan to support multi-line outputs.

Install

go get -u github.com/schollz/progressbar/v3

Usage

Basic usage

bar := progressbar.Default(100)
for i := 0; i < 100; i++ {
    bar.Add(1)
    time.Sleep(40 * time.Millisecond)
}

which looks like:

Example of basic bar

I/O operations

The progressbar implements an io.Writer so it can automatically detect the number of bytes written to a stream, so you can use it as a progressbar for an io.Reader.

req, _ := http.NewRequest("GET", "https://dl.google.com/go/go1.14.2.src.tar.gz", nil)
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()

f, _ := os.OpenFile("go1.14.2.src.tar.gz", os.O_CREATE|os.O_WRONLY, 0644)
defer f.Close()

bar := progressbar.DefaultBytes(
    resp.ContentLength,
    "downloading",
)
io.Copy(io.MultiWriter(f, bar), resp.Body)

which looks like:

Example of download bar

Progress bar with unknown length

A progressbar with unknown length is a spinner. Any bar with -1 length will automatically convert it to a spinner with a customizable spinner type. For example, the above code can be run and set the resp.ContentLength to -1.

which looks like:

Example of download bar with unknown length

Customization

There is a lot of customization that you can do - change the writer, the color, the width, description, theme, etc. See all the options.

bar := progressbar.NewOptions(1000,
    progressbar.OptionSetWriter(ansi.NewAnsiStdout()), //you should install "github.com/k0kubun/go-ansi"
    progressbar.OptionEnableColorCodes(true),
    progressbar.OptionShowBytes(true),
    progressbar.OptionSetWidth(15),
    progressbar.OptionSetDescription("[cyan][1/3][reset] Writing moshable file..."),
    progressbar.OptionSetTheme(progressbar.Theme{
        Saucer:        "[green]=[reset]",
        SaucerHead:    "[green]>[reset]",
        SaucerPadding: " ",
        BarStart:      "[",
        BarEnd:        "]",
    }))
for i := 0; i < 1000; i++ {
    bar.Add(1)
    time.Sleep(5 * time.Millisecond)
}

which looks like:

Example of customized bar

Contributing

Pull requests are welcome. Feel free to...

  • Revise documentation
  • Add new features
  • Fix bugs
  • Suggest improvements

Thanks

Thanks @Dynom for massive improvements in version 2.0!

Thanks @CrushedPixel for adding descriptions and color code support!

Thanks @MrMe42 for adding some minor features!

Thanks @tehstun for some great PRs!

Thanks @Benzammour and @haseth for helping create v3!

Thanks @briandowns for compiling the list of spinners.

License

MIT

progressbar's People

Contributors

bodgit avatar dynom avatar edigaryev avatar enihsyou avatar eogns47 avatar felicianotech avatar flowchartsman avatar haseth avatar hexnaught avatar kahlys avatar kiura avatar ma124 avatar makew0rld avatar michaeldorner avatar mrme42 avatar nathanbaulch avatar nilsbeck avatar oerlikon avatar olegchuev avatar rafaelmartins avatar richiesams avatar schollz avatar spakin avatar stephensli avatar t1moxa avatar talwat avatar tukaelu avatar vbauerster avatar virb3 avatar wystans avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

progressbar's Issues

Wrong import in example file

Now it tries to import

"github.com/schollz/progressbar/v2"

which fails, is suppose the '/v2' part should simply be removed

screen scrolling

my progressbar init:

        max := 10000
	writer := os.Stdout
	bar := progressbar.NewOptions(max,
		progressbar.OptionSetDescription(""),
		progressbar.OptionSetWriter(writer),
		progressbar.OptionSetWidth(50),
		progressbar.OptionThrottle(65*time.Millisecond),
		progressbar.OptionShowCount(),
		progressbar.OptionShowIts(),
		progressbar.OptionOnCompletion(func() {
			fmt.Fprint(writer, "\n")
		}),
		progressbar.OptionSpinnerType(14),
		progressbar.OptionFullWidth(),
	)
	_ = bar.RenderBlank()

	for i := 0; i <= max; i++ {
		bar.Add(1)
		time.Sleep(time.Millisecond * 50)
	}

2020-07-07 16 30 27
it starts scrolling.so what i can do?

Use by default `os.StdErr` for output

I know that with #11 support for specifying the output stream was added, and thus it is technically possible to use os.StdErr.

However given that such a library is most useful in CLI tools and filters (like sed, grep, etc.) that are part of a pipeline, having status printed on os.StdOut by default would take many (at least in the *NIX) world by surprise.

For example today I've tried integrating this library without thinking for a second it would clobber the standard output...

Therefore I would suggest making os.Stderr the default. (At least in a future version like v4 if backward compatibility is a major issue.)

Reader struct exported, but unusable due to unexported fields

It looks like you've created a wrapper for the Reader interface, but it's impossible to use, as you can't declare it in external packages as it has the unexported field "bar":

image

The Reader is exported as:

image

Is this a mistake, or is the Reader just a leftover experiment?

For my use case I'm opening a file (Reader) and feeding it to another component that expects a Reader. There is no writer involved.

Spinner not working

The spinner is not working for me. I try to use it when reading from os.Stdin:

r = progressbar.NewReader(os.Stdin, progressbar.DefaultBytes(-1, "Test"))

The resulting progress bar doesn't "spin", there is just a static character. Also the \n is not appended after completion.

I'm running this in zsh on macOS.

Progressbar in docker container

Not so much a bug as a request to see if someone can assist.

I have the progress bar in my app. If I run my app using go run main.go it works fine. However, if I run docker-container up --build it doesn't show the progress bar until it reaches 100%.

Does anyone know how what I should change to make it show the progress bar?

Display on StdErr

It would be nice if the progress bar would show on os.StdErr. My app has a lot of output which I want to redirect to a file, but still see the state of the progress bar.

Error with progress bar

After running the "make install" it's showing the following error:-

go generate ./templates
go: creating new go.mod: module github.com/blocklayerhq/chainkit
go: copying requirements from Gopkg.lock
go: github.com/schollz/[email protected]: go.mod has post-v0 module path "github.com/schollz/progressbar/v2" at revision 174fa38
go: error loading module requirements
make: *** [Makefile:13: generate] Error 1

what should I do, please help?

Names of examples erroneous

Go vet shows the following errors:

# github.com/schollz/progressbar/v2
./progressbar_test.go:39:1: ExampleProgressBarSet refers to unknown identifier: ProgressBarSet
./progressbar_test.go:46:1: ExampleProgressBarSet64 refers to unknown identifier: ProgressBarSet64
./progressbar_test.go:53:1: ExampleProgressBarBasic refers to unknown identifier: ProgressBarBasic
./progressbar_test.go:62:1: ExampleThrottle refers to unknown identifier: Throttle
./progressbar_test.go:73:1: ExampleChangeMax refers to unknown identifier: ChangeMax
./progressbar_test.go:79:1: ExampleFinish refers to unknown identifier: Finish
./progressbar_test.go:87:1: ExampleFinish2 refers to unknown identifier: Finish2
./progressbar_test.go:94:1: ExampleXOutOfY refers to unknown identifier: XOutOfY
./progressbar_test.go:103:1: ExampleSetBytes refers to unknown identifier: SetBytes
./progressbar_test.go:112:1: ExampleShowCount refers to unknown identifier: ShowCount
./progressbar_test.go:121:1: ExampleSetIts refers to unknown identifier: SetIts
./progressbar_test.go:331:1: ExampleDescribe refers to unknown identifier: Describe

For example ExampleProgressBarSet should be called ExampleProgressBar_Set to be detected properly as an example for the Set method. For more info see https://blog.golang.org/examples.

Additionally I'd suggest using the ioutil.TempFile function instead of explicitly creating a named file in TestReaderToFile and TestReaderToBuffer. TestReaderToBuffer does not actually to create a file at all.

If you like I can prepare a pull request.

Add a way to reduce flickering for ANSI code compatible environments

Since there is no way to determine if a terminal (emulator) supports certain ansi escape codes, it would be nice to offer a "option" that would allow to use ANSI escape codes to reduce terminal writes to the required minimum

This would allow for a more flicker-free experience (atleast for windows users)
currently the progressbar flickers when used in the "Windows Terminal", or a conhost environment.
This is due to the call to "clearProgressBar" which happens on every single render call.

func (p *ProgressBar) render() error {
    // ...
    
    // first, clear the existing progress bar
    err := clearProgressBar(p.config, p.state)
    if err != nil {
        return err
    }
    // either returns because finished, or renders current progress

by only calling the clear function if "finished" and otherwise appending the ANSI escape sequence of \033[0K to the rendered string, we can write a full clean line in just one write call, without a prior clear.

This however is only supported on terminal(emulators) that support ANSI escape sequences, like virtually every unix terminal and Windows 10 conhost (opt-in 1) and "Windows Terminal"

Before using the ANSI escape code option:
before

After:
after

I do not want the progressBar to implement windows specific code, but for it to offer a way to make use of ANSI escape sequences if a specific option is provided. e.g.

func OptionUseANSICodes(val bool) Option {
	return func(p *ProgressBar) {
		p.config.useANSICodes = val
	}
}

 
 
 
 
 
1 atleast ENABLE_VIRTUAL_TERMINAL_PROCESSING (0x04) must be enabled on the terminal output console handle (e.g. os.Stderr.Fd()) to support escape codes. This is easily achieved using syscall.LazyDll and calling the GetConsoleMode + SetConsoleMode Kernel32-APIs to enable the flags on demand.
This is code that shows how easy it can be to implement.
image

Multi Line

Will this do multi line outputs?

If so you may want to add that to the docs.

Feature request: add function to remove progressbar after 100%

Sometimes progress bar isn't the last thing in application output (and when it comes to 100% it might be good idea to replace the progress bar with something like "Operation finished, moving to next step". For this "replacement" a function that will erase progress bar from stdout may be useful.

Fix import path in examples

Trying to compile using the import "github.com/schollz/progressbar/v3" results in
main.go:4:2: cannot find package "github.com/schollz/progressbar/v3" in any of:
/usr/lib/go/src/github.com/schollz/progressbar/v3 (from $GOROOT)
/root/go/src/github.com/schollz/progressbar/v3 (from $GOPATH)

But it works when removing the v3 in the import: "github.com/schollz/progressbar"

Cannot push to the repo (for a pull request)

ERROR: Permission to schollz/progressbar.git denied to Kiura.
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

Sorry I am new to git cli, could you help me out here?

Confusing README

The README have functions, defined in v2 of library, but

go get -u github.com/schollz/progressbar

installs v1, so README examples are broken. The right way to install library is go get -u github.com/schollz/progressbar/v2.

custom io.Writer output

Hey,
this is a nice little library :)
I am trying to implement my own io.Writer to output to. Eventually I want to output the progress bar to a logging area I have put together in a terminal UI using this library however as a test case I have put together this:

import "github.com/schollz/progressbar"

type tmpStruct struct {
}

func (t *tmpStruct) Write(p []byte) (n int, err error) {
	fmt.Fprintf(os.Stdout, string(p[:]))
	return len(p), nil
}

func demoLoadingBarCount(maximumInt int) {
	var buf tmpStruct

	if bufWriter, ok := interface{}(buf).(io.Writer); ok {
		bar := progressbar.NewOptions(
			maximumInt,
			progressbar.OptionSetTheme(progressbar.Theme{Saucer: "#", SaucerPadding: "-", BarStart: ">", BarEnd: "<"}),
			progressbar.OptionSetWidth(10),
			progressbar.OptionSetWriter(bufWriter),
		)
		for i := 0; i < maximumInt; i++ {
			bar.Add(1)
			time.Sleep(10 * time.Millisecond)
		}
	}
}

The above seems to compile fine, but I don't see the progress bar on the terminal. Eventually I will change the os.Stdout to the writer of the terminal UI but for now I want to understand why the above isn't showing the terminal. Any help greatly appreciated.

Thanks

Feature request: unknown length (e.g. network io)

most IO progress implementations seem to only allow for a known fixed length denominator. in the case where the operation is for instance an HTTP POST, the total length/duration is not known and there doesn't seem to be a way to easily tie into the network layer to do a 'better' job. to satisfy this use case it would be great to have the progress bar simply ping back and forth, ping pong style, until progress bar Finish or Reset is called. Passing -1 perhaps to OptionSetWidth could be an approach to indicate unknown length.

Add an option to put the description after the bar

For my use case, I have a single progress bar that moves, but the description changes a lot more frequently, and putting that description before the bar would result in a lot of unwanted movement for the bar itself. Is it possible to tell progressbar to render the description after the bar?

Add IsFinished()

Being able to know when the progessbar is finished would be very helpful. The State() func is not helpful when the max is set to -1, aka when we don't know when the progress bar will end.

int64 for maxbytes

Anything against having int64 for maxBytes, currentNum and so on?
If we're processing a file, and we're using a progressbar, it's likely it's a huge file :)

int will do in 64bit OS, but not in 32bit one (such as raspbian)

OptionShowCount incorrectly renders with items below 1%

Currently, if a bar is created with maximum number of items X and then updated (.Add(i)) with i that is significantly lower than 1% of X (e.g. 0.1%), then the item count shown to the right of the bar ((n/X)) will only update when it has accumulated to a whole percentage value (e.g. 1%, 2%) and so on. When you have a lot of items in between, it looks really weird.

It is possible to introduce fractional percentage (which i guess will by default fix this behaviour), or somehow re-render the item count text on Add?

Throttle prevents initial RenderBlank from working

If you create a new default bar and immediately try to RenderBlank(), nothing will render. To work around this:

func NewBar(max int, description ...string) *progressbar.ProgressBar {
	bar := progressbar.Default(int64(max), description...)
	// wait for throttle duration so initial render doesn't skip
	time.Sleep(65 * time.Millisecond)
	bar.RenderBlank()
	return bar
}

Haven't tested, but I think the problem is the p.state.lastShown is set to time.Now() along with p.config.throttleDuration in:

func getBasicState() state {
	now := time.Now()
	return state{
		startTime:   now,
		lastShown:   now,
		counterTime: now,
	}
}

Maybe set lastShown to 0?

Cannot find package error Go version 1.13

Hi thanks for the package, I've run into a problem with the installation, same error as the others listed in schollz/croc#110.

Stack Trace:

jun ~ go get -u github.com/schollz/progressbar/v2
package github.com/schollz/progressbar/v2: cannot find package "github.com/schollz/progressbar/v2" in any of:
        /usr/lib/go/src/github.com/schollz/progressbar/v2 (from $GOROOT)
        /home/jun/go/src/github.com/schollz/progressbar/v2 (from $GOPATH)
jun ~ go version
go version go1.13 linux/amd64

However I'm running go 1.13. Is the only current solution using ?env:GO111MODULE=

Offer an initial view

Currently the progress bar renders itself once progression is added. However for lengty processes, it can take a while (in my case minutes) before anything shows. This isn't very user friendly and instead I would like the progress bar to render with a 0% state instead, giving some feedback that "it works".

Duplicate rendering of extra empty lines

When revert 3e6b9bf
Each time the progress bar is rendered, an empty line is added.

func main() {
	bar := progressbar.Default(100)
	for i := 0; i < 100; i++ {
		bar.Add(1)
		time.Sleep(40 * time.Millisecond)
	}
}

image

Cannot Install

When I try to install using λ › go get -u github.com/schollz/progressbar/v3 I get this error:

package github.com/schollz/progressbar/v3: cannot find package "github.com/schollz/progressbar/v3" in any of:
	/usr/lib/go/src/github.com/schollz/progressbar/v3 (from $GOROOT)
	/home/tozkoparan/go/src/github.com/schollz/progressbar/v3 (from $GOPATH)

cannot import - help

This is how I am trying to import it into my code :

import (
        ...
        ...
	"github.com/tidwall/gjson"
	"github.com/schollz/progressbar/v3"
)

And this is how I am running it

$ GO111MODULE=on go get -u github.com/schollz/progressbar/v3
go: downloading github.com/schollz/progressbar/v3 v3.5.1
go: downloading github.com/schollz/progressbar v1.0.0
go: github.com/schollz/progressbar/v3 upgrade => v3.5.1
go: downloading github.com/mattn/go-runewidth v0.0.9
go: downloading github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db
$ export GO111MODULE=on
$ go run main.go
main.go:18:2: cannot find module providing package github.com/schollz/progressbar/v3: working directory is not part of a module
main.go:17:2: cannot find module providing package github.com/tidwall/gjson: working directory is not part of a module

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.