From c8ce0a501669a73717ec5c24abdb2f9751f3c6c3 Mon Sep 17 00:00:00 2001 From: Nathan Rijksen Date: Wed, 21 Aug 2024 14:47:29 -0700 Subject: [PATCH 1/5] Implement multi-spinner. Non-interactive has unpolished UI/UX at this stage. --- internal/output/progress.go | 2 +- internal/output/spinner/noninteractive.go | 49 +++++++ internal/output/spinner/spinner.go | 124 ++++++++++++++++++ .../runtime/requirements/requirements.go | 17 ++- 4 files changed, 187 insertions(+), 5 deletions(-) create mode 100644 internal/output/spinner/noninteractive.go create mode 100644 internal/output/spinner/spinner.go diff --git a/internal/output/progress.go b/internal/output/progress.go index 6aff32be14..d54e74edb6 100644 --- a/internal/output/progress.go +++ b/internal/output/progress.go @@ -28,7 +28,7 @@ func (d *Spinner) MarshalOutput(f Format) interface{} { func StartSpinner(out Outputer, msg string, interval time.Duration) *Spinner { frames := []string{".", "..", "..."} if out.Config().Interactive { - frames = []string{`|`, `/`, `-`, `\`} + frames = SpinnerFrames } d := &Spinner{0, frames, out, make(chan struct{}, 1), interval, false} diff --git a/internal/output/spinner/noninteractive.go b/internal/output/spinner/noninteractive.go new file mode 100644 index 0000000000..972934919e --- /dev/null +++ b/internal/output/spinner/noninteractive.go @@ -0,0 +1,49 @@ +package spinner + +import ( + "os" + "time" + + "github.com/ActiveState/cli/internal/constants" +) + +type nonInteractive struct { + isGroup bool + supportsColors bool + stop chan struct{} +} + +func newNonInteractive(isGroup, supportColors bool) *nonInteractive { + n := &nonInteractive{isGroup: isGroup, supportsColors: supportColors, stop: make(chan struct{}, 1)} + go n.ticker() + return n +} + +func (n *nonInteractive) ticker() { + ticker := time.NewTicker(constants.TerminalAnimationInterval) + for { + select { + case <-ticker.C: + os.Stderr.WriteString(".") + case <-n.stop: + return + } + } +} + +func (n *nonInteractive) Add(prefix string) Spinnable { + os.Stderr.WriteString("\n" + color(prefix, !n.supportsColors) + " ") + return n +} + +func (n *nonInteractive) Wait() { + n.stop <- struct{}{} +} + +func (n *nonInteractive) Stop(msg string) { + os.Stderr.WriteString(color(msg, !n.supportsColors) + "\n") + if !n.isGroup { + // If this isn't a group Wait will never be called + n.stop <- struct{}{} + } +} diff --git a/internal/output/spinner/spinner.go b/internal/output/spinner/spinner.go new file mode 100644 index 0000000000..7ced25695d --- /dev/null +++ b/internal/output/spinner/spinner.go @@ -0,0 +1,124 @@ +package spinner + +import ( + "bytes" + "io" + "strings" + + "github.com/ActiveState/cli/internal/colorize" + "github.com/ActiveState/cli/internal/errs" + "github.com/ActiveState/cli/internal/logging" + "github.com/vbauerster/mpb/v7" + "github.com/vbauerster/mpb/v7/decor" +) + +type Groupable interface { + Add(prefix string) Spinnable + Wait() +} + +type Spinnable interface { + Stop(msg string) +} + +// Group collects multiple spinners +type Group struct { + mpbGroup *mpb.Progress + supportColors bool + interactive bool +} + +// Spinner represents a single spinner +type Spinner struct { + mpbBar *mpb.Bar + completionMsg string +} + +// StandaloneSpinner represents a single spinner that is used in standalone, meaning it doesn't have a group. +type StandaloneSpinner struct { + *Spinner + mpbGroup *mpb.Progress +} + +func NewGroup(supportColors, interactive bool) Groupable { + if !interactive { + return newNonInteractive(true, supportColors) + } + return &Group{mpb.New( + mpb.WithWidth(1)), + supportColors, + interactive, + } +} + +func NewSpinner(prefix string, supportColors, interactive bool) Spinnable { + if !interactive { + n := newNonInteractive(false, supportColors) + n.Add(prefix) + return n + } + mpbGroup := mpb.New(mpb.WithWidth(1)) + return &StandaloneSpinner{newSpinner(mpbGroup, prefix, supportColors, interactive), mpbGroup} +} + +func newSpinner(mpbGroup *mpb.Progress, prefix string, supportColors, interactive bool) *Spinner { + s := &Spinner{} + p := mpbGroup.Add( + 1, + mpb.NewBarFiller(mpb.SpinnerStyle([]string{`|`, `/`, `-`, `\`}...)), + mpb.PrependDecorators(decor.Any(func(s decor.Statistics) string { + return color(prefix, !supportColors) + })), + barFillerOnComplete(func() string { return color(strings.TrimPrefix(s.completionMsg, " "), !supportColors) }), + ) + s.mpbBar = p + return s +} + +func (g *Group) Add(prefix string) Spinnable { + s := newSpinner(g.mpbGroup, prefix, g.supportColors, g.interactive) + return s +} + +func (s *Spinner) Stop(msg string) { + s.completionMsg = msg + s.mpbBar.Increment() // Our "bar" has a total of 1, so a single increment will complete it +} + +func (s *StandaloneSpinner) Stop(msg string) { + s.Spinner.Stop(msg) + s.mpbGroup.Wait() +} + +func (g *Group) Wait() { + g.mpbGroup.Wait() +} + +func color(v string, strip bool) string { + if strip { + return colorize.StripColorCodes(v) + } + + b := &bytes.Buffer{} + _, err := colorize.Colorize(v, b, false) + if err != nil { + logging.Warning("colorize failed, stripping colors - error: %s", errs.JoinMessage(err)) + v = colorize.StripColorCodes(v) + } else { + v = b.String() + } + + return v +} + +func barFillerOnComplete(value func() string) mpb.BarOption { + return mpb.BarFillerMiddleware(func(base mpb.BarFiller) mpb.BarFiller { + return mpb.BarFillerFunc(func(w io.Writer, reqWidth int, st decor.Statistics) { + if st.Completed { + io.WriteString(w, value()) + } else { + base.Fill(w, reqWidth, st) + } + }) + }) +} diff --git a/internal/runbits/runtime/requirements/requirements.go b/internal/runbits/runtime/requirements/requirements.go index 65feccae49..c928ae1586 100644 --- a/internal/runbits/runtime/requirements/requirements.go +++ b/internal/runbits/runtime/requirements/requirements.go @@ -18,6 +18,7 @@ import ( "github.com/ActiveState/cli/internal/logging" "github.com/ActiveState/cli/internal/multilog" "github.com/ActiveState/cli/internal/output" + "github.com/ActiveState/cli/internal/output/spinner" "github.com/ActiveState/cli/internal/primer" "github.com/ActiveState/cli/internal/prompt" "github.com/ActiveState/cli/internal/rtutils/ptr" @@ -137,13 +138,18 @@ func (r *RequirementOperation) ExecuteRequirementOperation(ts *time.Time, requir return errNoRequirements } + pgGroup := spinner.NewGroup(r.Output.Config().Colored, r.Output.Config().Interactive) + out := r.Output - var pg *output.Spinner + var pg spinner.Spinnable defer func() { + // This is a bit awkward, but it would be even more awkward to manually address this for every error condition if pg != nil { - // This is a bit awkward, but it would be even more awkward to manually address this for every error condition pg.Stop(locale.T("progress_fail")) } + if pgGroup != nil { + pgGroup.Wait() + } }() if r.Project == nil { @@ -168,7 +174,7 @@ func (r *RequirementOperation) ExecuteRequirementOperation(ts *time.Time, requir } hasParentCommit := parentCommitID != "" - pg = output.StartSpinner(out, locale.T("progress_commit"), constants.TerminalAnimationInterval) + pg = pgGroup.Add(locale.T("progress_commit")) if err := r.checkForUpdate(parentCommitID, requirements...); err != nil { return locale.WrapError(err, "err_check_for_update", "Could not check for requirements updates") @@ -214,7 +220,7 @@ func (r *RequirementOperation) ExecuteRequirementOperation(ts *time.Time, requir } // Solve runtime - solveSpinner := output.StartSpinner(r.Output, locale.T("progress_solve_preruntime"), constants.TerminalAnimationInterval) + solveSpinner := pgGroup.Add(locale.T("progress_solve_preruntime")) commit, err := bp.StageCommit(params) if err != nil { solveSpinner.Stop(locale.T("progress_fail")) @@ -242,6 +248,9 @@ func (r *RequirementOperation) ExecuteRequirementOperation(ts *time.Time, requir } solveSpinner.Stop(locale.T("progress_success")) + pgGroup.Wait() + pgGroup = nil + dependencies.OutputChangeSummary(r.prime.Output(), commit.BuildPlan(), oldCommit.BuildPlan()) // Report CVEs From 0b7c40413d942665545d116e6d64f7a101d9776c Mon Sep 17 00:00:00 2001 From: Nathan Rijksen Date: Wed, 21 Aug 2024 14:47:38 -0700 Subject: [PATCH 2/5] Revert "Implement multi-spinner. Non-interactive has unpolished UI/UX at this stage." This reverts commit c8ce0a501669a73717ec5c24abdb2f9751f3c6c3. --- internal/output/progress.go | 2 +- internal/output/spinner/noninteractive.go | 49 ------- internal/output/spinner/spinner.go | 124 ------------------ .../runtime/requirements/requirements.go | 17 +-- 4 files changed, 5 insertions(+), 187 deletions(-) delete mode 100644 internal/output/spinner/noninteractive.go delete mode 100644 internal/output/spinner/spinner.go diff --git a/internal/output/progress.go b/internal/output/progress.go index d54e74edb6..6aff32be14 100644 --- a/internal/output/progress.go +++ b/internal/output/progress.go @@ -28,7 +28,7 @@ func (d *Spinner) MarshalOutput(f Format) interface{} { func StartSpinner(out Outputer, msg string, interval time.Duration) *Spinner { frames := []string{".", "..", "..."} if out.Config().Interactive { - frames = SpinnerFrames + frames = []string{`|`, `/`, `-`, `\`} } d := &Spinner{0, frames, out, make(chan struct{}, 1), interval, false} diff --git a/internal/output/spinner/noninteractive.go b/internal/output/spinner/noninteractive.go deleted file mode 100644 index 972934919e..0000000000 --- a/internal/output/spinner/noninteractive.go +++ /dev/null @@ -1,49 +0,0 @@ -package spinner - -import ( - "os" - "time" - - "github.com/ActiveState/cli/internal/constants" -) - -type nonInteractive struct { - isGroup bool - supportsColors bool - stop chan struct{} -} - -func newNonInteractive(isGroup, supportColors bool) *nonInteractive { - n := &nonInteractive{isGroup: isGroup, supportsColors: supportColors, stop: make(chan struct{}, 1)} - go n.ticker() - return n -} - -func (n *nonInteractive) ticker() { - ticker := time.NewTicker(constants.TerminalAnimationInterval) - for { - select { - case <-ticker.C: - os.Stderr.WriteString(".") - case <-n.stop: - return - } - } -} - -func (n *nonInteractive) Add(prefix string) Spinnable { - os.Stderr.WriteString("\n" + color(prefix, !n.supportsColors) + " ") - return n -} - -func (n *nonInteractive) Wait() { - n.stop <- struct{}{} -} - -func (n *nonInteractive) Stop(msg string) { - os.Stderr.WriteString(color(msg, !n.supportsColors) + "\n") - if !n.isGroup { - // If this isn't a group Wait will never be called - n.stop <- struct{}{} - } -} diff --git a/internal/output/spinner/spinner.go b/internal/output/spinner/spinner.go deleted file mode 100644 index 7ced25695d..0000000000 --- a/internal/output/spinner/spinner.go +++ /dev/null @@ -1,124 +0,0 @@ -package spinner - -import ( - "bytes" - "io" - "strings" - - "github.com/ActiveState/cli/internal/colorize" - "github.com/ActiveState/cli/internal/errs" - "github.com/ActiveState/cli/internal/logging" - "github.com/vbauerster/mpb/v7" - "github.com/vbauerster/mpb/v7/decor" -) - -type Groupable interface { - Add(prefix string) Spinnable - Wait() -} - -type Spinnable interface { - Stop(msg string) -} - -// Group collects multiple spinners -type Group struct { - mpbGroup *mpb.Progress - supportColors bool - interactive bool -} - -// Spinner represents a single spinner -type Spinner struct { - mpbBar *mpb.Bar - completionMsg string -} - -// StandaloneSpinner represents a single spinner that is used in standalone, meaning it doesn't have a group. -type StandaloneSpinner struct { - *Spinner - mpbGroup *mpb.Progress -} - -func NewGroup(supportColors, interactive bool) Groupable { - if !interactive { - return newNonInteractive(true, supportColors) - } - return &Group{mpb.New( - mpb.WithWidth(1)), - supportColors, - interactive, - } -} - -func NewSpinner(prefix string, supportColors, interactive bool) Spinnable { - if !interactive { - n := newNonInteractive(false, supportColors) - n.Add(prefix) - return n - } - mpbGroup := mpb.New(mpb.WithWidth(1)) - return &StandaloneSpinner{newSpinner(mpbGroup, prefix, supportColors, interactive), mpbGroup} -} - -func newSpinner(mpbGroup *mpb.Progress, prefix string, supportColors, interactive bool) *Spinner { - s := &Spinner{} - p := mpbGroup.Add( - 1, - mpb.NewBarFiller(mpb.SpinnerStyle([]string{`|`, `/`, `-`, `\`}...)), - mpb.PrependDecorators(decor.Any(func(s decor.Statistics) string { - return color(prefix, !supportColors) - })), - barFillerOnComplete(func() string { return color(strings.TrimPrefix(s.completionMsg, " "), !supportColors) }), - ) - s.mpbBar = p - return s -} - -func (g *Group) Add(prefix string) Spinnable { - s := newSpinner(g.mpbGroup, prefix, g.supportColors, g.interactive) - return s -} - -func (s *Spinner) Stop(msg string) { - s.completionMsg = msg - s.mpbBar.Increment() // Our "bar" has a total of 1, so a single increment will complete it -} - -func (s *StandaloneSpinner) Stop(msg string) { - s.Spinner.Stop(msg) - s.mpbGroup.Wait() -} - -func (g *Group) Wait() { - g.mpbGroup.Wait() -} - -func color(v string, strip bool) string { - if strip { - return colorize.StripColorCodes(v) - } - - b := &bytes.Buffer{} - _, err := colorize.Colorize(v, b, false) - if err != nil { - logging.Warning("colorize failed, stripping colors - error: %s", errs.JoinMessage(err)) - v = colorize.StripColorCodes(v) - } else { - v = b.String() - } - - return v -} - -func barFillerOnComplete(value func() string) mpb.BarOption { - return mpb.BarFillerMiddleware(func(base mpb.BarFiller) mpb.BarFiller { - return mpb.BarFillerFunc(func(w io.Writer, reqWidth int, st decor.Statistics) { - if st.Completed { - io.WriteString(w, value()) - } else { - base.Fill(w, reqWidth, st) - } - }) - }) -} diff --git a/internal/runbits/runtime/requirements/requirements.go b/internal/runbits/runtime/requirements/requirements.go index c928ae1586..65feccae49 100644 --- a/internal/runbits/runtime/requirements/requirements.go +++ b/internal/runbits/runtime/requirements/requirements.go @@ -18,7 +18,6 @@ import ( "github.com/ActiveState/cli/internal/logging" "github.com/ActiveState/cli/internal/multilog" "github.com/ActiveState/cli/internal/output" - "github.com/ActiveState/cli/internal/output/spinner" "github.com/ActiveState/cli/internal/primer" "github.com/ActiveState/cli/internal/prompt" "github.com/ActiveState/cli/internal/rtutils/ptr" @@ -138,18 +137,13 @@ func (r *RequirementOperation) ExecuteRequirementOperation(ts *time.Time, requir return errNoRequirements } - pgGroup := spinner.NewGroup(r.Output.Config().Colored, r.Output.Config().Interactive) - out := r.Output - var pg spinner.Spinnable + var pg *output.Spinner defer func() { - // This is a bit awkward, but it would be even more awkward to manually address this for every error condition if pg != nil { + // This is a bit awkward, but it would be even more awkward to manually address this for every error condition pg.Stop(locale.T("progress_fail")) } - if pgGroup != nil { - pgGroup.Wait() - } }() if r.Project == nil { @@ -174,7 +168,7 @@ func (r *RequirementOperation) ExecuteRequirementOperation(ts *time.Time, requir } hasParentCommit := parentCommitID != "" - pg = pgGroup.Add(locale.T("progress_commit")) + pg = output.StartSpinner(out, locale.T("progress_commit"), constants.TerminalAnimationInterval) if err := r.checkForUpdate(parentCommitID, requirements...); err != nil { return locale.WrapError(err, "err_check_for_update", "Could not check for requirements updates") @@ -220,7 +214,7 @@ func (r *RequirementOperation) ExecuteRequirementOperation(ts *time.Time, requir } // Solve runtime - solveSpinner := pgGroup.Add(locale.T("progress_solve_preruntime")) + solveSpinner := output.StartSpinner(r.Output, locale.T("progress_solve_preruntime"), constants.TerminalAnimationInterval) commit, err := bp.StageCommit(params) if err != nil { solveSpinner.Stop(locale.T("progress_fail")) @@ -248,9 +242,6 @@ func (r *RequirementOperation) ExecuteRequirementOperation(ts *time.Time, requir } solveSpinner.Stop(locale.T("progress_success")) - pgGroup.Wait() - pgGroup = nil - dependencies.OutputChangeSummary(r.prime.Output(), commit.BuildPlan(), oldCommit.BuildPlan()) // Report CVEs From a8827ea1fcf5b587e183c43b5f58d48806efec11 Mon Sep 17 00:00:00 2001 From: Nathan Rijksen Date: Wed, 21 Aug 2024 14:50:44 -0700 Subject: [PATCH 3/5] Drop the commit progress spinner, instead everything is handled under "solve" --- internal/output/progress.go | 4 ++-- .../runbits/runtime/requirements/requirements.go | 12 ++++-------- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/internal/output/progress.go b/internal/output/progress.go index 6aff32be14..9331a40f59 100644 --- a/internal/output/progress.go +++ b/internal/output/progress.go @@ -26,9 +26,9 @@ func (d *Spinner) MarshalOutput(f Format) interface{} { } func StartSpinner(out Outputer, msg string, interval time.Duration) *Spinner { - frames := []string{".", "..", "..."} + frames := []string{"."} if out.Config().Interactive { - frames = []string{`|`, `/`, `-`, `\`} + frames = SpinnerFrames } d := &Spinner{0, frames, out, make(chan struct{}, 1), interval, false} diff --git a/internal/runbits/runtime/requirements/requirements.go b/internal/runbits/runtime/requirements/requirements.go index 65feccae49..f7625b5e1d 100644 --- a/internal/runbits/runtime/requirements/requirements.go +++ b/internal/runbits/runtime/requirements/requirements.go @@ -168,7 +168,7 @@ func (r *RequirementOperation) ExecuteRequirementOperation(ts *time.Time, requir } hasParentCommit := parentCommitID != "" - pg = output.StartSpinner(out, locale.T("progress_commit"), constants.TerminalAnimationInterval) + pg = output.StartSpinner(r.Output, locale.T("progress_solve_preruntime"), constants.TerminalAnimationInterval) if err := r.checkForUpdate(parentCommitID, requirements...); err != nil { return locale.WrapError(err, "err_check_for_update", "Could not check for requirements updates") @@ -214,16 +214,11 @@ func (r *RequirementOperation) ExecuteRequirementOperation(ts *time.Time, requir } // Solve runtime - solveSpinner := output.StartSpinner(r.Output, locale.T("progress_solve_preruntime"), constants.TerminalAnimationInterval) commit, err := bp.StageCommit(params) if err != nil { - solveSpinner.Stop(locale.T("progress_fail")) return errs.Wrap(err, "Could not stage commit") } - pg.Stop(locale.T("progress_success")) - pg = nil - ns := requirements[0].Namespace var trig trigger.Trigger switch ns.Type() { @@ -237,10 +232,11 @@ func (r *RequirementOperation) ExecuteRequirementOperation(ts *time.Time, requir oldCommit, err := bp.FetchCommit(parentCommitID, r.Project.Owner(), r.Project.Name(), nil) if err != nil { - solveSpinner.Stop(locale.T("progress_fail")) return errs.Wrap(err, "Failed to fetch old build result") } - solveSpinner.Stop(locale.T("progress_success")) + + pg.Stop(locale.T("progress_success")) + pg = nil dependencies.OutputChangeSummary(r.prime.Output(), commit.BuildPlan(), oldCommit.BuildPlan()) From 53edce9cce4dbb7e5067c17dbb2591a723456731 Mon Sep 17 00:00:00 2001 From: Nathan Rijksen Date: Thu, 22 Aug 2024 09:44:10 -0700 Subject: [PATCH 4/5] Drop commit progress from import as well --- internal/runners/packages/import.go | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/internal/runners/packages/import.go b/internal/runners/packages/import.go index 43336fa51f..cc7d89f587 100644 --- a/internal/runners/packages/import.go +++ b/internal/runners/packages/import.go @@ -103,7 +103,7 @@ func (i *Import) Run(params *ImportRunParams) (rerr error) { return locale.WrapError(err, "err_import_language", "Unable to get language from project") } - pg := output.StartSpinner(out, locale.T("progress_commit"), constants.TerminalAnimationInterval) + pg := output.StartSpinner(i.prime.Output(), locale.T("progress_solve_preruntime"), constants.TerminalAnimationInterval) defer func() { if pg != nil { pg.Stop(locale.T("progress_fail")) @@ -125,7 +125,6 @@ func (i *Import) Run(params *ImportRunParams) (rerr error) { return locale.WrapError(err, "err_cannot_apply_changeset", "Could not apply changeset") } - solveSpinner := output.StartSpinner(i.prime.Output(), locale.T("progress_solve_preruntime"), constants.TerminalAnimationInterval) msg := locale.T("commit_reqstext_message") stagedCommit, err := bp.StageCommit(buildplanner.StageCommitParams{ Owner: proj.Owner(), @@ -137,24 +136,21 @@ func (i *Import) Run(params *ImportRunParams) (rerr error) { // Always update the local commit ID even if the commit fails to build if stagedCommit != nil && stagedCommit.Commit != nil && stagedCommit.Commit.CommitID != "" { if err := localcommit.Set(proj.Dir(), stagedCommit.CommitID.String()); err != nil { - solveSpinner.Stop(locale.T("progress_fail")) return locale.WrapError(err, "err_package_update_commit_id") } - pg.Stop(locale.T("progress_success")) - pg = nil } if err != nil { - solveSpinner.Stop(locale.T("progress_fail")) return locale.WrapError(err, "err_commit_changeset", "Could not commit import changes") } // Output change summary. previousCommit, err := bp.FetchCommit(localCommitId, proj.Owner(), proj.Name(), nil) if err != nil { - solveSpinner.Stop(locale.T("progress_fail")) return errs.Wrap(err, "Failed to fetch build result for previous commit") } - solveSpinner.Stop(locale.T("progress_success")) + + pg.Stop(locale.T("progress_success")) + pg = nil dependencies.OutputChangeSummary(i.prime.Output(), stagedCommit.BuildPlan(), previousCommit.BuildPlan()) From 5ab1e8ef7544b87784d0a280998f511f0e44d706 Mon Sep 17 00:00:00 2001 From: Nathan Rijksen Date: Thu, 22 Aug 2024 10:13:10 -0700 Subject: [PATCH 5/5] Fix tests --- test/integration/import_int_test.go | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/test/integration/import_int_test.go b/test/integration/import_int_test.go index 3f94af81f1..b55fff639f 100644 --- a/test/integration/import_int_test.go +++ b/test/integration/import_int_test.go @@ -41,7 +41,6 @@ func (suite *ImportIntegrationTestSuite) TestImport_detached() { cp = ts.Spawn("import", importPath) cp.Expect("Operating on project") cp.Expect("ActiveState-CLI/small-python") - cp.Expect("Creating commit") cp.Expect("Resolving Dependencies") cp.Expect("Import Finished") cp.ExpectExitCode(0) @@ -158,8 +157,9 @@ func (suite *ImportIntegrationTestSuite) TestImportCycloneDx() { for _, sbom := range []string{jsonSbom, xmlSbom} { suite.Run("import "+sbom, func() { cp := ts.Spawn("import", sbom) - cp.Expect("Creating commit") - cp.Expect("Done") + cp.Expect("Resolving Dependencies") + cp.Expect("Failed") + cp.Expect("unavailable") cp.ExpectNotExitCode(0) // solve should fail due to private namespace cp = ts.Spawn("history") @@ -193,8 +193,9 @@ func (suite *ImportIntegrationTestSuite) TestImportSpdx() { jsonSbom := filepath.Join(osutil.GetTestDataDir(), "import", "spdx", "appbomination.spdx.json") cp = ts.Spawn("import", jsonSbom) - cp.Expect("Creating commit") - cp.Expect("Done") + cp.Expect("Resolving Dependencies") + cp.Expect("Failed") + cp.Expect("unavailable") cp.ExpectNotExitCode(0) // solve should fail due to private namespace cp = ts.Spawn("history") @@ -217,8 +218,9 @@ func (suite *ImportIntegrationTestSuite) TestImportSpdx() { spdxSbom := filepath.Join(osutil.GetTestDataDir(), "import", "spdx", "example1.spdx") cp = ts.Spawn("import", spdxSbom) - cp.Expect("Creating commit") - cp.Expect("Done") + cp.Expect("Resolving Dependencies") + cp.Expect("Failed") + cp.Expect("unavailable") cp.ExpectNotExitCode(0) // solve should fail due to private namespace cp = ts.Spawn("history")