diff --git a/lib/flags/loadflags/api.go b/lib/flags/loadflags/api.go index ce21c669..c2dc6bf6 100644 --- a/lib/flags/loadflags/api.go +++ b/lib/flags/loadflags/api.go @@ -5,9 +5,11 @@ import ( ) func LoadForCli(progName string) error { + registerVersionFlag(progName) return loadForCli(progName) } func LoadForDaemon(progName string) error { + registerVersionFlag(progName) return loadFlags(filepath.Join("/etc", progName)) } diff --git a/lib/flags/loadflags/impl.go b/lib/flags/loadflags/impl.go index 6b257e18..e70c8e19 100644 --- a/lib/flags/loadflags/impl.go +++ b/lib/flags/loadflags/impl.go @@ -8,10 +8,24 @@ import ( "os" "path/filepath" "strings" + + "github.com/Cloud-Foundations/Dominator/lib/version" ) const systemDir = "/etc/config" +func registerVersionFlag(name string) { + flag.BoolFunc("version", "Print version information and exit", func(string) error { + info := version.Get() + fmt.Printf("%s %s\n", name, info.Version) + fmt.Printf(" Commit: %s\n", info.GitCommit) + fmt.Printf(" Built: %s\n", info.BuildDate) + fmt.Printf(" Go: %s\n", info.GoVersion) + os.Exit(0) + return nil + }) +} + func loadFlags(dirname string) error { err := loadFlagsFromFile(filepath.Join(dirname, "flags.default")) if err != nil { diff --git a/lib/version/VERSION b/lib/version/VERSION new file mode 100644 index 00000000..3061e9e5 --- /dev/null +++ b/lib/version/VERSION @@ -0,0 +1 @@ +v0.12.0 \ No newline at end of file diff --git a/lib/version/version.go b/lib/version/version.go new file mode 100644 index 00000000..c2e08856 --- /dev/null +++ b/lib/version/version.go @@ -0,0 +1,77 @@ +package version + +import ( + _ "embed" + "fmt" + "runtime" + "runtime/debug" + "strings" +) + +//go:embed VERSION +var baseVersion string + +type Info struct { + Version string `json:"version"` + GitCommit string `json:"gitCommit"` + BuildDate string `json:"buildDate"` + GoVersion string `json:"goVersion"` + Dirty bool `json:"dirty"` +} + +func Get() Info { + vcs := getVCSInfo() + version := strings.TrimSpace(baseVersion) + if vcs.revision != "unknown" { + version += "+" + vcs.revision + } + if vcs.dirty { + version += "-dirty" + } + return Info{ + Version: version, + GitCommit: vcs.revision, + BuildDate: vcs.buildTime, + GoVersion: runtime.Version(), + Dirty: vcs.dirty, + } +} + +func (i Info) String() string { + return fmt.Sprintf("%s (built: %s)", i.Version, i.BuildDate) +} + +type vcsInfo struct { + revision string + buildTime string + dirty bool +} + +func getVCSInfo() vcsInfo { + info := vcsInfo{ + revision: "unknown", + buildTime: "unknown", + } + + buildInfo, ok := debug.ReadBuildInfo() + if !ok { + return info + } + + for _, s := range buildInfo.Settings { + switch s.Key { + case "vcs.revision": + if len(s.Value) > 8 { + info.revision = s.Value[:8] + } else { + info.revision = s.Value + } + case "vcs.time": + info.buildTime = s.Value + case "vcs.modified": + info.dirty = s.Value == "true" + } + } + + return info +}