Add --cid-version and --hash-fun option to files API
License: MIT Signed-off-by: Kevin Atkinson <k@kevina.org>
Kevin Atkinson committed
Aug 13, 2017 at 14:12 UTC
18a6344bddec304e739601d3e27bfeaec0dac08a
1 file changed
+70
-6
core/commands/files/files.go
+70
-6
@@ -18,8 +18,10 @@ import (
18
ft "github.com/ipfs/go-ipfs/unixfs"
19
uio "github.com/ipfs/go-ipfs/unixfs/io"
20
21
+ cid "gx/ipfs/QmNp85zy9RLrQ5oQD4hPyS39ezrrXpcaa7R4Y9kxdWQLLQ/go-cid"
22
node "gx/ipfs/QmPN7cwmpcc4DWXb4KTB9dNAJgjuPY69h3npsMfhRrQL9c/go-ipld-format"
23
logging "gx/ipfs/QmSpJByNKFX1sCsHBEp3R73FL4NF6FnQTEGyNAXHm2GS52/go-log"
24
+ mh "gx/ipfs/QmU9a9NV9RdPNwZQDYd5uKsm6N6LJLSvLbywDDYFbaaC6P/go-multihash"
25
)
26
27
var log = logging.Logger("cmds/files")
@@ -39,11 +41,21 @@ of consistency guarantees. If the daemon is unexpectedly killed before running
41
'ipfs files flush' on the files in question, then data may be lost. This also
42
applies to running 'ipfs repo gc' concurrently with '--flush=false'
43
operations.
44
+
45
+The --cid-version and --hash-fun option only apply to newly created files
46
+and directories. If not specified these proprieties are inhertied
47
+from the parent directory.
48
`,
49
},
50
Options: []cmds.Option{
51
cmds.BoolOption("f", "flush", "Flush target and ancestors after write.").Default(true),
52
cmds.BoolOption("raw-leaves", "Use raw blocks for newly created leaf nodes. (experimental)"),
53
+ cmds.IntOption("cid-version", "cid-ver", "Cid version. Non-zero value will change default of 'raw-leaves' to true. (experimental)"),
54
+ cmds.StringOption("hash-fun", "Hash function to use. Will set Cid version to 1 if used. (experimental)"),
55
+ // ^^fixme: can't use just "hash" as the option name as the
56
+ // conflicts with "--hash" usage by the stat command, this is
57
+ // unfortunate as it creates an inconsistency with the "add"
58
+ // that uses "hash"
59
},
60
Subcommands: map[string]*cmds.Command{
61
"read": FilesReadCmd,
@@ -599,7 +611,13 @@ stat' on the file or any of its ancestors.
611
create, _, _ := req.Option("create").Bool()
612
trunc, _, _ := req.Option("truncate").Bool()
613
flush, _, _ := req.Option("flush").Bool()
602
- rawLeaves, _, _ := req.Option("raw-leaves").Bool()
614
+ rawLeaves, rawLeavesDef, _ := req.Option("raw-leaves").Bool()
615
+
616
+ prefix, err := getPrefix(req)
617
+ if err != nil {
618
+ res.SetError(err, cmds.ErrNormal)
619
+ return
620
+ }
621
622
nd, err := req.InvocContext().GetNode()
623
if err != nil {
@@ -617,12 +635,14 @@ stat' on the file or any of its ancestors.
635
return
636
}
637
620
- fi, err := getFileHandle(nd.FilesRoot, path, create)
638
+ fi, err := getFileHandle(nd.FilesRoot, path, create, prefix)
639
if err != nil {
640
res.SetError(err, cmds.ErrNormal)
641
return
642
}
625
- fi.RawLeaves = rawLeaves
643
+ if rawLeavesDef {
644
+ fi.RawLeaves = rawLeaves
645
+ }
646
647
wfd, err := fi.Open(mfs.OpenWriteOnly, flush)
648
if err != nil {
@@ -719,7 +739,21 @@ Examples:
739
740
flush, _, _ := req.Option("flush").Bool()
741
722
- err = mfs.Mkdir(n.FilesRoot, dirtomake, dashp, flush)
742
+ prefix, err := getPrefix(req)
743
+ if err != nil {
744
+ res.SetError(err, cmds.ErrNormal)
745
+ return
746
+ }
747
+ root := n.FilesRoot
748
+ if prefix != nil {
749
+ // FIXME: This is ugly and may not be correct either
750
+ // -- kevina
751
+ newRoot := *root
752
+ root = &newRoot
753
+ root.Prefix = prefix
754
+ }
755
+
756
+ err = mfs.Mkdir(root, dirtomake, dashp, flush)
757
if err != nil {
758
res.SetError(err, cmds.ErrNormal)
759
return
@@ -863,8 +897,36 @@ Remove files or directories.
897
},
898
}
899
866
-func getFileHandle(r *mfs.Root, path string, create bool) (*mfs.File, error) {
900
+func getPrefix(req cmds.Request) (*cid.Prefix, error) {
901
+ cidVer, cidVerSet, _ := req.Option("cid-version").Int()
902
+ hashFunStr, hashFunSet, _ := req.Option("hash-fun").String()
903
+
904
+ if !cidVerSet && !hashFunSet {
905
+ return nil, nil
906
+ }
907
+
908
+ if hashFunSet && cidVer == 0 {
909
+ cidVer = 1
910
+ }
911
+
912
+ prefix, err := dag.PrefixForCidVersion(cidVer)
913
+ if err != nil {
914
+ return nil, err
915
+ }
916
917
+ if hashFunSet {
918
+ hashFunCode, ok := mh.Names[strings.ToLower(hashFunStr)]
919
+ if !ok {
920
+ return nil, fmt.Errorf("unrecognized hash function: %s", strings.ToLower(hashFunStr))
921
+ }
922
+ prefix.MhType = hashFunCode
923
+ prefix.MhLength = -1
924
+ }
925
+
926
+ return &prefix, nil
927
+}
928
+
929
+func getFileHandle(r *mfs.Root, path string, create bool, prefix *cid.Prefix) (*mfs.File, error) {
930
target, err := mfs.Lookup(r, path)
931
switch err {
932
case nil:
@@ -890,7 +952,9 @@ func getFileHandle(r *mfs.Root, path string, create bool) (*mfs.File, error) {
952
if !ok {
953
return nil, fmt.Errorf("%s was not a directory", dirname)
954
}
893
- prefix := pdir.GetPrefix()
955
+ if prefix == nil {
956
+ prefix = pdir.GetPrefix()
957
+ }
958
959
nd := dag.NodeWithData(ft.FilePBData(nil, 0))
960
nd.SetPrefix(prefix)