diff --git a/AspNetCore.sln b/AspNetCore.sln index 3196580f8afa..aef714ac4734 100644 --- a/AspNetCore.sln +++ b/AspNetCore.sln @@ -1146,10 +1146,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.dotnet-openapi", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnet-microsoft.openapi.Tests", "src\Tools\Microsoft.dotnet-openapi\test\dotnet-microsoft.openapi.Tests.csproj", "{7A29AAAB-2B4B-4D47-A315-23A0E830E214}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Extensions.ApiDescription.Client", "Extensions.ApiDescription.Client", "{755D9C6A-F036-4122-8334-96F0CC70F370}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.ApiDescription.Client", "src\Tools\Extensions.ApiDescription.Client\src\Microsoft.Extensions.ApiDescription.Client.csproj", "{AB8C9BF4-3134-449B-BA3F-BAFDE9394491}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "dotnet-getdocument", "dotnet-getdocument", "{3CE23673-047A-47AA-A028-7F2942805870}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnet-getdocument", "src\Tools\dotnet-getdocument\src\dotnet-getdocument.csproj", "{7B1E6D8C-2658-4FD2-8BB2-672E9E56872F}" @@ -1162,8 +1158,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "GetDocumentInsider", "GetDo EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GetDocument.Insider", "src\Tools\GetDocumentInsider\src\GetDocument.Insider.csproj", "{DD63EA3C-929C-48FF-8E8A-8F3CC553E93B}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.ApiDescription.Client.Tests", "src\Tools\Extensions.ApiDescription.Client\test\Microsoft.Extensions.ApiDescription.Client.Tests.csproj", "{34E40892-48C1-4D3D-AB49-FAC3C4C00B42}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "FirstRunCertGenerator", "FirstRunCertGenerator", "{E5BE8CB1-57A8-48FD-9904-76A8C6B540BC}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.DeveloperCertificates.XPlat.Tests", "src\Tools\FirstRunCertGenerator\test\Microsoft.AspNetCore.DeveloperCertificates.XPlat.Tests.csproj", "{A8A42FB4-1B51-4290-9291-445D3A489758}" @@ -7204,22 +7198,6 @@ Global {7A29AAAB-2B4B-4D47-A315-23A0E830E214}.Release|x64.Build.0 = Release|Any CPU {7A29AAAB-2B4B-4D47-A315-23A0E830E214}.Release|x86.ActiveCfg = Release|Any CPU {7A29AAAB-2B4B-4D47-A315-23A0E830E214}.Release|x86.Build.0 = Release|Any CPU - {AB8C9BF4-3134-449B-BA3F-BAFDE9394491}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {AB8C9BF4-3134-449B-BA3F-BAFDE9394491}.Debug|Any CPU.Build.0 = Debug|Any CPU - {AB8C9BF4-3134-449B-BA3F-BAFDE9394491}.Debug|arm64.ActiveCfg = Debug|Any CPU - {AB8C9BF4-3134-449B-BA3F-BAFDE9394491}.Debug|arm64.Build.0 = Debug|Any CPU - {AB8C9BF4-3134-449B-BA3F-BAFDE9394491}.Debug|x64.ActiveCfg = Debug|Any CPU - {AB8C9BF4-3134-449B-BA3F-BAFDE9394491}.Debug|x64.Build.0 = Debug|Any CPU - {AB8C9BF4-3134-449B-BA3F-BAFDE9394491}.Debug|x86.ActiveCfg = Debug|Any CPU - {AB8C9BF4-3134-449B-BA3F-BAFDE9394491}.Debug|x86.Build.0 = Debug|Any CPU - {AB8C9BF4-3134-449B-BA3F-BAFDE9394491}.Release|Any CPU.ActiveCfg = Release|Any CPU - {AB8C9BF4-3134-449B-BA3F-BAFDE9394491}.Release|Any CPU.Build.0 = Release|Any CPU - {AB8C9BF4-3134-449B-BA3F-BAFDE9394491}.Release|arm64.ActiveCfg = Release|Any CPU - {AB8C9BF4-3134-449B-BA3F-BAFDE9394491}.Release|arm64.Build.0 = Release|Any CPU - {AB8C9BF4-3134-449B-BA3F-BAFDE9394491}.Release|x64.ActiveCfg = Release|Any CPU - {AB8C9BF4-3134-449B-BA3F-BAFDE9394491}.Release|x64.Build.0 = Release|Any CPU - {AB8C9BF4-3134-449B-BA3F-BAFDE9394491}.Release|x86.ActiveCfg = Release|Any CPU - {AB8C9BF4-3134-449B-BA3F-BAFDE9394491}.Release|x86.Build.0 = Release|Any CPU {7B1E6D8C-2658-4FD2-8BB2-672E9E56872F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {7B1E6D8C-2658-4FD2-8BB2-672E9E56872F}.Debug|Any CPU.Build.0 = Debug|Any CPU {7B1E6D8C-2658-4FD2-8BB2-672E9E56872F}.Debug|arm64.ActiveCfg = Debug|Any CPU @@ -7268,22 +7246,6 @@ Global {DD63EA3C-929C-48FF-8E8A-8F3CC553E93B}.Release|x64.Build.0 = Release|Any CPU {DD63EA3C-929C-48FF-8E8A-8F3CC553E93B}.Release|x86.ActiveCfg = Release|Any CPU {DD63EA3C-929C-48FF-8E8A-8F3CC553E93B}.Release|x86.Build.0 = Release|Any CPU - {34E40892-48C1-4D3D-AB49-FAC3C4C00B42}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {34E40892-48C1-4D3D-AB49-FAC3C4C00B42}.Debug|Any CPU.Build.0 = Debug|Any CPU - {34E40892-48C1-4D3D-AB49-FAC3C4C00B42}.Debug|arm64.ActiveCfg = Debug|Any CPU - {34E40892-48C1-4D3D-AB49-FAC3C4C00B42}.Debug|arm64.Build.0 = Debug|Any CPU - {34E40892-48C1-4D3D-AB49-FAC3C4C00B42}.Debug|x64.ActiveCfg = Debug|Any CPU - {34E40892-48C1-4D3D-AB49-FAC3C4C00B42}.Debug|x64.Build.0 = Debug|Any CPU - {34E40892-48C1-4D3D-AB49-FAC3C4C00B42}.Debug|x86.ActiveCfg = Debug|Any CPU - {34E40892-48C1-4D3D-AB49-FAC3C4C00B42}.Debug|x86.Build.0 = Debug|Any CPU - {34E40892-48C1-4D3D-AB49-FAC3C4C00B42}.Release|Any CPU.ActiveCfg = Release|Any CPU - {34E40892-48C1-4D3D-AB49-FAC3C4C00B42}.Release|Any CPU.Build.0 = Release|Any CPU - {34E40892-48C1-4D3D-AB49-FAC3C4C00B42}.Release|arm64.ActiveCfg = Release|Any CPU - {34E40892-48C1-4D3D-AB49-FAC3C4C00B42}.Release|arm64.Build.0 = Release|Any CPU - {34E40892-48C1-4D3D-AB49-FAC3C4C00B42}.Release|x64.ActiveCfg = Release|Any CPU - {34E40892-48C1-4D3D-AB49-FAC3C4C00B42}.Release|x64.Build.0 = Release|Any CPU - {34E40892-48C1-4D3D-AB49-FAC3C4C00B42}.Release|x86.ActiveCfg = Release|Any CPU - {34E40892-48C1-4D3D-AB49-FAC3C4C00B42}.Release|x86.Build.0 = Release|Any CPU {A8A42FB4-1B51-4290-9291-445D3A489758}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {A8A42FB4-1B51-4290-9291-445D3A489758}.Debug|Any CPU.Build.0 = Debug|Any CPU {A8A42FB4-1B51-4290-9291-445D3A489758}.Debug|arm64.ActiveCfg = Debug|Any CPU @@ -11318,15 +11280,12 @@ Global {192363C9-2D7B-47BD-A1A3-C6FEC6DF5D9D} = {0B200A66-B809-4ED3-A790-CB1C2E80975E} {4655E193-E5F4-449B-B1A3-6358AC8D3A27} = {192363C9-2D7B-47BD-A1A3-C6FEC6DF5D9D} {7A29AAAB-2B4B-4D47-A315-23A0E830E214} = {192363C9-2D7B-47BD-A1A3-C6FEC6DF5D9D} - {755D9C6A-F036-4122-8334-96F0CC70F370} = {0B200A66-B809-4ED3-A790-CB1C2E80975E} - {AB8C9BF4-3134-449B-BA3F-BAFDE9394491} = {755D9C6A-F036-4122-8334-96F0CC70F370} {3CE23673-047A-47AA-A028-7F2942805870} = {0B200A66-B809-4ED3-A790-CB1C2E80975E} {7B1E6D8C-2658-4FD2-8BB2-672E9E56872F} = {3CE23673-047A-47AA-A028-7F2942805870} {BE2C2FE4-7BC7-4A4B-A8B8-19FF0648DEFD} = {0B200A66-B809-4ED3-A790-CB1C2E80975E} {EBE144DD-577E-4E98-BFEB-94E479753927} = {BE2C2FE4-7BC7-4A4B-A8B8-19FF0648DEFD} {A1B75FC7-A777-4412-A635-D0C9ED8FE7A0} = {0B200A66-B809-4ED3-A790-CB1C2E80975E} {DD63EA3C-929C-48FF-8E8A-8F3CC553E93B} = {A1B75FC7-A777-4412-A635-D0C9ED8FE7A0} - {34E40892-48C1-4D3D-AB49-FAC3C4C00B42} = {755D9C6A-F036-4122-8334-96F0CC70F370} {E5BE8CB1-57A8-48FD-9904-76A8C6B540BC} = {0B200A66-B809-4ED3-A790-CB1C2E80975E} {A8A42FB4-1B51-4290-9291-445D3A489758} = {E5BE8CB1-57A8-48FD-9904-76A8C6B540BC} {3C8D5C14-F27B-4657-93C2-AC0E94EE683F} = {E5BE8CB1-57A8-48FD-9904-76A8C6B540BC} diff --git a/eng/ProjectReferences.props b/eng/ProjectReferences.props index 002b4ffdc5e0..224df6e32a19 100644 --- a/eng/ProjectReferences.props +++ b/eng/ProjectReferences.props @@ -70,7 +70,6 @@ - diff --git a/eng/ShippingAssemblies.props b/eng/ShippingAssemblies.props index bd06923b2454..5c1577ec3859 100644 --- a/eng/ShippingAssemblies.props +++ b/eng/ShippingAssemblies.props @@ -125,7 +125,6 @@ - diff --git a/src/Tools/Extensions.ApiDescription.Client/README.md b/src/Tools/Extensions.ApiDescription.Client/README.md deleted file mode 100644 index d268f30e3eb1..000000000000 --- a/src/Tools/Extensions.ApiDescription.Client/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# Microsoft.Extensions.ApiDescription.Client - -MSBuild glue for OpenAPI code generation. - -## How To Use - -See partner packages such as [NSwag.ApiDescription.Client](https://www.nuget.org/packages/NSwag.ApiDescription.Client/) for intended use. diff --git a/src/Tools/Extensions.ApiDescription.Client/src/CSharpIdentifier.cs b/src/Tools/Extensions.ApiDescription.Client/src/CSharpIdentifier.cs deleted file mode 100644 index 741240b119cb..000000000000 --- a/src/Tools/Extensions.ApiDescription.Client/src/CSharpIdentifier.cs +++ /dev/null @@ -1,54 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Globalization; -using System.Text; - -// Copied from -// https://github.com/dotnet/aspnetcore-tooling/blob/master/src/Razor/src/Microsoft.AspNetCore.Razor.Language/CSharpIdentifier.cs -namespace Microsoft.Extensions.ApiDescription.Client; - -internal static class CSharpIdentifier -{ - // CSharp Spec §2.4.2 - private static bool IsIdentifierStart(char character) - { - return char.IsLetter(character) || - character == '_' || - CharUnicodeInfo.GetUnicodeCategory(character) == UnicodeCategory.LetterNumber; - } - - public static bool IsIdentifierPart(char character) - { - return char.IsDigit(character) || - IsIdentifierStart(character) || - IsIdentifierPartByUnicodeCategory(character); - } - - private static bool IsIdentifierPartByUnicodeCategory(char character) - { - var category = CharUnicodeInfo.GetUnicodeCategory(character); - - return category == UnicodeCategory.NonSpacingMark || // Mn - category == UnicodeCategory.SpacingCombiningMark || // Mc - category == UnicodeCategory.ConnectorPunctuation || // Pc - category == UnicodeCategory.Format; // Cf - } - - public static string SanitizeIdentifier(string inputName) - { - if (!IsIdentifierStart(inputName[0]) && IsIdentifierPart(inputName[0])) - { - inputName = "_" + inputName; - } - - var builder = new StringBuilder(inputName.Length); - for (var i = 0; i < inputName.Length; i++) - { - var ch = inputName[i]; - builder.Append(IsIdentifierPart(ch) ? ch : '_'); - } - - return builder.ToString(); - } -} diff --git a/src/Tools/Extensions.ApiDescription.Client/src/GetCurrentOpenApiReference.cs b/src/Tools/Extensions.ApiDescription.Client/src/GetCurrentOpenApiReference.cs deleted file mode 100644 index 604d14f3d44e..000000000000 --- a/src/Tools/Extensions.ApiDescription.Client/src/GetCurrentOpenApiReference.cs +++ /dev/null @@ -1,33 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.Build.Framework; -using Microsoft.Build.Utilities; - -namespace Microsoft.Extensions.ApiDescription.Client; - -/// -/// Restore s from given property value. -/// -public class GetCurrentOpenApiReference : Task -{ - /// - /// The property value to deserialize. - /// - [Required] - public string Input { get; set; } - - /// - /// The restored s. Will never contain more than one item. - /// - [Output] - public ITaskItem[] Outputs { get; set; } - - /// - public override bool Execute() - { - Outputs = new[] { MetadataSerializer.DeserializeMetadata(Input) }; - - return true; - } -} diff --git a/src/Tools/Extensions.ApiDescription.Client/src/GetOpenApiReferenceMetadata.cs b/src/Tools/Extensions.ApiDescription.Client/src/GetOpenApiReferenceMetadata.cs deleted file mode 100644 index 276e8ee29138..000000000000 --- a/src/Tools/Extensions.ApiDescription.Client/src/GetOpenApiReferenceMetadata.cs +++ /dev/null @@ -1,134 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Collections.Generic; -using System.IO; -using Microsoft.Build.Framework; -using Microsoft.Build.Utilities; - -namespace Microsoft.Extensions.ApiDescription.Client; - -/// -/// Adds or corrects ClassName, FirstForGenerator, Namespace, and OutputPath metadata in OpenApiReference items. -/// Also stores final metadata as SerializedMetadata. -/// -public class GetOpenApiReferenceMetadata : Task -{ - private const string TypeScriptLanguageName = "TypeScript"; - - /// - /// Extension to use in default OutputPath metadata value. Ignored when generating TypeScript. - /// - [Required] - public string Extension { get; set; } - - /// - /// Default Namespace metadata value. - /// - [Required] - public string Namespace { get; set; } - - /// - /// Default directory for OutputPath values. - /// - public string OutputDirectory { get; set; } - - /// - /// The OpenApiReference items to update. - /// - [Required] - public ITaskItem[] Inputs { get; set; } - - /// - /// The updated OpenApiReference items. Will include ClassName, Namespace and OutputPath metadata. - /// - [Output] - public ITaskItem[] Outputs { get; set; } - - /// - public override bool Execute() - { - var outputs = new List(Inputs.Length); - var codeGenerators = new HashSet(); - var destinations = new HashSet(); - - foreach (var item in Inputs) - { - var codeGenerator = item.GetMetadata("CodeGenerator"); - if (string.IsNullOrEmpty(codeGenerator)) - { - // This case occurs when user overrides the required metadata with an empty string. - var type = string.IsNullOrEmpty(item.GetMetadata("SourceProject")) ? - "OpenApiReference" : - "OpenApiProjectReference"; - - Log.LogError(Resources.FormatInvalidEmptyMetadataValue("CodeGenerator", type, item.ItemSpec)); - continue; - } - - var newItem = new TaskItem(item); - outputs.Add(newItem); - - if (codeGenerators.Add(codeGenerator)) - { - newItem.SetMetadata("FirstForGenerator", "true"); - } - else - { - newItem.SetMetadata("FirstForGenerator", "false"); - } - - var outputPath = item.GetMetadata("OutputPath"); - if (string.IsNullOrEmpty(outputPath)) - { - // No need to further sanitize this path because the file must exist. - var filename = item.GetMetadata("Filename"); - var isTypeScript = codeGenerator.EndsWith( - TypeScriptLanguageName, - StringComparison.OrdinalIgnoreCase); - - outputPath = $"{filename}Client{(isTypeScript ? ".ts" : Extension)}"; - } - - // Place output file in correct directory (relative to project directory). - if (!Path.IsPathRooted(outputPath) && !string.IsNullOrEmpty(OutputDirectory)) - { - outputPath = Path.Combine(OutputDirectory, outputPath); - } - - if (!destinations.Add(outputPath)) - { - // This case may occur when user is experimenting e.g. with multiple code generators or options. - // May also occur when user accidentally duplicates OutputPath metadata. - Log.LogError(Resources.FormatDuplicateFileOutputPaths(outputPath)); - continue; - } - - MetadataSerializer.SetMetadata(newItem, "OutputPath", outputPath); - - var className = item.GetMetadata("ClassName"); - if (string.IsNullOrEmpty(className)) - { - var outputFilename = Path.GetFileNameWithoutExtension(outputPath); - - className = CSharpIdentifier.SanitizeIdentifier(outputFilename); - MetadataSerializer.SetMetadata(newItem, "ClassName", className); - } - - var @namespace = item.GetMetadata("Namespace"); - if (string.IsNullOrEmpty(@namespace)) - { - MetadataSerializer.SetMetadata(newItem, "Namespace", Namespace); - } - - // Add metadata which may be used as a property and passed to an inner build. - newItem.RemoveMetadata("SerializedMetadata"); - newItem.SetMetadata("SerializedMetadata", MetadataSerializer.SerializeMetadata(newItem)); - } - - Outputs = outputs.ToArray(); - - return !Log.HasLoggedErrors; - } -} diff --git a/src/Tools/Extensions.ApiDescription.Client/src/MetadataSerializer.cs b/src/Tools/Extensions.ApiDescription.Client/src/MetadataSerializer.cs deleted file mode 100644 index 9a3aa3eb3cca..000000000000 --- a/src/Tools/Extensions.ApiDescription.Client/src/MetadataSerializer.cs +++ /dev/null @@ -1,145 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Generic; -using System.Text; -using Microsoft.Build.Framework; -using Microsoft.Build.Utilities; - -namespace Microsoft.Extensions.ApiDescription.Client; - -/// -/// Utility methods to serialize and deserialize metadata. -/// -/// -/// Based on and uses the same escaping as -/// https://github.com/Microsoft/msbuild/blob/e70a3159d64f9ed6ec3b60253ef863fa883a99b1/src/Shared/EscapingUtilities.cs -/// -public static class MetadataSerializer -{ - private static readonly char[] CharsToEscape = { '%', '*', '?', '@', '$', '(', ')', ';', '\'' }; - private static readonly HashSet CharsToEscapeHash = new HashSet(CharsToEscape); - - /// - /// Add the given and to the . Or, - /// modify existing value to be . - /// - /// The to update. - /// The name of the new metadata. - /// The value of the new metadata. Assumed to be unescaped. - /// Uses same hex-encoded format as MSBuild's EscapeUtilities. - public static void SetMetadata(ITaskItem item, string key, string value) - { - if (item is ITaskItem2 item2) - { - item2.SetMetadataValueLiteral(key, value); - return; - } - - if (value.IndexOfAny(CharsToEscape) == -1) - { - item.SetMetadata(key, value); - return; - } - - var builder = new StringBuilder(); - EscapeValue(value, builder); - item.SetMetadata(key, builder.ToString()); - } - - /// - /// Serialize metadata for use as a property value passed into an inner build. - /// - /// The item to serialize. - /// A containing the serialized metadata. - /// Uses same hex-encoded format as MSBuild's EscapeUtilities. - public static string SerializeMetadata(ITaskItem item) - { - var builder = new StringBuilder(); - if (item is ITaskItem2 item2) - { - builder.Append($"Identity={item2.EvaluatedIncludeEscaped}"); - var metadata = item2.CloneCustomMetadataEscaped(); - foreach (var key in metadata.Keys) - { - var value = metadata[key]; - builder.Append($"|{key.ToString()}={value.ToString()}"); - } - } - else - { - builder.Append($"Identity="); - EscapeValue(item.ItemSpec, builder); - - var metadata = item.CloneCustomMetadata(); - foreach (var key in metadata.Keys) - { - builder.Append($"|{key.ToString()}="); - - var value = metadata[key]; - EscapeValue(value.ToString(), builder); - } - } - - return builder.ToString(); - } - - /// - /// Recreate an with metadata encoded in given . - /// - /// The serialized metadata. - /// The deserialized . - public static ITaskItem DeserializeMetadata(string value) - { - var metadata = value.Split('|'); - var item = new TaskItem(); - - // TaskItem implements ITaskITem2 explicitly and ITaskItem implicitly. - var item2 = (ITaskItem2)item; - foreach (var segment in metadata) - { - var keyAndValue = segment.Split(new[] { '=' }, count: 2); - if (string.Equals("Identity", keyAndValue[0])) - { - item2.EvaluatedIncludeEscaped = keyAndValue[1]; - continue; - } - - item2.SetMetadata(keyAndValue[0], keyAndValue[1]); - } - - return item; - } - - private static void EscapeValue(string value, StringBuilder builder) - { - if (string.IsNullOrEmpty(value)) - { - return; - } - - if (value.IndexOfAny(CharsToEscape) == -1) - { - builder.Append(value); - return; - } - - foreach (var @char in value) - { - if (CharsToEscapeHash.Contains(@char)) - { - builder.Append('%'); - builder.Append(HexDigitChar(@char / 0x10)); - builder.Append(HexDigitChar(@char & 0x0F)); - continue; - } - - builder.Append(@char); - } - } - - private static char HexDigitChar(int x) - { - return (char)(x + (x < 10 ? '0' : ('a' - 10))); - } -} diff --git a/src/Tools/Extensions.ApiDescription.Client/src/Microsoft.Extensions.ApiDescription.Client.csproj b/src/Tools/Extensions.ApiDescription.Client/src/Microsoft.Extensions.ApiDescription.Client.csproj deleted file mode 100644 index cd4ccaad9bf8..000000000000 --- a/src/Tools/Extensions.ApiDescription.Client/src/Microsoft.Extensions.ApiDescription.Client.csproj +++ /dev/null @@ -1,27 +0,0 @@ - - - - true - - MSBuild tasks and targets for code generation - false - $(MSBuildProjectName).nuspec - $(MSBuildProjectName) - Build Tasks;MSBuild;Swagger;OpenAPI;code generation;Web API client;service reference - netstandard2.0 - true - - - - - - - - - - - - - - - diff --git a/src/Tools/Extensions.ApiDescription.Client/src/Microsoft.Extensions.ApiDescription.Client.nuspec b/src/Tools/Extensions.ApiDescription.Client/src/Microsoft.Extensions.ApiDescription.Client.nuspec deleted file mode 100644 index 09c913fde636..000000000000 --- a/src/Tools/Extensions.ApiDescription.Client/src/Microsoft.Extensions.ApiDescription.Client.nuspec +++ /dev/null @@ -1,13 +0,0 @@ - - - - $CommonMetadataElements$ - - - - $CommonFileElements$ - - - - - diff --git a/src/Tools/Extensions.ApiDescription.Client/src/Resources.resx b/src/Tools/Extensions.ApiDescription.Client/src/Resources.resx deleted file mode 100644 index 1da8a3468400..000000000000 --- a/src/Tools/Extensions.ApiDescription.Client/src/Resources.resx +++ /dev/null @@ -1,126 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Multiple items have OutputPath='{0}'. All OpenApiReference items must have unique OutputPath metadata. - - - Invalid {0} metadata value for {1} item '{2}'. {0} metadata must not be set to the empty string. - - \ No newline at end of file diff --git a/src/Tools/Extensions.ApiDescription.Client/src/build/Microsoft.Extensions.ApiDescription.Client.props b/src/Tools/Extensions.ApiDescription.Client/src/build/Microsoft.Extensions.ApiDescription.Client.props deleted file mode 100644 index 8f7fb3efce7f..000000000000 --- a/src/Tools/Extensions.ApiDescription.Client/src/build/Microsoft.Extensions.ApiDescription.Client.props +++ /dev/null @@ -1,136 +0,0 @@ - - - - <_ApiDescriptionClientAssemblyPath>$(MSBuildThisFileDirectory)../tasks/netstandard2.0/Microsoft.Extensions.ApiDescription.Client.dll - - - - - - - - - - - true - - - true - - - true - - - $(BaseIntermediateOutputPath) - - - - - - - - - - - - - - - - NSwagCSharp - - - - - - $(OpenApiGenerateCodeOptions) - - - - - - - - - TargetFramework - - - - - - NSwagCSharp - - - - - - $(OpenApiGenerateCodeOptions) - - - - - - diff --git a/src/Tools/Extensions.ApiDescription.Client/src/build/Microsoft.Extensions.ApiDescription.Client.targets b/src/Tools/Extensions.ApiDescription.Client/src/build/Microsoft.Extensions.ApiDescription.Client.targets deleted file mode 100644 index f3640745069e..000000000000 --- a/src/Tools/Extensions.ApiDescription.Client/src/build/Microsoft.Extensions.ApiDescription.Client.targets +++ /dev/null @@ -1,179 +0,0 @@ - - - - - - _GenerateErrorsForOldItems; - _CreateOpenApiReferenceItemsForOpenApiProjectReferences; - _GetMetadataForOpenApiReferences; - _GenerateOpenApiCode; - _CreateCompileItemsForOpenApiReferences - - - - - - File;BrowseObject - - - - - - - - - false - false - true - - - true - - - - - - <_Temporary Remove="@(_Temporary)" /> - - - - - - - - - %(_Temporary.OriginalItemSpec) - - <_Temporary Remove="@(_Temporary)" /> - - - - - - - - <_Temporary Remove="@(_Temporary)" /> - - - - - - - - - - <_Temporary Remove="@(_Temporary)" /> - - - - - - - - - - - - - - - - - - - - - <_Files Remove="@(_Files)" /> - <_Files Include="@(OpenApiReference -> '%(OutputPath)')" - Condition="$([System.IO.File]::Exists('%(OpenApiReference.OutputPath)'))" /> - <_Directories Remove="@(_Directories)" /> - <_Directories Include="@(OpenApiReference -> '%(OutputPath)')" - Condition="Exists('%(OpenApiReference.OutputPath)') AND ! $([System.IO.File]::Exists('%(OpenApiReference.OutputPath)'))" /> - - - - <_Files SourceDocument="%(OriginalItemSpec)" RemoveMetadata="OriginalItemSpec" /> - <_Directories SourceDocument="%(OriginalItemSpec)" RemoveMetadata="OriginalItemSpec" /> - - - - - - - - - - - - <_TypeScriptCompileItemsFromDirectories>@(_Directories -> '%(Identity)/**/*.ts;%(Identity)/**/*.tsx') - <_CompileItemsFromDirectories>@(_Directories -> '%(Identity)/**/*$(DefaultLanguageSourceExtension)') - - - - - - - - - - <_Files Remove="@(_Files)" /> - <_Directories Remove="@(_Directories)" /> - - - - <_TypeScriptCompileItemsFromDirectories /> - <_CompileItemsFromDirectories /> - - - - - - - - - - - - - - - - - - - diff --git a/src/Tools/Extensions.ApiDescription.Client/src/build/OpenApiItemsSchema.xaml b/src/Tools/Extensions.ApiDescription.Client/src/build/OpenApiItemsSchema.xaml deleted file mode 100644 index 0859269d22cc..000000000000 --- a/src/Tools/Extensions.ApiDescription.Client/src/build/OpenApiItemsSchema.xaml +++ /dev/null @@ -1,191 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Tools/Extensions.ApiDescription.Client/src/buildMultiTargeting/Microsoft.Extensions.ApiDescription.Client.props b/src/Tools/Extensions.ApiDescription.Client/src/buildMultiTargeting/Microsoft.Extensions.ApiDescription.Client.props deleted file mode 100644 index 9ce9d3e25910..000000000000 --- a/src/Tools/Extensions.ApiDescription.Client/src/buildMultiTargeting/Microsoft.Extensions.ApiDescription.Client.props +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/Tools/Extensions.ApiDescription.Client/src/buildMultiTargeting/Microsoft.Extensions.ApiDescription.Client.targets b/src/Tools/Extensions.ApiDescription.Client/src/buildMultiTargeting/Microsoft.Extensions.ApiDescription.Client.targets deleted file mode 100644 index 41950aad7fc4..000000000000 --- a/src/Tools/Extensions.ApiDescription.Client/src/buildMultiTargeting/Microsoft.Extensions.ApiDescription.Client.targets +++ /dev/null @@ -1,20 +0,0 @@ - - - - - File;BrowseObject - - - - - - - - - diff --git a/src/Tools/Extensions.ApiDescription.Client/test/CSharpIdentifierTest.cs b/src/Tools/Extensions.ApiDescription.Client/test/CSharpIdentifierTest.cs deleted file mode 100644 index 319e91be644d..000000000000 --- a/src/Tools/Extensions.ApiDescription.Client/test/CSharpIdentifierTest.cs +++ /dev/null @@ -1,106 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Xunit; - -namespace Microsoft.Extensions.ApiDescription.Client; - -public class CSharpIdentifierTest -{ - [Theory] - [InlineData('a')] - [InlineData('Q')] - [InlineData('\u2164')] // UnicodeCategory.LetterNumber (roman numeral five) - [InlineData('_')] - [InlineData('9')] - [InlineData('\u0303')] // UnicodeCategory.NonSpacingMark (combining tilde) - [InlineData('\u09CB')] // UnicodeCategory.SpacingCombiningMark (Bengali vowel sign O) - [InlineData('\uFE4F')] // UnicodeCategory.ConnectorPunctuation (wavy low line) - [InlineData('\u2062')] // UnicodeCategory.Format (invisible times) - public void IsIdentifierPart_ReturnsTrue_WhenItShould(char character) - { - // Arrange and Act - var result = CSharpIdentifier.IsIdentifierPart(character); - - // Assert - Assert.True(result); - } - - [Theory] - [InlineData('/')] - [InlineData('-')] - [InlineData('\u20DF')] // UnicodeCategory.EnclosingMark (combining enclosing diamond) - [InlineData('\u2005')] // UnicodeCategory.SpaceSeparator (four-per-em space) - [InlineData('\u0096')] // UnicodeCategory.Control (start of guarded area) - [InlineData('\uFF1C')] // UnicodeCategory.MathSymbol (fullwidth less-than sign) - public void IsIdentifierPart_ReturnsFalse_WhenItShould(char character) - { - // Arrange and Act - var result = CSharpIdentifier.IsIdentifierPart(character); - - // Assert - Assert.False(result); - } - - // Output length is one longer than input in these cases. - [Theory] - [InlineData("9", "_9")] - [InlineData("\u0303", "_\u0303")] // UnicodeCategory.NonSpacingMark (combining tilde) - [InlineData("\u09CB", "_\u09CB")] // UnicodeCategory.SpacingCombiningMark (Bengali vowel sign O) - [InlineData("\uFE4F", "_\uFE4F")] // UnicodeCategory.ConnectorPunctuation (wavy low line) - [InlineData("\u2062", "_\u2062")] // UnicodeCategory.Format (invisible times) - public void SanitizeIdentifier_AddsUnderscore_WhenItShould(string input, string expectdOutput) - { - // Arrange and Act - var output = CSharpIdentifier.SanitizeIdentifier(input); - - // Assert - Assert.Equal(expectdOutput, output); - } - - [Theory] - [InlineData("a", "a")] - [InlineData("Q", "Q")] - [InlineData("\u2164", "\u2164")] - [InlineData("_", "_")] - public void SanitizeIdentifier_DoesNotAddUnderscore_WhenValidStartCharacter(string input, string expectdOutput) - { - // Arrange and Act - var output = CSharpIdentifier.SanitizeIdentifier(input); - - // Assert - Assert.Equal(expectdOutput, output); - } - - [Theory] - [InlineData("/", "_")] - [InlineData("-", "_")] - [InlineData("\u20DF", "_")] // UnicodeCategory.EnclosingMark (combining enclosing diamond) - [InlineData("\u2005", "_")] // UnicodeCategory.SpaceSeparator (four-per-em space) - [InlineData("\u0096", "_")] // UnicodeCategory.Control (start of guarded area) - [InlineData("\uFF1C", "_")] // UnicodeCategory.MathSymbol (fullwidth less-than sign) - public void SanitizeIdentifier_DoesNotAddUnderscore_WhenInvalidCharacter(string input, string expectdOutput) - { - // Arrange and Act - var output = CSharpIdentifier.SanitizeIdentifier(input); - - // Assert - Assert.Equal(expectdOutput, output); - } - - [Theory] - [InlineData("a/", "a_")] - [InlineData("aa-bb", "aa_bb")] - [InlineData("aa\u20DF\u20DF", "aa__")] // UnicodeCategory.EnclosingMark (combining enclosing diamond) - [InlineData("aa\u2005bb\u2005cc", "aa_bb_cc")] // UnicodeCategory.SpaceSeparator (four-per-em space) - [InlineData("aa\u0096\u0096bb", "aa__bb")] // UnicodeCategory.Control (start of guarded area) - [InlineData("aa\uFF1C\uFF1C\uFF1Cbb", "aa___bb")] // UnicodeCategory.MathSymbol (fullwidth less-than sign) - public void SanitizeIdentifier_ReplacesInvalidCharacters_WhenNotFirst(string input, string expectdOutput) - { - // Arrange and Act - var output = CSharpIdentifier.SanitizeIdentifier(input); - - // Assert - Assert.Equal(expectdOutput, output); - } -} diff --git a/src/Tools/Extensions.ApiDescription.Client/test/GetCurrentOpenApiReferenceTest.cs b/src/Tools/Extensions.ApiDescription.Client/test/GetCurrentOpenApiReferenceTest.cs deleted file mode 100644 index e0a4ffa5c416..000000000000 --- a/src/Tools/Extensions.ApiDescription.Client/test/GetCurrentOpenApiReferenceTest.cs +++ /dev/null @@ -1,56 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Collections.Generic; -using Xunit; - -namespace Microsoft.Extensions.ApiDescription.Client; - -public class GetCurrentOpenApiReferenceTest -{ - [Fact] - public void Execute_ReturnsExpectedItem() - { - // Arrange - var input = "Identity=../files/azureMonitor.json|ClassName=azureMonitorClient|" + - "CodeGenerator=NSwagCSharp|Namespace=ConsoleClient|Options=|OutputPath=" + - "C:\\dd\\dnx\\AspNetCore\\artifacts\\obj\\ConsoleClient\\azureMonitorClient.cs|" + - "OriginalItemSpec=../files/azureMonitor.json|FirstForGenerator=true"; - var task = new GetCurrentOpenApiReference - { - Input = input, - }; - - var expectedIdentity = "../files/azureMonitor.json"; - var expectedMetadata = new SortedDictionary(StringComparer.Ordinal) - { - { "ClassName", "azureMonitorClient" }, - { "CodeGenerator", "NSwagCSharp" }, - { "FirstForGenerator", "true" }, - { "Namespace", "ConsoleClient" }, - { "Options", "" }, - { "OriginalItemSpec", expectedIdentity }, - { "OutputPath", "C:\\dd\\dnx\\AspNetCore\\artifacts\\obj\\ConsoleClient\\azureMonitorClient.cs" }, - }; - - // Act - var result = task.Execute(); - - // Assert - Assert.True(result); - Assert.False(task.Log.HasLoggedErrors); - var output = Assert.Single(task.Outputs); - Assert.Equal(expectedIdentity, output.ItemSpec); - var metadata = Assert.IsAssignableFrom>(output.CloneCustomMetadata()); - - // The dictionary CloneCustomMetadata returns doesn't provide a useful KeyValuePair enumerator. - var orderedMetadata = new SortedDictionary(StringComparer.Ordinal); - foreach (var key in metadata.Keys) - { - orderedMetadata.Add(key, metadata[key]); - } - - Assert.Equal(expectedMetadata, orderedMetadata); - } -} diff --git a/src/Tools/Extensions.ApiDescription.Client/test/GetOpenApiReferenceMetadataTest.cs b/src/Tools/Extensions.ApiDescription.Client/test/GetOpenApiReferenceMetadataTest.cs deleted file mode 100644 index 3a6fd319472d..000000000000 --- a/src/Tools/Extensions.ApiDescription.Client/test/GetOpenApiReferenceMetadataTest.cs +++ /dev/null @@ -1,575 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Collections.Generic; -using System.IO; -using Microsoft.Build.Utilities; -using Xunit; - -namespace Microsoft.Extensions.ApiDescription.Client; - -public class GetOpenApiReferenceMetadataTest -{ - [Fact] - public void Execute_AddsExpectedMetadata() - { - // Arrange - var identity = Path.Combine("TestProjects", "files", "NSwag.json"); - var @namespace = "Console.Client"; - var outputPath = Path.Combine("obj", "NSwagClient.cs"); - var inputMetadata = new Dictionary { { "CodeGenerator", "NSwagCSharp" } }; - var task = new GetOpenApiReferenceMetadata - { - Extension = ".cs", - Inputs = new[] { new TaskItem(identity, inputMetadata) }, - Namespace = @namespace, - OutputDirectory = "obj", - }; - - var expectedMetadata = new SortedDictionary(StringComparer.Ordinal) - { - { "ClassName", "NSwagClient" }, - { "CodeGenerator", "NSwagCSharp" }, - { "FirstForGenerator", "true" }, - { "Namespace", @namespace }, - { "OriginalItemSpec", identity }, - { "OutputPath", outputPath }, - { - "SerializedMetadata", - $"Identity={identity}|FirstForGenerator=true|" + - $"CodeGenerator=NSwagCSharp|OutputPath={outputPath}|Namespace={@namespace}|" + - $"OriginalItemSpec={identity}|ClassName=NSwagClient" - }, - }; - - // Act - var result = task.Execute(); - - // Assert - Assert.True(result); - Assert.False(task.Log.HasLoggedErrors); - var output = Assert.Single(task.Outputs); - Assert.Equal(identity, output.ItemSpec); - var metadata = Assert.IsAssignableFrom>(output.CloneCustomMetadata()); - - // The dictionary CloneCustomMetadata returns doesn't provide a useful KeyValuePair enumerator. - var orderedMetadata = new SortedDictionary(StringComparer.Ordinal); - foreach (var key in metadata.Keys) - { - orderedMetadata.Add(key, metadata[key]); - } - - Assert.Equal(expectedMetadata, orderedMetadata); - } - - [Fact] - public void Execute_DoesNotOverrideClassName() - { - // Arrange - var identity = Path.Combine("TestProjects", "files", "NSwag.json"); - var className = "ThisIsClassy"; - var @namespace = "Console.Client"; - var outputPath = Path.Combine("obj", $"NSwagClient.cs"); - var inputMetadata = new Dictionary - { - { "CodeGenerator", "NSwagCSharp" }, - { "ClassName", className }, - }; - - var task = new GetOpenApiReferenceMetadata - { - Extension = ".cs", - Inputs = new[] { new TaskItem(identity, inputMetadata) }, - Namespace = @namespace, - OutputDirectory = "obj", - }; - - var expectedMetadata = new SortedDictionary(StringComparer.Ordinal) - { - { "ClassName", className }, - { "CodeGenerator", "NSwagCSharp" }, - { "FirstForGenerator", "true" }, - { "Namespace", @namespace }, - { "OriginalItemSpec", identity }, - { "OutputPath", outputPath }, - { - "SerializedMetadata", - $"Identity={identity}|FirstForGenerator=true|" + - $"CodeGenerator=NSwagCSharp|OutputPath={outputPath}|Namespace={@namespace}|" + - $"OriginalItemSpec={identity}|ClassName={className}" - }, - }; - - // Act - var result = task.Execute(); - - // Assert - Assert.True(result); - Assert.False(task.Log.HasLoggedErrors); - var output = Assert.Single(task.Outputs); - Assert.Equal(identity, output.ItemSpec); - var metadata = Assert.IsAssignableFrom>(output.CloneCustomMetadata()); - - // The dictionary CloneCustomMetadata returns doesn't provide a useful KeyValuePair enumerator. - var orderedMetadata = new SortedDictionary(StringComparer.Ordinal); - foreach (var key in metadata.Keys) - { - orderedMetadata.Add(key, metadata[key]); - } - - Assert.Equal(expectedMetadata, orderedMetadata); - } - - [Fact] - public void Execute_DoesNotOverrideNamespace() - { - // Arrange - var defaultNamespace = "Console.Client"; - var identity = Path.Combine("TestProjects", "files", "NSwag.json"); - var @namespace = "NotConsole.NotClient"; - var outputPath = Path.Combine("obj", "NSwagClient.cs"); - var inputMetadata = new Dictionary - { - { "CodeGenerator", "NSwagCSharp" }, - { "Namespace", @namespace }, - }; - - var task = new GetOpenApiReferenceMetadata - { - Extension = ".cs", - Inputs = new[] { new TaskItem(identity, inputMetadata) }, - Namespace = defaultNamespace, - OutputDirectory = "obj", - }; - - var expectedMetadata = new SortedDictionary(StringComparer.Ordinal) - { - { "ClassName", "NSwagClient" }, - { "CodeGenerator", "NSwagCSharp" }, - { "FirstForGenerator", "true" }, - { "Namespace", @namespace }, - { "OriginalItemSpec", identity }, - { "OutputPath", outputPath }, - { - "SerializedMetadata", - $"Identity={identity}|FirstForGenerator=true|" + - $"CodeGenerator=NSwagCSharp|OutputPath={outputPath}|Namespace={@namespace}|" + - $"OriginalItemSpec={identity}|ClassName=NSwagClient" - }, - }; - - // Act - var result = task.Execute(); - - // Assert - Assert.True(result); - Assert.False(task.Log.HasLoggedErrors); - var output = Assert.Single(task.Outputs); - Assert.Equal(identity, output.ItemSpec); - var metadata = Assert.IsAssignableFrom>(output.CloneCustomMetadata()); - - // The dictionary CloneCustomMetadata returns doesn't provide a useful KeyValuePair enumerator. - var orderedMetadata = new SortedDictionary(StringComparer.Ordinal); - foreach (var key in metadata.Keys) - { - orderedMetadata.Add(key, metadata[key]); - } - - Assert.Equal(expectedMetadata, orderedMetadata); - } - - [Fact] - public void Execute_DoesNotOverrideOutputPath_IfRooted() - { - // Arrange - var identity = Path.Combine("TestProjects", "files", "NSwag.json"); - var className = "ThisIsClassy"; - var @namespace = "Console.Client"; - var outputPath = Path.Combine(Path.GetTempPath(), $"{className}.cs"); - var inputMetadata = new Dictionary - { - { "CodeGenerator", "NSwagCSharp" }, - { "OutputPath", outputPath } - }; - - var task = new GetOpenApiReferenceMetadata - { - Extension = ".cs", - Inputs = new[] { new TaskItem(identity, inputMetadata) }, - Namespace = @namespace, - OutputDirectory = "bin", - }; - - var expectedMetadata = new SortedDictionary(StringComparer.Ordinal) - { - { "ClassName", className }, - { "CodeGenerator", "NSwagCSharp" }, - { "FirstForGenerator", "true" }, - { "Namespace", @namespace }, - { "OriginalItemSpec", identity }, - { "OutputPath", outputPath }, - { - "SerializedMetadata", - $"Identity={identity}|FirstForGenerator=true|" + - $"CodeGenerator=NSwagCSharp|OutputPath={outputPath}|Namespace={@namespace}|" + - $"OriginalItemSpec={identity}|ClassName={className}" - }, - }; - - // Act - var result = task.Execute(); - - // Assert - Assert.True(result); - Assert.False(task.Log.HasLoggedErrors); - var output = Assert.Single(task.Outputs); - Assert.Equal(identity, output.ItemSpec); - var metadata = Assert.IsAssignableFrom>(output.CloneCustomMetadata()); - - // The dictionary CloneCustomMetadata returns doesn't provide a useful KeyValuePair enumerator. - var orderedMetadata = new SortedDictionary(StringComparer.Ordinal); - foreach (var key in metadata.Keys) - { - orderedMetadata.Add(key, metadata[key]); - } - - Assert.Equal(expectedMetadata, orderedMetadata); - } - - [Fact] - public void Execute_LogsError_IfCodeGeneratorMissing() - { - // Arrange - var identity1 = Path.Combine("TestProjects", "files", "NSwag.json"); - var identity2 = Path.Combine("TestProjects", "files", "swashbuckle.json"); - var error1 = Resources.FormatInvalidEmptyMetadataValue("CodeGenerator", "OpenApiReference", identity1); - var error2 = Resources.FormatInvalidEmptyMetadataValue("CodeGenerator", "OpenApiProjectReference", identity2); - var @namespace = "Console.Client"; - var inputMetadata1 = new Dictionary - { - { "ExtraMetadata", "this is extra" }, - }; - var inputMetadata2 = new Dictionary - { - { "Options", "-quiet" }, - { "SourceProject", "ConsoleProject.csproj" }, - }; - - var buildEngine = new MockBuildEngine(); - var task = new GetOpenApiReferenceMetadata - { - BuildEngine = buildEngine, - Extension = ".cs", - Inputs = new[] - { - new TaskItem(identity1, inputMetadata1), - new TaskItem(identity2, inputMetadata2), - }, - Namespace = @namespace, - OutputDirectory = "obj", - }; - - // Act - var result = task.Execute(); - - // Assert - Assert.False(result); - Assert.True(task.Log.HasLoggedErrors); - Assert.Equal(2, buildEngine.Errors); - Assert.Equal(0, buildEngine.Messages); - Assert.Equal(0, buildEngine.Warnings); - Assert.Contains(error1, buildEngine.Log, StringComparison.OrdinalIgnoreCase); - Assert.Contains(error2, buildEngine.Log, StringComparison.OrdinalIgnoreCase); - } - - [Fact] - public void Execute_LogsError_IfOutputPathDuplicated() - { - // Arrange - var identity = Path.Combine("TestProjects", "files", "NSwag.json"); - var codeGenerator = "NSwagCSharp"; - var error = Resources.FormatDuplicateFileOutputPaths(Path.Combine("obj", "NSwagClient.cs")); - var @namespace = "Console.Client"; - var inputMetadata1 = new Dictionary - { - { "CodeGenerator", codeGenerator }, - { "ExtraMetadata", "this is extra" }, - }; - var inputMetadata2 = new Dictionary - { - { "CodeGenerator", codeGenerator }, - { "Options", "-quiet" }, - }; - - var buildEngine = new MockBuildEngine(); - var task = new GetOpenApiReferenceMetadata - { - BuildEngine = buildEngine, - Extension = ".cs", - Inputs = new[] - { - new TaskItem(identity, inputMetadata1), - new TaskItem(identity, inputMetadata2), - }, - Namespace = @namespace, - OutputDirectory = "obj", - }; - - // Act - var result = task.Execute(); - - // Assert - Assert.False(result); - Assert.True(task.Log.HasLoggedErrors); - Assert.Equal(1, buildEngine.Errors); - Assert.Equal(0, buildEngine.Messages); - Assert.Equal(0, buildEngine.Warnings); - Assert.Contains(error, buildEngine.Log, StringComparison.OrdinalIgnoreCase); - } - - [Fact] - public void Execute_SetsClassName_BasedOnOutputPath() - { - // Arrange - var identity = Path.Combine("TestProjects", "files", "NSwag.json"); - var className = "ThisIsClassy"; - var @namespace = "Console.Client"; - var outputPath = $"{className}.cs"; - var expectedOutputPath = Path.Combine("bin", outputPath); - var inputMetadata = new Dictionary - { - { "CodeGenerator", "NSwagCSharp" }, - { "OutputPath", outputPath } - }; - - var task = new GetOpenApiReferenceMetadata - { - Extension = ".cs", - Inputs = new[] { new TaskItem(identity, inputMetadata) }, - Namespace = @namespace, - OutputDirectory = "bin", - }; - - var expectedMetadata = new SortedDictionary(StringComparer.Ordinal) - { - { "ClassName", className }, - { "CodeGenerator", "NSwagCSharp" }, - { "FirstForGenerator", "true" }, - { "Namespace", @namespace }, - { "OriginalItemSpec", identity }, - { "OutputPath", expectedOutputPath }, - { - "SerializedMetadata", - $"Identity={identity}|FirstForGenerator=true|" + - $"CodeGenerator=NSwagCSharp|OutputPath={expectedOutputPath}|Namespace={@namespace}|" + - $"OriginalItemSpec={identity}|ClassName={className}" - }, - }; - - // Act - var result = task.Execute(); - - // Assert - Assert.True(result); - Assert.False(task.Log.HasLoggedErrors); - var output = Assert.Single(task.Outputs); - Assert.Equal(identity, output.ItemSpec); - var metadata = Assert.IsAssignableFrom>(output.CloneCustomMetadata()); - - // The dictionary CloneCustomMetadata returns doesn't provide a useful KeyValuePair enumerator. - var orderedMetadata = new SortedDictionary(StringComparer.Ordinal); - foreach (var key in metadata.Keys) - { - orderedMetadata.Add(key, metadata[key]); - } - - Assert.Equal(expectedMetadata, orderedMetadata); - } - - [Theory] - [InlineData("aa-bb.cs", "aa_bb")] - [InlineData("aa.bb.cc.ts", "aa_bb_cc")] - [InlineData("aa\u20DF\u20DF.tsx", "aa__")] // UnicodeCategory.EnclosingMark (combining enclosing diamond) - [InlineData("aa\u2005bb\u2005cc.cs", "aa_bb_cc")] // UnicodeCategory.SpaceSeparator (four-per-em space) - [InlineData("aa\u0096\u0096bb.cs", "aa__bb")] // UnicodeCategory.Control (start of guarded area) - [InlineData("aa\uFF1C\uFF1C\uFF1Cbb.cs", "aa___bb")] // UnicodeCategory.MathSymbol (fullwidth less-than sign) - public void Execute_SetsClassName_BasedOnSanitizedOutputPath(string outputPath, string className) - { - // Arrange - var identity = Path.Combine("TestProjects", "files", "NSwag.json"); - var @namespace = "Console.Client"; - var expectedOutputPath = Path.Combine("bin", outputPath); - var inputMetadata = new Dictionary - { - { "CodeGenerator", "NSwagCSharp" }, - { "OutputPath", outputPath } - }; - - var task = new GetOpenApiReferenceMetadata - { - Extension = ".cs", - Inputs = new[] { new TaskItem(identity, inputMetadata) }, - Namespace = @namespace, - OutputDirectory = "bin", - }; - - var expectedMetadata = new SortedDictionary(StringComparer.Ordinal) - { - { "ClassName", className }, - { "CodeGenerator", "NSwagCSharp" }, - { "FirstForGenerator", "true" }, - { "Namespace", @namespace }, - { "OriginalItemSpec", identity }, - { "OutputPath", expectedOutputPath }, - { - "SerializedMetadata", - $"Identity={identity}|FirstForGenerator=true|" + - $"CodeGenerator=NSwagCSharp|OutputPath={expectedOutputPath}|Namespace={@namespace}|" + - $"OriginalItemSpec={identity}|ClassName={className}" - }, - }; - - // Act - var result = task.Execute(); - - // Assert - Assert.True(result); - Assert.False(task.Log.HasLoggedErrors); - var output = Assert.Single(task.Outputs); - Assert.Equal(identity, output.ItemSpec); - var metadata = Assert.IsAssignableFrom>(output.CloneCustomMetadata()); - - // The dictionary CloneCustomMetadata returns doesn't provide a useful KeyValuePair enumerator. - var orderedMetadata = new SortedDictionary(StringComparer.Ordinal); - foreach (var key in metadata.Keys) - { - orderedMetadata.Add(key, metadata[key]); - } - - Assert.Equal(expectedMetadata, orderedMetadata); - } - - [Fact] - public void Execute_SetsFirstForGenerator_UsesCorrectExtension() - { - // Arrange - var identity12 = Path.Combine("TestProjects", "files", "NSwag.json"); - var identity3 = Path.Combine("TestProjects", "files", "swashbuckle.json"); - var className12 = "NSwagClient"; - var className3 = "swashbuckleClient"; - var codeGenerator13 = "NSwagCSharp"; - var codeGenerator2 = "NSwagTypeScript"; - var inputMetadata1 = new Dictionary { { "CodeGenerator", codeGenerator13 } }; - var inputMetadata2 = new Dictionary { { "CodeGenerator", codeGenerator2 } }; - var inputMetadata3 = new Dictionary { { "CodeGenerator", codeGenerator13 } }; - var @namespace = "Console.Client"; - var outputPath1 = Path.Combine("obj", $"{className12}.cs"); - var outputPath2 = Path.Combine("obj", $"{className12}.ts"); - var outputPath3 = Path.Combine("obj", $"{className3}.cs"); - - var task = new GetOpenApiReferenceMetadata - { - Extension = ".cs", - Inputs = new[] - { - new TaskItem(identity12, inputMetadata1), - new TaskItem(identity12, inputMetadata2), - new TaskItem(identity3, inputMetadata3), - }, - Namespace = @namespace, - OutputDirectory = "obj", - }; - - var expectedMetadata1 = new SortedDictionary(StringComparer.Ordinal) - { - { "ClassName", className12 }, - { "CodeGenerator", codeGenerator13 }, - { "FirstForGenerator", "true" }, - { "Namespace", @namespace }, - { "OriginalItemSpec", identity12 }, - { "OutputPath", outputPath1 }, - { - "SerializedMetadata", - $"Identity={identity12}|FirstForGenerator=true|" + - $"CodeGenerator={codeGenerator13}|OutputPath={outputPath1}|Namespace={@namespace}|" + - $"OriginalItemSpec={identity12}|ClassName={className12}" - }, - }; - var expectedMetadata2 = new SortedDictionary(StringComparer.Ordinal) - { - { "ClassName", className12 }, - { "CodeGenerator", codeGenerator2 }, - { "FirstForGenerator", "true" }, - { "Namespace", @namespace }, - { "OriginalItemSpec", identity12 }, - { "OutputPath", outputPath2 }, - { - "SerializedMetadata", - $"Identity={identity12}|FirstForGenerator=true|" + - $"CodeGenerator={codeGenerator2}|OutputPath={outputPath2}|Namespace={@namespace}|" + - $"OriginalItemSpec={identity12}|ClassName={className12}" - }, - }; - var expectedMetadata3 = new SortedDictionary(StringComparer.Ordinal) - { - { "ClassName", className3 }, - { "CodeGenerator", codeGenerator13 }, - { "FirstForGenerator", "false" }, - { "Namespace", @namespace }, - { "OriginalItemSpec", identity3 }, - { "OutputPath", outputPath3 }, - { - "SerializedMetadata", - $"Identity={identity3}|FirstForGenerator=false|" + - $"CodeGenerator={codeGenerator13}|OutputPath={outputPath3}|Namespace={@namespace}|" + - $"OriginalItemSpec={identity3}|ClassName={className3}" - }, - }; - - // Act - var result = task.Execute(); - - // Assert - Assert.True(result); - Assert.False(task.Log.HasLoggedErrors); - Assert.Collection( - task.Outputs, - output => - { - Assert.Equal(identity12, output.ItemSpec); - var metadata = Assert.IsAssignableFrom>(output.CloneCustomMetadata()); - var orderedMetadata = new SortedDictionary(StringComparer.Ordinal); - foreach (var key in metadata.Keys) - { - orderedMetadata.Add(key, metadata[key]); - } - - Assert.Equal(expectedMetadata1, orderedMetadata); - }, - output => - { - Assert.Equal(identity12, output.ItemSpec); - var metadata = Assert.IsAssignableFrom>(output.CloneCustomMetadata()); - var orderedMetadata = new SortedDictionary(StringComparer.Ordinal); - foreach (var key in metadata.Keys) - { - orderedMetadata.Add(key, metadata[key]); - } - - Assert.Equal(expectedMetadata2, orderedMetadata); - }, - output => - { - Assert.Equal(identity3, output.ItemSpec); - var metadata = Assert.IsAssignableFrom>(output.CloneCustomMetadata()); - var orderedMetadata = new SortedDictionary(StringComparer.Ordinal); - foreach (var key in metadata.Keys) - { - orderedMetadata.Add(key, metadata[key]); - } - - Assert.Equal(expectedMetadata3, orderedMetadata); - }); - } -} diff --git a/src/Tools/Extensions.ApiDescription.Client/test/MetadataSerializerTest.cs b/src/Tools/Extensions.ApiDescription.Client/test/MetadataSerializerTest.cs deleted file mode 100644 index c12361e719cc..000000000000 --- a/src/Tools/Extensions.ApiDescription.Client/test/MetadataSerializerTest.cs +++ /dev/null @@ -1,313 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Collections.Generic; -using Microsoft.Build.Framework; -using Microsoft.Build.Utilities; -using Moq; -using Xunit; - -namespace Microsoft.Extensions.ApiDescription.Client; - -// ItemSpec values always have '\\' converted to '/' on input when running on non-Windows. It is not possible to -// retrieve the original (unconverted) item spec value. In other respects, item spec values are treated identically -// to custom metadata values. -// -// ITaskItem members aka the implicitly-implemented methods and properties in TaskItem expect _escaped_ values on -// input and return _literal_ values. This includes TaskItem constructors and CloneCustomMetadata() (which returns -// a new dictionary containing literal values). TaskItem stores all values in their escaped form. -// -// Added ITaskItem2 members e.g. CloneCustomMetadataEscaped(), GetMetadataValueEscaped(...) and -// EvaluatedIncludeEscaped return escaped values. Of all TaskItem methods, only SetMetadataValueLiteral(...) -// accepts a literal input value. -// -// Metadata names are never escaped. -// -// MetadataSerializer expects literal values on input. -public class MetadataSerializerTest -{ - // Maps literal to escaped values. - public static TheoryData EscapedValuesMapping { get; } = new TheoryData - { - { "No escaping necessary for =.", "No escaping necessary for =." }, - { "Value needs escaping? (yes)", "Value needs escaping%3f %28yes%29" }, - { "$ comes earlier; @ comes later.", "%24 comes earlier%3b %40 comes later." }, - { - "A '%' *character* needs escaping %-escaping.", - "A %27%25%27 %2acharacter%2a needs escaping %25-escaping." - }, - }; - - public static TheoryData EscapedValues - { - get - { - var result = new TheoryData(); - foreach (var entry in EscapedValuesMapping) - { - result.Add((string)entry[1]); - } - - return result; - } - } - - public static TheoryData LiteralValues - { - get - { - var result = new TheoryData(); - foreach (var entry in EscapedValuesMapping) - { - result.Add((string)entry[0]); - } - - return result; - } - } - - [Theory] - [MemberData(nameof(LiteralValues))] - public void SetMetadata_UpdatesTaskAsExpected(string value) - { - // Arrange - var item = new TaskItem("My Identity"); - var key = "My key"; - - // Act - MetadataSerializer.SetMetadata(item, key, value); - - // Assert - Assert.Equal(value, item.GetMetadata(key)); - } - - [Theory] - [MemberData(nameof(EscapedValuesMapping))] - public void SetMetadata_UpdatesTaskAsExpected_WithLegacyItem(string value, string escapedValue) - { - // Arrange - var item = new Mock(MockBehavior.Strict); - var key = "My key"; - item.Setup(i => i.SetMetadata(key, escapedValue)).Verifiable(); - - // Act - MetadataSerializer.SetMetadata(item.Object, key, value); - - // Assert - item.Verify(i => i.SetMetadata(key, escapedValue), Times.Once); - } - - [Fact] - public void DeserializeMetadata_ReturnsExpectedTask() - { - // Arrange - var identity = "../files/azureMonitor.json"; - var input = $"Identity={identity}|ClassName=azureMonitorClient|" + - "CodeGenerator=NSwagCSharp|FirstForGenerator=true|Namespace=ConsoleClient|" + - "Options=|OriginalItemSpec=../files/azureMonitor.json|" + - "OutputPath=C:\\dd\\dnx\\AspNetCore\\artifacts\\obj\\ConsoleClient\\azureMonitorClient.cs"; - - var expectedMetadata = new SortedDictionary(StringComparer.Ordinal) - { - { "ClassName", "azureMonitorClient" }, - { "CodeGenerator", "NSwagCSharp" }, - { "FirstForGenerator", "true" }, - { "Namespace", "ConsoleClient" }, - { "Options", "" }, - { "OriginalItemSpec", identity }, - { "OutputPath", "C:\\dd\\dnx\\AspNetCore\\artifacts\\obj\\ConsoleClient\\azureMonitorClient.cs" }, - }; - - // Act - var item = MetadataSerializer.DeserializeMetadata(input); - - // Assert - Assert.Equal(identity, item.ItemSpec); - var metadata = Assert.IsAssignableFrom>(item.CloneCustomMetadata()); - - // The dictionary CloneCustomMetadata returns doesn't provide a useful KeyValuePair enumerator. - var orderedMetadata = new SortedDictionary(StringComparer.Ordinal); - foreach (var key in metadata.Keys) - { - orderedMetadata.Add(key, metadata[key]); - } - - Assert.Equal(expectedMetadata, orderedMetadata); - - } - - [Theory] - [MemberData(nameof(EscapedValuesMapping))] - public void DeserializeMetadata_ReturnsExpectedTask_WhenEscaping(string value, string escapedValue) - { - // Arrange - var identity = "../files/azureMonitor.json"; - var input = $"Identity={identity}|Value={escapedValue}"; - - // Act - var item = MetadataSerializer.DeserializeMetadata(input); - - // Assert - Assert.Equal(identity, item.ItemSpec); - Assert.Equal(value, item.GetMetadata("Value")); - } - - [Theory] - [MemberData(nameof(EscapedValuesMapping))] - public void DeserializeMetadata_ReturnsExpectedTask_WhenEscapingIdentity(string value, string escapedValue) - { - // Arrange - var input = $"Identity={escapedValue}|Value=a value"; - - // Act - var item = MetadataSerializer.DeserializeMetadata(input); - - // Assert - Assert.Equal(value, item.ItemSpec); - Assert.Equal("a value", item.GetMetadata("Value")); - } - - [Fact] - public void SerializeMetadata_ReturnsExpectedString() - { - // Arrange - var identity = "../files/azureMonitor.json"; - var metadata = new SortedDictionary(StringComparer.Ordinal) - { - { "ClassName", "azureMonitorClient" }, - { "CodeGenerator", "NSwagCSharp" }, - { "FirstForGenerator", "true" }, - { "Namespace", "ConsoleClient" }, - { "Options", "" }, - { "OriginalItemSpec", identity }, - { "OutputPath", "C:\\dd\\dnx\\AspNetCore\\artifacts\\obj\\ConsoleClient\\azureMonitorClient.cs" }, - }; - - var input = new TaskItem(identity, metadata); - var expectedResult = $"Identity={identity}|FirstForGenerator=true|" + - "Options=|CodeGenerator=NSwagCSharp|" + - "OutputPath=C:\\dd\\dnx\\AspNetCore\\artifacts\\obj\\ConsoleClient\\azureMonitorClient.cs|" + - "Namespace=ConsoleClient|OriginalItemSpec=../files/azureMonitor.json|ClassName=azureMonitorClient"; - - // Act - var result = MetadataSerializer.SerializeMetadata(input); - - // Assert - Assert.Equal(expectedResult, result); - } - - [Theory] - [MemberData(nameof(EscapedValues))] - public void SerializeMetadata_ReturnsExpectedString_WhenEscaping(string escapedValue) - { - // Arrange - var identity = "../files/azureMonitor.json"; - var expectedResult = $"Identity={identity}|Value={escapedValue}"; - var metadata = new SortedDictionary(StringComparer.Ordinal) { { "Value", escapedValue } }; - var input = new TaskItem(identity, metadata); - - // Act - var result = MetadataSerializer.SerializeMetadata(input); - - // Assert - Assert.Equal(expectedResult, result); - } - - [Theory] - [MemberData(nameof(EscapedValues))] - public void SerializeMetadata_ReturnsExpectedString_WhenEscapingIdentity(string escapedValue) - { - // Arrange - var metadata = new SortedDictionary(StringComparer.Ordinal) { { "Value", "a value" } }; - var expectedResult = $"Identity={escapedValue}|Value=a value"; - var input = new TaskItem(escapedValue, metadata); - - // Act - var result = MetadataSerializer.SerializeMetadata(input); - - // Assert - Assert.Equal(expectedResult, result); - } - - [Fact] - public void SerializeMetadata_ReturnsExpectedString_WithLegacyItem() - { - // Arrange - var identity = "../files/azureMonitor.json"; - var metadata = new SortedDictionary(StringComparer.Ordinal) - { - { "ClassName", "azureMonitorClient" }, - { "CodeGenerator", "NSwagCSharp" }, - { "FirstForGenerator", "true" }, - { "Namespace", "ConsoleClient" }, - { "Options", "" }, - { "OriginalItemSpec", identity }, - { "OutputPath", "C:\\dd\\dnx\\AspNetCore\\artifacts\\obj\\ConsoleClient\\azureMonitorClient.cs" }, - }; - - var input = new Mock(MockBehavior.Strict); - input.SetupGet(i => i.ItemSpec).Returns(identity).Verifiable(); - input.Setup(i => i.CloneCustomMetadata()).Returns(metadata).Verifiable(); - - var expectedResult = $"Identity={identity}|ClassName=azureMonitorClient|" + - "CodeGenerator=NSwagCSharp|FirstForGenerator=true|Namespace=ConsoleClient|" + - "Options=|OriginalItemSpec=../files/azureMonitor.json|" + - "OutputPath=C:\\dd\\dnx\\AspNetCore\\artifacts\\obj\\ConsoleClient\\azureMonitorClient.cs"; - - // Act - var result = MetadataSerializer.SerializeMetadata(input.Object); - - // Assert - Assert.Equal(expectedResult, result); - input.VerifyGet(i => i.ItemSpec, Times.Once); - input.Verify(i => i.CloneCustomMetadata(), Times.Once); - } - - [Theory] - [MemberData(nameof(EscapedValuesMapping))] - public void SerializeMetadata_ReturnsExpectedString_WithLegacyItem_WhenEscaping( - string value, - string escapedValue) - { - // Arrange - var identity = "../files/azureMonitor.json"; - var metadata = new SortedDictionary(StringComparer.Ordinal) { { "Value", value } }; - var input = new Mock(MockBehavior.Strict); - input.SetupGet(i => i.ItemSpec).Returns(identity).Verifiable(); - input.Setup(i => i.CloneCustomMetadata()).Returns(metadata).Verifiable(); - - var expectedResult = $"Identity={identity}|Value={escapedValue}"; - - // Act - var result = MetadataSerializer.SerializeMetadata(input.Object); - - // Assert - Assert.Equal(expectedResult, result); - input.VerifyGet(i => i.ItemSpec, Times.Once); - input.Verify(i => i.CloneCustomMetadata(), Times.Once); - } - - [Theory] - [MemberData(nameof(EscapedValuesMapping))] - public void SerializeMetadata_ReturnsExpectedString_WithLegacyItem_WhenEscapingIdentity( - string value, - string escapedValue) - { - // Arrange - var metadata = new SortedDictionary(StringComparer.Ordinal) { { "Value", "a value" } }; - var input = new Mock(MockBehavior.Strict); - input.SetupGet(i => i.ItemSpec).Returns(value).Verifiable(); - input.Setup(i => i.CloneCustomMetadata()).Returns(metadata).Verifiable(); - - var expectedResult = $"Identity={escapedValue}|Value=a value"; - - // Act - var result = MetadataSerializer.SerializeMetadata(input.Object); - - // Assert - Assert.Equal(expectedResult, result); - input.VerifyGet(i => i.ItemSpec, Times.Once); - input.Verify(i => i.CloneCustomMetadata(), Times.Once); - } -} diff --git a/src/Tools/Extensions.ApiDescription.Client/test/Microsoft.Extensions.ApiDescription.Client.Tests.csproj b/src/Tools/Extensions.ApiDescription.Client/test/Microsoft.Extensions.ApiDescription.Client.Tests.csproj deleted file mode 100644 index 1ccce0e63658..000000000000 --- a/src/Tools/Extensions.ApiDescription.Client/test/Microsoft.Extensions.ApiDescription.Client.Tests.csproj +++ /dev/null @@ -1,25 +0,0 @@ - - - $(DefaultNetCoreTargetFramework) - $(DefaultItemExcludes);TestProjects\**\* - ApiDescriptionClientTests - - - - - <_Parameter1>TargetFramework - <_Parameter2>$(TargetFramework) - - - - - - - - - - - - - diff --git a/src/Tools/Extensions.ApiDescription.Client/test/MockBuildEngine.cs b/src/Tools/Extensions.ApiDescription.Client/test/MockBuildEngine.cs deleted file mode 100644 index 9c003ad5632d..000000000000 --- a/src/Tools/Extensions.ApiDescription.Client/test/MockBuildEngine.cs +++ /dev/null @@ -1,101 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections; -using System.Collections.Generic; -using System.Text; -using Microsoft.Build.Framework; - -// Inspired by https://github.com/microsoft/msbuild/blob/master/src/Utilities.UnitTests/MockEngine.cs -namespace Microsoft.Extensions.ApiDescription.Client; - -internal sealed class MockBuildEngine : IBuildEngine3 -{ - private readonly StringBuilder _log = new StringBuilder(); - - public bool IsRunningMultipleNodes => false; - - public bool ContinueOnError => false; - - public string ProjectFileOfTaskNode => string.Empty; - - public int LineNumberOfTaskNode => 0; - - public int ColumnNumberOfTaskNode => 0; - - internal MessageImportance MinimumMessageImportance { get; set; } = MessageImportance.Low; - - internal int Messages { set; get; } - - internal int Warnings { set; get; } - - internal int Errors { set; get; } - - internal string Log => _log.ToString(); - - public bool BuildProjectFile( - string projectFileName, - string[] targetNames, - IDictionary globalProperties, - IDictionary targetOutputs) => false; - - public bool BuildProjectFile( - string projectFileName, - string[] targetNames, - IDictionary globalProperties, - IDictionary targetOutputs, - string toolsVersion) => false; - - public bool BuildProjectFilesInParallel( - string[] projectFileNames, - string[] targetNames, - IDictionary[] globalProperties, - IDictionary[] targetOutputsPerProject, - string[] toolsVersion, - bool useResultsCache, - bool unloadProjectsOnCompletion) => false; - - public BuildEngineResult BuildProjectFilesInParallel( - string[] projectFileNames, - string[] targetNames, - IDictionary[] globalProperties, - IList[] undefineProperties, - string[] toolsVersion, - bool includeTargetOutputs) => new BuildEngineResult(false, null); - - public void LogErrorEvent(BuildErrorEventArgs eventArgs) - { - _log.AppendLine(eventArgs.Message); - Errors++; - } - - public void LogWarningEvent(BuildWarningEventArgs eventArgs) - { - _log.AppendLine(eventArgs.Message); - Warnings++; - } - - public void LogCustomEvent(CustomBuildEventArgs eventArgs) - { - _log.AppendLine(eventArgs.Message); - } - - public void LogMessageEvent(BuildMessageEventArgs eventArgs) - { - // Only record the message if it is above the minimum importance. MessageImportance enum has higher values - // for lower importance. - if (eventArgs.Importance <= MinimumMessageImportance) - { - _log.AppendLine(eventArgs.Message); - Messages++; - } - } - - public void Reacquire() - { - } - - public void Yield() - { - } -} diff --git a/src/Tools/Extensions.ApiDescription.Client/test/TargetTest.cs b/src/Tools/Extensions.ApiDescription.Client/test/TargetTest.cs deleted file mode 100644 index 8ebb5794e595..000000000000 --- a/src/Tools/Extensions.ApiDescription.Client/test/TargetTest.cs +++ /dev/null @@ -1,506 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.IO; -using System.Linq; -using System.Reflection; -using Microsoft.AspNetCore.Internal; -using Microsoft.Extensions.CommandLineUtils; -using Microsoft.Extensions.Tools.Internal; -using Xunit.Abstractions; - -namespace Microsoft.Extensions.ApiDescription.Client; - -public class TargetTest : IDisposable -{ - private static Assembly _assembly = typeof(TargetTest).Assembly; - private static string _assemblyLocation = Path.GetDirectoryName(_assembly.Location); - private static string _targetFramework = _assembly.GetCustomAttributes() - .Single(m => m.Key == "TargetFramework") - .Value; - - private ITestOutputHelper _output; - private TemporaryDirectory _temporaryDirectory; - - public TargetTest(ITestOutputHelper output) - { - _output = output; - _temporaryDirectory = new TemporaryDirectory(); - - var build = _temporaryDirectory.SubDir("build"); - var files = _temporaryDirectory.SubDir("files"); - var tasks = _temporaryDirectory.SubDir("tasks").SubDir("netstandard2.0"); - _temporaryDirectory.Create(); - - // Populate temporary build folder. - var directory = new DirectoryInfo(Path.Combine(_assemblyLocation, "build")); - foreach (var file in directory.GetFiles()) - { - file.CopyTo(Path.Combine(build.Root, file.Name), overwrite: true); - } - directory = new DirectoryInfo(Path.Combine(_assemblyLocation, "TestProjects", "build")); - foreach (var file in directory.GetFiles()) - { - file.CopyTo(Path.Combine(build.Root, file.Name), overwrite: true); - } - - // Populate temporary files folder. - directory = new DirectoryInfo(Path.Combine(_assemblyLocation, "TestProjects", "files")); - foreach (var file in directory.GetFiles()) - { - file.CopyTo(Path.Combine(files.Root, file.Name), overwrite: true); - } - - // Populate temporary tasks folder. - directory = new DirectoryInfo(_assemblyLocation); - foreach (var file in directory.GetFiles("Microsoft.Extensions.ApiDescription.Client.???")) - { - file.CopyTo(Path.Combine(tasks.Root, file.Name), overwrite: true); - } - } - - [Fact] - public async Task AddsExpectedItems() - { - var project = new TemporaryOpenApiProject("test", _temporaryDirectory, "Microsoft.NET.Sdk") - .WithTargetFrameworks(_targetFramework) - .WithItem(new TemporaryOpenApiProject.ItemSpec - { - Include = "files/azureMonitor.json", - }); - _temporaryDirectory.WithCSharpProject(project); - project.Create(); - - using var process = await RunBuild(); - - Assert.Equal(0, process.ExitCode); - Assert.Empty(process.Error); - Assert.Contains($"Compile: {Path.Combine("obj", "azureMonitorClient.cs")}", process.Output); - Assert.Contains($"FileWrites: {Path.Combine("obj", "azureMonitorClient.cs")}", process.Output); - Assert.DoesNotContain("TypeScriptCompile:", process.Output); - } - - [Fact] - public async Task AddsExpectedItems_WithCodeGenerator() - { - var project = new TemporaryOpenApiProject("test", _temporaryDirectory, "Microsoft.NET.Sdk") - .WithTargetFrameworks(_targetFramework) - .WithItem(new TemporaryOpenApiProject.ItemSpec - { - Include = "files/azureMonitor.json", - CodeGenerator = "NSwagTypeScript", - }); - _temporaryDirectory.WithCSharpProject(project); - project.Create(); - - using var process = await RunBuild(); - - Assert.Equal(0, process.ExitCode); - Assert.Empty(process.Error); - Assert.DoesNotContain(" Compile:", process.Output); - Assert.Contains($"FileWrites: {Path.Combine("obj", "azureMonitorClient.ts")}", process.Output); - Assert.Contains($"TypeScriptCompile: {Path.Combine("obj", "azureMonitorClient.ts")}", process.Output); - } - - [Fact] - public async Task AddsExpectedItems_WithMultipleFiles() - { - var project = new TemporaryOpenApiProject("test", _temporaryDirectory, "Microsoft.NET.Sdk") - .WithTargetFrameworks(_targetFramework) - .WithItem(new TemporaryOpenApiProject.ItemSpec - { - Include = "files/azureMonitor.json;files/NSwag.json;files/swashbuckle.json", - }); - _temporaryDirectory.WithCSharpProject(project); - project.Create(); - - using var process = await RunBuild(); - - Assert.Equal(0, process.ExitCode); - Assert.Empty(process.Error); - Assert.Contains($"Compile: {Path.Combine("obj", "azureMonitorClient.cs")}", process.Output); - Assert.Contains($"Compile: {Path.Combine("obj", "NSwagClient.cs")}", process.Output); - Assert.Contains($"Compile: {Path.Combine("obj", "swashbuckleClient.cs")}", process.Output); - Assert.Contains($"FileWrites: {Path.Combine("obj", "azureMonitorClient.cs")}", process.Output); - Assert.Contains($"FileWrites: {Path.Combine("obj", "NSwagClient.cs")}", process.Output); - Assert.Contains($"FileWrites: {Path.Combine("obj", "swashbuckleClient.cs")}", process.Output); - Assert.DoesNotContain("TypeScriptCompile:", process.Output); - } - - [Fact] - public async Task AddsExpectedItems_WithMultipleFilesFromGenerator() - { - var project = new TemporaryOpenApiProject("test", _temporaryDirectory, "Microsoft.NET.Sdk") - .WithTargetFrameworks(_targetFramework) - .WithItem(new TemporaryOpenApiProject.ItemSpec - { - Include = "files/azureMonitor.json", - CodeGenerator = "CustomCSharp", - }); - _temporaryDirectory.WithCSharpProject(project); - project.Create(); - - using var process = await RunBuild(); - - Assert.Equal(0, process.ExitCode); - Assert.Empty(process.Error); - Assert.Contains($"Compile: {Path.Combine("obj", "azureMonitorClient.cs", "Generated1.cs")}", process.Output); - Assert.Contains($"Compile: {Path.Combine("obj", "azureMonitorClient.cs", "Generated2.cs")}", process.Output); - Assert.Contains( - $"FileWrites: {Path.Combine("obj", "azureMonitorClient.cs", "Generated1.cs")}", - process.Output); - Assert.Contains( - $"FileWrites: {Path.Combine("obj", "azureMonitorClient.cs", "Generated2.cs")}", - process.Output); - Assert.DoesNotContain("TypeScriptCompile:", process.Output); - } - - [Fact] - public async Task ExecutesGeneratorTarget() - { - var project = new TemporaryOpenApiProject("test", _temporaryDirectory, "Microsoft.NET.Sdk") - .WithTargetFrameworks(_targetFramework) - .WithItem(new TemporaryOpenApiProject.ItemSpec - { - Include = "files/azureMonitor.json", - }); - _temporaryDirectory.WithCSharpProject(project); - project.Create(); - - using var process = await RunBuild(); - - Assert.Equal(0, process.ExitCode); - Assert.Empty(process.Error); - Assert.Contains( - "GenerateNSwagCSharp " + - $"{Path.Combine(_temporaryDirectory.Root, "files", "azureMonitor.json")} " + - "Class: 'test.azureMonitorClient' FirstForGenerator: 'true' " + - $"Options: '' OutputPath: '{Path.Combine("obj", "azureMonitorClient.cs")}'", - process.Output); - } - - [Fact] - public async Task ExecutesGeneratorTarget_WithOpenApiGenerateCodeOptions() - { - var project = new TemporaryOpenApiProject("test", _temporaryDirectory, "Microsoft.NET.Sdk") - .WithTargetFrameworks(_targetFramework) - .WithProperty("OpenApiGenerateCodeOptions", "--an-option") - .WithItem(new TemporaryOpenApiProject.ItemSpec - { - Include = "files/azureMonitor.json", - }); - _temporaryDirectory.WithCSharpProject(project); - project.Create(); - - using var process = await RunBuild(); - - Assert.Equal(0, process.ExitCode); - Assert.Empty(process.Error); - Assert.Contains( - "GenerateNSwagCSharp " + - $"{Path.Combine(_temporaryDirectory.Root, "files", "azureMonitor.json")} " + - "Class: 'test.azureMonitorClient' FirstForGenerator: 'true' " + - $"Options: '--an-option' OutputPath: '{Path.Combine("obj", "azureMonitorClient.cs")}'", - process.Output); - } - - [Fact] - public async Task ExecutesGeneratorTarget_WithOpenApiCodeDirectory() - { - var project = new TemporaryOpenApiProject("test", _temporaryDirectory, "Microsoft.NET.Sdk") - .WithTargetFrameworks(_targetFramework) - .WithProperty("OpenApiCodeDirectory", "generated") - .WithItem(new TemporaryOpenApiProject.ItemSpec - { - Include = "files/azureMonitor.json", - }); - _temporaryDirectory.WithCSharpProject(project); - project.Create(); - - using var process = await RunBuild(); - - Assert.Equal(0, process.ExitCode); - Assert.Empty(process.Error); - Assert.Contains( - "GenerateNSwagCSharp " + - $"{Path.Combine(_temporaryDirectory.Root, "files", "azureMonitor.json")} " + - "Class: 'test.azureMonitorClient' FirstForGenerator: 'true' " + - $"Options: '' OutputPath: '{Path.Combine("generated", "azureMonitorClient.cs")}'", - process.Output); - } - - [Fact] - public async Task ExecutesGeneratorTarget_WithClassName() - { - var project = new TemporaryOpenApiProject("test", _temporaryDirectory, "Microsoft.NET.Sdk") - .WithTargetFrameworks(_targetFramework) - .WithItem(new TemporaryOpenApiProject.ItemSpec - { - Include = "files/azureMonitor.json", - ClassName = "AzureMonitor" - }); - _temporaryDirectory.WithCSharpProject(project); - project.Create(); - - using var process = await RunBuild(); - - Assert.Equal(0, process.ExitCode); - Assert.Empty(process.Error); - - // Note ClassName does **not** override OutputPath. - Assert.Contains( - "GenerateNSwagCSharp " + - $"{Path.Combine(_temporaryDirectory.Root, "files", "azureMonitor.json")} " + - "Class: 'test.AzureMonitor' FirstForGenerator: 'true' " + - $"Options: '' OutputPath: '{Path.Combine("obj", "azureMonitorClient.cs")}'", - process.Output); - } - - [Fact] - public async Task ExecutesGeneratorTarget_WithCodeGenerator() - { - var project = new TemporaryOpenApiProject("test", _temporaryDirectory, "Microsoft.NET.Sdk") - .WithTargetFrameworks(_targetFramework) - .WithItem(new TemporaryOpenApiProject.ItemSpec - { - Include = "files/azureMonitor.json", - CodeGenerator = "NSwagTypeScript" - }); - _temporaryDirectory.WithCSharpProject(project); - project.Create(); - - using var process = await RunBuild(); - - Assert.Equal(0, process.ExitCode); - Assert.Empty(process.Error); - Assert.Contains( - "GenerateNSwagTypeScript " + - $"{Path.Combine(_temporaryDirectory.Root, "files", "azureMonitor.json")} " + - "Class: 'test.azureMonitorClient' FirstForGenerator: 'true' " + - $"Options: '' OutputPath: '{Path.Combine("obj", "azureMonitorClient.ts")}'", - process.Output); - } - - [Fact] - public async Task ExecutesGeneratorTarget_WithNamespace() - { - var project = new TemporaryOpenApiProject("test", _temporaryDirectory, "Microsoft.NET.Sdk") - .WithTargetFrameworks(_targetFramework) - .WithItem(new TemporaryOpenApiProject.ItemSpec - { - Include = "files/azureMonitor.json", - Namespace = "SomeNamespace" - }); - _temporaryDirectory.WithCSharpProject(project); - project.Create(); - - using var process = await RunBuild(); - - Assert.Equal(0, process.ExitCode); - Assert.Empty(process.Error); - Assert.Contains( - "GenerateNSwagCSharp " + - $"{Path.Combine(_temporaryDirectory.Root, "files", "azureMonitor.json")} " + - "Class: 'SomeNamespace.azureMonitorClient' FirstForGenerator: 'true' " + - $"Options: '' OutputPath: '{Path.Combine("obj", "azureMonitorClient.cs")}'", - process.Output); - } - - [Fact] - public async Task ExecutesGeneratorTarget_WithOptions() - { - var project = new TemporaryOpenApiProject("test", _temporaryDirectory, "Microsoft.NET.Sdk") - .WithTargetFrameworks(_targetFramework) - .WithItem(new TemporaryOpenApiProject.ItemSpec - { - Include = "files/azureMonitor.json", - Options = "--an-option" - }); - _temporaryDirectory.WithCSharpProject(project); - project.Create(); - - using var process = await RunBuild(); - - Assert.Equal(0, process.ExitCode); - Assert.Empty(process.Error); - Assert.Contains( - "GenerateNSwagCSharp " + - $"{Path.Combine(_temporaryDirectory.Root, "files", "azureMonitor.json")} " + - "Class: 'test.azureMonitorClient' FirstForGenerator: 'true' " + - $"Options: '--an-option' OutputPath: '{Path.Combine("obj", "azureMonitorClient.cs")}'", - process.Output); - } - - [Fact] - public async Task ExecutesGeneratorTarget_WithOutputPath() - { - var project = new TemporaryOpenApiProject("test", _temporaryDirectory, "Microsoft.NET.Sdk") - .WithTargetFrameworks(_targetFramework) - .WithItem(new TemporaryOpenApiProject.ItemSpec - { - Include = "files/azureMonitor.json", - OutputPath = "Custom.cs" - }); - _temporaryDirectory.WithCSharpProject(project); - project.Create(); - - using var process = await RunBuild(); - - Assert.Equal(0, process.ExitCode); - Assert.Empty(process.Error); - - // Note OutputPath also overrides ClassName. - Assert.Contains( - "GenerateNSwagCSharp " + - $"{Path.Combine(_temporaryDirectory.Root, "files", "azureMonitor.json")} " + - "Class: 'test.Custom' FirstForGenerator: 'true' " + - $"Options: '' OutputPath: '{Path.Combine("obj", "Custom.cs")}'", - process.Output); - } - - [Fact] - public async Task ExecutesGeneratorTarget_WithMultipleFiles() - { - var project = new TemporaryOpenApiProject("test", _temporaryDirectory, "Microsoft.NET.Sdk") - .WithTargetFrameworks(_targetFramework) - .WithItem(new TemporaryOpenApiProject.ItemSpec - { - Include = "files/azureMonitor.json;files/NSwag.json;files/swashbuckle.json", - }); - _temporaryDirectory.WithCSharpProject(project); - project.Create(); - - using var process = await RunBuild(); - - Assert.Equal(0, process.ExitCode); - Assert.Empty(process.Error); - Assert.Contains( - "GenerateNSwagCSharp " + - $"{Path.Combine(_temporaryDirectory.Root, "files", "azureMonitor.json")} " + - "Class: 'test.azureMonitorClient' FirstForGenerator: 'true' " + - $"Options: '' OutputPath: '{Path.Combine("obj", "azureMonitorClient.cs")}'", - process.Output); - Assert.Contains( - "GenerateNSwagCSharp " + - $"{Path.Combine(_temporaryDirectory.Root, "files", "NSwag.json")} " + - "Class: 'test.NSwagClient' FirstForGenerator: 'false' " + - $"Options: '' OutputPath: '{Path.Combine("obj", "NSwagClient.cs")}'", - process.Output); - Assert.Contains( - "GenerateNSwagCSharp " + - $"{Path.Combine(_temporaryDirectory.Root, "files", "swashbuckle.json")} " + - "Class: 'test.swashbuckleClient' FirstForGenerator: 'false' " + - $"Options: '' OutputPath: '{Path.Combine("obj", "swashbuckleClient.cs")}'", - process.Output); - } - - [Fact] - public async Task ExecutesGeneratorTarget_WithMultipleGenerators() - { - var project = new TemporaryOpenApiProject("test", _temporaryDirectory, "Microsoft.NET.Sdk") - .WithTargetFrameworks(_targetFramework) - .WithItem(new TemporaryOpenApiProject.ItemSpec - { - Include = "files/azureMonitor.json", - }) - .WithItem(new TemporaryOpenApiProject.ItemSpec - { - Include = "files/azureMonitor.json", - CodeGenerator = "NSwagTypeScript" - }); - _temporaryDirectory.WithCSharpProject(project); - project.Create(); - - using var process = await RunBuild(); - - Assert.Equal(0, process.ExitCode); - Assert.Empty(process.Error); - Assert.Contains( - "GenerateNSwagCSharp " + - $"{Path.Combine(_temporaryDirectory.Root, "files", "azureMonitor.json")} " + - "Class: 'test.azureMonitorClient' FirstForGenerator: 'true' " + - $"Options: '' OutputPath: '{Path.Combine("obj", "azureMonitorClient.cs")}'", - process.Output); - Assert.Contains( - "GenerateNSwagTypeScript " + - $"{Path.Combine(_temporaryDirectory.Root, "files", "azureMonitor.json")} " + - "Class: 'test.azureMonitorClient' FirstForGenerator: 'true' " + - $"Options: '' OutputPath: '{Path.Combine("obj", "azureMonitorClient.ts")}'", - process.Output); - } - - [Fact] - public async Task SkipsGeneratorTarget_InSubsequentBuilds() - { - // Arrange - var project = new TemporaryOpenApiProject("test", _temporaryDirectory, "Microsoft.NET.Sdk") - .WithTargetFrameworks(_targetFramework) - .WithProperty("OpenApiGenerateCodeOnBuild", "false") - .WithItem(new TemporaryOpenApiProject.ItemSpec - { - Include = "files/azureMonitor.json", - }); - _temporaryDirectory.WithCSharpProject(project); - project.Create(); - - // Act 1 - using var firstProcess = await RunBuild(); - - // Assert 1 aka Guards - Assert.Equal(0, firstProcess.ExitCode); - Assert.Empty(firstProcess.Error); - - // Act 2 - using var secondProcess = await RunBuild(); - - // Assert 2 - Assert.Equal(0, secondProcess.ExitCode); - Assert.Empty(secondProcess.Error); - Assert.DoesNotContain("GenerateNSwagCSharp ", secondProcess.Output); - - // Act 3 - using var thirdProcess = await RunBuild(); - - // Assert 2 - Assert.Equal(0, thirdProcess.ExitCode); - Assert.Empty(thirdProcess.Error); - Assert.DoesNotContain("GenerateNSwagCSharp ", thirdProcess.Output); - } - - [Fact] - public async Task SkipsGeneratorTarget_WithOpenApiGenerateCodeOnBuild() - { - var project = new TemporaryOpenApiProject("test", _temporaryDirectory, "Microsoft.NET.Sdk") - .WithTargetFrameworks(_targetFramework) - .WithProperty("OpenApiGenerateCodeOnBuild", "false") - .WithItem(new TemporaryOpenApiProject.ItemSpec - { - Include = "files/azureMonitor.json", - }); - _temporaryDirectory.WithCSharpProject(project); - project.Create(); - - using var process = await RunBuild(); - - Assert.Equal(0, process.ExitCode); - Assert.Empty(process.Error); - Assert.DoesNotContain("GenerateNSwagCSharp ", process.Output); - } - - public void Dispose() - { - _temporaryDirectory.Dispose(); - } - - private async Task RunBuild() - { - var process = ProcessEx.Run( - _output, - _temporaryDirectory.Root, - DotNetMuxer.MuxerPathOrDefault(), - "build"); - await process.Exited; - - return process; - } -} diff --git a/src/Tools/Extensions.ApiDescription.Client/test/TemporaryOpenApiProject.cs b/src/Tools/Extensions.ApiDescription.Client/test/TemporaryOpenApiProject.cs deleted file mode 100644 index 5e6739779928..000000000000 --- a/src/Tools/Extensions.ApiDescription.Client/test/TemporaryOpenApiProject.cs +++ /dev/null @@ -1,88 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Text; - -namespace Microsoft.Extensions.Tools.Internal; - -public class TemporaryOpenApiProject : TemporaryCSharpProject -{ - public TemporaryOpenApiProject(string name, TemporaryDirectory directory, string sdk) - : base(name, directory, sdk) - { - } - - protected override string Template => -@" - - - - {0} - - - {1} - - - - - - - - - - - -"; - - protected override void AddAdditionalAttributes(StringBuilder sb, TemporaryCSharpProject.ItemSpec item) - { - var openApiItem = item as ItemSpec; - if (openApiItem.ClassName != null) - { - sb.Append(" ClassName=\"").Append(openApiItem.ClassName).Append('"'); - } - - if (openApiItem.CodeGenerator != null) - { - sb.Append(" CodeGenerator=\"").Append(openApiItem.CodeGenerator).Append('"'); - } - - if (openApiItem.Namespace != null) - { - sb.Append(" Namespace=\"").Append(openApiItem.Namespace).Append('"'); - } - - if (openApiItem.Options != null) - { - sb.Append(" Options=\"").Append(openApiItem.Options).Append('"'); - } - - if (openApiItem.OutputPath != null) - { - sb.Append(" OutputPath=\"").Append(openApiItem.OutputPath).Append('"'); - } - } - - public new class ItemSpec : TemporaryCSharpProject.ItemSpec - { - public ItemSpec() : base() - { - Name = "OpenApiReference"; - } - - // Metadata specific to OpenApiReference items. - public string ClassName { get; set; } - - public string CodeGenerator { get; set; } - - public string Namespace { get; set; } - - public string Options { get; set; } - - public string OutputPath { get; set; } - } -} diff --git a/src/Tools/Extensions.ApiDescription.Client/test/TestProjects/build/Fakes.targets b/src/Tools/Extensions.ApiDescription.Client/test/TestProjects/build/Fakes.targets deleted file mode 100644 index 480fb5b57316..000000000000 --- a/src/Tools/Extensions.ApiDescription.Client/test/TestProjects/build/Fakes.targets +++ /dev/null @@ -1,52 +0,0 @@ - - - - - <_HeaderMetadata Include="Licensed to the .NET Foundation under one or more agreements." /> - <_HeaderMetadata Include="The .NET Foundation licenses this file to you under the MIT license." /> - - <_Metadata Include="__TargetName__" /> - <_Metadata Include="%(CurrentOpenApiReference.FullPath)" /> - <_Metadata Include="Class: '%(CurrentOpenApiReference.Namespace).%(CurrentOpenApiReference.ClassName)'" /> - <_Metadata Include="FirstForGenerator: '%(CurrentOpenApiReference.FirstForGenerator)'" /> - <_Metadata Include="Options: '%(CurrentOpenApiReference.Options)'" /> - <_Metadata Include="OutputPath: '%(CurrentOpenApiReference.OutputPath)'" /> - - - <_Message>@(_Metadata, ' ') - <_Lines>@(_HeaderMetadata -> '// %(Identity)', '%0A') - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Tools/Extensions.ApiDescription.Client/test/TestProjects/files/NSwag.json b/src/Tools/Extensions.ApiDescription.Client/test/TestProjects/files/NSwag.json deleted file mode 100644 index f8ba05b6f7ef..000000000000 --- a/src/Tools/Extensions.ApiDescription.Client/test/TestProjects/files/NSwag.json +++ /dev/null @@ -1,183 +0,0 @@ -{ - "x-generator": "NSwag v11.18.6.0 (NJsonSchema v9.10.67.0 (Newtonsoft.Json v11.0.0.0))", - "swagger": "2.0", - "info": { - "title": "My Title", - "version": "1.0.0" - }, - "host": "localhost:5000", - "schemes": [ - "http" - ], - "consumes": [ - "application/json-patch+json", - "application/json", - "text/json", - "application/*+json", - "application/xml", - "text/xml", - "application/*+xml" - ], - "produces": [ - "text/plain", - "application/json", - "text/json", - "application/xml", - "text/xml" - ], - "paths": { - "/api/Values/matches": { - "post": { - "tags": [ - "Values" - ], - "operationId": "Values_Matches", - "consumes": [ - "application/json-patch+json", - "application/json", - "text/json", - "application/*+json", - "application/xml", - "text/xml", - "application/*+xml" - ], - "parameters": [ - { - "name": "possibilities", - "in": "body", - "required": true, - "schema": { - "type": "array", - "items": { - "type": "string" - } - }, - "x-nullable": true - }, - { - "type": "integer", - "name": "comparisonType", - "in": "query", - "x-schema": { - "$ref": "#/definitions/StringComparison" - }, - "x-nullable": false, - "enum": [ - 0, - 1, - 2, - 3, - 4, - 5 - ] - } - ], - "responses": { - "200": { - "x-nullable": true, - "description": "", - "schema": { - "type": "array", - "items": { - "type": "string" - } - } - } - } - } - }, - "/api/Values": { - "get": { - "tags": [ - "Values" - ], - "operationId": "Values_Get", - "responses": { - "200": { - "x-nullable": true, - "description": "", - "schema": { - "type": "array", - "items": { - "type": "string" - } - } - } - } - }, - "post": { - "tags": [ - "Values" - ], - "operationId": "Values_Post", - "consumes": [ - "application/xml" - ], - "parameters": [ - { - "name": "value", - "in": "body", - "required": true, - "schema": { - "type": "string" - }, - "x-nullable": true - } - ], - "responses": { - "200": { - "description": "" - } - } - } - }, - "/api/Values/too": { - "get": { - "tags": [ - "Values" - ], - "operationId": "Values_GetToo", - "responses": { - "200": { - "x-nullable": true, - "description": "", - "schema": { - "$ref": "#/definitions/Model" - } - } - } - } - } - }, - "definitions": { - "StringComparison": { - "type": "integer", - "description": "", - "x-enumNames": [ - "CurrentCulture", - "CurrentCultureIgnoreCase", - "InvariantCulture", - "InvariantCultureIgnoreCase", - "Ordinal", - "OrdinalIgnoreCase" - ], - "enum": [ - 0, - 1, - 2, - 3, - 4, - 5 - ] - }, - "Model": { - "type": "object", - "additionalProperties": false, - "properties": { - "userName": { - "type": "string" - } - } - } - } -} \ No newline at end of file diff --git a/src/Tools/Extensions.ApiDescription.Client/test/TestProjects/files/azureMonitor.json b/src/Tools/Extensions.ApiDescription.Client/test/TestProjects/files/azureMonitor.json deleted file mode 100644 index a63e1f5f2ada..000000000000 --- a/src/Tools/Extensions.ApiDescription.Client/test/TestProjects/files/azureMonitor.json +++ /dev/null @@ -1 +0,0 @@ -{"swagger":"2.0","info":{"title":"Microsoft Insights API","version":"2018-04-16","description":"Azure Monitor client to create/update/delete Scheduled Query Rules"},"host":"management.azure.com","schemes":["https"],"consumes":["application/json"],"produces":["application/json"],"security":[{"azure_auth":["user_impersonation"]}],"securityDefinitions":{"azure_auth":{"type":"oauth2","authorizationUrl":"https://login.microsoftonline.com/common/oauth2/authorize","flow":"implicit","description":"Azure Active Directory OAuth2 Flow","scopes":{"user_impersonation":"impersonate your user account"}}},"paths":{"/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/microsoft.insights/scheduledQueryRules/{ruleName}":{"put":{"description":"Creates or updates an log search rule.","tags":["scheduledQueryRules"],"operationId":"ScheduledQueryRules_CreateOrUpdate","parameters":[{"$ref":"#/parameters/SubscriptionIdParameter"},{"$ref":"#/parameters/ResourceGroupNameParameter"},{"$ref":"#/parameters/RuleNameParameter"},{"$ref":"#/parameters/ApiVersionParameter"},{"name":"parameters","in":"body","required":true,"schema":{"$ref":"#/definitions/LogSearchRuleResource"},"description":"The parameters of the rule to create or update."}],"responses":{"default":{"description":"Error response describing why the operation failed.","schema":{"$ref":"#/definitions/ErrorResponse"}},"200":{"description":"Successful request to update an Log Search rule","schema":{"$ref":"#/definitions/LogSearchRuleResource"}},"201":{"description":"Created alert rule","schema":{"$ref":"#/definitions/LogSearchRuleResource"}}},"x-ms-examples":{"Create or Update rule - AletringAction":{"$ref":"./examples/createOrUpdateScheduledQueryRules.json"},"Create or Update rule - LogToMetricAction":{"$ref":"./examples/createOrUpdateScheduledQueryRule-LogToMetricAction.json"}}},"get":{"description":"Gets an Log Search rule","tags":["scheduledQueryRules"],"operationId":"ScheduledQueryRules_Get","parameters":[{"$ref":"#/parameters/ResourceGroupNameParameter"},{"$ref":"#/parameters/RuleNameParameter"},{"$ref":"#/parameters/ApiVersionParameter"},{"$ref":"#/parameters/SubscriptionIdParameter"}],"responses":{"default":{"description":"Error response describing why the operation failed.","schema":{"$ref":"#/definitions/ErrorResponse"}},"200":{"description":"Successful request to get a Log Search rule","schema":{"$ref":"#/definitions/LogSearchRuleResource"}}},"x-ms-examples":{"Get rule":{"$ref":"./examples/getScheduledQueryRules.json"}}},"patch":{"tags":["scheduledQueryRules"],"description":"Update log search Rule.","operationId":"ScheduledQueryRules_Update","parameters":[{"$ref":"#/parameters/SubscriptionIdParameter"},{"$ref":"#/parameters/ResourceGroupNameParameter"},{"$ref":"#/parameters/RuleNameParameter"},{"$ref":"#/parameters/ApiVersionParameter"},{"name":"parameters","in":"body","required":true,"schema":{"$ref":"#/definitions/LogSearchRuleResourcePatch"},"description":"The parameters of the rule to update."}],"responses":{"default":{"description":"Error response describing why the operation failed.","schema":{"$ref":"#/definitions/ErrorResponse"}},"200":{"description":"Successful request to update an Log Search rule","schema":{"$ref":"#/definitions/LogSearchRuleResource"}}},"x-ms-examples":{"Patch Log Search Rule":{"$ref":"./examples/patchScheduledQueryRules.json"}}},"delete":{"description":"Deletes a Log Search rule","tags":["scheduledQueryRules"],"operationId":"ScheduledQueryRules_Delete","parameters":[{"$ref":"#/parameters/ResourceGroupNameParameter"},{"$ref":"#/parameters/RuleNameParameter"},{"$ref":"#/parameters/ApiVersionParameter"},{"$ref":"#/parameters/SubscriptionIdParameter"}],"responses":{"default":{"description":"Error response describing why the operation failed.","schema":{"$ref":"#/definitions/ErrorResponse"}},"200":{"description":"Successful request to delete a Log Search rule"},"204":{"description":"No Content. Resource not found"}},"x-ms-examples":{"Delete rule":{"$ref":"./examples/deleteScheduledQueryRules.json"}}}},"/subscriptions/{subscriptionId}/providers/microsoft.insights/scheduledQueryRules":{"get":{"tags":["scheduledQueryRules"],"operationId":"ScheduledQueryRules_ListBySubscription","description":"List the Log Search rules within a subscription group.","parameters":[{"$ref":"#/parameters/ApiVersionParameter"},{"$ref":"#/parameters/FilterParameter"},{"$ref":"#/parameters/SubscriptionIdParameter"}],"responses":{"default":{"description":"Error response describing why the operation failed.","schema":{"$ref":"#/definitions/ErrorResponse"}},"200":{"description":"Successful request for a list of alert rules","schema":{"$ref":"#/definitions/LogSearchRuleResourceCollection"}}},"x-ms-pageable":{"nextLinkName":null},"x-ms-examples":{"List rules":{"$ref":"./examples/listScheduledQueryRules.json"}},"x-ms-odata":"#/definitions/LogSearchRuleResource"}},"/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/microsoft.insights/scheduledQueryRules":{"get":{"tags":["scheduledQueryRules"],"operationId":"ScheduledQueryRules_ListByResourceGroup","description":"List the Log Search rules within a resource group.","parameters":[{"$ref":"#/parameters/ResourceGroupNameParameter"},{"$ref":"#/parameters/ApiVersionParameter"},{"$ref":"#/parameters/FilterParameter"},{"$ref":"#/parameters/SubscriptionIdParameter"}],"responses":{"default":{"description":"Error response describing why the operation failed.","schema":{"$ref":"#/definitions/ErrorResponse"}},"200":{"description":"Successful request for a list of alert rules","schema":{"$ref":"#/definitions/LogSearchRuleResourceCollection"}}},"x-ms-pageable":{"nextLinkName":null},"x-ms-examples":{"List rules":{"$ref":"./examples/listScheduledQueryRules.json"}},"x-ms-odata":"#/definitions/LogSearchRuleResource"}}},"definitions":{"Resource":{"properties":{"id":{"type":"string","readOnly":true,"description":"Azure resource Id"},"name":{"type":"string","readOnly":true,"description":"Azure resource name"},"type":{"type":"string","readOnly":true,"description":"Azure resource type"},"location":{"type":"string","description":"Resource location","x-ms-mutability":["create","read"]},"tags":{"additionalProperties":{"type":"string"},"description":"Resource tags"}},"required":["location"],"x-ms-azure-resource":true,"description":"An azure resource object"},"LogSearchRuleResource":{"type":"object","allOf":[{"$ref":"#/definitions/Resource"}],"required":["properties"],"properties":{"properties":{"x-ms-client-flatten":true,"$ref":"#/definitions/LogSearchRule","description":"The rule properties of the resource."}},"description":"The Log Search Rule resource."},"LogSearchRuleResourcePatch":{"properties":{"tags":{"additionalProperties":{"type":"string"},"description":"Resource tags"},"properties":{"x-ms-client-flatten":true,"$ref":"#/definitions/LogSearchRulePatch","description":"The log search rule properties of the resource."}},"description":"The log search rule resource for patch operations."},"LogSearchRuleResourceCollection":{"properties":{"value":{"type":"array","items":{"$ref":"#/definitions/LogSearchRuleResource"},"description":"The values for the Log Search Rule resources."}},"description":"Represents a collection of Log Search rule resources."},"Source":{"type":"object","description":"Specifies the log search query.","properties":{"query":{"type":"string","description":"Log search query. Required for action type - AlertingAction"},"authorizedResources":{"type":"array","items":{"type":"string"},"description":"List of Resource referred into query"},"dataSourceId":{"type":"string","description":"The resource uri over which log search query is to be run."},"queryType":{"$ref":"#/definitions/QueryType","description":"Set value to 'ResultCount' ."}},"required":["dataSourceId"]},"Schedule":{"type":"object","description":"Defines how often to run the search and the time interval.","properties":{"frequencyInMinutes":{"type":"integer","format":"int32","description":"frequency (in minutes) at which rule condition should be evaluated."},"timeWindowInMinutes":{"type":"integer","format":"int32","description":"Time window for which data needs to be fetched for query (should be greater than or equal to frequencyInMinutes)."}},"required":["frequencyInMinutes","timeWindowInMinutes"]},"TriggerCondition":{"description":"The condition that results in the Log Search rule.","properties":{"thresholdOperator":{"$ref":"#/definitions/ConditionalOperator","description":"Evaluation operation for rule - 'GreaterThan' or 'LessThan."},"threshold":{"description":"Result or count threshold based on which rule should be triggered.","format":"double","type":"number"},"metricTrigger":{"$ref":"#/definitions/LogMetricTrigger","description":"Trigger condition for metric query rule"}},"required":["thresholdOperator","threshold"],"type":"object"},"AzNsActionGroup":{"type":"object","properties":{"actionGroup":{"type":"array","description":"Azure Action Group reference.","items":{"type":"string"}},"emailSubject":{"type":"string","description":"Custom subject override for all email ids in Azure action group"},"customWebhookPayload":{"type":"string","description":"Custom payload to be sent for all webook URI in Azure action group"}},"description":"Azure action group"},"LogMetricTrigger":{"type":"object","properties":{"thresholdOperator":{"$ref":"#/definitions/ConditionalOperator","description":"Evaluation operation for Metric -'GreaterThan' or 'LessThan' or 'Equal'."},"threshold":{"format":"double","type":"number","description":"The threshold of the metric trigger."},"metricTriggerType":{"$ref":"#/definitions/MetricTriggerType","description":"Metric Trigger Type - 'Consecutive' or 'Total'"},"metricColumn":{"type":"string","description":"Evaluation of metric on a particular column"}},"description":"A log metrics trigger descriptor."},"ConditionalOperator":{"type":"string","enum":["GreaterThan","LessThan","Equal"],"x-ms-enum":{"name":"ConditionalOperator","modelAsString":true},"description":"Result Condition Evaluation criteria. Supported Values - 'GreaterThan' or 'LessThan' or 'Equal'."},"MetricTriggerType":{"type":"string","enum":["Consecutive","Total"],"x-ms-enum":{"name":"metricTriggerType","modelAsString":true},"description":"Metric Trigger Evaluation Type"},"AlertSeverity":{"type":"string","enum":["0","1","2","3","4"],"x-ms-enum":{"name":"AlertSeverity","modelAsString":true},"description":"Severity Level of Alert"},"QueryType":{"type":"string","enum":["ResultCount"],"x-ms-enum":{"name":"QueryType","modelAsString":true},"description":"Set value to 'ResultAcount'"},"LogSearchRule":{"description":"Log Search Rule Definition","properties":{"description":{"type":"string","description":"The description of the Log Search rule."},"enabled":{"type":"string","description":"The flag which indicates whether the Log Search rule is enabled. Value should be true or false","enum":["true","false"],"x-ms-enum":{"name":"enabled","modelAsString":true}},"lastUpdatedTime":{"readOnly":true,"type":"string","format":"date-time","description":"Last time the rule was updated in IS08601 format."},"provisioningState":{"readOnly":true,"type":"string","enum":["Succeeded","Deploying","Canceled","Failed"],"x-ms-enum":{"name":"provisioningState","modelAsString":true},"description":"Provisioning state of the scheduledquery rule"},"source":{"$ref":"#/definitions/Source","description":"Data Source against which rule will Query Data"},"schedule":{"$ref":"#/definitions/Schedule","description":"Schedule (Frequnecy, Time Window) for rule. Required for action type - AlertingAction"},"action":{"$ref":"#/definitions/Action","description":"Action needs to be taken on rule execution."}},"required":["source","action"]},"LogSearchRulePatch":{"description":"Log Search Rule Definition for Patching","properties":{"enabled":{"type":"string","description":"The flag which indicates whether the Log Search rule is enabled. Value should be true or false","enum":["true","false"],"x-ms-enum":{"name":"enabled","modelAsString":true}}}},"Action":{"type":"object","discriminator":"odata.type","properties":{"odata.type":{"type":"string","description":"Specifies the action. Supported values - AlertingAction, LogToMetricAction"}},"required":["odata.type"],"description":"Action descriptor."},"AlertingAction":{"description":"Specifiy action need to be taken when rule type is Alert","x-ms-discriminator-value":"Microsoft.WindowsAzure.Management.Monitoring.Alerts.Models.Microsoft.AppInsights.Nexus.DataContracts.Resources.ScheduledQueryRules.AlertingAction","type":"object","allOf":[{"$ref":"#/definitions/Action"}],"properties":{"severity":{"$ref":"#/definitions/AlertSeverity","description":"Severity of the alert"},"aznsAction":{"$ref":"#/definitions/AzNsActionGroup","description":"Azure action group reference."},"throttlingInMin":{"type":"integer","format":"int32","description":"time (in minutes) for which Alerts should be throttled or suppressed."},"trigger":{"$ref":"#/definitions/TriggerCondition","description":"The trigger condition that results in the alert rule being."}},"required":["aznsAction","trigger","severity"]},"Dimension":{"type":"object","description":"Specifies the criteria for converting log to metric.","properties":{"name":{"type":"string","description":"Name of the dimension"},"operator":{"type":"string","description":"Operator for dimension values","enum":["Include"],"x-ms-enum":{"name":"operator","modelAsString":true}},"values":{"type":"array","items":{"type":"string"},"description":"List of dimension values"}},"required":["name","operator","values"]},"Criteria":{"type":"object","description":"Specifies the criteria for converting log to metric.","properties":{"metricName":{"type":"string","description":"Name of the metric"},"dimensions":{"type":"array","items":{"$ref":"#/definitions/Dimension"},"description":"List of Dimensions for creating metric"}},"required":["metricName"]},"LogToMetricAction":{"description":"Specifiy action need to be taken when rule type is converting log to metric","x-ms-discriminator-value":"Microsoft.WindowsAzure.Management.Monitoring.Alerts.Models.Microsoft.AppInsights.Nexus.DataContracts.Resources.ScheduledQueryRules.LogToMetricAction","type":"object","allOf":[{"$ref":"#/definitions/Action"}],"properties":{"criteria":{"$ref":"#/definitions/Criteria","description":"Severity of the alert"}},"required":["criteria"]},"ErrorResponse":{"description":"Describes the format of Error response.","type":"object","properties":{"code":{"description":"Error code","type":"string"},"message":{"description":"Error message indicating why the operation failed.","type":"string"}}}},"parameters":{"SubscriptionIdParameter":{"name":"subscriptionId","in":"path","required":true,"type":"string","description":"The Azure subscription Id."},"ApiVersionParameter":{"name":"api-version","in":"query","required":true,"type":"string","description":"Client Api Version."},"ResourceGroupNameParameter":{"name":"resourceGroupName","in":"path","required":true,"type":"string","description":"The name of the resource group.","x-ms-parameter-location":"method"},"RuleNameParameter":{"name":"ruleName","in":"path","required":true,"type":"string","description":"The name of the rule.","x-ms-parameter-location":"method"},"FilterParameter":{"name":"$filter","in":"query","required":false,"type":"string","description":"The filter to apply on the operation. For more information please see https://msdn.microsoft.com/en-us/library/azure/dn931934.aspx","x-ms-parameter-location":"method"}}} \ No newline at end of file diff --git a/src/Tools/Extensions.ApiDescription.Client/test/TestProjects/files/swashbuckle.json b/src/Tools/Extensions.ApiDescription.Client/test/TestProjects/files/swashbuckle.json deleted file mode 100644 index 57b917e213cc..000000000000 --- a/src/Tools/Extensions.ApiDescription.Client/test/TestProjects/files/swashbuckle.json +++ /dev/null @@ -1,155 +0,0 @@ -{ - "swagger": "2.0", - "info": { - "version": "and so is version", - "title": "title is required" - }, - "paths": { - "/api/Values/matches": { - "post": { - "tags": [ - "Values" - ], - "operationId": "ApiValuesMatchesPost", - "consumes": [ - "application/json-patch+json", - "application/json", - "text/json", - "application/*+json", - "application/xml", - "text/xml", - "application/*+xml" - ], - "produces": [ - "text/plain", - "application/json", - "text/json", - "application/xml", - "text/xml" - ], - "parameters": [ - { - "name": "possibilities", - "in": "body", - "required": false, - "schema": { - "uniqueItems": false, - "type": "array", - "items": { - "type": "string" - } - } - }, - { - "name": "comparisonType", - "in": "query", - "required": false, - "type": "integer", - "format": "int32", - "enum": [ - 0, - 1, - 2, - 3, - 4, - 5 - ] - } - ], - "responses": { - "200": { - "description": "Success", - "schema": { - "uniqueItems": false, - "type": "array", - "items": { - "type": "string" - } - } - } - } - } - }, - "/api/Values": { - "get": { - "tags": [ - "Values" - ], - "operationId": "ApiValuesGet", - "consumes": [], - "produces": [ - "application/json" - ], - "parameters": [], - "responses": { - "200": { - "description": "Success", - "schema": { - "uniqueItems": false, - "type": "array", - "items": { - "type": "string" - } - } - } - } - }, - "post": { - "tags": [ - "Values" - ], - "operationId": "ApiValuesPost", - "consumes": [ - "application/xml" - ], - "produces": [], - "parameters": [ - { - "name": "value", - "in": "body", - "required": false, - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Success" - } - } - } - }, - "/api/Values/too": { - "get": { - "tags": [ - "Values" - ], - "operationId": "ApiValuesTooGet", - "consumes": [], - "produces": [ - "application/xml" - ], - "parameters": [], - "responses": { - "200": { - "description": "Success", - "schema": { - "$ref": "#/definitions/Model" - } - } - } - } - } - }, - "definitions": { - "Model": { - "type": "object", - "properties": { - "userName": { - "type": "string" - } - } - } - } -} \ No newline at end of file diff --git a/src/Tools/README.md b/src/Tools/README.md index 210711b734e3..05f77c07cd10 100644 --- a/src/Tools/README.md +++ b/src/Tools/README.md @@ -20,7 +20,6 @@ The following tools are produced by us but not bundled in the .NET Core CLI. The This folder also contains the infrastructure for our partners' service reference features: -- [Extensions.ApiDescription.Client](Extensions.ApiDescription.Client/README.md) MSBuild glue for OpenAPI code generation. - [Extensions.ApiDescription.Server](Extensions.ApiDescription.Server/README.md) MSBuild glue for OpenAPI document generation. - [dotnet-getdocument](dotnet-getdocument/README.md) the outside man of OpenAPI document generation tool. - [GetDocument.Insider](GetDocumentInsider/README.md) the inside man of OpenAPI document generation tool. diff --git a/src/Tools/Tools.slnf b/src/Tools/Tools.slnf index 7a09783caf7f..f426a052c762 100644 --- a/src/Tools/Tools.slnf +++ b/src/Tools/Tools.slnf @@ -101,8 +101,6 @@ "src\\Servers\\Kestrel\\Transport.Quic\\src\\Microsoft.AspNetCore.Server.Kestrel.Transport.Quic.csproj", "src\\Servers\\Kestrel\\Transport.Sockets\\src\\Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.csproj", "src\\Testing\\src\\Microsoft.AspNetCore.Testing.csproj", - "src\\Tools\\Extensions.ApiDescription.Client\\src\\Microsoft.Extensions.ApiDescription.Client.csproj", - "src\\Tools\\Extensions.ApiDescription.Client\\test\\Microsoft.Extensions.ApiDescription.Client.Tests.csproj", "src\\Tools\\Extensions.ApiDescription.Server\\src\\Microsoft.Extensions.ApiDescription.Server.csproj", "src\\Tools\\FirstRunCertGenerator\\src\\Microsoft.AspNetCore.DeveloperCertificates.XPlat.csproj", "src\\Tools\\FirstRunCertGenerator\\test\\Microsoft.AspNetCore.DeveloperCertificates.XPlat.Tests.csproj",