6
6
"net/url"
7
7
"os"
8
8
"path/filepath"
9
+ "regexp"
10
+ "strconv"
9
11
"strings"
10
12
11
13
"cloud.google.com/go/storage"
@@ -22,7 +24,7 @@ func (g *GCSGetter) ClientMode(u *url.URL) (ClientMode, error) {
22
24
ctx := g .Context ()
23
25
24
26
// Parse URL
25
- bucket , object , err := g .parseURL (u )
27
+ bucket , object , _ , err := g .parseURL (u )
26
28
if err != nil {
27
29
return 0 , err
28
30
}
@@ -59,7 +61,7 @@ func (g *GCSGetter) Get(dst string, u *url.URL) error {
59
61
ctx := g .Context ()
60
62
61
63
// Parse URL
62
- bucket , object , err := g .parseURL (u )
64
+ bucket , object , _ , err := g .parseURL (u )
63
65
if err != nil {
64
66
return err
65
67
}
@@ -105,7 +107,7 @@ func (g *GCSGetter) Get(dst string, u *url.URL) error {
105
107
}
106
108
objDst = filepath .Join (dst , objDst )
107
109
// Download the matching object.
108
- err = g .getObject (ctx , client , objDst , bucket , obj .Name )
110
+ err = g .getObject (ctx , client , objDst , bucket , obj .Name , "" )
109
111
if err != nil {
110
112
return err
111
113
}
@@ -118,20 +120,32 @@ func (g *GCSGetter) GetFile(dst string, u *url.URL) error {
118
120
ctx := g .Context ()
119
121
120
122
// Parse URL
121
- bucket , object , err := g .parseURL (u )
123
+ bucket , object , fragment , err := g .parseURL (u )
122
124
if err != nil {
123
125
return err
124
126
}
127
+ fmt .Println (object )
125
128
126
129
client , err := storage .NewClient (ctx )
127
130
if err != nil {
128
131
return err
129
132
}
130
- return g .getObject (ctx , client , dst , bucket , object )
133
+ return g .getObject (ctx , client , dst , bucket , object , fragment )
131
134
}
132
135
133
- func (g * GCSGetter ) getObject (ctx context.Context , client * storage.Client , dst , bucket , object string ) error {
134
- rc , err := client .Bucket (bucket ).Object (object ).NewReader (ctx )
136
+ func (g * GCSGetter ) getObject (ctx context.Context , client * storage.Client , dst , bucket , object , fragment string ) error {
137
+ var rc * storage.Reader
138
+ var err error
139
+ fragmentHasGeneration := regexp .MustCompile ("^\\ d+$" ).MatchString (fragment )
140
+ if fragmentHasGeneration {
141
+ generation , err := strconv .ParseInt (fragment , 10 , 64 )
142
+ if err != nil {
143
+ return err
144
+ }
145
+ rc , err = client .Bucket (bucket ).Object (object ).Generation (generation ).NewReader (ctx )
146
+ } else {
147
+ rc , err = client .Bucket (bucket ).Object (object ).NewReader (ctx )
148
+ }
135
149
if err != nil {
136
150
return err
137
151
}
@@ -145,7 +159,7 @@ func (g *GCSGetter) getObject(ctx context.Context, client *storage.Client, dst,
145
159
return copyReader (dst , rc , 0666 , g .client .umask ())
146
160
}
147
161
148
- func (g * GCSGetter ) parseURL (u * url.URL ) (bucket , path string , err error ) {
162
+ func (g * GCSGetter ) parseURL (u * url.URL ) (bucket , path , fragment string , err error ) {
149
163
if strings .Contains (u .Host , "googleapis.com" ) {
150
164
hostParts := strings .Split (u .Host , "." )
151
165
if len (hostParts ) != 3 {
@@ -160,6 +174,7 @@ func (g *GCSGetter) parseURL(u *url.URL) (bucket, path string, err error) {
160
174
}
161
175
bucket = pathParts [3 ]
162
176
path = pathParts [4 ]
177
+ fragment = u .Fragment
163
178
}
164
179
return
165
180
}
0 commit comments