@cryptotaxi247 / kubo / commits / b4a008720

"pin verify": fix API

License: MIT Signed-off-by: Kevin Atkinson <k@kevina.org>

Kevin Atkinson committed May 25, 2017 at 13:52 UTC b4a008720d2fd12429d953f4354cb0fcf8a252ff
1 file changed +74 -38
core/commands/pin.go
+74 -38
@@ -429,21 +429,43 @@ var verifyPinCmd = &cmds.Command{
429 verbose, _, _ := res.Request().Option("verbose").Bool()
430 quiet, _, _ := res.Request().Option("quiet").Bool()
431
432 - rdr, wtr := io.Pipe()
433 - out := pinVerify(req.Context(), n)
432 + if verbose && quiet {
433 + res.SetError(fmt.Errorf("The --verbose and --quiet options can not be used at the same time"), cmds.ErrNormal)
434 + }
435
435 - go func() {
436 - defer wtr.Close()
437 - for r := range out {
438 - if quiet && len(r.badNodes) > 0 {
439 - fmt.Fprintf(wtr, "%s\n", r.cid)
440 - } else if !quiet {
441 - r.Format(wtr, verbose)
442 - }
436 + opts := pinVerifyOpts{
437 + explain: !quiet,
438 + includeOk: verbose,
439 + }
440 + out := pinVerify(req.Context(), n, opts)
441 +
442 + res.SetOutput(out)
443 + },
444 + Type: PinVerifyRes{},
445 + Marshalers: cmds.MarshalerMap{
446 + cmds.Text: func(res cmds.Response) (io.Reader, error) {
447 + quiet, _, _ := res.Request().Option("quiet").Bool()
448 +
449 + outChan, ok := res.Output().(<-chan interface{})
450 + if !ok {
451 + return nil, u.ErrCast()
452 }
444 - }()
453
446 - res.SetOutput(rdr)
454 + rdr, wtr := io.Pipe()
455 + go func() {
456 + defer wtr.Close()
457 + for r0 := range outChan {
458 + r := r0.(*PinVerifyRes)
459 + if quiet && !r.Ok {
460 + fmt.Fprintf(wtr, "%s\n", r.Cid)
461 + } else if !quiet {
462 + r.Format(wtr)
463 + }
464 + }
465 + }()
466 +
467 + return rdr, nil
468 + },
469 },
470 }
471
@@ -529,27 +551,36 @@ func pinLsAll(typeStr string, ctx context.Context, n *core.IpfsNode) (map[string
551 return keys, nil
552 }
553
532 -type pinStatus struct {
533 - badNodes []badNode
554 +// PinVerifyRes is the result returned for each pin checked in "pin verify"
555 +type PinVerifyRes struct {
556 + Cid string
557 + PinStatus
558 }
559
536 -type badNode struct {
537 - cid *cid.Cid
538 - err error
560 +// PinStatus is part of PinVerifyRes, do not use directly
561 +type PinStatus struct {
562 + Ok bool
563 + BadNodes []BadNode `json:",omitempty"`
564 }
565
541 -type pinVerifyRes struct {
542 - cid *cid.Cid
543 - pinStatus
566 +// BadNode is used in PinVerifyRes
567 +type BadNode struct {
568 + Cid string
569 + Err string
570 }
571
546 -func pinVerify(ctx context.Context, n *core.IpfsNode) <-chan pinVerifyRes {
547 - visited := make(map[string]pinStatus)
572 +type pinVerifyOpts struct {
573 + explain bool
574 + includeOk bool
575 +}
576 +
577 +func pinVerify(ctx context.Context, n *core.IpfsNode, opts pinVerifyOpts) <-chan interface{} {
578 + visited := make(map[string]PinStatus)
579 getLinks := n.DAG.GetOfflineLinkService().GetLinks
580 recPins := n.Pinning.RecursiveKeys()
581
551 - var checkPin func(root *cid.Cid) pinStatus
552 - checkPin = func(root *cid.Cid) pinStatus {
582 + var checkPin func(root *cid.Cid) PinStatus
583 + checkPin = func(root *cid.Cid) PinStatus {
584 key := root.String()
585 if status, ok := visited[key]; ok {
586 return status
@@ -557,16 +588,20 @@ func pinVerify(ctx context.Context, n *core.IpfsNode) <-chan pinVerifyRes {
588
589 links, err := getLinks(ctx, root)
590 if err != nil {
560 - status := pinStatus{[]badNode{badNode{cid: root, err: err}}}
591 + status := PinStatus{Ok: false}
592 + if opts.explain {
593 + status.BadNodes = []BadNode{BadNode{Cid: key, Err: err.Error()}}
594 + }
595 visited[key] = status
596 return status
597 }
598
565 - status := pinStatus{}
599 + status := PinStatus{Ok: true}
600 for _, lnk := range links {
601 res := checkPin(lnk.Cid)
568 - if len(res.badNodes) > 0 {
569 - status.badNodes = append(status.badNodes, res.badNodes...)
602 + if !res.Ok {
603 + status.Ok = false
604 + status.BadNodes = append(status.BadNodes, res.BadNodes...)
605 }
606 }
607
@@ -574,27 +609,28 @@ func pinVerify(ctx context.Context, n *core.IpfsNode) <-chan pinVerifyRes {
609 return status
610 }
611
577 - out := make(chan pinVerifyRes)
612 + out := make(chan interface{})
613 go func() {
614 defer close(out)
615 for _, cid := range recPins {
616 pinStatus := checkPin(cid)
582 - out <- pinVerifyRes{cid, pinStatus}
617 + if !pinStatus.Ok || opts.includeOk {
618 + out <- &PinVerifyRes{cid.String(), pinStatus}
619 + }
620 }
621 }()
622
623 return out
624 }
625
589 -func (r pinVerifyRes) Format(out io.Writer, verbose bool) {
590 - if len(r.badNodes) == 0 {
591 - if verbose {
592 - fmt.Fprintf(out, "%s ok\n", r.cid)
593 - }
626 +// Format formats PinVerifyRes
627 +func (r PinVerifyRes) Format(out io.Writer) {
628 + if r.Ok {
629 + fmt.Fprintf(out, "%s ok\n", r.Cid)
630 } else {
595 - fmt.Fprintf(out, "%s broken\n", r.cid)
596 - for _, e := range r.badNodes {
597 - fmt.Fprintf(out, " %s: %s\n", e.cid, e.err)
631 + fmt.Fprintf(out, "%s broken\n", r.Cid)
632 + for _, e := range r.BadNodes {
633 + fmt.Fprintf(out, " %s: %s\n", e.Cid, e.Err)
634 }
635 }
636 }