diff --git a/configs/configload/getter.go b/configs/configload/getter.go deleted file mode 100644 index d0c4567b6..000000000 --- a/configs/configload/getter.go +++ /dev/null @@ -1,168 +0,0 @@ -package configload - -import ( - "fmt" - "log" - "os" - "path/filepath" - - cleanhttp "github.com/hashicorp/go-cleanhttp" - getter "github.com/hashicorp/go-getter" -) - -// We configure our own go-getter detector and getter sets here, because -// the set of sources we support is part of Terraform's documentation and -// so we don't want any new sources introduced in go-getter to sneak in here -// and work even though they aren't documented. This also insulates us from -// any meddling that might be done by other go-getter callers linked into our -// executable. - -var goGetterDetectors = []getter.Detector{ - new(getter.GitHubDetector), - new(getter.GitDetector), - new(getter.BitBucketDetector), - new(getter.GCSDetector), - new(getter.S3Detector), - new(getter.FileDetector), -} - -var goGetterNoDetectors = []getter.Detector{} - -var goGetterDecompressors = map[string]getter.Decompressor{ - "bz2": new(getter.Bzip2Decompressor), - "gz": new(getter.GzipDecompressor), - "xz": new(getter.XzDecompressor), - "zip": new(getter.ZipDecompressor), - - "tar.bz2": new(getter.TarBzip2Decompressor), - "tar.tbz2": new(getter.TarBzip2Decompressor), - - "tar.gz": new(getter.TarGzipDecompressor), - "tgz": new(getter.TarGzipDecompressor), - - "tar.xz": new(getter.TarXzDecompressor), - "txz": new(getter.TarXzDecompressor), -} - -var goGetterGetters = map[string]getter.Getter{ - "file": new(getter.FileGetter), - "gcs": new(getter.GCSGetter), - "git": new(getter.GitGetter), - "hg": new(getter.HgGetter), - "s3": new(getter.S3Getter), - "http": getterHTTPGetter, - "https": getterHTTPGetter, -} - -var getterHTTPClient = cleanhttp.DefaultClient() - -var getterHTTPGetter = &getter.HttpGetter{ - Client: getterHTTPClient, - Netrc: true, -} - -// A reusingGetter is a helper for the module installer that remembers -// the final resolved addresses of all of the sources it has already been -// asked to install, and will copy from a prior installation directory if -// it has the same resolved source address. -// -// The keys in a reusingGetter are resolved and trimmed source addresses -// (with a scheme always present, and without any "subdir" component), -// and the values are the paths where each source was previously installed. -type reusingGetter map[string]string - -// getWithGoGetter retrieves the package referenced in the given address -// into the installation path and then returns the full path to any subdir -// indicated in the address. -// -// The errors returned by this function are those surfaced by the underlying -// go-getter library, which have very inconsistent quality as -// end-user-actionable error messages. At this time we do not have any -// reasonable way to improve these error messages at this layer because -// the underlying errors are not separatelyr recognizable. -func (g reusingGetter) getWithGoGetter(instPath, addr string) (string, error) { - packageAddr, subDir := splitAddrSubdir(addr) - - log.Printf("[DEBUG] will download %q to %s", packageAddr, instPath) - - realAddr, err := getter.Detect(packageAddr, instPath, goGetterDetectors) - if err != nil { - return "", err - } - - var realSubDir string - realAddr, realSubDir = splitAddrSubdir(realAddr) - if realSubDir != "" { - subDir = filepath.Join(realSubDir, subDir) - } - - if realAddr != packageAddr { - log.Printf("[TRACE] go-getter detectors rewrote %q to %q", packageAddr, realAddr) - } - - if prevDir, exists := g[realAddr]; exists { - log.Printf("[TRACE] copying previous install %s to %s", prevDir, instPath) - err := os.Mkdir(instPath, os.ModePerm) - if err != nil { - return "", fmt.Errorf("failed to create directory %s: %s", instPath, err) - } - err = copyDir(instPath, prevDir) - if err != nil { - return "", fmt.Errorf("failed to copy from %s to %s: %s", prevDir, instPath, err) - } - } else { - log.Printf("[TRACE] fetching %q to %q", realAddr, instPath) - client := getter.Client{ - Src: realAddr, - Dst: instPath, - Pwd: instPath, - - Mode: getter.ClientModeDir, - - Detectors: goGetterNoDetectors, // we already did detection above - Decompressors: goGetterDecompressors, - Getters: goGetterGetters, - } - err = client.Get() - if err != nil { - return "", err - } - // Remember where we installed this so we might reuse this directory - // on subsequent calls to avoid re-downloading. - g[realAddr] = instPath - } - - // Our subDir string can contain wildcards until this point, so that - // e.g. a subDir of * can expand to one top-level directory in a .tar.gz - // archive. Now that we've expanded the archive successfully we must - // resolve that into a concrete path. - var finalDir string - if subDir != "" { - finalDir, err = getter.SubdirGlob(instPath, subDir) - log.Printf("[TRACE] expanded %q to %q", subDir, finalDir) - if err != nil { - return "", err - } - } else { - finalDir = instPath - } - - // If we got this far then we have apparently succeeded in downloading - // the requested object! - return filepath.Clean(finalDir), nil -} - -// splitAddrSubdir splits the given address (which is assumed to be a -// registry address or go-getter-style address) into a package portion -// and a sub-directory portion. -// -// The package portion defines what should be downloaded and then the -// sub-directory portion, if present, specifies a sub-directory within -// the downloaded object (an archive, VCS repository, etc) that contains -// the module's configuration files. -// -// The subDir portion will be returned as empty if no subdir separator -// ("//") is present in the address. -func splitAddrSubdir(addr string) (packageAddr, subDir string) { - return getter.SourceDirSubdir(addr) -} diff --git a/configs/configload/loader_test.go b/configs/configload/loader_test.go index 54b6ed2f2..7b3483b4a 100644 --- a/configs/configload/loader_test.go +++ b/configs/configload/loader_test.go @@ -1,92 +1,12 @@ package configload import ( - "fmt" - "io/ioutil" - "os" - "path/filepath" "testing" - "github.com/go-test/deep" "github.com/hashicorp/hcl/v2" "github.com/zclconf/go-cty/cty" ) -// tempChdir copies the contents of the given directory to a temporary -// directory and changes the test process's current working directory to -// point to that directory. Also returned is a function that should be -// called at the end of the test (e.g. via "defer") to restore the previous -// working directory. -// -// Tests using this helper cannot safely be run in parallel with other tests. -func tempChdir(t *testing.T, sourceDir string) (string, func()) { - t.Helper() - - tmpDir, err := ioutil.TempDir("", "terraform-configload") - if err != nil { - t.Fatalf("failed to create temporary directory: %s", err) - return "", nil - } - - if err := copyDir(tmpDir, sourceDir); err != nil { - t.Fatalf("failed to copy fixture to temporary directory: %s", err) - return "", nil - } - - oldDir, err := os.Getwd() - if err != nil { - t.Fatalf("failed to determine current working directory: %s", err) - return "", nil - } - - err = os.Chdir(tmpDir) - if err != nil { - t.Fatalf("failed to switch to temp dir %s: %s", tmpDir, err) - return "", nil - } - - t.Logf("tempChdir switched to %s after copying from %s", tmpDir, sourceDir) - - return tmpDir, func() { - err := os.Chdir(oldDir) - if err != nil { - panic(fmt.Errorf("failed to restore previous working directory %s: %s", oldDir, err)) - } - - if os.Getenv("TF_CONFIGLOAD_TEST_KEEP_TMP") == "" { - os.RemoveAll(tmpDir) - } - } -} - -// tempChdirLoader is a wrapper around tempChdir that also returns a Loader -// whose modules directory is at the conventional location within the -// created temporary directory. -func tempChdirLoader(t *testing.T, sourceDir string) (*Loader, func()) { - t.Helper() - - _, done := tempChdir(t, sourceDir) - modulesDir := filepath.Clean(".terraform/modules") - - err := os.MkdirAll(modulesDir, os.ModePerm) - if err != nil { - done() // undo the chdir in tempChdir so we can safely run other tests - t.Fatalf("failed to create modules directory: %s", err) - return nil, nil - } - - loader, err := NewLoader(&Config{ - ModulesDir: modulesDir, - }) - if err != nil { - done() // undo the chdir in tempChdir so we can safely run other tests - t.Fatalf("failed to create loader: %s", err) - return nil, nil - } - - return loader, done -} - func assertNoDiagnostics(t *testing.T, diags hcl.Diagnostics) bool { t.Helper() return assertDiagnosticCount(t, diags, 0) @@ -103,34 +23,6 @@ func assertDiagnosticCount(t *testing.T, diags hcl.Diagnostics, want int) bool { } return false } - -func assertDiagnosticSummary(t *testing.T, diags hcl.Diagnostics, want string) bool { - t.Helper() - - for _, diag := range diags { - if diag.Summary == want { - return false - } - } - - t.Errorf("missing diagnostic summary %q", want) - for _, diag := range diags { - t.Logf("- %s", diag) - } - return true -} - -func assertResultDeepEqual(t *testing.T, got, want interface{}) bool { - t.Helper() - if diff := deep.Equal(got, want); diff != nil { - for _, problem := range diff { - t.Errorf("%s", problem) - } - return true - } - return false -} - func assertResultCtyEqual(t *testing.T, got, want cty.Value) bool { t.Helper() if !got.RawEquals(want) { diff --git a/configs/configload/module_mgr.go b/configs/configload/module_mgr.go index 16871e310..cf930f537 100644 --- a/configs/configload/module_mgr.go +++ b/configs/configload/module_mgr.go @@ -60,17 +60,3 @@ func (m *moduleMgr) readModuleManifestSnapshot() error { m.manifest, err = modsdir.ReadManifestSnapshot(r) return err } - -// writeModuleManifestSnapshot writes a snapshot of the current manifest -// to the filesystem. -// -// The caller must guarantee no concurrent modifications of the manifest for -// the duration of a call to this function, or the behavior is undefined. -func (m *moduleMgr) writeModuleManifestSnapshot() error { - w, err := m.FS.Create(m.manifestSnapshotPath()) - if err != nil { - return err - } - - return m.manifest.WriteSnapshot(w) -}