diff --git a/go.mod b/go.mod index a708763d66..1d3e249dd2 100644 --- a/go.mod +++ b/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 diff --git a/go.sum b/go.sum index df6565c0a2..2f9cbba0b3 100644 --- a/go.sum +++ b/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= diff --git a/pkg/machine/pull.go b/pkg/machine/pull.go index 00b7ae1350..b7289433b6 100644 --- a/pkg/machine/pull.go +++ b/pkg/machine/pull.go @@ -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 diff --git a/vendor/github.com/containers/image/v5/copy/copy.go b/vendor/github.com/containers/image/v5/copy/copy.go index 26521fe090..41d578a973 100644 --- a/vendor/github.com/containers/image/v5/copy/copy.go +++ b/vendor/github.com/containers/image/v5/copy/copy.go @@ -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" ) diff --git a/vendor/github.com/containers/image/v5/copy/progress_bars.go b/vendor/github.com/containers/image/v5/copy/progress_bars.go index 85676f01c6..43145fb786 100644 --- a/vendor/github.com/containers/image/v5/copy/progress_bars.go +++ b/vendor/github.com/containers/image/v5/copy/progress_bars.go @@ -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. diff --git a/vendor/github.com/containers/image/v5/docker/registries_d.go b/vendor/github.com/containers/image/v5/docker/registries_d.go index 61a4964b6b..c7b884ab3c 100644 --- a/vendor/github.com/containers/image/v5/docker/registries_d.go +++ b/vendor/github.com/containers/image/v5/docker/registries_d.go @@ -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. diff --git a/vendor/github.com/containers/image/v5/internal/manifest/errors.go b/vendor/github.com/containers/image/v5/internal/manifest/errors.go index e5732a8c43..6ebe4b24cf 100644 --- a/vendor/github.com/containers/image/v5/internal/manifest/errors.go +++ b/vendor/github.com/containers/image/v5/internal/manifest/errors.go @@ -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) } diff --git a/vendor/github.com/containers/image/v5/openshift/openshift-copies.go b/vendor/github.com/containers/image/v5/openshift/openshift-copies.go index 42e8970a07..325d6ee5ff 100644 --- a/vendor/github.com/containers/image/v5/openshift/openshift-copies.go +++ b/vendor/github.com/containers/image/v5/openshift/openshift-copies.go @@ -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"` } diff --git a/vendor/github.com/containers/image/v5/version/version.go b/vendor/github.com/containers/image/v5/version/version.go index 83e576ead5..0d90b5b0c8 100644 --- a/vendor/github.com/containers/image/v5/version/version.go +++ b/vendor/github.com/containers/image/v5/version/version.go @@ -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. diff --git a/vendor/github.com/vbauerster/mpb/v7/cwriter/writer.go b/vendor/github.com/vbauerster/mpb/v7/cwriter/writer.go deleted file mode 100644 index 19fd90e942..0000000000 --- a/vendor/github.com/vbauerster/mpb/v7/cwriter/writer.go +++ /dev/null @@ -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 -} diff --git a/vendor/github.com/vbauerster/mpb/v7/cwriter/writer_posix.go b/vendor/github.com/vbauerster/mpb/v7/cwriter/writer_posix.go deleted file mode 100644 index f54a5d06b8..0000000000 --- a/vendor/github.com/vbauerster/mpb/v7/cwriter/writer_posix.go +++ /dev/null @@ -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 -} diff --git a/vendor/github.com/vbauerster/mpb/v7/decor/optimistic_string_writer.go b/vendor/github.com/vbauerster/mpb/v7/decor/optimistic_string_writer.go deleted file mode 100644 index c6a34384e6..0000000000 --- a/vendor/github.com/vbauerster/mpb/v7/decor/optimistic_string_writer.go +++ /dev/null @@ -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) - } -} diff --git a/vendor/github.com/vbauerster/mpb/v7/proxyreader.go b/vendor/github.com/vbauerster/mpb/v7/proxyreader.go deleted file mode 100644 index 51b63ea7a8..0000000000 --- a/vendor/github.com/vbauerster/mpb/v7/proxyreader.go +++ /dev/null @@ -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) -} diff --git a/vendor/github.com/vbauerster/mpb/v7/.gitignore b/vendor/github.com/vbauerster/mpb/v8/.gitignore similarity index 100% rename from vendor/github.com/vbauerster/mpb/v7/.gitignore rename to vendor/github.com/vbauerster/mpb/v8/.gitignore diff --git a/vendor/github.com/vbauerster/mpb/v7/README.md b/vendor/github.com/vbauerster/mpb/v8/README.md similarity index 89% rename from vendor/github.com/vbauerster/mpb/v7/README.md rename to vendor/github.com/vbauerster/mpb/v8/README.md index 413f9e1dbf..d5f7872766 100644 --- a/vendor/github.com/vbauerster/mpb/v7/README.md +++ b/vendor/github.com/vbauerster/mpb/v8/README.md @@ -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)) } }() } diff --git a/vendor/github.com/vbauerster/mpb/v7/UNLICENSE b/vendor/github.com/vbauerster/mpb/v8/UNLICENSE similarity index 100% rename from vendor/github.com/vbauerster/mpb/v7/UNLICENSE rename to vendor/github.com/vbauerster/mpb/v8/UNLICENSE diff --git a/vendor/github.com/vbauerster/mpb/v7/bar.go b/vendor/github.com/vbauerster/mpb/v8/bar.go similarity index 60% rename from vendor/github.com/vbauerster/mpb/v7/bar.go rename to vendor/github.com/vbauerster/mpb/v8/bar.go index 7db860e30d..b71e6b4659 100644 --- a/vendor/github.com/vbauerster/mpb/v7/bar.go +++ b/vendor/github.com/vbauerster/mpb/v8/bar.go @@ -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(' ') } diff --git a/vendor/github.com/vbauerster/mpb/v7/bar_filler.go b/vendor/github.com/vbauerster/mpb/v8/bar_filler.go similarity index 52% rename from vendor/github.com/vbauerster/mpb/v7/bar_filler.go rename to vendor/github.com/vbauerster/mpb/v8/bar_filler.go index 81177fc2ee..5ac343c7db 100644 --- a/vendor/github.com/vbauerster/mpb/v7/bar_filler.go +++ b/vendor/github.com/vbauerster/mpb/v8/bar_filler.go @@ -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() -} diff --git a/vendor/github.com/vbauerster/mpb/v7/bar_filler_bar.go b/vendor/github.com/vbauerster/mpb/v8/bar_filler_bar.go similarity index 85% rename from vendor/github.com/vbauerster/mpb/v7/bar_filler_bar.go rename to vendor/github.com/vbauerster/mpb/v8/bar_filler_bar.go index d8bf90a4a9..1db8f0b4b7 100644 --- a/vendor/github.com/vbauerster/mpb/v7/bar_filler_bar.go +++ b/vendor/github.com/vbauerster/mpb/v8/bar_filler_bar.go @@ -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 } diff --git a/vendor/github.com/vbauerster/mpb/v7/bar_filler_nop.go b/vendor/github.com/vbauerster/mpb/v8/bar_filler_nop.go similarity index 60% rename from vendor/github.com/vbauerster/mpb/v7/bar_filler_nop.go rename to vendor/github.com/vbauerster/mpb/v8/bar_filler_nop.go index 1a7086fecb..f7947f1dc8 100644 --- a/vendor/github.com/vbauerster/mpb/v7/bar_filler_nop.go +++ b/vendor/github.com/vbauerster/mpb/v8/bar_filler_nop.go @@ -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 + }) }) } diff --git a/vendor/github.com/vbauerster/mpb/v7/bar_filler_spinner.go b/vendor/github.com/vbauerster/mpb/v8/bar_filler_spinner.go similarity index 85% rename from vendor/github.com/vbauerster/mpb/v7/bar_filler_spinner.go rename to vendor/github.com/vbauerster/mpb/v8/bar_filler_spinner.go index d38525efc9..a28470d6e8 100644 --- a/vendor/github.com/vbauerster/mpb/v7/bar_filler_spinner.go +++ b/vendor/github.com/vbauerster/mpb/v8/bar_filler_spinner.go @@ -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 } diff --git a/vendor/github.com/vbauerster/mpb/v7/bar_option.go b/vendor/github.com/vbauerster/mpb/v8/bar_option.go similarity index 66% rename from vendor/github.com/vbauerster/mpb/v7/bar_option.go rename to vendor/github.com/vbauerster/mpb/v8/bar_option.go index 3506ed2f11..953e9d2781 100644 --- a/vendor/github.com/vbauerster/mpb/v7/bar_option.go +++ b/vendor/github.com/vbauerster/mpb/v8/bar_option.go @@ -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 +} diff --git a/vendor/github.com/vbauerster/mpb/v7/container_option.go b/vendor/github.com/vbauerster/mpb/v8/container_option.go similarity index 71% rename from vendor/github.com/vbauerster/mpb/v7/container_option.go rename to vendor/github.com/vbauerster/mpb/v8/container_option.go index 38239d4fa9..da0e9b1aca 100644 --- a/vendor/github.com/vbauerster/mpb/v7/container_option.go +++ b/vendor/github.com/vbauerster/mpb/v8/container_option.go @@ -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 +} diff --git a/vendor/github.com/vbauerster/mpb/v7/cwriter/doc.go b/vendor/github.com/vbauerster/mpb/v8/cwriter/doc.go similarity index 100% rename from vendor/github.com/vbauerster/mpb/v7/cwriter/doc.go rename to vendor/github.com/vbauerster/mpb/v8/cwriter/doc.go diff --git a/vendor/github.com/vbauerster/mpb/v7/cwriter/util_bsd.go b/vendor/github.com/vbauerster/mpb/v8/cwriter/util_bsd.go similarity index 58% rename from vendor/github.com/vbauerster/mpb/v7/cwriter/util_bsd.go rename to vendor/github.com/vbauerster/mpb/v8/cwriter/util_bsd.go index 4e3564ecee..215643b45c 100644 --- a/vendor/github.com/vbauerster/mpb/v7/cwriter/util_bsd.go +++ b/vendor/github.com/vbauerster/mpb/v8/cwriter/util_bsd.go @@ -1,4 +1,4 @@ -// +build darwin dragonfly freebsd netbsd openbsd +//go:build darwin || dragonfly || freebsd || netbsd || openbsd package cwriter diff --git a/vendor/github.com/vbauerster/mpb/v7/cwriter/util_linux.go b/vendor/github.com/vbauerster/mpb/v8/cwriter/util_linux.go similarity index 78% rename from vendor/github.com/vbauerster/mpb/v7/cwriter/util_linux.go rename to vendor/github.com/vbauerster/mpb/v8/cwriter/util_linux.go index 253f12dd2f..7d0e761232 100644 --- a/vendor/github.com/vbauerster/mpb/v7/cwriter/util_linux.go +++ b/vendor/github.com/vbauerster/mpb/v8/cwriter/util_linux.go @@ -1,4 +1,4 @@ -// +build aix linux +//go:build aix || linux package cwriter diff --git a/vendor/github.com/vbauerster/mpb/v7/cwriter/util_solaris.go b/vendor/github.com/vbauerster/mpb/v8/cwriter/util_solaris.go similarity index 82% rename from vendor/github.com/vbauerster/mpb/v7/cwriter/util_solaris.go rename to vendor/github.com/vbauerster/mpb/v8/cwriter/util_solaris.go index 4b29ff5c00..981f574f43 100644 --- a/vendor/github.com/vbauerster/mpb/v7/cwriter/util_solaris.go +++ b/vendor/github.com/vbauerster/mpb/v8/cwriter/util_solaris.go @@ -1,4 +1,4 @@ -// +build solaris +//go:build solaris package cwriter diff --git a/vendor/github.com/vbauerster/mpb/v7/cwriter/util_zos.go b/vendor/github.com/vbauerster/mpb/v8/cwriter/util_zos.go similarity index 85% rename from vendor/github.com/vbauerster/mpb/v7/cwriter/util_zos.go rename to vendor/github.com/vbauerster/mpb/v8/cwriter/util_zos.go index b7d67fc43b..5daf003a38 100644 --- a/vendor/github.com/vbauerster/mpb/v7/cwriter/util_zos.go +++ b/vendor/github.com/vbauerster/mpb/v8/cwriter/util_zos.go @@ -1,4 +1,4 @@ -// +build zos +//go:build zos package cwriter diff --git a/vendor/github.com/vbauerster/mpb/v8/cwriter/writer.go b/vendor/github.com/vbauerster/mpb/v8/cwriter/writer.go new file mode 100644 index 0000000000..35136de60b --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v8/cwriter/writer.go @@ -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 +} diff --git a/vendor/github.com/vbauerster/mpb/v8/cwriter/writer_posix.go b/vendor/github.com/vbauerster/mpb/v8/cwriter/writer_posix.go new file mode 100644 index 0000000000..e80d757afe --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v8/cwriter/writer_posix.go @@ -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 +} diff --git a/vendor/github.com/vbauerster/mpb/v7/cwriter/writer_windows.go b/vendor/github.com/vbauerster/mpb/v8/cwriter/writer_windows.go similarity index 70% rename from vendor/github.com/vbauerster/mpb/v7/cwriter/writer_windows.go rename to vendor/github.com/vbauerster/mpb/v8/cwriter/writer_windows.go index 2c4c3707be..44293f26ac 100644 --- a/vendor/github.com/vbauerster/mpb/v7/cwriter/writer_windows.go +++ b/vendor/github.com/vbauerster/mpb/v8/cwriter/writer_windows.go @@ -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 diff --git a/vendor/github.com/vbauerster/mpb/v7/decor/any.go b/vendor/github.com/vbauerster/mpb/v8/decor/any.go similarity index 99% rename from vendor/github.com/vbauerster/mpb/v7/decor/any.go rename to vendor/github.com/vbauerster/mpb/v8/decor/any.go index 39518f5945..1ab764aec6 100644 --- a/vendor/github.com/vbauerster/mpb/v7/decor/any.go +++ b/vendor/github.com/vbauerster/mpb/v8/decor/any.go @@ -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} } diff --git a/vendor/github.com/vbauerster/mpb/v7/decor/counters.go b/vendor/github.com/vbauerster/mpb/v8/decor/counters.go similarity index 99% rename from vendor/github.com/vbauerster/mpb/v7/decor/counters.go rename to vendor/github.com/vbauerster/mpb/v8/decor/counters.go index 4a5343d412..331c3df674 100644 --- a/vendor/github.com/vbauerster/mpb/v7/decor/counters.go +++ b/vendor/github.com/vbauerster/mpb/v8/decor/counters.go @@ -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 == "" { diff --git a/vendor/github.com/vbauerster/mpb/v7/decor/decorator.go b/vendor/github.com/vbauerster/mpb/v8/decor/decorator.go similarity index 91% rename from vendor/github.com/vbauerster/mpb/v7/decor/decorator.go rename to vendor/github.com/vbauerster/mpb/v8/decor/decorator.go index aad7709c06..a43a139baf 100644 --- a/vendor/github.com/vbauerster/mpb/v7/decor/decorator.go +++ b/vendor/github.com/vbauerster/mpb/v8/decor/decorator.go @@ -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. diff --git a/vendor/github.com/vbauerster/mpb/v7/decor/doc.go b/vendor/github.com/vbauerster/mpb/v8/decor/doc.go similarity index 75% rename from vendor/github.com/vbauerster/mpb/v7/decor/doc.go rename to vendor/github.com/vbauerster/mpb/v8/decor/doc.go index 4e4299307e..d41aa50619 100644 --- a/vendor/github.com/vbauerster/mpb/v7/decor/doc.go +++ b/vendor/github.com/vbauerster/mpb/v8/decor/doc.go @@ -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: // diff --git a/vendor/github.com/vbauerster/mpb/v7/decor/elapsed.go b/vendor/github.com/vbauerster/mpb/v8/decor/elapsed.go similarity index 99% rename from vendor/github.com/vbauerster/mpb/v7/decor/elapsed.go rename to vendor/github.com/vbauerster/mpb/v8/decor/elapsed.go index e389f15815..6cee7d1d47 100644 --- a/vendor/github.com/vbauerster/mpb/v7/decor/elapsed.go +++ b/vendor/github.com/vbauerster/mpb/v8/decor/elapsed.go @@ -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) diff --git a/vendor/github.com/vbauerster/mpb/v7/decor/eta.go b/vendor/github.com/vbauerster/mpb/v8/decor/eta.go similarity index 96% rename from vendor/github.com/vbauerster/mpb/v7/decor/eta.go rename to vendor/github.com/vbauerster/mpb/v8/decor/eta.go index d03caa7357..691f8b7b3f 100644 --- a/vendor/github.com/vbauerster/mpb/v7/decor/eta.go +++ b/vendor/github.com/vbauerster/mpb/v8/decor/eta.go @@ -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...), diff --git a/vendor/github.com/vbauerster/mpb/v7/decor/merge.go b/vendor/github.com/vbauerster/mpb/v8/decor/merge.go similarity index 91% rename from vendor/github.com/vbauerster/mpb/v7/decor/merge.go rename to vendor/github.com/vbauerster/mpb/v8/decor/merge.go index 8476711551..cc9a512c6b 100644 --- a/vendor/github.com/vbauerster/mpb/v7/decor/merge.go +++ b/vendor/github.com/vbauerster/mpb/v8/decor/merge.go @@ -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 diff --git a/vendor/github.com/vbauerster/mpb/v7/decor/moving_average.go b/vendor/github.com/vbauerster/mpb/v8/decor/moving_average.go similarity index 100% rename from vendor/github.com/vbauerster/mpb/v7/decor/moving_average.go rename to vendor/github.com/vbauerster/mpb/v8/decor/moving_average.go diff --git a/vendor/github.com/vbauerster/mpb/v7/decor/name.go b/vendor/github.com/vbauerster/mpb/v8/decor/name.go similarity index 98% rename from vendor/github.com/vbauerster/mpb/v7/decor/name.go rename to vendor/github.com/vbauerster/mpb/v8/decor/name.go index 3af3112545..31ac123b5b 100644 --- a/vendor/github.com/vbauerster/mpb/v7/decor/name.go +++ b/vendor/github.com/vbauerster/mpb/v8/decor/name.go @@ -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...) } diff --git a/vendor/github.com/vbauerster/mpb/v7/decor/on_abort.go b/vendor/github.com/vbauerster/mpb/v8/decor/on_abort.go similarity index 99% rename from vendor/github.com/vbauerster/mpb/v7/decor/on_abort.go rename to vendor/github.com/vbauerster/mpb/v8/decor/on_abort.go index 10ff67009c..f9a1197b52 100644 --- a/vendor/github.com/vbauerster/mpb/v7/decor/on_abort.go +++ b/vendor/github.com/vbauerster/mpb/v8/decor/on_abort.go @@ -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 diff --git a/vendor/github.com/vbauerster/mpb/v7/decor/on_complete.go b/vendor/github.com/vbauerster/mpb/v8/decor/on_complete.go similarity index 99% rename from vendor/github.com/vbauerster/mpb/v7/decor/on_complete.go rename to vendor/github.com/vbauerster/mpb/v8/decor/on_complete.go index 2ada2b31b1..663ec366de 100644 --- a/vendor/github.com/vbauerster/mpb/v7/decor/on_complete.go +++ b/vendor/github.com/vbauerster/mpb/v8/decor/on_complete.go @@ -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 diff --git a/vendor/github.com/vbauerster/mpb/v7/decor/on_condition.go b/vendor/github.com/vbauerster/mpb/v8/decor/on_condition.go similarity index 98% rename from vendor/github.com/vbauerster/mpb/v7/decor/on_condition.go rename to vendor/github.com/vbauerster/mpb/v8/decor/on_condition.go index 74a3d96676..f4626c33b5 100644 --- a/vendor/github.com/vbauerster/mpb/v7/decor/on_condition.go +++ b/vendor/github.com/vbauerster/mpb/v8/decor/on_condition.go @@ -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 diff --git a/vendor/github.com/vbauerster/mpb/v7/decor/percentage.go b/vendor/github.com/vbauerster/mpb/v8/decor/percentage.go similarity index 78% rename from vendor/github.com/vbauerster/mpb/v7/decor/percentage.go rename to vendor/github.com/vbauerster/mpb/v8/decor/percentage.go index e72668993e..8e0d832885 100644 --- a/vendor/github.com/vbauerster/mpb/v7/decor/percentage.go +++ b/vendor/github.com/vbauerster/mpb/v8/decor/percentage.go @@ -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" diff --git a/vendor/github.com/vbauerster/mpb/v8/decor/pool.go b/vendor/github.com/vbauerster/mpb/v8/decor/pool.go new file mode 100644 index 0000000000..c8b3cc69bd --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v8/decor/pool.go @@ -0,0 +1,10 @@ +package decor + +import "sync" + +var bytePool = sync.Pool{ + New: func() interface{} { + b := make([]byte, 0, 16) + return &b + }, +} diff --git a/vendor/github.com/vbauerster/mpb/v7/decor/size_type.go b/vendor/github.com/vbauerster/mpb/v8/decor/size_type.go similarity index 77% rename from vendor/github.com/vbauerster/mpb/v7/decor/size_type.go rename to vendor/github.com/vbauerster/mpb/v8/decor/size_type.go index 09ecc23f80..753c16014f 100644 --- a/vendor/github.com/vbauerster/mpb/v7/decor/size_type.go +++ b/vendor/github.com/vbauerster/mpb/v8/decor/size_type.go @@ -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) } diff --git a/vendor/github.com/vbauerster/mpb/v7/decor/sizeb1000_string.go b/vendor/github.com/vbauerster/mpb/v8/decor/sizeb1000_string.go similarity index 100% rename from vendor/github.com/vbauerster/mpb/v7/decor/sizeb1000_string.go rename to vendor/github.com/vbauerster/mpb/v8/decor/sizeb1000_string.go diff --git a/vendor/github.com/vbauerster/mpb/v7/decor/sizeb1024_string.go b/vendor/github.com/vbauerster/mpb/v8/decor/sizeb1024_string.go similarity index 100% rename from vendor/github.com/vbauerster/mpb/v7/decor/sizeb1024_string.go rename to vendor/github.com/vbauerster/mpb/v8/decor/sizeb1024_string.go diff --git a/vendor/github.com/vbauerster/mpb/v7/decor/speed.go b/vendor/github.com/vbauerster/mpb/v8/decor/speed.go similarity index 96% rename from vendor/github.com/vbauerster/mpb/v7/decor/speed.go rename to vendor/github.com/vbauerster/mpb/v8/decor/speed.go index f052352fc4..47d54dcca3 100644 --- a/vendor/github.com/vbauerster/mpb/v7/decor/speed.go +++ b/vendor/github.com/vbauerster/mpb/v8/decor/speed.go @@ -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" diff --git a/vendor/github.com/vbauerster/mpb/v7/decor/spinner.go b/vendor/github.com/vbauerster/mpb/v8/decor/spinner.go similarity index 100% rename from vendor/github.com/vbauerster/mpb/v7/decor/spinner.go rename to vendor/github.com/vbauerster/mpb/v8/decor/spinner.go diff --git a/vendor/github.com/vbauerster/mpb/v7/doc.go b/vendor/github.com/vbauerster/mpb/v8/doc.go similarity index 100% rename from vendor/github.com/vbauerster/mpb/v7/doc.go rename to vendor/github.com/vbauerster/mpb/v8/doc.go diff --git a/vendor/github.com/vbauerster/mpb/v7/internal/percentage.go b/vendor/github.com/vbauerster/mpb/v8/internal/percentage.go similarity index 100% rename from vendor/github.com/vbauerster/mpb/v7/internal/percentage.go rename to vendor/github.com/vbauerster/mpb/v8/internal/percentage.go diff --git a/vendor/github.com/vbauerster/mpb/v7/internal/width.go b/vendor/github.com/vbauerster/mpb/v8/internal/width.go similarity index 100% rename from vendor/github.com/vbauerster/mpb/v7/internal/width.go rename to vendor/github.com/vbauerster/mpb/v8/internal/width.go diff --git a/vendor/github.com/vbauerster/mpb/v7/priority_queue.go b/vendor/github.com/vbauerster/mpb/v8/priority_queue.go similarity index 100% rename from vendor/github.com/vbauerster/mpb/v7/priority_queue.go rename to vendor/github.com/vbauerster/mpb/v8/priority_queue.go diff --git a/vendor/github.com/vbauerster/mpb/v7/progress.go b/vendor/github.com/vbauerster/mpb/v8/progress.go similarity index 52% rename from vendor/github.com/vbauerster/mpb/v7/progress.go rename to vendor/github.com/vbauerster/mpb/v8/progress.go index 1dda06e5f0..c9b5cc8c5c 100644 --- a/vendor/github.com/vbauerster/mpb/v7/progress.go +++ b/vendor/github.com/vbauerster/mpb/v8/progress.go @@ -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() } diff --git a/vendor/github.com/vbauerster/mpb/v8/proxyreader.go b/vendor/github.com/vbauerster/mpb/v8/proxyreader.go new file mode 100644 index 0000000000..b0e7720b9e --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v8/proxyreader.go @@ -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) +} diff --git a/vendor/github.com/vbauerster/mpb/v8/proxywriter.go b/vendor/github.com/vbauerster/mpb/v8/proxywriter.go new file mode 100644 index 0000000000..f260dafa84 --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v8/proxywriter.go @@ -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) +} diff --git a/vendor/modules.txt b/vendor/modules.txt index f9d6e26e43..b018988bdf 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -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