...

Source file src/sigs.k8s.io/kustomize/kyaml/filesys/util.go

Documentation: sigs.k8s.io/kustomize/kyaml/filesys

     1  // Copyright 2019 The Kubernetes Authors.
     2  // SPDX-License-Identifier: Apache-2.0
     3  
     4  package filesys
     5  
     6  import (
     7  	"os"
     8  	"path/filepath"
     9  	"strings"
    10  )
    11  
    12  // RootedPath returns a rooted path, e.g. "/foo/bar" as
    13  // opposed to "foo/bar".
    14  func RootedPath(elem ...string) string {
    15  	return Separator + filepath.Join(elem...)
    16  }
    17  
    18  // StripTrailingSeps trims trailing filepath separators from input.
    19  func StripTrailingSeps(s string) string {
    20  	k := len(s)
    21  	for k > 0 && s[k-1] == filepath.Separator {
    22  		k--
    23  	}
    24  	return s[:k]
    25  }
    26  
    27  // StripLeadingSeps trims leading filepath separators from input.
    28  func StripLeadingSeps(s string) string {
    29  	k := 0
    30  	for k < len(s) && s[k] == filepath.Separator {
    31  		k++
    32  	}
    33  	return s[k:]
    34  }
    35  
    36  // PathSplit converts a file path to a slice of string.
    37  // If the path is absolute (if the path has a leading slash),
    38  // then the first entry in the result is an empty string.
    39  // Desired:  path == PathJoin(PathSplit(path))
    40  func PathSplit(incoming string) []string {
    41  	if incoming == "" {
    42  		return []string{}
    43  	}
    44  	dir, path := filepath.Split(incoming)
    45  	if dir == string(os.PathSeparator) {
    46  		if path == "" {
    47  			return []string{""}
    48  		}
    49  		return []string{"", path}
    50  	}
    51  	dir = strings.TrimSuffix(dir, string(os.PathSeparator))
    52  	if dir == "" {
    53  		return []string{path}
    54  	}
    55  	return append(PathSplit(dir), path)
    56  }
    57  
    58  // PathJoin converts a slice of string to a file path.
    59  // If the first entry is an empty string, then the returned
    60  // path is absolute (it has a leading slash).
    61  // Desired:  path == PathJoin(PathSplit(path))
    62  func PathJoin(incoming []string) string {
    63  	if len(incoming) == 0 {
    64  		return ""
    65  	}
    66  	if incoming[0] == "" {
    67  		return string(os.PathSeparator) + filepath.Join(incoming[1:]...)
    68  	}
    69  	return filepath.Join(incoming...)
    70  }
    71  
    72  // InsertPathPart inserts 'part' at position 'pos' in the given filepath.
    73  // The first position is 0.
    74  //
    75  // E.g. if part == 'PEACH'
    76  //
    77  //	             OLD : NEW                    : POS
    78  //	 --------------------------------------------------------
    79  //	         {empty} : PEACH                  : irrelevant
    80  //	               / : /PEACH                 : irrelevant
    81  //	             pie : PEACH/pie              : 0 (or negative)
    82  //	            /pie : /PEACH/pie             : 0 (or negative)
    83  //	             raw : raw/PEACH              : 1 (or larger)
    84  //	            /raw : /raw/PEACH             : 1 (or larger)
    85  //	 a/nice/warm/pie : a/nice/warm/PEACH/pie  : 3
    86  //	/a/nice/warm/pie : /a/nice/warm/PEACH/pie : 3
    87  //
    88  // * An empty part results in no change.
    89  //
    90  //   - Absolute paths get their leading '/' stripped, treated like
    91  //     relative paths, and the leading '/' is re-added on output.
    92  //     The meaning of pos is intentionally the same in either absolute or
    93  //     relative paths; if it weren't, this function could convert absolute
    94  //     paths to relative paths, which is not desirable.
    95  //
    96  //   - For robustness (liberal input, conservative output) Pos values
    97  //     that are too small (large) to index the split filepath result in a
    98  //     prefix (postfix) rather than an error.  Use extreme position values
    99  //     to assure a prefix or postfix (e.g. 0 will always prefix, and
   100  //     9999 will presumably always postfix).
   101  func InsertPathPart(path string, pos int, part string) string {
   102  	if part == "" {
   103  		return path
   104  	}
   105  	parts := PathSplit(path)
   106  	if pos < 0 {
   107  		pos = 0
   108  	} else if pos > len(parts) {
   109  		pos = len(parts)
   110  	}
   111  	if len(parts) > 0 && parts[0] == "" && pos < len(parts) {
   112  		// An empty string at 0 indicates an absolute path, and means
   113  		// we must increment pos.  This change means that a position
   114  		// specification has the same meaning in relative and absolute paths.
   115  		// E.g. in either the path 'a/b/c' or the path '/a/b/c',
   116  		// 'a' is at 0, 'b' is at 1 and 'c' is at 2, and inserting at
   117  		// zero means a new first field _without_ changing an absolute
   118  		// path to a relative path.
   119  		pos++
   120  	}
   121  	result := make([]string, len(parts)+1)
   122  	copy(result, parts[0:pos])
   123  	result[pos] = part
   124  	return PathJoin(append(result, parts[pos:]...)) //nolint: makezero
   125  }
   126  
   127  func IsHiddenFilePath(pattern string) bool {
   128  	return strings.HasPrefix(filepath.Base(pattern), ".")
   129  }
   130  
   131  // Removes paths containing hidden files/folders from a list of paths
   132  func RemoveHiddenFiles(paths []string) []string {
   133  	if len(paths) == 0 {
   134  		return paths
   135  	}
   136  	var result []string
   137  	for _, path := range paths {
   138  		if !IsHiddenFilePath(path) {
   139  			result = append(result, path)
   140  		}
   141  	}
   142  	return result
   143  }
   144  

View as plain text