bump docker/go-units v0.3.3

relevant changes:

  - docker/go-units#8 Enhance FromHumanSize to parse float64 string
  - docker/go-units#20 Add `HumanSizeWithPrecision` function

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn 2019-03-28 14:09:19 +01:00
parent 0fc0662338
commit 8e4f645fca
No known key found for this signature in database
GPG Key ID: 76698F39D527CE8C
5 changed files with 157 additions and 19 deletions

View File

@ -19,7 +19,7 @@ github.com/golang/protobuf 18c9bb3261723cd5401db4d0c9fbc5c3b6c70fe8
# Command-line interface.
github.com/cyphar/filepath-securejoin a261ee33d7a517f054effbf451841abaafe3e0fd # v0.2.2
github.com/docker/go-units 9b001659dd36225e356b4467c465d732e745f53d # v0.2.0
github.com/docker/go-units 47565b4f722fb6ceae66b95f853feed578a4a51c # v0.3.3
github.com/urfave/cli d53eb991652b1d438abdd34ce4bfa3ef1539108e
golang.org/x/sys 9eafafc0a87e0fd0aeeba439a4573537970c44c7 https://github.com/golang/sys

View File

@ -1,3 +1,5 @@
[![GoDoc](https://godoc.org/github.com/docker/go-units?status.svg)](https://godoc.org/github.com/docker/go-units)
# Introduction
go-units is a library to transform human friendly measurements into machine friendly values.
@ -6,6 +8,9 @@ go-units is a library to transform human friendly measurements into machine frie
See the [docs in godoc](https://godoc.org/github.com/docker/go-units) for examples and documentation.
## License
## Copyright and license
go-units is licensed under the Apache License, Version 2.0. See [LICENSE](LICENSE) for the full license text.
Copyright © 2015 Docker, Inc.
go-units is licensed under the Apache License, Version 2.0.
See [LICENSE](LICENSE) for the full text of the license.

View File

@ -12,19 +12,21 @@ import (
func HumanDuration(d time.Duration) string {
if seconds := int(d.Seconds()); seconds < 1 {
return "Less than a second"
} else if seconds == 1 {
return "1 second"
} else if seconds < 60 {
return fmt.Sprintf("%d seconds", seconds)
} else if minutes := int(d.Minutes()); minutes == 1 {
return "About a minute"
} else if minutes < 60 {
} else if minutes < 46 {
return fmt.Sprintf("%d minutes", minutes)
} else if hours := int(d.Hours()); hours == 1 {
} else if hours := int(d.Hours() + 0.5); hours == 1 {
return "About an hour"
} else if hours < 48 {
return fmt.Sprintf("%d hours", hours)
} else if hours < 24*7*2 {
return fmt.Sprintf("%d days", hours/24)
} else if hours < 24*30*3 {
} else if hours < 24*30*2 {
return fmt.Sprintf("%d weeks", hours/24/7)
} else if hours < 24*365*2 {
return fmt.Sprintf("%d months", hours/24/30)

View File

@ -31,33 +31,46 @@ type unitMap map[string]int64
var (
decimalMap = unitMap{"k": KB, "m": MB, "g": GB, "t": TB, "p": PB}
binaryMap = unitMap{"k": KiB, "m": MiB, "g": GiB, "t": TiB, "p": PiB}
sizeRegex = regexp.MustCompile(`^(\d+)([kKmMgGtTpP])?[bB]?$`)
sizeRegex = regexp.MustCompile(`^(\d+(\.\d+)*) ?([kKmMgGtTpP])?[iI]?[bB]?$`)
)
var decimapAbbrs = []string{"B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"}
var binaryAbbrs = []string{"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"}
// CustomSize returns a human-readable approximation of a size
// using custom format.
func CustomSize(format string, size float64, base float64, _map []string) string {
func getSizeAndUnit(size float64, base float64, _map []string) (float64, string) {
i := 0
for size >= base {
unitsLimit := len(_map) - 1
for size >= base && i < unitsLimit {
size = size / base
i++
}
return fmt.Sprintf(format, size, _map[i])
return size, _map[i]
}
// CustomSize returns a human-readable approximation of a size
// using custom format.
func CustomSize(format string, size float64, base float64, _map []string) string {
size, unit := getSizeAndUnit(size, base, _map)
return fmt.Sprintf(format, size, unit)
}
// HumanSizeWithPrecision allows the size to be in any precision,
// instead of 4 digit precision used in units.HumanSize.
func HumanSizeWithPrecision(size float64, precision int) string {
size, unit := getSizeAndUnit(size, 1000.0, decimapAbbrs)
return fmt.Sprintf("%.*g%s", precision, size, unit)
}
// HumanSize returns a human-readable approximation of a size
// capped at 4 valid numbers (eg. "2.746 MB", "796 KB").
func HumanSize(size float64) string {
return CustomSize("%.4g %s", size, 1000.0, decimapAbbrs)
return HumanSizeWithPrecision(size, 4)
}
// BytesSize returns a human-readable size in bytes, kibibytes,
// mebibytes, gibibytes, or tebibytes (eg. "44kiB", "17MiB").
func BytesSize(size float64) string {
return CustomSize("%.4g %s", size, 1024.0, binaryAbbrs)
return CustomSize("%.4g%s", size, 1024.0, binaryAbbrs)
}
// FromHumanSize returns an integer from a human-readable specification of a
@ -77,19 +90,19 @@ func RAMInBytes(size string) (int64, error) {
// Parses the human-readable size string into the amount it represents.
func parseSize(sizeStr string, uMap unitMap) (int64, error) {
matches := sizeRegex.FindStringSubmatch(sizeStr)
if len(matches) != 3 {
if len(matches) != 4 {
return -1, fmt.Errorf("invalid size: '%s'", sizeStr)
}
size, err := strconv.ParseInt(matches[1], 10, 0)
size, err := strconv.ParseFloat(matches[1], 64)
if err != nil {
return -1, err
}
unitPrefix := strings.ToLower(matches[2])
unitPrefix := strings.ToLower(matches[3])
if mul, ok := uMap[unitPrefix]; ok {
size *= mul
size *= float64(mul)
}
return size, nil
return int64(size), nil
}

118
vendor/github.com/docker/go-units/ulimit.go generated vendored Normal file
View File

@ -0,0 +1,118 @@
package units
import (
"fmt"
"strconv"
"strings"
)
// Ulimit is a human friendly version of Rlimit.
type Ulimit struct {
Name string
Hard int64
Soft int64
}
// Rlimit specifies the resource limits, such as max open files.
type Rlimit struct {
Type int `json:"type,omitempty"`
Hard uint64 `json:"hard,omitempty"`
Soft uint64 `json:"soft,omitempty"`
}
const (
// magic numbers for making the syscall
// some of these are defined in the syscall package, but not all.
// Also since Windows client doesn't get access to the syscall package, need to
// define these here
rlimitAs = 9
rlimitCore = 4
rlimitCPU = 0
rlimitData = 2
rlimitFsize = 1
rlimitLocks = 10
rlimitMemlock = 8
rlimitMsgqueue = 12
rlimitNice = 13
rlimitNofile = 7
rlimitNproc = 6
rlimitRss = 5
rlimitRtprio = 14
rlimitRttime = 15
rlimitSigpending = 11
rlimitStack = 3
)
var ulimitNameMapping = map[string]int{
//"as": rlimitAs, // Disabled since this doesn't seem usable with the way Docker inits a container.
"core": rlimitCore,
"cpu": rlimitCPU,
"data": rlimitData,
"fsize": rlimitFsize,
"locks": rlimitLocks,
"memlock": rlimitMemlock,
"msgqueue": rlimitMsgqueue,
"nice": rlimitNice,
"nofile": rlimitNofile,
"nproc": rlimitNproc,
"rss": rlimitRss,
"rtprio": rlimitRtprio,
"rttime": rlimitRttime,
"sigpending": rlimitSigpending,
"stack": rlimitStack,
}
// ParseUlimit parses and returns a Ulimit from the specified string.
func ParseUlimit(val string) (*Ulimit, error) {
parts := strings.SplitN(val, "=", 2)
if len(parts) != 2 {
return nil, fmt.Errorf("invalid ulimit argument: %s", val)
}
if _, exists := ulimitNameMapping[parts[0]]; !exists {
return nil, fmt.Errorf("invalid ulimit type: %s", parts[0])
}
var (
soft int64
hard = &soft // default to soft in case no hard was set
temp int64
err error
)
switch limitVals := strings.Split(parts[1], ":"); len(limitVals) {
case 2:
temp, err = strconv.ParseInt(limitVals[1], 10, 64)
if err != nil {
return nil, err
}
hard = &temp
fallthrough
case 1:
soft, err = strconv.ParseInt(limitVals[0], 10, 64)
if err != nil {
return nil, err
}
default:
return nil, fmt.Errorf("too many limit value arguments - %s, can only have up to two, `soft[:hard]`", parts[1])
}
if soft > *hard {
return nil, fmt.Errorf("ulimit soft limit must be less than or equal to hard limit: %d > %d", soft, *hard)
}
return &Ulimit{Name: parts[0], Soft: soft, Hard: *hard}, nil
}
// GetRlimit returns the RLimit corresponding to Ulimit.
func (u *Ulimit) GetRlimit() (*Rlimit, error) {
t, exists := ulimitNameMapping[u.Name]
if !exists {
return nil, fmt.Errorf("invalid ulimit name %s", u.Name)
}
return &Rlimit{Type: t, Soft: uint64(u.Soft), Hard: uint64(u.Hard)}, nil
}
func (u *Ulimit) String() string {
return fmt.Sprintf("%s=%d:%d", u.Name, u.Soft, u.Hard)
}