cli/bpmetadata/path.go (69 lines of code) (raw):

package bpmetadata import ( "fmt" "io/fs" "os" "path/filepath" "regexp" "sort" "strings" ) const ( regexExamples = ".*/(examples/.*)" regexModules = ".*/(modules/.*)" ) var ( reExamples = regexp.MustCompile(regexExamples) reModules = regexp.MustCompile(regexModules) ) func fileExists(path string) (bool, error) { info, err := os.Stat(path) if err != nil { return false, fmt.Errorf("unable to read file at the provided path: %w", err) } if info.IsDir() { return false, fmt.Errorf("provided path is a directory, need a valid file path") } return true, nil } func getExamples(configPath string) ([]*BlueprintMiscContent, error) { return getDirPaths(configPath, reExamples) } func getModules(configPath string) ([]*BlueprintMiscContent, error) { return getDirPaths(configPath, reModules) } // getDirPaths traverses a given path and looks for directories // with TF configs while ignoring the .terraform* directories created and // used internally by the Terraform CLI func getDirPaths(configPath string, re *regexp.Regexp) ([]*BlueprintMiscContent, error) { paths := []*BlueprintMiscContent{} err := filepath.Walk(configPath, func(path string, info fs.FileInfo, err error) error { if err != nil { return fmt.Errorf("error accessing examples in the path %q: %w", configPath, err) } // skip if this is a .terraform dir if info.IsDir() && strings.HasPrefix(info.Name(), ".terraform") { return filepath.SkipDir } // only interested if it has a TF config if !info.IsDir() && strings.HasSuffix(info.Name(), ".tf") { d := filepath.Dir(path) if l := trimPath(d, re); l != "" { dirPath := &BlueprintMiscContent{ Name: filepath.Base(d), Location: l, } paths = append(paths, dirPath) } return filepath.SkipDir } return nil }) if err != nil { return nil, fmt.Errorf("error accessing examples in the path %q: %w", configPath, err) } // Sort by configPath name before returning sort.SliceStable(paths, func(i, j int) bool { return paths[i].Name < paths[j].Name }) return paths, nil } func trimPath(assetPath string, re *regexp.Regexp) string { matches := re.FindStringSubmatch(assetPath) if len(matches) > 1 { return matches[1] } return "" }