Add support for ~/.opentf.d (#22)

* Use ~/.opentf.d instead of ~/.terraform.d

Stay backwards-compatible, though.

Signed-off-by: Jakub Martin <kubam@spacelift.io>

* Fix imports.

Signed-off-by: Jakub Martin <kubam@spacelift.io>

* Add tests.

Signed-off-by: Jakub Martin <kubam@spacelift.io>

* Use util function.

Signed-off-by: Jakub Martin <kubam@spacelift.io>

* Fix windows directories.

Signed-off-by: Jakub Martin <kubam@spacelift.io>

* Add a comment to the tests.

Signed-off-by: Jakub Martin <kubam@spacelift.io>

---------

Signed-off-by: Jakub Martin <kubam@spacelift.io>
This commit is contained in:
Kuba Martin 2023-08-21 12:38:11 +02:00 committed by GitHub
parent b9677e99c6
commit e650bab8d7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 93 additions and 11 deletions

View File

@ -7,10 +7,12 @@ import (
"os"
"path/filepath"
"reflect"
"runtime"
"testing"
"github.com/davecgh/go-spew/spew"
"github.com/google/go-cmp/cmp"
"github.com/placeholderplaceholderplaceholder/opentf/internal/tfdiags"
)
@ -549,3 +551,65 @@ func TestConfig_Merge_disableCheckpointSignature(t *testing.T) {
t.Fatalf("bad: %#v", actual)
}
}
func TestConfigDir_BackwardsCompatibility(t *testing.T) {
dir, err := os.MkdirTemp("", "opentf_test")
if err != nil {
t.Fatalf("failed to create temp dir: %s", err)
}
defer os.RemoveAll(dir)
terraformdName := ".terraform.d"
opentfdName := ".opentf.d"
if runtime.GOOS == "windows" {
terraformdName = "terraform.d"
opentfdName = "opentf.d"
}
if err := os.Setenv("OPENTF_TEST_HOME", dir); err != nil {
t.Fatalf("failed to set env var: %s", err)
}
// The three tests below are grouped for logical ease of understanding, but they are not independent.
// They have to run in this exact order.
t.Run("when no dir exists, use .opentf.d", func(t *testing.T) {
loadedConfigDir, err := configDir()
if err != nil {
t.Fatalf("failed to get config dir: %s", err)
}
if loadedConfigDir != filepath.Join(dir, opentfdName) {
t.Fatalf("bad: %s", loadedConfigDir)
}
})
t.Run("when only .terraform.d exists, use .terraform.d for backwards-compatibility reasons", func(t *testing.T) {
if err := os.MkdirAll(filepath.Join(dir, terraformdName), 0755); err != nil {
t.Fatalf("failed to create temp dir: %s", err)
}
loadedConfigDir, err := configDir()
if err != nil {
t.Fatalf("failed to get config dir: %s", err)
}
if loadedConfigDir != filepath.Join(dir, terraformdName) {
t.Fatalf("bad: %s", loadedConfigDir)
}
})
t.Run("when both .terraform.d and .opentf.d exist, use .opentf.d", func(t *testing.T) {
if err := os.MkdirAll(filepath.Join(dir, opentfdName), 0755); err != nil {
t.Fatalf("failed to create temp dir: %s", err)
}
loadedConfigDir, err := configDir()
if err != nil {
t.Fatalf("failed to get config dir: %s", err)
}
if loadedConfigDir != filepath.Join(dir, opentfdName) {
t.Fatalf("bad: %s", loadedConfigDir)
}
})
}

View File

