oh-my-posh/src/segments/terraform.go
2024-11-04 12:15:40 +01:00

117 lines
2.3 KiB
Go

package segments
import (
"encoding/json"
"errors"
"path/filepath"
"github.com/jandedobbeleer/oh-my-posh/src/properties"
"github.com/hashicorp/hcl/v2/gohcl"
"github.com/hashicorp/hcl/v2/hclparse"
)
type Terraform struct {
base
TerraformBlock
WorkspaceName string
}
func (tf *Terraform) Template() string {
return " {{ .WorkspaceName }}{{ if .Version }} {{ .Version }}{{ end }} "
}
type TerraFormConfig struct {
Terraform *TerraformBlock `hcl:"terraform,block"`
}
type TerraformBlock struct {
Version *string `hcl:"required_version" json:"terraform_version"`
}
func (tf *Terraform) Enabled() bool {
cmd := "terraform"
fetchVersion := tf.props.GetBool(properties.FetchVersion, false)
if !tf.env.HasCommand(cmd) || !tf.inContext(fetchVersion) {
return false
}
tf.WorkspaceName, _ = tf.env.RunCommand(cmd, "workspace", "show")
if !fetchVersion {
return true
}
if err := tf.setVersionFromTfFiles(); err == nil {
return true
}
tf.setVersionFromTfStateFile()
return true
}
func (tf *Terraform) inContext(fetchVersion bool) bool {
terraformFolder := filepath.Join(tf.env.Pwd(), ".terraform")
if tf.env.HasFolder(terraformFolder) {
return true
}
files := []string{".tf", ".tfplan", ".tfstate"}
for _, file := range files {
if tf.env.HasFiles(file) {
return true
}
}
if !fetchVersion {
return false
}
versionFiles := []string{"versions.tf", "main.tf", "terraform.tfstate"}
for _, file := range versionFiles {
if tf.env.HasFiles(file) {
return true
}
}
return false
}
func (tf *Terraform) setVersionFromTfFiles() error {
files := []string{"versions.tf", "main.tf"}
for _, file := range files {
if !tf.env.HasFiles(file) {
continue
}
parser := hclparse.NewParser()
content := tf.env.FileContent(file)
hclFile, diags := parser.ParseHCL([]byte(content), file)
if diags != nil {
continue
}
var config TerraFormConfig
diags = gohcl.DecodeBody(hclFile.Body, nil, &config)
if diags != nil {
continue
}
tf.TerraformBlock = *config.Terraform
return nil
}
return errors.New("no valid terraform files found")
}
func (tf *Terraform) setVersionFromTfStateFile() {
file := "terraform.tfstate"
if !tf.env.HasFiles(file) {
return
}
content := tf.env.FileContent(file)
_ = json.Unmarshal([]byte(content), &tf.TerraformBlock)
}