resolve.go 3.33 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"
Jan Winkelmann's avatar
Jan Winkelmann committed
9
	e "github.com/ipfs/go-ipfs/core/commands/e"
10
	ns "github.com/ipfs/go-ipfs/namesys"
11
	path "github.com/ipfs/go-ipfs/path"
Jan Winkelmann's avatar
Jan Winkelmann committed
12

13
	"gx/ipfs/QmceUdzxkimdYsgtX733uNgzf1DLHyBKN6ehGSp85ayppM/go-ipfs-cmdkit"
14 15
)

16 17
type ResolvedPath struct {
	Path path.Path
18 19
}

20
var ResolveCmd = &cmds.Command{
Jan Winkelmann's avatar
Jan Winkelmann committed
21
	Helptext: cmdkit.HelpText{
rht's avatar
rht committed
22
		Tagline: "Resolve the value of names to IPFS.",
23
		ShortDescription: `
24
There are a number of mutable name protocols that can link among
25
themselves and into IPNS. This command accepts any of these
26
identifiers and resolves them to the referenced item.
27 28
`,
		LongDescription: `
29
There are a number of mutable name protocols that can link among
30 31 32
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
33
identifiers and resolves them to the referenced item.
34

35
EXAMPLES
36 37 38

Resolve the value of your identity:

39
  $ ipfs resolve /ipns/QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy
40 41 42 43
  /ipfs/Qmcqtw8FfrVSBaRmbWwHxt3AuySBhJLcvmFYi3Lbc4xnwj

Resolve the value of another name:

44
  $ ipfs resolve /ipns/QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n
45
  /ipns/QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy
46

47
Resolve the value of another name recursively:
48

49
  $ ipfs resolve -r /ipns/QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n
50
  /ipfs/Qmcqtw8FfrVSBaRmbWwHxt3AuySBhJLcvmFYi3Lbc4xnwj
51

52 53
Resolve the value of an IPFS DAG path:

54
  $ ipfs resolve /ipfs/QmeZy1fGbwgVSrqbfh9fKQrAWgeyRnj7h8fsHS1oy3k99x/beep/boop
55 56
  /ipfs/QmYRMjyvAiHKN9UTi8Bzt1HUspmSRD8T8DwxfSMzLgBon1

57
`,
58
	},
59

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

Jeromy's avatar
Jeromy committed
68
		n, err := req.InvocContext().GetNode()
69
		if err != nil {
Jan Winkelmann's avatar
Jan Winkelmann committed
70
			res.SetError(err, cmdkit.ErrNormal)
71
			return
72 73
		}

74 75 76
		if !n.OnlineMode() {
			err := n.SetupOfflineRouting()
			if err != nil {
Jan Winkelmann's avatar
Jan Winkelmann committed
77
				res.SetError(err, cmdkit.ErrNormal)
78 79
				return
			}
80 81
		}

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

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

97 98 99
		// else, ipfs path or ipns with recursive flag
		p, err := path.ParsePath(name)
		if err != nil {
Jan Winkelmann's avatar
Jan Winkelmann committed
100
			res.SetError(err, cmdkit.ErrNormal)
101
			return
102
		}
103

104
		node, err := core.Resolve(req.Context(), n.Namesys, n.Resolver, p)
105
		if err != nil {
Jan Winkelmann's avatar
Jan Winkelmann committed
106
			res.SetError(err, cmdkit.ErrNormal)
107 108 109
			return
		}

Jeromy's avatar
Jeromy committed
110
		c := node.Cid()
111

Jeromy's avatar
Jeromy committed
112
		res.SetOutput(&ResolvedPath{path.FromCid(c)})
113
	},
114
	Marshalers: cmds.MarshalerMap{
115
		cmds.Text: func(res cmds.Response) (io.Reader, error) {
Jan Winkelmann's avatar
Jan Winkelmann committed
116 117 118 119 120 121
			v, err := unwrapOutput(res.Output())
			if err != nil {
				return nil, err
			}

			output, ok := v.(*ResolvedPath)
122
			if !ok {
Jan Winkelmann's avatar
Jan Winkelmann committed
123
				return nil, e.TypeErr(output, v)
124
			}
125
			return strings.NewReader(output.Path.String() + "\n"), nil
126
		},
127
	},
128
	Type: ResolvedPath{},
129
}