@ -31,10 +31,18 @@ func configDir() (string, error) {
return "", err
}
return filepath.Join(dir, ".terraform.d"), nil
newConfigDir := filepath.Join(dir, ".opentf.d")
legacyConfigDir := filepath.Join(dir, ".terraform.d")
return getNewOrLegacyPath(newConfigDir, legacyConfigDir)
}
func homeDir() (string, error) {
// For unit-testing purposes.
if home := os.Getenv("OPENTF_TEST_HOME"); home != "" {
return home, nil
}
// First prefer the HOME environmental variable
if home := os.Getenv("HOME"); home != "" {
// FIXME: homeDir gets called from globalPluginDirs during init, before

View File

@ -7,6 +7,7 @@
package cliconfig
import (
"os"
"path/filepath"
"syscall"
"unsafe"
@ -37,10 +38,18 @@ func configDir() (string, error) {
return "", err
}
return filepath.Join(dir, "terraform.d"), nil
newConfigDir := filepath.Join(dir, "opentf.d")
legacyConfigDir := filepath.Join(dir, "terraform.d")
return getNewOrLegacyPath(newConfigDir, legacyConfigDir)
}
func homeDir() (string, error) {
// For unit-testing purposes.
if home := os.Getenv("OPENTF_TEST_HOME"); home != "" {
return home, nil
}
b := make([]uint16, syscall.MAX_PATH)
// See: http://msdn.microsoft.com/en-us/library/windows/desktop/bb762181(v=vs.85).aspx

View File

@ -20,7 +20,7 @@ import (
// older versions where both satisfy the provider version constraints.
func globalPluginDirs() []string {
var ret []string
// Look in ~/.terraform.d/plugins/ , or its equivalent on non-UNIX
// Look in ~/.opentf.d/plugins/ , or its equivalent on non-UNIX
dir, err := cliconfig.ConfigDir()
if err != nil {
log.Printf("[ERROR] Error finding global config directory: %s", err)

View File

@ -96,7 +96,7 @@ func implicitProviderSource(services *disco.Disco) getproviders.Source {
// way to include them in bundles uploaded to Terraform Cloud, where
// there has historically otherwise been no way to use custom providers.
// - The "plugins" subdirectory of the CLI config search directory.
// (thats ~/.terraform.d/plugins on Unix systems, equivalents elsewhere)
// (thats ~/.opentf.d/plugins on Unix systems, equivalents elsewhere)
// - The "plugins" subdirectory of any platform-specific search paths,
// following e.g. the XDG base directory specification on Unix systems,
// Apple's guidelines on OS X, and "known folders" on Windows.

View File

@ -46,7 +46,7 @@ general syntax; see the following section for information on the meaning
of each of these settings:
```hcl
plugin_cache_dir = "$HOME/.terraform.d/plugin-cache"
plugin_cache_dir = "$HOME/.opentf.d/plugin-cache"
disable_checkpoint = true
```
@ -301,11 +301,12 @@ method.
The set of directories Terraform can select as filesystem mirrors depends on
the operating system where you are running Terraform:
* **Windows:** `%APPDATA%/terraform.d/plugins` and `%APPDATA%/HashiCorp/Terraform/plugins`
* **Mac OS X:** `$HOME/.terraform.d/plugins`,
* **Windows:** `%APPDATA%/opentf.d/plugins`, `%APPDATA%/terraform.d/plugins` and `%APPDATA%/HashiCorp/Terraform/plugins`
* **Mac OS X:** `$HOME/.opentf.d/plugins`,
`$HOME/.terraform.d/plugins`, and
`~/Library/Application Support/io.terraform/plugins`, and
`/Library/Application Support/io.terraform/plugins`
* **Linux and other Unix-like systems**:`$HOME/.terraform.d/plugins` and
* **Linux and other Unix-like systems**:`$HOME/.opentf.d/plugins`, `$HOME/.terraform.d/plugins` and
`terraform/plugins` located within a valid
[XDG Base Directory](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html)
data directory such as `$XDG_DATA_HOME/terraform/plugins`.
@ -347,7 +348,7 @@ To enable the plugin cache, use the `plugin_cache_dir` setting in
the CLI configuration file. For example:
```hcl
plugin_cache_dir = "$HOME/.terraform.d/plugin-cache"
plugin_cache_dir = "$HOME/.opentf.d/plugin-cache"
```
This directory must already exist before Terraform will cache plugins;
@ -363,7 +364,7 @@ variable can be used to enable caching or to override an existing cache
directory within a particular shell session:
```bash
export TF_PLUGIN_CACHE_DIR="$HOME/.terraform.d/plugin-cache"
export TF_PLUGIN_CACHE_DIR="$HOME/.opentf.d/plugin-cache"
```
When a plugin cache directory is enabled, the `terraform init` command will

View File

@ -202,7 +202,7 @@ provisioners must connect to the remote system using SSH or WinRM.
You must include [a `connection` block](/terraform/language/resources/provisioners/connection) so that Terraform knows how to communicate with the server.
Terraform includes several built-in provisioners. You can also use third-party provisioners as plugins, by placing them
in `%APPDATA%\terraform.d\plugins`, `~/.terraform.d/plugins`, or the same
in `%APPDATA%\opentf.d\plugins`, `~/.opentf.d/plugins`, or the same
directory where the Terraform binary is installed. However, we do not recommend
using any provisioners except the built-in `file`, `local-exec`, and
`remote-exec` provisioners.