github.com/eliastor/durgaform@v0.0.0-20220816172711-d0ab2d17673e/internal/command/views/show.go (about)

     1  package views
     2  
     3  import (
     4  	"fmt"
     5  	"github.com/eliastor/durgaform/internal/command/arguments"
     6  	"github.com/eliastor/durgaform/internal/command/format"
     7  	"github.com/eliastor/durgaform/internal/command/jsonplan"
     8  	"github.com/eliastor/durgaform/internal/command/jsonstate"
     9  	"github.com/eliastor/durgaform/internal/configs"
    10  	"github.com/eliastor/durgaform/internal/plans"
    11  	"github.com/eliastor/durgaform/internal/states/statefile"
    12  	"github.com/eliastor/durgaform/internal/durgaform"
    13  	"github.com/eliastor/durgaform/internal/tfdiags"
    14  )
    15  
    16  type Show interface {
    17  	// Display renders the plan, if it is available. If plan is nil, it renders the statefile.
    18  	Display(config *configs.Config, plan *plans.Plan, stateFile *statefile.File, schemas *durgaform.Schemas) int
    19  
    20  	// Diagnostics renders early diagnostics, resulting from argument parsing.
    21  	Diagnostics(diags tfdiags.Diagnostics)
    22  }
    23  
    24  func NewShow(vt arguments.ViewType, view *View) Show {
    25  	switch vt {
    26  	case arguments.ViewJSON:
    27  		return &ShowJSON{view: view}
    28  	case arguments.ViewHuman:
    29  		return &ShowHuman{view: view}
    30  	default:
    31  		panic(fmt.Sprintf("unknown view type %v", vt))
    32  	}
    33  }
    34  
    35  type ShowHuman struct {
    36  	view *View
    37  }
    38  
    39  var _ Show = (*ShowHuman)(nil)
    40  
    41  func (v *ShowHuman) Display(config *configs.Config, plan *plans.Plan, stateFile *statefile.File, schemas *durgaform.Schemas) int {
    42  	if plan != nil {
    43  		renderPlan(plan, schemas, v.view)
    44  	} else {
    45  		if stateFile == nil {
    46  			v.view.streams.Println("No state.")
    47  			return 0
    48  		}
    49  
    50  		v.view.streams.Println(format.State(&format.StateOpts{
    51  			State:   stateFile.State,
    52  			Color:   v.view.colorize,
    53  			Schemas: schemas,
    54  		}))
    55  	}
    56  	return 0
    57  }
    58  
    59  func (v *ShowHuman) Diagnostics(diags tfdiags.Diagnostics) {
    60  	v.view.Diagnostics(diags)
    61  }
    62  
    63  type ShowJSON struct {
    64  	view *View
    65  }
    66  
    67  var _ Show = (*ShowJSON)(nil)
    68  
    69  func (v *ShowJSON) Display(config *configs.Config, plan *plans.Plan, stateFile *statefile.File, schemas *durgaform.Schemas) int {
    70  	if plan != nil {
    71  		jsonPlan, err := jsonplan.Marshal(config, plan, stateFile, schemas)
    72  
    73  		if err != nil {
    74  			v.view.streams.Eprintf("Failed to marshal plan to json: %s", err)
    75  			return 1
    76  		}
    77  		v.view.streams.Println(string(jsonPlan))
    78  	} else {
    79  		// It is possible that there is neither state nor a plan.
    80  		// That's ok, we'll just return an empty object.
    81  		jsonState, err := jsonstate.Marshal(stateFile, schemas)
    82  		if err != nil {
    83  			v.view.streams.Eprintf("Failed to marshal state to json: %s", err)
    84  			return 1
    85  		}
    86  		v.view.streams.Println(string(jsonState))
    87  	}
    88  	return 0
    89  }
    90  
    91  // Diagnostics should only be called if show cannot be executed.
    92  // In this case, we choose to render human-readable diagnostic output,
    93  // primarily for backwards compatibility.
    94  func (v *ShowJSON) Diagnostics(diags tfdiags.Diagnostics) {
    95  	v.view.Diagnostics(diags)
    96  }