github.com/terramate-io/tf@v0.0.0-20230830114523-fce866b4dfcd/command/workdir/plugin_dirs.go (about)

     1  // Copyright (c) HashiCorp, Inc.
     2  // SPDX-License-Identifier: MPL-2.0
     3  
     4  package workdir
     5  
     6  import (
     7  	"encoding/json"
     8  	"io/ioutil"
     9  	"os"
    10  	"path/filepath"
    11  )
    12  
    13  const PluginPathFilename = "plugin_path"
    14  
    15  // ProviderLocalCacheDir returns the directory we'll use as the
    16  // working-directory-specific local cache of providers.
    17  //
    18  // The provider installer's job is to make sure that all providers needed for
    19  // a particular working directory are available in this cache directory. No
    20  // other component may write here, and in particular a Dir object itself
    21  // never reads or writes into this directory, instead just delegating all of
    22  // that responsibility to other components.
    23  //
    24  // Typically, the caller will ultimately pass the result of this method either
    25  // directly or indirectly into providercache.NewDir, to get an object
    26  // responsible for managing the contents.
    27  func (d *Dir) ProviderLocalCacheDir() string {
    28  	return filepath.Join(d.dataDir, "providers")
    29  }
    30  
    31  // ForcedPluginDirs returns a list of directories to use to find plugins,
    32  // instead of the default locations.
    33  //
    34  // Returns an zero-length list and no error in the normal case where there
    35  // are no overridden search directories. If ForcedPluginDirs returns a
    36  // non-empty list with no errors then the result totally replaces the default
    37  // search directories.
    38  func (d *Dir) ForcedPluginDirs() ([]string, error) {
    39  	raw, err := ioutil.ReadFile(filepath.Join(d.dataDir, PluginPathFilename))
    40  	if os.IsNotExist(err) {
    41  		return nil, nil
    42  	}
    43  
    44  	if err != nil {
    45  		return nil, err
    46  	}
    47  
    48  	var pluginPath []string
    49  	if err := json.Unmarshal(raw, &pluginPath); err != nil {
    50  		return nil, err
    51  	}
    52  	return pluginPath, nil
    53  }
    54  
    55  // SetForcedPluginDirs records an overridden list of directories to search
    56  // to find plugins, instead of the default locations. See ForcePluginDirs
    57  // for more information.
    58  //
    59  // Pass a zero-length list to deactivate forced plugin directories altogether,
    60  // thus allowing the working directory to return to using the default
    61  // search directories.
    62  func (d *Dir) SetForcedPluginDirs(dirs []string) error {
    63  
    64  	filePath := filepath.Join(d.dataDir, PluginPathFilename)
    65  	switch {
    66  	case len(dirs) == 0:
    67  		err := os.Remove(filePath)
    68  		if !os.IsNotExist(err) {
    69  			return err
    70  		}
    71  		return nil
    72  	default:
    73  		// We'll ignore errors from this one, because if we fail to create
    74  		// the directory then we'll fail to create the file below too,
    75  		// and that subsequent error will more directly reflect what we
    76  		// are trying to do here.
    77  		d.ensureDataDir()
    78  
    79  		raw, err := json.MarshalIndent(dirs, "", "  ")
    80  		if err != nil {
    81  			return err
    82  		}
    83  
    84  		return ioutil.WriteFile(filePath, raw, 0644)
    85  	}
    86  }