[#1267] call app.Bootstrap() before cobra commands execution

This commit is contained in:
Gani Georgiev
2022-12-15 23:20:23 +02:00
parent 8e582acbee
commit c25e67e13d
6 changed files with 189 additions and 20 deletions
+60 -8
View File
@@ -11,6 +11,7 @@ import (
"github.com/pocketbase/pocketbase/cmd"
"github.com/pocketbase/pocketbase/core"
"github.com/pocketbase/pocketbase/tools/list"
"github.com/spf13/cobra"
)
@@ -68,7 +69,7 @@ type Config struct {
func New() *PocketBase {
_, isUsingGoRun := inspectRuntime()
return NewWithConfig(Config{
return NewWithConfig(&Config{
DefaultDebug: isUsingGoRun,
})
}
@@ -80,7 +81,11 @@ func New() *PocketBase {
// Everything will be initialized when [Start()] is executed.
// If you want to initialize the application before calling [Start()],
// then you'll have to manually call [Bootstrap()].
func NewWithConfig(config Config) *PocketBase {
func NewWithConfig(config *Config) *PocketBase {
if config == nil {
panic("missing config")
}
// initialize a default data directory based on the executable baseDir
if config.DefaultDataDir == "" {
baseDir, _ := inspectRuntime()
@@ -124,11 +129,6 @@ func NewWithConfig(config Config) *PocketBase {
// hide the default help command (allow only `--help` flag)
pb.RootCmd.SetHelpCommand(&cobra.Command{Hidden: true})
// hook the bootstrap process
pb.RootCmd.PersistentPreRunE = func(cmd *cobra.Command, args []string) error {
return pb.Bootstrap()
}
return pb
}
@@ -148,6 +148,18 @@ func (pb *PocketBase) Start() error {
// This method differs from pb.Start() by not registering the default
// system commands!
func (pb *PocketBase) Execute() error {
// Run the bootstrap process if the command exist and it is not
// the default cobra version command to prevent creating
// unnecessary the initialization system files.
//
// https://github.com/pocketbase/pocketbase/issues/404
// https://github.com/pocketbase/pocketbase/discussions/1267
if !pb.skipBootstrap() {
if err := pb.Bootstrap(); err != nil {
return err
}
}
var wg sync.WaitGroup
wg.Add(1)
@@ -181,7 +193,7 @@ func (pb *PocketBase) onTerminate() error {
// eagerParseFlags parses the global app flags before calling pb.RootCmd.Execute().
// so we can have all PocketBase flags ready for use on initialization.
func (pb *PocketBase) eagerParseFlags(config Config) error {
func (pb *PocketBase) eagerParseFlags(config *Config) error {
pb.RootCmd.PersistentFlags().StringVar(
&pb.dataDirFlag,
"dir",
@@ -206,6 +218,46 @@ func (pb *PocketBase) eagerParseFlags(config Config) error {
return pb.RootCmd.ParseFlags(os.Args[1:])
}
// eager check if the app should skip the bootstap process:
// - already bootstrapped
// - is unknown command
// - is the default help command
// - is the default version command
func (pb *PocketBase) skipBootstrap() bool {
flags := []string{
"-h",
"--help",
"-v",
"--version",
}
if pb.IsBootstrapped() {
return true // already bootstrapped
}
cmd, _, err := pb.RootCmd.Find(os.Args[1:])
if err != nil {
return true // unknown command
}
for _, arg := range os.Args {
if !list.ExistInSlice(arg, flags) {
continue
}
// ensure that there is no user defined flag with the same name/shorthand
trimmed := strings.TrimLeft(arg, "-")
if len(trimmed) > 1 && cmd.Flags().Lookup(trimmed) == nil {
return true
}
if len(trimmed) == 1 && cmd.Flags().ShorthandLookup(trimmed) == nil {
return true
}
}
return false
}
// tries to find the base executable directory and how it was run
func inspectRuntime() (baseDir string, withGoRun bool) {
if strings.HasPrefix(os.Args[0], os.TempDir()) {