// Package tempdir allocates disposable storage outside a source worktree. package tempdir import ( "fmt" "os" "path/filepath" "strings" ) // Outside uses the system temporary directory and leaves cleanup to its caller. func Outside(repositoryDir, pattern string) (string, error) { directory, err := os.MkdirTemp("", pattern) if err != nil { return "", err } absolute, err := filepath.Abs(directory) if err != nil { os.RemoveAll(directory) return "", err } directory = absolute repository, err := filepath.Abs(repositoryDir) if err == nil && !strings.EqualFold(filepath.VolumeName(repository), filepath.VolumeName(directory)) { return directory, nil } if err == nil { var relative string relative, err = filepath.Rel(repository, directory) if err == nil && (relative == "." || relative != ".." && !strings.HasPrefix(relative, ".."+string(filepath.Separator))) { err = fmt.Errorf("temporary storage %q is inside repository %q; select an external temporary directory", directory, repository) } } if err != nil { os.RemoveAll(directory) return "", err } return directory, nil }