This repository has been archived by the owner on Aug 21, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathgcs.go
125 lines (105 loc) · 2.91 KB
/
gcs.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
package storage
import (
"fmt";
"io";
"context";
"regexp";
"strings";
"path/filepath";
gcs "cloud.google.com/go/storage";
"google.golang.org/api/option";
"google.golang.org/api/iterator";
)
var gcsBucketRegexp = regexp.MustCompile(`([\w\-\.]+)\/(.*)`)
type googleCloudStorage struct {
ctx context.Context
client *gcs.Client
}
func NewGCS(options ...option.ClientOption) (Storage, error) {
ctx := context.Background()
client, err := gcs.NewClient(ctx, options...)
if err != nil {
return nil, err
}
return &googleCloudStorage{
ctx: ctx,
client: client,
}, nil
}
func (s *googleCloudStorage) Exists(path string) (bool, error) {
object, err := s.objectAtPath(path)
if err != nil {
return false, err
}
_, err = object.Attrs(s.ctx)
return err == nil, nil
}
func (s *googleCloudStorage) ListFiles(path string) ([]string, error) {
bucketName, objectsPath, err := s.normalizePath(path)
if err != nil {
return nil, err
}
prefix := objectsPath
wildcard := isWildcard(objectsPath)
if wildcard {
prefix = filepath.Dir(prefix)
}
if !strings.HasSuffix(prefix, "/") {
prefix += "/"
}
objectIterator := s.client.Bucket(bucketName).Objects(s.ctx, &gcs.Query{
Delimiter: "/",
Prefix: prefix,
Versions: false,
})
result := make([]string, 0)
for {
object, err := objectIterator.Next()
if err == iterator.Done {
break
}
if err != nil {
return nil, err
}
if wildcard {
match, err := filepath.Match(objectsPath, object.Name)
if err != nil {
return nil, err
}
if !match {
continue
}
}
result = append(result, "gs://" + filepath.Join(bucketName, object.Name))
}
return result, nil
}
func (s *googleCloudStorage) Reader(path string) (io.ReadCloser, error) {
object, err := s.objectAtPath(path)
if err != nil {
return nil, err
}
return object.NewReader(s.ctx)
}
func (s *googleCloudStorage) Writer(path string) (io.WriteCloser, error) {
object, err := s.objectAtPath(path)
if err != nil {
return nil, err
}
return object.NewWriter(s.ctx), nil
}
func (s *googleCloudStorage) objectAtPath(path string) (*gcs.ObjectHandle, error) {
bucketName, objectName, err := s.normalizePath(path)
if err != nil {
return nil, err
}
return s.client.Bucket(bucketName).Object(objectName), nil
}
func (gcs *googleCloudStorage) normalizePath(path string) (string, string, error) {
path = strings.TrimPrefix(path, "gs://")
pathParts := gcsBucketRegexp.FindStringSubmatch(path)
if len(pathParts) != 3 {
return "", "", fmt.Errorf("Invalid path `%s`", path)
}
return pathParts[1], pathParts[2], nil
}