提交 abd390b8 作者: Matt Bell

core/commands: Made add command show streamed output

上级 71838adf
...@@ -20,10 +20,9 @@ import ( ...@@ -20,10 +20,9 @@ import (
// Error indicating the max depth has been exceded. // Error indicating the max depth has been exceded.
var ErrDepthLimitExceeded = fmt.Errorf("depth limit exceeded") var ErrDepthLimitExceeded = fmt.Errorf("depth limit exceeded")
type AddOutput struct { type AddedObject struct {
Objects []*Object Name string
Names []string Hash string
Quiet bool
} }
var AddCmd = &cmds.Command{ var AddCmd = &cmds.Command{
...@@ -45,58 +44,65 @@ remains to be implemented. ...@@ -45,58 +44,65 @@ remains to be implemented.
cmds.BoolOption("quiet", "q", "Write minimal output"), cmds.BoolOption("quiet", "q", "Write minimal output"),
}, },
Run: func(req cmds.Request) (interface{}, error) { Run: func(req cmds.Request) (interface{}, error) {
added := &AddOutput{}
n, err := req.Context().GetNode() n, err := req.Context().GetNode()
if err != nil { if err != nil {
return nil, err return nil, err
} }
for { outChan := make(chan interface{})
file, err := req.Files().NextFile()
if err != nil && err != io.EOF {
return nil, err
}
if file == nil {
break
}
_, err = addFile(n, file, added) go func() {
if err != nil { defer close(outChan)
return nil, err
}
}
quiet, _, err := req.Option("quiet").Bool() for {
if err != nil { file, err := req.Files().NextFile()
return nil, err if (err != nil && err != io.EOF) || file == nil {
} return
}
added.Quiet = quiet _, err = addFile(n, file, outChan)
if err != nil {
return
}
}
}()
return added, nil return outChan, nil
}, },
Marshalers: cmds.MarshalerMap{ Marshalers: cmds.MarshalerMap{
cmds.Text: func(res cmds.Response) (io.Reader, error) { cmds.Text: func(res cmds.Response) (io.Reader, error) {
val, ok := res.Output().(*AddOutput) outChan, ok := res.Output().(chan interface{})
if !ok { if !ok {
return nil, u.ErrCast() return nil, u.ErrCast()
} }
// TODO: use this with an option quiet, _, err := res.Request().Option("quiet").Bool()
// sort.Stable(val) if err != nil {
return nil, err
}
var buf bytes.Buffer marshal := func(v interface{}) (io.Reader, error) {
for i, obj := range val.Objects { obj, ok := v.(*AddedObject)
if val.Quiet { if !ok {
buf.Write([]byte(fmt.Sprintf("%s\n", obj.Hash))) return nil, u.ErrCast()
}
var buf bytes.Buffer
if quiet {
buf.WriteString(fmt.Sprintf("%s\n", obj.Hash))
} else { } else {
buf.Write([]byte(fmt.Sprintf("added %s %s\n", obj.Hash, val.Names[i]))) buf.WriteString(fmt.Sprintf("added %s %s\n", obj.Hash, obj.Name))
} }
return &buf, nil
} }
return &buf, nil
return &cmds.ChannelMarshaler{
Channel: outChan,
Marshaler: marshal,
}, nil
}, },
}, },
Type: &AddOutput{}, Type: &AddedObject{},
} }
func add(n *core.IpfsNode, readers []io.Reader) ([]*dag.Node, error) { func add(n *core.IpfsNode, readers []io.Reader) ([]*dag.Node, error) {
...@@ -132,9 +138,9 @@ func addNode(n *core.IpfsNode, node *dag.Node) error { ...@@ -132,9 +138,9 @@ func addNode(n *core.IpfsNode, node *dag.Node) error {
return nil return nil
} }
func addFile(n *core.IpfsNode, file cmds.File, added *AddOutput) (*dag.Node, error) { func addFile(n *core.IpfsNode, file cmds.File, out chan interface{}) (*dag.Node, error) {
if file.IsDirectory() { if file.IsDirectory() {
return addDir(n, file, added) return addDir(n, file, out)
} }
dns, err := add(n, []io.Reader{file}) dns, err := add(n, []io.Reader{file})
...@@ -143,13 +149,13 @@ func addFile(n *core.IpfsNode, file cmds.File, added *AddOutput) (*dag.Node, err ...@@ -143,13 +149,13 @@ func addFile(n *core.IpfsNode, file cmds.File, added *AddOutput) (*dag.Node, err
} }
log.Infof("adding file: %s", file.FileName()) log.Infof("adding file: %s", file.FileName())
if err := addDagnode(added, file.FileName(), dns[len(dns)-1]); err != nil { if err := outputDagnode(out, file.FileName(), dns[len(dns)-1]); err != nil {
return nil, err return nil, err
} }
return dns[len(dns)-1], nil // last dag node is the file. return dns[len(dns)-1], nil // last dag node is the file.
} }
func addDir(n *core.IpfsNode, dir cmds.File, added *AddOutput) (*dag.Node, error) { func addDir(n *core.IpfsNode, dir cmds.File, out chan interface{}) (*dag.Node, error) {
log.Infof("adding directory: %s", dir.FileName()) log.Infof("adding directory: %s", dir.FileName())
tree := &dag.Node{Data: ft.FolderPBData()} tree := &dag.Node{Data: ft.FolderPBData()}
...@@ -163,7 +169,7 @@ func addDir(n *core.IpfsNode, dir cmds.File, added *AddOutput) (*dag.Node, error ...@@ -163,7 +169,7 @@ func addDir(n *core.IpfsNode, dir cmds.File, added *AddOutput) (*dag.Node, error
break break
} }
node, err := addFile(n, file, added) node, err := addFile(n, file, out)
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -176,7 +182,7 @@ func addDir(n *core.IpfsNode, dir cmds.File, added *AddOutput) (*dag.Node, error ...@@ -176,7 +182,7 @@ func addDir(n *core.IpfsNode, dir cmds.File, added *AddOutput) (*dag.Node, error
} }
} }
err := addDagnode(added, dir.FileName(), tree) err := outputDagnode(out, dir.FileName(), tree)
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -189,27 +195,17 @@ func addDir(n *core.IpfsNode, dir cmds.File, added *AddOutput) (*dag.Node, error ...@@ -189,27 +195,17 @@ func addDir(n *core.IpfsNode, dir cmds.File, added *AddOutput) (*dag.Node, error
return tree, nil return tree, nil
} }
// addDagnode adds dagnode info to an output object // outputDagnode sends dagnode info over the output channel
func addDagnode(output *AddOutput, name string, dn *dag.Node) error { func outputDagnode(out chan interface{}, name string, dn *dag.Node) error {
o, err := getOutput(dn) o, err := getOutput(dn)
if err != nil { if err != nil {
return err return err
} }
output.Objects = append(output.Objects, o) out <- &AddedObject{
output.Names = append(output.Names, name) Hash: o.Hash,
return nil Name: name,
} }
// Sort interface implementation to sort add output by name
func (a AddOutput) Len() int { return nil
return len(a.Names)
}
func (a AddOutput) Swap(i, j int) {
a.Names[i], a.Names[j] = a.Names[j], a.Names[i]
a.Objects[i], a.Objects[j] = a.Objects[j], a.Objects[i]
}
func (a AddOutput) Less(i, j int) bool {
return a.Names[i] < a.Names[j]
} }
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论