progress

package module
v1.4.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 29, 2021 License: Apache-2.0, MIT Imports: 7 Imported by: 1

README

progress

😄 progress

go.dev reference License GitHub release Made by Manfred Touron

Go PR GolangCI codecov Go Report Card CodeFactor

Gitpod ready-to-code

Usage

TYPES

type Progress struct {
	Steps     []*Step   `json:"steps,omitempty"`
	CreatedAt time.Time `json:"created_at,omitempty"`

	// Has unexported fields.
}
    Progress is the top-level object of the 'progress' library.

func New() *Progress
    New creates and returns a new Progress.

func (p *Progress) AddStep(id string) *Step
    AddStep creates and returns a new Step with the provided 'id'. A non-empty,
    unique 'id' is required, else it will panic.

func (p *Progress) Get(id string) *Step
    Get retrieves a Step by its 'id'. A non-empty 'id' is required, else it will
    panic. If 'id' does not match an existing step, nil is returned.

func (p *Progress) MarshalJSON() ([]byte, error)
    MarshalJSON is a custom JSON marshaler that automatically computes and
    append the current snapshot.

func (p *Progress) Percent() float64
    Percent returns the current completion percentage, it's a faster alternative
    to Progress.Snapshot().Percent.

func (p *Progress) SafeAddStep(id string) (*Step, error)
    SafeAddStep is equivalent to AddStep with but returns error instead of
    panicking.

func (p *Progress) Snapshot() Snapshot
    Snapshot computes and returns the current stats of the Progress.

func (p *Progress) Subscribe(subscriber chan *Step)
    Subscribe register a provided chan as a target called each time a step is
    changed.

type Snapshot struct {
	State              State         `json:"state,omitempty"`
	Doing              string        `json:"doing,omitempty"`
	NotStarted         int           `json:"not_started,omitempty"`
	InProgress         int           `json:"in_progress,omitempty"`
	Completed          int           `json:"completed,omitempty"`
	Total              int           `json:"total,omitempty"`
	Percent            float64       `json:"percent,omitempty"`
	TotalDuration      time.Duration `json:"total_duration,omitempty"`
	StepDuration       time.Duration `json:"step_duration,omitempty"`
	CompletionEstimate time.Duration `json:"completion_estimate,omitempty"`
	DoneAt             *time.Time    `json:"done_at,omitempty"`
	StartedAt          *time.Time    `json:"started_at,omitempty"`
}
    Snapshot represents info and stats about a progress at a given time.

type State string

const (
	StateNotStarted State = "not started"
	StateInProgress State = "in progress"
	StateDone       State = "done"
)
type Step struct {
	ID          string      `json:"id,omitempty"`
	Description string      `json:"description,omitempty"`
	StartedAt   *time.Time  `json:"started_at,omitempty"`
	DoneAt      *time.Time  `json:"done_at,omitempty"`
	State       State       `json:"state,omitempty"`
	Data        interface{} `json:"data,omitempty"`

	// Has unexported fields.
}
    Step represents a progress step. It always have an 'id' and can be
    customized using helpers.

func (s *Step) Done()
    Done marks a step as done. If the step was already done, it panics.

func (s *Step) Duration() time.Duration
    Duration computes the step duration.

func (s *Step) MarshalJSON() ([]byte, error)
    MarshalJSON is a custom JSON marshaler that automatically computes and
    append some runtime metadata.

func (s *Step) SetAsCurrent()
    SetAsCurrent stops all in-progress steps and start this one.

func (s *Step) SetData(data interface{}) *Step
    SetData sets a custom step data. It returns itself (*Step) for chaining.

func (s *Step) SetDescription(desc string) *Step
    SetDescription sets a custom step description. It returns itself (*Step) for
    chaining.

func (s *Step) Start()
    Start marks a step as started. If a step was already InProgress or Done, it
    panics.

Example

import (
	"fmt"
	"time"

	"moul.io/progress"
	"moul.io/u"
)

