github.com/cobalt77/jfrog-client-go@v0.14.5/artifactory/services/fspatterns/utils.go (about) 1 package fspatterns 2 3 import ( 4 "bytes" 5 "errors" 6 "fmt" 7 "os" 8 "regexp" 9 "strings" 10 11 serviceutils "github.com/cobalt77/jfrog-client-go/artifactory/services/utils" 12 "github.com/cobalt77/jfrog-client-go/utils" 13 clientutils "github.com/cobalt77/jfrog-client-go/utils" 14 "github.com/cobalt77/jfrog-client-go/utils/errorutils" 15 "github.com/cobalt77/jfrog-client-go/utils/io/fileutils" 16 "github.com/cobalt77/jfrog-client-go/utils/io/fileutils/checksum" 17 ) 18 19 // Return all the existing paths of the provided root path 20 func GetPaths(rootPath string, isRecursive, includeDirs, isSymlink bool) ([]string, error) { 21 var paths []string 22 var err error 23 if isRecursive { 24 paths, err = fileutils.ListFilesRecursiveWalkIntoDirSymlink(rootPath, !isSymlink) 25 } else { 26 paths, err = fileutils.ListFiles(rootPath, includeDirs) 27 } 28 if err != nil { 29 return paths, err 30 } 31 return paths, nil 32 } 33 34 // Transform to regexp and prepare Exclude patterns to be used 35 func PrepareExcludePathPattern(params serviceutils.FileGetter) string { 36 exclusions := params.GetExclusions() 37 if len(exclusions) == 0 { 38 // Support legacy exclude patterns. 'Exclude patterns' are deprecated and replaced by 'exclusions'. 39 exclusions = params.GetExcludePatterns() 40 } 41 42 excludePathPattern := "" 43 if len(exclusions) > 0 { 44 for _, singleExcludePattern := range exclusions { 45 if len(singleExcludePattern) > 0 { 46 singleExcludePattern = utils.ReplaceTildeWithUserHome(singleExcludePattern) 47 singleExcludePattern = utils.PrepareLocalPathForUpload(singleExcludePattern, params.IsRegexp()) 48 if params.IsRecursive() && strings.HasSuffix(singleExcludePattern, fileutils.GetFileSeparator()) { 49 singleExcludePattern += "*" 50 } 51 excludePathPattern += fmt.Sprintf(`(%s)|`, singleExcludePattern) 52 } 53 } 54 if len(excludePathPattern) > 0 { 55 excludePathPattern = excludePathPattern[:len(excludePathPattern)-1] 56 } 57 } 58 return excludePathPattern 59 } 60 61 // Return only subpaths of the provided by the user path that matched to the provided regexp. 62 // Subpaths that matched to an exclude pattern won't returned 63 func PrepareAndFilterPaths(path, excludePathPattern string, preserveSymlinks, includeDirs bool, regexp *regexp.Regexp) (matches []string, isDir, isSymlinkFlow bool, err error) { 64 isDir, err = fileutils.IsDirExists(path, false) 65 if err != nil { 66 return 67 } 68 69 excludedPath, err := IsPathExcluded(path, excludePathPattern) 70 if err != nil { 71 return 72 } 73 74 if excludedPath { 75 return 76 } 77 isSymlinkFlow = preserveSymlinks && fileutils.IsPathSymlink(path) 78 79 if isDir && !includeDirs && !isSymlinkFlow { 80 return 81 } 82 matches = regexp.FindStringSubmatch(path) 83 return 84 } 85 86 func GetSingleFileToUpload(rootPath, targetPath string, flat, preserveSymLink bool) (utils.Artifact, error) { 87 symlinkPath, err := GetFileSymlinkPath(rootPath) 88 if err != nil { 89 return utils.Artifact{}, err 90 } 91 92 var uploadPath string 93 if !strings.HasSuffix(targetPath, "/") { 94 uploadPath = targetPath 95 } else { 96 // If not preserving symlinks and symlink target is valid, use symlink target for upload 97 if !preserveSymLink && symlinkPath != "" { 98 rootPath = symlinkPath 99 } 100 if flat { 101 uploadPath, _ = fileutils.GetFileAndDirFromPath(rootPath) 102 uploadPath = targetPath + uploadPath 103 } else { 104 uploadPath = targetPath + rootPath 105 uploadPath = utils.TrimPath(uploadPath) 106 } 107 } 108 109 return utils.Artifact{LocalPath: rootPath, TargetPath: uploadPath, Symlink: symlinkPath}, nil 110 } 111 112 func IsPathExcluded(path string, excludePathPattern string) (excludedPath bool, err error) { 113 if len(excludePathPattern) > 0 { 114 excludedPath, err = regexp.MatchString(excludePathPattern, path) 115 } 116 return 117 } 118 119 // If filePath is path to a symlink we should return the link content e.g where the link points 120 func GetFileSymlinkPath(filePath string) (string, error) { 121 fileInfo, e := os.Lstat(filePath) 122 if errorutils.CheckError(e) != nil { 123 return "", e 124 } 125 var symlinkPath = "" 126 if fileutils.IsFileSymlink(fileInfo) { 127 symlinkPath, e = os.Readlink(filePath) 128 if errorutils.CheckError(e) != nil { 129 return "", e 130 } 131 } 132 return symlinkPath, nil 133 } 134 135 // Get the local root path, from which to start collecting artifacts to be uploaded to Artifactory. 136 // If path dose not exist error will be returned. 137 func GetRootPath(pattern, target string, isRegexp, preserveSymLink bool) (string, error) { 138 placeholderParentheses := clientutils.NewParenthesesSlice(pattern, target) 139 rootPath := utils.GetRootPath(pattern, isRegexp, placeholderParentheses) 140 if !fileutils.IsPathExists(rootPath, preserveSymLink) { 141 return "", errorutils.CheckError(errors.New("Path does not exist: " + rootPath)) 142 } 143 144 return rootPath, nil 145 } 146 147 // When handling symlink we want to simulate the creation of empty file 148 func CreateSymlinkFileDetails() (*fileutils.FileDetails, error) { 149 checksumInfo, err := checksum.Calc(bytes.NewBuffer([]byte(fileutils.SYMLINK_FILE_CONTENT))) 150 if err != nil { 151 return nil, err 152 } 153 154 details := new(fileutils.FileDetails) 155 details.Checksum.Md5 = checksumInfo[checksum.MD5] 156 details.Checksum.Sha1 = checksumInfo[checksum.SHA1] 157 details.Checksum.Sha256 = checksumInfo[checksum.SHA256] 158 details.Size = int64(0) 159 return details, nil 160 }