Skip to content

Migrate Terraform commands from cli.Ui to views.View abstractions when rendering output. Investigate use of Streams, too. #37439

Description

@SarahFrench

Background

Different parts of the code base render output using either the older cli.Ui abstraction, or the newer views.View abstraction.

Views were introduced in #27738 to minimise the code needed to render output in either Human or JSON formats. Since then, only commands that have the option to create JSON/machine-readable output have been migrated to using Views. Other commands are still using the old Ui approach, and it's possible for one command to use a mixture of the two, due to both being accessible in a command's Meta. Two parallel solutions for the same problem makes it harder to onboard to the codebase.

Proposal

We should ensure that we migrate all commands over to using Views eventually. This appears to have been the plan in the past, but understandably it's a low-priority piece of work:

// Reconfigure the view. This is necessary for commands which use both
// views.View and cli.Ui during the migration phase.

Not in scope

  • Changes to how input is gathered.
  • Eliminating use of github.com/hashicorp/cli

Progress

Command Uses arguments package? Uses views package? Full migrated? PRs
console Yes No
fmt Yes No
get Yes Yes ✅ #39217
graph Yes No
import Yes No
init Yes Yes ✅ #37920 <- removed use of cli.Ui in meta_backend.go
login Yes No Args: #39319
logout Yes No Args: #39318
providers Yes No
providers lock Yes No
providers mirror Yes No
providers schema Yes No
state identities Yes No Args: #39334
state list Yes No
state pull Yes No
state push Yes No
state rm Yes No
state mv Yes No
state replace-provider Yes No
taint Yes No
unlock No No Args: #39336
untaint Yes No
version Yes Yes
workspace new Yes Yes ✅ #39191
workspace list Yes Yes ✅ #38925
workspace select Yes No
workspace show Yes Yes ✅ #39198
workspace delete Yes No

Also, an honourable mention for code in internal/command/meta_backend.go that mixes Views and Ui. That code is specific to the init command though, so could be addressed at the same time as the init command.

Caveats

Both use of cli.Ui and views logs errors to stderr and warnings to stdout. See: #38811

References

Code

The Meta allows access to both a Ui and a View:

View *views.View
Color bool // True if output should be colored
GlobalPluginDirs []string // Additional paths to search for plugins
Ui cli.Ui // Ui for output

The Meta struct also has some methods for handling output via Ui:

func (m *Meta) showDiagnostics(vals ...interface{}) {

The newer alternative(s) of the method above is the Diagnostics method in the Operation interface which is implemented differently for Human or JSON output:

type Operation interface {
Interrupted()
FatalInterrupt()
Stopping()
Cancelled(planMode plans.Mode)
EmergencyDumpState(stateFile *statefile.File) error
PlannedChange(change *plans.ResourceInstanceChangeSrc)
Plan(plan *plans.Plan, schemas *terraform.Schemas)
PlanNextStep(planPath string, genConfigPath string)
Diagnostics(diags tfdiags.Diagnostics)
}

Related issues

Potentially addresses #34768

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions