From 4b74557f4cecb41bbf764b375b438816fa85173f Mon Sep 17 00:00:00 2001 From: Alec Thomas Date: Wed, 25 Sep 2024 18:31:32 +1000 Subject: [PATCH] refactor: simplify terminal.KongContextBinder (#2819) Instead of passing around all the parameters required manually, we capture them in a closure once at startup. --- frontend/cli/cmd_dev.go | 4 ++-- frontend/cli/cmd_interactive.go | 2 +- frontend/cli/main.go | 39 ++++++++++++++++---------------- internal/terminal/interactive.go | 7 +++--- internal/terminal/status.go | 5 ++-- 5 files changed, 28 insertions(+), 29 deletions(-) diff --git a/frontend/cli/cmd_dev.go b/frontend/cli/cmd_dev.go index 42d61c4452..80b6a47a33 100644 --- a/frontend/cli/cmd_dev.go +++ b/frontend/cli/cmd_dev.go @@ -29,7 +29,7 @@ type devCmd struct { Build buildCmd `embed:""` } -func (d *devCmd) Run(ctx context.Context, k *kong.Kong, projConfig projectconfig.Config, cancel context.CancelFunc) error { +func (d *devCmd) Run(ctx context.Context, k *kong.Kong, projConfig projectconfig.Config, bindContext terminal.KongContextBinder) error { startTime := time.Now() if len(d.Build.Dirs) == 0 { d.Build.Dirs = projConfig.AbsModuleDirs() @@ -39,7 +39,7 @@ func (d *devCmd) Run(ctx context.Context, k *kong.Kong, projConfig projectconfig } client := rpc.ClientFromContext[ftlv1connect.ControllerServiceClient](ctx) - terminal.LaunchEmbeddedConsole(ctx, k, projConfig, bindContext, cancel, client) + terminal.LaunchEmbeddedConsole(ctx, k, bindContext, client) g, ctx := errgroup.WithContext(ctx) diff --git a/frontend/cli/cmd_interactive.go b/frontend/cli/cmd_interactive.go index ba3e8089ae..b3c2643820 100644 --- a/frontend/cli/cmd_interactive.go +++ b/frontend/cli/cmd_interactive.go @@ -15,7 +15,7 @@ type interactiveCmd struct { } func (i *interactiveCmd) Run(ctx context.Context, k *kong.Kong, projectConfig projectconfig.Config, binder terminal.KongContextBinder, cancel context.CancelFunc, client ftlv1connect.ControllerServiceClient) error { - err := terminal.RunInteractiveConsole(ctx, k, projectConfig, binder, cancel, client) + err := terminal.RunInteractiveConsole(ctx, k, binder, client) if err != nil { return fmt.Errorf("interactive console: %w", err) } diff --git a/frontend/cli/main.go b/frontend/cli/main.go index 781c4c642d..60e018d1a3 100644 --- a/frontend/cli/main.go +++ b/frontend/cli/main.go @@ -121,7 +121,8 @@ func main() { if err != nil && !errors.Is(err, os.ErrNotExist) { kctx.FatalIfErrorf(err) } - ctx = bindContext(ctx, kctx, config, createKongApplication(&InteractiveCLI{}), cancel) + bindContext := makeBindContext(config, cancel) + ctx = bindContext(ctx, kctx) err = kctx.Run(ctx) kctx.FatalIfErrorf(err) @@ -150,26 +151,26 @@ func createKongApplication(cli any) *kong.Kong { return app } -var _ terminal.KongContextBinder = bindContext +func makeBindContext(projectConfig projectconfig.Config, cancel context.CancelFunc) terminal.KongContextBinder { + var bindContext terminal.KongContextBinder + bindContext = func(ctx context.Context, kctx *kong.Context) context.Context { + kctx.Bind(projectConfig) -func bindContext(ctx context.Context, kctx *kong.Context, projectConfig projectconfig.Config, app *kong.Kong, cancel context.CancelFunc) context.Context { + controllerServiceClient := rpc.Dial(ftlv1connect.NewControllerServiceClient, cli.Endpoint.String(), log.Error) + ctx = rpc.ContextWithClient(ctx, controllerServiceClient) + kctx.BindTo(controllerServiceClient, (*ftlv1connect.ControllerServiceClient)(nil)) - kctx.Bind(projectConfig) - kctx.Bind(app) + kongcompletion.Register(kctx.Kong, kongcompletion.WithPredictors(terminal.Predictors(ctx, controllerServiceClient))) - controllerServiceClient := rpc.Dial(ftlv1connect.NewControllerServiceClient, cli.Endpoint.String(), log.Error) - ctx = rpc.ContextWithClient(ctx, controllerServiceClient) - kctx.BindTo(controllerServiceClient, (*ftlv1connect.ControllerServiceClient)(nil)) + verbServiceClient := rpc.Dial(ftlv1connect.NewVerbServiceClient, cli.Endpoint.String(), log.Error) + ctx = rpc.ContextWithClient(ctx, verbServiceClient) + kctx.BindTo(verbServiceClient, (*ftlv1connect.VerbServiceClient)(nil)) - kongcompletion.Register(app, kongcompletion.WithPredictors(terminal.Predictors(ctx, controllerServiceClient))) - - verbServiceClient := rpc.Dial(ftlv1connect.NewVerbServiceClient, cli.Endpoint.String(), log.Error) - ctx = rpc.ContextWithClient(ctx, verbServiceClient) - kctx.BindTo(verbServiceClient, (*ftlv1connect.VerbServiceClient)(nil)) - - kctx.Bind(cli.Endpoint) - kctx.BindTo(ctx, (*context.Context)(nil)) - kctx.BindTo(bindContext, (*terminal.KongContextBinder)(nil)) - kctx.BindTo(cancel, (*context.CancelFunc)(nil)) - return ctx + kctx.Bind(cli.Endpoint) + kctx.BindTo(ctx, (*context.Context)(nil)) + kctx.Bind(bindContext) + kctx.BindTo(cancel, (*context.CancelFunc)(nil)) + return ctx + } + return bindContext } diff --git a/internal/terminal/interactive.go b/internal/terminal/interactive.go index 15bd33973b..140050b074 100644 --- a/internal/terminal/interactive.go +++ b/internal/terminal/interactive.go @@ -15,7 +15,6 @@ import ( "github.com/posener/complete" "github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1/ftlv1connect" - "github.com/TBD54566975/ftl/internal/projectconfig" ) const interactivePrompt = "\033[32m>\033[0m " @@ -23,9 +22,9 @@ const interactivePrompt = "\033[32m>\033[0m " var _ readline.AutoCompleter = &FTLCompletion{} var errExitTrap = errors.New("exit trap") -type KongContextBinder func(ctx context.Context, kctx *kong.Context, projectConfig projectconfig.Config, app *kong.Kong, cancel context.CancelFunc) context.Context +type KongContextBinder func(ctx context.Context, kctx *kong.Context) context.Context -func RunInteractiveConsole(ctx context.Context, k *kong.Kong, projectConfig projectconfig.Config, binder KongContextBinder, cancelContext context.CancelFunc, client ftlv1connect.ControllerServiceClient) error { +func RunInteractiveConsole(ctx context.Context, k *kong.Kong, binder KongContextBinder, client ftlv1connect.ControllerServiceClient) error { l, err := readline.NewEx(&readline.Config{ Prompt: interactivePrompt, @@ -90,7 +89,7 @@ func RunInteractiveConsole(ctx context.Context, k *kong.Kong, projectConfig proj errorf("%s", err) return } - subctx := binder(ctx, kctx, projectConfig, k, cancelContext) + subctx := binder(ctx, kctx) err = kctx.Run(subctx) if err != nil { diff --git a/internal/terminal/status.go b/internal/terminal/status.go index e1ef78a7b2..a2cedd2b9a 100644 --- a/internal/terminal/status.go +++ b/internal/terminal/status.go @@ -20,7 +20,6 @@ import ( "github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1/ftlv1connect" "github.com/TBD54566975/ftl/internal/log" - "github.com/TBD54566975/ftl/internal/projectconfig" ) type BuildState string @@ -489,11 +488,11 @@ func (r *terminalStatusLine) SetMessage(message string) { r.manager.recalculateLines() } -func LaunchEmbeddedConsole(ctx context.Context, k *kong.Kong, projectConfig projectconfig.Config, binder KongContextBinder, cancel context.CancelFunc, client ftlv1connect.ControllerServiceClient) { +func LaunchEmbeddedConsole(ctx context.Context, k *kong.Kong, binder KongContextBinder, client ftlv1connect.ControllerServiceClient) { sm := FromContext(ctx) if _, ok := sm.(*terminalStatusManager); ok { go func() { - err := RunInteractiveConsole(ctx, k, projectConfig, binder, cancel, client) + err := RunInteractiveConsole(ctx, k, binder, client) if err != nil { fmt.Printf("\033[31mError: %s\033[0m\n", err) return