Function bodies 64 total
spinner.Spinner.StopWithMessage method · go · L79-L92 (14 LOC)internal/spinner/spinner.go
func (s *Spinner) StopWithMessage(msg string) {
s.mu.Lock()
if !s.running {
s.mu.Unlock()
return
}
s.running = false
close(s.done)
s.mu.Unlock()
// Wait for the goroutine to finish before writing to avoid data race.
<-s.stopped
_, _ = fmt.Fprintf(s.w, "\r\033[K%s\n", msg)
}storage.MockClient.PutObject method · go · L36-L44 (9 LOC)internal/storage/mock.go
func (m *MockClient) PutObject(bucket, key string, data []byte, meta *ObjectMetadata) {
m.mu.Lock()
defer m.mu.Unlock()
obj := mockObject{data: data}
if meta != nil {
obj.meta = *meta
}
m.objects[m.key(bucket, key)] = obj
}storage.MockClient.Download method · go · L53-L62 (10 LOC)internal/storage/mock.go
func (m *MockClient) Download(_ context.Context, bucket, key string, w io.Writer) error {
m.mu.Lock()
defer m.mu.Unlock()
obj, ok := m.objects[m.key(bucket, key)]
if !ok {
return fmt.Errorf("object not found: %s/%s", bucket, key)
}
_, err := io.Copy(w, bytes.NewReader(obj.data))
return err
}storage.MockClient.Upload method · go · L64-L77 (14 LOC)internal/storage/mock.go
func (m *MockClient) Upload(_ context.Context, bucket, key string, r io.Reader, meta *ObjectMetadata) error {
data, err := io.ReadAll(r)
if err != nil {
return err
}
m.mu.Lock()
defer m.mu.Unlock()
obj := mockObject{data: data}
if meta != nil {
obj.meta = *meta
}
m.objects[m.key(bucket, key)] = obj
return nil
}storage.MockClient.HeadObject method · go · L79-L91 (13 LOC)internal/storage/mock.go
func (m *MockClient) HeadObject(_ context.Context, bucket, key string) (*ObjectMetadata, error) {
m.mu.Lock()
defer m.mu.Unlock()
obj, ok := m.objects[m.key(bucket, key)]
if !ok {
return nil, fmt.Errorf("object not found: %s/%s", bucket, key)
}
meta := obj.meta
if meta.Metadata == nil {
meta.Metadata = make(map[string]string)
}
return &meta, nil
}storage.MockClient.UpdateMetadata method · go · L93-L106 (14 LOC)internal/storage/mock.go
func (m *MockClient) UpdateMetadata(_ context.Context, bucket, key string, meta *ObjectMetadata) error {
m.mu.Lock()
defer m.mu.Unlock()
k := m.key(bucket, key)
obj, ok := m.objects[k]
if !ok {
return fmt.Errorf("object not found: %s/%s", bucket, key)
}
if meta != nil {
obj.meta = *meta
}
m.objects[k] = obj
return nil
}storage.MockClient.List method · go · L108-L143 (36 LOC)internal/storage/mock.go
func (m *MockClient) List(_ context.Context, bucket, prefix, delimiter string) ([]ListEntry, error) {
m.mu.Lock()
defer m.mu.Unlock()
var entries []ListEntry
seen := make(map[string]bool)
for fullKey, obj := range m.objects {
parts := strings.SplitN(fullKey, "/", 2)
if parts[0] != bucket || len(parts) < 2 {
continue
}
objKey := parts[1]
if !strings.HasPrefix(objKey, prefix) {
continue
}
rest := objKey[len(prefix):]
if delimiter != "" {
if idx := strings.Index(rest, delimiter); idx >= 0 {
dirKey := prefix + rest[:idx+1]
if !seen[dirKey] {
seen[dirKey] = true
entries = append(entries, ListEntry{Key: dirKey, IsDir: true})
}
continue
}
}
entries = append(entries, ListEntry{
Key: objKey,
Size: int64(len(obj.data)),
})
}
return entries, nil
}All rows scored by the Repobility analyzer (https://repobility.com)
s3client.New function · go · L32-L62 (31 LOC)internal/storage/s3client/s3client.go
func New(ctx context.Context, opts Options) (*S3Client, error) {
var cfgOpts []func(*config.LoadOptions) error
if opts.Profile != "" {
cfgOpts = append(cfgOpts, config.WithSharedConfigProfile(opts.Profile))
}
if opts.Region != "" {
cfgOpts = append(cfgOpts, config.WithRegion(opts.Region))
}
cfg, err := config.LoadDefaultConfig(ctx, cfgOpts...)
if err != nil {
return nil, fmt.Errorf("loading AWS config: %w", err)
}
var s3Opts []func(*s3.Options)
if opts.EndpointURL != "" {
s3Opts = append(s3Opts, func(o *s3.Options) {
o.BaseEndpoint = aws.String(opts.EndpointURL)
o.UsePathStyle = true
})
}
if opts.NoSignRequest {
s3Opts = append(s3Opts, func(o *s3.Options) {
o.Credentials = aws.AnonymousCredentials{}
})
}
client := s3.NewFromConfig(cfg, s3Opts...)
return &S3Client{client: client}, nil
}s3client.S3Client.Download method · go · L64-L78 (15 LOC)internal/storage/s3client/s3client.go
func (c *S3Client) Download(ctx context.Context, bucket, key string, w io.Writer) error {
out, err := c.client.GetObject(ctx, &s3.GetObjectInput{
Bucket: aws.String(bucket),
Key: aws.String(key),
})
if err != nil {
return fmt.Errorf("downloading s3://%s/%s: %w", bucket, key, err)
}
defer out.Body.Close()
if _, err := io.Copy(w, out.Body); err != nil {
return fmt.Errorf("reading s3://%s/%s: %w", bucket, key, err)
}
return nil
}s3client.S3Client.Upload method · go · L80-L139 (60 LOC)internal/storage/s3client/s3client.go
func (c *S3Client) Upload(ctx context.Context, bucket, key string, r io.Reader, meta *storage.ObjectMetadata) error {
input := &s3.PutObjectInput{
Bucket: aws.String(bucket),
Key: aws.String(key),
Body: r,
}
if meta != nil {
if meta.ContentType != "" {
input.ContentType = aws.String(meta.ContentType)
}
if meta.CacheControl != "" {
input.CacheControl = aws.String(meta.CacheControl)
}
if meta.ContentEncoding != "" {
input.ContentEncoding = aws.String(meta.ContentEncoding)
}
if meta.ContentDisposition != "" {
input.ContentDisposition = aws.String(meta.ContentDisposition)
}
if len(meta.Metadata) > 0 {
input.Metadata = meta.Metadata
}
}
if _, err := c.client.PutObject(ctx, input); err != nil {
return fmt.Errorf("uploading to s3://%s/%s: %w", bucket, key, err)
}
return nil
}
func (c *S3Client) HeadObject(ctx context.Context, bucket, key string) (*storage.ObjectMetadata, error) {
out, err := c.client.HeadObject(ctx, &s3.HeadObjectInpus3client.S3Client.HeadObject method · go · L111-L171 (61 LOC)internal/storage/s3client/s3client.go
func (c *S3Client) HeadObject(ctx context.Context, bucket, key string) (*storage.ObjectMetadata, error) {
out, err := c.client.HeadObject(ctx, &s3.HeadObjectInput{
Bucket: aws.String(bucket),
Key: aws.String(key),
})
if err != nil {
return nil, fmt.Errorf("head s3://%s/%s: %w", bucket, key, err)
}
meta := &storage.ObjectMetadata{
Metadata: make(map[string]string),
}
if out.ContentType != nil {
meta.ContentType = *out.ContentType
}
if out.CacheControl != nil {
meta.CacheControl = *out.CacheControl
}
if out.ContentEncoding != nil {
meta.ContentEncoding = *out.ContentEncoding
}
if out.ContentDisposition != nil {
meta.ContentDisposition = *out.ContentDisposition
}
for k, v := range out.Metadata {
meta.Metadata[k] = v
}
return meta, nil
}
func (c *S3Client) UpdateMetadata(ctx context.Context, bucket, key string, meta *storage.ObjectMetadata) error {
encodedKey := encodeKeySegments(key)
source := fmt.Sprintf("%s/%s", bucket, encodedKey)
input := &s3s3client.S3Client.UpdateMetadata method · go · L141-L209 (69 LOC)internal/storage/s3client/s3client.go
func (c *S3Client) UpdateMetadata(ctx context.Context, bucket, key string, meta *storage.ObjectMetadata) error {
encodedKey := encodeKeySegments(key)
source := fmt.Sprintf("%s/%s", bucket, encodedKey)
input := &s3.CopyObjectInput{
Bucket: aws.String(bucket),
Key: aws.String(key),
CopySource: aws.String(source),
MetadataDirective: types.MetadataDirectiveReplace,
}
if meta.ContentType != "" {
input.ContentType = aws.String(meta.ContentType)
}
if meta.CacheControl != "" {
input.CacheControl = aws.String(meta.CacheControl)
}
if meta.ContentEncoding != "" {
input.ContentEncoding = aws.String(meta.ContentEncoding)
}
if meta.ContentDisposition != "" {
input.ContentDisposition = aws.String(meta.ContentDisposition)
}
if len(meta.Metadata) > 0 {
input.Metadata = meta.Metadata
}
if _, err := c.client.CopyObject(ctx, input); err != nil {
return fmt.Errorf("updating metadata for s3://%s/%s: %w", bucket, key, err)
}
return nil
}
s3client.S3Client.ListBuckets method · go · L213-L225 (13 LOC)internal/storage/s3client/s3client.go
func (c *S3Client) ListBuckets(ctx context.Context) ([]string, error) {
out, err := c.client.ListBuckets(ctx, &s3.ListBucketsInput{})
if err != nil {
return nil, fmt.Errorf("listing buckets: %w", err)
}
var names []string
for _, b := range out.Buckets {
if b.Name != nil {
names = append(names, *b.Name)
}
}
return names, nil
}s3client.encodeKeySegments function · go · L228-L234 (7 LOC)internal/storage/s3client/s3client.go
func encodeKeySegments(key string) string {
segments := strings.Split(key, "/")
for i, seg := range segments {
segments[i] = strings.ReplaceAll(url.QueryEscape(seg), "+", "%20")
}
return strings.Join(segments, "/")
}‹ prevpage 2 / 2