func Example() {
	// initialize a new progress.Progress
	prog := progress.New()
	prog.AddStep("init").SetDescription("initialize")
	prog.AddStep("step1").SetDescription("step 1")
	prog.AddStep("step2").SetData([]string{"hello", "world"}).SetDescription("step 2")
	prog.AddStep("step3")
	prog.AddStep("finish")

	// automatically mark the last step as done when the function quit
	defer prog.Get("finish").Done()

	// mark init as Done
	prog.Get("init").Done()

	// mark step1 as started
	prog.Get("step1").SetData(42).Start()

	// then, mark it as done + attach custom data
	prog.Get("step1").SetData(1337).Done()

	// mark step2 as started
	prog.Get("step2").Start()

	fmt.Println(u.PrettyJSON(prog))

	// outputs something like this:
	// {
	//  "steps": [
	//    {
	//      "id": "init",
	//      "description": "initialize",
	//      "started_at": "2020-12-22T20:26:05.717427484+01:00",
	//      "done_at": "2020-12-22T20:26:05.717427484+01:00",
	//      "state": "done"
	//    },
	//    {
	//      "id": "step1",
	//      "description": "step 1",
	//      "started_at": "2020-12-22T20:26:05.71742797+01:00",
	//      "done_at": "2020-12-22T20:26:05.717428258+01:00",
	//      "state": "done",
	//      "data": 1337,
	//      "duration": 286
	//    },
	//    {
	//      "id": "step2",
	//      "description": "step 2",
	//      "started_at": "2020-12-22T20:26:05.71742865+01:00",
	//      "state": "in progress",
	//      "data": [
	//        "hello",
	//        "world"
	//      ],
	//      "duration": 496251
	//    },
	//    {
	//      "id": "step3"
	//    },
	//    {
	//      "id": "finish"
	//    }
	//  ],
	//  "created_at": "2020-12-22T20:26:05.717423018+01:00",
	//  "snapshot": {
	//    "state": "in progress",
	//    "doing": "step 2",
	//    "not_started": 2,
	//    "in_progress": 1,
	//    "completed": 2,
	//    "total": 5,
	//    "percent": 50,
	//    "total_duration": 25935,
	//    "started_at": "2020-12-22T20:26:05.717427484+01:00"
	//  }
	//}
}

func ExampleProgressSubscribe() {
	prog := progress.New()
	done := make(chan bool)
	ch := make(chan *progress.Step, 0)
	prog.Subscribe(ch)
	go func() {
		idx := 0
		for step := range ch {
			if step == nil {
				break
			}
			fmt.Println(idx, step.ID, step.State)
			idx++
		}
		done <- true
	}()
	time.Sleep(10 * time.Millisecond)
	prog.AddStep("step1").SetDescription("hello")
	prog.AddStep("step2")
	prog.Get("step1").Start()
	prog.Get("step2").Done()
	prog.AddStep("step3")
	prog.Get("step3").Start()
	prog.Get("step1").Done()
	prog.Get("step3").Done()
	// fmt.Println(u.PrettyJSON(prog))
	<-done
	close(ch)

	// Output:
	// 0 step1 not started
	// 1 step1 not started
	// 2 step2 not started
	// 3 step1 in progress
	// 4 step2 done
	// 5 step3 not started
	// 6 step3 in progress
	// 7 step1 done
	// 8 step3 done
}

Install

Using go
go get moul.io/progress

Contribute

I really welcome contributions. Your input is the most precious material. I'm well aware of that and I thank you in advance. Everyone is encouraged to look at what they can do on their own scale; no effort is too small.

Everything on contribution is sum up here: CONTRIBUTING.md

Contributors ✨

All Contributors

Thanks goes to these wonderful people (emoji key):


Manfred Touron

🚧 📖 ⚠️ 💻

moul-bot

🚧

This project follows the all-contributors specification. Contributions of any kind welcome!

Stargazers over time

Stargazers over time

License

© 2020 Manfred Touron

Licensed under the Apache License, Version 2.0 (LICENSE-APACHE) or the MIT license (LICENSE-MIT), at your option. See the COPYRIGHT file for more details.

SPDX-License-Identifier: (Apache-2.0 OR MIT)

Documentation

Overview

message from the author:

