pkg.re/essentialkaos/ek.10@v12.41.0+incompatible/tmp/tmp.go (about)

     1  // Package tmp provides methods and structs for working with temporary data
     2  package tmp
     3  
     4  // ////////////////////////////////////////////////////////////////////////////////// //
     5  //                                                                                    //
     6  //                         Copyright (c) 2022 ESSENTIAL KAOS                          //
     7  //      Apache License, Version 2.0 <https://www.apache.org/licenses/LICENSE-2.0>     //
     8  //                                                                                    //
     9  // ////////////////////////////////////////////////////////////////////////////////// //
    10  
    11  import (
    12  	"fmt"
    13  	"os"
    14  	"path"
    15  
    16  	"pkg.re/essentialkaos/ek.v12/fsutil"
    17  	"pkg.re/essentialkaos/ek.v12/rand"
    18  )
    19  
    20  // ////////////////////////////////////////////////////////////////////////////////// //
    21  
    22  // Temp is basic temp struct
    23  type Temp struct {
    24  	Dir       string
    25  	DirPerms  os.FileMode
    26  	FilePerms os.FileMode
    27  
    28  	targets []string
    29  }
    30  
    31  // ////////////////////////////////////////////////////////////////////////////////// //
    32  
    33  // Dir is default temporary directory
    34  var Dir = "/tmp"
    35  
    36  // DefaultDirPerms is default permissions for directories
    37  var DefaultDirPerms = os.FileMode(0750)
    38  
    39  // DefaultFilePerms is default permissions for files
    40  var DefaultFilePerms = os.FileMode(0640)
    41  
    42  // ////////////////////////////////////////////////////////////////////////////////// //
    43  
    44  // NewTemp creates new Temp structure
    45  func NewTemp(dir ...string) (*Temp, error) {
    46  	tempDir := path.Clean(Dir)
    47  
    48  	if len(dir) != 0 {
    49  		tempDir = path.Clean(dir[0])
    50  	}
    51  
    52  	if !fsutil.IsExist(tempDir) {
    53  		return nil, fmt.Errorf("Directory %s does not exist", tempDir)
    54  	}
    55  
    56  	if !fsutil.IsDir(tempDir) {
    57  		return nil, fmt.Errorf("%s is not a directory", tempDir)
    58  	}
    59  
    60  	if !fsutil.IsWritable(tempDir) {
    61  		return nil, fmt.Errorf("Directory %s is not writable", tempDir)
    62  	}
    63  
    64  	return &Temp{
    65  		Dir:       tempDir,
    66  		DirPerms:  DefaultDirPerms,
    67  		FilePerms: DefaultFilePerms,
    68  	}, nil
    69  }
    70  
    71  // ////////////////////////////////////////////////////////////////////////////////// //
    72  
    73  // MkDir makes temporary directory
    74  func (t *Temp) MkDir(nameSuffix ...string) (string, error) {
    75  	if t == nil {
    76  		return "", fmt.Errorf("Temp struct is nil")
    77  	}
    78  
    79  	name := ""
    80  
    81  	if len(nameSuffix) != 0 {
    82  		name = nameSuffix[0]
    83  	}
    84  
    85  	tmpDir := getTempName(t.Dir, name)
    86  	err := os.MkdirAll(tmpDir, t.DirPerms)
    87  
    88  	if err != nil {
    89  		return "", err
    90  	}
    91  
    92  	t.targets = append(t.targets, tmpDir)
    93  
    94  	return tmpDir, err
    95  }
    96  
    97  // MkFile makes temporary file
    98  func (t *Temp) MkFile(nameSuffix ...string) (*os.File, string, error) {
    99  	if t == nil {
   100  		return nil, "", fmt.Errorf("Temp struct is nil")
   101  	}
   102  
   103  	name := ""
   104  
   105  	if len(nameSuffix) != 0 {
   106  		name = nameSuffix[0]
   107  	}
   108  
   109  	tmpFile := getTempName(t.Dir, name)
   110  	fd, err := os.OpenFile(tmpFile, os.O_RDWR|os.O_CREATE, t.FilePerms)
   111  
   112  	if err != nil {
   113  		return nil, "", err
   114  	}
   115  
   116  	t.targets = append(t.targets, tmpFile)
   117  
   118  	return fd, tmpFile, nil
   119  }
   120  
   121  // MkName returns name for temporary object
   122  func (t *Temp) MkName(nameSuffix ...string) string {
   123  	name := ""
   124  
   125  	if len(nameSuffix) != 0 {
   126  		name = nameSuffix[0]
   127  	}
   128  
   129  	tmpObj := getTempName(t.Dir, name)
   130  	t.targets = append(t.targets, tmpObj)
   131  
   132  	return tmpObj
   133  }
   134  
   135  // Clean removes all temporary targets
   136  func (t *Temp) Clean() {
   137  	if t == nil || t.targets == nil || len(t.targets) == 0 {
   138  		return
   139  	}
   140  
   141  	for _, target := range t.targets {
   142  		os.RemoveAll(target)
   143  	}
   144  }
   145  
   146  // ////////////////////////////////////////////////////////////////////////////////// //
   147  
   148  // getTempName returns name of temporary file
   149  func getTempName(dir, name string) string {
   150  	var result string
   151  
   152  	for {
   153  		if name != "" {
   154  			result = path.Join(dir, "_"+rand.String(12)+"_"+name)
   155  		} else {
   156  			result = path.Join(dir, "_tmp_"+rand.String(12))
   157  		}
   158  
   159  		if !fsutil.IsExist(result) {
   160  			break
   161  		}
   162  	}
   163  
   164  	return result
   165  }