resolve.go 3.16 KB
Newer Older
1 2 3
package commands

import (
4 5
	"io"
	"strings"
6

7
	cmds "github.com/ipfs/go-ipfs/commands"
8
	context "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
9
	namesys "github.com/ipfs/go-ipfs/namesys"
10
	path "github.com/ipfs/go-ipfs/path"
11
	u "github.com/ipfs/go-ipfs/util"
12 13
)

14 15
type ResolvedPath struct {
	Path path.Path
16 17
}

18
var ResolveCmd = &cmds.Command{
19
	Helptext: cmds.HelpText{
20
		Tagline: "Resolve the value of names to IPFS",
21
		ShortDescription: `
22 23 24
There are a number of mutable name protocols that can link among
themselves and into IPNS.  This command accepts any of these
identifiers and resolves them to the referenced item.
25 26
`,
		LongDescription: `
27 28 29 30 31
There are a number of mutable name protocols that can link among
themselves and into IPNS.  For example IPNS references can (currently)
point at IPFS object, and DNS links can point at other DNS links, IPNS
entries, or IPFS objects.  This command accepts any of these
identifiers and resolves them to the referenced item.
32 33 34 35 36

Examples:

Resolve the value of your identity:

37 38 39 40 41 42 43
  > ipfs resolve /ipns/QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy
  /ipfs/Qmcqtw8FfrVSBaRmbWwHxt3AuySBhJLcvmFYi3Lbc4xnwj

Resolve the value of another name:

  > ipfs resolve /ipns/QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n
  /ipns/QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy
44

45
Resolve the value of another name recursively:
46

47 48
  > ipfs resolve -r /ipns/QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n
  /ipfs/Qmcqtw8FfrVSBaRmbWwHxt3AuySBhJLcvmFYi3Lbc4xnwj
49 50

`,
51
	},
52 53

	Arguments: []cmds.Argument{
54
		cmds.StringArg("name", true, false, "The name to resolve.").EnableStdin(),
55
	},
56
	Options: []cmds.Option{
57
		cmds.BoolOption("recursive", "r", "Resolve until the result is an IPFS name"),
58
	},
59
	Run: func(req cmds.Request, res cmds.Response) {
60

Jeromy's avatar
Jeromy committed
61
		n, err := req.InvocContext().GetNode()
62
		if err != nil {
63 64
			res.SetError(err, cmds.ErrNormal)
			return
65 66
		}

67 68 69 70 71 72
		if !n.OnlineMode() {
			err := n.SetupOfflineRouting()
			if err != nil {
				res.SetError(err, cmds.ErrNormal)
				return
			}
73 74
		}

75
		name := req.Arguments()[0]
76 77 78 79 80 81
		recursive, _, _ := req.Option("recursive").Bool()
		depth := 1
		if recursive {
			depth = namesys.DefaultDepthLimit
		}

82 83 84 85 86 87 88 89 90 91
		if strings.HasPrefix(name, "/ipfs/") || !strings.HasPrefix(name, "/") {
			resolved, err := resolveIpfsPath(req.Context(), n.Resolver, name)
			if err != nil {
				res.SetError(err, cmds.ErrNormal)
				return
			}
			res.SetOutput(&ResolvedPath{resolved})
			return
		}

Jeromy's avatar
Jeromy committed
92
		output, err := n.Namesys.ResolveN(req.Context(), name, depth)
93
		if err != nil {
94 95
			res.SetError(err, cmds.ErrNormal)
			return
96 97
		}

98
		res.SetOutput(&ResolvedPath{output})
99
	},
100
	Marshalers: cmds.MarshalerMap{
101
		cmds.Text: func(res cmds.Response) (io.Reader, error) {
102
			output, ok := res.Output().(*ResolvedPath)
103 104 105
			if !ok {
				return nil, u.ErrCast()
			}
106
			return strings.NewReader(output.Path.String()), nil
107
		},
108
	},
109
	Type: ResolvedPath{},
110
}
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129

func resolveIpfsPath (ctx context.Context, r *path.Resolver, name string) (path.Path, error) {
	p, err := path.ParsePath(name)
	if err != nil {
		return "", err
	}

	node, err := r.ResolvePath(ctx, p)
	if err != nil {
		return "", err
	}

	key, err := node.Key()
	if err != nil {
		return "", err
	}

	return path.FromKey(key), nil
}