+--------------------------------------------------------------+
| * * * ░░░░░░░░░░░░░░░░░░░░  Hello  ░░░░░░░░░░░░░░░░░░░░░░░░░░|
+--------------------------------------------------------------+
|                                                              |
|     ++              ______________________________________   |
|     ++++           /                                      \  |
|      ++++          |                                      |  |
|    ++++++++++      |   Feel free to contribute to this    |  |
|   +++       |      |       project or contact me on       |  |
|   ++         |     |    manfred.life if you like this     |  |
|   +  -==   ==|     |               project!               |  |
|  (   <*>   <*>     |                                      |  |
|   |          |    /|                  :)                  |  |
|   |         _)   / |                                      |  |
|   |      +++    /  \______________________________________/  |
|    \      =+   /                                             |
|     \      +                                                 |
|     |\++++++                                                 |
|     |  ++++      ||//                                        |
|  ___|   |___    _||/__                                     __|
| /    ---    \   \|  |||                   __ _  ___  __ __/ /|
|/  |       |  \    \ /                    /  ' \/ _ \/ // / / |
||  |       |  |    | |                   /_/_/_/\___/\_,_/_/  |
+--------------------------------------------------------------+
Example
package main

import (
	"fmt"

	"moul.io/progress"
	"moul.io/u"
)

func main() {
	// initialize a new progress.Progress
	prog := progress.New()
	prog.AddStep("init").SetDescription("initialize")
	prog.AddStep("step1").SetDescription("step 1")
	prog.AddStep("step2").SetData([]string{"hello", "world"}).SetDescription("step 2")
	prog.AddStep("step3")
	prog.AddStep("finish")

	// automatically mark the last step as done when the function quit
	defer prog.Get("finish").Done()

	// mark init as Done
	prog.Get("init").Done()

	// mark step1 as started
	prog.Get("step1").SetData(42).Start()

	// then, mark it as done + attach custom data
	prog.Get("step1").SetData(1337).Done()

	// mark step2 as started
	prog.Get("step2").Start()

	fmt.Println(u.PrettyJSON(prog))

	// outputs something like this:
	// {
	//  "steps": [
	//    {
	//      "id": "init",
	//      "description": "initialize",
	//      "started_at": "2020-12-22T20:26:05.717427484+01:00",
	//      "done_at": "2020-12-22T20:26:05.717427484+01:00",
	//      "state": "done"
	//    },
	//    {
	//      "id": "step1",
	//      "description": "step 1",
	//      "started_at": "2020-12-22T20:26:05.71742797+01:00",
	//      "done_at": "2020-12-22T20:26:05.717428258+01:00",
	//      "state": "done",
	//      "data": 1337,
	//      "duration": 286
	//    },
	//    {
	//      "id": "step2",
	//      "description": "step 2",
	//      "started_at": "2020-12-22T20:26:05.71742865+01:00",
	//      "state": "in progress",
	//      "data": [
	//        "hello",
	//        "world"
	//      ],
	//      "duration": 496251
	//    },
	//    {
	//      "id": "step3"
	//    },
	//    {
	//      "id": "finish"
	//    }
	//  ],
	//  "created_at": "2020-12-22T20:26:05.717423018+01:00",
	//  "snapshot": {
	//    "state": "in progress",
	//    "doing": "step 2",
	//    "not_started": 2,
	//    "in_progress": 1,
	//    "completed": 2,
	//    "total": 5,
	//    "percent": 50,
	//    "total_duration": 25935,
	//    "started_at": "2020-12-22T20:26:05.717427484+01:00"
	//  }
	//}
}
Output:

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	ErrStepRequiresID       = errors.New("progress.AddStep requires a non-empty ID as argument")
	ErrStepIDShouldBeUnique = errors.New("progress.AddStep requires a unique ID as argument")
)

Functions

This section is empty.

Types

type Progress

type Progress struct {
	Steps     []*Step   `json:"steps,omitempty"`
	CreatedAt time.Time `json:"created_at,omitempty"`
	// contains filtered or unexported fields
}

Progress is the top-level object of the 'progress' library.

func New

func New() *Progress

