Commit ab81afbc authored by Juan Benet's avatar Juan Benet

Merge pull request #1662 from ipfs/ipfs-path-resolve

Resolve IPFS DAG paths in `ipfs resolve` command
parents bea47c9b 740447ee
......@@ -5,7 +5,7 @@ import (
"strings"
cmds "github.com/ipfs/go-ipfs/commands"
namesys "github.com/ipfs/go-ipfs/namesys"
"github.com/ipfs/go-ipfs/core"
path "github.com/ipfs/go-ipfs/path"
u "github.com/ipfs/go-ipfs/util"
)
......@@ -46,6 +46,11 @@ Resolve the value of another name recursively:
> ipfs resolve -r /ipns/QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n
/ipfs/Qmcqtw8FfrVSBaRmbWwHxt3AuySBhJLcvmFYi3Lbc4xnwj
Resolve the value of an IPFS DAG path:
> ipfs resolve /ipfs/QmeZy1fGbwgVSrqbfh9fKQrAWgeyRnj7h8fsHS1oy3k99x/beep/boop
/ipfs/QmYRMjyvAiHKN9UTi8Bzt1HUspmSRD8T8DwxfSMzLgBon1
`,
},
......@@ -73,18 +78,38 @@ Resolve the value of another name recursively:
name := req.Arguments()[0]
recursive, _, _ := req.Option("recursive").Bool()
depth := 1
if recursive {
depth = namesys.DefaultDepthLimit
// the case when ipns is resolved step by step
if strings.HasPrefix(name, "/ipns/") && !recursive {
p, err := n.Namesys.ResolveN(req.Context(), name, 1)
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}
res.SetOutput(&ResolvedPath{p})
return
}
// else, ipfs path or ipns with recursive flag
p, err := path.ParsePath(name)
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}
node, err := core.Resolve(req.Context(), n, p)
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}
output, err := n.Namesys.ResolveN(req.Context(), name, depth)
key, err := node.Key()
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}
res.SetOutput(&ResolvedPath{output})
res.SetOutput(&ResolvedPath{path.FromKey(key)})
},
Marshalers: cmds.MarshalerMap{
cmds.Text: func(res cmds.Response) (io.Reader, error) {
......
......@@ -17,7 +17,7 @@ var ErrNoNamesys = errors.New(
// Resolve resolves the given path by parsing out protocol-specific
// entries (e.g. /ipns/<node-key>) and then going through the /ipfs/
// entries and returning the final merkledage node. Effectively
// entries and returning the final merkledag node. Effectively
// enables /ipns/, /dns/, etc. in commands.
func Resolve(ctx context.Context, n *IpfsNode, p path.Path) (*merkledag.Node, error) {
if strings.HasPrefix(p.String(), "/ipns/") {
......
#!/bin/sh
test_description="Test resolve command"
. lib/test-lib.sh
test_init_ipfs
test_expect_success "resolve: prepare files" '
mkdir -p a/b &&
echo "a/b/c" >a/b/c &&
a_hash=$(ipfs add -q -r a | tail -n1) &&
b_hash=$(ipfs add -q -r a/b | tail -n1) &&
c_hash=$(ipfs add -q -r a/b/c | tail -n1)
'
test_resolve_setup_name() {
ref=$1
test_expect_success "resolve: prepare name" '
id_hash=$(ipfs id -f="<id>") &&
ipfs name publish "$ref" &&
printf "$ref" >expected_nameval &&
ipfs name resolve >actual_nameval &&
test_cmp expected_nameval actual_nameval
'
}
test_resolve_setup_name_fail() {
ref=$1
test_expect_failure "resolve: prepare name" '
id_hash=$(ipfs id -f="<id>") &&
ipfs name publish "$ref" &&
printf "$ref" >expected_nameval &&
ipfs name resolve >actual_nameval &&
test_cmp expected_nameval actual_nameval
'
}
test_resolve() {
src=$1
dst=$2
test_expect_success "resolve succeeds: $src" '
ipfs resolve -r "$src" >actual
'
test_expect_success "resolved correctly: $src -> $dst" '
printf "$dst" >expected &&
test_cmp expected actual
'
}
test_resolve_cmd() {
test_resolve "/ipfs/$a_hash" "/ipfs/$a_hash"
test_resolve "/ipfs/$a_hash/b" "/ipfs/$b_hash"
test_resolve "/ipfs/$a_hash/b/c" "/ipfs/$c_hash"
test_resolve "/ipfs/$b_hash/c" "/ipfs/$c_hash"
test_resolve_setup_name "/ipfs/$a_hash"
test_resolve "/ipns/$id_hash" "/ipfs/$a_hash"
test_resolve "/ipns/$id_hash/b" "/ipfs/$b_hash"
test_resolve "/ipns/$id_hash/b/c" "/ipfs/$c_hash"
test_resolve_setup_name "/ipfs/$b_hash"
test_resolve "/ipns/$id_hash" "/ipfs/$b_hash"
test_resolve "/ipns/$id_hash/c" "/ipfs/$c_hash"
test_resolve_setup_name "/ipfs/$c_hash"
test_resolve "/ipns/$id_hash" "/ipfs/$c_hash"
}
#todo remove this once the online resolve is fixed
test_resolve_fail() {
src=$1
dst=$2
test_expect_failure "resolve succeeds: $src" '
ipfs resolve "$src" >actual
'
test_expect_failure "resolved correctly: $src -> $dst" '
printf "$dst" >expected &&
test_cmp expected actual
'
}
test_resolve_cmd_fail() {
test_resolve "/ipfs/$a_hash" "/ipfs/$a_hash"
test_resolve "/ipfs/$a_hash/b" "/ipfs/$b_hash"
test_resolve "/ipfs/$a_hash/b/c" "/ipfs/$c_hash"
test_resolve "/ipfs/$b_hash/c" "/ipfs/$c_hash"
test_resolve_setup_name_fail "/ipfs/$a_hash"
test_resolve_fail "/ipns/$id_hash" "/ipfs/$a_hash"
test_resolve_fail "/ipns/$id_hash/b" "/ipfs/$b_hash"
test_resolve_fail "/ipns/$id_hash/b/c" "/ipfs/$c_hash"
test_resolve_setup_name_fail "/ipfs/$b_hash"
test_resolve_fail "/ipns/$id_hash" "/ipfs/$b_hash"
test_resolve_fail "/ipns/$id_hash/c" "/ipfs/$c_hash"
test_resolve_setup_name_fail "/ipfs/$c_hash"
test_resolve_fail "/ipns/$id_hash" "/ipfs/$c_hash"
}
# should work offline
test_resolve_cmd
# should work online
test_launch_ipfs_daemon
test_resolve_cmd_fail
test_kill_ipfs_daemon
test_done
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