diff --git a/.vscode/launch.json b/.vscode/launch.json index fb2523b..773bad4 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -7,7 +7,7 @@ "request": "launch", "preLaunchTask": "build", // If you have changed target frameworks, make sure to update the program path. - "program": "${workspaceFolder}/src/TemplateRefGenerator/bin/Debug/net9.0/TemplateRefGenerator", + "program": "${workspaceFolder}/src/TemplateRefGenerator/bin/Debug/net10.0/TemplateRefGenerator", "args": [ "--source-folder", "../../../bicep-types-az/generated", @@ -26,7 +26,7 @@ "request": "launch", "preLaunchTask": "build", // If you have changed target frameworks, make sure to update the program path. - "program": "${workspaceFolder}/src/TemplateRefGenerator/bin/Debug/net9.0/TemplateRefGenerator", + "program": "${workspaceFolder}/src/TemplateRefGenerator/bin/Debug/net10.0/TemplateRefGenerator", "args": [ "--source-folder", "../../../bicep-types-az/generated", diff --git a/docs/dev_guide.md b/docs/dev_guide.md index a1494d3..c3b09f3 100644 --- a/docs/dev_guide.md +++ b/docs/dev_guide.md @@ -36,14 +36,14 @@ Run `dotnet build` to build this project. After building the .NET solution, you can use the CLI by running: ```sh -./src/TemplateRefGenerator/bin/Debug/net9.0/TemplateRefGenerator +./src/TemplateRefGenerator/bin/Debug/net10.0/TemplateRefGenerator ``` If you run this command without supplying any arguments, you will see a help message giving information on the supported arguments. Here's an example of how you can run the CLI tool: ```sh -src/TemplateRefGenerator/bin/Debug/net9.0/TemplateRefGenerator --source-folder ../bicep-types-az/generated --output-folder ./generated +src/TemplateRefGenerator/bin/Debug/net10.0/TemplateRefGenerator --source-folder ../bicep-types-az/generated --output-folder ./generated ``` To get detailed logging, use the `--verbose` flag. \ No newline at end of file diff --git a/global.json b/global.json index 2f52ea2..07ba211 100644 --- a/global.json +++ b/global.json @@ -4,7 +4,7 @@ }, "sdk": { "allowPrerelease": false, - "version": "9.0.309", + "version": "10.0.101", "rollForward": "latestPatch" } } \ No newline at end of file diff --git a/src/Directory.Build.props b/src/Directory.Build.props index cf493fb..ebe27fc 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -4,7 +4,7 @@ default enable enable - net9.0 + net10.0 true $(NoWarn);NU5104 true diff --git a/src/TemplateRefGenerator.Tests/Files/markdown/microsoft.addons/2018-03-01/supportproviders/supportplantypes.md b/src/TemplateRefGenerator.Tests/Files/markdown/microsoft.addons/2018-03-01/supportproviders/supportplantypes.md index 0849c05..7c50b0e 100644 --- a/src/TemplateRefGenerator.Tests/Files/markdown/microsoft.addons/2018-03-01/supportproviders/supportplantypes.md +++ b/src/TemplateRefGenerator.Tests/Files/markdown/microsoft.addons/2018-03-01/supportproviders/supportplantypes.md @@ -39,7 +39,7 @@ resource symbolicname 'Microsoft.Addons/supportProviders/supportPlanTypes@2018-0 | Name | Description | Value | | ---- | ----------- | ------------ | | name | The resource name | 'Advanced'
'Essential'
'Standard' (required) | -| parent | In Bicep, you can specify the parent resource for a child resource. You only need to add this property when the child resource is declared outside of the parent resource.

