github.com/jaredpalmer/terraform@v1.1.0-alpha20210908.0.20210911170307-88705c943a03/internal/repl/session.go (about) 1 package repl 2 3 import ( 4 "strings" 5 6 "github.com/zclconf/go-cty/cty" 7 8 "github.com/hashicorp/hcl/v2" 9 "github.com/hashicorp/hcl/v2/hclsyntax" 10 "github.com/hashicorp/terraform/internal/lang" 11 "github.com/hashicorp/terraform/internal/tfdiags" 12 ) 13 14 // Session represents the state for a single REPL session. 15 type Session struct { 16 // Scope is the evaluation scope where expressions will be evaluated. 17 Scope *lang.Scope 18 } 19 20 // Handle handles a single line of input from the REPL. 21 // 22 // This is a stateful operation if a command is given (such as setting 23 // a variable). This function should not be called in parallel. 24 // 25 // The return value is the output and the error to show. 26 func (s *Session) Handle(line string) (string, bool, tfdiags.Diagnostics) { 27 switch { 28 case strings.TrimSpace(line) == "": 29 return "", false, nil 30 case strings.TrimSpace(line) == "exit": 31 return "", true, nil 32 case strings.TrimSpace(line) == "help": 33 ret, diags := s.handleHelp() 34 return ret, false, diags 35 default: 36 ret, diags := s.handleEval(line) 37 return ret, false, diags 38 } 39 } 40 41 func (s *Session) handleEval(line string) (string, tfdiags.Diagnostics) { 42 var diags tfdiags.Diagnostics 43 44 // Parse the given line as an expression 45 expr, parseDiags := hclsyntax.ParseExpression([]byte(line), "<console-input>", hcl.Pos{Line: 1, Column: 1}) 46 diags = diags.Append(parseDiags) 47 if parseDiags.HasErrors() { 48 return "", diags 49 } 50 51 val, valDiags := s.Scope.EvalExpr(expr, cty.DynamicPseudoType) 52 diags = diags.Append(valDiags) 53 if valDiags.HasErrors() { 54 return "", diags 55 } 56 57 return FormatValue(val, 0), diags 58 } 59 60 func (s *Session) handleHelp() (string, tfdiags.Diagnostics) { 61 text := ` 62 The Terraform console allows you to experiment with Terraform interpolations. 63 You may access resources in the state (if you have one) just as you would 64 from a configuration. For example: "aws_instance.foo.id" would evaluate 65 to the ID of "aws_instance.foo" if it exists in your state. 66 67 Type in the interpolation to test and hit <enter> to see the result. 68 69 To exit the console, type "exit" and hit <enter>, or use Control-C or 70 Control-D. 71 ` 72 73 return strings.TrimSpace(text), nil 74 }