From cb10aeff6bad8f8047b3f6dea60b95e28d89f18a Mon Sep 17 00:00:00 2001 From: Robin Olsen Date: Mon, 2 Mar 2026 11:41:57 +0100 Subject: [PATCH] (hotfix) make sure app is initialized only when we need it --- cmd/pm/init.go | 68 +++++++++++++++++++++++++++++++++++++++++++++++- cmd/pm/main.go | 16 +++++------- cmd/pm/runner.go | 22 ++++++++++++++++ 3 files changed, 95 insertions(+), 11 deletions(-) diff --git a/cmd/pm/init.go b/cmd/pm/init.go index 22bd4c3..322a2b2 100644 --- a/cmd/pm/init.go +++ b/cmd/pm/init.go @@ -65,6 +65,8 @@ func init() { issues.RootCmd.CompletionOptions.DisableDefaultCmd = true } + setupLazyInitialization() + RootCmd.AddGroup(&cobra.Group{ID: "issues", Title: "Issue Management"}) issues.CreateCmd.GroupID = "issues" issues.GetCmd.GroupID = "issues" @@ -115,10 +117,74 @@ var replCmd = &cobra.Command{ }, } -func initializeServices(ctx context.Context) (*app.App, func(), error) { +func initializeApp(ctx context.Context) (*app.App, func(), error) { return app.New(ctx, tasks.BaseConfig().WithAutoInit(true)) } +func setupLazyInitialization() { + prevPreRun := RootCmd.PersistentPreRun + prevPreRunE := RootCmd.PersistentPreRunE + + RootCmd.PersistentPreRunE = func(cmd *cobra.Command, args []string) error { + if commandNeedsApp(cmd) { + if err := ensureAppInitialized(cmd.Context()); err != nil { + return err + } + } + + if prevPreRunE != nil { + if err := prevPreRunE(cmd, args); err != nil { + return err + } + } + + if prevPreRun != nil { + prevPreRun(cmd, args) + } + + return nil + } +} + +func commandNeedsApp(cmd *cobra.Command) bool { + name := cmd.Name() + switch name { + case "help", "completion", "__complete", "__completeNoDesc": + return false + } + + if cmd == RootCmd || name == "survey" { + return false + } + + if parent := cmd.Parent(); parent != nil && parent.Name() == "survey" { + switch name { + case "tasks", "interfaces": + return false + } + } + + return true +} + +func ensureAppInitialized(ctx context.Context) error { + if App != nil { + return nil + } + + application, cleanup, err := initializeApp(ctx) + if err != nil { + return err + } + + App = application + appCleanup = cleanup + survey.SetApp(App) + issues.SetApp(App) + + return nil +} + func initInterfaces() map[string]task.Interface { interfaces := make(map[string]task.Interface) for _, name := range task.ListInterfaces() { diff --git a/cmd/pm/main.go b/cmd/pm/main.go index 77519f4..4b74d3a 100644 --- a/cmd/pm/main.go +++ b/cmd/pm/main.go @@ -5,24 +5,20 @@ import ( "github.com/LazyBachelor/LazyPM/internal/app" issues "github.com/LazyBachelor/LazyPM/internal/commands/issues" - survey "github.com/LazyBachelor/LazyPM/internal/commands/survey" "github.com/charmbracelet/fang" ) var App *app.App +var appCleanup func() var RootCmd = issues.RootCmd func main() { ctx := context.Background() - app, cleanup, err := initializeServices(ctx) - if err != nil { - return - } - defer cleanup() - - App = app - survey.SetApp(App) - issues.SetApp(App) + defer func() { + if appCleanup != nil { + appCleanup() + } + }() if err := fang.Execute(ctx, RootCmd, fang.WithColorSchemeFunc(fang.AnsiColorScheme)); err != nil { diff --git a/cmd/pm/runner.go b/cmd/pm/runner.go index 53ba5b5..3da601e 100644 --- a/cmd/pm/runner.go +++ b/cmd/pm/runner.go @@ -15,6 +15,20 @@ import ( func runStartCmd(cmd *cobra.Command, args []string) error { app := survey.AppFromContext(cmd.Context()) + if app == nil { + if err := ensureAppInitialized(cmd.Context()); err != nil { + return fmt.Errorf("failed to initialize services: %w", err) + } + app = survey.AppFromContext(cmd.Context()) + if app == nil { + app = App + } + } + + if app == nil { + return fmt.Errorf("application services are not available") + } + interfaces := initInterfaces() surveyTasks := initTasks(app) @@ -53,6 +67,14 @@ func taskLoop(ctx context.Context, surveyTasks map[string]task.Tasker, interface iNames = append(iNames, name) } + if len(iNames) == 0 { + return fmt.Errorf("no interfaces are available") + } + + if len(surveyTasks) == 0 { + return fmt.Errorf("no tasks are available") + } + rand.Shuffle(len(iNames), func(i, j int) { iNames[i], iNames[j] = iNames[j], iNames[i] })