sigs.k8s.io/prow@v0.0.0-20240503223140-c5e374dc7eb1/pkg/io/iterator.go (about)

     1  /*
     2  Copyright 2020 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package io
    18  
    19  import (
    20  	"context"
    21  	"io"
    22  	"strings"
    23  	"time"
    24  
    25  	"cloud.google.com/go/storage"
    26  	"gocloud.dev/blob"
    27  	"google.golang.org/api/iterator"
    28  )
    29  
    30  type ObjectAttributes struct {
    31  	// Name is the full path of the object or directory
    32  	Name string
    33  	// ObjName is the last segment of the name in case of an object
    34  	ObjName string
    35  	// IsDir is true if the object is a directory
    36  	IsDir bool
    37  	// Size is the size of the blob's content in bytes in case of an object.
    38  	Size int64
    39  	// Updated is the creation or modification time in case of the object.
    40  	Updated time.Time
    41  }
    42  
    43  // ObjectIterator iterates through storage objects
    44  // It returns attr as long as it finds objects. When no
    45  // objects can be found anymore io.EOF error is returned
    46  type ObjectIterator interface {
    47  	Next(ctx context.Context) (attr ObjectAttributes, err error)
    48  }
    49  
    50  // gcsObjectIterator implements ObjectIterator for GCS
    51  type gcsObjectIterator struct {
    52  	Iterator *storage.ObjectIterator
    53  }
    54  
    55  func (g gcsObjectIterator) Next(_ context.Context) (ObjectAttributes, error) {
    56  	oAttrs, err := g.Iterator.Next()
    57  	// oAttrs object has only 'Name' or 'Prefix' field set.
    58  	if err == iterator.Done {
    59  		return ObjectAttributes{}, io.EOF
    60  	}
    61  	if err != nil {
    62  		return ObjectAttributes{}, err
    63  	}
    64  	var attr ObjectAttributes
    65  	if oAttrs.Prefix == "" {
    66  		// object
    67  		attr.Name = oAttrs.Name
    68  		nameSplit := strings.Split(oAttrs.Name, "/")
    69  		attr.ObjName = nameSplit[len(nameSplit)-1]
    70  		attr.Size = oAttrs.Size
    71  		attr.Updated = oAttrs.Updated
    72  	} else {
    73  		// directory
    74  		attr.Name = oAttrs.Prefix
    75  		attr.IsDir = true
    76  	}
    77  	return attr, nil
    78  }
    79  
    80  // gcsObjectIterator implements ObjectIterator via the gocloud/blob package
    81  type openerObjectIterator struct {
    82  	Iterator *blob.ListIterator
    83  }
    84  
    85  func (g openerObjectIterator) Next(ctx context.Context) (ObjectAttributes, error) {
    86  	oAttrs, err := g.Iterator.Next(ctx)
    87  	if err == io.EOF {
    88  		return ObjectAttributes{}, io.EOF
    89  	}
    90  	if err != nil {
    91  		return ObjectAttributes{}, err
    92  	}
    93  	attr := ObjectAttributes{
    94  		Name:  oAttrs.Key,
    95  		IsDir: oAttrs.IsDir,
    96  	}
    97  	if !oAttrs.IsDir {
    98  		// object
    99  		nameSplit := strings.Split(oAttrs.Key, "/")
   100  		attr.ObjName = nameSplit[len(nameSplit)-1]
   101  		attr.Size = oAttrs.Size
   102  		attr.Updated = oAttrs.ModTime
   103  	}
   104  	return attr, nil
   105  }