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  }