| // Copyright (c) HashiCorp, Inc. |
| // SPDX-License-Identifier: MPL-2.0 |
| |
| package tfexec |
| |
| import ( |
| "context" |
| "fmt" |
| "os/exec" |
| "strings" |
| ) |
| |
| type graphConfig struct { |
| plan string |
| drawCycles bool |
| graphType string |
| } |
| |
| var defaultGraphOptions = graphConfig{} |
| |
| type GraphOption interface { |
| configureGraph(*graphConfig) |
| } |
| |
| func (opt *GraphPlanOption) configureGraph(conf *graphConfig) { |
| conf.plan = opt.file |
| } |
| |
| func (opt *DrawCyclesOption) configureGraph(conf *graphConfig) { |
| conf.drawCycles = opt.drawCycles |
| } |
| |
| func (opt *GraphTypeOption) configureGraph(conf *graphConfig) { |
| conf.graphType = opt.graphType |
| } |
| |
| func (tf *Terraform) Graph(ctx context.Context, opts ...GraphOption) (string, error) { |
| graphCmd, err := tf.graphCmd(ctx, opts...) |
| if err != nil { |
| return "", err |
| } |
| var outBuf strings.Builder |
| graphCmd.Stdout = &outBuf |
| err = tf.runTerraformCmd(ctx, graphCmd) |
| if err != nil { |
| return "", err |
| } |
| |
| return outBuf.String(), nil |
| |
| } |
| |
| func (tf *Terraform) graphCmd(ctx context.Context, opts ...GraphOption) (*exec.Cmd, error) { |
| c := defaultGraphOptions |
| |
| for _, o := range opts { |
| o.configureGraph(&c) |
| } |
| |
| args := []string{"graph"} |
| |
| if c.plan != "" { |
| // plan was a positional argument prior to Terraform 0.15.0. Ensure proper use by checking version. |
| if err := tf.compatible(ctx, tf0_15_0, nil); err == nil { |
| args = append(args, "-plan="+c.plan) |
| } else { |
| args = append(args, c.plan) |
| } |
| } |
| |
| if c.drawCycles { |
| err := tf.compatible(ctx, tf0_5_0, nil) |
| if err != nil { |
| return nil, fmt.Errorf("-draw-cycles was first introduced in Terraform 0.5.0: %w", err) |
| } |
| args = append(args, "-draw-cycles") |
| } |
| |
| if c.graphType != "" { |
| err := tf.compatible(ctx, tf0_8_0, nil) |
| if err != nil { |
| return nil, fmt.Errorf("-graph-type was first introduced in Terraform 0.8.0: %w", err) |
| } |
| args = append(args, "-type="+c.graphType) |
| } |
| |
| return tf.buildTerraformCmd(ctx, nil, args...), nil |
| } |