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

import (
4 5
	"io"
	"strings"
6

7
	cmds "github.com/ipfs/go-ipfs/commands"
8
	"github.com/ipfs/go-ipfs/core"
9
	ns "github.com/ipfs/go-ipfs/namesys"
10
	path "github.com/ipfs/go-ipfs/path"
11
	u "gx/ipfs/QmWbjfz3u6HkAdPh34dgPchGbQjob6LXLhAeCGii2TX69n/go-ipfs-util"
12 13
)

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

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

33
EXAMPLES
34 35 36

Resolve the value of your identity:

37
  $ ipfs resolve /ipns/QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy
38 39 40 41
  /ipfs/Qmcqtw8FfrVSBaRmbWwHxt3AuySBhJLcvmFYi3Lbc4xnwj

Resolve the value of another name:

42
  $ ipfs resolve /ipns/QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n
43
  /ipns/QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy
44

45
Resolve the value of another name recursively:
46

47
  $ ipfs resolve -r /ipns/QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n
48
  /ipfs/Qmcqtw8FfrVSBaRmbWwHxt3AuySBhJLcvmFYi3Lbc4xnwj
49

50 51
Resolve the value of an IPFS DAG path:

52
  $ ipfs resolve /ipfs/QmeZy1fGbwgVSrqbfh9fKQrAWgeyRnj7h8fsHS1oy3k99x/beep/boop
53 54
  /ipfs/QmYRMjyvAiHKN9UTi8Bzt1HUspmSRD8T8DwxfSMzLgBon1

55
`,
56
	},
57 58

	Arguments: []cmds.Argument{
Jeromy's avatar
Jeromy committed
59
		cmds.StringArg("name", true, false, "The name to resolve.").EnableStdin(),
60
	},
61
	Options: []cmds.Option{
62
		cmds.BoolOption("recursive", "r", "Resolve until the result is an IPFS name.").Default(false),
63
	},
64
	Run: func(req cmds.Request, res cmds.Response) {
65

Jeromy's avatar
Jeromy committed
66
		n, err := req.InvocContext().GetNode()
67
		if err != nil {
68 69
			res.SetError(err, cmds.ErrNormal)
			return
70 71
		}

72 73 74 75 76 77
		if !n.OnlineMode() {
			err := n.SetupOfflineRouting()
			if err != nil {
				res.SetError(err, cmds.ErrNormal)
				return
			}
78 79
		}

80
		name := req.Arguments()[0]
81
		recursive, _, _ := req.Option("recursive").Bool()
82 83 84 85

		// the case when ipns is resolved step by step
		if strings.HasPrefix(name, "/ipns/") && !recursive {
			p, err := n.Namesys.ResolveN(req.Context(), name, 1)
86 87
			// ErrResolveRecursion is fine
			if err != nil && err != ns.ErrResolveRecursion {
88 89 90 91 92
				res.SetError(err, cmds.ErrNormal)
				return
			}
			res.SetOutput(&ResolvedPath{p})
			return
93 94
		}

95 96 97 98 99
		// else, ipfs path or ipns with recursive flag
		p, err := path.ParsePath(name)
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
100
		}
101

102
		node, err := core.Resolve(req.Context(), n.Namesys, n.Resolver, p)
103 104
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
105 106 107
			return
		}

Jeromy's avatar
Jeromy committed
108
		c := node.Cid()
109

Jeromy's avatar
Jeromy committed
110
		res.SetOutput(&ResolvedPath{path.FromCid(c)})
111
	},
112
	Marshalers: cmds.MarshalerMap{
113
		cmds.Text: func(res cmds.Response) (io.Reader, error) {
114
			output, ok := res.Output().(*ResolvedPath)
115 116 117
			if !ok {
				return nil, u.ErrCast()
			}
118
			return strings.NewReader(output.Path.String() + "\n"), nil
119
		},
120
	},
121
	Type: ResolvedPath{},
122
}