blob: 04ccc4e454e3abb8eb0b4dcad9ec684adb2f5caa [file] [log] [blame]
package main
import (
"context"
"flag"
"io/ioutil"
"log"
"os"
"strings"
"github.com/hashicorp/logutils"
"github.com/mitchellh/cli"
"github.com/hashicorp/terraform-exec/tfinstall"
"github.com/hashicorp/terraform-exec/tfinstall/gitref"
)
// TODO: add versioning to this?
const userAgentAppend = "tfinstall-cli"
func main() {
filter := &logutils.LevelFilter{
Levels: []logutils.LogLevel{"DEBUG", "WARN", "ERROR"},
MinLevel: logutils.LogLevel("WARN"),
Writer: os.Stderr,
}
log.SetOutput(filter)
ui := &cli.ColoredUi{
ErrorColor: cli.UiColorRed,
WarnColor: cli.UiColorYellow,
Ui: &cli.BasicUi{
Reader: os.Stdin,
Writer: os.Stdout,
ErrorWriter: os.Stderr,
},
}
exitStatus := run(ui, os.Args[1:])
os.Exit(exitStatus)
}
func help() string {
return `Usage: tfinstall [--dir=DIR] VERSION-OR-REF
Downloads, verifies, and installs a official releases of the Terraform binary
from releases.hashicorp.com or downloads, compiles, and installs a version of
the Terraform binary from the GitHub repository.
To download an official release, pass "latest" or a valid semantic versioning
version string.
To download and compile a version of the Terraform binary from the GitHub
repository pass a ref in the form "refs/...", some examples are shown below.
If a binary is successfully installed, its path will be printed to stdout.
Unless --dir is given, the default system temporary directory will be used.
Options:
--dir Directory into which to install the terraform binary. The
directory must exist.
Examples:
tfinstall 0.12.28
tfinstall latest
tfinstall 0.13.0-beta3
tfinstall --dir=/home/kmoe/bin 0.12.28
tfinstall refs/heads/main
tfinstall refs/tags/v0.12.29
tfinstall refs/pull/25633/head
`
}
func run(ui cli.Ui, args []string) int {
ctx := context.Background()
args = os.Args[1:]
flags := flag.NewFlagSet("", flag.ExitOnError)
var tfDir string
flags.StringVar(&tfDir, "dir", "", "Local directory into which to install terraform")
err := flags.Parse(args)
if err != nil {
ui.Error(err.Error())
return 1
}
if flags.NArg() != 1 {
ui.Error("Please specify VERSION-OR-REF")
ui.Output(help())
return 127
}
tfVersion := flags.Args()[0]
if tfDir == "" {
tfDir, err = ioutil.TempDir("", "tfinstall")
if err != nil {
ui.Error(err.Error())
return 1
}
}
var findArgs []tfinstall.ExecPathFinder
switch {
case tfVersion == "latest":
finder := tfinstall.LatestVersion(tfDir, false)
finder.UserAgent = userAgentAppend
findArgs = append(findArgs, finder)
case strings.HasPrefix(tfVersion, "refs/"):
findArgs = append(findArgs, gitref.Install(tfVersion, "", tfDir))
default:
if strings.HasPrefix(tfVersion, "v") {
tfVersion = tfVersion[1:]
}
finder := tfinstall.ExactVersion(tfVersion, tfDir)
finder.UserAgent = userAgentAppend
findArgs = append(findArgs, finder)
}
tfPath, err := tfinstall.Find(ctx, findArgs...)
if err != nil {
ui.Error(err.Error())
return 1
}
ui.Output(tfPath)
return 0
}