From 1d07afb30ee9ff00de72182200b7e1c6d1606d77 Mon Sep 17 00:00:00 2001 From: Eugene Burkov Date: Wed, 31 Mar 2021 12:55:21 +0300 Subject: [PATCH] Pull request: 2416 improve version output Merge in DNS/adguard-home from 2416-version to master Updates #2416. Squashed commit of the following: commit ad529ee429abd7fa12400e089a4e566da3df9f66 Merge: 9ba2f684 bfc7e16d Author: Eugene Burkov Date: Wed Mar 31 12:42:37 2021 +0300 Merge branch 'master' into 2416-version commit 9ba2f6845b1202909f3e142ae99e44815c9e090e Author: Eugene Burkov Date: Wed Mar 31 12:40:53 2021 +0300 all: fix docs commit 521a61df49381fecf1bc992752d7cbbcccb23bb6 Author: Eugene Burkov Date: Tue Mar 30 17:48:56 2021 +0300 all: imp code commit 844c4e0fb0192779bea4bfd3b0f5e4cf69e2073c Author: Eugene Burkov Date: Tue Mar 30 17:48:56 2021 +0300 all: imp docs, log changes commit c8206b0d161a7040dec7983dbaa240a8d08f4746 Author: Eugene Burkov Date: Tue Mar 30 17:19:51 2021 +0300 version: imp verbose output commit b2b41d478023bdd2dd01a73c44be309ba94e4ac8 Author: Eugene Burkov Date: Tue Mar 30 16:37:23 2021 +0300 version: imp code, docs commit 553bd9ce5fb59348f5ecd21a762dccf3834befee Author: Eugene Burkov Date: Tue Mar 30 14:07:05 2021 +0300 version: imp verbosed output --- .github/ISSUE_TEMPLATE/Bug_report.md | 2 +- CHANGELOG.md | 2 + internal/home/options.go | 24 +++- internal/version/norace.go | 5 + internal/version/race.go | 5 + internal/version/version.go | 176 +++++++++++++++++++++++---- scripts/make/go-build.sh | 7 +- 7 files changed, 192 insertions(+), 29 deletions(-) create mode 100644 internal/version/norace.go create mode 100644 internal/version/race.go diff --git a/.github/ISSUE_TEMPLATE/Bug_report.md b/.github/ISSUE_TEMPLATE/Bug_report.md index 9aaebca4..f2fe2ac0 100644 --- a/.github/ISSUE_TEMPLATE/Bug_report.md +++ b/.github/ISSUE_TEMPLATE/Bug_report.md @@ -15,7 +15,7 @@ Please answer the following questions for yourself before submitting an issue. * ### Issue Details - + * **Version of AdGuard Home server:** * diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a3c1f64..870842c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ and this project adheres to ### Added +- Verbose version output with `-v --version` ([#2416]). - The ability to set a custom TLD for known local-network hosts ([#2393]). - The ability to serve DNS queries on multiple hosts and interfaces ([#1401]). - `ips` and `text` DHCP server options ([#2385]). @@ -45,6 +46,7 @@ and this project adheres to [#2385]: https://github.com/AdguardTeam/AdGuardHome/issues/2385 [#2393]: https://github.com/AdguardTeam/AdGuardHome/issues/2393 [#2412]: https://github.com/AdguardTeam/AdGuardHome/issues/2412 +[#2416]: https://github.com/AdguardTeam/AdGuardHome/issues/2416 [#2498]: https://github.com/AdguardTeam/AdGuardHome/issues/2498 [#2533]: https://github.com/AdguardTeam/AdGuardHome/issues/2533 [#2541]: https://github.com/AdguardTeam/AdGuardHome/issues/2541 diff --git a/internal/home/options.go b/internal/home/options.go index 553ed856..293c50b0 100644 --- a/internal/home/options.go +++ b/internal/home/options.go @@ -191,16 +191,28 @@ var glinetArg = arg{ } var versionArg = arg{ - "Show the version and exit", - "version", "", - nil, nil, func(o options, exec string) (effect, error) { - return func() error { fmt.Println(version.Full()); os.Exit(0); return nil }, nil + description: "Show the version and exit", + longName: "version", + shortName: "", + updateWithValue: nil, + updateNoValue: nil, + effect: func(o options, exec string) (effect, error) { + return func() error { + if o.verbose { + fmt.Println(version.Verbose()) + } else { + fmt.Println(version.Full()) + } + os.Exit(0) + + return nil + }, nil }, - func(o options) []string { return nil }, + serialize: func(o options) []string { return nil }, } var helpArg = arg{ - "Print this help", + "Print this help. Show more detailed version description with -v", "help", "", nil, nil, func(o options, exec string) (effect, error) { return func() error { _ = printHelp(exec); os.Exit(64); return nil }, nil diff --git a/internal/version/norace.go b/internal/version/norace.go new file mode 100644 index 00000000..5b1ccacb --- /dev/null +++ b/internal/version/norace.go @@ -0,0 +1,5 @@ +// +build !race + +package version + +const isRace = false diff --git a/internal/version/race.go b/internal/version/race.go new file mode 100644 index 00000000..6db3a347 --- /dev/null +++ b/internal/version/race.go @@ -0,0 +1,5 @@ +// +build race + +package version + +const isRace = true diff --git a/internal/version/version.go b/internal/version/version.go index df79a9c0..7d0a28e9 100644 --- a/internal/version/version.go +++ b/internal/version/version.go @@ -4,19 +4,9 @@ package version import ( "fmt" "runtime" -) - -// These are set by the linker. Unfortunately we cannot set constants during -// linking, and Go doesn't have a concept of immutable variables, so to be -// thorough we have to only export them through getters. -// -// TODO(a.garipov): Find out if we can get GOARM and GOMIPS values the same way -// we can GOARCH and GOOS. -var ( - channel string = ChannelDevelopment - goarm string - gomips string - version string + "runtime/debug" + "strconv" + "strings" ) // Channel constants. @@ -27,21 +17,31 @@ const ( ChannelRelease = "release" ) +// These are set by the linker. Unfortunately we cannot set constants during +// linking, and Go doesn't have a concept of immutable variables, so to be +// thorough we have to only export them through getters. +// +// TODO(a.garipov): Find out if we can get GOARM and GOMIPS values the same way +// we can GOARCH and GOOS. +var ( + channel string = ChannelDevelopment + goarm string + gomips string + version string + buildtime string +) + // Channel returns the current AdGuard Home release channel. func Channel() (v string) { return channel } +// vFmtFull defines the format of full version output. +const vFmtFull = "AdGuard Home, version %s" + // Full returns the full current version of AdGuard Home. func Full() (v string) { - msg := "AdGuard Home, version %s, channel %s, arch %s %s" - if goarm != "" { - msg = msg + " v" + goarm - } else if gomips != "" { - msg = msg + " " + gomips - } - - return fmt.Sprintf(msg, version, channel, runtime.GOOS, runtime.GOARCH) + return fmt.Sprintf(vFmtFull, version) } // GOARM returns the GOARM value used to build the current AdGuard Home release. @@ -59,3 +59,137 @@ func GOMIPS() (v string) { func Version() (v string) { return version } + +// Common formatting constants. +const ( + sp = " " + nl = "\n" + tb = "\t" + nltb = nl + tb +) + +// writeStrings is a convenient wrapper for strings.(*Builder).WriteString that +// deals with multiple strings and ignores errors that are guaranteed to be nil. +func writeStrings(b *strings.Builder, strs ...string) { + for _, s := range strs { + _, _ = b.WriteString(s) + } +} + +// Constants defining the format of module information string. +const ( + modInfoAtSep = "@" + modInfoDevSep = sp + modInfoSumLeft = " (sum: " + modInfoSumRight = ")" +) + +// fmtModule returns formatted information about module. The result looks like: +// +// github.com/Username/module@v1.2.3 (sum: someHASHSUM=) +// +func fmtModule(m *debug.Module) (formatted string) { + if m == nil { + return "" + } + + if repl := m.Replace; repl != nil { + return fmtModule(repl) + } + + b := &strings.Builder{} + + writeStrings(b, m.Path) + if ver := m.Version; ver != "" { + sep := modInfoAtSep + if ver == "(devel)" { + sep = modInfoDevSep + } + writeStrings(b, sep, ver) + } + if sum := m.Sum; sum != "" { + writeStrings(b, modInfoSumLeft, sum, modInfoSumRight) + } + + return b.String() +} + +// Constants defining the headers of build information message. +const ( + vFmtAGHHdr = "AdGuard Home" + vFmtVerHdr = "Version: " + vFmtChanHdr = "Channel: " + vFmtGoHdr = "Go version: " + vFmtTimeHdr = "Build time: " + vFmtRaceHdr = "Race: " + vFmtGOOSHdr = "GOOS: " + runtime.GOOS + vFmtGOARCHHdr = "GOARCH: " + runtime.GOARCH + vFmtGOARMHdr = "GOARM: " + vFmtGOMIPSHdr = "GOMIPS: " + vFmtMainHdr = "Main module:" + vFmtDepsHdr = "Dependencies:" +) + +// Verbose returns formatted build information. Output example: +// +// AdGuard Home +// Version: v0.105.3 +// Channel: development +// Go version: go1.15.3 +// Build time: 2021-03-30T16:26:08Z+0300 +// GOOS: darwin +// GOARCH: amd64 +// Race: false +// Main module: +// ... +// Dependencies: +// ... +// +// TODO(e.burkov): Make it write into passed io.Writer. +func Verbose() (v string) { + b := &strings.Builder{} + + writeStrings( + b, + vFmtAGHHdr, + nl, + vFmtVerHdr, + version, + nl, + vFmtChanHdr, + channel, + nl, + vFmtGoHdr, + runtime.Version(), + ) + if buildtime != "" { + writeStrings(b, nl, vFmtTimeHdr, buildtime) + } + writeStrings(b, nl, vFmtGOOSHdr, nl, vFmtGOARCHHdr) + if goarm != "" { + writeStrings(b, nl, vFmtGOARMHdr, "v", goarm) + } else if gomips != "" { + writeStrings(b, nl, vFmtGOMIPSHdr, gomips) + } + writeStrings(b, nl, vFmtRaceHdr, strconv.FormatBool(isRace)) + + info, ok := debug.ReadBuildInfo() + if !ok { + return b.String() + } + + writeStrings(b, nl, vFmtMainHdr, nltb, fmtModule(&info.Main)) + + if len(info.Deps) == 0 { + return b.String() + } + + writeStrings(b, nl, vFmtDepsHdr) + for _, dep := range info.Deps { + if depStr := fmtModule(dep); depStr != "" { + writeStrings(b, nltb, depStr) + } + } + + return b.String() +} diff --git a/scripts/make/go-build.sh b/scripts/make/go-build.sh index dbf6f7ac..353ea7e2 100644 --- a/scripts/make/go-build.sh +++ b/scripts/make/go-build.sh @@ -54,12 +54,17 @@ esac # TODO(a.garipov): Additional validation? version="$VERSION" +# Set date and time of the current build. +buildtime="$(date -u +%FT%TZ%z)" + # Set the linker flags accordingly: set the release channel and the # current version as well as goarm and gomips variable values, if the # variables are set and are not empty. readonly version_pkg='github.com/AdguardTeam/AdGuardHome/internal/version' -ldflags="-s -w -X ${version_pkg}.version=${version}" +ldflags="-s -w" +ldflags="${ldflags} -X ${version_pkg}.version=${version}" ldflags="${ldflags} -X ${version_pkg}.channel=${channel}" +ldflags="${ldflags} -X ${version_pkg}.buildtime=${buildtime}" if [ "${GOARM:-}" != '' ] then ldflags="${ldflags} -X ${version_pkg}.goarm=${GOARM}"