github.com/jfrog/jfrog-client-go@v1.40.2/utils/io/fileutils/temp.go (about)

     1  package fileutils
     2  
     3  import (
     4  	"os"
     5  	"path"
     6  	"strconv"
     7  	"strings"
     8  	"time"
     9  
    10  	"github.com/jfrog/jfrog-client-go/utils/errorutils"
    11  )
    12  
    13  var (
    14  	tempPrefix = "jfrog.cli.temp."
    15  
    16  	// Max temp file age in hours
    17  	maxFileAge = 24.0
    18  
    19  	// Path to the root temp dir
    20  	tempDirBase string
    21  )
    22  
    23  func init() {
    24  	tempDirBase = os.TempDir()
    25  }
    26  
    27  // Creates the temp dir at tempDirBase.
    28  // Set tempDirPath to the created directory path.
    29  func CreateTempDir() (string, error) {
    30  	if tempDirBase == "" {
    31  		return "", errorutils.CheckErrorf("temp dir cannot be created in an empty base dir.")
    32  	}
    33  	timestamp := strconv.FormatInt(time.Now().Unix(), 10)
    34  	dirPath, err := os.MkdirTemp(tempDirBase, tempPrefix+"-"+timestamp+"-")
    35  	if err != nil {
    36  		return "", errorutils.CheckError(err)
    37  	}
    38  	return dirPath, nil
    39  }
    40  
    41  // Change the containing directory of temp dir.
    42  func SetTempDirBase(dirPath string) {
    43  	tempDirBase = dirPath
    44  }
    45  
    46  func GetTempDirBase() string {
    47  	return tempDirBase
    48  }
    49  
    50  func RemoveTempDir(dirPath string) error {
    51  	exists, err := IsDirExists(dirPath, false)
    52  	if err != nil {
    53  		return err
    54  	}
    55  	if !exists {
    56  		return nil
    57  	}
    58  	if err = os.RemoveAll(dirPath); err == nil {
    59  		return nil
    60  	}
    61  	// Sometimes removing the directory fails (in Windows) because it's locked by another process.
    62  	// That's a known issue, but its cause is unknown (golang.org/issue/30789).
    63  	// In this case, we'll only remove the contents of the directory, and let CleanOldDirs() remove the directory itself at a later time.
    64  	return RemoveDirContents(dirPath)
    65  }
    66  
    67  // Create a new temp file named "tempPrefix+timeStamp".
    68  func CreateTempFile() (*os.File, error) {
    69  	if tempDirBase == "" {
    70  		return nil, errorutils.CheckErrorf("temp File cannot be created in an empty base dir.")
    71  	}
    72  	timestamp := strconv.FormatInt(time.Now().Unix(), 10)
    73  	fd, err := os.CreateTemp(tempDirBase, tempPrefix+"-"+timestamp+"-")
    74  	return fd, err
    75  }
    76  
    77  // Old runs/tests may leave junk at temp dir.
    78  // Each temp file/Dir is named with prefix+timestamp, search for all temp files/dirs that match the common prefix and validate their timestamp.
    79  func CleanOldDirs() error {
    80  	// Get all files at temp dir
    81  	files, err := os.ReadDir(tempDirBase)
    82  	if err != nil {
    83  		return errorutils.CheckError(err)
    84  	}
    85  	now := time.Now()
    86  	// Search for files/dirs that match the template.
    87  	for _, file := range files {
    88  		fileName := file.Name()
    89  		if strings.HasPrefix(fileName, tempPrefix) {
    90  			var timeStamp time.Time
    91  			timeStamp, err = extractTimestamp(fileName)
    92  			if err != nil {
    93  				return err
    94  			}
    95  			// Delete old file/dirs.
    96  			if now.Sub(timeStamp).Hours() > maxFileAge {
    97  				if err = RemovePath(path.Join(tempDirBase, fileName)); err != nil {
    98  					return err
    99  				}
   100  			}
   101  		}
   102  	}
   103  	return nil
   104  }
   105  
   106  func extractTimestamp(item string) (time.Time, error) {
   107  	// Get timestamp from file/dir.
   108  	endTimestampIdx := strings.LastIndex(item, "-")
   109  	beginningTimestampIdx := strings.LastIndex(item[:endTimestampIdx], "-")
   110  	timestampStr := item[beginningTimestampIdx+1 : endTimestampIdx]
   111  	// Convert to int.
   112  	timeStampInt, err := strconv.ParseInt(timestampStr, 10, 64)
   113  	if err != nil {
   114  		return time.Time{}, errorutils.CheckError(err)
   115  	}
   116  	// Convert to time type.
   117  	return time.Unix(timeStampInt, 0), nil
   118  }