/*Package fs provides tools for creating temporary files, and testing the contents and structure of a directory. */ package fs // import "gotest.tools/fs" import ( "io/ioutil" "os" "path/filepath" "runtime" "strings" "gotest.tools/assert" "gotest.tools/x/subtest" ) // Path objects return their filesystem path. Path may be implemented by a // real filesystem object (such as File and Dir) or by a type which updates // entries in a Manifest. type Path interface { Path() string Remove() } var ( _ Path = &Dir{} _ Path = &File{} ) // File is a temporary file on the filesystem type File struct { path string } type helperT interface { Helper() } // NewFile creates a new file in a temporary directory using prefix as part of // the filename. The PathOps are applied to the before returning the File. func NewFile(t assert.TestingT, prefix string, ops ...PathOp) *File { if ht, ok := t.(helperT); ok { ht.Helper() } tempfile, err := ioutil.TempFile("", cleanPrefix(prefix)+"-") assert.NilError(t, err) file := &File{path: tempfile.Name()} assert.NilError(t, tempfile.Close()) for _, op := range ops { assert.NilError(t, op(file)) } if tc, ok := t.(subtest.TestContext); ok { tc.AddCleanup(file.Remove) } return file } func cleanPrefix(prefix string) string { // windows requires both / and \ are replaced if runtime.GOOS == "windows" { prefix = strings.Replace(prefix, string(os.PathSeparator), "-", -1) } return strings.Replace(prefix, "/", "-", -1) } // Path returns the full path to the file func (f *File) Path() string { return f.path } // Remove the file func (f *File) Remove() { // nolint: errcheck os.Remove(f.path) } // Dir is a temporary directory type Dir struct { path string } // NewDir returns a new temporary directory using prefix as part of the directory // name. The PathOps are applied before returning the Dir. func NewDir(t assert.TestingT, prefix string, ops ...PathOp) *Dir { if ht, ok := t.(helperT); ok { ht.Helper() } path, err := ioutil.TempDir("", cleanPrefix(prefix)+"-") assert.NilError(t, err) dir := &Dir{path: path} for _, op := range ops { assert.NilError(t, op(dir)) } if tc, ok := t.(subtest.TestContext); ok { tc.AddCleanup(dir.Remove) } return dir } // Path returns the full path to the directory func (d *Dir) Path() string { return d.path } // Remove the directory func (d *Dir) Remove() { // nolint: errcheck os.RemoveAll(d.path) } // Join returns a new path with this directory as the base of the path func (d *Dir) Join(parts ...string) string { return filepath.Join(append([]string{d.Path()}, parts...)...) }