refactor: dedicated constants package, no explicit bridge version

This commit is contained in:
James Houlahan
2020-04-23 10:07:41 +02:00
committed by Jakub Cuth
parent 32ca7b3903
commit 522cadb8b1
11 changed files with 88 additions and 42 deletions

View File

@ -55,6 +55,7 @@ import (
"github.com/ProtonMail/proton-bridge/internal/smtp" "github.com/ProtonMail/proton-bridge/internal/smtp"
"github.com/ProtonMail/proton-bridge/pkg/args" "github.com/ProtonMail/proton-bridge/pkg/args"
"github.com/ProtonMail/proton-bridge/pkg/config" "github.com/ProtonMail/proton-bridge/pkg/config"
"github.com/ProtonMail/proton-bridge/pkg/constants"
"github.com/ProtonMail/proton-bridge/pkg/listener" "github.com/ProtonMail/proton-bridge/pkg/listener"
"github.com/ProtonMail/proton-bridge/pkg/pmapi" "github.com/ProtonMail/proton-bridge/pkg/pmapi"
"github.com/ProtonMail/proton-bridge/pkg/updates" "github.com/ProtonMail/proton-bridge/pkg/updates"
@ -68,45 +69,29 @@ import (
// Different number will drop old files and create new ones. // Different number will drop old files and create new ones.
const cacheVersion = "c11" const cacheVersion = "c11"
// Following variables are set via ldflags during build.
var ( var (
// Version of the build.
Version = "" //nolint[gochecknoglobals]
// Revision is current hash of the build.
Revision = "" //nolint[gochecknoglobals]
// BuildTime stamp of the build.
BuildTime = "" //nolint[gochecknoglobals]
// AppShortName to make setup
AppShortName = "bridge" //nolint[gochecknoglobals]
// DSNSentry client keys to be able to report crashes to Sentry
DSNSentry = "" //nolint[gochecknoglobals]
)
var (
longVersion = Version + " (" + Revision + ")" //nolint[gochecknoglobals]
buildVersion = longVersion + " " + BuildTime //nolint[gochecknoglobals]
log = logrus.WithField("pkg", "main") //nolint[gochecknoglobals] log = logrus.WithField("pkg", "main") //nolint[gochecknoglobals]
// How many crashes in a row. // How many crashes in a row.
numberOfCrashes = 0 //nolint[gochecknoglobals] numberOfCrashes = 0 //nolint[gochecknoglobals]
// After how many crashes bridge gives up starting. // After how many crashes bridge gives up starting.
maxAllowedCrashes = 10 //nolint[gochecknoglobals] maxAllowedCrashes = 10 //nolint[gochecknoglobals]
) )
func main() { func main() {
if err := raven.SetDSN(DSNSentry); err != nil { if err := raven.SetDSN(constants.DSNSentry); err != nil {
log.WithError(err).Errorln("Can not setup sentry DSN") log.WithError(err).Errorln("Can not setup sentry DSN")
} }
raven.SetRelease(Revision) raven.SetRelease(constants.Revision)
bridge.UpdateCurrentUserAgent(Version, runtime.GOOS, "", "") bridge.UpdateCurrentUserAgent(constants.Version, runtime.GOOS, "", "")
args.FilterProcessSerialNumberFromArgs() args.FilterProcessSerialNumberFromArgs()
filterRestartNumberFromArgs() filterRestartNumberFromArgs()
app := cli.NewApp() app := cli.NewApp()
app.Name = "Protonmail Bridge" app.Name = "Protonmail Bridge"
app.Version = buildVersion app.Version = constants.BuildVersion
app.Flags = []cli.Flag{ app.Flags = []cli.Flag{
cli.StringFlag{ cli.StringFlag{
Name: "log-level, l", Name: "log-level, l",
@ -135,13 +120,13 @@ func main() {
// Always log the basic info about current bridge. // Always log the basic info about current bridge.
logrus.SetLevel(logrus.InfoLevel) logrus.SetLevel(logrus.InfoLevel)
log.WithField("version", Version). log.WithField("version", constants.Version).
WithField("revision", Revision). WithField("revision", constants.Revision).
WithField("runtime", runtime.GOOS). WithField("runtime", runtime.GOOS).
WithField("build", BuildTime). WithField("build", constants.BuildTime).
WithField("args", os.Args). WithField("args", os.Args).
WithField("appLong", app.Name). WithField("appLong", app.Name).
WithField("appShort", AppShortName). WithField("appShort", constants.AppShortName).
Info("Run app") Info("Run app")
if err := app.Run(os.Args); err != nil { if err := app.Run(os.Args); err != nil {
log.Error("Program exited with error: ", err) log.Error("Program exited with error: ", err)
@ -174,7 +159,7 @@ func (ph *panicHandler) HandlePanic() {
// IMPORTANT: ***Read the comments before CHANGING the order *** // IMPORTANT: ***Read the comments before CHANGING the order ***
func run(context *cli.Context) (contextError error) { // nolint[funlen] func run(context *cli.Context) (contextError error) { // nolint[funlen]
// We need to have config instance to setup a logs, panic handler, etc ... // We need to have config instance to setup a logs, panic handler, etc ...
cfg := config.New(AppShortName, Version, Revision, cacheVersion) cfg := config.New(constants.AppShortName, constants.Version, constants.Revision, cacheVersion)
// We want to know about any problem. Our PanicHandler calls sentry which is // We want to know about any problem. Our PanicHandler calls sentry which is
// not dependent on anything else. If that fails, it tries to create crash // not dependent on anything else. If that fails, it tries to create crash
@ -208,7 +193,16 @@ func run(context *cli.Context) (contextError error) { // nolint[funlen]
// It's safe to get version JSON file even when other instance is running. // It's safe to get version JSON file even when other instance is running.
// (thus we put it before check of presence of other Bridge instance). // (thus we put it before check of presence of other Bridge instance).
updates := updates.New(AppShortName, Version, Revision, BuildTime, bridge.ReleaseNotes, bridge.ReleaseFixedBugs, cfg.GetUpdateDir()) updates := updates.New(
constants.AppShortName,
constants.Version,
constants.Revision,
constants.BuildTime,
bridge.ReleaseNotes,
bridge.ReleaseFixedBugs,
cfg.GetUpdateDir(),
)
if dir := context.GlobalString("version-json"); dir != "" { if dir := context.GlobalString("version-json"); dir != "" {
generateVersionFiles(updates, dir) generateVersionFiles(updates, dir)
return nil return nil
@ -280,7 +274,7 @@ func run(context *cli.Context) (contextError error) { // nolint[funlen]
// implementation depending on whether build flag pmapi_prod is used or not. // implementation depending on whether build flag pmapi_prod is used or not.
cm.SetRoundTripper(cfg.GetRoundTripper(cm, eventListener)) cm.SetRoundTripper(cfg.GetRoundTripper(cm, eventListener))
bridgeInstance := bridge.New(cfg, pref, panicHandler, eventListener, Version, cm, credentialsStore) bridgeInstance := bridge.New(cfg, pref, panicHandler, eventListener, cm, credentialsStore)
imapBackend := imap.NewIMAPBackend(panicHandler, eventListener, cfg, bridgeInstance) imapBackend := imap.NewIMAPBackend(panicHandler, eventListener, cfg, bridgeInstance)
smtpBackend := smtp.NewSMTPBackend(panicHandler, eventListener, pref, bridgeInstance) smtpBackend := smtp.NewSMTPBackend(panicHandler, eventListener, pref, bridgeInstance)
@ -326,7 +320,7 @@ func run(context *cli.Context) (contextError error) { // nolint[funlen]
} }
showWindowOnStart := !context.GlobalBool("no-window") showWindowOnStart := !context.GlobalBool("no-window")
frontend := frontend.New(Version, buildVersion, frontendMode, showWindowOnStart, panicHandler, cfg, pref, eventListener, updates, bridgeInstance, smtpBackend) frontend := frontend.New(constants.Version, constants.BuildVersion, frontendMode, showWindowOnStart, panicHandler, cfg, pref, eventListener, updates, bridgeInstance, smtpBackend)
// Last part is to start everything. // Last part is to start everything.
log.Debug("Starting frontend...") log.Debug("Starting frontend...")
@ -346,7 +340,7 @@ func run(context *cli.Context) (contextError error) { // nolint[funlen]
// It will happen only when c10/prefs.json exists and c11/prefs.json not. // It will happen only when c10/prefs.json exists and c11/prefs.json not.
// No configuration changed between c10 and c11 versions. // No configuration changed between c10 and c11 versions.
func migratePreferencesFromC10(cfg *config.Config) { func migratePreferencesFromC10(cfg *config.Config) {
pref10Path := config.New(AppShortName, Version, Revision, "c10").GetPreferencesPath() pref10Path := config.New(constants.AppShortName, constants.Version, constants.Revision, "c10").GetPreferencesPath()
if _, err := os.Stat(pref10Path); os.IsNotExist(err) { if _, err := os.Stat(pref10Path); os.IsNotExist(err) {
log.WithField("path", pref10Path).Trace("Old preferences does not exist, migration skipped") log.WithField("path", pref10Path).Trace("Old preferences does not exist, migration skipped")
return return

View File

@ -46,7 +46,6 @@ type Bridge struct {
pref PreferenceProvider pref PreferenceProvider
panicHandler PanicHandler panicHandler PanicHandler
events listener.Listener events listener.Listener
version string
clientManager ClientManager clientManager ClientManager
credStorer CredentialsStorer credStorer CredentialsStorer
storeCache *store.Cache storeCache *store.Cache
@ -77,7 +76,6 @@ func New(
pref PreferenceProvider, pref PreferenceProvider,
panicHandler PanicHandler, panicHandler PanicHandler,
eventListener listener.Listener, eventListener listener.Listener,
version string,
clientManager ClientManager, clientManager ClientManager,
credStorer CredentialsStorer, credStorer CredentialsStorer,
) *Bridge { ) *Bridge {
@ -88,7 +86,6 @@ func New(
pref: pref, pref: pref,
panicHandler: panicHandler, panicHandler: panicHandler,
events: eventListener, events: eventListener,
version: version,
clientManager: clientManager, clientManager: clientManager,
credStorer: credStorer, credStorer: credStorer,
storeCache: store.NewCache(config.GetIMAPCachePath()), storeCache: store.NewCache(config.GetIMAPCachePath()),
@ -122,7 +119,7 @@ func New(
} }
if pref.GetBool(preferences.FirstStartKey) { if pref.GetBool(preferences.FirstStartKey) {
b.SendMetric(metrics.New(metrics.Setup, metrics.FirstStart, metrics.Label(version))) b.SendMetric(metrics.New(metrics.Setup, metrics.FirstStart, metrics.Label(config.GetVersion())))
} }
return b return b
@ -572,7 +569,7 @@ func (b *Bridge) StopWatchers() {
} }
func (b *Bridge) updateCurrentUserAgent() { func (b *Bridge) updateCurrentUserAgent() {
UpdateCurrentUserAgent(b.version, b.userAgentOS, b.userAgentClientName, b.userAgentClientVersion) UpdateCurrentUserAgent(b.config.GetVersion(), b.userAgentOS, b.userAgentClientName, b.userAgentClientVersion)
} }
// hasUser returns whether the bridge currently has a user with ID `id`. // hasUser returns whether the bridge currently has a user with ID `id`.

View File

@ -244,10 +244,11 @@ func testNewBridge(t *testing.T, m mocks) *Bridge {
m.prefProvider.EXPECT().GetBool(preferences.AllowProxyKey).Return(false).AnyTimes() m.prefProvider.EXPECT().GetBool(preferences.AllowProxyKey).Return(false).AnyTimes()
m.config.EXPECT().GetDBDir().Return("/tmp").AnyTimes() m.config.EXPECT().GetDBDir().Return("/tmp").AnyTimes()
m.config.EXPECT().GetIMAPCachePath().Return(cacheFile.Name()).AnyTimes() m.config.EXPECT().GetIMAPCachePath().Return(cacheFile.Name()).AnyTimes()
m.config.EXPECT().GetVersion().Return("ver").AnyTimes()
m.eventListener.EXPECT().Add(events.UpgradeApplicationEvent, gomock.Any()) m.eventListener.EXPECT().Add(events.UpgradeApplicationEvent, gomock.Any())
m.clientManager.EXPECT().GetAuthUpdateChannel().Return(make(chan pmapi.ClientAuth)) m.clientManager.EXPECT().GetAuthUpdateChannel().Return(make(chan pmapi.ClientAuth))
bridge := New(m.config, m.prefProvider, m.PanicHandler, m.eventListener, "ver", m.clientManager, m.credentialsStore) bridge := New(m.config, m.prefProvider, m.PanicHandler, m.eventListener, m.clientManager, m.credentialsStore)
waitForEvents() waitForEvents()

View File

@ -91,6 +91,20 @@ func (mr *MockConfigerMockRecorder) GetIMAPCachePath() *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetIMAPCachePath", reflect.TypeOf((*MockConfiger)(nil).GetIMAPCachePath)) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetIMAPCachePath", reflect.TypeOf((*MockConfiger)(nil).GetIMAPCachePath))
} }
// GetVersion mocks base method
func (m *MockConfiger) GetVersion() string {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetVersion")
ret0, _ := ret[0].(string)
return ret0
}
// GetVersion indicates an expected call of GetVersion
func (mr *MockConfigerMockRecorder) GetVersion() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetVersion", reflect.TypeOf((*MockConfiger)(nil).GetVersion))
}
// MockPreferenceProvider is a mock of PreferenceProvider interface // MockPreferenceProvider is a mock of PreferenceProvider interface
type MockPreferenceProvider struct { type MockPreferenceProvider struct {
ctrl *gomock.Controller ctrl *gomock.Controller

View File

@ -25,6 +25,7 @@ import (
type Configer interface { type Configer interface {
ClearData() error ClearData() error
GetDBDir() string GetDBDir() string
GetVersion() string
GetIMAPCachePath() string GetIMAPCachePath() string
GetAPIConfig() *pmapi.ClientConfig GetAPIConfig() *pmapi.ClientConfig
} }

View File

@ -172,6 +172,11 @@ func (c *Config) IsDevMode() bool {
return os.Getenv("PROTONMAIL_ENV") == "dev" return os.Getenv("PROTONMAIL_ENV") == "dev"
} }
// GetVersion returns the version.
func (c *Config) GetVersion() string {
return c.version
}
// GetLogDir returns folder for log files. // GetLogDir returns folder for log files.
func (c *Config) GetLogDir() string { func (c *Config) GetLogDir() string {
return c.appDirs.UserLogs() return c.appDirs.UserLogs()

View File

@ -0,0 +1,26 @@
// Package constants contains variables that are set via ldflags during build.
package constants
// nolint[gochecknoglobals]
var (
// Version of the build.
Version = ""
// Revision is current hash of the build.
Revision = ""
// BuildTime stamp of the build.
BuildTime = ""
// AppShortName to make setup.
AppShortName = "bridge"
// DSNSentry client keys to be able to report crashes to Sentry.
DSNSentry = ""
// LongVersion is derived from Version and Revision.
LongVersion = Version + " (" + Revision + ")"
// BuildVersion is derived from LongVersion and BuildTime.
BuildVersion = LongVersion + " " + BuildTime
)

View File

@ -1,9 +1,9 @@
.PHONY: check-has-go install-godog test test-live test-debug test-live-debug .PHONY: check-has-go install-godog test test-live test-debug test-live-debug
export GO111MODULE=on export GO111MODULE=on
export VERSION:=1.2.5-integrationtest
export VERBOSITY?=fatal export VERBOSITY?=fatal
export TEST_DATA=testdata export TEST_DATA=testdata
export VERSION:=dev-integrationtests
check-has-go: check-has-go:
@which go || (echo "Install Go-lang!" && exit 1) @which go || (echo "Install Go-lang!" && exit 1)

View File

@ -18,11 +18,11 @@
package context package context
import ( import (
"os"
"runtime" "runtime"
"github.com/ProtonMail/proton-bridge/internal/bridge" "github.com/ProtonMail/proton-bridge/internal/bridge"
"github.com/ProtonMail/proton-bridge/internal/preferences" "github.com/ProtonMail/proton-bridge/internal/preferences"
"github.com/ProtonMail/proton-bridge/pkg/constants"
"github.com/ProtonMail/proton-bridge/pkg/listener" "github.com/ProtonMail/proton-bridge/pkg/listener"
) )
@ -64,13 +64,12 @@ func newBridgeInstance(
eventListener listener.Listener, eventListener listener.Listener,
clientManager bridge.ClientManager, clientManager bridge.ClientManager,
) *bridge.Bridge { ) *bridge.Bridge {
version := os.Getenv("VERSION") bridge.UpdateCurrentUserAgent(constants.Version, runtime.GOOS, "", "")
bridge.UpdateCurrentUserAgent(version, runtime.GOOS, "", "")
panicHandler := &panicHandler{t: t} panicHandler := &panicHandler{t: t}
pref := preferences.New(cfg) pref := preferences.New(cfg)
return bridge.New(cfg, pref, panicHandler, eventListener, version, clientManager, credStore) return bridge.New(cfg, pref, panicHandler, eventListener, clientManager, credStore)
} }
// SetLastBridgeError sets the last error that occurred while executing a bridge action. // SetLastBridgeError sets the last error that occurred while executing a bridge action.

View File

@ -23,6 +23,7 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"github.com/ProtonMail/gopenpgp/constants"
"github.com/ProtonMail/proton-bridge/pkg/pmapi" "github.com/ProtonMail/proton-bridge/pkg/pmapi"
) )
@ -48,13 +49,16 @@ func (c *fakeConfig) ClearData() error {
} }
func (c *fakeConfig) GetAPIConfig() *pmapi.ClientConfig { func (c *fakeConfig) GetAPIConfig() *pmapi.ClientConfig {
return &pmapi.ClientConfig{ return &pmapi.ClientConfig{
AppVersion: "Bridge_" + os.Getenv("VERSION"), AppVersion: "Bridge_" + constants.Version,
ClientID: "bridge", ClientID: "bridge",
} }
} }
func (c *fakeConfig) GetDBDir() string { func (c *fakeConfig) GetDBDir() string {
return c.dir return c.dir
} }
func (c *fakeConfig) GetVersion() string {
return constants.Version
}
func (c *fakeConfig) GetLogDir() string { func (c *fakeConfig) GetLogDir() string {
return c.dir return c.dir
} }

View File

@ -22,6 +22,7 @@ import (
"os" "os"
"testing" "testing"
"github.com/ProtonMail/proton-bridge/pkg/constants"
"github.com/cucumber/godog" "github.com/cucumber/godog"
"github.com/cucumber/godog/colors" "github.com/cucumber/godog/colors"
) )
@ -33,6 +34,9 @@ var opt = godog.Options{ //nolint[gochecknoglobals]
func init() { //nolint[gochecknoinits] func init() { //nolint[gochecknoinits]
godog.BindFlags("godog.", flag.CommandLine, &opt) godog.BindFlags("godog.", flag.CommandLine, &opt)
// This would normally be done using ldflags but `godog` command doesn't support that.
constants.Version = os.Getenv("VERSION")
} }
func TestMain(m *testing.M) { func TestMain(m *testing.M) {
@ -46,5 +50,6 @@ func TestMain(m *testing.M) {
if st := m.Run(); st > status { if st := m.Run(); st > status {
status = st status = st
} }
os.Exit(status) os.Exit(status)
} }