summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/cron.yml40
-rw-r--r--Makefile13
-rw-r--r--commands/root.go79
-rw-r--r--commands/version.go87
-rw-r--r--doc/generate.go2
-rw-r--r--doc/man/git-bug-version.137
-rw-r--r--doc/md/git-bug.md2
-rw-r--r--doc/md/git-bug_version.md38
-rw-r--r--main.go8
-rw-r--r--misc/completion/generate.go2
-rw-r--r--version.go94
11 files changed, 259 insertions, 143 deletions
diff --git a/.github/workflows/cron.yml b/.github/workflows/cron.yml
new file mode 100644
index 000000000..e68c9db05
--- /dev/null
+++ b/.github/workflows/cron.yml
@@ -0,0 +1,40 @@
+---
+name: cron
+
+on:
+ schedule:
+ - cron: '0 10 31 5 *' # 05/31 at 10:00
+
+permissions:
+ contents: read
+
+jobs:
+ rename-default-branch:
+ runs-on: ubuntu-latest
+ if: github.ref_name == "master"
+ steps:
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ with:
+ fetch-depth: 0
+
+ - name: configure git remote
+ run: |
+ git remote set-url origin git@github.com:git-bug/git-bug.git
+
+ - name: "merge pull request: 1464"
+ env:
+ GH_TOKEN: ${{ secrets.RENAME_TOKEN_1404 }}
+ run: gh pr merge 1464 --admin --squash
+
+ - name: "set default branch: refs/heads/trunk"
+ env:
+ GH_TOKEN: ${{ secrets.RENAME_TOKEN_1404 }}
+ run: gh repo edit --default-branch trunk
+
+ - name: "set base for all PRs: refs/heads/trunk"
+ env:
+ GH_TOKEN: ${{ secrets.RENAME_TOKEN_1404 }}
+ run: |-
+ for pr in $(gh pr list -B master -s open --json number --jq '.[] | .number'); do
+ gh pr edit "$pr" -B trunk
+ done
diff --git a/Makefile b/Makefile
index 608679926..4745d195d 100644
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,3 @@
-all: build
-
-GIT_COMMIT:=$(shell git rev-list -1 HEAD)
-GIT_LAST_TAG:=$(shell git describe --abbrev=0 --tags 2>/dev/null || true)
-GIT_EXACT_TAG:=$(shell git name-rev --name-only --tags HEAD)
UNAME_S := $(shell uname -s)
XARGS:=xargs -r
ifeq ($(UNAME_S),Darwin)
@@ -11,10 +6,10 @@ endif
SYSTEM=$(shell nix eval --impure --expr 'builtins.currentSystem' --raw 2>/dev/null || echo '')
-COMMANDS_PATH:=github.com/git-bug/git-bug/commands
-LDFLAGS:=-X ${COMMANDS_PATH}.GitCommit="${GIT_COMMIT}" \
- -X ${COMMANDS_PATH}.GitLastTag="${GIT_LAST_TAG}" \
- -X ${COMMANDS_PATH}.GitExactTag="${GIT_EXACT_TAG}"
+TAG:=$(shell git name-rev --name-only --tags HEAD)
+LDFLAGS:=-X main.version="${TAG}"
+
+all: build
.PHONY: list-checks
list-checks:
diff --git a/commands/root.go b/commands/root.go
index 1a4109a3c..1b64b5090 100644
--- a/commands/root.go
+++ b/commands/root.go
@@ -1,25 +1,17 @@
-// Package commands contains the CLI commands
package commands
import (
- "fmt"
"os"
- "runtime/debug"
"github.com/spf13/cobra"
- bridgecmd "github.com/git-bug/git-bug/commands/bridge"
- bugcmd "github.com/git-bug/git-bug/commands/bug"
+ "github.com/git-bug/git-bug/commands/bridge"
+ "github.com/git-bug/git-bug/commands/bug"
"github.com/git-bug/git-bug/commands/execenv"
- usercmd "github.com/git-bug/git-bug/commands/user"
+ "github.com/git-bug/git-bug/commands/user"
)
-// These variables are initialized externally during the build. See the Makefile.
-var GitCommit string
-var GitLastTag string
-var GitExactTag string
-
-func NewRootCommand() *cobra.Command {
+func NewRootCommand(version string) *cobra.Command {
cmd := &cobra.Command{
Use: execenv.RootCommandName,
Short: "A bug tracker embedded in Git",
@@ -33,7 +25,7 @@ the same git remote you are already using to collaborate with other people.
PersistentPreRun: func(cmd *cobra.Command, args []string) {
root := cmd.Root()
- root.Version = getVersion()
+ root.Version = version
},
// For the root command, force the execution of the PreRun
@@ -80,64 +72,3 @@ the same git remote you are already using to collaborate with other people.
return cmd
}
-
-func Execute() {
- if err := NewRootCommand().Execute(); err != nil {
- os.Exit(1)
- }
-}
-
-func getVersion() string {
- if GitExactTag == "undefined" {
- GitExactTag = ""
- }
-
- if GitExactTag != "" {
- // we are exactly on a tag --> release version
- return GitLastTag
- }
-
- if GitLastTag != "" {
- // not exactly on a tag --> dev version
- return fmt.Sprintf("%s-dev-%.10s", GitLastTag, GitCommit)
- }
-
- // we don't have commit information, try golang build info
- if commit, dirty, err := getCommitAndDirty(); err == nil {
- if dirty {
- return fmt.Sprintf("dev-%.10s-dirty", commit)
- }
- return fmt.Sprintf("dev-%.10s", commit)
- }
-
- return "dev-unknown"
-}
-
-func getCommitAndDirty() (commit string, dirty bool, err error) {
- info, ok := debug.ReadBuildInfo()
- if !ok {
- return "", false, fmt.Errorf("unable to read build info")
- }
-
- var commitFound bool
-
- // get the commit and modified status
- // (that is the flag for repository dirty or not)
- for _, kv := range info.Settings {
- switch kv.Key {
- case "vcs.revision":
- commit = kv.Value
- commitFound = true
- case "vcs.modified":
- if kv.Value == "true" {
- dirty = true
- }
- }
- }
-
- if !commitFound {
- return "", false, fmt.Errorf("no commit found")
- }
-
- return commit, dirty, nil
-}
diff --git a/commands/version.go b/commands/version.go
index 189a2e350..ffa4a180a 100644
--- a/commands/version.go
+++ b/commands/version.go
@@ -1,63 +1,66 @@
package commands
import (
- "runtime"
+ "log/slog"
"github.com/spf13/cobra"
"github.com/git-bug/git-bug/commands/execenv"
)
-type versionOptions struct {
- number bool
- commit bool
- all bool
-}
+// TODO: 0.12.0: remove deprecated build vars
+var (
+ GitCommit string
+ GitLastTag string
+ GitExactTag string
+)
func newVersionCommand(env *execenv.Env) *cobra.Command {
- options := versionOptions{}
+ return &cobra.Command{
+ Use: "version",
+ Short: "Print version information",
+ Example: "git bug version",
+ Long: `
+Print version information.
- cmd := &cobra.Command{
- Use: "version",
- Short: "Show git-bug version information",
- Run: func(cmd *cobra.Command, args []string) {
- runVersion(env, options, cmd.Root())
- },
- }
+Format:
+ git-bug <version> [commit[/dirty]] <compiler version> <platform> <arch>
- flags := cmd.Flags()
- flags.SortFlags = false
+Format Description:
+ <version> may be one of:
+ - A semantic version string, prefixed with a "v", e.g. v1.2.3
+ - "undefined" (if not provided, or built with an invalid version string)
- flags.BoolVarP(&options.number, "number", "n", false,
- "Only show the version number",
- )
- flags.BoolVarP(&options.commit, "commit", "c", false,
- "Only show the commit hash",
- )
- flags.BoolVarP(&options.all, "all", "a", false,
- "Show all version information",
- )
+ [commit], if present, is the commit hash that was checked out during the
+ build. This may be suffixed with '/dirty' if there were local file
+ modifications. This is indicative of your build being patched, or modified in
+ some way from the commit.
- return cmd
-}
+ <compiler version> is the version of the go compiler used for the build.
-func runVersion(env *execenv.Env, opts versionOptions, root *cobra.Command) {
- if opts.all {
- env.Out.Printf("%s version: %s\n", execenv.RootCommandName, root.Version)
- env.Out.Printf("System version: %s/%s\n", runtime.GOARCH, runtime.GOOS)
- env.Out.Printf("Golang version: %s\n", runtime.Version())
- return
- }
+ <platform> is the target platform (GOOS).
- if opts.number {
- env.Out.Println(root.Version)
- return
+ <arch> is the target architecture (GOARCH).
+`,
+ Run: func(cmd *cobra.Command, args []string) {
+ defer warnDeprecated()
+ env.Out.Printf("%s %s", execenv.RootCommandName, cmd.Root().Version)
+ },
}
+}
- if opts.commit {
- env.Out.Println(GitCommit)
- return
+// warnDeprecated warns about deprecated build variables
+// TODO: 0.12.0: remove support for old build tags
+func warnDeprecated() {
+ msg := "please contact your package maintainer"
+ reason := "deprecated build variable"
+ if GitLastTag != "" {
+ slog.Warn(msg, "reason", reason, "name", "GitLastTag", "value", GitLastTag)
+ }
+ if GitExactTag != "" {
+ slog.Warn(msg, "reason", reason, "name", "GitExactTag", "value", GitExactTag)
+ }
+ if GitCommit != "" {
+ slog.Warn(msg, "reason", reason, "name", "GitCommit", "value", GitCommit)
}
-
- env.Out.Printf("%s version: %s\n", execenv.RootCommandName, root.Version)
}
diff --git a/doc/generate.go b/doc/generate.go
index 0001f1a77..005d9df76 100644
--- a/doc/generate.go
+++ b/doc/generate.go
@@ -34,7 +34,7 @@ func main() {
wg.Add(1)
go func(name string, f func(*cobra.Command) error) {
defer wg.Done()
- root := commands.NewRootCommand()
+ root := commands.NewRootCommand("")
err := f(root)
if err != nil {
fmt.Printf(" - %s: FATAL\n", name)
diff --git a/doc/man/git-bug-version.1 b/doc/man/git-bug-version.1
index 7183b696e..988849e8a 100644
--- a/doc/man/git-bug-version.1
+++ b/doc/man/git-bug-version.1
@@ -2,7 +2,7 @@
.TH "GIT-BUG" "1" "Apr 2019" "Generated from git-bug's source code" ""
.SH NAME
-git-bug-version - Show git-bug version information
+git-bug-version - Print version information
.SH SYNOPSIS
@@ -10,25 +10,44 @@ git-bug-version - Show git-bug version information
.SH DESCRIPTION
-Show git-bug version information
+Print version information.
+.PP
+Format:
+ git-bug [commit[/dirty]]
-.SH OPTIONS
-\fB-n\fP, \fB--number\fP[=false]
- Only show the version number
+.PP
+Format Description:
+ may be one of:
+ - A semantic version string, prefixed with a "v", e.g. v1.2.3
+ - "undefined" (if not provided, or built with an invalid version string)
+
+.PP
+[commit], if present, is the commit hash that was checked out during the
+ build. This may be suffixed with '/dirty' if there were local file
+ modifications. This is indicative of your build being patched, or modified in
+ some way from the commit.
.PP
-\fB-c\fP, \fB--commit\fP[=false]
- Only show the commit hash
+ is the version of the go compiler used for the build.
.PP
-\fB-a\fP, \fB--all\fP[=false]
- Show all version information
+ is the target platform (GOOS).
.PP
+ is the target architecture (GOARCH).
+
+
+.SH OPTIONS
\fB-h\fP, \fB--help\fP[=false]
help for version
+.SH EXAMPLE
+.EX
+git bug version
+.EE
+
+
.SH SEE ALSO
\fBgit-bug(1)\fP
diff --git a/doc/md/git-bug.md b/doc/md/git-bug.md
index 03bebb65e..2ef0b7725 100644
--- a/doc/md/git-bug.md
+++ b/doc/md/git-bug.md
@@ -31,7 +31,7 @@ git-bug [flags]
* [git-bug push](git-bug_push.md) - Push updates to a git remote
* [git-bug termui](git-bug_termui.md) - Launch the terminal UI
* [git-bug user](git-bug_user.md) - List identities
-* [git-bug version](git-bug_version.md) - Show git-bug version information
+* [git-bug version](git-bug_version.md) - Print version information
* [git-bug webui](git-bug_webui.md) - Launch the web UI
* [git-bug wipe](git-bug_wipe.md) - Wipe git-bug from the git repository
diff --git a/doc/md/git-bug_version.md b/doc/md/git-bug_version.md
index ceba8790f..a2569aff1 100644
--- a/doc/md/git-bug_version.md
+++ b/doc/md/git-bug_version.md
@@ -1,18 +1,46 @@
## git-bug version
-Show git-bug version information
+Print version information
+
+### Synopsis
+
+
+Print version information.
+
+Format:
+ git-bug <version> [commit[/dirty]] <compiler version> <platform> <arch>
+
+Format Description:
+ <version> may be one of:
+ - A semantic version string, prefixed with a "v", e.g. v1.2.3
+ - "undefined" (if not provided, or built with an invalid version string)
+
+ [commit], if present, is the commit hash that was checked out during the
+ build. This may be suffixed with '/dirty' if there were local file
+ modifications. This is indicative of your build being patched, or modified in
+ some way from the commit.
+
+ <compiler version> is the version of the go compiler used for the build.
+
+ <platform> is the target platform (GOOS).
+
+ <arch> is the target architecture (GOARCH).
+
```
git-bug version [flags]
```
+### Examples
+
+```
+git bug version
+```
+
### Options
```
- -n, --number Only show the version number
- -c, --commit Only show the commit hash
- -a, --all Show all version information
- -h, --help help for version
+ -h, --help help for version
```
### SEE ALSO
diff --git a/main.go b/main.go
index 7a2034bab..5b7a4caa6 100644
--- a/main.go
+++ b/main.go
@@ -4,9 +4,15 @@
package main
import (
+ "os"
+
"github.com/git-bug/git-bug/commands"
)
func main() {
- commands.Execute()
+ v, _ := getVersion()
+ root := commands.NewRootCommand(v)
+ if err := root.Execute(); err != nil {
+ os.Exit(1)
+ }
}
diff --git a/misc/completion/generate.go b/misc/completion/generate.go
index b64c1034f..5c6468121 100644
--- a/misc/completion/generate.go
+++ b/misc/completion/generate.go
@@ -26,7 +26,7 @@ func main() {
wg.Add(1)
go func(name string, f func(*cobra.Command) error) {
defer wg.Done()
- root := commands.NewRootCommand()
+ root := commands.NewRootCommand("")
err := f(root)
if err != nil {
fmt.Printf(" - %s: %v\n", name, err)
diff --git a/version.go b/version.go
new file mode 100644
index 000000000..de9bd8753
--- /dev/null
+++ b/version.go
@@ -0,0 +1,94 @@
+package main
+
+import (
+ "errors"
+ "fmt"
+ "runtime/debug"
+ "strings"
+
+ "github.com/git-bug/git-bug/commands"
+ "golang.org/x/mod/semver"
+)
+
+var (
+ version = "undefined"
+)
+
+// getVersion returns a string representing the version information defined when
+// the binary was built, or a sane default indicating a local build. a string is
+// always returned. an error may be returned along with the string in the event
+// that we detect a local build but are unable to get build metadata.
+//
+// TODO: support validation of the version (that it's a real version)
+// TODO: support notifying the user if their version is out of date
+func getVersion() (string, error) {
+ var arch string
+ var commit string
+ var modified bool
+ var platform string
+
+ var v strings.Builder
+
+ // this supports overriding the default version if the deprecated var used
+ // for setting the exact version for releases is supplied. we are doing this
+ // in order to give downstream package maintainers a longer window to
+ // migrate.
+ //
+ // TODO: 0.12.0: remove support for old build tags
+ if version == "undefined" && commands.GitExactTag != "" {
+ version = commands.GitExactTag
+ }
+
+ // automatically add the v prefix if it's missing
+ if version != "undefined" && !strings.HasPrefix(version, "v") {
+ version = fmt.Sprintf("v%s", version)
+ }
+
+ // reset the version string to undefined if it is invalid
+ if ok := semver.IsValid(version); !ok {
+ version = "undefined"
+ }
+
+ v.WriteString(version)
+
+ info, ok := debug.ReadBuildInfo()
+ if !ok {
+ v.WriteString(fmt.Sprintf(" (no build info)\n"))
+ return v.String(), errors.New("unable to read build metadata")
+ }
+
+ for _, kv := range info.Settings {
+ switch kv.Key {
+ case "GOOS":
+ platform = kv.Value
+ case "GOARCH":
+ arch = kv.Value
+ case "vcs.modified":
+ if kv.Value == "true" {
+ modified = true
+ }
+ case "vcs.revision":
+ commit = kv.Value
+ }
+ }
+
+ if commit != "" {
+ v.WriteString(fmt.Sprintf(" %.12s", commit))
+ }
+
+ if modified {
+ v.WriteString("/dirty")
+ }
+
+ v.WriteString(fmt.Sprintf(" %s", info.GoVersion))
+
+ if platform != "" {
+ v.WriteString(fmt.Sprintf(" %s", platform))
+ }
+
+ if arch != "" {
+ v.WriteString(fmt.Sprintf(" %s", arch))
+ }
+
+ return fmt.Sprint(v.String(), "\n"), nil
+}