diff --git a/internal/cli/kraft/build/builder_kraftfile_unikraft.go b/internal/cli/kraft/build/builder_kraftfile_unikraft.go index 43366b1b4..564ca4f63 100644 --- a/internal/cli/kraft/build/builder_kraftfile_unikraft.go +++ b/internal/cli/kraft/build/builder_kraftfile_unikraft.go @@ -169,7 +169,7 @@ func (build *builderKraftfileUnikraft) pull(ctx context.Context, opts *BuildOpti fmt.Sprintf("pulling %s", unikraft.TypeNameVersion(template), ), - func(ctx context.Context, w func(progress float64)) error { + func(ctx context.Context, prompt func(), w func(progress float64)) error { return templatePack.Pull( ctx, pack.WithPullProgressFunc(w), @@ -296,7 +296,7 @@ func (build *builderKraftfileUnikraft) pull(ctx context.Context, opts *BuildOpti fmt.Sprintf("pulling %s", unikraft.TypeNameVersion(p), ), - func(ctx context.Context, w func(progress float64)) error { + func(ctx context.Context, prompt func(), w func(progress float64)) error { return p.Pull( ctx, pack.WithPullProgressFunc(w), @@ -472,7 +472,7 @@ func (build *builderKraftfileUnikraft) Build(ctx context.Context, opts *BuildOpt configure := true if opts.project.IsConfigured(*opts.Target) { - configure, err = confirm.NewConfirm("project already configured, are you sure you want to rerun the configure step:") + configure, err = confirm.NewConfirm("project already configured, are you sure you want to rerun the configure step:", func() {}) if err != nil { return err } @@ -481,7 +481,7 @@ func (build *builderKraftfileUnikraft) Build(ctx context.Context, opts *BuildOpt if configure { processes = append(processes, paraprogress.NewProcess( fmt.Sprintf("configuring %s (%s)", (*opts.Target).Name(), target.TargetPlatArchName(*opts.Target)), - func(ctx context.Context, w func(progress float64)) error { + func(ctx context.Context, prompt func(), w func(progress float64)) error { return opts.project.Configure( ctx, *opts.Target, // Target-specific options @@ -504,7 +504,7 @@ func (build *builderKraftfileUnikraft) Build(ctx context.Context, opts *BuildOpt processes = append(processes, paraprogress.NewProcess( fmt.Sprintf("building %s (%s)", (*opts.Target).Name(), target.TargetPlatArchName(*opts.Target)), - func(ctx context.Context, w func(progress float64)) error { + func(ctx context.Context, prompt func(), w func(progress float64)) error { err := opts.project.Build( ctx, *opts.Target, // Target-specific options @@ -551,7 +551,7 @@ func (build *builderKraftfileUnikraft) Statistics(ctx context.Context, opts *Bui processes = append(processes, paraprogress.NewProcess( fmt.Sprintf("statistics %s (%s)", (*opts.Target).Name(), target.TargetPlatArchName(*opts.Target)), - func(ctx context.Context, w func(progress float64)) error { + func(ctx context.Context, prompt func(), w func(progress float64)) error { lines, err := linesOfCode(ctx, opts) if lines > 1 { opts.statistics["lines of code"] = fmt.Sprintf("%d", lines) diff --git a/internal/cli/kraft/cloud/volume/import/import.go b/internal/cli/kraft/cloud/volume/import/import.go index 69647577e..5615361e4 100644 --- a/internal/cli/kraft/cloud/volume/import/import.go +++ b/internal/cli/kraft/cloud/volume/import/import.go @@ -165,7 +165,7 @@ func importVolumeData(ctx context.Context, opts *ImportOptions) (retErr error) { var copyCPIOErr error paraprogress, err := paraProgress(ctx, fmt.Sprintf("Importing data (%s)", humanize.IBytes(uint64(cpioSize))), - func(ctx context.Context, callback func(float64)) (retErr error) { + func(ctx context.Context, prompt func(), callback func(float64)) (retErr error) { instAddr := instFQDN + ":" + strconv.FormatUint(uint64(volimportPort), 10) conn, err := tls.Dial("tcp4", instAddr, nil) if err != nil { @@ -228,7 +228,7 @@ func processTree(ctx context.Context, txt string, fn processtree.SpinnerProcess) } // paraProgress returns a TUI ParaProgress configured to run the given function. -func paraProgress(ctx context.Context, txt string, fn func(context.Context, func(float64)) error) (*paraprogress.ParaProgress, error) { +func paraProgress(ctx context.Context, txt string, fn func(context.Context, func(), func(float64)) error) (*paraprogress.ParaProgress, error) { return paraprogress.NewParaProgress(ctx, []*paraprogress.Process{ paraprogress.NewProcess(txt, fn), }) diff --git a/internal/cli/kraft/fetch/fetch.go b/internal/cli/kraft/fetch/fetch.go index 4c536e547..76e951875 100644 --- a/internal/cli/kraft/fetch/fetch.go +++ b/internal/cli/kraft/fetch/fetch.go @@ -208,7 +208,7 @@ func (opts *FetchOptions) pull(ctx context.Context, project app.Application, wor fmt.Sprintf("pulling %s", unikraft.TypeNameVersion(pullPack), ), - func(ctx context.Context, w func(progress float64)) error { + func(ctx context.Context, prompt func(), w func(progress float64)) error { return pullPack.Pull( ctx, pack.WithPullProgressFunc(w), @@ -346,7 +346,7 @@ func (opts *FetchOptions) pull(ctx context.Context, project app.Application, wor fmt.Sprintf("pulling %s", unikraft.TypeNameVersion(p), ), - func(ctx context.Context, w func(progress float64)) error { + func(ctx context.Context, prompt func(), w func(progress float64)) error { return p.Pull( ctx, pack.WithPullProgressFunc(w), @@ -424,7 +424,7 @@ func (opts *FetchOptions) Run(ctx context.Context, _ []string) error { configure := true if opts.project.IsConfigured(targ) { - configure, err = confirm.NewConfirm("project already configured, are you sure you want to rerun the configure step:") + configure, err = confirm.NewConfirm("project already configured, are you sure you want to rerun the configure step:", func() {}) if err != nil { return err } @@ -433,7 +433,7 @@ func (opts *FetchOptions) Run(ctx context.Context, _ []string) error { if configure { processes = append(processes, paraprogress.NewProcess( fmt.Sprintf("configuring %s (%s)", targ.Name(), target.TargetPlatArchName(targ)), - func(ctx context.Context, w func(progress float64)) error { + func(ctx context.Context, prompt func(), w func(progress float64)) error { return opts.project.Configure( ctx, targ, // Target-specific options @@ -456,7 +456,7 @@ func (opts *FetchOptions) Run(ctx context.Context, _ []string) error { processes = append(processes, paraprogress.NewProcess( fmt.Sprintf("fetching %s (%s)", targ.Name(), target.TargetPlatArchName(targ)), - func(ctx context.Context, w func(progress float64)) error { + func(ctx context.Context, prompt func(), w func(progress float64)) error { err := opts.project.Fetch( ctx, targ, // Target-specific options diff --git a/internal/cli/kraft/lib/create/create.go b/internal/cli/kraft/lib/create/create.go index 0bbe040d5..5b88835d0 100644 --- a/internal/cli/kraft/lib/create/create.go +++ b/internal/cli/kraft/lib/create/create.go @@ -95,7 +95,7 @@ func (opts *CreateOptions) Run(ctx context.Context, args []string) error { if !config.G[config.KraftKit](ctx).NoPrompt { if !opts.GitInit { - opts.GitInit, err = confirm.NewConfirm("Do you want to intialise library with git:") + opts.GitInit, err = confirm.NewConfirm("Do you want to intialise library with git:", func() {}) if err != nil { return err } @@ -124,7 +124,7 @@ func (opts *CreateOptions) Run(ctx context.Context, args []string) error { } if !opts.UpdateRefs { - opts.UpdateRefs, err = confirm.NewConfirm("Do you want to package it:") + opts.UpdateRefs, err = confirm.NewConfirm("Do you want to package it:", func() {}) if err != nil { return err } diff --git a/internal/cli/kraft/menu/menu.go b/internal/cli/kraft/menu/menu.go index b9890383e..5f17d5ab2 100644 --- a/internal/cli/kraft/menu/menu.go +++ b/internal/cli/kraft/menu/menu.go @@ -193,7 +193,7 @@ func (opts *MenuOptions) pull(ctx context.Context, project app.Application, work fmt.Sprintf("pulling %s", unikraft.TypeNameVersion(pullPack), ), - func(ctx context.Context, w func(progress float64)) error { + func(ctx context.Context, prompt func(), w func(progress float64)) error { return pullPack.Pull( ctx, pack.WithPullProgressFunc(w), @@ -337,7 +337,7 @@ func (opts *MenuOptions) pull(ctx context.Context, project app.Application, work fmt.Sprintf("pulling %s", unikraft.TypeNameVersion(p), ), - func(ctx context.Context, w func(progress float64)) error { + func(ctx context.Context, prompt func(), w func(progress float64)) error { return p.Pull( ctx, pack.WithPullProgressFunc(w), @@ -426,7 +426,7 @@ func (opts *MenuOptions) Run(ctx context.Context, _ []string) error { configure := true if opts.project.IsConfigured(targ) { - configure, err = confirm.NewConfirm("project already configured, are you sure you want to rerun the configure step:") + configure, err = confirm.NewConfirm("project already configured, are you sure you want to rerun the configure step:", func() {}) if err != nil { return err } @@ -435,7 +435,7 @@ func (opts *MenuOptions) Run(ctx context.Context, _ []string) error { if configure { processes = append(processes, paraprogress.NewProcess( fmt.Sprintf("configuring %s (%s)", targ.Name(), target.TargetPlatArchName(targ)), - func(ctx context.Context, w func(progress float64)) error { + func(ctx context.Context, prompt func(), w func(progress float64)) error { return opts.project.Configure( ctx, targ, // Target-specific options diff --git a/internal/cli/kraft/pkg/packager_kraftfile_runtime.go b/internal/cli/kraft/pkg/packager_kraftfile_runtime.go index 3de48d187..5a0a7e64c 100644 --- a/internal/cli/kraft/pkg/packager_kraftfile_runtime.go +++ b/internal/cli/kraft/pkg/packager_kraftfile_runtime.go @@ -237,7 +237,7 @@ func (p *packagerKraftfileRuntime) Pack(ctx context.Context, opts *PkgOptions, a ctx, []*paraprogress.Process{paraprogress.NewProcess( fmt.Sprintf("pulling %s", runtime.String()), - func(ctx context.Context, w func(progress float64)) error { + func(ctx context.Context, prompt func(), w func(progress float64)) error { popts := []pack.PullOption{} if log.LoggerTypeFromString(config.G[config.KraftKit](ctx).Log.Type) == log.FANCY { popts = append(popts, pack.WithPullProgressFunc(w)) diff --git a/internal/cli/kraft/pkg/pull/pull.go b/internal/cli/kraft/pkg/pull/pull.go index ea5e573b9..0931b4cd8 100644 --- a/internal/cli/kraft/pkg/pull/pull.go +++ b/internal/cli/kraft/pkg/pull/pull.go @@ -259,7 +259,7 @@ func (opts *PullOptions) Run(ctx context.Context, args []string) error { fmt.Sprintf("pulling %s", unikraft.TypeNameVersion(pullPack), ), - func(ctx context.Context, w func(progress float64)) error { + func(ctx context.Context, prompt func(), w func(progress float64)) error { return pullPack.Pull( ctx, pack.WithPullProgressFunc(w), @@ -457,7 +457,7 @@ func (opts *PullOptions) Run(ctx context.Context, args []string) error { p := p processes = append(processes, paraprogress.NewProcess( fmt.Sprintf("pulling %s", p.String()), - func(ctx context.Context, w func(progress float64)) error { + func(ctx context.Context, prompt func(), w func(progress float64)) error { return p.Pull( ctx, pack.WithPullProgressFunc(w), diff --git a/internal/cli/kraft/run/runner_kraftfile_runtime.go b/internal/cli/kraft/run/runner_kraftfile_runtime.go index 598860012..8d5b10ad0 100644 --- a/internal/cli/kraft/run/runner_kraftfile_runtime.go +++ b/internal/cli/kraft/run/runner_kraftfile_runtime.go @@ -277,7 +277,7 @@ func (runner *runnerKraftfileRuntime) Prepare(ctx context.Context, opts *RunOpti ctx, []*paraprogress.Process{paraprogress.NewProcess( fmt.Sprintf("pulling %s", found.String()), - func(ctx context.Context, w func(progress float64)) error { + func(ctx context.Context, prompt func(), w func(progress float64)) error { popts := []pack.PullOption{} if log.LoggerTypeFromString(config.G[config.KraftKit](ctx).Log.Type) == log.FANCY { popts = append(popts, pack.WithPullProgressFunc(w)) diff --git a/internal/cli/kraft/run/runner_linuxu.go b/internal/cli/kraft/run/runner_linuxu.go index 7bcac6e6b..9da9a7a41 100644 --- a/internal/cli/kraft/run/runner_linuxu.go +++ b/internal/cli/kraft/run/runner_linuxu.go @@ -144,7 +144,7 @@ func (runner *runnerLinuxu) Prepare(ctx context.Context, opts *RunOptions, machi ctx, []*paraprogress.Process{paraprogress.NewProcess( fmt.Sprintf("pulling %s", loader.Name()), - func(ctx context.Context, w func(progress float64)) error { + func(ctx context.Context, prompt func(), w func(progress float64)) error { popts := []pack.PullOption{ pack.WithPullWorkdir(dir), } diff --git a/internal/cli/kraft/run/runner_package.go b/internal/cli/kraft/run/runner_package.go index 5fd1f7765..1ff6a2fa5 100644 --- a/internal/cli/kraft/run/runner_package.go +++ b/internal/cli/kraft/run/runner_package.go @@ -243,7 +243,7 @@ func (runner *runnerPackage) Prepare(ctx context.Context, opts *RunOptions, mach ctx, []*paraprogress.Process{paraprogress.NewProcess( fmt.Sprintf("pulling %s", runner.packName), - func(ctx context.Context, w func(progress float64)) error { + func(ctx context.Context, prompt func(), w func(progress float64)) error { return selected.Pull( ctx, pack.WithPullProgressFunc(w), diff --git a/tui/confirm/confirm.go b/tui/confirm/confirm.go index 5dd59161e..0e2784f88 100644 --- a/tui/confirm/confirm.go +++ b/tui/confirm/confirm.go @@ -13,7 +13,7 @@ import ( // NewConfirm is a utility method used in a CLI context to prompt the user with // a yes/no question. -func NewConfirm(question string) (bool, error) { +func NewConfirm(question string, beforeAfter func()) (bool, error) { input := confirmation.New( tui.TextWhiteBgBlue("[?]")+" "+ question, @@ -24,5 +24,8 @@ func NewConfirm(question string) (bool, error) { input.KeyMap.SelectYes = append(input.KeyMap.SelectYes, "+") input.KeyMap.SelectNo = append(input.KeyMap.SelectNo, "-") + beforeAfter() + defer beforeAfter() + return input.RunPrompt() } diff --git a/tui/paraprogress/process.go b/tui/paraprogress/process.go index 8dead3fdb..54210ae54 100644 --- a/tui/paraprogress/process.go +++ b/tui/paraprogress/process.go @@ -67,8 +67,9 @@ type ProgressMsg struct { type Process struct { id int percent float64 - processFunc func(context.Context, func(float64)) error + processFunc func(context.Context, func(), func(float64)) error progress progress.Model + prompting bool spinner spinner.Model timer stopwatch.Model timerWidth int @@ -85,7 +86,7 @@ type Process struct { Status ProcessStatus } -func NewProcess(name string, processFunc func(context.Context, func(float64)) error) *Process { +func NewProcess(name string, processFunc func(context.Context, func(), func(float64)) error) *Process { d := &Process{ id: nextID(), Name: name, @@ -131,7 +132,7 @@ func (p *Process) Start() tea.Cmd { log.G(p.ctx).Info(p.Name) } - err := p.processFunc(p.ctx, p.onProgress) + err := p.processFunc(p.ctx, p.TogglePrompting, p.onProgress) p.Status = StatusSuccess if err != nil { p.Status = StatusFailed @@ -241,7 +242,11 @@ func (d *Process) Update(msg tea.Msg) (*Process, tea.Cmd) { return d, tea.Batch(cmds...) } -func (p Process) View() string { +func (p *Process) TogglePrompting() { + p.prompting = !p.prompting +} + +func (p *Process) View() string { left := "" switch p.Status { @@ -304,5 +309,9 @@ func (p Process) View() string { } } + if p.prompting { + return "" + } + return s }