github.com/qri-io/qri@v0.10.1-0.20220104210721-c771715036cb/repo/repo.go (about)

     1  // Package repo represents a repository of qri information
     2  // Analogous to a git repository, repo expects a rigid structure
     3  // filled with rich types specific to qri.
     4  package repo
     5  
     6  import (
     7  	"fmt"
     8  
     9  	golog "github.com/ipfs/go-log"
    10  	"github.com/qri-io/qfs"
    11  	"github.com/qri-io/qfs/muxfs"
    12  	"github.com/qri-io/qri/dscache"
    13  	"github.com/qri-io/qri/dsref"
    14  	"github.com/qri-io/qri/event"
    15  	"github.com/qri-io/qri/logbook"
    16  	"github.com/qri-io/qri/profile"
    17  	reporef "github.com/qri-io/qri/repo/ref"
    18  )
    19  
    20  var (
    21  	log = golog.Logger("repo")
    22  	// DefaultQriLocation is where qri data defaults to storing. The keyword $HOME
    23  	// (and only $HOME) will be replaced with the current user home directory
    24  	DefaultQriLocation = "$HOME/.qri"
    25  
    26  	// ErrNotFound is the err implementers should return when stuff isn't found
    27  	ErrNotFound = fmt.Errorf("repo: not found")
    28  	// ErrNoHistory is the err implementers should return when no versions exist in history
    29  	ErrNoHistory = fmt.Errorf("repo: no history")
    30  	// ErrPeerIDRequired is for when a peerID is missing-but-expected
    31  	ErrPeerIDRequired = fmt.Errorf("repo: peerID is required")
    32  	// ErrPeernameRequired is for when a peername is missing-but-expected
    33  	ErrPeernameRequired = fmt.Errorf("repo: peername is required")
    34  	// ErrNoRepo is for when a repo is missing-but-expected
    35  	ErrNoRepo = fmt.Errorf("repo: no repo found")
    36  	// ErrNameRequired is for when a name is missing-but-expected
    37  	ErrNameRequired = fmt.Errorf("repo: name is required")
    38  	// ErrPathRequired is for when a path is missing-but-expected
    39  	ErrPathRequired = fmt.Errorf("repo: path is required")
    40  	// ErrNameTaken is for when a name name is already taken
    41  	ErrNameTaken = fmt.Errorf("repo: name already in use")
    42  	// ErrRepoEmpty is for when the repo has no datasets
    43  	ErrRepoEmpty = fmt.Errorf("repo: this repo contains no datasets")
    44  	// ErrNotPinner is for when the repo doesn't have the concept of pinning as a feature
    45  	ErrNotPinner = fmt.Errorf("repo: backing store doesn't support pinning")
    46  	// ErrNoRegistry indicates no regsitry is currently configured
    47  	ErrNoRegistry = fmt.Errorf("no configured registry")
    48  	// ErrEmptyRef indicates that the given reference is empty
    49  	ErrEmptyRef = fmt.Errorf("repo: empty dataset reference")
    50  )
    51  
    52  // Repo is the interface for working with a qri repository qri repos are stored
    53  // graph of resources:datasets, known peers, analytics data, change requests, etc.
    54  // Repos are connected to a single peer profile.
    55  // Repos must wrap an underlying cafs.Filestore, which
    56  // is intended to act as the canonical store of state across all peers
    57  // that this repo may interact with.
    58  type Repo interface {
    59  	// repos are created with an event bus, and provid an accessor
    60  	Bus() event.Bus
    61  
    62  	// Filesystem is currently a read-only source of Filesystem-like data
    63  	// Filestores can multiplex to read from multiple sources like the local
    64  	// filesystem, over http, or content-addressed filesystems.
    65  	// the long term-plan is to merge Filestore & Store
    66  	Filesystem() *muxfs.Mux
    67  
    68  	// A Repo can resolve dataset references it knows about locally from its
    69  	// Refstore
    70  	// NOTE (b5): this implementation will be dropped when the Refstore interface
    71  	// is removed from the repo, delegating local ref resolution to dscache
    72  	dsref.Resolver
    73  	// All Repos must keep a Refstore, defining a store of known datasets
    74  	// NOTE(dlong): Refstore is going away soon, everything is going to move to Dscache
    75  	Refstore
    76  	// Dscache is a cache of datasets that have been built according to logbook
    77  	Dscache() *dscache.Dscache
    78  
    79  	// Repos have a logbook for recording & storing operation logs
    80  	Logbook() *logbook.Book
    81  
    82  	// A repository must maintain profile information about encountered peers.
    83  	// Decsisions regarding retentaion of peers is left to the the implementation
    84  	Profiles() profile.Store
    85  
    86  	// Done returns a channel that the repo will send on when the repo is closed
    87  	Done() <-chan struct{}
    88  	// DoneErr gives any error that occurred in the shutdown process
    89  	DoneErr() error
    90  }
    91  
    92  // QFSSetter sets a qfs.Filesystem
    93  // the whole interface is a short-term hack that should only need to be
    94  // called in one context: when lib is setting up a Repo
    95  // TODO (b5): either decouple repo & qfs completely, or merge them
    96  type QFSSetter interface {
    97  	SetFilesystem(qfs.Filesystem)
    98  }
    99  
   100  // SearchParams encapsulates parameters provided to Searchable.Search
   101  type SearchParams struct {
   102  	Q             string
   103  	Limit, Offset int
   104  }
   105  
   106  // Searchable is an opt-in interface for supporting repository search
   107  type Searchable interface {
   108  	Search(p SearchParams) ([]reporef.DatasetRef, error)
   109  }