提交 6fc049b5 作者: Overbool 提交者: Steven Allen

commands/pin: use new cmds lib

License: MIT
Signed-off-by: 's avatarOverbool <overbool.xu@gmail.com>
上级 901e9fb9
package commands package commands
import ( import (
"bytes"
"context" "context"
"fmt" "fmt"
"io" "io"
"time" "time"
cmds "github.com/ipfs/go-ipfs/commands"
core "github.com/ipfs/go-ipfs/core" core "github.com/ipfs/go-ipfs/core"
e "github.com/ipfs/go-ipfs/core/commands/e" cmdenv "github.com/ipfs/go-ipfs/core/commands/cmdenv"
iface "github.com/ipfs/go-ipfs/core/coreapi/interface" iface "github.com/ipfs/go-ipfs/core/coreapi/interface"
options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" options "github.com/ipfs/go-ipfs/core/coreapi/interface/options"
corerepo "github.com/ipfs/go-ipfs/core/corerepo" corerepo "github.com/ipfs/go-ipfs/core/corerepo"
pin "github.com/ipfs/go-ipfs/pin" pin "github.com/ipfs/go-ipfs/pin"
cmds "gx/ipfs/QmSXUokcP4TJpFfqozT69AVAYRtzXVMUjzQVkYX41R9Svs/go-ipfs-cmds"
offline "gx/ipfs/QmPpnbwgAuvhUkA9jGooR88ZwZtTUHXXvoQNKdjZC6nYku/go-ipfs-exchange-offline" offline "gx/ipfs/QmPpnbwgAuvhUkA9jGooR88ZwZtTUHXXvoQNKdjZC6nYku/go-ipfs-exchange-offline"
cid "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid" cid "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid"
bserv "gx/ipfs/QmVPeMNK9DfGLXDZzs2W4RoFWC9Zq1EnLGmLXtYtWrNdcW/go-blockservice" bserv "gx/ipfs/QmVPeMNK9DfGLXDZzs2W4RoFWC9Zq1EnLGmLXtYtWrNdcW/go-blockservice"
...@@ -65,43 +64,36 @@ var addPinCmd = &cmds.Command{ ...@@ -65,43 +64,36 @@ var addPinCmd = &cmds.Command{
cmdkit.BoolOption(pinProgressOptionName, "Show progress"), cmdkit.BoolOption(pinProgressOptionName, "Show progress"),
}, },
Type: AddPinOutput{}, Type: AddPinOutput{},
Run: func(req cmds.Request, res cmds.Response) { Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
n, err := req.InvocContext().GetNode() n, err := cmdenv.GetNode(env)
if err != nil { if err != nil {
res.SetError(err, cmdkit.ErrNormal) return err
return
} }
api, err := req.InvocContext().GetApi() api, err := cmdenv.GetApi(env)
if err != nil { if err != nil {
res.SetError(err, cmdkit.ErrNormal) return err
return
} }
defer n.Blockstore.PinLock().Unlock() defer n.Blockstore.PinLock().Unlock()
// set recursive flag // set recursive flag
recursive, _, err := req.Option(pinRecursiveOptionName).Bool() recursive, _ := req.Options[pinRecursiveOptionName].(bool)
if err != nil { showProgress, _ := req.Options[pinProgressOptionName].(bool)
res.SetError(err, cmdkit.ErrNormal)
return
}
showProgress, _, _ := req.Option(pinProgressOptionName).Bool()
if !showProgress { if !showProgress {
added, err := corerepo.Pin(n, api, req.Context(), req.Arguments(), recursive) added, err := corerepo.Pin(n, api, req.Context, req.Arguments, recursive)
if err != nil { if err != nil {
res.SetError(err, cmdkit.ErrNormal) return err
return
} }
res.SetOutput(&AddPinOutput{Pins: cidsToStrings(added)}) return res.Emit(&AddPinOutput{Pins: cidsToStrings(added)})
return
} }
out := make(chan interface{}) out := make(chan interface{})
res.SetOutput((<-chan interface{})(out)) res.Emit(out)
v := new(dag.ProgressTracker) v := new(dag.ProgressTracker)
ctx := v.DeriveContext(req.Context()) ctx := v.DeriveContext(req.Context)
type pinResult struct { type pinResult struct {
pins []cid.Cid pins []cid.Cid
...@@ -109,7 +101,7 @@ var addPinCmd = &cmds.Command{ ...@@ -109,7 +101,7 @@ var addPinCmd = &cmds.Command{
} }
ch := make(chan pinResult, 1) ch := make(chan pinResult, 1)
go func() { go func() {
added, err := corerepo.Pin(n, api, ctx, req.Arguments(), recursive) added, err := corerepo.Pin(n, api, ctx, req.Arguments, recursive)
ch <- pinResult{pins: added, err: err} ch <- pinResult{pins: added, err: err}
}() }()
...@@ -120,63 +112,49 @@ var addPinCmd = &cmds.Command{ ...@@ -120,63 +112,49 @@ var addPinCmd = &cmds.Command{
select { select {
case val := <-ch: case val := <-ch:
if val.err != nil { if val.err != nil {
res.SetError(val.err, cmdkit.ErrNormal) return val.err
return
} }
if pv := v.Value(); pv != 0 { if pv := v.Value(); pv != 0 {
out <- &AddPinOutput{Progress: v.Value()} out <- &AddPinOutput{Progress: v.Value()}
} }
out <- &AddPinOutput{Pins: cidsToStrings(val.pins)} out <- &AddPinOutput{Pins: cidsToStrings(val.pins)}
return return nil
case <-ticker.C: case <-ticker.C:
out <- &AddPinOutput{Progress: v.Value()} out <- &AddPinOutput{Progress: v.Value()}
case <-ctx.Done(): case <-ctx.Done():
log.Error(ctx.Err()) log.Error(ctx.Err())
res.SetError(ctx.Err(), cmdkit.ErrNormal) return ctx.Err()
return
} }
} }
},
Marshalers: cmds.MarshalerMap{
cmds.Text: func(res cmds.Response) (io.Reader, error) {
v, err := unwrapOutput(res.Output())
if err != nil {
return nil, err
}
return nil
},
Encoders: cmds.EncoderMap{
cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *AddPinOutput) error {
var added []string var added []string
switch out := v.(type) { if out.Pins != nil {
case *AddPinOutput: added = out.Pins
if out.Pins != nil { } else {
added = out.Pins // this can only happen if the progress option is set
} else { return fmt.Errorf("Fetched/Processed %d nodes\r", out.Progress)
// this can only happen if the progress option is set
fmt.Fprintf(res.Stderr(), "Fetched/Processed %d nodes\r", out.Progress)
}
if res.Error() != nil {
return nil, res.Error()
}
default:
return nil, e.TypeErr(out, v)
} }
var pintype string var pintype string
rec, found, _ := res.Request().Option("recursive").Bool() rec, found := req.Options["recursive"].(bool)
if rec || !found { if rec || !found {
pintype = "recursively" pintype = "recursively"
} else { } else {
pintype = "directly" pintype = "directly"
} }
buf := new(bytes.Buffer)
for _, k := range added { for _, k := range added {
fmt.Fprintf(buf, "pinned %s %s\n", k, pintype) fmt.Fprintf(w, "pinned %s %s\n", k, pintype)
} }
return buf, nil
}, return nil
}),
}, },
} }
...@@ -196,52 +174,34 @@ collected if needed. (By default, recursively. Use -r=false for direct pins.) ...@@ -196,52 +174,34 @@ collected if needed. (By default, recursively. Use -r=false for direct pins.)
cmdkit.BoolOption(pinRecursiveOptionName, "r", "Recursively unpin the object linked to by the specified object(s).").WithDefault(true), cmdkit.BoolOption(pinRecursiveOptionName, "r", "Recursively unpin the object linked to by the specified object(s).").WithDefault(true),
}, },
Type: PinOutput{}, Type: PinOutput{},
Run: func(req cmds.Request, res cmds.Response) { Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
n, err := req.InvocContext().GetNode() n, err := cmdenv.GetNode(env)
if err != nil { if err != nil {
res.SetError(err, cmdkit.ErrNormal) return err
return
} }
api, err := req.InvocContext().GetApi() api, err := cmdenv.GetApi(env)
if err != nil { if err != nil {
res.SetError(err, cmdkit.ErrNormal) return err
return
} }
// set recursive flag // set recursive flag
recursive, _, err := req.Option(pinRecursiveOptionName).Bool() recursive, _ := req.Options[pinRecursiveOptionName].(bool)
if err != nil {
res.SetError(err, cmdkit.ErrNormal)
return
}
removed, err := corerepo.Unpin(n, api, req.Context(), req.Arguments(), recursive) removed, err := corerepo.Unpin(n, api, req.Context, req.Arguments, recursive)
if err != nil { if err != nil {
res.SetError(err, cmdkit.ErrNormal) return err
return
} }
res.SetOutput(&PinOutput{cidsToStrings(removed)}) return res.Emit(&PinOutput{cidsToStrings(removed)})
}, },
Marshalers: cmds.MarshalerMap{ Encoders: cmds.EncoderMap{
cmds.Text: func(res cmds.Response) (io.Reader, error) { cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *PinOutput) error {
v, err := unwrapOutput(res.Output()) for _, k := range out.Pins {
if err != nil { fmt.Fprintf(w, "unpinned %s\n", k)
return nil, err
}
added, ok := v.(*PinOutput)
if !ok {
return nil, e.TypeErr(added, v)
}
buf := new(bytes.Buffer)
for _, k := range added.Pins {
fmt.Fprintf(buf, "unpinned %s\n", k)
} }
return buf, nil return nil
}, }),
}, },
} }
...@@ -301,74 +261,58 @@ Example: ...@@ -301,74 +261,58 @@ Example:
cmdkit.StringOption(pinTypeOptionName, "t", "The type of pinned keys to list. Can be \"direct\", \"indirect\", \"recursive\", or \"all\".").WithDefault("all"), cmdkit.StringOption(pinTypeOptionName, "t", "The type of pinned keys to list. Can be \"direct\", \"indirect\", \"recursive\", or \"all\".").WithDefault("all"),
cmdkit.BoolOption(pinQuietOptionName, "q", "Write just hashes of objects."), cmdkit.BoolOption(pinQuietOptionName, "q", "Write just hashes of objects."),
}, },
Run: func(req cmds.Request, res cmds.Response) { Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
n, err := req.InvocContext().GetNode() n, err := cmdenv.GetNode(env)
if err != nil { if err != nil {
res.SetError(err, cmdkit.ErrNormal) return err
return
} }
api, err := req.InvocContext().GetApi() api, err := cmdenv.GetApi(env)
if err != nil { if err != nil {
res.SetError(err, cmdkit.ErrNormal) return err
return
} }
typeStr, _, err := req.Option(pinTypeOptionName).String() typeStr, _ := req.Options[pinTypeOptionName].(string)
if err != nil { if err != nil {
res.SetError(err, cmdkit.ErrNormal) return err
return
} }
switch typeStr { switch typeStr {
case "all", "direct", "indirect", "recursive": case "all", "direct", "indirect", "recursive":
default: default:
err = fmt.Errorf("invalid type '%s', must be one of {direct, indirect, recursive, all}", typeStr) err = fmt.Errorf("invalid type '%s', must be one of {direct, indirect, recursive, all}", typeStr)
res.SetError(err, cmdkit.ErrClient) return err
return
} }
var keys map[string]RefKeyObject var keys map[string]RefKeyObject
if len(req.Arguments()) > 0 { if len(req.Arguments) > 0 {
keys, err = pinLsKeys(req.Context(), req.Arguments(), typeStr, n, api) keys, err = pinLsKeys(req.Context, req.Arguments, typeStr, n, api)
} else { } else {
keys, err = pinLsAll(req.Context(), typeStr, n) keys, err = pinLsAll(req.Context, typeStr, n)
} }
if err != nil { if err != nil {
res.SetError(err, cmdkit.ErrNormal) return err
} else { } else {
res.SetOutput(&RefKeyList{Keys: keys}) return res.Emit(&RefKeyList{Keys: keys})
} }
}, },
Type: RefKeyList{}, Type: RefKeyList{},
Marshalers: cmds.MarshalerMap{ Encoders: cmds.EncoderMap{
cmds.Text: func(res cmds.Response) (io.Reader, error) { cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *RefKeyList) error {
v, err := unwrapOutput(res.Output()) quiet, _ := req.Options[pinQuietOptionName].(bool)
if err != nil {
return nil, err
}
quiet, _, err := res.Request().Option(pinQuietOptionName).Bool() for k, v := range out.Keys {
if err != nil {
return nil, err
}
keys, ok := v.(*RefKeyList)
if !ok {
return nil, e.TypeErr(keys, v)
}
out := new(bytes.Buffer)
for k, v := range keys.Keys {
if quiet { if quiet {
fmt.Fprintf(out, "%s\n", k) fmt.Fprintf(w, "%s\n", k)
} else { } else {
fmt.Fprintf(out, "%s %s\n", k, v.Type) fmt.Fprintf(w, "%s %s\n", k, v.Type)
} }
} }
return out, nil
}, return nil
}),
}, },
} }
...@@ -394,54 +338,36 @@ new pin and removing the old one. ...@@ -394,54 +338,36 @@ new pin and removing the old one.
cmdkit.BoolOption(pinUnpinOptionName, "Remove the old pin.").WithDefault(true), cmdkit.BoolOption(pinUnpinOptionName, "Remove the old pin.").WithDefault(true),
}, },
Type: PinOutput{}, Type: PinOutput{},
Run: func(req cmds.Request, res cmds.Response) { Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
api, err := req.InvocContext().GetApi() api, err := cmdenv.GetApi(env)
if err != nil { if err != nil {
res.SetError(err, cmdkit.ErrNormal) return err
return
} }
unpin, _, err := req.Option(pinUnpinOptionName).Bool() unpin, _ := req.Options[pinUnpinOptionName].(bool)
if err != nil {
res.SetError(err, cmdkit.ErrNormal)
return
}
from, err := iface.ParsePath(req.Arguments()[0]) from, err := iface.ParsePath(req.Arguments[0])
if err != nil { if err != nil {
res.SetError(err, cmdkit.ErrNormal) return err
return
} }
to, err := iface.ParsePath(req.Arguments()[1]) to, err := iface.ParsePath(req.Arguments[1])
if err != nil { if err != nil {
res.SetError(err, cmdkit.ErrNormal) return err
return
} }
err = api.Pin().Update(req.Context(), from, to, options.Pin.Unpin(unpin)) err = api.Pin().Update(req.Context, from, to, options.Pin.Unpin(unpin))
if err != nil { if err != nil {
res.SetError(err, cmdkit.ErrNormal) return err
return
} }
res.SetOutput(&PinOutput{Pins: []string{from.String(), to.String()}}) return res.Emit(&PinOutput{Pins: []string{from.String(), to.String()}})
}, },
Marshalers: cmds.MarshalerMap{ Encoders: cmds.EncoderMap{
cmds.Text: func(res cmds.Response) (io.Reader, error) { cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *PinOutput) error {
v, err := unwrapOutput(res.Output()) fmt.Fprintf(w, "updated %s to %s\n", out.Pins[0], out.Pins[1])
if err != nil { return nil
return nil, err }),
}
added, ok := v.(*PinOutput)
if !ok {
return nil, e.TypeErr(added, v)
}
buf := new(bytes.Buffer)
fmt.Fprintf(buf, "updated %s to %s\n", added.Pins[0], added.Pins[1])
return buf, nil
},
}, },
} }
...@@ -457,51 +383,40 @@ var verifyPinCmd = &cmds.Command{ ...@@ -457,51 +383,40 @@ var verifyPinCmd = &cmds.Command{
cmdkit.BoolOption(pinVerboseOptionName, "Also write the hashes of non-broken pins."), cmdkit.BoolOption(pinVerboseOptionName, "Also write the hashes of non-broken pins."),
cmdkit.BoolOption(pinQuietOptionName, "q", "Write just hashes of broken pins."), cmdkit.BoolOption(pinQuietOptionName, "q", "Write just hashes of broken pins."),
}, },
Run: func(req cmds.Request, res cmds.Response) { Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
n, err := req.InvocContext().GetNode() n, err := cmdenv.GetNode(env)
if err != nil { if err != nil {
res.SetError(err, cmdkit.ErrNormal) return err
return
} }
verbose, _, _ := res.Request().Option(pinVerboseOptionName).Bool() verbose, _ := req.Options[pinVerboseOptionName].(bool)
quiet, _, _ := res.Request().Option(pinQuietOptionName).Bool() quiet, _ := req.Options[pinQuietOptionName].(bool)
if verbose && quiet { if verbose && quiet {
res.SetError(fmt.Errorf("the --verbose and --quiet options can not be used at the same time"), cmdkit.ErrNormal) return fmt.Errorf("the --verbose and --quiet options can not be used at the same time")
} }
opts := pinVerifyOpts{ opts := pinVerifyOpts{
explain: !quiet, explain: !quiet,
includeOk: verbose, includeOk: verbose,
} }
out := pinVerify(req.Context(), n, opts) out := pinVerify(req.Context, n, opts)
res.SetOutput(out) return res.Emit(out)
}, },
Type: PinVerifyRes{}, Type: PinVerifyRes{},
Marshalers: cmds.MarshalerMap{ Encoders: cmds.EncoderMap{
cmds.Text: func(res cmds.Response) (io.Reader, error) { cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *PinVerifyRes) error {
quiet, _, _ := res.Request().Option(pinQuietOptionName).Bool() quiet, _ := req.Options[pinQuietOptionName].(bool)
out, err := unwrapOutput(res.Output())
if err != nil {
return nil, err
}
r, ok := out.(*PinVerifyRes)
if !ok {
return nil, e.TypeErr(r, out)
}
buf := &bytes.Buffer{} if quiet && !out.Ok {
if quiet && !r.Ok { fmt.Fprintf(w, "%s\n", out.Cid)
fmt.Fprintf(buf, "%s\n", r.Cid)
} else if !quiet { } else if !quiet {
r.Format(buf) out.Format(w)
} }
return buf, nil return nil
}, }),
}, },
} }
......
...@@ -135,7 +135,7 @@ var rootSubcommands = map[string]*cmds.Command{ ...@@ -135,7 +135,7 @@ var rootSubcommands = map[string]*cmds.Command{
"mount": MountCmd, "mount": MountCmd,
"name": name.NameCmd, "name": name.NameCmd,
"object": ocmd.ObjectCmd, "object": ocmd.ObjectCmd,
"pin": lgc.NewCommand(PinCmd), "pin": PinCmd,
"ping": PingCmd, "ping": PingCmd,
"p2p": P2PCmd, "p2p": P2PCmd,
"refs": lgc.NewCommand(RefsCmd), "refs": lgc.NewCommand(RefsCmd),
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论