commands/pin: use new cmds lib

License: MIT
Signed-off-by: Overbool <overbool.xu@gmail.com>
This commit is contained in:
Overbool 2018-10-27 12:26:17 +08:00 committed by Steven Allen
parent 901e9fb955
commit 6fc049b59f
2 changed files with 105 additions and 190 deletions

View File

@ -1,20 +1,19 @@
package commands
import (
"bytes"
"context"
"fmt"
"io"
"time"
cmds "github.com/ipfs/go-ipfs/commands"
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"
options "github.com/ipfs/go-ipfs/core/coreapi/interface/options"
corerepo "github.com/ipfs/go-ipfs/core/corerepo"
pin "github.com/ipfs/go-ipfs/pin"
cmds "gx/ipfs/QmSXUokcP4TJpFfqozT69AVAYRtzXVMUjzQVkYX41R9Svs/go-ipfs-cmds"
offline "gx/ipfs/QmPpnbwgAuvhUkA9jGooR88ZwZtTUHXXvoQNKdjZC6nYku/go-ipfs-exchange-offline"
cid "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid"
bserv "gx/ipfs/QmVPeMNK9DfGLXDZzs2W4RoFWC9Zq1EnLGmLXtYtWrNdcW/go-blockservice"
@ -65,43 +64,36 @@ var addPinCmd = &cmds.Command{
cmdkit.BoolOption(pinProgressOptionName, "Show progress"),
},
Type: AddPinOutput{},
Run: func(req cmds.Request, res cmds.Response) {
n, err := req.InvocContext().GetNode()
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
n, err := cmdenv.GetNode(env)
if err != nil {
res.SetError(err, cmdkit.ErrNormal)
return
return err
}
api, err := req.InvocContext().GetApi()
api, err := cmdenv.GetApi(env)
if err != nil {
res.SetError(err, cmdkit.ErrNormal)
return
return err
}
defer n.Blockstore.PinLock().Unlock()
// set recursive flag
recursive, _, err := req.Option(pinRecursiveOptionName).Bool()
if err != nil {
res.SetError(err, cmdkit.ErrNormal)
return
}
showProgress, _, _ := req.Option(pinProgressOptionName).Bool()
recursive, _ := req.Options[pinRecursiveOptionName].(bool)
showProgress, _ := req.Options[pinProgressOptionName].(bool)
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 {
res.SetError(err, cmdkit.ErrNormal)
return
return err
}
res.SetOutput(&AddPinOutput{Pins: cidsToStrings(added)})
return
return res.Emit(&AddPinOutput{Pins: cidsToStrings(added)})
}
out := make(chan interface{})
res.SetOutput((<-chan interface{})(out))
res.Emit(out)
v := new(dag.ProgressTracker)
ctx := v.DeriveContext(req.Context())
ctx := v.DeriveContext(req.Context)
type pinResult struct {
pins []cid.Cid
@ -109,7 +101,7 @@ var addPinCmd = &cmds.Command{
}
ch := make(chan pinResult, 1)
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}
}()
@ -120,63 +112,49 @@ var addPinCmd = &cmds.Command{
select {
case val := <-ch:
if val.err != nil {
res.SetError(val.err, cmdkit.ErrNormal)
return
return val.err
}
if pv := v.Value(); pv != 0 {
out <- &AddPinOutput{Progress: v.Value()}
}
out <- &AddPinOutput{Pins: cidsToStrings(val.pins)}
return
return nil
case <-ticker.C:
out <- &AddPinOutput{Progress: v.Value()}
case <-ctx.Done():
log.Error(ctx.Err())
res.SetError(ctx.Err(), cmdkit.ErrNormal)
return
return ctx.Err()
}
}
},
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
switch out := v.(type) {
case *AddPinOutput:
if out.Pins != nil {
added = out.Pins
} else {
// 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)
if out.Pins != nil {
added = out.Pins
} else {
// this can only happen if the progress option is set
return fmt.Errorf("Fetched/Processed %d nodes\r", out.Progress)
}
var pintype string
rec, found, _ := res.Request().Option("recursive").Bool()
rec, found := req.Options["recursive"].(bool)
if rec || !found {
pintype = "recursively"
} else {
pintype = "directly"
}
buf := new(bytes.Buffer)
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.)
cmdkit.BoolOption(pinRecursiveOptionName, "r", "Recursively unpin the object linked to by the specified object(s).").WithDefault(true),
},
Type: PinOutput{},
Run: func(req cmds.Request, res cmds.Response) {
n, err := req.InvocContext().GetNode()
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
n, err := cmdenv.GetNode(env)
if err != nil {
res.SetError(err, cmdkit.ErrNormal)
return
return err
}
api, err := req.InvocContext().GetApi()
api, err := cmdenv.GetApi(env)
if err != nil {
res.SetError(err, cmdkit.ErrNormal)
return
return err
}
// set recursive flag
recursive, _, err := req.Option(pinRecursiveOptionName).Bool()
recursive, _ := req.Options[pinRecursiveOptionName].(bool)
removed, err := corerepo.Unpin(n, api, req.Context, req.Arguments, recursive)
if err != nil {
res.SetError(err, cmdkit.ErrNormal)
return
return err
}
removed, err := corerepo.Unpin(n, api, req.Context(), req.Arguments(), recursive)
if err != nil {
res.SetError(err, cmdkit.ErrNormal)
return
}
res.SetOutput(&PinOutput{cidsToStrings(removed)})
return res.Emit(&PinOutput{cidsToStrings(removed)})
},
Marshalers: cmds.MarshalerMap{
cmds.Text: func(res cmds.Response) (io.Reader, error) {
v, err := unwrapOutput(res.Output())
if err != nil {
return nil, err
Encoders: cmds.EncoderMap{
cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *PinOutput) error {
for _, k := range out.Pins {
fmt.Fprintf(w, "unpinned %s\n", k)
}
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:
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."),
},
Run: func(req cmds.Request, res cmds.Response) {
n, err := req.InvocContext().GetNode()
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
n, err := cmdenv.GetNode(env)
if err != nil {
res.SetError(err, cmdkit.ErrNormal)
return
return err
}
api, err := req.InvocContext().GetApi()
api, err := cmdenv.GetApi(env)
if err != nil {
res.SetError(err, cmdkit.ErrNormal)
return
return err
}
typeStr, _, err := req.Option(pinTypeOptionName).String()
typeStr, _ := req.Options[pinTypeOptionName].(string)
if err != nil {
res.SetError(err, cmdkit.ErrNormal)
return
return err
}
switch typeStr {
case "all", "direct", "indirect", "recursive":
default:
err = fmt.Errorf("invalid type '%s', must be one of {direct, indirect, recursive, all}", typeStr)
res.SetError(err, cmdkit.ErrClient)
return
return err
}
var keys map[string]RefKeyObject
if len(req.Arguments()) > 0 {
keys, err = pinLsKeys(req.Context(), req.Arguments(), typeStr, n, api)
if len(req.Arguments) > 0 {
keys, err = pinLsKeys(req.Context, req.Arguments, typeStr, n, api)
} else {
keys, err = pinLsAll(req.Context(), typeStr, n)
keys, err = pinLsAll(req.Context, typeStr, n)
}
if err != nil {
res.SetError(err, cmdkit.ErrNormal)
return err
} else {
res.SetOutput(&RefKeyList{Keys: keys})
return res.Emit(&RefKeyList{Keys: keys})
}
},
Type: RefKeyList{},
Marshalers: cmds.MarshalerMap{
cmds.Text: func(res cmds.Response) (io.Reader, error) {
v, err := unwrapOutput(res.Output())
if err != nil {
return nil, err
}
Encoders: cmds.EncoderMap{
cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *RefKeyList) error {
quiet, _ := req.Options[pinQuietOptionName].(bool)
quiet, _, err := res.Request().Option(pinQuietOptionName).Bool()
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 {
for k, v := range out.Keys {
if quiet {
fmt.Fprintf(out, "%s\n", k)
fmt.Fprintf(w, "%s\n", k)
} 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.
cmdkit.BoolOption(pinUnpinOptionName, "Remove the old pin.").WithDefault(true),
},
Type: PinOutput{},
Run: func(req cmds.Request, res cmds.Response) {
api, err := req.InvocContext().GetApi()
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
api, err := cmdenv.GetApi(env)
if err != nil {
res.SetError(err, cmdkit.ErrNormal)
return
return err
}
unpin, _, err := req.Option(pinUnpinOptionName).Bool()
unpin, _ := req.Options[pinUnpinOptionName].(bool)
from, err := iface.ParsePath(req.Arguments[0])
if err != nil {
res.SetError(err, cmdkit.ErrNormal)
return
return err
}
from, err := iface.ParsePath(req.Arguments()[0])
to, err := iface.ParsePath(req.Arguments[1])
if err != nil {
res.SetError(err, cmdkit.ErrNormal)
return
return err
}
to, err := iface.ParsePath(req.Arguments()[1])
err = api.Pin().Update(req.Context, from, to, options.Pin.Unpin(unpin))
if err != nil {
res.SetError(err, cmdkit.ErrNormal)
return
return err
}
err = api.Pin().Update(req.Context(), from, to, options.Pin.Unpin(unpin))
if err != nil {
res.SetError(err, cmdkit.ErrNormal)
return
}
res.SetOutput(&PinOutput{Pins: []string{from.String(), to.String()}})
return res.Emit(&PinOutput{Pins: []string{from.String(), to.String()}})
},
Marshalers: cmds.MarshalerMap{
cmds.Text: func(res cmds.Response) (io.Reader, error) {
v, err := unwrapOutput(res.Output())
if err != 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
},
Encoders: cmds.EncoderMap{
cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *PinOutput) error {
fmt.Fprintf(w, "updated %s to %s\n", out.Pins[0], out.Pins[1])
return nil
}),
},
}
@ -457,51 +383,40 @@ var verifyPinCmd = &cmds.Command{
cmdkit.BoolOption(pinVerboseOptionName, "Also write the hashes of non-broken pins."),
cmdkit.BoolOption(pinQuietOptionName, "q", "Write just hashes of broken pins."),
},
Run: func(req cmds.Request, res cmds.Response) {
n, err := req.InvocContext().GetNode()
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
n, err := cmdenv.GetNode(env)
if err != nil {
res.SetError(err, cmdkit.ErrNormal)
return
return err
}
verbose, _, _ := res.Request().Option(pinVerboseOptionName).Bool()
quiet, _, _ := res.Request().Option(pinQuietOptionName).Bool()
verbose, _ := req.Options[pinVerboseOptionName].(bool)
quiet, _ := req.Options[pinQuietOptionName].(bool)
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{
explain: !quiet,
includeOk: verbose,
}
out := pinVerify(req.Context(), n, opts)
out := pinVerify(req.Context, n, opts)
res.SetOutput(out)
return res.Emit(out)
},
Type: PinVerifyRes{},
Marshalers: cmds.MarshalerMap{
cmds.Text: func(res cmds.Response) (io.Reader, error) {
quiet, _, _ := res.Request().Option(pinQuietOptionName).Bool()
Encoders: cmds.EncoderMap{
cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *PinVerifyRes) error {
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 && !r.Ok {
fmt.Fprintf(buf, "%s\n", r.Cid)
if quiet && !out.Ok {
fmt.Fprintf(w, "%s\n", out.Cid)
} else if !quiet {
r.Format(buf)
out.Format(w)
}
return buf, nil
},
return nil
}),
},
}

View File

@ -135,7 +135,7 @@ var rootSubcommands = map[string]*cmds.Command{
"mount": MountCmd,
"name": name.NameCmd,
"object": ocmd.ObjectCmd,
"pin": lgc.NewCommand(PinCmd),
"pin": PinCmd,
"ping": PingCmd,
"p2p": P2PCmd,
"refs": lgc.NewCommand(RefsCmd),