"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
}