delete tfinstall packages
diff --git a/cmd/tfinstall/main.go b/cmd/tfinstall/main.go deleted file mode 100644 index 04ccc4e..0000000 --- a/cmd/tfinstall/main.go +++ /dev/null
@@ -1,132 +0,0 @@ -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 -}
diff --git a/tfinstall/doc.go b/tfinstall/doc.go deleted file mode 100644 index e48ea41..0000000 --- a/tfinstall/doc.go +++ /dev/null
@@ -1,4 +0,0 @@ -// Package tfinstall offers multiple strategies for finding and/or installing -// a binary version of Terraform. Some of the strategies can also authenticate -// the source of the binary as an official HashiCorp release. -package tfinstall
diff --git a/tfinstall/download.go b/tfinstall/download.go deleted file mode 100644 index 69c51f0..0000000 --- a/tfinstall/download.go +++ /dev/null
@@ -1,125 +0,0 @@ -package tfinstall - -import ( - "context" - "fmt" - "io/ioutil" - "os" - "path/filepath" - "runtime" - "strings" - - "github.com/hashicorp/go-getter" - "golang.org/x/crypto/openpgp" -) - -func ensureInstallDir(installDir string) (string, error) { - if installDir == "" { - return ioutil.TempDir("", "tfexec") - } - - if _, err := os.Stat(installDir); err != nil { - return "", fmt.Errorf("could not access directory %s for installing Terraform: %w", installDir, err) - } - - return installDir, nil -} - -func downloadWithVerification(ctx context.Context, tfVersion string, installDir string, appendUserAgent string) (string, error) { - osName := runtime.GOOS - archName := runtime.GOARCH - - // setup: ensure we have a place to put our downloaded terraform binary - tfDir, err := ensureInstallDir(installDir) - if err != nil { - return "", err - } - - httpGetter := &getter.HttpGetter{ - Netrc: true, - Client: newHTTPClient(appendUserAgent), - } - client := getter.Client{ - Ctx: ctx, - Getters: map[string]getter.Getter{ - "https": httpGetter, - }, - } - client.Mode = getter.ClientModeAny - - // firstly, download and verify the signature of the checksum file - - sumsTmpDir, err := ioutil.TempDir("", "tfinstall") - if err != nil { - return "", err - } - defer os.RemoveAll(sumsTmpDir) - - sumsFilename := "terraform_" + tfVersion + "_SHA256SUMS" - sumsSigFilename := sumsFilename + ".72D7468F.sig" - - sumsURL := fmt.Sprintf("%s/%s/%s", baseURL, tfVersion, sumsFilename) - sumsSigURL := fmt.Sprintf("%s/%s/%s", baseURL, tfVersion, sumsSigFilename) - - client.Src = sumsURL - client.Dst = sumsTmpDir - err = client.Get() - if err != nil { - return "", fmt.Errorf("error fetching checksums at URL %s: %w", sumsURL, err) - } - - client.Src = sumsSigURL - err = client.Get() - if err != nil { - return "", fmt.Errorf("error fetching checksums signature: %s", err) - } - - sumsPath := filepath.Join(sumsTmpDir, sumsFilename) - sumsSigPath := filepath.Join(sumsTmpDir, sumsSigFilename) - - err = verifySumsSignature(sumsPath, sumsSigPath) - if err != nil { - return "", err - } - - // secondly, download Terraform itself, verifying the checksum - url := tfURL(tfVersion, osName, archName) - client.Src = url - client.Dst = tfDir - client.Mode = getter.ClientModeDir - err = client.Get() - if err != nil { - return "", err - } - - return filepath.Join(tfDir, "terraform"), nil -} - -// verifySumsSignature downloads SHA256SUMS and SHA256SUMS.sig and verifies -// the signature using the HashiCorp public key. -func verifySumsSignature(sumsPath, sumsSigPath string) error { - el, err := openpgp.ReadArmoredKeyRing(strings.NewReader(hashicorpPublicKey)) - if err != nil { - return err - } - data, err := os.Open(sumsPath) - if err != nil { - return err - } - sig, err := os.Open(sumsSigPath) - if err != nil { - return err - } - _, err = openpgp.CheckDetachedSignature(el, data, sig) - - return err -} - -func tfURL(tfVersion, osName, archName string) string { - sumsFilename := "terraform_" + tfVersion + "_SHA256SUMS" - sumsURL := fmt.Sprintf("%s/%s/%s", baseURL, tfVersion, sumsFilename) - return fmt.Sprintf( - "%s/%s/terraform_%s_%s_%s.zip?checksum=file:%s", - baseURL, tfVersion, tfVersion, osName, archName, sumsURL, - ) -}
diff --git a/tfinstall/exact_path.go b/tfinstall/exact_path.go deleted file mode 100644 index 010cc50..0000000 --- a/tfinstall/exact_path.go +++ /dev/null
@@ -1,27 +0,0 @@ -package tfinstall - -import ( - "context" - "os" -) - -type ExactPathOption struct { - execPath string -} - -var _ ExecPathFinder = &ExactPathOption{} - -func ExactPath(execPath string) *ExactPathOption { - opt := &ExactPathOption{ - execPath: execPath, - } - return opt -} - -func (opt *ExactPathOption) ExecPath(context.Context) (string, error) { - if _, err := os.Stat(opt.execPath); err != nil { - // fall through to the next strategy if the local path does not exist - return "", nil - } - return opt.execPath, nil -}
diff --git a/tfinstall/exact_path_test.go b/tfinstall/exact_path_test.go deleted file mode 100644 index 2c037cd..0000000 --- a/tfinstall/exact_path_test.go +++ /dev/null
@@ -1,29 +0,0 @@ -package tfinstall - -import ( - "context" - "fmt" - "os/exec" - "strings" - "testing" -) - -// test that Find returns an appropriate error when given an exact path -// which exists, but is not a terraform executable -func TestExactPath(t *testing.T) { - // we just want the path to a local executable that definitely exists - execPath, err := exec.LookPath("go") - if err != nil { - t.Fatal(err) - } - - _, err = Find(context.Background(), ExactPath(execPath)) - if err == nil { - t.Fatalf("expected Find() to fail when given ExactPath(%s), but it did not", execPath) - } - - expected := fmt.Sprintf("executable found at path %s is not terraform", execPath) - if !strings.HasPrefix(err.Error(), expected) { - t.Fatalf("expected Find() to return %s, but got %s", expected, err) - } -}
diff --git a/tfinstall/exact_version.go b/tfinstall/exact_version.go deleted file mode 100644 index afcb9ac..0000000 --- a/tfinstall/exact_version.go +++ /dev/null
@@ -1,35 +0,0 @@ -package tfinstall - -import ( - "context" - - "github.com/hashicorp/go-version" -) - -type ExactVersionOption struct { - tfVersion string - installDir string - - UserAgent string -} - -var _ ExecPathFinder = &ExactVersionOption{} - -func ExactVersion(tfVersion string, installDir string) *ExactVersionOption { - opt := &ExactVersionOption{ - tfVersion: tfVersion, - installDir: installDir, - } - - return opt -} - -func (opt *ExactVersionOption) ExecPath(ctx context.Context) (string, error) { - // validate version - _, err := version.NewVersion(opt.tfVersion) - if err != nil { - return "", err - } - - return downloadWithVerification(ctx, opt.tfVersion, opt.installDir, opt.UserAgent) -}
diff --git a/tfinstall/exact_version_test.go b/tfinstall/exact_version_test.go deleted file mode 100644 index d5c7db3..0000000 --- a/tfinstall/exact_version_test.go +++ /dev/null
@@ -1,66 +0,0 @@ -package tfinstall - -import ( - "context" - "io/ioutil" - "os" - "os/exec" - "strings" - "testing" -) - -// downloads terraform 0.12.26 from the live releases site -func TestFindExactVersion(t *testing.T) { - tmpDir, err := ioutil.TempDir("", "tfinstall-test") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(tmpDir) - - tfpath, err := Find(context.Background(), ExactVersion("0.12.26", tmpDir)) - if err != nil { - t.Fatal(err) - } - - // run "terraform version" to check we've downloaded a terraform 0.12.26 binary - cmd := exec.Command(tfpath, "version") - - out, err := cmd.Output() - if err != nil { - t.Fatal(err) - } - - expected := "Terraform v0.12.26" - actual := string(out) - if !strings.HasPrefix(actual, expected) { - t.Fatalf("ran terraform version, expected %s, but got %s", expected, actual) - } -} - -// downloads terraform 0.13.0-beta1 from the live releases site -func TestFindExactVersionPrerelease(t *testing.T) { - tmpDir, err := ioutil.TempDir("", "tfinstall-test") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(tmpDir) - - tfpath, err := Find(context.Background(), ExactVersion("0.13.0-beta1", tmpDir)) - if err != nil { - t.Fatal(err) - } - - // run "terraform version" to check we've downloaded a terraform 0.12.26 binary - cmd := exec.Command(tfpath, "version") - - out, err := cmd.Output() - if err != nil { - t.Fatal(err) - } - - expected := "Terraform v0.13.0-beta1" - actual := string(out) - if !strings.HasPrefix(actual, expected) { - t.Fatalf("ran terraform version, expected %s, but got %s", expected, actual) - } -}
diff --git a/tfinstall/gitref/git_ref.go b/tfinstall/gitref/git_ref.go deleted file mode 100644 index d738b71..0000000 --- a/tfinstall/gitref/git_ref.go +++ /dev/null
@@ -1,103 +0,0 @@ -package gitref - -import ( - "context" - "fmt" - "io/ioutil" - "log" - "os" - "os/exec" - "path/filepath" - "runtime" - - "github.com/go-git/go-git/v5" - "github.com/go-git/go-git/v5/plumbing" -) - -type Option struct { - installDir string - repoURL string - ref string -} - -func Install(ref, repo, installDir string) *Option { - return &Option{ - installDir: installDir, - repoURL: repo, - ref: ref, - } -} - -func (opt *Option) ExecPath(ctx context.Context) (string, error) { - installDir, err := ensureInstallDir(opt.installDir) - if err != nil { - return "", err - } - - ref := plumbing.ReferenceName(opt.ref) - if opt.ref == "" { - ref = plumbing.ReferenceName("refs/heads/main") - } - - repoURL := opt.repoURL - if repoURL == "" { - repoURL = "https://github.com/hashicorp/terraform.git" - } - - _, err = git.PlainClone(installDir, false, &git.CloneOptions{ - URL: repoURL, - ReferenceName: ref, - - Depth: 1, - Tags: git.NoTags, - }) - if err != nil { - return "", fmt.Errorf("unable to clone %q: %w", repoURL, err) - } - - var binName string - { - // TODO: maybe there is a better way to make sure this filename is available? - // I guess we could locate it in a different dir, or nest the git underneath - // the root tmp dir, etc. - binPattern := "terraform" - if runtime.GOOS == "windows" { - binPattern = "terraform*.exe" - } - binFile, err := ioutil.TempFile(installDir, binPattern) - if err != nil { - return "", fmt.Errorf("unable to create bin file: %w", err) - } - binName = binFile.Name() - binFile.Close() - } - - goArgs := []string{"build", "-o", binName} - - vendorDir := filepath.Join(installDir, "vendor") - if fi, err := os.Stat(vendorDir); err == nil && fi.IsDir() { - goArgs = append(goArgs, "-mod", "vendor") - } - - cmd := exec.CommandContext(ctx, "go", goArgs...) - cmd.Dir = installDir - out, err := cmd.CombinedOutput() - log.Print(string(out)) - if err != nil { - return "", fmt.Errorf("unable to build Terraform: %w\n%s", err, out) - } - - return binName, nil -} - -func ensureInstallDir(installDir string) (string, error) { - if installDir == "" { - return ioutil.TempDir("", "tfexec") - } - - if _, err := os.Stat(installDir); err != nil { - return "", fmt.Errorf("could not access directory %s for installing Terraform: %w", installDir, err) - } - - return installDir, nil -}
diff --git a/tfinstall/gitref/git_ref_test.go b/tfinstall/gitref/git_ref_test.go deleted file mode 100644 index b116da5..0000000 --- a/tfinstall/gitref/git_ref_test.go +++ /dev/null
@@ -1,75 +0,0 @@ -package gitref_test - -import ( - "context" - "io/ioutil" - "os" - "os/exec" - "strings" - "testing" - - "github.com/hashicorp/terraform-exec/tfinstall" - "github.com/hashicorp/terraform-exec/tfinstall/gitref" -) - -// ensure the option satisfies the interface -var _ tfinstall.ExecPathFinder = &gitref.Option{} - -func TestGitRef(t *testing.T) { - if testing.Short() { - t.Skip("skipping git ref tests for short run") - } - - cmd := exec.Command("go", "version") - out, err := cmd.CombinedOutput() - if err != nil { - t.Fatalf("error with Go installation: %s\n%s", err, string(out)) - } - t.Logf("go version\n%s", string(out)) - - for n, c := range map[string]struct { - expectedVersion string - ref string - }{ - "branch v0.12": {"Terraform v0.12.", "refs/heads/v0.12"}, - "tag v0.12.29": {"Terraform v0.12.29", "refs/tags/v0.12.29"}, - // "commit 83630a7": {"Terraform v0.12.29", "83630a7003fb8b868a3bf940798326634c3c6acc"}, - "empty": {"Terraform v1.", ""}, // should pull main, which is currently v1 dev - } { - c := c - t.Run(n, func(t *testing.T) { - // these are really long running due to the compilation, run them in parallel - t.Parallel() - - ctx := context.Background() - - // hacking this tmpdir to local dir due to circle perms, should be env var - tmpDir, err := ioutil.TempDir("", "tfinstall-test") - if err != nil { - t.Fatal(err) - } - t.Cleanup(func() { - os.RemoveAll(tmpDir) - }) - - t.Logf("finding / building ref %q...", c.ref) - tfpath, err := tfinstall.Find(ctx, gitref.Install(c.ref, "", tmpDir)) - if err != nil { - t.Fatalf("%T %s", err, err) - } - - t.Logf("testing version cmd...") - cmd := exec.Command(tfpath, "version") - - out, err := cmd.Output() - if err != nil { - t.Fatalf("%s\n\n%s", err, out) - } - - actual := string(out) - if !strings.Contains(actual, c.expectedVersion) { - t.Fatalf("ran terraform version, expected %s, but got %s", c.expectedVersion, actual) - } - }) - } -}
diff --git a/tfinstall/http.go b/tfinstall/http.go deleted file mode 100644 index 70d95a6..0000000 --- a/tfinstall/http.go +++ /dev/null
@@ -1,37 +0,0 @@ -package tfinstall - -import ( - "fmt" - "net/http" - "os" - "strings" - - cleanhttp "github.com/hashicorp/go-cleanhttp" - - intversion "github.com/hashicorp/terraform-exec/internal/version" -) - -type userAgentRoundTripper struct { - inner http.RoundTripper - userAgent string -} - -func (rt *userAgentRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { - if _, ok := req.Header["User-Agent"]; !ok { - req.Header.Set("User-Agent", rt.userAgent) - } - return rt.inner.RoundTrip(req) -} - -func newHTTPClient(appendUA string) *http.Client { - appendUA = strings.TrimSpace(appendUA + " " + os.Getenv("TF_APPEND_USER_AGENT")) - userAgent := strings.TrimSpace(fmt.Sprintf("HashiCorp-tfinstall/%s %s", intversion.ModuleVersion(), appendUA)) - - cli := cleanhttp.DefaultPooledClient() - cli.Transport = &userAgentRoundTripper{ - userAgent: userAgent, - inner: cli.Transport, - } - - return cli -}
diff --git a/tfinstall/latest_version.go b/tfinstall/latest_version.go deleted file mode 100644 index f01735c..0000000 --- a/tfinstall/latest_version.go +++ /dev/null
@@ -1,51 +0,0 @@ -package tfinstall - -import ( - "context" - "fmt" - - "github.com/hashicorp/go-checkpoint" -) - -type LatestVersionOption struct { - forceCheckpoint bool - installDir string - - UserAgent string -} - -var _ ExecPathFinder = &LatestVersionOption{} - -func LatestVersion(installDir string, forceCheckpoint bool) *LatestVersionOption { - opt := &LatestVersionOption{ - forceCheckpoint: forceCheckpoint, - installDir: installDir, - } - - return opt -} - -func (opt *LatestVersionOption) ExecPath(ctx context.Context) (string, error) { - v, err := latestVersion(opt.forceCheckpoint) - if err != nil { - return "", err - } - - return downloadWithVerification(ctx, v, opt.installDir, opt.UserAgent) -} - -func latestVersion(forceCheckpoint bool) (string, error) { - resp, err := checkpoint.Check(&checkpoint.CheckParams{ - Product: "terraform", - Force: forceCheckpoint, - }) - if err != nil { - return "", err - } - - if resp.CurrentVersion == "" { - return "", fmt.Errorf("could not determine latest version of terraform using checkpoint: CHECKPOINT_DISABLE may be set") - } - - return resp.CurrentVersion, nil -}
diff --git a/tfinstall/latest_version_test.go b/tfinstall/latest_version_test.go deleted file mode 100644 index 1467090..0000000 --- a/tfinstall/latest_version_test.go +++ /dev/null
@@ -1,59 +0,0 @@ -package tfinstall - -import ( - "context" - "encoding/json" - "io/ioutil" - "os" - "os/exec" - "testing" - - "github.com/hashicorp/go-version" -) - -// latest version calculation itself is handled by checkpoint, so the test can be straightforward - -// just test that we've managed to download a version of terraform later than 0.12.27 -func TestLatestVersion(t *testing.T) { - lowerBound := "0.12.27" - - tmpDir, err := ioutil.TempDir("", "tfinstall-test") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(tmpDir) - - tfpath, err := Find(context.Background(), LatestVersion(tmpDir, false)) - if err != nil { - t.Fatal(err) - } - - cmd := exec.Command(tfpath, "version", "-json") - - out, err := cmd.Output() - if err != nil { - t.Fatal(err) - } - - lowerBoundVersion, err := version.NewVersion("0.15.0") - if err != nil { - t.Fatal(err) - } - - type versionOutput struct { - TerraformVersion string `json:"terraform_version"` - } - vOut := versionOutput{} - err = json.Unmarshal(out, &vOut) - if err != nil { - t.Fatal(err) - } - - actualVersion, err := version.NewVersion(vOut.TerraformVersion) - if err != nil { - t.Fatal(err) - } - - if actualVersion.LessThan(lowerBoundVersion) { - t.Fatalf("ran terraform version, expected version to be greater than %s, but got %s", lowerBound, out) - } -}
diff --git a/tfinstall/look_path.go b/tfinstall/look_path.go deleted file mode 100644 index 2ebec09..0000000 --- a/tfinstall/look_path.go +++ /dev/null
@@ -1,30 +0,0 @@ -package tfinstall - -import ( - "context" - "log" - "os/exec" -) - -type LookPathOption struct { -} - -var _ ExecPathFinder = &LookPathOption{} - -func LookPath() *LookPathOption { - opt := &LookPathOption{} - - return opt -} - -func (opt *LookPathOption) ExecPath(context.Context) (string, error) { - p, err := exec.LookPath("terraform") - if err != nil { - if notFoundErr, ok := err.(*exec.Error); ok && notFoundErr.Err == exec.ErrNotFound { - log.Printf("[WARN] could not locate a terraform executable on system path; continuing") - return "", nil - } - return "", err - } - return p, nil -}
diff --git a/tfinstall/pubkey.go b/tfinstall/pubkey.go deleted file mode 100644 index c545595..0000000 --- a/tfinstall/pubkey.go +++ /dev/null
@@ -1,124 +0,0 @@ -package tfinstall - -const hashicorpPublicKey = `-----BEGIN PGP PUBLIC KEY BLOCK----- - -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 -ZF5q4h4I33PSGDdSvGXn9UMY5Isjpg== -=7pIB ------END PGP PUBLIC KEY BLOCK-----`
diff --git a/tfinstall/tfinstall.go b/tfinstall/tfinstall.go deleted file mode 100644 index 3dd6963..0000000 --- a/tfinstall/tfinstall.go +++ /dev/null
@@ -1,62 +0,0 @@ -package tfinstall - -import ( - "context" - "fmt" - "os/exec" - "strings" -) - -const baseURL = "https://releases.hashicorp.com/terraform" - -type ExecPathFinder interface { - ExecPath(context.Context) (string, error) -} - -func Find(ctx context.Context, opts ...ExecPathFinder) (string, error) { - var terraformPath string - - // go through the options in order - // until a valid terraform executable is found - for _, opt := range opts { - p, err := opt.ExecPath(ctx) - if err != nil { - return "", fmt.Errorf("unexpected error: %s", err) - } - - if p == "" { - // strategy did not locate an executable - fall through to next - continue - } else { - terraformPath = p - break - } - } - - if terraformPath == "" { - return "", fmt.Errorf("could not find terraform executable") - } - - err := runTerraformVersion(terraformPath) - if err != nil { - return "", fmt.Errorf("executable found at path %s is not terraform: %s", terraformPath, err) - } - - return terraformPath, nil -} - -func runTerraformVersion(execPath string) error { - cmd := exec.Command(execPath, "version") - - out, err := cmd.Output() - if err != nil { - return err - } - - // very basic sanity check - if !strings.Contains(string(out), "Terraform v") { - return fmt.Errorf("located executable at %s, but output of `terraform version` was:\n%s", execPath, out) - } - - return nil -}
diff --git a/tfinstall/tfinstall_test.go b/tfinstall/tfinstall_test.go deleted file mode 100644 index 3b34225..0000000 --- a/tfinstall/tfinstall_test.go +++ /dev/null
@@ -1,39 +0,0 @@ -package tfinstall - -import ( - "context" - "io/ioutil" - "os" - "os/exec" - "strings" - "testing" -) - -// test that Find falls back to the next working strategy when the file at -// ExactPath does not exist -func TestFindFallback(t *testing.T) { - tmpDir, err := ioutil.TempDir("", "tfinstall-test") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(tmpDir) - - tfpath, err := Find(context.Background(), ExactPath("/hopefully/completely/nonexistent/path"), ExactVersion("0.12.26", tmpDir)) - if err != nil { - t.Fatal(err) - } - - // run "terraform version" to check we've downloaded a terraform 0.12.26 binary - cmd := exec.Command(tfpath, "version") - - out, err := cmd.Output() - if err != nil { - t.Fatal(err) - } - - expected := "Terraform v0.12.26" - actual := string(out) - if !strings.HasPrefix(actual, expected) { - t.Fatalf("ran terraform version, expected %s, but got %s", expected, actual) - } -}