Unverified Commit 254dda28 authored by Steven Allen's avatar Steven Allen Committed by GitHub

Merge pull request #5677 from chenminjian/refact/cmd/repo

refact(cmd/repo): repo's sub cmds uses new cmd lib
parents 3f4b95b8 ff27f9f1
package commands package commands
import ( import (
"bytes"
"context" "context"
"errors" "errors"
"fmt" "fmt"
...@@ -13,8 +12,6 @@ import ( ...@@ -13,8 +12,6 @@ import (
"sync" "sync"
"text/tabwriter" "text/tabwriter"
oldcmds "github.com/ipfs/go-ipfs/commands"
lgc "github.com/ipfs/go-ipfs/commands/legacy"
cmdenv "github.com/ipfs/go-ipfs/core/commands/cmdenv" cmdenv "github.com/ipfs/go-ipfs/core/commands/cmdenv"
e "github.com/ipfs/go-ipfs/core/commands/e" e "github.com/ipfs/go-ipfs/core/commands/e"
corerepo "github.com/ipfs/go-ipfs/core/corerepo" corerepo "github.com/ipfs/go-ipfs/core/corerepo"
...@@ -42,9 +39,9 @@ var RepoCmd = &cmds.Command{ ...@@ -42,9 +39,9 @@ var RepoCmd = &cmds.Command{
Subcommands: map[string]*cmds.Command{ Subcommands: map[string]*cmds.Command{
"stat": repoStatCmd, "stat": repoStatCmd,
"gc": repoGcCmd, "gc": repoGcCmd,
"fsck": lgc.NewCommand(RepoFsckCmd), "fsck": repoFsckCmd,
"version": lgc.NewCommand(repoVersionCmd), "version": repoVersionCmd,
"verify": lgc.NewCommand(repoVerifyCmd), "verify": repoVerifyCmd,
}, },
} }
...@@ -224,7 +221,7 @@ Version string The repo version. ...@@ -224,7 +221,7 @@ Version string The repo version.
}, },
} }
var RepoFsckCmd = &oldcmds.Command{ var repoFsckCmd = &cmds.Command{
Helptext: cmdkit.HelpText{ Helptext: cmdkit.HelpText{
Tagline: "Remove repo lockfiles.", Tagline: "Remove repo lockfiles.",
ShortDescription: ` ShortDescription: `
...@@ -233,13 +230,15 @@ lockfiles, as well as the api file. This command can only run when no ipfs ...@@ -233,13 +230,15 @@ lockfiles, as well as the api file. This command can only run when no ipfs
daemons are running. daemons are running.
`, `,
}, },
Run: func(req oldcmds.Request, res oldcmds.Response) { Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
configRoot := req.InvocContext().ConfigRoot configRoot, err := cmdenv.GetConfigRoot(env)
if err != nil {
return err
}
dsPath, err := config.DataStorePath(configRoot) dsPath, err := config.DataStorePath(configRoot)
if err != nil { if err != nil {
res.SetError(err, cmdkit.ErrNormal) return err
return
} }
dsLockFile := filepath.Join(dsPath, "LOCK") // TODO: get this lockfile programmatically dsLockFile := filepath.Join(dsPath, "LOCK") // TODO: get this lockfile programmatically
...@@ -252,25 +251,25 @@ daemons are running. ...@@ -252,25 +251,25 @@ daemons are running.
err = os.Remove(repoLockFile) err = os.Remove(repoLockFile)
if err != nil && !os.IsNotExist(err) { if err != nil && !os.IsNotExist(err) {
res.SetError(err, cmdkit.ErrNormal) return err
return
} }
err = os.Remove(dsLockFile) err = os.Remove(dsLockFile)
if err != nil && !os.IsNotExist(err) { if err != nil && !os.IsNotExist(err) {
res.SetError(err, cmdkit.ErrNormal) return err
return
} }
err = os.Remove(apiFile) err = os.Remove(apiFile)
if err != nil && !os.IsNotExist(err) { if err != nil && !os.IsNotExist(err) {
res.SetError(err, cmdkit.ErrNormal) return err
return
} }
res.SetOutput(&MessageOutput{"Lockfiles have been removed.\n"}) return cmds.EmitOnce(res, &MessageOutput{"Lockfiles have been removed.\n"})
}, },
Type: MessageOutput{}, Type: MessageOutput{},
Marshalers: oldcmds.MarshalerMap{ Encoders: cmds.EncoderMap{
oldcmds.Text: MessageTextMarshaler, cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *MessageOutput) error {
fmt.Fprintf(w, out.Message)
return nil
}),
}, },
} }
...@@ -321,95 +320,71 @@ func verifyResultChan(ctx context.Context, keys <-chan cid.Cid, bs bstore.Blocks ...@@ -321,95 +320,71 @@ func verifyResultChan(ctx context.Context, keys <-chan cid.Cid, bs bstore.Blocks
return results return results
} }
var repoVerifyCmd = &oldcmds.Command{ var repoVerifyCmd = &cmds.Command{
Helptext: cmdkit.HelpText{ Helptext: cmdkit.HelpText{
Tagline: "Verify all blocks in repo are not corrupted.", Tagline: "Verify all blocks in repo are not corrupted.",
}, },
Run: func(req oldcmds.Request, res oldcmds.Response) { Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
nd, err := req.InvocContext().GetNode() nd, err := cmdenv.GetNode(env)
if err != nil { if err != nil {
res.SetError(err, cmdkit.ErrNormal) return err
return
} }
out := make(chan interface{})
res.SetOutput((<-chan interface{})(out))
defer close(out)
bs := bstore.NewBlockstore(nd.Repo.Datastore()) bs := bstore.NewBlockstore(nd.Repo.Datastore())
bs.HashOnRead(true) bs.HashOnRead(true)
keys, err := bs.AllKeysChan(req.Context()) keys, err := bs.AllKeysChan(req.Context)
if err != nil { if err != nil {
log.Error(err) log.Error(err)
return return err
} }
results := verifyResultChan(req.Context(), keys, bs) results := verifyResultChan(req.Context, keys, bs)
var fails int var fails int
var i int var i int
for msg := range results { for msg := range results {
if msg != "" { if msg != "" {
select { if err := res.Emit(&VerifyProgress{Msg: msg}); err != nil {
case out <- &VerifyProgress{Msg: msg}: return err
case <-req.Context().Done():
return
} }
fails++ fails++
} }
i++ i++
select { if err := res.Emit(&VerifyProgress{Progress: i}); err != nil {
case out <- &VerifyProgress{Progress: i}: return err
case <-req.Context().Done():
return
} }
} }
if fails == 0 { if fails != 0 {
select { return errors.New("verify complete, some blocks were corrupt")
case out <- &VerifyProgress{Msg: "verify complete, all blocks validated."}:
case <-req.Context().Done():
return
}
} else {
res.SetError(fmt.Errorf("verify complete, some blocks were corrupt"), cmdkit.ErrNormal)
} }
return res.Emit(&VerifyProgress{Msg: "verify complete, all blocks validated."})
}, },
Type: &VerifyProgress{}, Type: &VerifyProgress{},
Marshalers: oldcmds.MarshalerMap{ Encoders: cmds.EncoderMap{
oldcmds.Text: func(res oldcmds.Response) (io.Reader, error) { cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, obj *VerifyProgress) error {
v, err := unwrapOutput(res.Output())
if err != nil {
return nil, err
}
obj, ok := v.(*VerifyProgress)
if !ok {
return nil, e.TypeErr(obj, v)
}
buf := new(bytes.Buffer)
if strings.Contains(obj.Msg, "was corrupt") { if strings.Contains(obj.Msg, "was corrupt") {
fmt.Fprintln(os.Stdout, obj.Msg) fmt.Fprintln(os.Stdout, obj.Msg)
return buf, nil return nil
} }
if obj.Msg != "" { if obj.Msg != "" {
if len(obj.Msg) < 20 { if len(obj.Msg) < 20 {
obj.Msg += " " obj.Msg += " "
} }
fmt.Fprintln(buf, obj.Msg) fmt.Fprintln(w, obj.Msg)
return buf, nil return nil
} }
fmt.Fprintf(buf, "%d blocks processed.\r", obj.Progress) fmt.Fprintf(w, "%d blocks processed.\r", obj.Progress)
return buf, nil return nil
}, }),
}, },
} }
var repoVersionCmd = &oldcmds.Command{ var repoVersionCmd = &cmds.Command{
Helptext: cmdkit.HelpText{ Helptext: cmdkit.HelpText{
Tagline: "Show the repo version.", Tagline: "Show the repo version.",
ShortDescription: ` ShortDescription: `
...@@ -420,36 +395,22 @@ var repoVersionCmd = &oldcmds.Command{ ...@@ -420,36 +395,22 @@ var repoVersionCmd = &oldcmds.Command{
Options: []cmdkit.Option{ Options: []cmdkit.Option{
cmdkit.BoolOption(repoQuietOptionName, "q", "Write minimal output."), cmdkit.BoolOption(repoQuietOptionName, "q", "Write minimal output."),
}, },
Run: func(req oldcmds.Request, res oldcmds.Response) { Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
res.SetOutput(&RepoVersion{ return cmds.EmitOnce(res, &RepoVersion{
Version: fmt.Sprint(fsrepo.RepoVersion), Version: fmt.Sprint(fsrepo.RepoVersion),
}) })
}, },
Type: RepoVersion{}, Type: RepoVersion{},
Marshalers: oldcmds.MarshalerMap{ Encoders: cmds.EncoderMap{
oldcmds.Text: func(res oldcmds.Response) (io.Reader, error) { cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *RepoVersion) error {
v, err := unwrapOutput(res.Output()) quiet, _ := req.Options[repoQuietOptionName].(bool)
if err != nil {
return nil, err
}
response, ok := v.(*RepoVersion)
if !ok {
return nil, e.TypeErr(response, v)
}
quiet, _, err := res.Request().Option("quiet").Bool()
if err != nil {
return nil, err
}
buf := new(bytes.Buffer)
if quiet { if quiet {
buf = bytes.NewBufferString(fmt.Sprintf("fs-repo@%s\n", response.Version)) fmt.Fprintf(w, fmt.Sprintf("fs-repo@%s\n", out.Version))
} else { } else {
buf = bytes.NewBufferString(fmt.Sprintf("ipfs repo version fs-repo@%s\n", response.Version)) fmt.Fprintf(w, fmt.Sprintf("ipfs repo version fs-repo@%s\n", out.Version))
} }
return buf, nil return nil
}),
},
}, },
} }
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment