version.go 3.86 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

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

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

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

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

Steven Allen's avatar
Steven Allen committed
40 41 42 43 44
	Options: []cmds.Option{
		cmds.BoolOption(versionNumberOptionName, "n", "Only show the version number."),
		cmds.BoolOption(versionCommitOptionName, "Show the commit hash."),
		cmds.BoolOption(versionRepoOptionName, "Show repo version."),
		cmds.BoolOption(versionAllOptionName, "Show all version information"),
45
	},
46 47
	// must be permitted to run before init
	Extra: CreateCmdExtras(SetDoesNotUseRepo(true), SetDoesNotUseConfigAsInput(true)),
48
	Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
49
		return cmds.EmitOnce(res, &VersionOutput{
50 51
			Version: version.CurrentVersionNumber,
			Commit:  version.CurrentCommit,
52
			Repo:    fmt.Sprint(fsrepo.RepoVersion),
Jakub Sztandera's avatar
Jakub Sztandera committed
53 54
			System:  runtime.GOARCH + "/" + runtime.GOOS, //TODO: Precise version here
			Golang:  runtime.Version(),
55
		})
56
	},
57 58 59
	Encoders: cmds.EncoderMap{
		cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, version *VersionOutput) error {
			all, _ := req.Options[versionAllOptionName].(bool)
Jakub Sztandera's avatar
Jakub Sztandera committed
60
			if all {
61 62 63 64 65
				ver := version.Version
				if version.Commit != "" {
					ver += "-" + version.Commit
				}
				out := fmt.Sprintf("go-ipfs version: %s\n"+
Jakub Sztandera's avatar
Jakub Sztandera committed
66
					"Repo version: %s\nSystem version: %s\nGolang version: %s\n",
67
					ver, version.Repo, version.System, version.Golang)
68 69
				fmt.Fprint(w, out)
				return nil
Jakub Sztandera's avatar
Jakub Sztandera committed
70 71
			}

72 73 74 75 76 77
			commit, _ := req.Options[versionCommitOptionName].(bool)
			commitTxt := ""
			if commit && version.Commit != "" {
				commitTxt = "-" + version.Commit
			}

78 79 80 81 82 83 84 85 86 87 88 89
			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
			}

90 91 92
			fmt.Fprint(w, fmt.Sprintf("ipfs version %s%s\n", version.Version, commitTxt))
			return nil
		}),
93
	},
94
	Type: VersionOutput{},
95
}
96 97 98 99 100 101 102 103

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

104 105
const pkgVersionFmt = "%s@%s"

106
var depsVersionCommand = &cmds.Command{
Steven Allen's avatar
Steven Allen committed
107
	Helptext: cmds.HelpText{
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
		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 {
124
				dep.ReplacedBy = fmt.Sprintf(pkgVersionFmt, repl.Path, repl.Version)
125 126 127
			}
			return
		}
Jakub Sztandera's avatar
Jakub Sztandera committed
128 129 130
		if err := res.Emit(toDependency(&info.Main)); err != nil {
			return err
		}
131
		for _, dep := range info.Deps {
Jakub Sztandera's avatar
Jakub Sztandera committed
132 133 134
			if err := res.Emit(toDependency(dep)); err != nil {
				return err
			}
135 136 137 138 139
		}
		return nil
	},
	Encoders: cmds.EncoderMap{
		cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, dep Dependency) error {
140
			fmt.Fprintf(w, pkgVersionFmt, dep.Path, dep.Version)
141 142 143 144
			if dep.ReplacedBy != "" {
				fmt.Fprintf(w, " => %s", dep.ReplacedBy)
			}
			fmt.Fprintf(w, "\n")
Jakub Sztandera's avatar
Jakub Sztandera committed
145
			return nil
146 147 148
		}),
	},
}