pkg/terraform_module_ref.go (125 lines of code) (raw):

package pkg import ( "fmt" "github.com/Azure/mapotf/pkg/terraform" "github.com/go-git/go-git/v5" "os" "path/filepath" ) var AbsDir func(string) (string, error) = filepath.Abs type TerraformModuleRef struct { Key string `json:"Key"` Source string `json:"Source"` Dir string `json:"Dir"` AbsDir string Version string `json:"Version"` GitHash string } func NewTerraformRootModuleRef(dir string) (*TerraformModuleRef, error) { return NewTerraformModuleRef(dir, "", "", "") } func NewTerraformModuleRef(dir, key, source, version string) (*TerraformModuleRef, error) { m := &TerraformModuleRef{ Key: key, Source: source, Dir: dir, Version: version, } if err := m.LoadAbsDir(); err != nil { return nil, err } m.LoadGitHash() return m, nil } func (m *TerraformModuleRef) Load() error { if err := m.LoadAbsDir(); err != nil { return err } m.LoadGitHash() return nil } func (m *TerraformModuleRef) LoadGitHash() { h, err := gitHash(m.AbsDir) if err != nil { //TODO:log error return } m.GitHash = h } func (m *TerraformModuleRef) LoadAbsDir() error { absDir, err := AbsDir(m.Dir) if err != nil { return fmt.Errorf("error getting absolute path for %s: %+v", m.Dir, err) } m.AbsDir = absDir return nil } func (r *TerraformModuleRef) toTerraformPkgType() terraform.ModuleRef { return terraform.ModuleRef{ Key: r.Key, Source: r.Source, Dir: r.Dir, AbsDir: r.AbsDir, Version: r.Version, GitHash: r.GitHash, } } func gitHash(dir string) (string, error) { gitPath, err := lookupGitPath(dir) if err != nil { return "", fmt.Errorf("cannot lookup git path: %+v", err) } r, err := git.PlainOpen(filepath.Dir(gitPath)) if err != nil { return "", err } ref, err := r.Head() if err != nil { return "", err } commit, err := r.CommitObject(ref.Hash()) if err != nil { return "", err } return commit.Hash.String(), nil } func lookupGitPath(path string) (string, error) { path, err := filepath.Abs(path) if err != nil { return "", err } fi, err := os.Stat(filepath.Join(path, ".git")) if err != nil { if !os.IsNotExist(err) { return "", err } isBare, err := isBareRepo(path) if err != nil { return "", err } if isBare { return path, nil } parent := filepath.Dir(path) if parent == path { return "", fmt.Errorf(".git not found") } return lookupGitPath(parent) } if !fi.IsDir() { return "", fmt.Errorf(".git exist but is not a directory") } return filepath.Join(path, ".git"), nil } func isBareRepo(path string) (bool, error) { markers := []string{"HEAD", "objects", "refs"} for _, marker := range markers { _, err := os.Stat(filepath.Join(path, marker)) if err != nil && !os.IsNotExist(err) { return false, err } if err != nil { return false, nil } } return true, nil }