40 lines
1.1 KiB
Go
40 lines
1.1 KiB
Go
// 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
|
|
}
|