Skip to content

Commit

Permalink
Merge pull request #2428 from ActiveState/mitchell/dx-1449
Browse files Browse the repository at this point in the history
Initial dotprogress indicator for non-interactive mode.
  • Loading branch information
mitchell-as committed Mar 14, 2023
2 parents 6636745 + 6a2bb05 commit 5cc54b4
Show file tree
Hide file tree
Showing 8 changed files with 100 additions and 6 deletions.
4 changes: 1 addition & 3 deletions cmd/state/main.go
Expand Up @@ -39,7 +39,6 @@ import (
"github.com/ActiveState/cli/pkg/platform/model"
"github.com/ActiveState/cli/pkg/project"
"github.com/ActiveState/cli/pkg/projectfile"
"golang.org/x/crypto/ssh/terminal"
)

func main() {
Expand Down Expand Up @@ -99,8 +98,7 @@ func main() {
setPrinterColors(outFlags)

isInteractive := strings.ToLower(os.Getenv(constants.NonInteractiveEnvVarName)) != "true" &&
!outFlags.NonInteractive &&
terminal.IsTerminal(int(os.Stdin.Fd())) &&
out.Config().Interactive &&
out.Type() != output.EditorV0FormatName &&
out.Type() != output.EditorFormatName
// Run our main command logic, which is logic that defers to the error handling logic below
Expand Down
2 changes: 1 addition & 1 deletion cmd/state/output.go
Expand Up @@ -55,7 +55,7 @@ func initOutput(flags outputFlags, formatName string, shellName string) (output.
OutWriter: os.Stdout,
ErrWriter: os.Stderr,
Colored: !flags.DisableColor(),
Interactive: term.IsTerminal(int(os.Stdin.Fd())),
Interactive: !flags.NonInteractive && term.IsTerminal(int(os.Stdin.Fd())),
ShellName: shellName,
})
if err != nil {
Expand Down
2 changes: 2 additions & 0 deletions internal/locale/locales/en-us.yaml
Expand Up @@ -1862,6 +1862,8 @@ progress_project:
other: " • Initializing Project"
progress_search:
other: " • Searching for [ACTIONABLE]{{.V0}}[/RESET] in the ActiveState Catalog"
setup_runtime:
other: "Setting Up Runtime"
progress_solve:
other: "Resolving Dependencies"
progress_success:
Expand Down
48 changes: 48 additions & 0 deletions internal/runbits/runtime/progress/dotprogress.go
@@ -0,0 +1,48 @@
package progress

import (
"time"

"github.com/ActiveState/cli/internal/errs"
"github.com/ActiveState/cli/internal/locale"
"github.com/ActiveState/cli/internal/output"
"github.com/ActiveState/cli/pkg/platform/runtime/setup/events"
)

const dotInterval = time.Second

type DotProgressDigester struct {
out output.Outputer
spinner *output.Spinner
success bool
}

// NewDotProgressIndicator prints dots at an interval while a runtime is being setup (during solve,
// download, and install steps).
// The primary goal is to indicate to various CI systems (or during non-interactive mode) that
// progress is being made.
func NewDotProgressIndicator(out output.Outputer) *DotProgressDigester {
return &DotProgressDigester{out: out}
}

func (d *DotProgressDigester) Handle(event events.Eventer) error {
switch event.(type) {
case events.Start:
d.spinner = output.StartSpinner(d.out, locale.T("setup_runtime"), time.Second)
case events.Success:
d.success = true
}
return nil
}

func (d *DotProgressDigester) Close() error {
if d.spinner == nil {
return errs.New("spinner not initialized")
}
if d.success {
d.spinner.Stop(locale.T("progress_completed"))
} else {
d.spinner.Stop(locale.T("progress_failed"))
}
return nil
}
2 changes: 1 addition & 1 deletion internal/runbits/runtime/progress/progress.go
Expand Up @@ -157,7 +157,7 @@ func (p *ProgressDigester) Handle(ev events.Eventer) error {
p.success = true

case events.SolveStart:
p.out.Notice(locale.Tl("setup_runtime", "Setting Up Runtime"))
p.out.Notice(locale.T("setup_runtime"))
p.solveSpinner = output.StartSpinner(p.out, locale.T("progress_solve"), refreshRate)

case events.SolveError:
Expand Down
5 changes: 4 additions & 1 deletion internal/runbits/runtimeevents.go
Expand Up @@ -14,5 +14,8 @@ func NewRuntimeProgressIndicator(out output.Outputer) events.Handler {
if out.Type() != output.PlainFormatName {
w = nil
}
return progress.NewProgressIndicator(w, out)
if out.Config().Interactive {
return progress.NewProgressIndicator(w, out)
}
return progress.NewDotProgressIndicator(out)
}
1 change: 1 addition & 0 deletions internal/testhelpers/tagsuite/tagsuite.go
Expand Up @@ -50,6 +50,7 @@ const (
Perl = "perl"
Platforms = "platforms"
Prepare = "prepare"
Progress = "progress"
Projects = "projects"
Projectfile = "projectfile"
Pull = "pull"
Expand Down
42 changes: 42 additions & 0 deletions test/integration/progress_int_test.go
@@ -0,0 +1,42 @@
package integration

import (
"testing"

"github.com/ActiveState/cli/internal/locale"
"github.com/ActiveState/cli/internal/testhelpers/e2e"
"github.com/ActiveState/cli/internal/testhelpers/tagsuite"
"github.com/stretchr/testify/suite"
)

type ProgressIntegrationTestSuite struct {
tagsuite.Suite
}

func (suite *ProgressIntegrationTestSuite) TestProgress() {
suite.OnlyRunForTags(tagsuite.Progress)
ts := e2e.New(suite.T(), false)
defer ts.Close()

cp := ts.SpawnWithOpts(
e2e.WithArgs("checkout", "ActiveState-CLI/small-python"),
e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"),
)
cp.Expect(locale.T("setup_runtime"))
cp.Expect("Checked out")
suite.Assert().NotContains(cp.TrimmedSnapshot(), "...")
cp.ExpectExitCode(0)

cp = ts.SpawnWithOpts(
e2e.WithArgs("checkout", "ActiveState-CLI/small-python", "small-python2", "--non-interactive"),
e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"),
)
cp.Expect(locale.T("setup_runtime"))
cp.Expect("...")
cp.Expect("Checked out")
cp.ExpectExitCode(0)
}

func TestProgressIntegrationTestSuite(t *testing.T) {
suite.Run(t, new(ProgressIntegrationTestSuite))
}

0 comments on commit 5cc54b4

Please sign in to comment.