version.go 3.7 KB
Newer Older
1 2 3
package commands

import (
4
	"errors"
Brian Tiger Chow's avatar
Brian Tiger Chow committed
5
	"fmt"
6
	"io"
Jakub Sztandera's avatar
Jakub Sztandera committed
7
	"runtime"
8
	"runtime/debug"
Brian Tiger Chow's avatar
Brian Tiger Chow committed
9

10
	version "github.com/ipfs/go-ipfs"
11
	fsrepo "github.com/ipfs/go-ipfs/repo/fsrepo"
12

13
	cmdkit "github.com/ipfs/go-ipfs-cmdkit"
Jakub Sztandera's avatar
Jakub Sztandera committed
14
	cmds "github.com/ipfs/go-ipfs-cmds"
15 16 17 18
)

type VersionOutput struct {
	Version string
19 20
	Commit  string
	Repo    string
Jakub Sztandera's avatar
Jakub Sztandera committed
21 22
	System  string
	Golang  string
23 24
}

Kejie Zhang's avatar
Kejie Zhang committed
25 26 27 28 29 30 31
const (
	versionNumberOptionName = "number"
	versionCommitOptionName = "commit"
	versionRepoOptionName   = "repo"
	versionAllOptionName    = "all"
)

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
32
var VersionCmd = &cmds.Command{
Jan Winkelmann's avatar
Jan Winkelmann committed
33
	Helptext: cmdkit.HelpText{
34
		Tagline:          "Show ipfs version information.",
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
35
		ShortDescription: "Returns the current version of ipfs and exits.",
36
	},
37 38 39
	Subcommands: map[string]*cmds.Command{
		"deps": depsVersionCommand,
	},
40

Jan Winkelmann's avatar
Jan Winkelmann committed
41
	Options: []cmdkit.Option{
Kejie Zhang's avatar
Kejie Zhang committed
42 43 44 45
		cmdkit.BoolOption(versionNumberOptionName, "n", "Only show the version number."),
		cmdkit.BoolOption(versionCommitOptionName, "Show the commit hash."),
		cmdkit.BoolOption(versionRepoOptionName, "Show repo version."),
		cmdkit.BoolOption(versionAllOptionName, "Show all version information"),
46
	},
47
	Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
48
		return cmds.EmitOnce(res, &VersionOutput{
49 50
			Version: version.CurrentVersionNumber,
			Commit:  version.CurrentCommit,
51
			Repo:    fmt.Sprint(fsrepo.RepoVersion),
Jakub Sztandera's avatar
Jakub Sztandera committed
52 53
			System:  runtime.GOARCH + "/" + runtime.GOOS, //TODO: Precise version here
			Golang:  runtime.Version(),
54
		})
55
	},
56 57 58
	Encoders: cmds.EncoderMap{
		cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, version *VersionOutput) error {
			commit, _ := req.Options[versionCommitOptionName].(bool)
59
			commitTxt := ""
60
			if commit {
Jan Winkelmann's avatar
Jan Winkelmann committed
61
				commitTxt = "-" + version.Commit
62 63
			}

64
			all, _ := req.Options[versionAllOptionName].(bool)
Jakub Sztandera's avatar
Jakub Sztandera committed
65 66 67
			if all {
				out := fmt.Sprintf("go-ipfs version: %s-%s\n"+
					"Repo version: %s\nSystem version: %s\nGolang version: %s\n",
Jan Winkelmann's avatar
Jan Winkelmann committed
68
					version.Version, version.Commit, version.Repo, version.System, version.Golang)
69 70
				fmt.Fprint(w, out)
				return nil
Jakub Sztandera's avatar
Jakub Sztandera committed
71 72
			}

73 74 75 76 77 78 79 80 81 82 83 84
			repo, _ := req.Options[versionRepoOptionName].(bool)
			if repo {
				fmt.Fprintln(w, version.Repo)
				return nil
			}

			number, _ := req.Options[versionNumberOptionName].(bool)
			if number {
				fmt.Fprintln(w, version.Version+commitTxt)
				return nil
			}

85 86 87
			fmt.Fprint(w, fmt.Sprintf("ipfs version %s%s\n", version.Version, commitTxt))
			return nil
		}),
88
	},
89
	Type: VersionOutput{},
90
}
91 92 93 94 95 96 97 98

type Dependency struct {
	Path       string
	Version    string
	ReplacedBy string
	Sum        string
}

99 100
const pkgVersionFmt = "%s@%s"

101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
var depsVersionCommand = &cmds.Command{
	Helptext: cmdkit.HelpText{
		Tagline: "Shows information about dependencies used for build",
		ShortDescription: `
Print out all dependencies and their versions.`,
	},
	Type: Dependency{},

	Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
		info, ok := debug.ReadBuildInfo()
		if !ok {
			return errors.New("no embedded dependency information")
		}
		toDependency := func(mod *debug.Module) (dep Dependency) {
			dep.Path = mod.Path
			dep.Version = mod.Version
			dep.Sum = mod.Sum
			if repl := mod.Replace; repl != nil {
119
				dep.ReplacedBy = fmt.Sprintf(pkgVersionFmt, repl.Path, repl.Version)
120 121 122
			}
			return
		}
Jakub Sztandera's avatar
Jakub Sztandera committed
123 124 125
		if err := res.Emit(toDependency(&info.Main)); err != nil {
			return err
		}
126
		for _, dep := range info.Deps {
Jakub Sztandera's avatar
Jakub Sztandera committed
127 128 129
			if err := res.Emit(toDependency(dep)); err != nil {
				return err
			}
130 131 132 133 134
		}
		return nil
	},
	Encoders: cmds.EncoderMap{
		cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, dep Dependency) error {
135
			fmt.Fprintf(w, pkgVersionFmt, dep.Path, dep.Version)
136 137 138 139
			if dep.ReplacedBy != "" {
				fmt.Fprintf(w, " => %s", dep.ReplacedBy)
			}
			fmt.Fprintf(w, "\n")
Jakub Sztandera's avatar
Jakub Sztandera committed
140
			return nil
141 142 143
		}),
	},
}