mirror of
https://github.com/containers/podman
synced 2024-10-18 16:24:34 +00:00
Update from /github.com/vbauerster/mpb/v7 to /v8
Also update to c/image after https://github.com/containers/image/pull/1821 , so that we don't ship two versions of the package simultaneously. [NO NEW TESTS NEEDED] Signed-off-by: Miloslav Trmač <mitr@redhat.com>
This commit is contained in:
parent
e64508378f
commit
be47eeb85c
6
go.mod
6
go.mod
|
@ -14,7 +14,7 @@ require (
|
|||
github.com/containers/buildah v1.29.0
|
||||
github.com/containers/common v0.51.0
|
||||
github.com/containers/conmon v2.0.20+incompatible
|
||||
github.com/containers/image/v5 v5.24.0
|
||||
github.com/containers/image/v5 v5.24.1-0.20230202144111-a49c94a010be
|
||||
github.com/containers/ocicrypt v1.1.7
|
||||
github.com/containers/psgo v1.8.0
|
||||
github.com/containers/storage v1.45.3
|
||||
|
@ -57,7 +57,7 @@ require (
|
|||
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635
|
||||
github.com/uber/jaeger-client-go v2.30.0+incompatible
|
||||
github.com/ulikunitz/xz v0.5.11
|
||||
github.com/vbauerster/mpb/v7 v7.5.3
|
||||
github.com/vbauerster/mpb/v8 v8.1.4
|
||||
github.com/vishvananda/netlink v1.2.1-beta.2
|
||||
go.etcd.io/bbolt v1.3.7
|
||||
golang.org/x/net v0.5.0
|
||||
|
@ -153,7 +153,7 @@ require (
|
|||
github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980 // indirect
|
||||
github.com/sylabs/sif/v2 v2.9.0 // indirect
|
||||
github.com/tchap/go-patricia v2.3.0+incompatible // indirect
|
||||
github.com/theupdateframework/go-tuf v0.5.2-0.20221207161717-9cb61d6e65f5 // indirect
|
||||
github.com/theupdateframework/go-tuf v0.5.2 // indirect
|
||||
github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 // indirect
|
||||
github.com/vbatts/tar-split v0.11.2 // indirect
|
||||
github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f // indirect
|
||||
|
|
14
go.sum
14
go.sum
|
@ -272,8 +272,8 @@ github.com/containers/common v0.51.0 h1:Ax4YHNTG8cEPHZJcMYRoP7sfBgOISceeyOvmZzmS
|
|||
github.com/containers/common v0.51.0/go.mod h1:3W2WIdalgQfrsX/T5tjX+6CxgT3ThJVN2G9sNuFjuCM=
|
||||
github.com/containers/conmon v2.0.20+incompatible h1:YbCVSFSCqFjjVwHTPINGdMX1F6JXHGTUje2ZYobNrkg=
|
||||
github.com/containers/conmon v2.0.20+incompatible/go.mod h1:hgwZ2mtuDrppv78a/cOBNiCm6O0UMWGx1mu7P00nu5I=
|
||||
github.com/containers/image/v5 v5.24.0 h1:2Pu8ztTntqNxteVN15bORCQnM8rfnbYuyKwUiiKUBuc=
|
||||
github.com/containers/image/v5 v5.24.0/go.mod h1:oss5F6ssGQz8ZtC79oY+fuzYA3m3zBek9tq9gmhuvHc=
|
||||
github.com/containers/image/v5 v5.24.1-0.20230202144111-a49c94a010be h1:Bcsn9ohcVpCM9D2kZvIVMrO0QmmP87jhVZh/r9WrQ18=
|
||||
github.com/containers/image/v5 v5.24.1-0.20230202144111-a49c94a010be/go.mod h1:7Aonfvk5Wz0DLP40xgVSOGvygK3JXvDLxgotyGp4/KA=
|
||||
github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 h1:Qzk5C6cYglewc+UyGf6lc8Mj2UaPTHy/iF2De0/77CA=
|
||||
github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY=
|
||||
github.com/containers/ocicrypt v1.0.1/go.mod h1:MeJDzk1RJHv89LjsH0Sp5KTY3ZYkjXO/C+bKAeWFIrc=
|
||||
|
@ -756,7 +756,6 @@ github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNx
|
|||
github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
|
||||
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU=
|
||||
github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
|
||||
|
@ -1045,8 +1044,8 @@ github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG
|
|||
github.com/tchap/go-patricia v2.2.6+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I=
|
||||
github.com/tchap/go-patricia v2.3.0+incompatible h1:GkY4dP3cEfEASBPPkWd+AmjYxhmDkqO9/zg7R0lSQRs=
|
||||
github.com/tchap/go-patricia v2.3.0+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I=
|
||||
github.com/theupdateframework/go-tuf v0.5.2-0.20221207161717-9cb61d6e65f5 h1:s+Yvt6bzRwHljSE7j6DLBDcfpZEdBhrvLgOUmd8f7ZM=
|
||||
github.com/theupdateframework/go-tuf v0.5.2-0.20221207161717-9cb61d6e65f5/go.mod h1:Le8NAjvDJK1vmLgpVYr4AR1Tqam/b/mTdQyTy37UJDA=
|
||||
github.com/theupdateframework/go-tuf v0.5.2 h1:habfDzTmpbzBLIFGWa2ZpVhYvFBoK0C1onC3a4zuPRA=
|
||||
github.com/theupdateframework/go-tuf v0.5.2/go.mod h1:SyMV5kg5n4uEclsyxXJZI2UxPFJNDc4Y+r7wv+MlvTA=
|
||||
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
|
||||
github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 h1:e/5i7d4oYZ+C1wj2THlRK+oAhjeS/TRQwMfkIuet3w0=
|
||||
|
@ -1068,8 +1067,8 @@ github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtX
|
|||
github.com/urfave/cli v1.22.9/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/vbatts/tar-split v0.11.2 h1:Via6XqJr0hceW4wff3QRzD5gAk/tatMw/4ZA7cTlIME=
|
||||
github.com/vbatts/tar-split v0.11.2/go.mod h1:vV3ZuO2yWSVsz+pfFzDG/upWH1JhjOiEaWq6kXyQ3VI=
|
||||
github.com/vbauerster/mpb/v7 v7.5.3 h1:BkGfmb6nMrrBQDFECR/Q7RkKCw7ylMetCb4079CGs4w=
|
||||
github.com/vbauerster/mpb/v7 v7.5.3/go.mod h1:i+h4QY6lmLvBNK2ah1fSreiw3ajskRlBp9AhY/PnuOE=
|
||||
github.com/vbauerster/mpb/v8 v8.1.4 h1:MOcLTIbbAA892wVjRiuFHa1nRlNvifQMDVh12Bq/xIs=
|
||||
github.com/vbauerster/mpb/v8 v8.1.4/go.mod h1:2fRME8lCLU9gwJwghZb1bO9A3Plc8KPeQ/ayGj+Ek4I=
|
||||
github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
|
||||
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
|
||||
github.com/vishvananda/netlink v1.1.1-0.20201029203352-d40f9887b852/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho=
|
||||
|
@ -1402,7 +1401,6 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||
golang.org/x/sys v0.0.0-20220817070843-5a390386f1f2/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220823224334-20c2bfdbfe24/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220909162455-aba9fc2a8ff2/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18=
|
||||
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
|
|
|
@ -20,8 +20,8 @@ import (
|
|||
"github.com/containers/storage/pkg/archive"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/ulikunitz/xz"
|
||||
"github.com/vbauerster/mpb/v7"
|
||||
"github.com/vbauerster/mpb/v7/decor"
|
||||
"github.com/vbauerster/mpb/v8"
|
||||
"github.com/vbauerster/mpb/v8/decor"
|
||||
)
|
||||
|
||||
// GenericDownload is used when a user provides a URL
|
||||
|
|
2
vendor/github.com/containers/image/v5/copy/copy.go
generated
vendored
2
vendor/github.com/containers/image/v5/copy/copy.go
generated
vendored
|
@ -31,7 +31,7 @@ import (
|
|||
digest "github.com/opencontainers/go-digest"
|
||||
imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/vbauerster/mpb/v7"
|
||||
"github.com/vbauerster/mpb/v8"
|
||||
"golang.org/x/sync/semaphore"
|
||||
"golang.org/x/term"
|
||||
)
|
||||
|
|
4
vendor/github.com/containers/image/v5/copy/progress_bars.go
generated
vendored
4
vendor/github.com/containers/image/v5/copy/progress_bars.go
generated
vendored
|
@ -7,8 +7,8 @@ import (
|
|||
|
||||
"github.com/containers/image/v5/internal/private"
|
||||
"github.com/containers/image/v5/types"
|
||||
"github.com/vbauerster/mpb/v7"
|
||||
"github.com/vbauerster/mpb/v7/decor"
|
||||
"github.com/vbauerster/mpb/v8"
|
||||
"github.com/vbauerster/mpb/v8/decor"
|
||||
)
|
||||
|
||||
// newProgressPool creates a *mpb.Progress.
|
||||
|
|
16
vendor/github.com/containers/image/v5/docker/registries_d.go
generated
vendored
16
vendor/github.com/containers/image/v5/docker/registries_d.go
generated
vendored
|
@ -13,9 +13,9 @@ import (
|
|||
"github.com/containers/image/v5/internal/rootless"
|
||||
"github.com/containers/image/v5/types"
|
||||
"github.com/containers/storage/pkg/homedir"
|
||||
"github.com/ghodss/yaml"
|
||||
"github.com/opencontainers/go-digest"
|
||||
"github.com/sirupsen/logrus"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
// systemRegistriesDirPath is the path to registries.d, used for locating lookaside Docker signature storage.
|
||||
|
@ -39,18 +39,18 @@ var defaultDockerDir = "/var/lib/containers/sigstore"
|
|||
// registryConfiguration is one of the files in registriesDirPath configuring lookaside locations, or the result of merging them all.
|
||||
// NOTE: Keep this in sync with docs/registries.d.md!
|
||||
type registryConfiguration struct {
|
||||
DefaultDocker *registryNamespace `json:"default-docker"`
|
||||
DefaultDocker *registryNamespace `yaml:"default-docker"`
|
||||
// The key is a namespace, using fully-expanded Docker reference format or parent namespaces (per dockerReference.PolicyConfiguration*),
|
||||
Docker map[string]registryNamespace `json:"docker"`
|
||||
Docker map[string]registryNamespace `yaml:"docker"`
|
||||
}
|
||||
|
||||
// registryNamespace defines lookaside locations for a single namespace.
|
||||
type registryNamespace struct {
|
||||
Lookaside string `json:"lookaside"` // For reading, and if LookasideStaging is not present, for writing.
|
||||
LookasideStaging string `json:"lookaside-staging"` // For writing only.
|
||||
SigStore string `json:"sigstore"` // For compatibility, deprecated in favor of Lookaside.
|
||||
SigStoreStaging string `json:"sigstore-staging"` // For compatibility, deprecated in favor of LookasideStaging.
|
||||
UseSigstoreAttachments *bool `json:"use-sigstore-attachments,omitempty"`
|
||||
Lookaside string `yaml:"lookaside"` // For reading, and if LookasideStaging is not present, for writing.
|
||||
LookasideStaging string `yaml:"lookaside-staging"` // For writing only.
|
||||
SigStore string `yaml:"sigstore"` // For compatibility, deprecated in favor of Lookaside.
|
||||
SigStoreStaging string `yaml:"sigstore-staging"` // For compatibility, deprecated in favor of LookasideStaging.
|
||||
UseSigstoreAttachments *bool `yaml:"use-sigstore-attachments,omitempty"`
|
||||
}
|
||||
|
||||
// lookasideStorageBase is an "opaque" type representing a lookaside Docker signature storage.
|
||||
|
|
8
vendor/github.com/containers/image/v5/internal/manifest/errors.go
generated
vendored
8
vendor/github.com/containers/image/v5/internal/manifest/errors.go
generated
vendored
|
@ -2,6 +2,10 @@ package manifest
|
|||
|
||||
import "fmt"
|
||||
|
||||
// FIXME: This is a duplicate of c/image/manifestDockerV2Schema2ConfigMediaType.
|
||||
// Deduplicate that, depending on outcome of https://github.com/containers/image/pull/1791 .
|
||||
const dockerV2Schema2ConfigMediaType = "application/vnd.docker.container.image.v1+json"
|
||||
|
||||
// NonImageArtifactError (detected via errors.As) is used when asking for an image-specific operation
|
||||
// on an object which is not a “container image” in the standard sense (e.g. an OCI artifact)
|
||||
//
|
||||
|
@ -28,5 +32,9 @@ func NewNonImageArtifactError(mimeType string) error {
|
|||
}
|
||||
|
||||
func (e NonImageArtifactError) Error() string {
|
||||
// Special-case these invalid mixed images, which show up from time to time:
|
||||
if e.mimeType == dockerV2Schema2ConfigMediaType {
|
||||
return fmt.Sprintf("invalid mixed OCI image with Docker v2s2 config (%q)", e.mimeType)
|
||||
}
|
||||
return fmt.Sprintf("unsupported image-specific operation on artifact with type %q", e.mimeType)
|
||||
}
|
||||
|
|
83
vendor/github.com/containers/image/v5/openshift/openshift-copies.go
generated
vendored
83
vendor/github.com/containers/image/v5/openshift/openshift-copies.go
generated
vendored
|
@ -3,7 +3,7 @@ package openshift
|
|||
import (
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"encoding/json"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
|
@ -17,10 +17,10 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/containers/storage/pkg/homedir"
|
||||
"github.com/ghodss/yaml"
|
||||
"github.com/imdario/mergo"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/net/http2"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
// restTLSClientConfig is a modified copy of k8s.io/kubernetes/pkg/client/restclient.TLSClientConfig.
|
||||
|
@ -672,11 +672,7 @@ func load(data []byte) (*clientcmdConfig, error) {
|
|||
return config, nil
|
||||
}
|
||||
// Note: This does absolutely no kind/version checking or conversions.
|
||||
data, err := yaml.YAMLToJSON(data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := json.Unmarshal(data, config); err != nil {
|
||||
if err := yaml.Unmarshal(data, config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return config, nil
|
||||
|
@ -1057,20 +1053,20 @@ func (c *restConfig) HasCertAuth() bool {
|
|||
// IMPORTANT if you add fields to this struct, please update IsConfigEmpty()
|
||||
type clientcmdConfig struct {
|
||||
// Clusters is a map of referenceable names to cluster configs
|
||||
Clusters clustersMap `json:"clusters"`
|
||||
Clusters clustersMap `yaml:"clusters"`
|
||||
// AuthInfos is a map of referenceable names to user configs
|
||||
AuthInfos authInfosMap `json:"users"`
|
||||
AuthInfos authInfosMap `yaml:"users"`
|
||||
// Contexts is a map of referenceable names to context configs
|
||||
Contexts contextsMap `json:"contexts"`
|
||||
Contexts contextsMap `yaml:"contexts"`
|
||||
// CurrentContext is the name of the context that you would like to use by default
|
||||
CurrentContext string `json:"current-context"`
|
||||
CurrentContext string `yaml:"current-context"`
|
||||
}
|
||||
|
||||
type clustersMap map[string]*clientcmdCluster
|
||||
|
||||
func (m *clustersMap) UnmarshalJSON(data []byte) error {
|
||||
func (m *clustersMap) UnmarshalYAML(value *yaml.Node) error {
|
||||
var a []v1NamedCluster
|
||||
if err := json.Unmarshal(data, &a); err != nil {
|
||||
if err := value.Decode(&a); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, e := range a {
|
||||
|
@ -1082,9 +1078,9 @@ func (m *clustersMap) UnmarshalJSON(data []byte) error {
|
|||
|
||||
type authInfosMap map[string]*clientcmdAuthInfo
|
||||
|
||||
func (m *authInfosMap) UnmarshalJSON(data []byte) error {
|
||||
func (m *authInfosMap) UnmarshalYAML(value *yaml.Node) error {
|
||||
var a []v1NamedAuthInfo
|
||||
if err := json.Unmarshal(data, &a); err != nil {
|
||||
if err := value.Decode(&a); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, e := range a {
|
||||
|
@ -1096,9 +1092,9 @@ func (m *authInfosMap) UnmarshalJSON(data []byte) error {
|
|||
|
||||
type contextsMap map[string]*clientcmdContext
|
||||
|
||||
func (m *contextsMap) UnmarshalJSON(data []byte) error {
|
||||
func (m *contextsMap) UnmarshalYAML(value *yaml.Node) error {
|
||||
var a []v1NamedContext
|
||||
if err := json.Unmarshal(data, &a); err != nil {
|
||||
if err := value.Decode(&a); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, e := range a {
|
||||
|
@ -1118,19 +1114,32 @@ func clientcmdNewConfig() *clientcmdConfig {
|
|||
}
|
||||
}
|
||||
|
||||
// yamlBinaryAsBase64String is a []byte that can be stored in yaml as a !!str, not a !!binary
|
||||
type yamlBinaryAsBase64String []byte
|
||||
|
||||
func (bin *yamlBinaryAsBase64String) UnmarshalText(text []byte) error {
|
||||
res := make([]byte, base64.StdEncoding.DecodedLen(len(text)))
|
||||
n, err := base64.StdEncoding.Decode(res, text)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*bin = res[:n]
|
||||
return nil
|
||||
}
|
||||
|
||||
// clientcmdCluster is a modified copy of k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api.Cluster.
|
||||
// Cluster contains information about how to communicate with a kubernetes cluster
|
||||
type clientcmdCluster struct {
|
||||
// LocationOfOrigin indicates where this object came from. It is used for round tripping config post-merge, but never serialized.
|
||||
LocationOfOrigin string
|
||||
// Server is the address of the kubernetes cluster (https://hostname:port).
|
||||
Server string `json:"server"`
|
||||
Server string `yaml:"server"`
|
||||
// InsecureSkipTLSVerify skips the validity check for the server's certificate. This will make your HTTPS connections insecure.
|
||||
InsecureSkipTLSVerify bool `json:"insecure-skip-tls-verify,omitempty"`
|
||||
InsecureSkipTLSVerify bool `yaml:"insecure-skip-tls-verify,omitempty"`
|
||||
// CertificateAuthority is the path to a cert file for the certificate authority.
|
||||
CertificateAuthority string `json:"certificate-authority,omitempty"`
|
||||
CertificateAuthority string `yaml:"certificate-authority,omitempty"`
|
||||
// CertificateAuthorityData contains PEM-encoded certificate authority certificates. Overrides CertificateAuthority
|
||||
CertificateAuthorityData []byte `json:"certificate-authority-data,omitempty"`
|
||||
CertificateAuthorityData yamlBinaryAsBase64String `yaml:"certificate-authority-data,omitempty"`
|
||||
}
|
||||
|
||||
// clientcmdAuthInfo is a modified copy of k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api.AuthInfo.
|
||||
|
@ -1139,19 +1148,19 @@ type clientcmdAuthInfo struct {
|
|||
// LocationOfOrigin indicates where this object came from. It is used for round tripping config post-merge, but never serialized.
|
||||
LocationOfOrigin string
|
||||
// ClientCertificate is the path to a client cert file for TLS.
|
||||
ClientCertificate string `json:"client-certificate,omitempty"`
|
||||
ClientCertificate string `yaml:"client-certificate,omitempty"`
|
||||
// ClientCertificateData contains PEM-encoded data from a client cert file for TLS. Overrides ClientCertificate
|
||||
ClientCertificateData []byte `json:"client-certificate-data,omitempty"`
|
||||
ClientCertificateData yamlBinaryAsBase64String `yaml:"client-certificate-data,omitempty"`
|
||||
// ClientKey is the path to a client key file for TLS.
|
||||
ClientKey string `json:"client-key,omitempty"`
|
||||
ClientKey string `yaml:"client-key,omitempty"`
|
||||
// ClientKeyData contains PEM-encoded data from a client key file for TLS. Overrides ClientKey
|
||||
ClientKeyData []byte `json:"client-key-data,omitempty"`
|
||||
ClientKeyData yamlBinaryAsBase64String `yaml:"client-key-data,omitempty"`
|
||||
// Token is the bearer token for authentication to the kubernetes cluster.
|
||||
Token string `json:"token,omitempty"`
|
||||
Token string `yaml:"token,omitempty"`
|
||||
// Username is the username for basic authentication to the kubernetes cluster.
|
||||
Username string `json:"username,omitempty"`
|
||||
Username string `yaml:"username,omitempty"`
|
||||
// Password is the password for basic authentication to the kubernetes cluster.
|
||||
Password string `json:"password,omitempty"`
|
||||
Password string `yaml:"password,omitempty"`
|
||||
}
|
||||
|
||||
// clientcmdContext is a modified copy of k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api.Context.
|
||||
|
@ -1160,36 +1169,36 @@ type clientcmdContext struct {
|
|||
// LocationOfOrigin indicates where this object came from. It is used for round tripping config post-merge, but never serialized.
|
||||
LocationOfOrigin string
|
||||
// Cluster is the name of the cluster for this context
|
||||
Cluster string `json:"cluster"`
|
||||
Cluster string `yaml:"cluster"`
|
||||
// AuthInfo is the name of the authInfo for this context
|
||||
AuthInfo string `json:"user"`
|
||||
AuthInfo string `yaml:"user"`
|
||||
// Namespace is the default namespace to use on unspecified requests
|
||||
Namespace string `json:"namespace,omitempty"`
|
||||
Namespace string `yaml:"namespace,omitempty"`
|
||||
}
|
||||
|
||||
// v1NamedCluster is a modified copy of k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api.v1.NamedCluster.
|
||||
// NamedCluster relates nicknames to cluster information
|
||||
type v1NamedCluster struct {
|
||||
// Name is the nickname for this Cluster
|
||||
Name string `json:"name"`
|
||||
Name string `yaml:"name"`
|
||||
// Cluster holds the cluster information
|
||||
Cluster clientcmdCluster `json:"cluster"`
|
||||
Cluster clientcmdCluster `yaml:"cluster"`
|
||||
}
|
||||
|
||||
// v1NamedContext is a modified copy of k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api.v1.NamedContext.
|
||||
// NamedContext relates nicknames to context information
|
||||
type v1NamedContext struct {
|
||||
// Name is the nickname for this Context
|
||||
Name string `json:"name"`
|
||||
Name string `yaml:"name"`
|
||||
// Context holds the context information
|
||||
Context clientcmdContext `json:"context"`
|
||||
Context clientcmdContext `yaml:"context"`
|
||||
}
|
||||
|
||||
// v1NamedAuthInfo is a modified copy of k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api.v1.NamedAuthInfo.
|
||||
// NamedAuthInfo relates nicknames to auth information
|
||||
type v1NamedAuthInfo struct {
|
||||
// Name is the nickname for this AuthInfo
|
||||
Name string `json:"name"`
|
||||
Name string `yaml:"name"`
|
||||
// AuthInfo holds the auth information
|
||||
AuthInfo clientcmdAuthInfo `json:"user"`
|
||||
AuthInfo clientcmdAuthInfo `yaml:"user"`
|
||||
}
|
||||
|
|
4
vendor/github.com/containers/image/v5/version/version.go
generated
vendored
4
vendor/github.com/containers/image/v5/version/version.go
generated
vendored
|
@ -8,10 +8,10 @@ const (
|
|||
// VersionMinor is for functionality in a backwards-compatible manner
|
||||
VersionMinor = 24
|
||||
// VersionPatch is for backwards-compatible bug fixes
|
||||
VersionPatch = 0
|
||||
VersionPatch = 1
|
||||
|
||||
// VersionDev indicates development branch. Releases will be empty string.
|
||||
VersionDev = ""
|
||||
VersionDev = "-dev"
|
||||
)
|
||||
|
||||
// Version is the specification version that the package types support.
|
||||
|
|
91
vendor/github.com/vbauerster/mpb/v7/cwriter/writer.go
generated
vendored
91
vendor/github.com/vbauerster/mpb/v7/cwriter/writer.go
generated
vendored
|
@ -1,91 +0,0 @@
|
|||
package cwriter
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"io"
|
||||
"os"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// ErrNotTTY not a TeleTYpewriter error.
|
||||
var ErrNotTTY = errors.New("not a terminal")
|
||||
|
||||
// https://github.com/dylanaraps/pure-sh-bible#cursor-movement
|
||||
const (
|
||||
escOpen = "\x1b["
|
||||
cuuAndEd = "A\x1b[J"
|
||||
)
|
||||
|
||||
// Writer is a buffered the writer that updates the terminal. The
|
||||
// contents of writer will be flushed when Flush is called.
|
||||
type Writer struct {
|
||||
out io.Writer
|
||||
buf bytes.Buffer
|
||||
lines int // how much lines to clear before flushing new ones
|
||||
fd int
|
||||
terminal bool
|
||||
termSize func(int) (int, int, error)
|
||||
}
|
||||
|
||||
// New returns a new Writer with defaults.
|
||||
func New(out io.Writer) *Writer {
|
||||
w := &Writer{
|
||||
out: out,
|
||||
termSize: func(_ int) (int, int, error) {
|
||||
return -1, -1, ErrNotTTY
|
||||
},
|
||||
}
|
||||
if f, ok := out.(*os.File); ok {
|
||||
w.fd = int(f.Fd())
|
||||
if IsTerminal(w.fd) {
|
||||
w.terminal = true
|
||||
w.termSize = func(fd int) (int, int, error) {
|
||||
return GetSize(fd)
|
||||
}
|
||||
}
|
||||
}
|
||||
return w
|
||||
}
|
||||
|
||||
// Flush flushes the underlying buffer.
|
||||
func (w *Writer) Flush(lines int) (err error) {
|
||||
// some terminals interpret 'cursor up 0' as 'cursor up 1'
|
||||
if w.lines > 0 {
|
||||
err = w.clearLines()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
w.lines = lines
|
||||
_, err = w.buf.WriteTo(w.out)
|
||||
return
|
||||
}
|
||||
|
||||
// Write appends the contents of p to the underlying buffer.
|
||||
func (w *Writer) Write(p []byte) (n int, err error) {
|
||||
return w.buf.Write(p)
|
||||
}
|
||||
|
||||
// WriteString writes string to the underlying buffer.
|
||||
func (w *Writer) WriteString(s string) (n int, err error) {
|
||||
return w.buf.WriteString(s)
|
||||
}
|
||||
|
||||
// ReadFrom reads from the provided io.Reader and writes to the
|
||||
// underlying buffer.
|
||||
func (w *Writer) ReadFrom(r io.Reader) (n int64, err error) {
|
||||
return w.buf.ReadFrom(r)
|
||||
}
|
||||
|
||||
// GetTermSize returns WxH of underlying terminal.
|
||||
func (w *Writer) GetTermSize() (width, height int, err error) {
|
||||
return w.termSize(w.fd)
|
||||
}
|
||||
|
||||
func (w *Writer) ansiCuuAndEd() error {
|
||||
buf := make([]byte, 8)
|
||||
buf = strconv.AppendInt(buf[:copy(buf, escOpen)], int64(w.lines), 10)
|
||||
_, err := w.out.Write(append(buf, cuuAndEd...))
|
||||
return err
|
||||
}
|
26
vendor/github.com/vbauerster/mpb/v7/cwriter/writer_posix.go
generated
vendored
26
vendor/github.com/vbauerster/mpb/v7/cwriter/writer_posix.go
generated
vendored
|
@ -1,26 +0,0 @@
|
|||
// +build !windows
|
||||
|
||||
package cwriter
|
||||
|
||||
import (
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func (w *Writer) clearLines() error {
|
||||
return w.ansiCuuAndEd()
|
||||
}
|
||||
|
||||
// GetSize returns the dimensions of the given terminal.
|
||||
func GetSize(fd int) (width, height int, err error) {
|
||||
ws, err := unix.IoctlGetWinsize(fd, unix.TIOCGWINSZ)
|
||||
if err != nil {
|
||||
return -1, -1, err
|
||||
}
|
||||
return int(ws.Col), int(ws.Row), nil
|
||||
}
|
||||
|
||||
// IsTerminal returns whether the given file descriptor is a terminal.
|
||||
func IsTerminal(fd int) bool {
|
||||
_, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
|
||||
return err == nil
|
||||
}
|
10
vendor/github.com/vbauerster/mpb/v7/decor/optimistic_string_writer.go
generated
vendored
10
vendor/github.com/vbauerster/mpb/v7/decor/optimistic_string_writer.go
generated
vendored
|
@ -1,10 +0,0 @@
|
|||
package decor
|
||||
|
||||
import "io"
|
||||
|
||||
func mustWriteString(w io.Writer, s string) {
|
||||
_, err := io.WriteString(w, s)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
79
vendor/github.com/vbauerster/mpb/v7/proxyreader.go
generated
vendored
79
vendor/github.com/vbauerster/mpb/v7/proxyreader.go
generated
vendored
|
@ -1,79 +0,0 @@
|
|||
package mpb
|
||||
|
||||
import (
|
||||
"io"
|
||||
"time"
|
||||
)
|
||||
|
||||
type proxyReader struct {
|
||||
io.ReadCloser
|
||||
bar *Bar
|
||||
}
|
||||
|
||||
func (x proxyReader) Read(p []byte) (int, error) {
|
||||
n, err := x.ReadCloser.Read(p)
|
||||
x.bar.IncrBy(n)
|
||||
return n, err
|
||||
}
|
||||
|
||||
type proxyWriterTo struct {
|
||||
proxyReader
|
||||
wt io.WriterTo
|
||||
}
|
||||
|
||||
func (x proxyWriterTo) WriteTo(w io.Writer) (int64, error) {
|
||||
n, err := x.wt.WriteTo(w)
|
||||
x.bar.IncrInt64(n)
|
||||
return n, err
|
||||
}
|
||||
|
||||
type ewmaProxyReader struct {
|
||||
proxyReader
|
||||
}
|
||||
|
||||
func (x ewmaProxyReader) Read(p []byte) (int, error) {
|
||||
start := time.Now()
|
||||
n, err := x.proxyReader.Read(p)
|
||||
if n > 0 {
|
||||
x.bar.DecoratorEwmaUpdate(time.Since(start))
|
||||
}
|
||||
return n, err
|
||||
}
|
||||
|
||||
type ewmaProxyWriterTo struct {
|
||||
ewmaProxyReader
|
||||
wt proxyWriterTo
|
||||
}
|
||||
|
||||
func (x ewmaProxyWriterTo) WriteTo(w io.Writer) (int64, error) {
|
||||
start := time.Now()
|
||||
n, err := x.wt.WriteTo(w)
|
||||
if n > 0 {
|
||||
x.bar.DecoratorEwmaUpdate(time.Since(start))
|
||||
}
|
||||
return n, err
|
||||
}
|
||||
|
||||
func (b *Bar) newProxyReader(r io.Reader) (rc io.ReadCloser) {
|
||||
pr := proxyReader{toReadCloser(r), b}
|
||||
if wt, ok := r.(io.WriterTo); ok {
|
||||
pw := proxyWriterTo{pr, wt}
|
||||
if b.hasEwma {
|
||||
rc = ewmaProxyWriterTo{ewmaProxyReader{pr}, pw}
|
||||
} else {
|
||||
rc = pw
|
||||
}
|
||||
} else if b.hasEwma {
|
||||
rc = ewmaProxyReader{pr}
|
||||
} else {
|
||||
rc = pr
|
||||
}
|
||||
return rc
|
||||
}
|
||||
|
||||
func toReadCloser(r io.Reader) io.ReadCloser {
|
||||
if rc, ok := r.(io.ReadCloser); ok {
|
||||
return rc
|
||||
}
|
||||
return io.NopCloser(r)
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
# Multi Progress Bar
|
||||
|
||||
[![GoDoc](https://pkg.go.dev/badge/github.com/vbauerster/mpb)](https://pkg.go.dev/github.com/vbauerster/mpb/v7)
|
||||
[![GoDoc](https://pkg.go.dev/badge/github.com/vbauerster/mpb)](https://pkg.go.dev/github.com/vbauerster/mpb/v8)
|
||||
[![Test status](https://github.com/vbauerster/mpb/actions/workflows/test.yml/badge.svg)](https://github.com/vbauerster/mpb/actions/workflows/test.yml)
|
||||
[![Donate with PayPal](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.me/vbauerster)
|
||||
[![Lint status](https://github.com/vbauerster/mpb/actions/workflows/golangci-lint.yml/badge.svg)](https://github.com/vbauerster/mpb/actions/workflows/golangci-lint.yml)
|
||||
|
||||
**mpb** is a Go lib for rendering progress bars in terminal applications.
|
||||
|
||||
|
@ -26,8 +26,8 @@ import (
|
|||
"math/rand"
|
||||
"time"
|
||||
|
||||
"github.com/vbauerster/mpb/v7"
|
||||
"github.com/vbauerster/mpb/v7/decor"
|
||||
"github.com/vbauerster/mpb/v8"
|
||||
"github.com/vbauerster/mpb/v8/decor"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
@ -97,9 +97,8 @@ func main() {
|
|||
// EWMA's unit of measure is an iteration's duration
|
||||
start := time.Now()
|
||||
time.Sleep(time.Duration(rng.Intn(10)+1) * max / 10)
|
||||
bar.Increment()
|
||||
// we need to call DecoratorEwmaUpdate to fulfill ewma decorator's contract
|
||||
bar.DecoratorEwmaUpdate(time.Since(start))
|
||||
// we need to call EwmaIncrement to fulfill ewma decorator's contract
|
||||
bar.EwmaIncrement(time.Since(start))
|
||||
}
|
||||
}()
|
||||
}
|
429
vendor/github.com/vbauerster/mpb/v7/bar.go → vendor/github.com/vbauerster/mpb/v8/bar.go
generated
vendored
429
vendor/github.com/vbauerster/mpb/v7/bar.go → vendor/github.com/vbauerster/mpb/v8/bar.go
generated
vendored
|
@ -3,43 +3,40 @@ package mpb
|
|||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"runtime/debug"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/acarl005/stripansi"
|
||||
"github.com/mattn/go-runewidth"
|
||||
"github.com/vbauerster/mpb/v7/decor"
|
||||
"github.com/vbauerster/mpb/v8/decor"
|
||||
)
|
||||
|
||||
// Bar represents a progress bar.
|
||||
type Bar struct {
|
||||
index int // used by heap
|
||||
priority int // used by heap
|
||||
hasEwma bool
|
||||
frameCh chan *renderFrame
|
||||
operateState chan func(*bState)
|
||||
done chan struct{}
|
||||
container *Progress
|
||||
bs *bState
|
||||
cancel func()
|
||||
recoveredPanic interface{}
|
||||
index int // used by heap
|
||||
priority int // used by heap
|
||||
frameCh chan *renderFrame
|
||||
operateState chan func(*bState)
|
||||
done chan struct{}
|
||||
container *Progress
|
||||
bs *bState
|
||||
cancel func()
|
||||
}
|
||||
|
||||
type extenderFunc func(rows []io.Reader, width int, stat decor.Statistics) []io.Reader
|
||||
type syncTable [2][]chan int
|
||||
type extenderFunc func([]io.Reader, decor.Statistics) ([]io.Reader, error)
|
||||
|
||||
// bState is actual bar's state.
|
||||
type bState struct {
|
||||
id int
|
||||
priority int
|
||||
reqWidth int
|
||||
shutdown int
|
||||
total int64
|
||||
current int64
|
||||
refill int64
|
||||
lastIncrement int64
|
||||
trimSpace bool
|
||||
completed bool
|
||||
aborted bool
|
||||
|
@ -55,7 +52,7 @@ type bState struct {
|
|||
filler BarFiller
|
||||
middleware func(BarFiller) BarFiller
|
||||
extender extenderFunc
|
||||
debugOut io.Writer
|
||||
manualRefresh chan interface{}
|
||||
|
||||
wait struct {
|
||||
bar *Bar // key for (*pState).queueBars
|
||||
|
@ -65,7 +62,8 @@ type bState struct {
|
|||
|
||||
type renderFrame struct {
|
||||
rows []io.Reader
|
||||
shutdown int
|
||||
shutdown bool
|
||||
err error
|
||||
}
|
||||
|
||||
func newBar(container *Progress, bs *bState) *Bar {
|
||||
|
@ -73,7 +71,6 @@ func newBar(container *Progress, bs *bState) *Bar {
|
|||
|
||||
bar := &Bar{
|
||||
priority: bs.priority,
|
||||
hasEwma: len(bs.ewmaDecorators) != 0,
|
||||
frameCh: make(chan *renderFrame, 1),
|
||||
operateState: make(chan func(*bState)),
|
||||
done: make(chan struct{}),
|
||||
|
@ -85,20 +82,37 @@ func newBar(container *Progress, bs *bState) *Bar {
|
|||
return bar
|
||||
}
|
||||
|
||||
// ProxyReader wraps r with metrics required for progress tracking.
|
||||
// If r is 'unknown total/size' reader it's mandatory to call
|
||||
// (*Bar).SetTotal(-1, true) method after (Reader).Read returns io.EOF.
|
||||
// Panics if r is nil. If bar is already completed or aborted, returns
|
||||
// nil.
|
||||
// ProxyReader wraps io.Reader with metrics required for progress tracking.
|
||||
// If `r` is 'unknown total/size' reader it's mandatory to call
|
||||
// (*Bar).SetTotal(-1, true) method after (io.Reader).Read returns io.EOF.
|
||||
// If bar is already completed or aborted, returns nil.
|
||||
// Panics if `r` is nil.
|
||||
func (b *Bar) ProxyReader(r io.Reader) io.ReadCloser {
|
||||
if r == nil {
|
||||
panic("expected non nil io.Reader")
|
||||
}
|
||||
result := make(chan bool)
|
||||
select {
|
||||
case b.operateState <- func(s *bState) { result <- len(s.ewmaDecorators) != 0 }:
|
||||
return newProxyReader(r, b, <-result)
|
||||
case <-b.done:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// ProxyWriter wraps io.Writer with metrics required for progress tracking.
|
||||
// If bar is already completed or aborted, returns nil.
|
||||
// Panics if `w` is nil.
|
||||
func (b *Bar) ProxyWriter(w io.Writer) io.WriteCloser {
|
||||
if w == nil {
|
||||
panic("expected non nil io.Writer")
|
||||
}
|
||||
result := make(chan bool)
|
||||
select {
|
||||
case b.operateState <- func(s *bState) { result <- len(s.ewmaDecorators) != 0 }:
|
||||
return newProxyWriter(w, b, <-result)
|
||||
case <-b.done:
|
||||
return nil
|
||||
default:
|
||||
return b.newProxyReader(r)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -142,7 +156,8 @@ func (b *Bar) TraverseDecorators(cb func(decor.Decorator)) {
|
|||
sync := make(chan struct{})
|
||||
select {
|
||||
case b.operateState <- func(s *bState) {
|
||||
for _, decorators := range [...][]decor.Decorator{
|
||||
defer close(sync)
|
||||
for _, decorators := range [][]decor.Decorator{
|
||||
s.pDecorators,
|
||||
s.aDecorators,
|
||||
} {
|
||||
|
@ -150,7 +165,6 @@ func (b *Bar) TraverseDecorators(cb func(decor.Decorator)) {
|
|||
cb(extractBaseDecorator(d))
|
||||
}
|
||||
}
|
||||
close(sync)
|
||||
}:
|
||||
<-sync
|
||||
case <-b.done:
|
||||
|
@ -158,7 +172,7 @@ func (b *Bar) TraverseDecorators(cb func(decor.Decorator)) {
|
|||
}
|
||||
|
||||
// EnableTriggerComplete enables triggering complete event. It's
|
||||
// effective only for bar which was constructed with `total <= 0` and
|
||||
// effective only for bars which were constructed with `total <= 0` and
|
||||
// after total has been set with (*Bar).SetTotal(int64, false). If bar
|
||||
// has been incremented to the total, complete event is triggered right
|
||||
// away.
|
||||
|
@ -171,7 +185,7 @@ func (b *Bar) EnableTriggerComplete() {
|
|||
if s.current >= s.total {
|
||||
s.current = s.total
|
||||
s.completed = true
|
||||
go b.forceRefresh()
|
||||
b.forceRefresh(s.manualRefresh)
|
||||
} else {
|
||||
s.triggerComplete = true
|
||||
}
|
||||
|
@ -182,7 +196,7 @@ func (b *Bar) EnableTriggerComplete() {
|
|||
|
||||
// SetTotal sets total to an arbitrary value. It's effective only for
|
||||
// bar which was constructed with `total <= 0`. Setting total to negative
|
||||
// value is equivalent to (*Bar).SetTotal((*Bar).Current(), bool).
|
||||
// value is equivalent to (*Bar).SetTotal((*Bar).Current(), bool) but faster.
|
||||
// If triggerCompleteNow is true, total value is set to current and
|
||||
// complete event is triggered right away.
|
||||
func (b *Bar) SetTotal(total int64, triggerCompleteNow bool) {
|
||||
|
@ -199,7 +213,7 @@ func (b *Bar) SetTotal(total int64, triggerCompleteNow bool) {
|
|||
if triggerCompleteNow {
|
||||
s.current = s.total
|
||||
s.completed = true
|
||||
go b.forceRefresh()
|
||||
b.forceRefresh(s.manualRefresh)
|
||||
}
|
||||
}:
|
||||
case <-b.done:
|
||||
|
@ -207,16 +221,39 @@ func (b *Bar) SetTotal(total int64, triggerCompleteNow bool) {
|
|||
}
|
||||
|
||||
// SetCurrent sets progress' current to an arbitrary value.
|
||||
// Setting a negative value will cause a panic.
|
||||
func (b *Bar) SetCurrent(current int64) {
|
||||
if current < 0 {
|
||||
return
|
||||
}
|
||||
select {
|
||||
case b.operateState <- func(s *bState) {
|
||||
s.lastIncrement = current - s.current
|
||||
s.current = current
|
||||
if s.triggerComplete && s.current >= s.total {
|
||||
s.current = s.total
|
||||
s.completed = true
|
||||
go b.forceRefresh()
|
||||
b.forceRefresh(s.manualRefresh)
|
||||
}
|
||||
}:
|
||||
case <-b.done:
|
||||
}
|
||||
}
|
||||
|
||||
// EwmaSetCurrent sets progress' current to an arbitrary value and updates
|
||||
// EWMA based decorators by dur of a single iteration.
|
||||
func (b *Bar) EwmaSetCurrent(current int64, iterDur time.Duration) {
|
||||
if current < 0 {
|
||||
return
|
||||
}
|
||||
select {
|
||||
case b.operateState <- func(s *bState) {
|
||||
if n := current - s.current; n > 0 {
|
||||
s.ewmaUpdate(n, iterDur)
|
||||
}
|
||||
s.current = current
|
||||
if s.triggerComplete && s.current >= s.total {
|
||||
s.current = s.total
|
||||
s.completed = true
|
||||
b.forceRefresh(s.manualRefresh)
|
||||
}
|
||||
}:
|
||||
case <-b.done:
|
||||
|
@ -240,37 +277,44 @@ func (b *Bar) IncrInt64(n int64) {
|
|||
}
|
||||
select {
|
||||
case b.operateState <- func(s *bState) {
|
||||
s.lastIncrement = n
|
||||
s.current += n
|
||||
if s.triggerComplete && s.current >= s.total {
|
||||
s.current = s.total
|
||||
s.completed = true
|
||||
go b.forceRefresh()
|
||||
b.forceRefresh(s.manualRefresh)
|
||||
}
|
||||
}:
|
||||
case <-b.done:
|
||||
}
|
||||
}
|
||||
|
||||
// DecoratorEwmaUpdate updates all EWMA based decorators. Should be
|
||||
// called on each iteration, because EWMA's unit of measure is an
|
||||
// iteration's duration. Panics if called before *Bar.Incr... family
|
||||
// methods.
|
||||
func (b *Bar) DecoratorEwmaUpdate(dur time.Duration) {
|
||||
// EwmaIncrement is a shorthand for b.EwmaIncrInt64(1, iterDur).
|
||||
func (b *Bar) EwmaIncrement(iterDur time.Duration) {
|
||||
b.EwmaIncrInt64(1, iterDur)
|
||||
}
|
||||
|
||||
// EwmaIncrBy is a shorthand for b.EwmaIncrInt64(int64(n), iterDur).
|
||||
func (b *Bar) EwmaIncrBy(n int, iterDur time.Duration) {
|
||||
b.EwmaIncrInt64(int64(n), iterDur)
|
||||
}
|
||||
|
||||
// EwmaIncrInt64 increments progress by amount of n and updates EWMA based
|
||||
// decorators by dur of a single iteration.
|
||||
func (b *Bar) EwmaIncrInt64(n int64, iterDur time.Duration) {
|
||||
if n <= 0 {
|
||||
return
|
||||
}
|
||||
select {
|
||||
case b.operateState <- func(s *bState) {
|
||||
if s.lastIncrement > 0 {
|
||||
s.decoratorEwmaUpdate(dur)
|
||||
s.lastIncrement = 0
|
||||
} else {
|
||||
panic("increment required before ewma iteration update")
|
||||
s.ewmaUpdate(n, iterDur)
|
||||
s.current += n
|
||||
if s.triggerComplete && s.current >= s.total {
|
||||
s.current = s.total
|
||||
s.completed = true
|
||||
b.forceRefresh(s.manualRefresh)
|
||||
}
|
||||
}:
|
||||
case <-b.done:
|
||||
if b.bs.lastIncrement > 0 {
|
||||
b.bs.decoratorEwmaUpdate(dur)
|
||||
b.bs.lastIncrement = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -305,7 +349,7 @@ func (b *Bar) Abort(drop bool) {
|
|||
}
|
||||
s.aborted = true
|
||||
s.dropOnComplete = drop
|
||||
go b.forceRefresh()
|
||||
b.forceRefresh(s.manualRefresh)
|
||||
}:
|
||||
case <-b.done:
|
||||
}
|
||||
|
@ -333,6 +377,20 @@ func (b *Bar) Completed() bool {
|
|||
}
|
||||
}
|
||||
|
||||
// IsRunning reports whether the bar is running, i.e. not yet completed
|
||||
// and not yet aborted.
|
||||
func (b *Bar) IsRunning() bool {
|
||||
result := make(chan bool)
|
||||
select {
|
||||
case b.operateState <- func(s *bState) {
|
||||
result <- !s.completed && !s.aborted
|
||||
}:
|
||||
return <-result
|
||||
case <-b.done:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// Wait blocks until bar is completed or aborted.
|
||||
func (b *Bar) Wait() {
|
||||
<-b.done
|
||||
|
@ -358,74 +416,54 @@ func (b *Bar) serve(ctx context.Context, bs *bState) {
|
|||
}
|
||||
|
||||
func (b *Bar) render(tw int) {
|
||||
select {
|
||||
case b.operateState <- func(s *bState) {
|
||||
var done bool
|
||||
fn := func(s *bState) {
|
||||
var rows []io.Reader
|
||||
stat := newStatistics(tw, s)
|
||||
defer func() {
|
||||
// recovering if user defined decorator panics for example
|
||||
if p := recover(); p != nil {
|
||||
if s.debugOut != nil {
|
||||
for _, fn := range []func() (int, error){
|
||||
func() (int, error) {
|
||||
return fmt.Fprintln(s.debugOut, p)
|
||||
},
|
||||
func() (int, error) {
|
||||
return s.debugOut.Write(debug.Stack())
|
||||
},
|
||||
} {
|
||||
if _, err := fn(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
s.aborted = !s.completed
|
||||
s.extender = makePanicExtender(p)
|
||||
b.recoveredPanic = p
|
||||
}
|
||||
if fn := s.extender; fn != nil {
|
||||
rows = fn(rows, s.reqWidth, stat)
|
||||
}
|
||||
frame := &renderFrame{
|
||||
rows: rows,
|
||||
}
|
||||
if s.completed || s.aborted {
|
||||
b.cancel()
|
||||
frame.shutdown++
|
||||
}
|
||||
b.frameCh <- frame
|
||||
}()
|
||||
if b.recoveredPanic == nil {
|
||||
rows = append(rows, s.draw(stat))
|
||||
r, err := s.draw(stat)
|
||||
if err != nil {
|
||||
b.frameCh <- &renderFrame{err: err}
|
||||
return
|
||||
}
|
||||
}:
|
||||
case <-b.done:
|
||||
var rows []io.Reader
|
||||
s, stat := b.bs, newStatistics(tw, b.bs)
|
||||
if b.recoveredPanic == nil {
|
||||
rows = append(rows, s.draw(stat))
|
||||
rows = append(rows, r)
|
||||
if s.extender != nil {
|
||||
rows, err = s.extender(rows, stat)
|
||||
if err != nil {
|
||||
b.frameCh <- &renderFrame{err: err}
|
||||
return
|
||||
}
|
||||
}
|
||||
if fn := s.extender; fn != nil {
|
||||
rows = fn(rows, s.reqWidth, stat)
|
||||
}
|
||||
frame := &renderFrame{
|
||||
rows: rows,
|
||||
frame := &renderFrame{rows: rows}
|
||||
if s.completed || s.aborted {
|
||||
frame.shutdown = !done || s.shutdown == 1
|
||||
b.cancel()
|
||||
}
|
||||
b.frameCh <- frame
|
||||
}
|
||||
select {
|
||||
case b.operateState <- fn:
|
||||
case <-b.done:
|
||||
done = true
|
||||
fn(b.bs)
|
||||
}
|
||||
}
|
||||
|
||||
func (b *Bar) forceRefresh() {
|
||||
func (b *Bar) forceRefresh(refreshCh chan interface{}) {
|
||||
b.container.bwg.Add(1)
|
||||
go b.forceRefreshImpl(refreshCh)
|
||||
}
|
||||
|
||||
func (b *Bar) forceRefreshImpl(refreshCh chan interface{}) {
|
||||
defer b.container.bwg.Done()
|
||||
var anyOtherRunning bool
|
||||
b.container.traverseBars(func(bar *Bar) bool {
|
||||
anyOtherRunning = b != bar && bar.isRunning()
|
||||
anyOtherRunning = b != bar && bar.IsRunning()
|
||||
return !anyOtherRunning
|
||||
})
|
||||
if !anyOtherRunning {
|
||||
for {
|
||||
select {
|
||||
case b.container.refreshCh <- time.Now():
|
||||
time.Sleep(prr)
|
||||
case refreshCh <- time.Now():
|
||||
case <-b.done:
|
||||
return
|
||||
}
|
||||
|
@ -433,20 +471,8 @@ func (b *Bar) forceRefresh() {
|
|||
}
|
||||
}
|
||||
|
||||
func (b *Bar) isRunning() bool {
|
||||
result := make(chan bool)
|
||||
select {
|
||||
case b.operateState <- func(s *bState) {
|
||||
result <- !s.completed && !s.aborted
|
||||
}:
|
||||
return <-result
|
||||
case <-b.done:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func (b *Bar) wSyncTable() [][]chan int {
|
||||
result := make(chan [][]chan int)
|
||||
func (b *Bar) wSyncTable() syncTable {
|
||||
result := make(chan syncTable)
|
||||
select {
|
||||
case b.operateState <- func(s *bState) { result <- s.wSyncTable() }:
|
||||
return <-result
|
||||
|
@ -455,68 +481,111 @@ func (b *Bar) wSyncTable() [][]chan int {
|
|||
}
|
||||
}
|
||||
|
||||
func (s *bState) draw(stat decor.Statistics) io.Reader {
|
||||
bufP, bufB, bufA := s.buffers[0], s.buffers[1], s.buffers[2]
|
||||
nlr := bytes.NewReader([]byte("\n"))
|
||||
tw := stat.AvailableWidth
|
||||
for _, d := range s.pDecorators {
|
||||
str := d.Decor(stat)
|
||||
stat.AvailableWidth -= runewidth.StringWidth(stripansi.Strip(str))
|
||||
bufP.WriteString(str)
|
||||
func (s *bState) draw(stat decor.Statistics) (io.Reader, error) {
|
||||
r, err := s.drawImpl(stat)
|
||||
if err != nil {
|
||||
for _, b := range s.buffers {
|
||||
b.Reset()
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
if stat.AvailableWidth < 1 {
|
||||
trunc := strings.NewReader(runewidth.Truncate(stripansi.Strip(bufP.String()), tw, "…"))
|
||||
bufP.Reset()
|
||||
return io.MultiReader(trunc, nlr)
|
||||
}
|
||||
|
||||
if !s.trimSpace && stat.AvailableWidth > 1 {
|
||||
stat.AvailableWidth -= 2
|
||||
bufB.WriteByte(' ')
|
||||
defer bufB.WriteByte(' ')
|
||||
}
|
||||
|
||||
tw = stat.AvailableWidth
|
||||
for _, d := range s.aDecorators {
|
||||
str := d.Decor(stat)
|
||||
stat.AvailableWidth -= runewidth.StringWidth(stripansi.Strip(str))
|
||||
bufA.WriteString(str)
|
||||
}
|
||||
if stat.AvailableWidth < 1 {
|
||||
trunc := strings.NewReader(runewidth.Truncate(stripansi.Strip(bufA.String()), tw, "…"))
|
||||
bufA.Reset()
|
||||
return io.MultiReader(bufP, bufB, trunc, nlr)
|
||||
}
|
||||
|
||||
s.filler.Fill(bufB, s.reqWidth, stat)
|
||||
|
||||
return io.MultiReader(bufP, bufB, bufA, nlr)
|
||||
return io.MultiReader(r, strings.NewReader("\n")), nil
|
||||
}
|
||||
|
||||
func (s *bState) wSyncTable() [][]chan int {
|
||||
columns := make([]chan int, 0, len(s.pDecorators)+len(s.aDecorators))
|
||||
var pCount int
|
||||
for _, d := range s.pDecorators {
|
||||
if ch, ok := d.Sync(); ok {
|
||||
columns = append(columns, ch)
|
||||
pCount++
|
||||
func (s *bState) drawImpl(stat decor.Statistics) (io.Reader, error) {
|
||||
decorFiller := func(buf *bytes.Buffer, decorators []decor.Decorator) (res struct {
|
||||
width int
|
||||
truncate bool
|
||||
err error
|
||||
}) {
|
||||
res.width = stat.AvailableWidth
|
||||
for _, d := range decorators {
|
||||
str := d.Decor(stat)
|
||||
if stat.AvailableWidth > 0 {
|
||||
stat.AvailableWidth -= runewidth.StringWidth(stripansi.Strip(str))
|
||||
if res.err == nil {
|
||||
_, res.err = buf.WriteString(str)
|
||||
}
|
||||
}
|
||||
}
|
||||
res.truncate = stat.AvailableWidth < 0
|
||||
return res
|
||||
}
|
||||
|
||||
bufP, bufB, bufA := s.buffers[0], s.buffers[1], s.buffers[2]
|
||||
|
||||
resP := decorFiller(bufP, s.pDecorators)
|
||||
resA := decorFiller(bufA, s.aDecorators)
|
||||
|
||||
for _, err := range []error{resP.err, resA.err} {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
var aCount int
|
||||
for _, d := range s.aDecorators {
|
||||
if ch, ok := d.Sync(); ok {
|
||||
columns = append(columns, ch)
|
||||
aCount++
|
||||
|
||||
if resP.truncate {
|
||||
trunc := strings.NewReader(runewidth.Truncate(stripansi.Strip(bufP.String()), resP.width, "…"))
|
||||
bufP.Reset()
|
||||
bufA.Reset()
|
||||
return trunc, nil
|
||||
}
|
||||
|
||||
if resA.truncate {
|
||||
trunc := strings.NewReader(runewidth.Truncate(stripansi.Strip(bufA.String()), resA.width, "…"))
|
||||
bufA.Reset()
|
||||
return io.MultiReader(bufP, trunc), nil
|
||||
}
|
||||
|
||||
if !s.trimSpace && stat.AvailableWidth >= 2 {
|
||||
stat.AvailableWidth -= 2
|
||||
writeFiller := func(buf *bytes.Buffer) error {
|
||||
return s.filler.Fill(buf, stat)
|
||||
}
|
||||
for _, fn := range []func(*bytes.Buffer) error{
|
||||
writeSpace,
|
||||
writeFiller,
|
||||
writeSpace,
|
||||
} {
|
||||
if err := fn(bufB); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
err := s.filler.Fill(bufB, stat)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return io.MultiReader(bufP, bufB, bufA), nil
|
||||
}
|
||||
|
||||
func (s *bState) wSyncTable() (table syncTable) {
|
||||
var count int
|
||||
var row []chan int
|
||||
|
||||
for i, decorators := range [][]decor.Decorator{
|
||||
s.pDecorators,
|
||||
s.aDecorators,
|
||||
} {
|
||||
for _, d := range decorators {
|
||||
if ch, ok := d.Sync(); ok {
|
||||
row = append(row, ch)
|
||||
count++
|
||||
}
|
||||
}
|
||||
switch i {
|
||||
case 0:
|
||||
table[i] = row[0:count]
|
||||
default:
|
||||
table[i] = row[len(table[i-1]):count]
|
||||
}
|
||||
}
|
||||
table := make([][]chan int, 2)
|
||||
table[0] = columns[0:pCount]
|
||||
table[1] = columns[pCount : pCount+aCount : pCount+aCount]
|
||||
return table
|
||||
}
|
||||
|
||||
func (s *bState) subscribeDecorators() {
|
||||
for _, decorators := range [...][]decor.Decorator{
|
||||
for _, decorators := range [][]decor.Decorator{
|
||||
s.pDecorators,
|
||||
s.aDecorators,
|
||||
} {
|
||||
|
@ -535,16 +604,16 @@ func (s *bState) subscribeDecorators() {
|
|||
}
|
||||
}
|
||||
|
||||
func (s bState) decoratorEwmaUpdate(dur time.Duration) {
|
||||
wg := new(sync.WaitGroup)
|
||||
func (s bState) ewmaUpdate(n int64, dur time.Duration) {
|
||||
var wg sync.WaitGroup
|
||||
for i := 0; i < len(s.ewmaDecorators); i++ {
|
||||
switch d := s.ewmaDecorators[i]; i {
|
||||
case len(s.ewmaDecorators) - 1:
|
||||
d.EwmaUpdate(s.lastIncrement, dur)
|
||||
d.EwmaUpdate(n, dur)
|
||||
default:
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
d.EwmaUpdate(s.lastIncrement, dur)
|
||||
d.EwmaUpdate(n, dur)
|
||||
wg.Done()
|
||||
}()
|
||||
}
|
||||
|
@ -553,7 +622,7 @@ func (s bState) decoratorEwmaUpdate(dur time.Duration) {
|
|||
}
|
||||
|
||||
func (s bState) decoratorAverageAdjust(start time.Time) {
|
||||
wg := new(sync.WaitGroup)
|
||||
var wg sync.WaitGroup
|
||||
for i := 0; i < len(s.averageDecorators); i++ {
|
||||
switch d := s.averageDecorators[i]; i {
|
||||
case len(s.averageDecorators) - 1:
|
||||
|
@ -570,7 +639,7 @@ func (s bState) decoratorAverageAdjust(start time.Time) {
|
|||
}
|
||||
|
||||
func (s bState) decoratorShutdownNotify() {
|
||||
wg := new(sync.WaitGroup)
|
||||
var wg sync.WaitGroup
|
||||
for i := 0; i < len(s.shutdownListeners); i++ {
|
||||
switch d := s.shutdownListeners[i]; i {
|
||||
case len(s.shutdownListeners) - 1:
|
||||
|
@ -589,6 +658,7 @@ func (s bState) decoratorShutdownNotify() {
|
|||
func newStatistics(tw int, s *bState) decor.Statistics {
|
||||
return decor.Statistics{
|
||||
AvailableWidth: tw,
|
||||
RequestedWidth: s.reqWidth,
|
||||
ID: s.id,
|
||||
Total: s.total,
|
||||
Current: s.current,
|
||||
|
@ -605,13 +675,6 @@ func extractBaseDecorator(d decor.Decorator) decor.Decorator {
|
|||
return d
|
||||
}
|
||||
|
||||
func makePanicExtender(p interface{}) extenderFunc {
|
||||
pstr := fmt.Sprint(p)
|
||||
return func(rows []io.Reader, _ int, stat decor.Statistics) []io.Reader {
|
||||
r := io.MultiReader(
|
||||
strings.NewReader(runewidth.Truncate(pstr, stat.AvailableWidth, "…")),
|
||||
bytes.NewReader([]byte("\n")),
|
||||
)
|
||||
return append(rows, r)
|
||||
}
|
||||
func writeSpace(buf *bytes.Buffer) error {
|
||||
return buf.WriteByte(' ')
|
||||
}
|
|
@ -3,17 +3,13 @@ package mpb
|
|||
import (
|
||||
"io"
|
||||
|
||||
"github.com/vbauerster/mpb/v7/decor"
|
||||
"github.com/vbauerster/mpb/v8/decor"
|
||||
)
|
||||
|
||||
// BarFiller interface.
|
||||
// Bar (without decorators) renders itself by calling BarFiller's Fill method.
|
||||
//
|
||||
// reqWidth is requested width set by `func WithWidth(int) ContainerOption`.
|
||||
// If not set, it defaults to terminal width.
|
||||
//
|
||||
type BarFiller interface {
|
||||
Fill(w io.Writer, reqWidth int, stat decor.Statistics)
|
||||
Fill(io.Writer, decor.Statistics) error
|
||||
}
|
||||
|
||||
// BarFillerBuilder interface.
|
||||
|
@ -22,17 +18,16 @@ type BarFiller interface {
|
|||
// BarStyle()
|
||||
// SpinnerStyle()
|
||||
// NopStyle()
|
||||
//
|
||||
type BarFillerBuilder interface {
|
||||
Build() BarFiller
|
||||
}
|
||||
|
||||
// BarFillerFunc is function type adapter to convert compatible function
|
||||
// into BarFiller interface.
|
||||
type BarFillerFunc func(w io.Writer, reqWidth int, stat decor.Statistics)
|
||||
type BarFillerFunc func(io.Writer, decor.Statistics) error
|
||||
|
||||
func (f BarFillerFunc) Fill(w io.Writer, reqWidth int, stat decor.Statistics) {
|
||||
f(w, reqWidth, stat)
|
||||
func (f BarFillerFunc) Fill(w io.Writer, stat decor.Statistics) error {
|
||||
return f(w, stat)
|
||||
}
|
||||
|
||||
// BarFillerBuilderFunc is function type adapter to convert compatible
|
||||
|
@ -42,9 +37,3 @@ type BarFillerBuilderFunc func() BarFiller
|
|||
func (f BarFillerBuilderFunc) Build() BarFiller {
|
||||
return f()
|
||||
}
|
||||
|
||||
// NewBarFiller constructs a BarFiller from provided BarFillerBuilder.
|
||||
// Deprecated. Prefer using `*Progress.New(...)` directly.
|
||||
func NewBarFiller(b BarFillerBuilder) BarFiller {
|
||||
return b.Build()
|
||||
}
|
|
@ -5,8 +5,8 @@ import (
|
|||
|
||||
"github.com/acarl005/stripansi"
|
||||
"github.com/mattn/go-runewidth"
|
||||
"github.com/vbauerster/mpb/v7/decor"
|
||||
"github.com/vbauerster/mpb/v7/internal"
|
||||
"github.com/vbauerster/mpb/v8/decor"
|
||||
"github.com/vbauerster/mpb/v8/internal"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -36,8 +36,8 @@ type bFiller struct {
|
|||
components [components]*component
|
||||
tip struct {
|
||||
count uint
|
||||
onComplete *component
|
||||
frames []*component
|
||||
onComplete *component
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -148,20 +148,22 @@ func (s *barStyle) Build() BarFiller {
|
|||
return bf
|
||||
}
|
||||
|
||||
func (s *bFiller) Fill(w io.Writer, width int, stat decor.Statistics) {
|
||||
width = internal.CheckRequestedWidth(width, stat.AvailableWidth)
|
||||
brackets := s.components[iLbound].width + s.components[iRbound].width
|
||||
func (s *bFiller) Fill(w io.Writer, stat decor.Statistics) (err error) {
|
||||
width := internal.CheckRequestedWidth(stat.RequestedWidth, stat.AvailableWidth)
|
||||
// don't count brackets as progress
|
||||
width -= brackets
|
||||
width -= (s.components[iLbound].width + s.components[iRbound].width)
|
||||
if width < 0 {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
mustWrite(w, s.components[iLbound].bytes)
|
||||
defer mustWrite(w, s.components[iRbound].bytes)
|
||||
_, err = w.Write(s.components[iLbound].bytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if width == 0 {
|
||||
return
|
||||
_, err = w.Write(s.components[iRbound].bytes)
|
||||
return err
|
||||
}
|
||||
|
||||
var filling [][]byte
|
||||
|
@ -171,7 +173,7 @@ func (s *bFiller) Fill(w io.Writer, width int, stat decor.Statistics) {
|
|||
var refWidth int
|
||||
curWidth := int(internal.PercentageRound(stat.Total, stat.Current, uint(width)))
|
||||
|
||||
if stat.Current >= stat.Total {
|
||||
if stat.Completed {
|
||||
tip = s.tip.onComplete
|
||||
} else {
|
||||
tip = s.tip.frames[s.tip.count%uint(len(s.tip.frames))]
|
||||
|
@ -230,24 +232,28 @@ func (s *bFiller) Fill(w io.Writer, width int, stat decor.Statistics) {
|
|||
}
|
||||
|
||||
if s.rev {
|
||||
flush(w, padding, filling)
|
||||
} else {
|
||||
flush(w, filling, padding)
|
||||
filling, padding = padding, filling
|
||||
}
|
||||
err = flush(w, filling, padding)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = w.Write(s.components[iRbound].bytes)
|
||||
return err
|
||||
}
|
||||
|
||||
func flush(w io.Writer, filling, padding [][]byte) {
|
||||
func flush(w io.Writer, filling, padding [][]byte) error {
|
||||
for i := len(filling) - 1; i >= 0; i-- {
|
||||
mustWrite(w, filling[i])
|
||||
_, err := w.Write(filling[i])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
for i := 0; i < len(padding); i++ {
|
||||
mustWrite(w, padding[i])
|
||||
}
|
||||
}
|
||||
|
||||
func mustWrite(w io.Writer, p []byte) {
|
||||
_, err := w.Write(p)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
_, err := w.Write(padding[i])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -3,12 +3,14 @@ package mpb
|
|||
import (
|
||||
"io"
|
||||
|
||||
"github.com/vbauerster/mpb/v7/decor"
|
||||
"github.com/vbauerster/mpb/v8/decor"
|
||||
)
|
||||
|
||||
// NopStyle provides BarFillerBuilder which builds NOP BarFiller.
|
||||
func NopStyle() BarFillerBuilder {
|
||||
return BarFillerBuilderFunc(func() BarFiller {
|
||||
return BarFillerFunc(func(io.Writer, int, decor.Statistics) {})
|
||||
return BarFillerFunc(func(io.Writer, decor.Statistics) error {
|
||||
return nil
|
||||
})
|
||||
})
|
||||
}
|
|
@ -6,8 +6,8 @@ import (
|
|||
|
||||
"github.com/acarl005/stripansi"
|
||||
"github.com/mattn/go-runewidth"
|
||||
"github.com/vbauerster/mpb/v7/decor"
|
||||
"github.com/vbauerster/mpb/v7/internal"
|
||||
"github.com/vbauerster/mpb/v8/decor"
|
||||
"github.com/vbauerster/mpb/v8/internal"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -63,17 +63,16 @@ func (s *spinnerStyle) Build() BarFiller {
|
|||
return sf
|
||||
}
|
||||
|
||||
func (s *sFiller) Fill(w io.Writer, width int, stat decor.Statistics) {
|
||||
width = internal.CheckRequestedWidth(width, stat.AvailableWidth)
|
||||
func (s *sFiller) Fill(w io.Writer, stat decor.Statistics) (err error) {
|
||||
width := internal.CheckRequestedWidth(stat.RequestedWidth, stat.AvailableWidth)
|
||||
|
||||
frame := s.frames[s.count%uint(len(s.frames))]
|
||||
frameWidth := runewidth.StringWidth(stripansi.Strip(frame))
|
||||
|
||||
if width < frameWidth {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
var err error
|
||||
rest := width - frameWidth
|
||||
switch s.position {
|
||||
case positionLeft:
|
||||
|
@ -84,8 +83,6 @@ func (s *sFiller) Fill(w io.Writer, width int, stat decor.Statistics) {
|
|||
str := strings.Repeat(" ", rest/2) + frame + strings.Repeat(" ", rest/2+rest%2)
|
||||
_, err = io.WriteString(w, str)
|
||||
}
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
s.count++
|
||||
return err
|
||||
}
|
|
@ -4,44 +4,41 @@ import (
|
|||
"bytes"
|
||||
"io"
|
||||
|
||||
"github.com/vbauerster/mpb/v7/decor"
|
||||
"github.com/vbauerster/mpb/v8/decor"
|
||||
)
|
||||
|
||||
// BarOption is a func option to alter default behavior of a bar.
|
||||
type BarOption func(*bState)
|
||||
|
||||
func skipNil(decorators []decor.Decorator) (filtered []decor.Decorator) {
|
||||
for _, d := range decorators {
|
||||
if d != nil {
|
||||
filtered = append(filtered, d)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *bState) addDecorators(dest *[]decor.Decorator, decorators ...decor.Decorator) {
|
||||
func inspect(decorators []decor.Decorator) (dest []decor.Decorator) {
|
||||
type mergeWrapper interface {
|
||||
MergeUnwrap() []decor.Decorator
|
||||
}
|
||||
for _, decorator := range decorators {
|
||||
if mw, ok := decorator.(mergeWrapper); ok {
|
||||
*dest = append(*dest, mw.MergeUnwrap()...)
|
||||
if decorator == nil {
|
||||
continue
|
||||
}
|
||||
*dest = append(*dest, decorator)
|
||||
if mw, ok := decorator.(mergeWrapper); ok {
|
||||
dest = append(dest, mw.MergeUnwrap()...)
|
||||
}
|
||||
dest = append(dest, decorator)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// AppendDecorators let you inject decorators to the bar's right side.
|
||||
func AppendDecorators(decorators ...decor.Decorator) BarOption {
|
||||
decorators = inspect(decorators)
|
||||
return func(s *bState) {
|
||||
s.addDecorators(&s.aDecorators, skipNil(decorators)...)
|
||||
s.aDecorators = decorators
|
||||
}
|
||||
}
|
||||
|
||||
// PrependDecorators let you inject decorators to the bar's left side.
|
||||
func PrependDecorators(decorators ...decor.Decorator) BarOption {
|
||||
decorators = inspect(decorators)
|
||||
return func(s *bState) {
|
||||
s.addDecorators(&s.pDecorators, skipNil(decorators)...)
|
||||
s.pDecorators = decorators
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -91,15 +88,12 @@ func BarFillerClearOnComplete() BarOption {
|
|||
// BarFillerOnComplete replaces bar's filler with message, on complete event.
|
||||
func BarFillerOnComplete(message string) BarOption {
|
||||
return BarFillerMiddleware(func(base BarFiller) BarFiller {
|
||||
return BarFillerFunc(func(w io.Writer, reqWidth int, st decor.Statistics) {
|
||||
return BarFillerFunc(func(w io.Writer, st decor.Statistics) error {
|
||||
if st.Completed {
|
||||
_, err := io.WriteString(w, message)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
} else {
|
||||
base.Fill(w, reqWidth, st)
|
||||
return err
|
||||
}
|
||||
return base.Fill(w, st)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
@ -121,32 +115,26 @@ func BarPriority(priority int) BarOption {
|
|||
|
||||
// BarExtender extends bar with arbitrary lines. Provided BarFiller will be
|
||||
// called at each render/flush cycle. Any lines written to the underlying
|
||||
// io.Writer will be printed after the bar itself.
|
||||
func BarExtender(filler BarFiller) BarOption {
|
||||
return barExtender(filler, false)
|
||||
}
|
||||
|
||||
// BarExtenderRev extends bar with arbitrary lines in reverse order. Provided
|
||||
// BarFiller will be called at each render/flush cycle. Any lines written
|
||||
// to the underlying io.Writer will be printed before the bar itself.
|
||||
func BarExtenderRev(filler BarFiller) BarOption {
|
||||
return barExtender(filler, true)
|
||||
}
|
||||
|
||||
func barExtender(filler BarFiller, rev bool) BarOption {
|
||||
// io.Writer will extend the bar either in above (rev = true) or below
|
||||
// (rev = false) direction.
|
||||
func BarExtender(filler BarFiller, rev bool) BarOption {
|
||||
if filler == nil {
|
||||
return nil
|
||||
}
|
||||
fn := makeExtenderFunc(filler, rev)
|
||||
return func(s *bState) {
|
||||
s.extender = makeExtenderFunc(filler, rev)
|
||||
s.extender = fn
|
||||
}
|
||||
}
|
||||
|
||||
func makeExtenderFunc(filler BarFiller, rev bool) extenderFunc {
|
||||
buf := new(bytes.Buffer)
|
||||
base := func(rows []io.Reader, width int, stat decor.Statistics) []io.Reader {
|
||||
buf.Reset()
|
||||
filler.Fill(buf, width, stat)
|
||||
base := func(rows []io.Reader, stat decor.Statistics) ([]io.Reader, error) {
|
||||
err := filler.Fill(buf, stat)
|
||||
if err != nil {
|
||||
buf.Reset()
|
||||
return rows, err
|
||||
}
|
||||
for {
|
||||
b, err := buf.ReadBytes('\n')
|
||||
if err != nil {
|
||||
|
@ -154,19 +142,22 @@ func makeExtenderFunc(filler BarFiller, rev bool) extenderFunc {
|
|||
}
|
||||
rows = append(rows, bytes.NewReader(b))
|
||||
}
|
||||
return rows
|
||||
buf.Reset()
|
||||
return rows, err
|
||||
}
|
||||
|
||||
if !rev {
|
||||
return base
|
||||
} else {
|
||||
return func(rows []io.Reader, width int, stat decor.Statistics) []io.Reader {
|
||||
rows = base(rows, width, stat)
|
||||
for left, right := 0, len(rows)-1; left < right; left, right = left+1, right-1 {
|
||||
rows[left], rows[right] = rows[right], rows[left]
|
||||
}
|
||||
return rows
|
||||
}
|
||||
return func(rows []io.Reader, stat decor.Statistics) ([]io.Reader, error) {
|
||||
rows, err := base(rows, stat)
|
||||
if err != nil {
|
||||
return rows, err
|
||||
}
|
||||
for left, right := 0, len(rows)-1; left < right; left, right = left+1, right-1 {
|
||||
rows[left], rows[right] = rows[right], rows[left]
|
||||
}
|
||||
return rows, err
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -185,7 +176,7 @@ func BarNoPop() BarOption {
|
|||
}
|
||||
}
|
||||
|
||||
// BarOptional will invoke provided option only when cond is true.
|
||||
// BarOptional will return provided option only when cond is true.
|
||||
func BarOptional(option BarOption, cond bool) BarOption {
|
||||
if cond {
|
||||
return option
|
||||
|
@ -193,11 +184,26 @@ func BarOptional(option BarOption, cond bool) BarOption {
|
|||
return nil
|
||||
}
|
||||
|
||||
// BarOptOn will invoke provided option only when higher order predicate
|
||||
// evaluates to true.
|
||||
// BarOptOn will return provided option only when predicate evaluates to true.
|
||||
func BarOptOn(option BarOption, predicate func() bool) BarOption {
|
||||
if predicate() {
|
||||
return option
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// BarFuncOptional will call option and return its value only when cond is true.
|
||||
func BarFuncOptional(option func() BarOption, cond bool) BarOption {
|
||||
if cond {
|
||||
return option()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// BarFuncOptOn will call option and return its value only when predicate evaluates to true.
|
||||
func BarFuncOptOn(option func() BarOption, predicate func() bool) BarOption {
|
||||
if predicate() {
|
||||
return option()
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -33,15 +33,16 @@ func WithWidth(width int) ContainerOption {
|
|||
// WithRefreshRate overrides default 150ms refresh rate.
|
||||
func WithRefreshRate(d time.Duration) ContainerOption {
|
||||
return func(s *pState) {
|
||||
s.rr = d
|
||||
s.refreshRate = d
|
||||
}
|
||||
}
|
||||
|
||||
// WithManualRefresh disables internal auto refresh time.Ticker.
|
||||
// Refresh will occur upon receive value from provided ch.
|
||||
func WithManualRefresh(ch <-chan interface{}) ContainerOption {
|
||||
func WithManualRefresh(ch chan interface{}) ContainerOption {
|
||||
return func(s *pState) {
|
||||
s.externalRefresh = ch
|
||||
s.manualRefresh = ch
|
||||
s.disableAutoRefresh = true
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -71,34 +72,37 @@ func WithShutdownNotifier(ch chan struct{}) ContainerOption {
|
|||
// will effectively disable auto refresh rate and discard any output,
|
||||
// useful if you want to disable progress bars with little overhead.
|
||||
func WithOutput(w io.Writer) ContainerOption {
|
||||
var discarded bool
|
||||
if w == nil {
|
||||
w = io.Discard
|
||||
discarded = true
|
||||
}
|
||||
return func(s *pState) {
|
||||
if w == nil {
|
||||
s.output = io.Discard
|
||||
s.outputDiscarded = true
|
||||
return
|
||||
}
|
||||
s.output = w
|
||||
s.outputDiscarded = discarded
|
||||
}
|
||||
}
|
||||
|
||||
// WithDebugOutput sets debug output.
|
||||
func WithDebugOutput(w io.Writer) ContainerOption {
|
||||
if w == nil {
|
||||
return nil
|
||||
w = io.Discard
|
||||
}
|
||||
return func(s *pState) {
|
||||
s.debugOut = w
|
||||
}
|
||||
}
|
||||
|
||||
// PopCompletedMode will pop and stop rendering completed bars.
|
||||
// PopCompletedMode will pop completed bars to the top.
|
||||
// To stop rendering bar after it has been popped, use
|
||||
// mpb.BarRemoveOnComplete() option on that bar.
|
||||
func PopCompletedMode() ContainerOption {
|
||||
return func(s *pState) {
|
||||
s.popCompleted = true
|
||||
}
|
||||
}
|
||||
|
||||
// ContainerOptional will invoke provided option only when cond is true.
|
||||
// ContainerOptional will return provided option only when cond is true.
|
||||
func ContainerOptional(option ContainerOption, cond bool) ContainerOption {
|
||||
if cond {
|
||||
return option
|
||||
|
@ -106,11 +110,26 @@ func ContainerOptional(option ContainerOption, cond bool) ContainerOption {
|
|||
return nil
|
||||
}
|
||||
|
||||
// ContainerOptOn will invoke provided option only when higher order
|
||||
// predicate evaluates to true.
|
||||
// ContainerOptOn will return provided option only when predicate evaluates to true.
|
||||
func ContainerOptOn(option ContainerOption, predicate func() bool) ContainerOption {
|
||||
if predicate() {
|
||||
return option
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContainerFuncOptional will call option and return its value only when cond is true.
|
||||
func ContainerFuncOptional(option func() ContainerOption, cond bool) ContainerOption {
|
||||
if cond {
|
||||
return option()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContainerFuncOptOn will call option and return its value only when predicate evaluates to true.
|
||||
func ContainerFuncOptOn(option func() ContainerOption, predicate func() bool) ContainerOption {
|
||||
if predicate() {
|
||||
return option()
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
// +build darwin dragonfly freebsd netbsd openbsd
|
||||
//go:build darwin || dragonfly || freebsd || netbsd || openbsd
|
||||
|
||||
package cwriter
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
// +build aix linux
|
||||
//go:build aix || linux
|
||||
|
||||
package cwriter
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
// +build solaris
|
||||
//go:build solaris
|
||||
|
||||
package cwriter
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
// +build zos
|
||||
//go:build zos
|
||||
|
||||
package cwriter
|
||||
|
54
vendor/github.com/vbauerster/mpb/v8/cwriter/writer.go
generated
vendored
Normal file
54
vendor/github.com/vbauerster/mpb/v8/cwriter/writer.go
generated
vendored
Normal file
|
@ -0,0 +1,54 @@
|
|||
package cwriter
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"io"
|
||||
"os"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// https://github.com/dylanaraps/pure-sh-bible#cursor-movement
|
||||
const (
|
||||
escOpen = "\x1b["
|
||||
cuuAndEd = "A\x1b[J"
|
||||
)
|
||||
|
||||
// ErrNotTTY not a TeleTYpewriter error.
|
||||
var ErrNotTTY = errors.New("not a terminal")
|
||||
|
||||
// New returns a new Writer with defaults.
|
||||
func New(out io.Writer) *Writer {
|
||||
w := &Writer{
|
||||
Buffer: new(bytes.Buffer),
|
||||
out: out,
|
||||
termSize: func(_ int) (int, int, error) {
|
||||
return -1, -1, ErrNotTTY
|
||||
},
|
||||
}
|
||||
if f, ok := out.(*os.File); ok {
|
||||
w.fd = int(f.Fd())
|
||||
if IsTerminal(w.fd) {
|
||||
w.terminal = true
|
||||
w.termSize = func(fd int) (int, int, error) {
|
||||
return GetSize(fd)
|
||||
}
|
||||
}
|
||||
}
|
||||
bb := make([]byte, 16)
|
||||
w.ew = escWriter(bb[:copy(bb, []byte(escOpen))])
|
||||
return w
|
||||
}
|
||||
|
||||
// GetTermSize returns WxH of underlying terminal.
|
||||
func (w *Writer) GetTermSize() (width, height int, err error) {
|
||||
return w.termSize(w.fd)
|
||||
}
|
||||
|
||||
type escWriter []byte
|
||||
|
||||
func (b escWriter) ansiCuuAndEd(out io.Writer, n int) error {
|
||||
b = strconv.AppendInt(b, int64(n), 10)
|
||||
_, err := out.Write(append(b, []byte(cuuAndEd)...))
|
||||
return err
|
||||
}
|
48
vendor/github.com/vbauerster/mpb/v8/cwriter/writer_posix.go
generated
vendored
Normal file
48
vendor/github.com/vbauerster/mpb/v8/cwriter/writer_posix.go
generated
vendored
Normal file
|
@ -0,0 +1,48 @@
|
|||
//go:build !windows
|
||||
|
||||
package cwriter
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// Writer is a buffered terminal writer, which moves cursor N lines up
|
||||
// on each flush except the first one, where N is a number of lines of
|
||||
// a previous flush.
|
||||
type Writer struct {
|
||||
*bytes.Buffer
|
||||
out io.Writer
|
||||
ew escWriter
|
||||
fd int
|
||||
terminal bool
|
||||
termSize func(int) (int, int, error)
|
||||
}
|
||||
|
||||
// Flush flushes the underlying buffer.
|
||||
// It's caller's responsibility to pass correct number of lines.
|
||||
func (w *Writer) Flush(lines int) error {
|
||||
_, err := w.WriteTo(w.out)
|
||||
// some terminals interpret 'cursor up 0' as 'cursor up 1'
|
||||
if err == nil && lines > 0 {
|
||||
err = w.ew.ansiCuuAndEd(w, lines)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// GetSize returns the dimensions of the given terminal.
|
||||
func GetSize(fd int) (width, height int, err error) {
|
||||
ws, err := unix.IoctlGetWinsize(fd, unix.TIOCGWINSZ)
|
||||
if err != nil {
|
||||
return -1, -1, err
|
||||
}
|
||||
return int(ws.Col), int(ws.Row), nil
|
||||
}
|
||||
|
||||
// IsTerminal returns whether the given file descriptor is a terminal.
|
||||
func IsTerminal(fd int) bool {
|
||||
_, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
|
||||
return err == nil
|
||||
}
|
|
@ -1,8 +1,10 @@
|
|||
// +build windows
|
||||
//go:build windows
|
||||
|
||||
package cwriter
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
|
@ -15,10 +17,37 @@ var (
|
|||
procFillConsoleOutputCharacter = kernel32.NewProc("FillConsoleOutputCharacterW")
|
||||
)
|
||||
|
||||
func (w *Writer) clearLines() error {
|
||||
// Writer is a buffered terminal writer, which moves cursor N lines up
|
||||
// on each flush except the first one, where N is a number of lines of
|
||||
// a previous flush.
|
||||
type Writer struct {
|
||||
*bytes.Buffer
|
||||
out io.Writer
|
||||
ew escWriter
|
||||
lines int
|
||||
fd int
|
||||
terminal bool
|
||||
termSize func(int) (int, int, error)
|
||||
}
|
||||
|
||||
// Flush flushes the underlying buffer.
|
||||
// It's caller's responsibility to pass correct number of lines.
|
||||
func (w *Writer) Flush(lines int) error {
|
||||
if w.lines > 0 {
|
||||
err := w.clearLines(w.lines)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
w.lines = lines
|
||||
_, err := w.WriteTo(w.out)
|
||||
return err
|
||||
}
|
||||
|
||||
func (w *Writer) clearLines(n int) error {
|
||||
if !w.terminal {
|
||||
// hope it's cygwin or similar
|
||||
return w.ansiCuuAndEd()
|
||||
return w.ew.ansiCuuAndEd(w.out, n)
|
||||
}
|
||||
|
||||
var info windows.ConsoleScreenBufferInfo
|
||||
|
@ -26,7 +55,7 @@ func (w *Writer) clearLines() error {
|
|||
return err
|
||||
}
|
||||
|
||||
info.CursorPosition.Y -= int16(w.lines)
|
||||
info.CursorPosition.Y -= int16(n)
|
||||
if info.CursorPosition.Y < 0 {
|
||||
info.CursorPosition.Y = 0
|
||||
}
|
||||
|
@ -40,7 +69,7 @@ func (w *Writer) clearLines() error {
|
|||
X: info.Window.Left,
|
||||
Y: info.CursorPosition.Y,
|
||||
}
|
||||
count := uint32(info.Size.X) * uint32(w.lines)
|
||||
count := uint32(info.Size.X) * uint32(n)
|
||||
_, _, _ = procFillConsoleOutputCharacter.Call(
|
||||
uintptr(w.fd),
|
||||
uintptr(' '),
|
||||
|
@ -52,7 +81,6 @@ func (w *Writer) clearLines() error {
|
|||
}
|
||||
|
||||
// GetSize returns the visible dimensions of the given terminal.
|
||||
//
|
||||
// These dimensions don't include any scrollback buffer height.
|
||||
func GetSize(fd int) (width, height int, err error) {
|
||||
var info windows.ConsoleScreenBufferInfo
|
|
@ -6,7 +6,6 @@ package decor
|
|||
// `fn` DecorFunc callback
|
||||
//
|
||||
// `wcc` optional WC config
|
||||
//
|
||||
func Any(fn DecorFunc, wcc ...WC) Decorator {
|
||||
return &any{initWC(wcc...), fn}
|
||||
}
|
|
@ -42,7 +42,6 @@ func CountersKiloByte(pairFmt string, wcc ...WC) Decorator {
|
|||
// pairFmt="% .1f / % .1f" output: "1.0 MB / 12.0 MB"
|
||||
// pairFmt="%d / %d" output: "1MB / 12MB"
|
||||
// pairFmt="% d / % d" output: "1 MB / 12 MB"
|
||||
//
|
||||
func Counters(unit int, pairFmt string, wcc ...WC) Decorator {
|
||||
producer := func(unit int, pairFmt string) DecorFunc {
|
||||
if pairFmt == "" {
|
||||
|
@ -99,7 +98,6 @@ func TotalKiloByte(format string, wcc ...WC) Decorator {
|
|||
// format="% .1f" output: "12.0 MiB"
|
||||
// format="%d" output: "12MiB"
|
||||
// format="% d" output: "12 MiB"
|
||||
//
|
||||
func Total(unit int, format string, wcc ...WC) Decorator {
|
||||
producer := func(unit int, format string) DecorFunc {
|
||||
if format == "" {
|
||||
|
@ -157,7 +155,6 @@ func CurrentKiloByte(format string, wcc ...WC) Decorator {
|
|||
// format="% .1f" output: "12.0 MiB"
|
||||
// format="%d" output: "12MiB"
|
||||
// format="% d" output: "12 MiB"
|
||||
//
|
||||
func Current(unit int, format string, wcc ...WC) Decorator {
|
||||
producer := func(unit int, format string) DecorFunc {
|
||||
if format == "" {
|
||||
|
@ -215,7 +212,6 @@ func InvertedCurrentKiloByte(format string, wcc ...WC) Decorator {
|
|||
// format="% .1f" output: "12.0 MiB"
|
||||
// format="%d" output: "12MiB"
|
||||
// format="% d" output: "12 MiB"
|
||||
//
|
||||
func InvertedCurrent(unit int, format string, wcc ...WC) Decorator {
|
||||
producer := func(unit int, format string) DecorFunc {
|
||||
if format == "" {
|
|
@ -44,10 +44,11 @@ const (
|
|||
ET_STYLE_MMSS
|
||||
)
|
||||
|
||||
// Statistics consists of progress related statistics, that Decorator
|
||||
// may need.
|
||||
// Statistics contains fields which are necessary for implementing
|
||||
// `decor.Decorator` and `mpb.BarFiller` interfaces.
|
||||
type Statistics struct {
|
||||
AvailableWidth int
|
||||
AvailableWidth int // calculated width initially equal to terminal width
|
||||
RequestedWidth int // width set by `mpb.WithWidth`
|
||||
ID int
|
||||
Total int64
|
||||
Current int64
|
||||
|
@ -138,17 +139,17 @@ type WC struct {
|
|||
// Should be called by any Decorator implementation.
|
||||
func (wc *WC) FormatMsg(msg string) string {
|
||||
pureWidth := runewidth.StringWidth(msg)
|
||||
stripWidth := runewidth.StringWidth(stripansi.Strip(msg))
|
||||
maxCell := wc.W
|
||||
viewWidth := runewidth.StringWidth(stripansi.Strip(msg))
|
||||
max := wc.W
|
||||
if (wc.C & DSyncWidth) != 0 {
|
||||
cellCount := stripWidth
|
||||
viewWidth := viewWidth
|
||||
if (wc.C & DextraSpace) != 0 {
|
||||
cellCount++
|
||||
viewWidth++
|
||||
}
|
||||
wc.wsync <- cellCount
|
||||
maxCell = <-wc.wsync
|
||||
wc.wsync <- viewWidth
|
||||
max = <-wc.wsync
|
||||
}
|
||||
return wc.fill(msg, maxCell+(pureWidth-stripWidth))
|
||||
return wc.fill(msg, max-viewWidth+pureWidth)
|
||||
}
|
||||
|
||||
// Init initializes width related config.
|
|
@ -1,4 +1,4 @@
|
|||
// Package decor provides common decorators for "github.com/vbauerster/mpb/v7" module.
|
||||
// Package decor provides common decorators for "github.com/vbauerster/mpb/v8" module.
|
||||
//
|
||||
// Some decorators returned by this package might have a closure state. It is ok to use
|
||||
// decorators concurrently, unless you share the same decorator among multiple
|
||||
|
@ -6,10 +6,10 @@
|
|||
//
|
||||
// Don't:
|
||||
//
|
||||
// p := mpb.New()
|
||||
// name := decor.Name("bar")
|
||||
// p.AddBar(100, mpb.AppendDecorators(name))
|
||||
// p.AddBar(100, mpb.AppendDecorators(name))
|
||||
// p := mpb.New()
|
||||
// name := decor.Name("bar")
|
||||
// p.AddBar(100, mpb.AppendDecorators(name))
|
||||
// p.AddBar(100, mpb.AppendDecorators(name))
|
||||
//
|
||||
// Do:
|
||||
//
|
|
@ -9,7 +9,6 @@ import (
|
|||
// `style` one of [ET_STYLE_GO|ET_STYLE_HHMMSS|ET_STYLE_HHMM|ET_STYLE_MMSS]
|
||||
//
|
||||
// `wcc` optional WC config
|
||||
//
|
||||
func Elapsed(style TimeStyle, wcc ...WC) Decorator {
|
||||
return NewElapsed(style, time.Now(), wcc...)
|
||||
}
|
||||
|
@ -21,7 +20,6 @@ func Elapsed(style TimeStyle, wcc ...WC) Decorator {
|
|||
// `startTime` start time
|
||||
//
|
||||
// `wcc` optional WC config
|
||||
//
|
||||
func NewElapsed(style TimeStyle, startTime time.Time, wcc ...WC) Decorator {
|
||||
var msg string
|
||||
producer := chooseTimeProducer(style)
|
|
@ -22,10 +22,9 @@ func (f TimeNormalizerFunc) Normalize(src time.Duration) time.Duration {
|
|||
return f(src)
|
||||
}
|
||||
|
||||
// EwmaETA exponential-weighted-moving-average based ETA decorator.
|
||||
// For this decorator to work correctly you have to measure each
|
||||
// iteration's duration and pass it to the
|
||||
// *Bar.DecoratorEwmaUpdate(time.Duration) method after each increment.
|
||||
// EwmaETA exponential-weighted-moving-average based ETA decorator. For this
|
||||
// decorator to work correctly you have to measure each iteration's duration
|
||||
// and pass it to one of the (*Bar).EwmaIncr... family methods.
|
||||
func EwmaETA(style TimeStyle, age float64, wcc ...WC) Decorator {
|
||||
var average ewma.MovingAverage
|
||||
if age == 0 {
|
||||
|
@ -45,7 +44,6 @@ func EwmaETA(style TimeStyle, age float64, wcc ...WC) Decorator {
|
|||
// `normalizer` available implementations are [FixedIntervalTimeNormalizer|MaxTolerateTimeNormalizer]
|
||||
//
|
||||
// `wcc` optional WC config
|
||||
//
|
||||
func MovingAverageETA(style TimeStyle, average ewma.MovingAverage, normalizer TimeNormalizer, wcc ...WC) Decorator {
|
||||
d := &movingAverageETA{
|
||||
WC: initWC(wcc...),
|
||||
|
@ -85,7 +83,6 @@ func (d *movingAverageETA) EwmaUpdate(n int64, dur time.Duration) {
|
|||
// `style` one of [ET_STYLE_GO|ET_STYLE_HHMMSS|ET_STYLE_HHMM|ET_STYLE_MMSS]
|
||||
//
|
||||
// `wcc` optional WC config
|
||||
//
|
||||
func AverageETA(style TimeStyle, wcc ...WC) Decorator {
|
||||
return NewAverageETA(style, time.Now(), nil, wcc...)
|
||||
}
|
||||
|
@ -99,7 +96,6 @@ func AverageETA(style TimeStyle, wcc ...WC) Decorator {
|
|||
// `normalizer` available implementations are [FixedIntervalTimeNormalizer|MaxTolerateTimeNormalizer]
|
||||
//
|
||||
// `wcc` optional WC config
|
||||
//
|
||||
func NewAverageETA(style TimeStyle, startTime time.Time, normalizer TimeNormalizer, wcc ...WC) Decorator {
|
||||
d := &averageETA{
|
||||
WC: initWC(wcc...),
|
|
@ -10,12 +10,11 @@ import (
|
|||
// Merge wraps its decorator argument with intention to sync width
|
||||
// with several decorators of another bar. Visual example:
|
||||
//
|
||||
// +----+--------+---------+--------+
|
||||
// | B1 | MERGE(D, P1, Pn) |
|
||||
// +----+--------+---------+--------+
|
||||
// | B2 | D0 | D1 | Dn |
|
||||
// +----+--------+---------+--------+
|
||||
//
|
||||
// +----+--------+---------+--------+
|
||||
// | B1 | MERGE(D, P1, Pn) |
|
||||
// +----+--------+---------+--------+
|
||||
// | B2 | D0 | D1 | Dn |
|
||||
// +----+--------+---------+--------+
|
||||
func Merge(decorator Decorator, placeholders ...WC) Decorator {
|
||||
if decorator == nil {
|
||||
return nil
|
|
@ -6,7 +6,6 @@ package decor
|
|||
// `str` string to display
|
||||
//
|
||||
// `wcc` optional WC config
|
||||
//
|
||||
func Name(str string, wcc ...WC) Decorator {
|
||||
return Any(func(Statistics) string { return str }, wcc...)
|
||||
}
|
|
@ -7,7 +7,6 @@ package decor
|
|||
// `decorator` Decorator to wrap
|
||||
//
|
||||
// `message` message to display on abort event
|
||||
//
|
||||
func OnAbort(decorator Decorator, message string) Decorator {
|
||||
if decorator == nil {
|
||||
return nil
|
|
@ -6,7 +6,6 @@ package decor
|
|||
// `decorator` Decorator to wrap
|
||||
//
|
||||
// `message` message to display on complete event
|
||||
//
|
||||
func OnComplete(decorator Decorator, message string) Decorator {
|
||||
if decorator == nil {
|
||||
return nil
|
|
@ -5,7 +5,6 @@ package decor
|
|||
// `decorator` Decorator
|
||||
//
|
||||
// `cond` bool
|
||||
//
|
||||
func OnCondition(decorator Decorator, cond bool) Decorator {
|
||||
return Conditional(cond, decorator, nil)
|
||||
}
|
||||
|
@ -15,7 +14,6 @@ func OnCondition(decorator Decorator, cond bool) Decorator {
|
|||
// `decorator` Decorator
|
||||
//
|
||||
// `predicate` func() bool
|
||||
//
|
||||
func OnPredicate(decorator Decorator, predicate func() bool) Decorator {
|
||||
return Predicative(predicate, decorator, nil)
|
||||
}
|
||||
|
@ -28,7 +26,6 @@ func OnPredicate(decorator Decorator, predicate func() bool) Decorator {
|
|||
// `a` Decorator
|
||||
//
|
||||
// `b` Decorator
|
||||
//
|
||||
func Conditional(cond bool, a, b Decorator) Decorator {
|
||||
if cond {
|
||||
return a
|
||||
|
@ -45,7 +42,6 @@ func Conditional(cond bool, a, b Decorator) Decorator {
|
|||
// `a` Decorator
|
||||
//
|
||||
// `b` Decorator
|
||||
//
|
||||
func Predicative(predicate func() bool, a, b Decorator) Decorator {
|
||||
if predicate() {
|
||||
return a
|
|
@ -4,7 +4,7 @@ import (
|
|||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/vbauerster/mpb/v7/internal"
|
||||
"github.com/vbauerster/mpb/v8/internal"
|
||||
)
|
||||
|
||||
type percentageType float64
|
||||
|
@ -23,11 +23,18 @@ func (s percentageType) Format(st fmt.State, verb rune) {
|
|||
}
|
||||
}
|
||||
|
||||
mustWriteString(st, strconv.FormatFloat(float64(s), 'f', prec, 64))
|
||||
p := bytePool.Get().(*[]byte)
|
||||
b := strconv.AppendFloat(*p, float64(s), 'f', prec, 64)
|
||||
if st.Flag(' ') {
|
||||
mustWriteString(st, " ")
|
||||
b = append(b, ' ', '%')
|
||||
} else {
|
||||
b = append(b, '%')
|
||||
}
|
||||
mustWriteString(st, "%")
|
||||
_, err := st.Write(b)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
bytePool.Put(p)
|
||||
}
|
||||
|
||||
// Percentage returns percentage decorator. It's a wrapper of NewPercentage.
|
||||
|
@ -43,7 +50,6 @@ func Percentage(wcc ...WC) Decorator {
|
|||
// format="% .1f" output: "1.0 %"
|
||||
// format="%d" output: "1%"
|
||||
// format="% d" output: "1 %"
|
||||
//
|
||||
func NewPercentage(format string, wcc ...WC) Decorator {
|
||||
if format == "" {
|
||||
format = "% d"
|
10
vendor/github.com/vbauerster/mpb/v8/decor/pool.go
generated
vendored
Normal file
10
vendor/github.com/vbauerster/mpb/v8/decor/pool.go
generated
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
package decor
|
||||
|
||||
import "sync"
|
||||
|
||||
var bytePool = sync.Pool{
|
||||
New: func() interface{} {
|
||||
b := make([]byte, 0, 16)
|
||||
return &b
|
||||
},
|
||||
}
|
|
@ -49,11 +49,17 @@ func (self SizeB1024) Format(st fmt.State, verb rune) {
|
|||
unit = _iTiB
|
||||
}
|
||||
|
||||
mustWriteString(st, strconv.FormatFloat(float64(self)/float64(unit), 'f', prec, 64))
|
||||
p := bytePool.Get().(*[]byte)
|
||||
b := strconv.AppendFloat(*p, float64(self)/float64(unit), 'f', prec, 64)
|
||||
if st.Flag(' ') {
|
||||
mustWriteString(st, " ")
|
||||
b = append(b, ' ')
|
||||
}
|
||||
mustWriteString(st, unit.String())
|
||||
b = append(b, []byte(unit.String())...)
|
||||
_, err := st.Write(b)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
bytePool.Put(p)
|
||||
}
|
||||
|
||||
const (
|
||||
|
@ -97,9 +103,15 @@ func (self SizeB1000) Format(st fmt.State, verb rune) {
|
|||
unit = _TB
|
||||
}
|
||||
|
||||
mustWriteString(st, strconv.FormatFloat(float64(self)/float64(unit), 'f', prec, 64))
|
||||
p := bytePool.Get().(*[]byte)
|
||||
b := strconv.AppendFloat(*p, float64(self)/float64(unit), 'f', prec, 64)
|
||||
if st.Flag(' ') {
|
||||
mustWriteString(st, " ")
|
||||
b = append(b, ' ')
|
||||
}
|
||||
mustWriteString(st, unit.String())
|
||||
b = append(b, []byte(unit.String())...)
|
||||
_, err := st.Write(b)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
bytePool.Put(p)
|
||||
}
|
|
@ -12,7 +12,6 @@ import (
|
|||
// used with SizeB1000 or SizeB1024 types, for example:
|
||||
//
|
||||
// fmt.Printf("%.1f", FmtAsSpeed(SizeB1024(2048)))
|
||||
//
|
||||
func FmtAsSpeed(input fmt.Formatter) fmt.Formatter {
|
||||
return &speedFormatter{input}
|
||||
}
|
||||
|
@ -23,13 +22,15 @@ type speedFormatter struct {
|
|||
|
||||
func (self *speedFormatter) Format(st fmt.State, verb rune) {
|
||||
self.Formatter.Format(st, verb)
|
||||
mustWriteString(st, "/s")
|
||||
_, err := st.Write([]byte("/s"))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// EwmaSpeed exponential-weighted-moving-average based speed decorator.
|
||||
// For this decorator to work correctly you have to measure each
|
||||
// iteration's duration and pass it to the
|
||||
// *Bar.DecoratorEwmaUpdate(time.Duration) method after each increment.
|
||||
// For this decorator to work correctly you have to measure each iteration's
|
||||
// duration and pass it to one of the (*Bar).EwmaIncr... family methods.
|
||||
func EwmaSpeed(unit int, format string, age float64, wcc ...WC) Decorator {
|
||||
var average ewma.MovingAverage
|
||||
if age == 0 {
|
||||
|
@ -57,7 +58,6 @@ func EwmaSpeed(unit int, format string, age float64, wcc ...WC) Decorator {
|
|||
// unit=UnitKiB, format="% .1f" output: "1.0 MiB/s"
|
||||
// unit=UnitKB, format="%.1f" output: "1.0MB/s"
|
||||
// unit=UnitKB, format="% .1f" output: "1.0 MB/s"
|
||||
//
|
||||
func MovingAverageSpeed(unit int, format string, average ewma.MovingAverage, wcc ...WC) Decorator {
|
||||
if format == "" {
|
||||
format = "%.0f"
|
||||
|
@ -119,7 +119,6 @@ func AverageSpeed(unit int, format string, wcc ...WC) Decorator {
|
|||
// unit=UnitKiB, format="% .1f" output: "1.0 MiB/s"
|
||||
// unit=UnitKB, format="%.1f" output: "1.0MB/s"
|
||||
// unit=UnitKB, format="% .1f" output: "1.0 MB/s"
|
||||
//
|
||||
func NewAverageSpeed(unit int, format string, startTime time.Time, wcc ...WC) Decorator {
|
||||
if format == "" {
|
||||
format = "%.0f"
|
|
@ -11,23 +11,26 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/vbauerster/mpb/v7/cwriter"
|
||||
"github.com/vbauerster/mpb/v8/cwriter"
|
||||
)
|
||||
|
||||
const (
|
||||
prr = 150 * time.Millisecond // default RefreshRate
|
||||
defaultRefreshRate = 150 * time.Millisecond
|
||||
)
|
||||
|
||||
// DoneError represents an error when `*mpb.Progress` is done but its functionality is requested.
|
||||
var DoneError = fmt.Errorf("%T instance can't be reused after it's done!", (*Progress)(nil))
|
||||
|
||||
// Progress represents a container that renders one or more progress bars.
|
||||
type Progress struct {
|
||||
ctx context.Context
|
||||
uwg *sync.WaitGroup
|
||||
cwg *sync.WaitGroup
|
||||
bwg *sync.WaitGroup
|
||||
operateState chan func(*pState)
|
||||
interceptIo chan func(io.Writer)
|
||||
done chan struct{}
|
||||
refreshCh chan time.Time
|
||||
once sync.Once
|
||||
shutdown chan struct{}
|
||||
cancel func()
|
||||
}
|
||||
|
||||
// pState holds bars in its priorityQueue, it gets passed to (*Progress).serve monitor goroutine.
|
||||
|
@ -37,20 +40,25 @@ type pState struct {
|
|||
pMatrix map[int][]chan int
|
||||
aMatrix map[int][]chan int
|
||||
|
||||
// for reuse purposes
|
||||
rows []io.Reader
|
||||
pool []*Bar
|
||||
|
||||
// following are provided/overrided by user
|
||||
idCount int
|
||||
reqWidth int
|
||||
popPriority int
|
||||
popCompleted bool
|
||||
outputDiscarded bool
|
||||
rr time.Duration
|
||||
uwg *sync.WaitGroup
|
||||
externalRefresh <-chan interface{}
|
||||
renderDelay <-chan struct{}
|
||||
shutdownNotifier chan struct{}
|
||||
queueBars map[*Bar]*Bar
|
||||
output io.Writer
|
||||
debugOut io.Writer
|
||||
refreshRate time.Duration
|
||||
idCount int
|
||||
reqWidth int
|
||||
popPriority int
|
||||
popCompleted bool
|
||||
outputDiscarded bool
|
||||
disableAutoRefresh bool
|
||||
manualRefresh chan interface{}
|
||||
renderDelay <-chan struct{}
|
||||
shutdownNotifier chan struct{}
|
||||
queueBars map[*Bar]*Bar
|
||||
output io.Writer
|
||||
debugOut io.Writer
|
||||
uwg *sync.WaitGroup
|
||||
}
|
||||
|
||||
// New creates new Progress container instance. It's not possible to
|
||||
|
@ -64,11 +72,14 @@ func New(options ...ContainerOption) *Progress {
|
|||
// method has been called.
|
||||
func NewWithContext(ctx context.Context, options ...ContainerOption) *Progress {
|
||||
s := &pState{
|
||||
bHeap: priorityQueue{},
|
||||
rr: prr,
|
||||
queueBars: make(map[*Bar]*Bar),
|
||||
output: os.Stdout,
|
||||
popPriority: math.MinInt32,
|
||||
rows: make([]io.Reader, 0, 64),
|
||||
pool: make([]*Bar, 0, 64),
|
||||
refreshRate: defaultRefreshRate,
|
||||
popPriority: math.MinInt32,
|
||||
manualRefresh: make(chan interface{}),
|
||||
queueBars: make(map[*Bar]*Bar),
|
||||
output: os.Stdout,
|
||||
debugOut: io.Discard,
|
||||
}
|
||||
|
||||
for _, opt := range options {
|
||||
|
@ -77,16 +88,24 @@ func NewWithContext(ctx context.Context, options ...ContainerOption) *Progress {
|
|||
}
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
p := &Progress{
|
||||
ctx: ctx,
|
||||
uwg: s.uwg,
|
||||
cwg: new(sync.WaitGroup),
|
||||
bwg: new(sync.WaitGroup),
|
||||
operateState: make(chan func(*pState)),
|
||||
interceptIo: make(chan func(io.Writer)),
|
||||
done: make(chan struct{}),
|
||||
cancel: cancel,
|
||||
}
|
||||
|
||||
if s.shutdownNotifier != nil {
|
||||
p.shutdown = s.shutdownNotifier
|
||||
s.shutdownNotifier = nil
|
||||
} else {
|
||||
p.shutdown = make(chan struct{})
|
||||
}
|
||||
|
||||
p.cwg.Add(1)
|
||||
go p.serve(s, cwriter.New(s.output))
|
||||
return p
|
||||
}
|
||||
|
@ -101,15 +120,15 @@ func (p *Progress) AddSpinner(total int64, options ...BarOption) *Bar {
|
|||
return p.New(total, SpinnerStyle(), options...)
|
||||
}
|
||||
|
||||
// New creates a bar with provided BarFillerBuilder.
|
||||
// New creates a bar by calling `Build` method on provided `BarFillerBuilder`.
|
||||
func (p *Progress) New(total int64, builder BarFillerBuilder, options ...BarOption) *Bar {
|
||||
return p.Add(total, builder.Build(), options...)
|
||||
return p.AddFiller(total, builder.Build(), options...)
|
||||
}
|
||||
|
||||
// Add creates a bar which renders itself by provided filler.
|
||||
// AddFiller creates a bar which renders itself by provided filler.
|
||||
// If `total <= 0` triggering complete event by increment methods is disabled.
|
||||
// Panics if *Progress instance is done, i.e. called after (*Progress).Wait().
|
||||
func (p *Progress) Add(total int64, filler BarFiller, options ...BarOption) *Bar {
|
||||
func (p *Progress) AddFiller(total int64, filler BarFiller, options ...BarOption) *Bar {
|
||||
if filler == nil {
|
||||
filler = NopStyle().Build()
|
||||
}
|
||||
|
@ -132,7 +151,7 @@ func (p *Progress) Add(total int64, filler BarFiller, options ...BarOption) *Bar
|
|||
return bar
|
||||
case <-p.done:
|
||||
p.bwg.Done()
|
||||
panic(fmt.Sprintf("%T instance can't be reused after it's done!", p))
|
||||
panic(DoneError)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -140,13 +159,13 @@ func (p *Progress) traverseBars(cb func(b *Bar) bool) {
|
|||
sync := make(chan struct{})
|
||||
select {
|
||||
case p.operateState <- func(s *pState) {
|
||||
defer close(sync)
|
||||
for i := 0; i < s.bHeap.Len(); i++ {
|
||||
bar := s.bHeap[i]
|
||||
if !cb(bar) {
|
||||
break
|
||||
}
|
||||
}
|
||||
close(sync)
|
||||
}:
|
||||
<-sync
|
||||
case <-p.done:
|
||||
|
@ -178,54 +197,113 @@ func (p *Progress) BarCount() int {
|
|||
}
|
||||
}
|
||||
|
||||
// Wait waits for all bars to complete and finally shutdowns container.
|
||||
// After this method has been called, there is no way to reuse *Progress
|
||||
// instance.
|
||||
// Write is implementation of io.Writer.
|
||||
// Writing to `*mpb.Progress` will print lines above a running bar.
|
||||
// Writes aren't flushed immediately, but at next refresh cycle.
|
||||
// If Write is called after `*mpb.Progress` is done, `mpb.DoneError`
|
||||
// is returned.
|
||||
func (p *Progress) Write(b []byte) (int, error) {
|
||||
type result struct {
|
||||
n int
|
||||
err error
|
||||
}
|
||||
ch := make(chan *result)
|
||||
select {
|
||||
case p.interceptIo <- func(w io.Writer) {
|
||||
n, err := w.Write(b)
|
||||
ch <- &result{n, err}
|
||||
}:
|
||||
res := <-ch
|
||||
return res.n, res.err
|
||||
case <-p.done:
|
||||
return 0, DoneError
|
||||
}
|
||||
}
|
||||
|
||||
// Wait waits for all bars to complete and finally shutdowns container. After
|
||||
// this method has been called, there is no way to reuse (*Progress) instance.
|
||||
func (p *Progress) Wait() {
|
||||
// wait for user wg, if any
|
||||
if p.uwg != nil {
|
||||
p.uwg.Wait()
|
||||
}
|
||||
|
||||
// wait for bars to quit, if any
|
||||
p.bwg.Wait()
|
||||
|
||||
p.once.Do(p.shutdown)
|
||||
|
||||
// wait for container to quit
|
||||
p.cwg.Wait()
|
||||
p.Shutdown()
|
||||
}
|
||||
|
||||
func (p *Progress) shutdown() {
|
||||
close(p.done)
|
||||
// Shutdown cancels any running bar immediately and then shutdowns (*Progress)
|
||||
// instance. Normally this method shouldn't be called unless you know what you
|
||||
// are doing. Proper way to shutdown is to call (*Progress).Wait() instead.
|
||||
func (p *Progress) Shutdown() {
|
||||
p.cancel()
|
||||
<-p.shutdown
|
||||
}
|
||||
|
||||
func (p *Progress) newTicker(s *pState) chan time.Time {
|
||||
ch := make(chan time.Time)
|
||||
go func() {
|
||||
var autoRefresh <-chan time.Time
|
||||
if !s.disableAutoRefresh && !s.outputDiscarded {
|
||||
if s.renderDelay != nil {
|
||||
<-s.renderDelay
|
||||
}
|
||||
ticker := time.NewTicker(s.refreshRate)
|
||||
defer ticker.Stop()
|
||||
autoRefresh = ticker.C
|
||||
}
|
||||
for {
|
||||
select {
|
||||
case t := <-autoRefresh:
|
||||
ch <- t
|
||||
case x := <-s.manualRefresh:
|
||||
if t, ok := x.(time.Time); ok {
|
||||
ch <- t
|
||||
} else {
|
||||
ch <- time.Now()
|
||||
}
|
||||
case <-p.ctx.Done():
|
||||
close(p.done)
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
return ch
|
||||
}
|
||||
|
||||
func (p *Progress) serve(s *pState, cw *cwriter.Writer) {
|
||||
defer p.cwg.Done()
|
||||
defer close(p.shutdown)
|
||||
|
||||
p.refreshCh = s.newTicker(p.done)
|
||||
|
||||
render := func(debugOut io.Writer) {
|
||||
err := s.render(cw)
|
||||
for err != nil {
|
||||
if debugOut != nil {
|
||||
_, err = fmt.Fprintln(debugOut, err)
|
||||
} else {
|
||||
panic(err)
|
||||
}
|
||||
debugOut = nil
|
||||
render := func() error {
|
||||
if s.bHeap.Len() == 0 {
|
||||
return nil
|
||||
}
|
||||
return s.render(cw)
|
||||
}
|
||||
|
||||
refreshCh := p.newTicker(s)
|
||||
|
||||
for {
|
||||
select {
|
||||
case op := <-p.operateState:
|
||||
op(s)
|
||||
case <-p.refreshCh:
|
||||
render(s.debugOut)
|
||||
case <-s.shutdownNotifier:
|
||||
case fn := <-p.interceptIo:
|
||||
fn(cw)
|
||||
case <-refreshCh:
|
||||
err := render()
|
||||
if err != nil {
|
||||
s.heapUpdated = false
|
||||
render = func() error { return nil }
|
||||
_, _ = fmt.Fprintln(s.debugOut, err.Error())
|
||||
p.cancel() // cancel all bars
|
||||
}
|
||||
case <-p.done:
|
||||
for s.heapUpdated {
|
||||
render(s.debugOut)
|
||||
err := render()
|
||||
if err != nil {
|
||||
_, _ = fmt.Fprintln(s.debugOut, err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -233,12 +311,13 @@ func (p *Progress) serve(s *pState, cw *cwriter.Writer) {
|
|||
}
|
||||
|
||||
func (s *pState) render(cw *cwriter.Writer) error {
|
||||
var wg sync.WaitGroup
|
||||
if s.heapUpdated {
|
||||
s.updateSyncMatrix()
|
||||
s.heapUpdated = false
|
||||
}
|
||||
syncWidth(s.pMatrix)
|
||||
syncWidth(s.aMatrix)
|
||||
syncWidth(&wg, s.pMatrix)
|
||||
syncWidth(&wg, s.aMatrix)
|
||||
|
||||
width, height, err := cw.GetTermSize()
|
||||
if err != nil {
|
||||
|
@ -250,21 +329,25 @@ func (s *pState) render(cw *cwriter.Writer) error {
|
|||
go bar.render(width)
|
||||
}
|
||||
|
||||
return s.flush(cw, height)
|
||||
err = s.flush(&wg, cw, height)
|
||||
wg.Wait()
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *pState) flush(cw *cwriter.Writer, height int) error {
|
||||
var wg sync.WaitGroup
|
||||
func (s *pState) flush(wg *sync.WaitGroup, cw *cwriter.Writer, height int) error {
|
||||
var popCount int
|
||||
rows := make([]io.Reader, 0, height)
|
||||
pool := make([]*Bar, 0, s.bHeap.Len())
|
||||
|
||||
for s.bHeap.Len() > 0 {
|
||||
var usedRows int
|
||||
b := heap.Pop(&s.bHeap).(*Bar)
|
||||
frame := <-b.frameCh
|
||||
if frame.err != nil {
|
||||
// b.frameCh is buffered it's ok to return here
|
||||
return frame.err
|
||||
}
|
||||
var usedRows int
|
||||
for i := len(frame.rows) - 1; i >= 0; i-- {
|
||||
if row := frame.rows[i]; len(rows) < height {
|
||||
rows = append(rows, row)
|
||||
if row := frame.rows[i]; len(s.rows) < height {
|
||||
s.rows = append(s.rows, row)
|
||||
usedRows++
|
||||
} else {
|
||||
wg.Add(1)
|
||||
|
@ -274,83 +357,65 @@ func (s *pState) flush(cw *cwriter.Writer, height int) error {
|
|||
}()
|
||||
}
|
||||
}
|
||||
if frame.shutdown != 0 {
|
||||
if frame.shutdown {
|
||||
b.Wait() // waiting for b.done, so it's safe to read b.bs
|
||||
drop := b.bs.dropOnComplete
|
||||
if qb, ok := s.queueBars[b]; ok {
|
||||
delete(s.queueBars, b)
|
||||
qb.priority = b.priority
|
||||
pool = append(pool, qb)
|
||||
drop = true
|
||||
} else if s.popCompleted && !b.bs.noPop {
|
||||
if frame.shutdown > 1 {
|
||||
popCount += usedRows
|
||||
drop = true
|
||||
} else {
|
||||
s.popPriority++
|
||||
b.priority = s.popPriority
|
||||
}
|
||||
s.pool = append(s.pool, qb)
|
||||
s.heapUpdated = true
|
||||
continue
|
||||
}
|
||||
if drop {
|
||||
if s.popCompleted && !b.bs.noPop {
|
||||
switch b.bs.shutdown++; b.bs.shutdown {
|
||||
case 1:
|
||||
b.priority = s.popPriority
|
||||
s.popPriority++
|
||||
default:
|
||||
if b.bs.dropOnComplete {
|
||||
popCount += usedRows
|
||||
s.heapUpdated = true
|
||||
continue
|
||||
}
|
||||
}
|
||||
} else if b.bs.dropOnComplete {
|
||||
s.heapUpdated = true
|
||||
continue
|
||||
}
|
||||
}
|
||||
pool = append(pool, b)
|
||||
s.pool = append(s.pool, b)
|
||||
}
|
||||
|
||||
for _, b := range pool {
|
||||
heap.Push(&s.bHeap, b)
|
||||
switch len(s.pool) {
|
||||
case 0:
|
||||
if s.heapUpdated {
|
||||
s.updateSyncMatrix()
|
||||
s.heapUpdated = false
|
||||
}
|
||||
case 1:
|
||||
heap.Push(&s.bHeap, s.pool[0])
|
||||
s.pool = s.pool[:0]
|
||||
default:
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
for _, b := range s.pool {
|
||||
heap.Push(&s.bHeap, b)
|
||||
}
|
||||
s.pool = s.pool[:0]
|
||||
wg.Done()
|
||||
}()
|
||||
}
|
||||
|
||||
for i := len(rows) - 1; i >= 0; i-- {
|
||||
_, err := cw.ReadFrom(rows[i])
|
||||
for i := len(s.rows) - 1; i >= 0; i-- {
|
||||
_, err := cw.ReadFrom(s.rows[i])
|
||||
if err != nil {
|
||||
wg.Wait()
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
return cw.Flush(len(rows) - popCount)
|
||||
}
|
||||
|
||||
func (s *pState) newTicker(done <-chan struct{}) chan time.Time {
|
||||
ch := make(chan time.Time)
|
||||
if s.shutdownNotifier == nil {
|
||||
s.shutdownNotifier = make(chan struct{})
|
||||
}
|
||||
go func() {
|
||||
if s.renderDelay != nil {
|
||||
<-s.renderDelay
|
||||
}
|
||||
var internalRefresh <-chan time.Time
|
||||
if !s.outputDiscarded {
|
||||
if s.externalRefresh == nil {
|
||||
ticker := time.NewTicker(s.rr)
|
||||
defer ticker.Stop()
|
||||
internalRefresh = ticker.C
|
||||
}
|
||||
} else {
|
||||
s.externalRefresh = nil
|
||||
}
|
||||
for {
|
||||
select {
|
||||
case t := <-internalRefresh:
|
||||
ch <- t
|
||||
case x := <-s.externalRefresh:
|
||||
if t, ok := x.(time.Time); ok {
|
||||
ch <- t
|
||||
} else {
|
||||
ch <- time.Now()
|
||||
}
|
||||
case <-done:
|
||||
close(s.shutdownNotifier)
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
return ch
|
||||
err := cw.Flush(len(s.rows) - popCount)
|
||||
s.rows = s.rows[:0]
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *pState) updateSyncMatrix() {
|
||||
|
@ -359,13 +424,12 @@ func (s *pState) updateSyncMatrix() {
|
|||
for i := 0; i < s.bHeap.Len(); i++ {
|
||||
bar := s.bHeap[i]
|
||||
table := bar.wSyncTable()
|
||||
pRow, aRow := table[0], table[1]
|
||||
|
||||
for i, ch := range pRow {
|
||||
for i, ch := range table[0] {
|
||||
s.pMatrix[i] = append(s.pMatrix[i], ch)
|
||||
}
|
||||
|
||||
for i, ch := range aRow {
|
||||
for i, ch := range table[1] {
|
||||
s.aMatrix[i] = append(s.aMatrix[i], ch)
|
||||
}
|
||||
}
|
||||
|
@ -373,12 +437,12 @@ func (s *pState) updateSyncMatrix() {
|
|||
|
||||
func (s *pState) makeBarState(total int64, filler BarFiller, options ...BarOption) *bState {
|
||||
bs := &bState{
|
||||
id: s.idCount,
|
||||
priority: s.idCount,
|
||||
reqWidth: s.reqWidth,
|
||||
total: total,
|
||||
filler: filler,
|
||||
debugOut: s.debugOut,
|
||||
id: s.idCount,
|
||||
priority: s.idCount,
|
||||
reqWidth: s.reqWidth,
|
||||
total: total,
|
||||
filler: filler,
|
||||
manualRefresh: s.manualRefresh,
|
||||
}
|
||||
|
||||
if total > 0 {
|
||||
|
@ -405,13 +469,14 @@ func (s *pState) makeBarState(total int64, filler BarFiller, options ...BarOptio
|
|||
return bs
|
||||
}
|
||||
|
||||
func syncWidth(matrix map[int][]chan int) {
|
||||
func syncWidth(wg *sync.WaitGroup, matrix map[int][]chan int) {
|
||||
for _, column := range matrix {
|
||||
go maxWidthDistributor(column)
|
||||
wg.Add(1)
|
||||
go maxWidthDistributor(wg, column)
|
||||
}
|
||||
}
|
||||
|
||||
func maxWidthDistributor(column []chan int) {
|
||||
func maxWidthDistributor(wg *sync.WaitGroup, column []chan int) {
|
||||
var maxWidth int
|
||||
for _, ch := range column {
|
||||
if w := <-ch; w > maxWidth {
|
||||
|
@ -421,4 +486,5 @@ func maxWidthDistributor(column []chan int) {
|
|||
for _, ch := range column {
|
||||
ch <- maxWidth
|
||||
}
|
||||
wg.Done()
|
||||
}
|
96
vendor/github.com/vbauerster/mpb/v8/proxyreader.go
generated
vendored
Normal file
96
vendor/github.com/vbauerster/mpb/v8/proxyreader.go
generated
vendored
Normal file
|
@ -0,0 +1,96 @@
|
|||
package mpb
|
||||
|
||||
import (
|
||||
"io"
|
||||
"time"
|
||||
)
|
||||
|
||||
type proxyReader struct {
|
||||
io.ReadCloser
|
||||
bar *Bar
|
||||
}
|
||||
|
||||
func (x proxyReader) Read(p []byte) (int, error) {
|
||||
n, err := x.ReadCloser.Read(p)
|
||||
x.bar.IncrBy(n)
|
||||
return n, err
|
||||
}
|
||||
|
||||
type proxyWriterTo struct {
|
||||
proxyReader
|
||||
}
|
||||
|
||||
func (x proxyWriterTo) WriteTo(w io.Writer) (int64, error) {
|
||||
n, err := x.ReadCloser.(io.WriterTo).WriteTo(w)
|
||||
x.bar.IncrInt64(n)
|
||||
return n, err
|
||||
}
|
||||
|
||||
type ewmaProxyReader struct {
|
||||
io.ReadCloser
|
||||
bar *Bar
|
||||
}
|
||||
|
||||
func (x ewmaProxyReader) Read(p []byte) (int, error) {
|
||||
start := time.Now()
|
||||
n, err := x.ReadCloser.Read(p)
|
||||
x.bar.EwmaIncrBy(n, time.Since(start))
|
||||
return n, err
|
||||
}
|
||||
|
||||
type ewmaProxyWriterTo struct {
|
||||
ewmaProxyReader
|
||||
}
|
||||
|
||||
func (x ewmaProxyWriterTo) WriteTo(w io.Writer) (int64, error) {
|
||||
start := time.Now()
|
||||
n, err := x.ReadCloser.(io.WriterTo).WriteTo(w)
|
||||
x.bar.EwmaIncrInt64(n, time.Since(start))
|
||||
return n, err
|
||||
}
|
||||
|
||||
func newProxyReader(r io.Reader, b *Bar, hasEwma bool) io.ReadCloser {
|
||||
rc := toReadCloser(r)
|
||||
if hasEwma {
|
||||
epr := ewmaProxyReader{rc, b}
|
||||
if _, ok := r.(io.WriterTo); ok {
|
||||
return ewmaProxyWriterTo{epr}
|
||||
}
|
||||
return epr
|
||||
}
|
||||
pr := proxyReader{rc, b}
|
||||
if _, ok := r.(io.WriterTo); ok {
|
||||
return proxyWriterTo{pr}
|
||||
}
|
||||
return pr
|
||||
}
|
||||
|
||||
func toReadCloser(r io.Reader) io.ReadCloser {
|
||||
if rc, ok := r.(io.ReadCloser); ok {
|
||||
return rc
|
||||
}
|
||||
return toNopReadCloser(r)
|
||||
}
|
||||
|
||||
func toNopReadCloser(r io.Reader) io.ReadCloser {
|
||||
if _, ok := r.(io.WriterTo); ok {
|
||||
return nopReadCloserWriterTo{r}
|
||||
}
|
||||
return nopReadCloser{r}
|
||||
}
|
||||
|
||||
type nopReadCloser struct {
|
||||
io.Reader
|
||||
}
|
||||
|
||||
func (nopReadCloser) Close() error { return nil }
|
||||
|
||||
type nopReadCloserWriterTo struct {
|
||||
io.Reader
|
||||
}
|
||||
|
||||
func (nopReadCloserWriterTo) Close() error { return nil }
|
||||
|
||||
func (c nopReadCloserWriterTo) WriteTo(w io.Writer) (int64, error) {
|
||||
return c.Reader.(io.WriterTo).WriteTo(w)
|
||||
}
|
96
vendor/github.com/vbauerster/mpb/v8/proxywriter.go
generated
vendored
Normal file
96
vendor/github.com/vbauerster/mpb/v8/proxywriter.go
generated
vendored
Normal file
|
@ -0,0 +1,96 @@
|
|||
package mpb
|
||||
|
||||
import (
|
||||
"io"
|
||||
"time"
|
||||
)
|
||||
|
||||
type proxyWriter struct {
|
||||
io.WriteCloser
|
||||
bar *Bar
|
||||
}
|
||||
|
||||
func (x proxyWriter) Write(p []byte) (int, error) {
|
||||
n, err := x.WriteCloser.Write(p)
|
||||
x.bar.IncrBy(n)
|
||||
return n, err
|
||||
}
|
||||
|
||||
type proxyReaderFrom struct {
|
||||
proxyWriter
|
||||
}
|
||||
|
||||
func (x proxyReaderFrom) ReadFrom(r io.Reader) (int64, error) {
|
||||
n, err := x.WriteCloser.(io.ReaderFrom).ReadFrom(r)
|
||||
x.bar.IncrInt64(n)
|
||||
return n, err
|
||||
}
|
||||
|
||||
type ewmaProxyWriter struct {
|
||||
io.WriteCloser
|
||||
bar *Bar
|
||||
}
|
||||
|
||||
func (x ewmaProxyWriter) Write(p []byte) (int, error) {
|
||||
start := time.Now()
|
||||
n, err := x.WriteCloser.Write(p)
|
||||
x.bar.EwmaIncrBy(n, time.Since(start))
|
||||
return n, err
|
||||
}
|
||||
|
||||
type ewmaProxyReaderFrom struct {
|
||||
ewmaProxyWriter
|
||||
}
|
||||
|
||||
func (x ewmaProxyReaderFrom) ReadFrom(r io.Reader) (int64, error) {
|
||||
start := time.Now()
|
||||
n, err := x.WriteCloser.(io.ReaderFrom).ReadFrom(r)
|
||||
x.bar.EwmaIncrInt64(n, time.Since(start))
|
||||
return n, err
|
||||
}
|
||||
|
||||
func newProxyWriter(w io.Writer, b *Bar, hasEwma bool) io.WriteCloser {
|
||||
wc := toWriteCloser(w)
|
||||
if hasEwma {
|
||||
epw := ewmaProxyWriter{wc, b}
|
||||
if _, ok := w.(io.ReaderFrom); ok {
|
||||
return ewmaProxyReaderFrom{epw}
|
||||
}
|
||||
return epw
|
||||
}
|
||||
pw := proxyWriter{wc, b}
|
||||
if _, ok := w.(io.ReaderFrom); ok {
|
||||
return proxyReaderFrom{pw}
|
||||
}
|
||||
return pw
|
||||
}
|
||||
|
||||
func toWriteCloser(w io.Writer) io.WriteCloser {
|
||||
if wc, ok := w.(io.WriteCloser); ok {
|
||||
return wc
|
||||
}
|
||||
return toNopWriteCloser(w)
|
||||
}
|
||||
|
||||
func toNopWriteCloser(w io.Writer) io.WriteCloser {
|
||||
if _, ok := w.(io.ReaderFrom); ok {
|
||||
return nopWriteCloserReaderFrom{w}
|
||||
}
|
||||
return nopWriteCloser{w}
|
||||
}
|
||||
|
||||
type nopWriteCloser struct {
|
||||
io.Writer
|
||||
}
|
||||
|
||||
func (nopWriteCloser) Close() error { return nil }
|
||||
|
||||
type nopWriteCloserReaderFrom struct {
|
||||
io.Writer
|
||||
}
|
||||
|
||||
func (nopWriteCloserReaderFrom) Close() error { return nil }
|
||||
|
||||
func (c nopWriteCloserReaderFrom) ReadFrom(r io.Reader) (int64, error) {
|
||||
return c.Writer.(io.ReaderFrom).ReadFrom(r)
|
||||
}
|
16
vendor/modules.txt
vendored
16
vendor/modules.txt
vendored
|
@ -175,7 +175,7 @@ github.com/containers/common/version
|
|||
# github.com/containers/conmon v2.0.20+incompatible
|
||||
## explicit
|
||||
github.com/containers/conmon/runner/config
|
||||
# github.com/containers/image/v5 v5.24.0
|
||||
# github.com/containers/image/v5 v5.24.1-0.20230202144111-a49c94a010be
|
||||
## explicit; go 1.17
|
||||
github.com/containers/image/v5/copy
|
||||
github.com/containers/image/v5/directory
|
||||
|
@ -838,7 +838,7 @@ github.com/syndtr/gocapability/capability
|
|||
# github.com/tchap/go-patricia v2.3.0+incompatible
|
||||
## explicit
|
||||
github.com/tchap/go-patricia/patricia
|
||||
# github.com/theupdateframework/go-tuf v0.5.2-0.20221207161717-9cb61d6e65f5
|
||||
# github.com/theupdateframework/go-tuf v0.5.2
|
||||
## explicit; go 1.18
|
||||
github.com/theupdateframework/go-tuf/encrypted
|
||||
# github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399
|
||||
|
@ -863,12 +863,12 @@ github.com/ulikunitz/xz/lzma
|
|||
github.com/vbatts/tar-split/archive/tar
|
||||
github.com/vbatts/tar-split/tar/asm
|
||||
github.com/vbatts/tar-split/tar/storage
|
||||
# github.com/vbauerster/mpb/v7 v7.5.3
|
||||
## explicit; go 1.14
|
||||
github.com/vbauerster/mpb/v7
|
||||
github.com/vbauerster/mpb/v7/cwriter
|
||||
github.com/vbauerster/mpb/v7/decor
|
||||
github.com/vbauerster/mpb/v7/internal
|
||||
# github.com/vbauerster/mpb/v8 v8.1.4
|
||||
## explicit; go 1.17
|
||||
github.com/vbauerster/mpb/v8
|
||||
github.com/vbauerster/mpb/v8/cwriter
|
||||
github.com/vbauerster/mpb/v8/decor
|
||||
github.com/vbauerster/mpb/v8/internal
|
||||
# github.com/vishvananda/netlink v1.2.1-beta.2
|
||||
## explicit; go 1.12
|
||||
github.com/vishvananda/netlink
|
||||
|
|
Loading…
Reference in a new issue