github.com/grailbio/base@v0.0.11/file/s3file/versions.go (about)

     1  package s3file
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  
     7  	"github.com/grailbio/base/errors"
     8  	"github.com/grailbio/base/file"
     9  	"github.com/grailbio/base/file/addfs"
    10  	"github.com/grailbio/base/file/fsnode"
    11  	"github.com/grailbio/base/grail/biofs/biofseventlog"
    12  )
    13  
    14  type versionsFunc struct{}
    15  
    16  var (
    17  	VersionsFunc versionsFunc
    18  	_            addfs.PerNodeFunc = VersionsFunc
    19  )
    20  
    21  func (versionsFunc) Apply(ctx context.Context, node fsnode.T) ([]fsnode.T, error) {
    22  	biofseventlog.UsedFeature("s3.versions.func")
    23  	// For now, we rely on gfilefs's fsnode.T implementations saving the underlying path as Sys().
    24  	// This is temporary (BXDS-1030). When we fix that, we'll need to make this detect the
    25  	// concrete type for S3-backed fsnode.T's instead of looking for Sys(). That'll likely require
    26  	// refactoring such as merging gfilefs into this package.
    27  	path, ok := node.Info().Sys().(string)
    28  	if !ok {
    29  		return nil, nil
    30  	}
    31  	scheme, bucket, key, err := ParseURL(path)
    32  	if err != nil || scheme != Scheme {
    33  		return nil, nil
    34  	}
    35  	implIface := file.FindImplementation(Scheme)
    36  	impl, ok := implIface.(*s3Impl)
    37  	if !ok {
    38  		return nil, errors.E(errors.Precondition, fmt.Sprintf("unrecognized s3 impl: %T", implIface))
    39  	}
    40  	var (
    41  		q   = s3Query{impl, bucket, key}
    42  		gen fsnode.ChildrenGenerator
    43  	)
    44  	switch node.(type) {
    45  	case fsnode.Parent:
    46  		gen = versionsDirViewGen{q}
    47  	case fsnode.Leaf:
    48  		gen = versionsObjViewGen{q}
    49  	default:
    50  		return nil, errors.E(errors.Precondition, fmt.Sprintf("unrecognized node: %T", node))
    51  	}
    52  	return []fsnode.T{
    53  		fsnode.NewParent(
    54  			fsnode.NewDirInfo("versions").WithCacheableFor(fsnode.CacheableFor(node)),
    55  			gen,
    56  		),
    57  	}, nil
    58  }