version.go 3.73 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
	Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
47
		return cmds.EmitOnce(res, &VersionOutput{
48 49
			Version: version.CurrentVersionNumber,
			Commit:  version.CurrentCommit,
50
			Repo:    fmt.Sprint(fsrepo.RepoVersion),
Jakub Sztandera's avatar
Jakub Sztandera committed
51 52
			System:  runtime.GOARCH + "/" + runtime.GOOS, //TODO: Precise version here
			Golang:  runtime.Version(),
53
		})
54
	},
55 56 57
	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
58
			if all {
59 60 61 62 63
				ver := version.Version
				if version.Commit != "" {
					ver += "-" + version.Commit
				}
				out := fmt.Sprintf("go-ipfs version: %s\n"+
Jakub Sztandera's avatar
Jakub Sztandera committed
64
					"Repo version: %s\nSystem version: %s\nGolang version: %s\n",
65
					ver, version.Repo, version.System, version.Golang)
66 67
				fmt.Fprint(w, out)
				return nil
Jakub Sztandera's avatar
Jakub Sztandera committed
68 69
			}

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

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

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

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

102 103
const pkgVersionFmt = "%s@%s"

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