mirror of
https://github.com/ipfs/kubo.git
synced 2025-06-26 15:42:21 +08:00
Merge pull request #1662 from ipfs/ipfs-path-resolve
Resolve IPFS DAG paths in `ipfs resolve` command
This commit is contained in:
@ -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
|
||||
}
|
||||
|
||||
output, err := n.Namesys.ResolveN(req.Context(), name, depth)
|
||||
// else, ipfs path or ipns with recursive flag
|
||||
p, err := path.ParsePath(name)
|
||||
if err != nil {
|
||||
res.SetError(err, cmds.ErrNormal)
|
||||
return
|
||||
}
|
||||
|
||||
res.SetOutput(&ResolvedPath{output})
|
||||
node, err := core.Resolve(req.Context(), n, p)
|
||||
if err != nil {
|
||||
res.SetError(err, cmds.ErrNormal)
|
||||
return
|
||||
}
|
||||
|
||||
key, err := node.Key()
|
||||
if err != nil {
|
||||
res.SetError(err, cmds.ErrNormal)
|
||||
return
|
||||
}
|
||||
|
||||
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/") {
|
||||
|
117
test/sharness/t0160-resolve.sh
Executable file
117
test/sharness/t0160-resolve.sh
Executable file
@ -0,0 +1,117 @@
|
||||
#!/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
|
Reference in New Issue
Block a user