Skip to content

Commit

Permalink
Add version command to the default framework CLI commands (#458)
Browse files Browse the repository at this point in the history
* feat(framework): add version command

* feat(framework): use go binary build info to resolve application version

* feat(framework): use go binary build info to resolve application version

* feat(framework): use cmd Print

* feat(framework): edit implementation

* feat(framework): fix linter errors

---------

Co-authored-by: Kirill Grigorev <kirill.grigorev@omnevo.net>
  • Loading branch information
kgrigorev and Kirill Grigorev authored Dec 9, 2024
1 parent a90e42b commit 7903a65
Show file tree
Hide file tree
Showing 6 changed files with 130 additions and 13 deletions.
56 changes: 56 additions & 0 deletions framework/flamingo/flamingo.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,65 @@
package flamingo

import (
"fmt"
"io"
"runtime"
"runtime/debug"
)

var appVersion = "develop"

const (
vcsRevisionSettingKey = "vcs.revision"
)

type (
AppInfo struct {
AppVersion string
VCSRevision string
RuntimeVersion string
MainPackagePath string
FlamingoVersion string
}
)

// AppVersion returns the application version
// set this during build with `go build -ldflags "-X flamingo.me/flamingo/v3/framework/flamingo.appVersion=1.2.3"`.
func AppVersion() string {
return appVersion
}

// GetAppInfo provides basic application information like runtime version, flamingo version etc.
func GetAppInfo() AppInfo {
appInfo := AppInfo{
AppVersion: AppVersion(),
RuntimeVersion: runtime.Version(),
}

if info, ok := debug.ReadBuildInfo(); ok {
appInfo.MainPackagePath = info.Main.Path

for _, module := range info.Deps {
if module.Path == "flamingo.me/flamingo/v3" {
appInfo.FlamingoVersion = module.Version
}
}

for _, setting := range info.Settings {
if setting.Key == vcsRevisionSettingKey {
appInfo.VCSRevision = setting.Value
}
}
}

return appInfo
}

// PrintAppInfo prints application info to the writer
func PrintAppInfo(writer io.Writer, appInfo AppInfo) {
_, _ = fmt.Fprintf(writer, "%20s\t%s\n", "App version:", appInfo.AppVersion)
_, _ = fmt.Fprintf(writer, "%20s\t%s\n", "Go runtime version:", appInfo.RuntimeVersion)
_, _ = fmt.Fprintf(writer, "%20s\t%s\n", "VCS revision:", appInfo.VCSRevision)
_, _ = fmt.Fprintf(writer, "%20s\t%s\n", "Path:", appInfo.MainPackagePath)
_, _ = fmt.Fprintf(writer, "%20s\t%s\n", "Flamingo version:", appInfo.FlamingoVersion)
}
48 changes: 48 additions & 0 deletions framework/flamingo/flamingo_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package flamingo_test

import (
"bytes"
"testing"

"github.com/stretchr/testify/assert"

"flamingo.me/flamingo/v3/framework/flamingo"
)

func TestPrintAppInfo(t *testing.T) {
t.Parallel()

type args struct {
appInfo flamingo.AppInfo
}

tests := []struct {
name string
args args
wantWriter string
}{
{
name: "",
args: args{
appInfo: flamingo.AppInfo{
AppVersion: "v1.2.3",
VCSRevision: "c9ce01204a18ff2f3e9ed999fbf7f3eb8e70b614",
RuntimeVersion: "go1.23.3",
MainPackagePath: "go.aoe.com/whitelabel-airline/flamingo",
FlamingoVersion: "v3.11.0",
},
},
wantWriter: " App version:\tv1.2.3\n Go runtime version:\tgo1.23.3\n VCS revision:\tc9ce01204a18ff2f3e9ed999fbf7f3eb8e70b614\n Path:\tgo.aoe.com/whitelabel-airline/flamingo\n Flamingo version:\tv3.11.0\n",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()

writer := &bytes.Buffer{}
flamingo.PrintAppInfo(writer, tt.args.appInfo)
assert.Equalf(t, tt.wantWriter, writer.String(), "PrintAppInfo(%v, %v)", writer, tt.args.appInfo)
})
}
}
22 changes: 22 additions & 0 deletions framework/flamingo/versioncmd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package flamingo

import (
"bytes"

"github.com/spf13/cobra"
)

func VersionCmd() *cobra.Command {
return &cobra.Command{
Use: "version",
Short: "Application version",
Run: func(cmd *cobra.Command, args []string) {
var buffer bytes.Buffer

appInfo := GetAppInfo()
PrintAppInfo(&buffer, appInfo)

cmd.Println(buffer.String())
},
}
}
1 change: 1 addition & 0 deletions framework/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ func (*InitModule) Configure(injector *dingo.Injector) {
injector.BindMulti(new(cobra.Command)).ToProvider(web.HandlerCmd)
injector.BindMulti(new(cobra.Command)).ToProvider(config.ModulesCmd)
injector.BindMulti(new(cobra.Command)).ToProvider(config.Cmd)
injector.BindMulti(new(cobra.Command)).ToProvider(flamingo.VersionCmd)

web.BindRoutes(injector, new(routes))

Expand Down
1 change: 1 addition & 0 deletions framework/module_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"testing"

"flamingo.me/dingo"

"flamingo.me/flamingo/v3/framework"
)

Expand Down
15 changes: 2 additions & 13 deletions framework/systemendpoint/application/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,8 @@ package application
import (
"context"
"errors"
"fmt"
"net"
"net/http"
"runtime"
"runtime/debug"
"sync"

"flamingo.me/flamingo/v3/framework/flamingo"
Expand Down Expand Up @@ -61,16 +58,8 @@ func (s *SystemServer) Start() {
}

serveMux.HandleFunc("/version", func(writer http.ResponseWriter, _ *http.Request) {
_, _ = fmt.Fprintf(writer, "version: %s\n", flamingo.AppVersion())
_, _ = fmt.Fprintf(writer, "go: %s\n", runtime.Version())
if info, ok := debug.ReadBuildInfo(); ok {
_, _ = fmt.Fprintf(writer, "path: %s\n", info.Path)
for _, module := range info.Deps {
if module.Path == "flamingo.me/flamingo/v3" {
_, _ = fmt.Fprintf(writer, "flamingo: %s\n", module.Version)
}
}
}
appInfo := flamingo.GetAppInfo()
flamingo.PrintAppInfo(writer, appInfo)
})

listener, err := net.Listen("tcp", s.serviceAddress)
Expand Down

0 comments on commit 7903a65

Please sign in to comment.