Last active
August 15, 2023 18:28
-
-
Save njhale/f8b06cc742a8f04030e0c0e18d1779a7 to your computer and use it in GitHub Desktop.
Clone a directory for the lifetime of a Go test
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package forkdir | |
import ( | |
"fmt" | |
"io" | |
"os" | |
"path/filepath" | |
"testing" | |
"github.com/acorn-io/z" | |
) | |
// ForkDir creates a temporary copy of a directory tree and returns its path. | |
// Each copy is tied to the lifetime of the test that created it, and is deleted when that test is over. | |
func ForkDir(t *testing.T, path string) (forkPath string) { | |
t.Helper() | |
// Create a temporary directory to hold the copies | |
pattern := fmt.Sprintf("%s.*.%s", t.Name(), filepath.Base(path)) | |
forkPath = z.MustBe(os.MkdirTemp("", pattern)) | |
// Be sure to delete the copy once the test that requested it is done | |
t.Cleanup(func() { | |
z.Must(os.Remove(forkPath)) | |
}) | |
copyFile := func(src, dest string) { | |
srcFile, destFile := z.MustBe(os.Open(src)), z.MustBe(os.Create(dest)) | |
defer func() { z.Must(srcFile.Close(), destFile.Close()) }() | |
z.MustBe(io.Copy(destFile, srcFile)) | |
} | |
var copyDir func(string, string) | |
copyDir = func(src, dest string) { | |
for _, fd := range z.MustBe(os.ReadDir(src)) { | |
name := fd.Name() | |
nextSrc, nextDest := filepath.Join(src, name), filepath.Join(dest, name) | |
switch mode := fd.Type(); { | |
case mode.IsDir(): | |
// Traverse subtree | |
copyDir(nextSrc, nextDest) | |
case mode.IsRegular(): | |
// Copy regular file | |
copyFile(nextSrc, nextDest) | |
} | |
// Ignore links and other file types | |
} | |
} | |
copyDir(path, forkPath) | |
return forkPath | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment