package shell import ( "context" "io" files "github.com/ipfs/go-ipfs-files" ) type FilesOpt func(*RequestBuilder) error type MfsLsEntry struct { Name string Type uint8 Size uint64 Hash string } type FilesStatObject struct { Blocks int CumulativeSize uint64 Hash string Local bool Size uint64 SizeLocal uint64 Type string WithLocality bool } type filesLsOutput struct { Entries []*MfsLsEntry } type filesFlushOutput struct { Cid string } type filesLs struct{} type filesChcid struct{} type filesMkdir struct{} type filesRead struct{} type filesWrite struct{} type filesStat struct{} var ( FilesLs filesLs FilesChcid filesChcid FilesMkdir filesMkdir FilesRead filesRead FilesWrite filesWrite FilesStat filesStat ) // Stat use long listing format func (filesLs) Stat(long bool) FilesOpt { return func(rb *RequestBuilder) error { rb.Option("long", long) return nil } } // CidVersion cid version to use. (experimental) func (filesChcid) CidVersion(version int) FilesOpt { return func(rb *RequestBuilder) error { rb.Option("cid-version", version) return nil } } // Hash hash function to use. Will set Cid version to 1 if used. (experimental) func (filesChcid) Hash(hash string) FilesOpt { return func(rb *RequestBuilder) error { rb.Option("hash", hash) return nil } } // Parents no error if existing, make parent directories as needed func (filesMkdir) Parents(parents bool) FilesOpt { return func(rb *RequestBuilder) error { rb.Option("parents", parents) return nil } } // CidVersion cid version to use. (experimental) func (filesMkdir) CidVersion(version int) FilesOpt { return func(rb *RequestBuilder) error { rb.Option("cid-version", version) return nil } } // Hash hash function to use. Will set Cid version to 1 if used. (experimental) func (filesMkdir) Hash(hash string) FilesOpt { return func(rb *RequestBuilder) error { rb.Option("hash", hash) return nil } } // Offset byte offset to begin reading from func (filesRead) Offset(offset int64) FilesOpt { return func(rb *RequestBuilder) error { rb.Option("offset", offset) return nil } } // Count maximum number of bytes to read func (filesRead) Count(count int64) FilesOpt { return func(rb *RequestBuilder) error { rb.Option("count", count) return nil } } // Hash print only hash. Implies '--format='. Conflicts with other format options. func (filesStat) Hash(hash bool) FilesOpt { return func(rb *RequestBuilder) error { rb.Option("hash", hash) return nil } } // Size print only size. Implies '--format='. Conflicts with other format options. func (filesStat) Size(size bool) FilesOpt { return func(rb *RequestBuilder) error { rb.Option("size", size) return nil } } // WithLocal compute the amount of the dag that is local, and if possible the total size. func (filesStat) WithLocal(withLocal bool) FilesOpt { return func(rb *RequestBuilder) error { rb.Option("with-local", withLocal) return nil } } // Offset byte offset to begin writing at func (filesWrite) Offset(offset int64) FilesOpt { return func(rb *RequestBuilder) error { rb.Option("offset", offset) return nil } } // Create create the file if it does not exist func (filesWrite) Create(create bool) FilesOpt { return func(rb *RequestBuilder) error { rb.Option("create", create) return nil } } // Parents make parent directories as needed func (filesWrite) Parents(parents bool) FilesOpt { return func(rb *RequestBuilder) error { rb.Option("parents", parents) return nil } } // Truncate truncate the file to size zero before writing func (filesWrite) Truncate(truncate bool) FilesOpt { return func(rb *RequestBuilder) error { rb.Option("truncate", truncate) return nil } } // Count maximum number of bytes to write func (filesWrite) Count(count int64) FilesOpt { return func(rb *RequestBuilder) error { rb.Option("count", count) return nil } } // RawLeaves use raw blocks for newly created leaf nodes. (experimental) func (filesWrite) RawLeaves(rawLeaves bool) FilesOpt { return func(rb *RequestBuilder) error { rb.Option("raw-leaves", rawLeaves) return nil } } // CidVersion cid version to use. (experimental) func (filesWrite) CidVersion(version int) FilesOpt { return func(rb *RequestBuilder) error { rb.Option("cid-version", version) return nil } } // Hash hash function to use. Will set Cid version to 1 if used. (experimental) func (filesWrite) Hash(hash string) FilesOpt { return func(rb *RequestBuilder) error { rb.Option("hash", hash) return nil } } // FilesChcid change the cid version or hash function of the root node of a given path func (s *Shell) FilesChcid(ctx context.Context, path string, options ...FilesOpt) error { if len(path) == 0 { path = "/" } rb := s.Request("files/chcid", path) for _, opt := range options { if err := opt(rb); err != nil { return err } } return rb.Exec(ctx, nil) } // FilesCp copy any IPFS files and directories into MFS (or copy within MFS) func (s *Shell) FilesCp(ctx context.Context, src string, dest string) error { return s.Request("files/cp", src, dest).Exec(ctx, nil) } // FilesFlush flush a given path's data to disk func (s *Shell) FilesFlush(ctx context.Context, path string) (string, error) { if len(path) == 0 { path = "/" } out := &filesFlushOutput{} if err := s.Request("files/flush", path). Exec(ctx, out); err != nil { return "", err } return out.Cid, nil } // FilesLs list directories in the local mutable namespace func (s *Shell) FilesLs(ctx context.Context, path string, options ...FilesOpt) ([]*MfsLsEntry, error) { if len(path) == 0 { path = "/" } var out filesLsOutput rb := s.Request("files/ls", path) for _, opt := range options { if err := opt(rb); err != nil { return nil, err } } if err := rb.Exec(ctx, &out); err != nil { return nil, err } return out.Entries, nil } // FilesMkdir make directories func (s *Shell) FilesMkdir(ctx context.Context, path string, options ...FilesOpt) error { rb := s.Request("files/mkdir", path) for _, opt := range options { if err := opt(rb); err != nil { return err } } return rb.Exec(ctx, nil) } // FilesMv move files func (s *Shell) FilesMv(ctx context.Context, src string, dest string) error { return s.Request("files/mv", src, dest).Exec(ctx, nil) } // FilesRead read a file in a given MFS func (s *Shell) FilesRead(ctx context.Context, path string, options ...FilesOpt) (io.ReadCloser, error) { rb := s.Request("files/read", path) for _, opt := range options { if err := opt(rb); err != nil { return nil, err } } resp, err := rb.Send(ctx) if err != nil { return nil, err } if resp.Error != nil { return nil, resp.Error } return resp.Output, nil } // FilesRm remove a file func (s *Shell) FilesRm(ctx context.Context, path string, force bool) error { return s.Request("files/rm", path). Option("force", force). Exec(ctx, nil) } // FilesStat display file status func (s *Shell) FilesStat(ctx context.Context, path string, options ...FilesOpt) (*FilesStatObject, error) { out := &FilesStatObject{} rb := s.Request("files/stat", path) for _, opt := range options { if err := opt(rb); err != nil { return nil, err } } if err := rb.Exec(ctx, out); err != nil { return nil, err } return out, nil } // FilesWrite write to a mutable file in a given filesystem func (s *Shell) FilesWrite(ctx context.Context, path string, data io.Reader, options ...FilesOpt) error { fr := files.NewReaderFile(data) slf := files.NewSliceDirectory([]files.DirEntry{files.FileEntry("", fr)}) fileReader := files.NewMultiFileReader(slf, true) rb := s.Request("files/write", path) for _, opt := range options { if err := opt(rb); err != nil { return err } } return rb.Body(fileReader).Exec(ctx, nil) }