Skip to content

Commit 607534c

Browse files
authored
feat(storage/transfermanager): add option to StripPrefix on directory download (#10894)
1 parent 35ad73d commit 607534c

2 files changed

Lines changed: 21 additions & 4 deletions

File tree

storage/transfermanager/downloader.go

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"math"
2626
"os"
2727
"path/filepath"
28+
"strings"
2829
"sync"
2930
"time"
3031

@@ -175,8 +176,13 @@ func (d *Downloader) DownloadDirectory(ctx context.Context, input *DownloadDirec
175176
inputs := make([]DownloadObjectInput, 0, len(objectsToQueue))
176177

177178
for _, object := range objectsToQueue {
178-
objDirectory := filepath.Join(input.LocalDirectory, filepath.Dir(object))
179-
filePath := filepath.Join(input.LocalDirectory, object)
179+
objectWithoutPrefix := object
180+
if len(input.StripPrefix) > 0 {
181+
objectWithoutPrefix, _ = strings.CutPrefix(object, input.StripPrefix)
182+
}
183+
184+
objDirectory := filepath.Join(input.LocalDirectory, filepath.Dir(objectWithoutPrefix))
185+
filePath := filepath.Join(input.LocalDirectory, objectWithoutPrefix)
180186

181187
// Make sure all directories in the object path exist.
182188
err := os.MkdirAll(objDirectory, fs.ModeDir|fs.ModePerm)
@@ -750,6 +756,12 @@ type DownloadDirectoryInput struct {
750756
// The directory will be created if it does not already exist. Required.
751757
LocalDirectory string
752758

759+
// StripPrefix is a prefix to be removed from the path of the local file on
760+
// download from GCS. For example, if you have an object in GCS called
761+
// "mydirectory/a/file", and StripPrefix is set to "mydirectory/", the file
762+
// will be downloaded to "{LocalDirectory}/a/file". Optional.
763+
StripPrefix string
764+
753765
// Prefix is the prefix filter to download objects whose names begin with this.
754766
// Optional.
755767
Prefix string

storage/transfermanager/integration_test.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
"math/rand"
2929
"os"
3030
"path/filepath"
31+
"strings"
3132
"sync"
3233
"testing"
3334
"time"
@@ -100,6 +101,7 @@ func TestIntegration_DownloadDirectory(t *testing.T) {
100101
if err := d.DownloadDirectory(ctx, &DownloadDirectoryInput{
101102
Bucket: tb.bucket,
102103
LocalDirectory: localDir,
104+
StripPrefix: "dir/",
103105
OnObjectDownload: func(got *DownloadOutput) {
104106
callbackMu.Lock()
105107
numCallbacks++
@@ -113,7 +115,9 @@ func TestIntegration_DownloadDirectory(t *testing.T) {
113115
t.Errorf("expected object size %d, got %d", want, got)
114116
}
115117

116-
path := filepath.Join(localDir, got.Object)
118+
objectWithoutPrefix, _ := strings.CutPrefix(got.Object, "dir/")
119+
path := filepath.Join(localDir, objectWithoutPrefix)
120+
117121
f, err := os.Open(path)
118122
if err != nil {
119123
t.Errorf("os.Open(%q): %v", path, err)
@@ -156,7 +160,8 @@ func TestIntegration_DownloadDirectory(t *testing.T) {
156160
t.Errorf("expected object size %d, got %d", want, got)
157161
}
158162

159-
path := filepath.Join(localDir, got.Object)
163+
objectWithoutPrefix, _ := strings.CutPrefix(got.Object, "dir/")
164+
path := filepath.Join(localDir, objectWithoutPrefix)
160165
f, err := os.Open(path)
161166
if err != nil {
162167
t.Errorf("os.Open(%q): %v", path, err)

0 commit comments

Comments
 (0)