Skip to content

Commit

Permalink
attempt to handle --version even in untagged builds
Browse files Browse the repository at this point in the history
If we are installed via `go-install` rather than downloading a
tagged binary from github, the `Tag` etc variables will all be
empty, and therefore the `--version` flag is diked out. But there
is a way around this!

If the version info is not filled in via build-time flags, use
`debug.BuildInfo` to introspect as much information as we can
out of the module metadata:

```
$ go install github.com/odenio/goimports-reviser/[email protected]
go: downloading github.com/odenio/goimports-reviser/v3 v3.6.6-pre5

$ ~/go/bin/goimports-reviser --version
version: 3.6.6-pre5
built with: go1.22.4
tag: v3.6.6-pre5
commit: n/a
source: github.com/odenio/goimports-reviser/v3
```

Additionally, add a `--version-only` flag that prints only the version
string itself, handy for use in shell pipelines. Can be used on its own
or in combination with the `--version` flag:

```
$ ./go/bin/goimports-reviser --version-only
3.6.6-pre5
```
  • Loading branch information
n-oden committed Jul 12, 2024
1 parent 5f29621 commit 0730f56
Showing 1 changed file with 86 additions and 14 deletions.
100 changes: 86 additions & 14 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@ package main
import (
"crypto/md5"
"encoding/hex"
"errors"
"flag"
"fmt"
"log"
"os"
"os/user"
"path"
"path/filepath"
"regexp"
"runtime/debug"
"strings"

"github.com/incu6us/goimports-reviser/v3/helper"
Expand All @@ -19,6 +22,7 @@ import (
const (
projectNameArg = "project-name"
versionArg = "version"
versionOnlyArg = "version-only"
removeUnusedImportsArg = "rm-unused"
setAliasArg = "set-alias"
companyPkgPrefixesArg = "company-prefixes"
Expand All @@ -31,6 +35,7 @@ const (
useCacheArg = "use-cache"
applyToGeneratedFiles = "apply-to-generated-files"
excludesArg = "excludes"
modulePathRegex = `^github.com/\w+/goimports-reviser(/v\d+)?@?`

// Deprecated options
localArg = "local"
Expand All @@ -45,6 +50,7 @@ var (
GoVersion string

shouldShowVersion *bool
shouldShowVersionOnly *bool
shouldRemoveUnusedImports *bool
shouldSetAlias *bool
shouldFormat *bool
Expand All @@ -53,6 +59,7 @@ var (
setExitStatus *bool
isRecursive *bool
isUseCache *bool
modulePathMatcher = regexp.MustCompile(modulePathRegex)
)

var (
Expand Down Expand Up @@ -168,13 +175,18 @@ Optional parameter.`,
"Apply imports sorting and formatting(if the option is set) to generated files. Generated file is a file with first comment which starts with comment '// Code generated'. Optional parameter.",
)

if Tag != "" {
shouldShowVersion = flag.Bool(
versionArg,
false,
"Show version.",
)
}
shouldShowVersion = flag.Bool(
versionArg,
false,
"Show version information",
)

shouldShowVersionOnly = flag.Bool(
versionOnlyArg,
false,
"Show only the version string",
)

}

func printUsage() {
Expand All @@ -185,27 +197,87 @@ func printUsage() {
flag.PrintDefaults()
}

func getBuildInfo() *debug.BuildInfo {
bi, ok := debug.ReadBuildInfo()
if !ok {
return nil
}
return bi
}

func getMyModuleInfo(bi *debug.BuildInfo) (*debug.Module, error) {
if bi == nil {
return nil, errors.New("no build info available")
}
// depending on the context in which we are called, the main module may not be set
if bi.Main.Path != "" {
return &bi.Main, nil
}
// if the main module is not set, we need to find the dep that contains our module
for _, m := range bi.Deps {
if modulePathMatcher.MatchString(m.Path) {
return m, nil
}
}
return nil, errors.New("no matching module found in build info")
}

func printVersion() {
if Tag != "" {
fmt.Printf(
"version: %s\nbuilt with: %s\ntag: %s\ncommit: %s\nsource: %s\n",
strings.TrimPrefix(Tag, "v"),
GoVersion,
Tag,
Commit,
SourceURL,
)
return
}
bi := getBuildInfo()
myModule, err := getMyModuleInfo(bi)
if err != nil {
log.Fatalf("failed to get my module info: %s", err)
}
fmt.Printf(
"version: %s\nbuild with: %s\ntag: %s\ncommit: %s\nsource: %s\n",
strings.TrimPrefix(Tag, "v"),
GoVersion,
Tag,
Commit,
SourceURL,
"version: %s\nbuilt with: %s\ntag: %s\ncommit: %s\nsource: %s\n",
strings.TrimPrefix(myModule.Version, "v"),
bi.GoVersion,
myModule.Version,
"n/a",
myModule.Path,
)
}

func printVersionOnly() {
if Tag != "" {
fmt.Println(strings.TrimPrefix(Tag, "v"))
return
}
bi := getBuildInfo()
myModule, err := getMyModuleInfo(bi)
if err != nil {
log.Fatalf("failed to get my module info: %s", err)
}
fmt.Println(strings.TrimPrefix(myModule.Version, "v"))
}

func main() {
deprecatedMessagesCh := make(chan string, 10)
flag.Parse()

if shouldShowVersionOnly != nil && *shouldShowVersionOnly {
printVersionOnly()
return
}

if shouldShowVersion != nil && *shouldShowVersion {
printVersion()
return
}

originPath := flag.Arg(0)

if filePath != "" {
deprecatedMessagesCh <- fmt.Sprintf("-%s is deprecated. Put file name as last argument to the command(Example: goimports-reviser -rm-unused -set-alias -format goimports-reviser/main.go)", filePathArg)
originPath = filePath
Expand Down Expand Up @@ -391,7 +463,7 @@ func validateRequiredParam(filePath string) error {
stat, _ := os.Stdin.Stat()
if stat.Mode()&os.ModeNamedPipe == 0 {
// no data on stdin
return fmt.Errorf("no data on stdin")
return errors.New("no data on stdin")
}
}
return nil
Expand Down

0 comments on commit 0730f56

Please sign in to comment.