For more information, see [Child resource outside parent resource](/azure/azure-resource-manager/bicep/child-resource-name-type#outside-parent-resource). | Symbolic name for resource of type: [supportProviders](~/microsoft.addons/supportproviders.md) | +| parent | In Bicep, you can specify the parent resource for a child resource. You only need to add this property when the child resource is declared outside of the parent resource.

For more information, see [Child resource outside parent resource](/azure/azure-resource-manager/bicep/child-resource-name-type#outside-parent-resource). | Symbolic name for resource of type: supportProviders | ::: zone-end @@ -105,7 +105,7 @@ resource "azapi_resource" "symbolicname" { | Name | Description | Value | | ---- | ----------- | ------------ | | name | The resource name | 'Advanced'
'Essential'
'Standard' (required) | -| parent_id | The ID of the resource that is the parent for this resource. | ID for resource of type: [supportProviders](~/microsoft.addons/supportproviders.md) | +| parent_id | The ID of the resource that is the parent for this resource. | ID for resource of type: supportProviders | | type | The resource type | "Microsoft.Addons/supportProviders/supportPlanTypes@2018-03-01" | diff --git a/src/TemplateRefGenerator/Generators/MarkdownGenerator.cs b/src/TemplateRefGenerator/Generators/MarkdownGenerator.cs index 5f0b80b..3ccda07 100644 --- a/src/TemplateRefGenerator/Generators/MarkdownGenerator.cs +++ b/src/TemplateRefGenerator/Generators/MarkdownGenerator.cs @@ -38,6 +38,10 @@ public IReadOnlyDictionary> GetApiVersionsByType( .SelectMany(x => x.Value.Select(y => (type: y, version: x.Key))) .GroupBy(x => x.type, x => x.version, StringComparer.OrdinalIgnoreCase) .ToDictionary(x => x.Key, x => x.ToImmutableArray(), StringComparer.OrdinalIgnoreCase); + + public bool HasType(string resourceType, string apiVersion) + => ResourceTypeByApiVersion.TryGetValue(apiVersion, out var types) + && types.Contains(resourceType, StringComparer.OrdinalIgnoreCase); } public record GenerateResult( @@ -49,7 +53,9 @@ public record ResourceMetadata( string ResourceType, string UnqualifiedResourceType, string ApiVersion, - ResourceType Type); + ResourceType Type, + bool IsChildResource, + bool IsParentTypeAvailable); public record NamedType(string Name, TypeBase Type); @@ -171,7 +177,7 @@ private static string GetResourceRemarks(ResourceMetadata resource, RemarksFile sb.Append($""" ### Azure Quickstart Samples -The following [Azure Quickstart templates](https://aka.ms/azqst) contain Bicep samples for deploying this resource type. +The following {MarkdownUtils.GetLink("Azure Quickstart templates", "https://aka.ms/azqst")} contain Bicep samples for deploying this resource type. > [!div class="mx-tableFixed"] > | Bicep File | Description | @@ -209,7 +215,7 @@ private static string GetJsonQuickstartsSection(SamplesFile samples, ResourceMet sb.Append($""" ### Azure Quickstart Templates -The following [Azure Quickstart templates](https://aka.ms/azqst) deploy this resource type. +The following {MarkdownUtils.GetLink("Azure Quickstart templates", "https://aka.ms/azqst")} deploy this resource type. > [!div class="mx-tableFixed"] > | Template | Description | @@ -250,7 +256,7 @@ The following [Azure Quickstart templates](https://aka.ms/azqst) deploy this res sb.Append($""" ### Azure Verified Modules -The following [Azure Verified Modules](https://aka.ms/avm) can be used to deploy this resource type. +The following {MarkdownUtils.GetLink("Azure Verified Modules", "https://aka.ms/avm")} can be used to deploy this resource type. > [!div class="mx-tableFixed"] > | Module | Description | @@ -288,28 +294,28 @@ private static string GetBicepZone(ConfigLoader configLoader, RemarksLoader rema if (resource.Type.ScopeType.HasFlag(ScopeType.Tenant)) { sb.Append($""" -* **Tenant** - See [tenant deployment commands](/azure/azure-resource-manager/bicep/deploy-to-tenant) +* **Tenant** - See {MarkdownUtils.GetLink("tenant deployment commands", "/azure/azure-resource-manager/bicep/deploy-to-tenant")} """); } if (resource.Type.ScopeType.HasFlag(ScopeType.ManagementGroup)) { sb.Append($""" -* **Management groups** - See [management group deployment commands](/azure/azure-resource-manager/bicep/deploy-to-management-group) +* **Management groups** - See {MarkdownUtils.GetLink("management group deployment commands", "/azure/azure-resource-manager/bicep/deploy-to-management-group")} """); } if (resource.Type.ScopeType.HasFlag(ScopeType.Subscription)) { sb.Append($""" -* **Subscription** - See [subscription deployment commands](/azure/azure-resource-manager/bicep/deploy-to-subscription) +* **Subscription** - See {MarkdownUtils.GetLink("subscription deployment commands", "/azure/azure-resource-manager/bicep/deploy-to-subscription")} """); } if (resource.Type.ScopeType.HasFlag(ScopeType.ResourceGroup)) { sb.Append($""" -* **Resource groups** - See [resource group deployment commands](/azure/azure-resource-manager/bicep/deploy-to-resource-group) +* **Resource groups** - See {MarkdownUtils.GetLink("resource group deployment commands", "/azure/azure-resource-manager/bicep/deploy-to-resource-group")} """); } @@ -318,7 +324,7 @@ private static string GetBicepZone(ConfigLoader configLoader, RemarksLoader rema sb.Append($""" -For a list of changed properties in each API version, see [change log](~/{resource.Provider.ToLowerInvariant()}/change-log/{resource.UnqualifiedResourceType.ToLowerInvariant()}.md). +For a list of changed properties in each API version, see {MarkdownUtils.GetLink("change log", $"~/{resource.Provider.ToLowerInvariant()}/change-log/{resource.UnqualifiedResourceType.ToLowerInvariant()}.md")}. ## Resource format @@ -417,28 +423,28 @@ private static string GetArmTemplateZone(ConfigLoader configLoader, ResourceMeta if (resource.Type.ScopeType.HasFlag(ScopeType.Tenant)) { sb.Append($""" -* **Tenant** - See [tenant deployment commands](/azure/azure-resource-manager/templates/deploy-to-tenant) +* **Tenant** - See {MarkdownUtils.GetLink("tenant deployment commands", "/azure/azure-resource-manager/templates/deploy-to-tenant")} """); } if (resource.Type.ScopeType.HasFlag(ScopeType.ManagementGroup)) { sb.Append($""" -* **Management groups** - See [management group deployment commands](/azure/azure-resource-manager/templates/deploy-to-management-group) +* **Management groups** - See {MarkdownUtils.GetLink("management group deployment commands", "/azure/azure-resource-manager/templates/deploy-to-management-group")} """); } if (resource.Type.ScopeType.HasFlag(ScopeType.Subscription)) { sb.Append($""" -* **Subscription** - See [subscription deployment commands](/azure/azure-resource-manager/templates/deploy-to-subscription) +* **Subscription** - See {MarkdownUtils.GetLink("subscription deployment commands", "/azure/azure-resource-manager/templates/deploy-to-subscription")} """); } if (resource.Type.ScopeType.HasFlag(ScopeType.ResourceGroup)) { sb.Append($""" -* **Resource groups** - See [resource group deployment commands](/azure/azure-resource-manager/templates/deploy-to-resource-group) +* **Resource groups** - See {MarkdownUtils.GetLink("resource group deployment commands", "/azure/azure-resource-manager/templates/deploy-to-resource-group")} """); } @@ -447,7 +453,7 @@ private static string GetArmTemplateZone(ConfigLoader configLoader, ResourceMeta sb.Append($""" -For a list of changed properties in each API version, see [change log](~/{resource.Provider.ToLowerInvariant()}/change-log/{resource.UnqualifiedResourceType.ToLowerInvariant()}.md). +For a list of changed properties in each API version, see {MarkdownUtils.GetLink("change log", $"~/{resource.Provider.ToLowerInvariant()}/change-log/{resource.UnqualifiedResourceType.ToLowerInvariant()}.md")}. ## Resource format @@ -548,7 +554,7 @@ private static string GetTerraformZone(ConfigLoader configLoader, RemarksLoader sb.Append($""" -For a list of changed properties in each API version, see [change log](~/{resource.Provider.ToLowerInvariant()}/change-log/{resource.UnqualifiedResourceType.ToLowerInvariant()}.md). +For a list of changed properties in each API version, see {MarkdownUtils.GetLink("change log", $"~/{resource.Provider.ToLowerInvariant()}/change-log/{resource.UnqualifiedResourceType.ToLowerInvariant()}.md")}. ## Resource format @@ -855,8 +861,8 @@ private static IEnumerable GetProperties( yield return new( "parent", - $"In Bicep, you can specify the parent resource for a child resource. You only need to add this property when the child resource is declared outside of the parent resource.{Br}{Br}For more information, see [Child resource outside parent resource](/azure/azure-resource-manager/bicep/child-resource-name-type#outside-parent-resource).", - $"Symbolic name for resource of type: [{parentTypeUnqualified}](~/{parentType.ToLowerInvariant()}.md)"); + $"In Bicep, you can specify the parent resource for a child resource. You only need to add this property when the child resource is declared outside of the parent resource.{Br}{Br}For more information, see {MarkdownUtils.GetLink("Child resource outside parent resource", "/azure/azure-resource-manager/bicep/child-resource-name-type#outside-parent-resource")}.", + $"Symbolic name for resource of type: {GetParentResourceNameWithOptionalLink(resource)}"); } else if (resource.Type.ScopeType == ScopeType.Unknown || resource.Type.ScopeType.HasFlag(ScopeType.Extension)) @@ -864,7 +870,7 @@ private static IEnumerable GetProperties( yield return new( "scope", "Use when creating a resource at a scope that is different than the deployment scope.", - "Set this property to the symbolic name of a resource to apply the [extension resource](/azure/azure-resource-manager/bicep/scope-extension-resources)."); + $"Set this property to the symbolic name of a resource to apply the {MarkdownUtils.GetLink("extension resource", "/azure/azure-resource-manager/bicep/scope-extension-resources")}."); } break; case DeploymentType.Terraform: @@ -876,7 +882,7 @@ private static IEnumerable GetProperties( yield return new( "parent_id", $"The ID of the resource that is the parent for this resource.", - $"ID for resource of type: [{parentTypeUnqualified}](~/{parentType.ToLowerInvariant()}.md)"); + $"ID for resource of type: {GetParentResourceNameWithOptionalLink(resource)}"); } else if (resource.Type.ScopeType == ScopeType.Unknown || resource.Type.ScopeType.HasFlag(ScopeType.Extension)) @@ -910,7 +916,7 @@ private static IEnumerable GetProperties( if (isResourceType && propName == "tags") { var tagsType = deploymentType != DeploymentType.Terraform ? - "Dictionary of tag names and values. See [Tags in templates](/azure/azure-resource-manager/management/tag-resources#arm-templates)" : + $"Dictionary of tag names and values. See {MarkdownUtils.GetLink("Tags in templates", "/azure/azure-resource-manager/management/tag-resources#arm-templates")}" : "Dictionary of tag names and values."; yield return new( @@ -1016,13 +1022,17 @@ public static string GenerateMarkdown(GroupedTypes groupedTypes, ResourceType re var apiVersion = resourceType.Name.Split('@')[1]; var providerNamespace = Utils.GetProviderNamespace(resourceTypeName); var unqualifiedResourceType = Utils.GetUnqualifiedType(resourceTypeName); + var isChildResource = Utils.IsChildResource(unqualifiedResourceType); + var isParentTypeAvailable = isChildResource && groupedTypes.HasType(Utils.GetParentResource(resourceTypeName), apiVersion); var resource = new ResourceMetadata( Provider: providerNamespace, ResourceType: resourceTypeName, UnqualifiedResourceType: unqualifiedResourceType, ApiVersion: apiVersion, - Type: resourceType); + Type: resourceType, + IsChildResource: isChildResource, + IsParentTypeAvailable: isParentTypeAvailable); var namedTypes = GetNamedTypes(resource); var remarks = remarksLoader.GetRemarks(providerNamespace); @@ -1039,4 +1049,19 @@ public static string GenerateMarkdown(GroupedTypes groupedTypes, ResourceType re {GetTerraformZone(configLoader, remarksLoader, resource, namedTypes, remarks, 2)} """; } + + private static string GetParentResourceNameWithOptionalLink(ResourceMetadata resource) + { + if (!resource.IsChildResource) + { + throw new InvalidOperationException($"Resource {resource.ResourceType} is not a child resource"); + } + + var parentType = Utils.GetParentResource(resource.ResourceType); + var parentTypeUnqualified = Utils.GetParentResource(resource.UnqualifiedResourceType); + + return resource.IsParentTypeAvailable ? + MarkdownUtils.GetLink(parentTypeUnqualified, $"~/{parentType.ToLowerInvariant()}.md") : + parentTypeUnqualified; + } } \ No newline at end of file