github.com/terramate-io/tf@v0.0.0-20230830114523-fce866b4dfcd/command/providers_schema.go (about)

     1  // Copyright (c) HashiCorp, Inc.
     2  // SPDX-License-Identifier: MPL-2.0
     3  
     4  package command
     5  
     6  import (
     7  	"fmt"
     8  	"os"
     9  
    10  	"github.com/terramate-io/tf/backend"
    11  	"github.com/terramate-io/tf/command/arguments"
    12  	"github.com/terramate-io/tf/command/jsonprovider"
    13  	"github.com/terramate-io/tf/tfdiags"
    14  )
    15  
    16  // ProvidersCommand is a Command implementation that prints out information
    17  // about the providers used in the current configuration/state.
    18  type ProvidersSchemaCommand struct {
    19  	Meta
    20  }
    21  
    22  func (c *ProvidersSchemaCommand) Help() string {
    23  	return providersSchemaCommandHelp
    24  }
    25  
    26  func (c *ProvidersSchemaCommand) Synopsis() string {
    27  	return "Show schemas for the providers used in the configuration"
    28  }
    29  
    30  func (c *ProvidersSchemaCommand) Run(args []string) int {
    31  	args = c.Meta.process(args)
    32  	cmdFlags := c.Meta.defaultFlagSet("providers schema")
    33  	var jsonOutput bool
    34  	cmdFlags.BoolVar(&jsonOutput, "json", false, "produce JSON output")
    35  
    36  	cmdFlags.Usage = func() { c.Ui.Error(c.Help()) }
    37  	if err := cmdFlags.Parse(args); err != nil {
    38  		c.Ui.Error(fmt.Sprintf("Error parsing command-line flags: %s\n", err.Error()))
    39  		return 1
    40  	}
    41  
    42  	if !jsonOutput {
    43  		c.Ui.Error(
    44  			"The `terraform providers schema` command requires the `-json` flag.\n")
    45  		cmdFlags.Usage()
    46  		return 1
    47  	}
    48  
    49  	// Check for user-supplied plugin path
    50  	var err error
    51  	if c.pluginPath, err = c.loadPluginPath(); err != nil {
    52  		c.Ui.Error(fmt.Sprintf("Error loading plugin path: %s", err))
    53  		return 1
    54  	}
    55  
    56  	var diags tfdiags.Diagnostics
    57  
    58  	// Load the backend
    59  	b, backendDiags := c.Backend(nil)
    60  	diags = diags.Append(backendDiags)
    61  	if backendDiags.HasErrors() {
    62  		c.showDiagnostics(diags)
    63  		return 1
    64  	}
    65  
    66  	// We require a local backend
    67  	local, ok := b.(backend.Local)
    68  	if !ok {
    69  		c.showDiagnostics(diags) // in case of any warnings in here
    70  		c.Ui.Error(ErrUnsupportedLocalOp)
    71  		return 1
    72  	}
    73  
    74  	// This is a read-only command
    75  	c.ignoreRemoteVersionConflict(b)
    76  
    77  	// we expect that the config dir is the cwd
    78  	cwd, err := os.Getwd()
    79  	if err != nil {
    80  		c.Ui.Error(fmt.Sprintf("Error getting cwd: %s", err))
    81  		return 1
    82  	}
    83  
    84  	// Build the operation
    85  	opReq := c.Operation(b, arguments.ViewJSON)
    86  	opReq.ConfigDir = cwd
    87  	opReq.ConfigLoader, err = c.initConfigLoader()
    88  	opReq.AllowUnsetVariables = true
    89  	if err != nil {
    90  		diags = diags.Append(err)
    91  		c.showDiagnostics(diags)
    92  		return 1
    93  	}
    94  
    95  	// Get the context
    96  	lr, _, ctxDiags := local.LocalRun(opReq)
    97  	diags = diags.Append(ctxDiags)
    98  	if ctxDiags.HasErrors() {
    99  		c.showDiagnostics(diags)
   100  		return 1
   101  	}
   102  
   103  	schemas, moreDiags := lr.Core.Schemas(lr.Config, lr.InputState)
   104  	diags = diags.Append(moreDiags)
   105  	if moreDiags.HasErrors() {
   106  		c.showDiagnostics(diags)
   107  		return 1
   108  	}
   109  
   110  	jsonSchemas, err := jsonprovider.Marshal(schemas)
   111  	if err != nil {
   112  		c.Ui.Error(fmt.Sprintf("Failed to marshal provider schemas to json: %s", err))
   113  		return 1
   114  	}
   115  	c.Ui.Output(string(jsonSchemas))
   116  
   117  	return 0
   118  }
   119  
   120  const providersSchemaCommandHelp = `
   121  Usage: terraform [global options] providers schema -json
   122  
   123    Prints out a json representation of the schemas for all providers used 
   124    in the current configuration.
   125  `