New creates and returns a new Progress.

func (*Progress) AddStep

func (p *Progress) AddStep(id string) *Step

AddStep creates and returns a new Step with the provided 'id'. A non-empty, unique 'id' is required, else it will panic.

func (*Progress) Close

func (p *Progress) Close()

Close cleans up the allocated ressources.

func (*Progress) Get

func (p *Progress) Get(id string) *Step

Get retrieves a Step by its 'id'. A non-empty 'id' is required, else it will panic. If 'id' does not match an existing step, nil is returned.

func (*Progress) MarshalJSON

func (p *Progress) MarshalJSON() ([]byte, error)

MarshalJSON is a custom JSON marshaler that automatically computes and append the current snapshot.

func (*Progress) Progress

func (p *Progress) Progress() float64

Progress returns the current completion rate, it's a faster alternative to Progress.Snapshot().Progress. The returned value is between 0.0 and 1.0.

func (*Progress) SafeAddStep

func (p *Progress) SafeAddStep(id string) (*Step, error)

SafeAddStep is equivalent to AddStep with but returns error instead of panicking.

func (*Progress) Snapshot

func (p *Progress) Snapshot() Snapshot

Snapshot computes and returns the current stats of the Progress.

func (*Progress) Subscribe

func (p *Progress) Subscribe() chan *Step

Subscribe registers the provided chan as a target called each time a step is changed.

type Snapshot

type Snapshot struct {
	State              State         `json:"state,omitempty"`
	Doing              string        `json:"doing,omitempty"`
	NotStarted         int           `json:"not_started,omitempty"`
	InProgress         int           `json:"in_progress,omitempty"`
	Completed          int           `json:"completed,omitempty"`
	Total              int           `json:"total,omitempty"`
	Progress           float64       `json:"progress,omitempty"`
	TotalDuration      time.Duration `json:"total_duration,omitempty"`
	StepDuration       time.Duration `json:"step_duration,omitempty"`
	CompletionEstimate time.Duration `json:"completion_estimate,omitempty"`
	DoneAt             *time.Time    `json:"done_at,omitempty"`
	StartedAt          *time.Time    `json:"started_at,omitempty"`
}

Snapshot represents info and stats about a progress at a given time.

type State

type State string
const (
	StateNotStarted State = "not started"
	StateInProgress State = "in progress"
	StateDone       State = "done"
	StateStopped    State = "stopped"
)

type Step

type Step struct {
	ID          string      `json:"id,omitempty"`
	Description string      `json:"description,omitempty"`
	StartedAt   *time.Time  `json:"started_at,omitempty"`
	DoneAt      *time.Time  `json:"done_at,omitempty"`
	State       State       `json:"state,omitempty"`
	Data        interface{} `json:"data,omitempty"`
	Progress    float64     `json:"progress,omitempty"`
	// contains filtered or unexported fields
}

Step represents a progress step. It always have an 'id' and can be customized using helpers.

func (*Step) Done

func (s *Step) Done() *Step

Done marks a step as done. If the step was already done, it panics.

func (*Step) Duration

func (s *Step) Duration() time.Duration

Duration computes the step duration.

func (*Step) MarshalJSON

func (s *Step) MarshalJSON() ([]byte, error)

MarshalJSON is a custom JSON marshaler that automatically computes and append some runtime metadata.

func (*Step) SetAsCurrent

func (s *Step) SetAsCurrent() *Step

SetAsCurrent stops all in-progress steps and start this one.

func (*Step) SetData

func (s *Step) SetData(data interface{}) *Step

SetData sets a custom step data. It returns itself (*Step) for chaining.

func (*Step) SetDescription

func (s *Step) SetDescription(desc string) *Step

SetDescription sets a custom step description. It returns itself (*Step) for chaining.

func (*Step) SetProgress

func (s *Step) SetProgress(progress float64) *Step

SetProgress sets the current step progress rate. It may also update the current Step.State depending on the passed progress. The value should be something between 0.0 and 1.0.

func (*Step) Start

func (s *Step) Start() *Step

Start marks a step as started. If a step was already InProgress or Done, it panics.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL