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 }