resolve.go 3.24 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/QmZNVWh8LLjAavuQ2JXuFmuYH3C11xo988vSgp7UQrTRj1/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{
59
		cmds.StringArg("name", true, false, "The name to resolve."),
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, p)
103 104
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
105 106 107
			return
		}

108
		key, err := node.Key()
109
		if err != nil {
110 111
			res.SetError(err, cmds.ErrNormal)
			return
112 113
		}

114
		res.SetOutput(&ResolvedPath{path.FromKey(key)})
115
	},
116
	Marshalers: cmds.MarshalerMap{
117
		cmds.Text: func(res cmds.Response) (io.Reader, error) {
118
			output, ok := res.Output().(*ResolvedPath)
119 120 121
			if !ok {
				return nil, u.ErrCast()
			}
122
			return strings.NewReader(output.Path.String() + "\n"), nil
123
		},
124
	},
125
	Type: ResolvedPath{},
126
}