Merge pull request #2100 from kolyshkin/cut
Use strings.Cut{,Prefix,Suffix} where appropriate
This commit is contained in:
commit
205caa7ccf
4
check.go
4
check.go
|
|
@ -1003,12 +1003,12 @@ func (c *checkDirectory) remove(path string) {
|
|||
func (c *checkDirectory) header(hdr *tar.Header) {
|
||||
name := path.Clean(hdr.Name)
|
||||
dir, base := path.Split(name)
|
||||
if strings.HasPrefix(base, archive.WhiteoutPrefix) {
|
||||
if file, ok := strings.CutPrefix(base, archive.WhiteoutPrefix); ok {
|
||||
if base == archive.WhiteoutOpaqueDir {
|
||||
c.remove(path.Clean(dir))
|
||||
c.add(path.Clean(dir), tar.TypeDir, hdr.Uid, hdr.Gid, hdr.Size, os.FileMode(hdr.Mode), hdr.ModTime.Unix())
|
||||
} else {
|
||||
c.remove(path.Join(dir, base[len(archive.WhiteoutPrefix):]))
|
||||
c.remove(path.Join(dir, file))
|
||||
}
|
||||
} else {
|
||||
if hdr.Typeflag == tar.TypeLink {
|
||||
|
|
|
|||
|
|
@ -22,36 +22,36 @@ func copyContent(flags *mflag.FlagSet, action string, m storage.Store, args []st
|
|||
return 1, nil
|
||||
}
|
||||
if len(chownOptions) > 0 {
|
||||
chownParts := strings.SplitN(chownOptions, ":", 2)
|
||||
if len(chownParts) == 1 {
|
||||
chownParts = append(chownParts, chownParts[0])
|
||||
uidStr, gidStr, ok := strings.Cut(chownOptions, ":")
|
||||
if !ok {
|
||||
gidStr = uidStr
|
||||
}
|
||||
uid, err := strconv.ParseUint(chownParts[0], 10, 32)
|
||||
uid, err := strconv.ParseUint(uidStr, 10, 32)
|
||||
if err != nil {
|
||||
return 1, fmt.Errorf("error %q as a numeric UID: %v", chownParts[0], err)
|
||||
return 1, fmt.Errorf("bad UID: %w", err)
|
||||
}
|
||||
gid, err := strconv.ParseUint(chownParts[1], 10, 32)
|
||||
gid, err := strconv.ParseUint(gidStr, 10, 32)
|
||||
if err != nil {
|
||||
return 1, fmt.Errorf("error %q as a numeric GID: %v", chownParts[1], err)
|
||||
return 1, fmt.Errorf("bad GID: %w", err)
|
||||
}
|
||||
chownOpts = &idtools.IDPair{UID: int(uid), GID: int(gid)}
|
||||
}
|
||||
target := args[len(args)-1]
|
||||
if strings.Contains(target, ":") {
|
||||
targetParts := strings.SplitN(target, ":", 2)
|
||||
if len(targetParts) != 2 {
|
||||
layer, targetRel, ok := strings.Cut(target, ":")
|
||||
if !ok {
|
||||
return 1, fmt.Errorf("error parsing target location %q: only one part", target)
|
||||
}
|
||||
targetLayer, err := m.Layer(targetParts[0])
|
||||
targetLayer, err := m.Layer(layer)
|
||||
if err != nil {
|
||||
return 1, fmt.Errorf("error finding layer %q: %+v", targetParts[0], err)
|
||||
return 1, fmt.Errorf("error finding layer %q: %+v", layer, err)
|
||||
}
|
||||
untarIDMappings = idtools.NewIDMappingsFromMaps(targetLayer.UIDMap, targetLayer.GIDMap)
|
||||
targetMount, err := m.Mount(targetLayer.ID, targetLayer.MountLabel)
|
||||
if err != nil {
|
||||
return 1, fmt.Errorf("error mounting layer %q: %+v", targetLayer.ID, err)
|
||||
}
|
||||
target = filepath.Join(targetMount, targetParts[1])
|
||||
target = filepath.Join(targetMount, targetRel)
|
||||
defer func() {
|
||||
if _, err := m.Unmount(targetLayer.ID, false); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error unmounting layer %q: %+v\n", targetLayer.ID, err)
|
||||
|
|
@ -63,21 +63,17 @@ func copyContent(flags *mflag.FlagSet, action string, m storage.Store, args []st
|
|||
for _, srcSpec := range args {
|
||||
var tarIDMappings *idtools.IDMappings
|
||||
source := srcSpec
|
||||
if strings.Contains(source, ":") {
|
||||
sourceParts := strings.SplitN(source, ":", 2)
|
||||
if len(sourceParts) != 2 {
|
||||
return 1, fmt.Errorf("error parsing source location %q: only one part", source)
|
||||
}
|
||||
sourceLayer, err := m.Layer(sourceParts[0])
|
||||
if layer, sourceRel, ok := strings.Cut(source, ":"); ok {
|
||||
sourceLayer, err := m.Layer(layer)
|
||||
if err != nil {
|
||||
return 1, fmt.Errorf("error finding layer %q: %+v", sourceParts[0], err)
|
||||
return 1, fmt.Errorf("error finding layer %q: %+v", layer, err)
|
||||
}
|
||||
tarIDMappings = idtools.NewIDMappingsFromMaps(sourceLayer.UIDMap, sourceLayer.GIDMap)
|
||||
sourceMount, err := m.Mount(sourceLayer.ID, sourceLayer.MountLabel)
|
||||
if err != nil {
|
||||
return 1, fmt.Errorf("error mounting layer %q: %+v", sourceLayer.ID, err)
|
||||
}
|
||||
source = filepath.Join(sourceMount, sourceParts[1])
|
||||
source = filepath.Join(sourceMount, sourceRel)
|
||||
defer func() {
|
||||
if _, err := m.Unmount(sourceLayer.ID, false); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error unmounting layer %q: %+v\n", sourceLayer.ID, err)
|
||||
|
|
|
|||
|
|
@ -103,20 +103,20 @@ func mountOverlayFromMain() {
|
|||
// paths, but we don't want to mess with other options.
|
||||
var upperk, upperv, workk, workv, lowerk, lowerv, labelk, labelv, others string
|
||||
for _, arg := range strings.Split(options.Label, ",") {
|
||||
kv := strings.SplitN(arg, "=", 2)
|
||||
switch kv[0] {
|
||||
key, val, _ := strings.Cut(arg, "=")
|
||||
switch key {
|
||||
case "upperdir":
|
||||
upperk = "upperdir="
|
||||
upperv = kv[1]
|
||||
upperv = val
|
||||
case "workdir":
|
||||
workk = "workdir="
|
||||
workv = kv[1]
|
||||
workv = val
|
||||
case "lowerdir":
|
||||
lowerk = "lowerdir="
|
||||
lowerv = kv[1]
|
||||
lowerv = val
|
||||
case "label":
|
||||
labelk = "label="
|
||||
labelv = kv[1]
|
||||
labelv = val
|
||||
default:
|
||||
if others == "" {
|
||||
others = arg
|
||||
|
|
|
|||
|
|
@ -764,8 +764,8 @@ func writeLayerFromTar(r io.Reader, w hcsshim.LayerWriter, root string) (int64,
|
|||
buf := bufio.NewWriter(nil)
|
||||
for err == nil {
|
||||
base := path.Base(hdr.Name)
|
||||
if strings.HasPrefix(base, archive.WhiteoutPrefix) {
|
||||
name := path.Join(path.Dir(hdr.Name), base[len(archive.WhiteoutPrefix):])
|
||||
if rm, ok := strings.CutPrefix(base, archive.WhiteoutPrefix); ok {
|
||||
name := path.Join(path.Dir(hdr.Name), rm)
|
||||
err = w.Remove(filepath.FromSlash(name))
|
||||
if err != nil {
|
||||
return 0, err
|
||||
|
|
|
|||
|
|
@ -144,12 +144,8 @@ func (opts *MapOpts) Set(value string) error {
|
|||
}
|
||||
value = v
|
||||
}
|
||||
vals := strings.SplitN(value, "=", 2)
|
||||
if len(vals) == 1 {
|
||||
(opts.values)[vals[0]] = ""
|
||||
} else {
|
||||
(opts.values)[vals[0]] = vals[1]
|
||||
}
|
||||
key, val, _ := strings.Cut(value, "=")
|
||||
opts.values[key] = val
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -46,14 +46,13 @@ func ParseFlag(arg string, prev Args) (Args, error) {
|
|||
return filters, nil
|
||||
}
|
||||
|
||||
if !strings.Contains(arg, "=") {
|
||||
name, value, ok := strings.Cut(arg, "=")
|
||||
if !ok {
|
||||
return filters, ErrBadFormat
|
||||
}
|
||||
|
||||
f := strings.SplitN(arg, "=", 2)
|
||||
|
||||
name := strings.ToLower(strings.TrimSpace(f[0]))
|
||||
value := strings.TrimSpace(f[1])
|
||||
name = strings.ToLower(strings.TrimSpace(name))
|
||||
value = strings.TrimSpace(value)
|
||||
|
||||
filters.Add(name, value)
|
||||
|
||||
|
|
@ -140,14 +139,14 @@ func (args Args) MatchKVList(key string, sources map[string]string) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
for value := range fieldValues {
|
||||
testKV := strings.SplitN(value, "=", 2)
|
||||
for field := range fieldValues {
|
||||
key, val, gotVal := strings.Cut(field, "=")
|
||||
|
||||
v, ok := sources[testKV[0]]
|
||||
v, ok := sources[key]
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
if len(testKV) == 2 && testKV[1] != v {
|
||||
if gotVal && val != v {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -124,8 +124,7 @@ func (overlayWhiteoutConverter) ConvertReadWithHandler(hdr *tar.Header, path str
|
|||
}
|
||||
|
||||
// if a file was deleted and we are using overlay, we need to create a character device
|
||||
if strings.HasPrefix(base, WhiteoutPrefix) {
|
||||
originalBase := base[len(WhiteoutPrefix):]
|
||||
if originalBase, ok := strings.CutPrefix(base, WhiteoutPrefix); ok {
|
||||
originalPath := filepath.Join(dir, originalBase)
|
||||
|
||||
if err := handler.Mknod(originalPath, unix.S_IFCHR, 0); err != nil {
|
||||
|
|
|
|||
|
|
@ -98,8 +98,7 @@ func aufsDeletedFile(root, path string, fi os.FileInfo) (string, error) {
|
|||
f := filepath.Base(path)
|
||||
|
||||
// If there is a whiteout, then the file was removed
|
||||
if strings.HasPrefix(f, WhiteoutPrefix) {
|
||||
originalFile := f[len(WhiteoutPrefix):]
|
||||
if originalFile, ok := strings.CutPrefix(f, WhiteoutPrefix); ok {
|
||||
return filepath.Join(filepath.Dir(path), originalFile), nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -80,9 +80,9 @@ func parseFileFlags(fflags string) (uint32, uint32, error) {
|
|||
var set, clear uint32 = 0, 0
|
||||
for _, fflag := range strings.Split(fflags, ",") {
|
||||
isClear := false
|
||||
if strings.HasPrefix(fflag, "no") {
|
||||
if clean, ok := strings.CutPrefix(fflag, "no"); ok {
|
||||
isClear = true
|
||||
fflag = strings.TrimPrefix(fflag, "no")
|
||||
fflag = clean
|
||||
}
|
||||
if value, ok := flagNameToValue[fflag]; ok {
|
||||
if isClear {
|
||||
|
|
|
|||
|
|
@ -554,8 +554,10 @@ func (fs *FlagSet) PrintDefaults() {
|
|||
if len(names) > 0 && len(flag.Usage) > 0 {
|
||||
val := flag.DefValue
|
||||
|
||||
if home != "" && strings.HasPrefix(val, home) {
|
||||
val = homedir.GetShortcutString() + val[len(home):]
|
||||
if home != "" {
|
||||
if relhome, ok := strings.CutPrefix(val, home); ok {
|
||||
val = homedir.GetShortcutString() + relhome
|
||||
}
|
||||
}
|
||||
|
||||
if isZeroValue(val) {
|
||||
|
|
|
|||
|
|
@ -97,14 +97,14 @@ func MergeTmpfsOptions(options []string) ([]string, error) {
|
|||
}
|
||||
continue
|
||||
}
|
||||
opt := strings.SplitN(option, "=", 2)
|
||||
if len(opt) != 2 || !validFlags[opt[0]] {
|
||||
opt, _, ok := strings.Cut(option, "=")
|
||||
if !ok || !validFlags[opt] {
|
||||
return nil, fmt.Errorf("invalid tmpfs option %q", opt)
|
||||
}
|
||||
if !dataCollisions[opt[0]] {
|
||||
if !dataCollisions[opt] {
|
||||
// We prepend the option and add to collision map
|
||||
newOptions = append([]string{option}, newOptions...)
|
||||
dataCollisions[opt[0]] = true
|
||||
dataCollisions[opt] = true
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -140,8 +140,8 @@ func ParseOptions(options string) (int, string) {
|
|||
func ParseTmpfsOptions(options string) (int, string, error) {
|
||||
flags, data := ParseOptions(options)
|
||||
for _, o := range strings.Split(data, ",") {
|
||||
opt := strings.SplitN(o, "=", 2)
|
||||
if !validFlags[opt[0]] {
|
||||
opt, _, _ := strings.Cut(o, "=")
|
||||
if !validFlags[opt] {
|
||||
return 0, "", fmt.Errorf("invalid tmpfs option %q", opt)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,13 +40,9 @@ func mount(device, target, mType string, flag uintptr, data string) error {
|
|||
isNullFS = true
|
||||
continue
|
||||
}
|
||||
opt := strings.SplitN(x, "=", 2)
|
||||
options = append(options, opt[0])
|
||||
if len(opt) == 2 {
|
||||
options = append(options, opt[1])
|
||||
} else {
|
||||
options = append(options, "")
|
||||
}
|
||||
name, val, _ := strings.Cut(x, "=")
|
||||
options = append(options, name)
|
||||
options = append(options, val)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -209,7 +209,8 @@ func validateMount(t *testing.T, mnt string, opts, optional, vfs string) {
|
|||
|
||||
// clean strips off any value param after the colon
|
||||
func clean(v string) string {
|
||||
return strings.SplitN(v, ":", 2)[0]
|
||||
ret, _, _ := strings.Cut(v, ":")
|
||||
return ret
|
||||
}
|
||||
|
||||
// has returns true if key is a member of m
|
||||
|
|
|
|||
|
|
@ -36,12 +36,12 @@ func getRelease() (string, error) {
|
|||
for _, line := range data {
|
||||
if strings.Contains(line, "Kernel Version") {
|
||||
// It has the format like ' Kernel Version: Darwin 14.5.0'
|
||||
content := strings.SplitN(line, ":", 2)
|
||||
if len(content) != 2 {
|
||||
_, val, ok := strings.Cut(line, ":")
|
||||
if !ok {
|
||||
return "", fmt.Errorf("kernel version is invalid")
|
||||
}
|
||||
|
||||
prettyNames, err := shellwords.Parse(content[1])
|
||||
prettyNames, err := shellwords.Parse(val)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("kernel version is invalid: %w", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,14 +41,13 @@ func GetOperatingSystem() (string, error) {
|
|||
scanner := bufio.NewScanner(osReleaseFile)
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
if strings.HasPrefix(line, "PRETTY_NAME=") {
|
||||
data := strings.SplitN(line, "=", 2)
|
||||
prettyNames, err := shellwords.Parse(data[1])
|
||||
if name, ok := strings.CutPrefix(line, "PRETTY_NAME="); ok {
|
||||
prettyNames, err := shellwords.Parse(name)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("PRETTY_NAME is invalid: %s", err.Error())
|
||||
}
|
||||
if len(prettyNames) != 1 {
|
||||
return "", fmt.Errorf("PRETTY_NAME needs to be enclosed by quotes if they have spaces: %s", data[1])
|
||||
return "", fmt.Errorf("PRETTY_NAME needs to be enclosed by quotes if they have spaces: %s", name)
|
||||
}
|
||||
prettyName = prettyNames[0]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,11 +11,11 @@ import (
|
|||
|
||||
// ParseKeyValueOpt parses and validates the specified string as a key/value pair (key=value)
|
||||
func ParseKeyValueOpt(opt string) (string, string, error) {
|
||||
parts := strings.SplitN(opt, "=", 2)
|
||||
if len(parts) != 2 {
|
||||
k, v, ok := strings.Cut(opt, "=")
|
||||
if !ok {
|
||||
return "", "", fmt.Errorf("unable to parse key/value option: %s", opt)
|
||||
}
|
||||
return strings.TrimSpace(parts[0]), strings.TrimSpace(parts[1]), nil
|
||||
return strings.TrimSpace(k), strings.TrimSpace(v), nil
|
||||
}
|
||||
|
||||
// ParseUintList parses and validates the specified string as the value
|
||||
|
|
@ -42,19 +42,19 @@ func ParseUintList(val string) (map[int]bool, error) {
|
|||
errInvalidFormat := fmt.Errorf("invalid format: %s", val)
|
||||
|
||||
for _, r := range split {
|
||||
if !strings.Contains(r, "-") {
|
||||
minS, maxS, ok := strings.Cut(r, "-")
|
||||
if !ok {
|
||||
v, err := strconv.Atoi(r)
|
||||
if err != nil {
|
||||
return nil, errInvalidFormat
|
||||
}
|
||||
availableInts[v] = true
|
||||
} else {
|
||||
split := strings.SplitN(r, "-", 2)
|
||||
min, err := strconv.Atoi(split[0])
|
||||
min, err := strconv.Atoi(minS)
|
||||
if err != nil {
|
||||
return nil, errInvalidFormat
|
||||
}
|
||||
max, err := strconv.Atoi(split[1])
|
||||
max, err := strconv.Atoi(maxS)
|
||||
if err != nil {
|
||||
return nil, errInvalidFormat
|
||||
}
|
||||
|
|
|
|||
|
|
@ -344,8 +344,8 @@ func getRootlessStorageOpts(systemOpts StoreOptions) (StoreOptions, error) {
|
|||
dirEntries, err := os.ReadDir(opts.GraphRoot)
|
||||
if err == nil {
|
||||
for _, entry := range dirEntries {
|
||||
if strings.HasSuffix(entry.Name(), "-images") {
|
||||
opts.GraphDriverName = strings.TrimSuffix(entry.Name(), "-images")
|
||||
if name, ok := strings.CutSuffix(entry.Name(), "-images"); ok {
|
||||
opts.GraphDriverName = name
|
||||
break
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue