in cli/azd/tools/avmres/main.go [37:143]
func run() error {
var avmModules []*avmModuleReference
err := filepath.WalkDir(*bicepDir, func(path string, d os.DirEntry, err error) error {
if err != nil {
return err
}
if d.IsDir() {
return nil
}
if filepath.Ext(path) != ".bicep" && filepath.Ext(path) != ".bicept" {
return nil
}
bytes, err := os.ReadFile(filepath.Join(*bicepDir, path))
if err != nil {
return fmt.Errorf("reading bicep file: %w", err)
}
matches := bicepAvmModuleRegex.FindAllStringSubmatch(string(bytes), -1)
for _, match := range matches {
if len(match) > 2 {
pathAndVersion := strings.Split(match[2], ":")
module := &avmModuleReference{
BicepName: match[1],
ModulePath: pathAndVersion[0],
ModuleVersion: pathAndVersion[1],
BicepFile: path,
}
avmModules = append(avmModules, module)
}
}
return nil
})
if err != nil {
return fmt.Errorf("walking bicep dir: %w", err)
}
for _, avmModule := range avmModules {
readme, err := fetchGithub(
*token,
"Azure/bicep-registry-modules",
fmt.Sprintf("%s/README.md", avmModule.ModulePath),
fmt.Sprintf("%s/%s", avmModule.ModulePath, avmModule.ModuleVersion))
if err != nil {
return fmt.Errorf("fetching README: %w", err)
}
brackets := regexp.MustCompile(`\[(.*?)\]`)
lines := strings.Split(string(readme), "\n")
resourceType := ""
apiVersion := ""
inSection := false
for i, line := range lines {
if i == 0 {
// Extract the resource type from something that looks like:
// # Storage Accounts `[Microsoft.Storage/storageAccounts]`
matches := brackets.FindStringSubmatch(line)
if len(matches) > 1 {
resourceType = matches[1]
}
}
if strings.HasPrefix(line, "## Resource Types") {
inSection = true
}
if inSection {
// Example input:
//nolint:lll
// | `Microsoft.Storage/storageAccounts` | [2023-05-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/2023-05-01/storageAccounts) |
if strings.HasPrefix(line, "|") { // inside table
if strings.Contains(line, "`"+resourceType+"`") { // found the resource type
matches := brackets.FindStringSubmatch(line)
if len(matches) > 1 {
apiVersion = matches[1]
break
}
}
}
}
}
if resourceType == "" || apiVersion == "" {
return fmt.Errorf("unable to find resource type or API version, run with --emit-source to see the source")
}
avmModule.ResourceType = resourceType
avmModule.ApiVersion = apiVersion
}
slices.SortFunc(avmModules, func(a, b *avmModuleReference) int {
return strings.Compare(a.BicepName, b.BicepName)
})
formatter := output.TableFormatter{}
err = formatter.Format(avmModules, os.Stdout, tableInputOptions)
if err != nil {
return fmt.Errorf("formatting output: %w", err)
}
return nil
}