aboutsummaryrefslogtreecommitdiff
path: root/format/pack/ingest/temp.go
diff options
context:
space:
mode:
authorGravatar Runxi Yu2026-03-05 18:24:40 +0800
committerGravatar Runxi Yu2026-03-05 19:05:47 +0800
commit57f1818d547f2f1dca38033b4e29f62d89ef80f9 (patch)
tree88d55ac38e2427860bf380c8cce42fcb3bb1e9ee /format/pack/ingest/temp.go
parentinternal/compress/zlib: Use flate's compression consumed counter (diff)
signatureNo signature
format/pack/ingest: Init
Diffstat (limited to 'format/pack/ingest/temp.go')
-rw-r--r--format/pack/ingest/temp.go80
1 files changed, 80 insertions, 0 deletions
diff --git a/format/pack/ingest/temp.go b/format/pack/ingest/temp.go
new file mode 100644
index 00000000..cdda06c6
--- /dev/null
+++ b/format/pack/ingest/temp.go
@@ -0,0 +1,80 @@
+package ingest
+
+import (
+ "crypto/rand"
+ "errors"
+ "fmt"
+ "io/fs"
+ "os"
+)
+
+// openTemporaryArtifacts creates/open temp pack/idx/(rev) files under destination.
+func openTemporaryArtifacts(state *ingestState) error {
+ packName, packFile, err := createTempFile(state.destination, "tmp_pack_")
+ if err != nil {
+ return err
+ }
+ state.packTmpName = packName
+ state.packFile = packFile
+
+ idxName, idxFile, err := createTempFile(state.destination, "tmp_idx_")
+ if err != nil {
+ return err
+ }
+ state.idxTmpName = idxName
+ state.idxFile = idxFile
+
+ if state.writeRev {
+ revName, revFile, err := createTempFile(state.destination, "tmp_rev_")
+ if err != nil {
+ return err
+ }
+ state.revTmpName = revName
+ state.revFile = revFile
+ }
+
+ return nil
+}
+
+// closeTemporaryArtifacts closes all temporary artifact file descriptors.
+func closeTemporaryArtifacts(state *ingestState) error {
+ var out error
+ if state.packFile != nil {
+ if err := state.packFile.Close(); err != nil && out == nil {
+ out = err
+ }
+ state.packFile = nil
+ }
+ if state.idxFile != nil {
+ if err := state.idxFile.Close(); err != nil && out == nil {
+ out = err
+ }
+ state.idxFile = nil
+ }
+ if state.revFile != nil {
+ if err := state.revFile.Close(); err != nil && out == nil {
+ out = err
+ }
+ state.revFile = nil
+ }
+
+ return out
+}
+
+// createTempFile creates one temporary file under root using prefix.
+func createTempFile(root *os.Root, prefix string) (string, *os.File, error) {
+ for range 32 {
+ name := prefix + rand.Text()
+ file, err := root.OpenFile(name, os.O_CREATE|os.O_EXCL|os.O_RDWR, 0o644)
+ if err == nil {
+ return name, file, nil
+ }
+ if errors.Is(err, fs.ErrExist) {
+ continue
+ }
+
+ return "", nil, fmt.Errorf("format/pack/ingest: create temp file %q: %w", name, err)
+ }
+
+ return "", nil, fmt.Errorf("format/pack/ingest: unable to create temporary file for prefix %q", prefix)
+}