Merge pull request #1418 from hashicorp/b-module-storage-path

config/module: storage path should be independent of system
This commit is contained in:
Mitchell Hashimoto 2015-04-07 17:56:27 -07:00
commit 3a3cae9c9c
7 changed files with 56 additions and 23 deletions

View File

@ -14,16 +14,16 @@ type uiModuleStorage struct {
Ui cli.Ui Ui cli.Ui
} }
func (s *uiModuleStorage) Dir(source string) (string, bool, error) { func (s *uiModuleStorage) Dir(key string) (string, bool, error) {
return s.Storage.Dir(source) return s.Storage.Dir(key)
} }
func (s *uiModuleStorage) Get(source string, update bool) error { func (s *uiModuleStorage) Get(key string, source string, update bool) error {
updateStr := "" updateStr := ""
if update { if update {
updateStr = " (update)" updateStr = " (update)"
} }
s.Ui.Output(fmt.Sprintf("Get: %s%s", source, updateStr)) s.Ui.Output(fmt.Sprintf("Get: %s%s", source, updateStr))
return s.Storage.Get(source, update) return s.Storage.Get(key, source, update)
} }

View File

@ -16,8 +16,8 @@ type FolderStorage struct {
} }
// Dir implements Storage.Dir // Dir implements Storage.Dir
func (s *FolderStorage) Dir(source string) (d string, e bool, err error) { func (s *FolderStorage) Dir(key string) (d string, e bool, err error) {
d = s.dir(source) d = s.dir(key)
_, err = os.Stat(d) _, err = os.Stat(d)
if err == nil { if err == nil {
// Directory exists // Directory exists
@ -39,8 +39,8 @@ func (s *FolderStorage) Dir(source string) (d string, e bool, err error) {
} }
// Get implements Storage.Get // Get implements Storage.Get
func (s *FolderStorage) Get(source string, update bool) error { func (s *FolderStorage) Get(key string, source string, update bool) error {
dir := s.dir(source) dir := s.dir(key)
if !update { if !update {
if _, err := os.Stat(dir); err == nil { if _, err := os.Stat(dir); err == nil {
// If the directory already exists, then we're done since // If the directory already exists, then we're done since
@ -59,7 +59,7 @@ func (s *FolderStorage) Get(source string, update bool) error {
// dir returns the directory name internally that we'll use to map to // dir returns the directory name internally that we'll use to map to
// internally. // internally.
func (s *FolderStorage) dir(source string) string { func (s *FolderStorage) dir(key string) string {
sum := md5.Sum([]byte(source)) sum := md5.Sum([]byte(key))
return filepath.Join(s.StorageDir, hex.EncodeToString(sum[:])) return filepath.Join(s.StorageDir, hex.EncodeToString(sum[:]))
} }

View File

@ -24,14 +24,16 @@ func TestFolderStorage(t *testing.T) {
t.Fatal("should not exist") t.Fatal("should not exist")
} }
key := "foo"
// We can get it // We can get it
err = s.Get(module, false) err = s.Get(key, module, false)
if err != nil { if err != nil {
t.Fatalf("err: %s", err) t.Fatalf("err: %s", err)
} }
// Now the module exists // Now the module exists
dir, ok, err := s.Dir(module) dir, ok, err := s.Dir(key)
if err != nil { if err != nil {
t.Fatalf("err: %s", err) t.Fatalf("err: %s", err)
} }

View File

@ -9,17 +9,17 @@ type Storage interface {
Dir(string) (string, bool, error) Dir(string) (string, bool, error)
// Get will download and optionally update the given module. // Get will download and optionally update the given module.
Get(string, bool) error Get(string, string, bool) error
} }
func getStorage(s Storage, src string, mode GetMode) (string, bool, error) { func getStorage(s Storage, key string, src string, mode GetMode) (string, bool, error) {
// Get the module with the level specified if we were told to. // Get the module with the level specified if we were told to.
if mode > GetModeNone { if mode > GetModeNone {
if err := s.Get(src, mode == GetModeUpdate); err != nil { if err := s.Get(key, src, mode == GetModeUpdate); err != nil {
return "", false, err return "", false, err
} }
} }
// Get the directory where the module is. // Get the directory where the module is.
return s.Dir(src) return s.Dir(key)
} }

View File

@ -23,6 +23,7 @@ type Tree struct {
name string name string
config *config.Config config *config.Config
children map[string]*Tree children map[string]*Tree
path []string
lock sync.RWMutex lock sync.RWMutex
} }
@ -152,6 +153,11 @@ func (t *Tree) Load(s Storage, mode GetMode) error {
"module %s: duplicated. module names must be unique", m.Name) "module %s: duplicated. module names must be unique", m.Name)
} }
// Determine the path to this child
path := make([]string, len(t.path), len(t.path)+1)
copy(path, t.path)
path = append(path, m.Name)
// Split out the subdir if we have one // Split out the subdir if we have one
source, subDir := getDirSubdir(m.Source) source, subDir := getDirSubdir(m.Source)
@ -167,7 +173,9 @@ func (t *Tree) Load(s Storage, mode GetMode) error {
} }
// Get the directory where this module is so we can load it // Get the directory where this module is so we can load it
dir, ok, err := getStorage(s, source, mode) key := strings.Join(path, ".")
key = "root." + key
dir, ok, err := getStorage(s, key, source, mode)
if err != nil { if err != nil {
return err return err
} }
@ -187,6 +195,9 @@ func (t *Tree) Load(s Storage, mode GetMode) error {
return fmt.Errorf( return fmt.Errorf(
"module %s: %s", m.Name, err) "module %s: %s", m.Name, err)
} }
// Set the path of this child
children[m.Name].path = path
} }
// Go through all the children and load them. // Go through all the children and load them.
@ -202,10 +213,19 @@ func (t *Tree) Load(s Storage, mode GetMode) error {
return nil return nil
} }
// Path is the full path to this tree.
func (t *Tree) Path() []string {
return t.path
}
// String gives a nice output to describe the tree. // String gives a nice output to describe the tree.
func (t *Tree) String() string { func (t *Tree) String() string {
var result bytes.Buffer var result bytes.Buffer
result.WriteString(t.Name() + "\n") path := strings.Join(t.path, ", ")
if path != "" {
path = fmt.Sprintf(" (path: %s)", path)
}
result.WriteString(t.Name() + path + "\n")
cs := t.Children() cs := t.Children()
if cs == nil { if cs == nil {

View File

@ -22,6 +22,7 @@ func (t *Tree) GobDecode(bs []byte) error {
t.name = data.Name t.name = data.Name
t.config = data.Config t.config = data.Config
t.children = data.Children t.children = data.Children
t.path = data.Path
return nil return nil
} }
@ -31,6 +32,7 @@ func (t *Tree) GobEncode() ([]byte, error) {
Config: t.config, Config: t.config,
Children: t.children, Children: t.children,
Name: t.name, Name: t.name,
Path: t.path,
} }
var buf bytes.Buffer var buf bytes.Buffer
@ -51,4 +53,5 @@ type treeGob struct {
Config *config.Config Config *config.Config
Children map[string]*Tree Children map[string]*Tree
Name string Name string
Path []string
} }

View File

@ -18,6 +18,8 @@ func TestTreeChild(t *testing.T) {
t.Fatal("should not be nil") t.Fatal("should not be nil")
} else if c.Name() != "root" { } else if c.Name() != "root" {
t.Fatalf("bad: %#v", c.Name()) t.Fatalf("bad: %#v", c.Name())
} else if !reflect.DeepEqual(c.Path(), []string(nil)) {
t.Fatalf("bad: %#v", c.Path())
} }
// Should be able to get the root child // Should be able to get the root child
@ -25,6 +27,8 @@ func TestTreeChild(t *testing.T) {
t.Fatal("should not be nil") t.Fatal("should not be nil")
} else if c.Name() != "root" { } else if c.Name() != "root" {
t.Fatalf("bad: %#v", c.Name()) t.Fatalf("bad: %#v", c.Name())
} else if !reflect.DeepEqual(c.Path(), []string(nil)) {
t.Fatalf("bad: %#v", c.Path())
} }
// Should be able to get the foo child // Should be able to get the foo child
@ -32,6 +36,8 @@ func TestTreeChild(t *testing.T) {
t.Fatal("should not be nil") t.Fatal("should not be nil")
} else if c.Name() != "foo" { } else if c.Name() != "foo" {
t.Fatalf("bad: %#v", c.Name()) t.Fatalf("bad: %#v", c.Name())
} else if !reflect.DeepEqual(c.Path(), []string{"foo"}) {
t.Fatalf("bad: %#v", c.Path())
} }
// Should be able to get the nested child // Should be able to get the nested child
@ -39,6 +45,8 @@ func TestTreeChild(t *testing.T) {
t.Fatal("should not be nil") t.Fatal("should not be nil")
} else if c.Name() != "bar" { } else if c.Name() != "bar" {
t.Fatalf("bad: %#v", c.Name()) t.Fatalf("bad: %#v", c.Name())
} else if !reflect.DeepEqual(c.Path(), []string{"foo", "bar"}) {
t.Fatalf("bad: %#v", c.Path())
} }
} }
@ -274,16 +282,16 @@ func TestTreeValidate_requiredChildVar(t *testing.T) {
const treeLoadStr = ` const treeLoadStr = `
root root
foo foo (path: foo)
` `
const treeLoadParentStr = ` const treeLoadParentStr = `
root root
a a (path: a)
b b (path: a, b)
` `
const treeLoadSubdirStr = ` const treeLoadSubdirStr = `
root root
foo foo (path: foo)
bar bar (path: foo, bar)
` `