aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/cli/internal/cacheitem/create.go
diff options
context:
space:
mode:
Diffstat (limited to 'cli/internal/cacheitem/create.go')
-rw-r--r--cli/internal/cacheitem/create.go119
1 files changed, 0 insertions, 119 deletions
diff --git a/cli/internal/cacheitem/create.go b/cli/internal/cacheitem/create.go
deleted file mode 100644
index ce5b1c8..0000000
--- a/cli/internal/cacheitem/create.go
+++ /dev/null
@@ -1,119 +0,0 @@
-package cacheitem
-
-import (
- "archive/tar"
- "bufio"
- "io"
- "os"
- "strings"
- "time"
-
- "github.com/DataDog/zstd"
-
- "github.com/moby/sys/sequential"
- "github.com/vercel/turbo/cli/internal/tarpatch"
- "github.com/vercel/turbo/cli/internal/turbopath"
-)
-
-// Create makes a new CacheItem at the specified path.
-func Create(path turbopath.AbsoluteSystemPath) (*CacheItem, error) {
- handle, err := path.OpenFile(os.O_WRONLY|os.O_CREATE|os.O_TRUNC|os.O_APPEND, 0644)
- if err != nil {
- return nil, err
- }
-
- cacheItem := &CacheItem{
- Path: path,
- handle: handle,
- compressed: strings.HasSuffix(path.ToString(), ".zst"),
- }
-
- cacheItem.init()
- return cacheItem, nil
-}
-
-// init prepares the CacheItem for writing.
-// Wires all the writers end-to-end:
-// tar.Writer -> zstd.Writer -> fileBuffer -> file
-func (ci *CacheItem) init() {
- fileBuffer := bufio.NewWriterSize(ci.handle, 2^20) // Flush to disk in 1mb chunks.
-
- var tw *tar.Writer
- if ci.compressed {
- zw := zstd.NewWriter(fileBuffer)
- tw = tar.NewWriter(zw)
- ci.zw = zw
- } else {
- tw = tar.NewWriter(fileBuffer)
- }
-
- ci.tw = tw
- ci.fileBuffer = fileBuffer
-}
-
-// AddFile adds a user-cached item to the tar.
-func (ci *CacheItem) AddFile(fsAnchor turbopath.AbsoluteSystemPath, filePath turbopath.AnchoredSystemPath) error {
- // Calculate the fully-qualified path to the file to read it.
- sourcePath := filePath.RestoreAnchor(fsAnchor)
-
- // We grab the FileInfo which tar.FileInfoHeader accepts.
- fileInfo, lstatErr := sourcePath.Lstat()
- if lstatErr != nil {
- return lstatErr
- }
-
- // Determine if we need to populate the additional link argument to tar.FileInfoHeader.
- var link string
- if fileInfo.Mode()&os.ModeSymlink != 0 {
- linkTarget, readlinkErr := sourcePath.Readlink()
- if readlinkErr != nil {
- return readlinkErr
- }
- link = linkTarget
- }
-
- // Normalize the path within the cache.
- cacheDestinationName := filePath.ToUnixPath()
-
- // Generate the the header.
- // We do not use header generation from stdlib because it can throw an error.
- header, headerErr := tarpatch.FileInfoHeader(cacheDestinationName, fileInfo, link)
- if headerErr != nil {
- return headerErr
- }
-
- // Throw an error if trying to create a cache that contains a type we don't support.
- if (header.Typeflag != tar.TypeReg) && (header.Typeflag != tar.TypeDir) && (header.Typeflag != tar.TypeSymlink) {
- return errUnsupportedFileType
- }
-
- // Consistent creation.
- header.Uid = 0
- header.Gid = 0
- header.AccessTime = time.Unix(0, 0)
- header.ModTime = time.Unix(0, 0)
- header.ChangeTime = time.Unix(0, 0)
-
- // Always write the header.
- if err := ci.tw.WriteHeader(header); err != nil {
- return err
- }
-
- // If there is a body to be written, do so.
- if header.Typeflag == tar.TypeReg && header.Size > 0 {
- // Windows has a distinct "sequential read" opening mode.
- // We use a library that will switch to this mode for Windows.
- sourceFile, sourceErr := sequential.OpenFile(sourcePath.ToString(), os.O_RDONLY, 0777)
- if sourceErr != nil {
- return sourceErr
- }
-
- if _, err := io.Copy(ci.tw, sourceFile); err != nil {
- return err
- }
-
- return sourceFile.Close()
- }
-
- return nil
-}