added ls + recusrive directory adding
Juan Batiz-Benet committed
Jul 5, 2014 at 18:19 UTC
5abf3c2ae9f0818ca74fd9a352a05dc903d419b1
5 files changed
+115
-21
cli/add.go
+43
-20
@@ -6,11 +6,16 @@ import (
6
"github.com/jbenet/commander"
7
core "github.com/jbenet/go-ipfs/core"
8
importer "github.com/jbenet/go-ipfs/importer"
9
+ dag "github.com/jbenet/go-ipfs/merkledag"
10
u "github.com/jbenet/go-ipfs/util"
11
mh "github.com/jbenet/go-multihash"
12
+ "io/ioutil"
13
"os"
14
+ "path/filepath"
15
)
16
17
+var DepthLimitExceeded = fmt.Errorf("depth limit exceeded")
18
+
19
var cmdIpfsAdd = &commander.Command{
20
UsageLine: "add",
21
Short: "Add an object to ipfs.",
@@ -49,18 +54,26 @@ func addCmd(c *commander.Command, inp []string) error {
54
}
55
56
for _, fpath := range inp {
52
- err = addPath(n, fpath, depth)
57
+ _, err := addPath(n, fpath, depth)
58
if err != nil {
54
- u.PErr("error adding %s: %v\n", fpath, err)
59
+ if !recursive {
60
+ return fmt.Errorf("%s is a directory. Use -r to add recursively.", fpath)
61
+ } else {
62
+ u.PErr("error adding %s: %v\n", fpath, err)
63
+ }
64
}
65
}
66
return err
67
}
68
60
-func addPath(n *core.IpfsNode, fpath string, depth int) error {
69
+func addPath(n *core.IpfsNode, fpath string, depth int) (*dag.Node, error) {
70
+ if depth == 0 {
71
+ return nil, DepthLimitExceeded
72
+ }
73
+
74
fi, err := os.Stat(fpath)
75
if err != nil {
63
- return err
76
+ return nil, err
77
}
78
79
if fi.IsDir() {
@@ -70,33 +83,43 @@ func addPath(n *core.IpfsNode, fpath string, depth int) error {
83
}
84
}
85
73
-func addDir(n *core.IpfsNode, fpath string, depth int) error {
74
- return u.NotImplementedError
75
-}
86
+func addDir(n *core.IpfsNode, fpath string, depth int) (*dag.Node, error) {
87
+ tree := &dag.Node{}
88
77
-func addFile(n *core.IpfsNode, fpath string, depth int) error {
78
- stat, err := os.Stat(fpath)
89
+ files, err := ioutil.ReadDir(fpath)
90
if err != nil {
80
- return err
91
+ return nil, err
92
}
93
83
- if stat.IsDir() {
84
- return fmt.Errorf("addFile: `fpath` is a directory")
85
- }
94
+ // construct nodes for containing files.
95
+ for _, f := range files {
96
+ fp := filepath.Join(fpath, f.Name())
97
+ nd, err := addPath(n, fp, depth-1)
98
+ if err != nil {
99
+ return nil, err
100
+ }
101
87
- f, err := os.Open(fpath)
88
- if err != nil {
89
- return err
102
+ if err = tree.AddNodeLink(f.Name(), nd); err != nil {
103
+ return nil, err
104
+ }
105
}
91
- defer f.Close()
106
93
- root, err := importer.NewDagFromReader(f, stat.Size())
107
+ return tree, addNode(n, tree, fpath)
108
+}
109
+
110
+func addFile(n *core.IpfsNode, fpath string, depth int) (*dag.Node, error) {
111
+ root, err := importer.NewDagFromFile(fpath)
112
if err != nil {
95
- return err
113
+ return nil, err
114
}
115
116
+ return root, addNode(n, root, fpath)
117
+}
118
+
119
+// addNode adds the node to the graph + local storage
120
+func addNode(n *core.IpfsNode, nd *dag.Node, fpath string) error {
121
// add the file to the graph + local storage
99
- k, err := n.AddDagNode(root)
122
+ k, err := n.AddDagNode(nd)
123
if err != nil {
124
return err
125
}
cli/ipfs.go
+1
@@ -38,6 +38,7 @@ Use "ipfs help <command>" for more information about a command.
38
Subcommands: []*commander.Command{
39
cmdIpfsAdd,
40
cmdIpfsCat,
41
+ cmdIpfsLs,
42
cmdIpfsVersion,
43
cmdIpfsCommands,
44
},
cli/ls.go
new
+51
@@ -0,0 +1,51 @@
1
+package main
2
+
3
+import (
4
+ "github.com/gonuts/flag"
5
+ "github.com/jbenet/commander"
6
+ u "github.com/jbenet/go-ipfs/util"
7
+ mh "github.com/jbenet/go-multihash"
8
+)
9
+
10
+var cmdIpfsLs = &commander.Command{
11
+ UsageLine: "ls",
12
+ Short: "List links from an object.",
13
+ Long: `ipfs ls <ipfs-path> - List links from an object.
14
+
15
+ Retrieves the object named by <ipfs-path> and displays the links
16
+ it contains, with the following format:
17
+
18
+ <link base58 hash> <link size in bytes> <link name>
19
+
20
+`,
21
+ Run: lsCmd,
22
+ Flag: *flag.NewFlagSet("ipfs-ls", flag.ExitOnError),
23
+}
24
+
25
+func lsCmd(c *commander.Command, inp []string) error {
26
+ if len(inp) < 1 {
27
+ u.POut(c.Long)
28
+ return nil
29
+ }
30
+
31
+ // for now only hashes, no path resolution
32
+ h, err := mh.FromB58String(inp[0])
33
+ if err != nil {
34
+ return err
35
+ }
36
+
37
+ n, err := localNode()
38
+ if err != nil {
39
+ return err
40
+ }
41
+
42
+ nd, err := n.GetDagNode(u.Key(h))
43
+ if err != nil {
44
+ return err
45
+ }
46
+
47
+ for _, link := range nd.Links {
48
+ u.POut("%s %d %s\n", link.Hash.B58String(), link.Size, link.Name)
49
+ }
50
+ return nil
51
+}
core/core.go
-1
@@ -11,7 +11,6 @@ import (
11
)
12
13
// IPFS Core module. It represents an IPFS instance.
14
-
14
type IpfsNode struct {
15
16
// the node's configuration
importer/importer.go
+20
@@ -5,6 +5,7 @@ import (
5
dag "github.com/jbenet/go-ipfs/merkledag"
6
"io"
7
"io/ioutil"
8
+ "os"
9
)
10
11
var BlockSizeLimit = int64(1048576) // 1 MB
@@ -38,3 +39,22 @@ func NewDagFromReader(r io.Reader, size int64) (*dag.Node, error) {
39
// no children for now because not block splitting yet
40
return root, nil
41
}
42
+
43
+func NewDagFromFile(fpath string) (*dag.Node, error) {
44
+ stat, err := os.Stat(fpath)
45
+ if err != nil {
46
+ return nil, err
47
+ }
48
+
49
+ if stat.IsDir() {
50
+ return nil, fmt.Errorf("`fpath` is a directory")
51
+ }
52
+
53
+ f, err := os.Open(fpath)
54
+ if err != nil {
55
+ return nil, err
56
+ }
57
+ defer f.Close()
58
+
59
+ return NewDagFromReader(f, stat.Size())
60
+}