github.com/tilt-dev/tilt@v0.36.0/internal/testutils/tempdir/temp_dir_fixture.go (about)

     1  package tempdir
     2  
     3  import (
     4  	"os"
     5  	"path/filepath"
     6  	"regexp"
     7  	"strings"
     8  	"testing"
     9  
    10  	"github.com/stretchr/testify/require"
    11  )
    12  
    13  type TempDirFixture struct {
    14  	t      testing.TB
    15  	dir    string
    16  	oldDir string
    17  }
    18  
    19  // everything not listed in this character class will get replaced by _, so that it's a safe filename
    20  var sanitizeForFilenameRe = regexp.MustCompile("[^a-zA-Z0-9.]")
    21  
    22  func SanitizeFileName(name string) string {
    23  	return sanitizeForFilenameRe.ReplaceAllString(name, "_")
    24  }
    25  
    26  func NewTempDirFixture(t testing.TB) *TempDirFixture {
    27  	dir := t.TempDir()
    28  
    29  	dir, err := filepath.EvalSymlinks(dir)
    30  	require.NoError(t, err)
    31  
    32  	f := &TempDirFixture{
    33  		t:   t,
    34  		dir: dir,
    35  	}
    36  	t.Cleanup(f.tearDown)
    37  	return f
    38  }
    39  
    40  func (f *TempDirFixture) T() testing.TB {
    41  	return f.t
    42  }
    43  
    44  func (f *TempDirFixture) Path() string {
    45  	return f.dir
    46  }
    47  
    48  func (f *TempDirFixture) Chdir() {
    49  	cwd, err := os.Getwd()
    50  	if err != nil {
    51  		f.t.Fatal(err)
    52  	}
    53  
    54  	f.oldDir = cwd
    55  
    56  	err = os.Chdir(f.Path())
    57  	if err != nil {
    58  		f.t.Fatal(err)
    59  	}
    60  }
    61  
    62  func (f *TempDirFixture) JoinPath(path ...string) string {
    63  	p := []string{}
    64  	isAbs := len(path) > 0 && filepath.IsAbs(path[0])
    65  	if isAbs {
    66  		if !strings.HasPrefix(path[0], f.Path()) {
    67  			f.t.Fatalf("Path outside fixture tempdir are forbidden: %s", path[0])
    68  		}
    69  	} else {
    70  		p = append(p, f.Path())
    71  	}
    72  
    73  	p = append(p, path...)
    74  	return filepath.Join(p...)
    75  }
    76  
    77  func (f *TempDirFixture) JoinPaths(paths []string) []string {
    78  	joined := make([]string, len(paths))
    79  	for i, p := range paths {
    80  		joined[i] = f.JoinPath(p)
    81  	}
    82  	return joined
    83  }
    84  
    85  // Returns the full path to the file written.
    86  func (f *TempDirFixture) WriteFile(path string, contents string) string {
    87  	fullPath := f.JoinPath(path)
    88  	base := filepath.Dir(fullPath)
    89  	err := os.MkdirAll(base, os.FileMode(0777))
    90  	if err != nil {
    91  		f.t.Fatal(err)
    92  	}
    93  	err = os.WriteFile(fullPath, []byte(contents), os.FileMode(0777))
    94  	if err != nil {
    95  		f.t.Fatal(err)
    96  	}
    97  	return fullPath
    98  }
    99  
   100  // Returns the full path to the file written.
   101  func (f *TempDirFixture) CopyFile(originalPath, newPath string) {
   102  	contents, err := os.ReadFile(originalPath)
   103  	if err != nil {
   104  		f.t.Fatal(err)
   105  	}
   106  	f.WriteFile(newPath, string(contents))
   107  }
   108  
   109  // Read the file.
   110  func (f *TempDirFixture) ReadFile(path string) string {
   111  	fullPath := f.JoinPath(path)
   112  	contents, err := os.ReadFile(fullPath)
   113  	if err != nil {
   114  		f.t.Fatal(err)
   115  	}
   116  	return string(contents)
   117  }
   118  
   119  func (f *TempDirFixture) WriteSymlink(linkContents, destPath string) {
   120  	fullDestPath := f.JoinPath(destPath)
   121  	err := os.MkdirAll(filepath.Dir(fullDestPath), os.FileMode(0777))
   122  	if err != nil {
   123  		f.t.Fatal(err)
   124  	}
   125  	err = os.Symlink(linkContents, fullDestPath)
   126  	if err != nil {
   127  		f.t.Fatal(err)
   128  	}
   129  }
   130  
   131  func (f *TempDirFixture) MkdirAll(path string) {
   132  	fullPath := f.JoinPath(path)
   133  	err := os.MkdirAll(fullPath, os.FileMode(0777))
   134  	if err != nil {
   135  		f.t.Fatal(err)
   136  	}
   137  }
   138  
   139  func (f *TempDirFixture) TouchFiles(paths []string) {
   140  	for _, p := range paths {
   141  		f.WriteFile(p, "")
   142  	}
   143  }
   144  
   145  func (f *TempDirFixture) Rm(pathInRepo string) {
   146  	fullPath := f.JoinPath(pathInRepo)
   147  	err := os.RemoveAll(fullPath)
   148  	if err != nil {
   149  		f.t.Fatal(err)
   150  	}
   151  }
   152  
   153  func (f *TempDirFixture) NewFile(prefix string) (*os.File, error) {
   154  	return os.CreateTemp(f.dir, prefix)
   155  }
   156  
   157  func (f *TempDirFixture) TempDir(prefix string) string {
   158  	name, err := os.MkdirTemp(f.dir, prefix)
   159  	if err != nil {
   160  		f.t.Fatal(err)
   161  	}
   162  	return name
   163  }
   164  
   165  func (f *TempDirFixture) tearDown() {
   166  	if f.oldDir != "" {
   167  		err := os.Chdir(f.oldDir)
   168  		if err != nil {
   169  			f.t.Fatal(err)
   170  		}
   171  	}
   172  }