mirror of
https://github.com/ipfs/kubo.git
synced 2026-02-24 11:57:44 +08:00
Merge pull request #5679 from overbool/refactor/commands/refs
commands/refs: use new cmds
This commit is contained in:
commit
98f6b2f684
@ -203,18 +203,8 @@ var dupsFileStore = &cmds.Command{
|
||||
|
||||
return nil
|
||||
},
|
||||
Encoders: cmds.EncoderMap{
|
||||
cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *RefWrapper) error {
|
||||
if out.Err != "" {
|
||||
return fmt.Errorf(out.Err)
|
||||
}
|
||||
|
||||
fmt.Fprintln(w, out.Ref)
|
||||
|
||||
return nil
|
||||
}),
|
||||
},
|
||||
Type: RefWrapper{},
|
||||
Encoders: refsEncoderMap,
|
||||
Type: RefWrapper{},
|
||||
}
|
||||
|
||||
func getFilestore(env cmds.Environment) (*core.IpfsNode, *filestore.Filestore, error) {
|
||||
|
||||
@ -1,22 +1,33 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
cmds "github.com/ipfs/go-ipfs/commands"
|
||||
"github.com/ipfs/go-ipfs/core"
|
||||
e "github.com/ipfs/go-ipfs/core/commands/e"
|
||||
core "github.com/ipfs/go-ipfs/core"
|
||||
cmdenv "github.com/ipfs/go-ipfs/core/commands/cmdenv"
|
||||
|
||||
cid "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid"
|
||||
path "gx/ipfs/QmRG3XuGwT7GYuAqgWDJBKTzdaHMwAnc1x7J2KHEXNHxzG/go-path"
|
||||
cmds "gx/ipfs/Qma6uuSyjkecGhMFFLfzyJDPyoDtNJSHJNweDccZhaWkgU/go-ipfs-cmds"
|
||||
ipld "gx/ipfs/QmcKKBwfz6FyQdHR2jsXrrF6XeSBXYL86anmWNewpFpoF5/go-ipld-format"
|
||||
cmdkit "gx/ipfs/Qmde5VP1qUkyQXKCfmEUA7bP64V2HAptbJ7phuPp7jXWwg/go-ipfs-cmdkit"
|
||||
)
|
||||
|
||||
var refsEncoderMap = cmds.EncoderMap{
|
||||
cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *RefWrapper) error {
|
||||
if out.Err != "" {
|
||||
return fmt.Errorf(out.Err)
|
||||
}
|
||||
fmt.Fprintln(w, out.Ref)
|
||||
|
||||
return nil
|
||||
}),
|
||||
}
|
||||
|
||||
// KeyList is a general type for outputting lists of keys
|
||||
type KeyList struct {
|
||||
Keys []cid.Cid
|
||||
@ -30,25 +41,7 @@ const (
|
||||
refsMaxDepthOptionName = "max-depth"
|
||||
)
|
||||
|
||||
// KeyListTextMarshaler outputs a KeyList as plaintext, one key per line
|
||||
func KeyListTextMarshaler(res cmds.Response) (io.Reader, error) {
|
||||
out, err := unwrapOutput(res.Output())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
output, ok := out.(*KeyList)
|
||||
if !ok {
|
||||
return nil, e.TypeErr(output, out)
|
||||
}
|
||||
|
||||
buf := new(bytes.Buffer)
|
||||
for _, key := range output.Keys {
|
||||
buf.WriteString(key.String() + "\n")
|
||||
}
|
||||
return buf, nil
|
||||
}
|
||||
|
||||
// RefsCmd is the `ipfs refs` command
|
||||
var RefsCmd = &cmds.Command{
|
||||
Helptext: cmdkit.HelpText{
|
||||
Tagline: "List links (references) from an object.",
|
||||
@ -74,91 +67,62 @@ NOTE: List all references recursively by using the flag '-r'.
|
||||
cmdkit.BoolOption(refsRecursiveOptionName, "r", "Recursively list links of child nodes."),
|
||||
cmdkit.IntOption(refsMaxDepthOptionName, "Only for recursive refs, limits fetch and listing to the given depth").WithDefault(-1),
|
||||
},
|
||||
Run: func(req cmds.Request, res cmds.Response) {
|
||||
ctx := req.Context()
|
||||
n, err := req.InvocContext().GetNode()
|
||||
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
|
||||
err := req.ParseBodyArgs()
|
||||
if err != nil {
|
||||
res.SetError(err, cmdkit.ErrNormal)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
unique, _, err := req.Option(refsUniqueOptionName).Bool()
|
||||
ctx := req.Context
|
||||
n, err := cmdenv.GetNode(env)
|
||||
if err != nil {
|
||||
res.SetError(err, cmdkit.ErrNormal)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
recursive, _, err := req.Option(refsRecursiveOptionName).Bool()
|
||||
if err != nil {
|
||||
res.SetError(err, cmdkit.ErrNormal)
|
||||
return
|
||||
}
|
||||
|
||||
maxDepth, _, err := req.Option(refsMaxDepthOptionName).Int()
|
||||
if err != nil {
|
||||
res.SetError(err, cmdkit.ErrNormal)
|
||||
return
|
||||
}
|
||||
unique, _ := req.Options[refsUniqueOptionName].(bool)
|
||||
recursive, _ := req.Options[refsRecursiveOptionName].(bool)
|
||||
maxDepth, _ := req.Options[refsMaxDepthOptionName].(int)
|
||||
edges, _ := req.Options[refsEdgesOptionName].(bool)
|
||||
format, _ := req.Options[refsFormatOptionName].(string)
|
||||
|
||||
if !recursive {
|
||||
maxDepth = 1 // write only direct refs
|
||||
}
|
||||
|
||||
format, _, err := req.Option(refsFormatOptionName).String()
|
||||
if err != nil {
|
||||
res.SetError(err, cmdkit.ErrNormal)
|
||||
return
|
||||
}
|
||||
|
||||
edges, _, err := req.Option(refsEdgesOptionName).Bool()
|
||||
if err != nil {
|
||||
res.SetError(err, cmdkit.ErrNormal)
|
||||
return
|
||||
}
|
||||
if edges {
|
||||
if format != "<dst>" {
|
||||
res.SetError(errors.New("using format argument with edges is not allowed"),
|
||||
cmdkit.ErrClient)
|
||||
return
|
||||
return errors.New("using format argument with edges is not allowed")
|
||||
}
|
||||
|
||||
format = "<src> -> <dst>"
|
||||
}
|
||||
|
||||
objs, err := objectsForPaths(ctx, n, req.Arguments())
|
||||
objs, err := objectsForPaths(ctx, n, req.Arguments)
|
||||
if err != nil {
|
||||
res.SetError(err, cmdkit.ErrNormal)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
out := make(chan interface{})
|
||||
res.SetOutput((<-chan interface{})(out))
|
||||
rw := RefWriter{
|
||||
res: res,
|
||||
DAG: n.DAG,
|
||||
Ctx: ctx,
|
||||
Unique: unique,
|
||||
PrintFmt: format,
|
||||
MaxDepth: maxDepth,
|
||||
}
|
||||
|
||||
go func() {
|
||||
defer close(out)
|
||||
|
||||
rw := RefWriter{
|
||||
out: out,
|
||||
DAG: n.DAG,
|
||||
Ctx: ctx,
|
||||
Unique: unique,
|
||||
PrintFmt: format,
|
||||
MaxDepth: maxDepth,
|
||||
}
|
||||
|
||||
for _, o := range objs {
|
||||
if _, err := rw.WriteRefs(o); err != nil {
|
||||
select {
|
||||
case out <- &RefWrapper{Err: err.Error()}:
|
||||
case <-ctx.Done():
|
||||
}
|
||||
return
|
||||
for _, o := range objs {
|
||||
if _, err := rw.WriteRefs(o); err != nil {
|
||||
if err := res.Emit(&RefWrapper{Err: err.Error()}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
Marshalers: refsMarshallerMap,
|
||||
Type: RefWrapper{},
|
||||
Encoders: refsEncoderMap,
|
||||
Type: RefWrapper{},
|
||||
}
|
||||
|
||||
var RefsLocalCmd = &cmds.Command{
|
||||
@ -169,58 +133,30 @@ Displays the hashes of all local objects.
|
||||
`,
|
||||
},
|
||||
|
||||
Run: func(req cmds.Request, res cmds.Response) {
|
||||
ctx := req.Context()
|
||||
n, err := req.InvocContext().GetNode()
|
||||
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
|
||||
ctx := req.Context
|
||||
n, err := cmdenv.GetNode(env)
|
||||
if err != nil {
|
||||
res.SetError(err, cmdkit.ErrNormal)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
// todo: make async
|
||||
allKeys, err := n.Blockstore.AllKeysChan(ctx)
|
||||
if err != nil {
|
||||
res.SetError(err, cmdkit.ErrNormal)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
out := make(chan interface{})
|
||||
res.SetOutput((<-chan interface{})(out))
|
||||
|
||||
go func() {
|
||||
defer close(out)
|
||||
|
||||
for k := range allKeys {
|
||||
select {
|
||||
case out <- &RefWrapper{Ref: k.String()}:
|
||||
case <-req.Context().Done():
|
||||
return
|
||||
}
|
||||
for k := range allKeys {
|
||||
err := res.Emit(&RefWrapper{Ref: k.String()})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}()
|
||||
},
|
||||
Marshalers: refsMarshallerMap,
|
||||
Type: RefWrapper{},
|
||||
}
|
||||
|
||||
var refsMarshallerMap = cmds.MarshalerMap{
|
||||
cmds.Text: func(res cmds.Response) (io.Reader, error) {
|
||||
v, err := unwrapOutput(res.Output())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
obj, ok := v.(*RefWrapper)
|
||||
if !ok {
|
||||
return nil, e.TypeErr(obj, v)
|
||||
}
|
||||
|
||||
if obj.Err != "" {
|
||||
return nil, errors.New(obj.Err)
|
||||
}
|
||||
|
||||
return strings.NewReader(obj.Ref + "\n"), nil
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
Encoders: refsEncoderMap,
|
||||
Type: RefWrapper{},
|
||||
}
|
||||
|
||||
func objectsForPaths(ctx context.Context, n *core.IpfsNode, paths []string) ([]ipld.Node, error) {
|
||||
@ -246,7 +182,7 @@ type RefWrapper struct {
|
||||
}
|
||||
|
||||
type RefWriter struct {
|
||||
out chan interface{}
|
||||
res cmds.ResponseEmitter
|
||||
DAG ipld.DAGService
|
||||
Ctx context.Context
|
||||
|
||||
@ -260,7 +196,6 @@ type RefWriter struct {
|
||||
// WriteRefs writes refs of the given object to the underlying writer.
|
||||
func (rw *RefWriter) WriteRefs(n ipld.Node) (int, error) {
|
||||
return rw.writeRefsRecursive(n, 0)
|
||||
|
||||
}
|
||||
|
||||
func (rw *RefWriter) writeRefsRecursive(n ipld.Node, depth int) (int, error) {
|
||||
@ -394,6 +329,5 @@ func (rw *RefWriter) WriteEdge(from, to cid.Cid, linkname string) error {
|
||||
s += to.String()
|
||||
}
|
||||
|
||||
rw.out <- &RefWrapper{Ref: s}
|
||||
return nil
|
||||
return rw.res.Emit(&RefWrapper{Ref: s})
|
||||
}
|
||||
|
||||
@ -138,7 +138,7 @@ var rootSubcommands = map[string]*cmds.Command{
|
||||
"pin": PinCmd,
|
||||
"ping": PingCmd,
|
||||
"p2p": P2PCmd,
|
||||
"refs": lgc.NewCommand(RefsCmd),
|
||||
"refs": RefsCmd,
|
||||
"resolve": ResolveCmd,
|
||||
"swarm": SwarmCmd,
|
||||
"tar": TarCmd,
|
||||
@ -155,7 +155,8 @@ var RootRO = &cmds.Command{}
|
||||
|
||||
var CommandsDaemonROCmd = CommandsCmd(RootRO)
|
||||
|
||||
var RefsROCmd = &oldcmds.Command{}
|
||||
// RefsROCmd is `ipfs refs` command
|
||||
var RefsROCmd = &cmds.Command{}
|
||||
|
||||
var rootROSubcommands = map[string]*cmds.Command{
|
||||
"commands": CommandsDaemonROCmd,
|
||||
@ -198,12 +199,12 @@ func init() {
|
||||
|
||||
// sanitize readonly refs command
|
||||
*RefsROCmd = *RefsCmd
|
||||
RefsROCmd.Subcommands = map[string]*oldcmds.Command{}
|
||||
RefsROCmd.Subcommands = map[string]*cmds.Command{}
|
||||
|
||||
// this was in the big map definition above before,
|
||||
// but if we leave it there lgc.NewCommand will be executed
|
||||
// before the value is updated (:/sanitize readonly refs command/)
|
||||
rootROSubcommands["refs"] = lgc.NewCommand(RefsROCmd)
|
||||
rootROSubcommands["refs"] = RefsROCmd
|
||||
|
||||
Root.Subcommands = rootSubcommands
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user