terraform-switcher icon indicating copy to clipboard operation
terraform-switcher copied to clipboard

Feature request: option to dry-run

Open yermulnik opened this issue 3 years ago • 1 comments

I'd like to ask to implement a feature which would allow me to run tfswitch in a dry-run mode where it only outputs whether it would switch terraform version in current directory or not with different exist codes for the two operations (e.g. 0 for when no switching is required and 1 for when tfswitch would switch versions). My use case: we're managing different infrastructures from different repositories including legacy setups – most of these are using different versions of terraform and we're not planning to unify them. most of the time I need to switch terraform version when I work on something in several different setups at the same time but it's not always that I need to actually switch terraform version (e.g. when I only need to cd into dir to check something) hence suggested cdtfswitch() bash alias is not something I indeed need but would rather want to inject something like tfswitch --dry-run >/dev/null || echo "tfswitch to use correct terraform version" into my PROMPT_COMMAND env var so that I get notified my terrform version doesn't match terraform version constraint every time I hit enter on the command line. Maybe there's an existing functionality where I can include tfswitch as a Go library in my own small cmdline helper tool? Couldn't find this option =( Thanks in advance.

yermulnik avatar Mar 31 '21 15:03 yermulnik

As an interim solution (sort of FWIW) here's the ugly bit of Go code I came up with:

package main

import (
	"fmt"
	"os"

	"github.com/hashicorp/go-version"
	"github.com/jessevdk/go-flags"
)

var opts struct {
	Verbose []bool `short:"v" long:"verbose" description:"Show verbose debug information"`
}

func usage() {
	fmt.Fprintf(os.Stderr, "Usage: %s [-v] <tf version> <tf version constraint>\n", os.Args[0])
	os.Exit(2)
}

func main() {
	args, err := flags.Parse(&opts)
	if err != nil {
		usage()
	}

	if len(args) != 2 {
		usage()
	}

	v1, err := version.NewVersion(args[0])
	if err != nil {
		fmt.Println("ERROR:", err)
		usage()
	}

	constraints, err := version.NewConstraint(args[1])
	if err != nil {
		fmt.Println("ERROR:", err)
		usage()
	}

	if constraints.Check(v1) {
		if len(opts.Verbose) > 0 {
			fmt.Printf("\"%s\" satisfies constraint \"%s\"\n", v1, constraints)
		}
		os.Exit(0)
	} else {
		if len(opts.Verbose) > 0 {
			fmt.Printf("\"%s\" DOES NOT satisfy constraint \"%s\"\n", v1, constraints)
		}
		os.Exit(1)
	}
}
> terraform version | head -1
Terraform v0.13.6

> fgrep required_version *.tf
  required_version = "~> 1.0.0"

> tf_version_check -v "$(terraform version -json | jq -r .terraform_version)" "$(awk '/^[[:space:]]+required_version[[:space:]]+/ {print gensub("^.+= \"(.+)\"^M?$","\\1","g");}' *.tf 2>/dev/null)"
"0.13.6" DOES NOT satisfy constraint "~> 1.0.0"

> tf_version_check "$(terraform version -json | jq -r .terraform_version)" "$(awk '/^[[:space:]]+required_version[[:space:]]+/ {print gensub("^.+= \"(.+)\"^M?$","\\1","g");}' *.tf 2>/dev/null)" && echo GOOD || echo BAD
BAD

> tfswitch
Reading configuration from home directory for .tfswitch.toml
Reading required version from terraform file
Reading required version from constraint: ~> 1.0.0
Matched version: 1.0.11
Switched terraform to version "1.0.11"

> tf_version_check -v "$(terraform version -json | jq -r .terraform_version)" "$(awk '/^[[:space:]]+required_version[[:space:]]+/ {print gensub("^.+= \"(.+)\"^M?$","\\1","g");}' *.tf 2>/dev/null)"
"1.0.11" satisfies constraint "~> 1.0.0"

> tf_version_check "$(terraform version -json | jq -r .terraform_version)" "$(awk '/^[[:space:]]+required_version[[:space:]]+/ {print gensub("^.+= \"(.+)\"^M?$","\\1","g");}' *.tf 2>/dev/null)" && echo GOOD || echo BAD
GOOD

yermulnik avatar Nov 29 '21 10:11 yermulnik