Rename all the service reference things (#9559)
- #7492 - remove document generation from client project; will be included in Web API project infrastructure (coming soon) - adjust eng/ProjectReferences.props to new project name - simplify item de-duplication in `_CreateCompileItemsForServiceFileReferences` target i.e. use `Remove` attribute - also handle `.tsx` files in this target - provide `%(FirstForGenerator)` metadata, #4916 - add `$(OpenApiGenerateAtDesignTime)` property (default `true` for now), #4944 - generate code in `obj` directory by default, #4945 - provide a default `%(CodeGenerator)` value, ##7491 1 of 2 (remainder will come in next milestone) nits: - remove a useless `StringBuilder.Append(...)` call - remove `%(OpenApiProjectReference.SourceProject)` metadata, duplicated `%(OriginalItemSpec)` - be more consistent about using element syntax for item metadata
This commit is contained in:
parent
1c19e8ee89
commit
ce8f053af7
|
|
@ -8,7 +8,7 @@
|
||||||
<ProjectReferenceProvider Include="Microsoft.AspNetCore.Identity.Specification.Tests" ProjectPath="$(RepositoryRoot)src\Identity\Specification.Tests\src\Microsoft.AspNetCore.Identity.Specification.Tests.csproj" />
|
<ProjectReferenceProvider Include="Microsoft.AspNetCore.Identity.Specification.Tests" ProjectPath="$(RepositoryRoot)src\Identity\Specification.Tests\src\Microsoft.AspNetCore.Identity.Specification.Tests.csproj" />
|
||||||
<ProjectReferenceProvider Include="Microsoft.Web.Xdt.Extensions" ProjectPath="$(RepositoryRoot)src\SiteExtensions\Microsoft.Web.Xdt.Extensions\src\Microsoft.Web.Xdt.Extensions.csproj" />
|
<ProjectReferenceProvider Include="Microsoft.Web.Xdt.Extensions" ProjectPath="$(RepositoryRoot)src\SiteExtensions\Microsoft.Web.Xdt.Extensions\src\Microsoft.Web.Xdt.Extensions.csproj" />
|
||||||
<ProjectReferenceProvider Include="Microsoft.AspNetCore.DeveloperCertificates.XPlat" ProjectPath="$(RepositoryRoot)src\Tools\FirstRunCertGenerator\src\Microsoft.AspNetCore.DeveloperCertificates.XPlat.csproj" />
|
<ProjectReferenceProvider Include="Microsoft.AspNetCore.DeveloperCertificates.XPlat" ProjectPath="$(RepositoryRoot)src\Tools\FirstRunCertGenerator\src\Microsoft.AspNetCore.DeveloperCertificates.XPlat.csproj" />
|
||||||
<ProjectReferenceProvider Include="Microsoft.Extensions.ApiDescription.Tasks" ProjectPath="$(RepositoryRoot)src\Mvc\Extensions.ApiDescription.Design\src\Microsoft.Extensions.ApiDescription.Design.csproj" />
|
<ProjectReferenceProvider Include="Microsoft.Extensions.ApiDescription.Tasks" ProjectPath="$(RepositoryRoot)src\Mvc\Extensions.ApiDescription.Client\src\Microsoft.Extensions.ApiDescription.Client.csproj" />
|
||||||
<ProjectReferenceProvider Include="Microsoft.AspNetCore.SignalR.Specification.Tests" ProjectPath="$(RepositoryRoot)src\SignalR\server\Specification.Tests\src\Microsoft.AspNetCore.SignalR.Specification.Tests.csproj" />
|
<ProjectReferenceProvider Include="Microsoft.AspNetCore.SignalR.Specification.Tests" ProjectPath="$(RepositoryRoot)src\SignalR\server\Specification.Tests\src\Microsoft.AspNetCore.SignalR.Specification.Tests.csproj" />
|
||||||
<ProjectReferenceProvider Include="Microsoft.AspNetCore.Blazor.Build" ProjectPath="$(RepositoryRoot)src\Components\Blazor\Build\src\Microsoft.AspNetCore.Blazor.Build.csproj" />
|
<ProjectReferenceProvider Include="Microsoft.AspNetCore.Blazor.Build" ProjectPath="$(RepositoryRoot)src\Components\Blazor\Build\src\Microsoft.AspNetCore.Blazor.Build.csproj" />
|
||||||
<ProjectReferenceProvider Include="Microsoft.AspNetCore" ProjectPath="$(RepositoryRoot)src\DefaultBuilder\src\Microsoft.AspNetCore.csproj" RefProjectPath="$(RepositoryRoot)src\DefaultBuilder\ref\Microsoft.AspNetCore.csproj" />
|
<ProjectReferenceProvider Include="Microsoft.AspNetCore" ProjectPath="$(RepositoryRoot)src\DefaultBuilder\src\Microsoft.AspNetCore.csproj" RefProjectPath="$(RepositoryRoot)src\DefaultBuilder\ref\Microsoft.AspNetCore.csproj" />
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,8 @@ using Microsoft.Build.Utilities;
|
||||||
namespace Microsoft.Extensions.ApiDescription.Tasks
|
namespace Microsoft.Extensions.ApiDescription.Tasks
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds or corrects ClassName, Namespace and OutputPath metadata in ServiceFileReference items. Also stores final
|
/// Adds or corrects ClassName, FirstForGenerator, Namespace, and OutputPath metadata in OpenApiReference items.
|
||||||
/// metadata as SerializedMetadata.
|
/// Also stores final metadata as SerializedMetadata.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class GetFileReferenceMetadata : Task
|
public class GetFileReferenceMetadata : Task
|
||||||
{
|
{
|
||||||
|
|
@ -35,13 +35,13 @@ namespace Microsoft.Extensions.ApiDescription.Tasks
|
||||||
public string OutputDirectory { get; set; }
|
public string OutputDirectory { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The ServiceFileReference items to update.
|
/// The OpenApiReference items to update.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Required]
|
[Required]
|
||||||
public ITaskItem[] Inputs { get; set; }
|
public ITaskItem[] Inputs { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The updated ServiceFileReference items. Will include ClassName, Namespace and OutputPath metadata.
|
/// The updated OpenApiReference items. Will include ClassName, Namespace and OutputPath metadata.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Output]
|
[Output]
|
||||||
public ITaskItem[] Outputs{ get; set; }
|
public ITaskItem[] Outputs{ get; set; }
|
||||||
|
|
@ -50,36 +50,45 @@ namespace Microsoft.Extensions.ApiDescription.Tasks
|
||||||
public override bool Execute()
|
public override bool Execute()
|
||||||
{
|
{
|
||||||
var outputs = new List<ITaskItem>(Inputs.Length);
|
var outputs = new List<ITaskItem>(Inputs.Length);
|
||||||
|
var codeGenerators = new HashSet<string>();
|
||||||
var destinations = new HashSet<string>();
|
var destinations = new HashSet<string>();
|
||||||
|
|
||||||
foreach (var item in Inputs)
|
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", "OpenApiReference", item.ItemSpec));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
var newItem = new TaskItem(item);
|
var newItem = new TaskItem(item);
|
||||||
outputs.Add(newItem);
|
outputs.Add(newItem);
|
||||||
|
|
||||||
var codeGenerator = item.GetMetadata("CodeGenerator");
|
if (codeGenerators.Add(codeGenerator))
|
||||||
if (string.IsNullOrEmpty("CodeGenerator"))
|
|
||||||
{
|
{
|
||||||
// This case occurs when user forgets to specify the required metadata. We have no default here.
|
newItem.SetMetadata("FirstForGenerator", "true");
|
||||||
string type;
|
}
|
||||||
if (!string.IsNullOrEmpty(item.GetMetadata("SourceProject")))
|
else
|
||||||
{
|
{
|
||||||
type = "ServiceProjectReference";
|
newItem.SetMetadata("FirstForGenerator", "false");
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
type = "ServiceFileReference";
|
|
||||||
}
|
|
||||||
|
|
||||||
Log.LogError(Resources.FormatInvalidEmptyMetadataValue("CodeGenerator", type, item.ItemSpec));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var outputPath = item.GetMetadata("OutputPath");
|
var outputPath = item.GetMetadata("OutputPath");
|
||||||
if (string.IsNullOrEmpty(outputPath))
|
if (string.IsNullOrEmpty(outputPath))
|
||||||
{
|
{
|
||||||
// No need to further sanitize this path.
|
// No need to further sanitize this path because the file must exist.
|
||||||
var filename = item.GetMetadata("Filename");
|
var filename = item.GetMetadata("Filename");
|
||||||
var isTypeScript = codeGenerator.EndsWith(TypeScriptLanguageName, StringComparison.OrdinalIgnoreCase);
|
var isTypeScript = codeGenerator.EndsWith(
|
||||||
|
TypeScriptLanguageName,
|
||||||
|
StringComparison.OrdinalIgnoreCase);
|
||||||
|
|
||||||
outputPath = $"{filename}Client{(isTypeScript ? ".ts" : Extension)}";
|
outputPath = $"{filename}Client{(isTypeScript ? ".ts" : Extension)}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -94,6 +103,7 @@ namespace Microsoft.Extensions.ApiDescription.Tasks
|
||||||
// This case may occur when user is experimenting e.g. with multiple code generators or options.
|
// 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.
|
// May also occur when user accidentally duplicates OutputPath metadata.
|
||||||
Log.LogError(Resources.FormatDuplicateFileOutputPaths(outputPath));
|
Log.LogError(Resources.FormatDuplicateFileOutputPaths(outputPath));
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
MetadataSerializer.SetMetadata(newItem, "OutputPath", outputPath);
|
MetadataSerializer.SetMetadata(newItem, "OutputPath", outputPath);
|
||||||
|
|
@ -115,7 +115,6 @@ namespace Microsoft.Extensions.ApiDescription.Tasks
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(value))
|
if (string.IsNullOrEmpty(value))
|
||||||
{
|
{
|
||||||
builder.Append(value);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -27,15 +27,9 @@
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="Microsoft.Build.Utilities.Core" />
|
<Reference Include="Microsoft.Build.Utilities.Core" />
|
||||||
<Reference Include="System.Net.Http" Condition="'$(TargetFramework)' == 'net461'" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<Target Name="PopulateNuspec">
|
<Target Name="PopulateNuspec">
|
||||||
<MSBuild Projects="../../dotnet-getdocument/src/dotnet-getdocument.csproj"
|
|
||||||
BuildInParallel="$(BuildInParallel)"
|
|
||||||
RemoveProperties="RuntimeIdentifier;TargetFrameworks;TargetFramework"
|
|
||||||
Targets="Publish" />
|
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<NuspecProperties>
|
<NuspecProperties>
|
||||||
id=$(PackageId);
|
id=$(PackageId);
|
||||||
|
|
@ -21,9 +21,5 @@
|
||||||
<file src="buildMultiTargeting\*" target="buildMultiTargeting" />
|
<file src="buildMultiTargeting\*" target="buildMultiTargeting" />
|
||||||
<file src="bin\$configuration$\net461\Microsoft.Extensions.ApiDescription.Tasks.*" target="tasks\net461" />
|
<file src="bin\$configuration$\net461\Microsoft.Extensions.ApiDescription.Tasks.*" target="tasks\net461" />
|
||||||
<file src="bin\$configuration$\netstandard2.0\Microsoft.Extensions.ApiDescription.Tasks.*" target="tasks\netstandard2.0" />
|
<file src="bin\$configuration$\netstandard2.0\Microsoft.Extensions.ApiDescription.Tasks.*" target="tasks\netstandard2.0" />
|
||||||
<file src="..\..\dotnet-getdocument\src\bin\$configuration$\netcoreapp2.1\publish\*.*" target="tools" />
|
|
||||||
<file src="..\..\GetDocumentInsider\src\bin\$configuration$\net461\GetDocument.Insider.*" target="tools\net461" />
|
|
||||||
<file src="..\..\GetDocumentInsider\src\bin\x86\$configuration$\net461\GetDocument.Insider.*" target="tools\net461-x86" />
|
|
||||||
<file src="..\..\GetDocumentInsider\src\bin\$configuration$\netcoreapp2.0\GetDocument.Insider.*" target="tools\netcoreapp2.0" />
|
|
||||||
</files>
|
</files>
|
||||||
</package>
|
</package>
|
||||||
|
|
@ -11,7 +11,7 @@ namespace Microsoft.Extensions.ApiDescription.Tasks
|
||||||
= new ResourceManager("Microsoft.Extensions.ApiDescription.Tasks.Resources", typeof(Resources).GetTypeInfo().Assembly);
|
= new ResourceManager("Microsoft.Extensions.ApiDescription.Tasks.Resources", typeof(Resources).GetTypeInfo().Assembly);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Multiple items have OutputPath='{0}'. All ServiceFileReference and ServiceProjectReference items must have unique OutputPath metadata.
|
/// Multiple items have OutputPath='{0}'. All OpenApiReference items must have unique OutputPath metadata.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal static string DuplicateFileOutputPaths
|
internal static string DuplicateFileOutputPaths
|
||||||
{
|
{
|
||||||
|
|
@ -19,25 +19,11 @@ namespace Microsoft.Extensions.ApiDescription.Tasks
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Multiple items have OutputPath='{0}'. All ServiceFileReference and ServiceProjectReference items must have unique OutputPath metadata.
|
/// Multiple items have OutputPath='{0}'. All OpenApiReference items must have unique OutputPath metadata.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal static string FormatDuplicateFileOutputPaths(object p0)
|
internal static string FormatDuplicateFileOutputPaths(object p0)
|
||||||
=> string.Format(CultureInfo.CurrentCulture, GetString("DuplicateFileOutputPaths"), p0);
|
=> string.Format(CultureInfo.CurrentCulture, GetString("DuplicateFileOutputPaths"), p0);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Mutliple ServiceProjectReference items have DocumentPath='{0}'. ServiceProjectReference items must have unique DocumentPath metadata.
|
|
||||||
/// </summary>
|
|
||||||
internal static string DuplicateProjectDocumentPaths
|
|
||||||
{
|
|
||||||
get => GetString("DuplicateProjectDocumentPaths");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Mutliple ServiceProjectReference items have DocumentPath='{0}'. ServiceProjectReference items must have unique DocumentPath metadata.
|
|
||||||
/// </summary>
|
|
||||||
internal static string FormatDuplicateProjectDocumentPaths(object p0)
|
|
||||||
=> string.Format(CultureInfo.CurrentCulture, GetString("DuplicateProjectDocumentPaths"), p0);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Invalid {0} metadata value for {1} item '{2}'. {0} metadata must not be set to the empty string.
|
/// Invalid {0} metadata value for {1} item '{2}'. {0} metadata must not be set to the empty string.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -118,11 +118,7 @@
|
||||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
</resheader>
|
</resheader>
|
||||||
<data name="DuplicateFileOutputPaths" xml:space="preserve">
|
<data name="DuplicateFileOutputPaths" xml:space="preserve">
|
||||||
<value>Multiple items have OutputPath='{0}'. All ServiceFileReference and ServiceProjectReference items must have unique OutputPath metadata.</value>
|
<value>Multiple items have OutputPath='{0}'. All OpenApiReference items must have unique OutputPath metadata.</value>
|
||||||
<comment>ServiceProjectReference items become ServiceFileReference items and all ServiceFileReference items must have unique OutputPath metadata.</comment>
|
|
||||||
</data>
|
|
||||||
<data name="DuplicateProjectDocumentPaths" xml:space="preserve">
|
|
||||||
<value>Mutliple ServiceProjectReference items have DocumentPath='{0}'. ServiceProjectReference items must have unique DocumentPath metadata.</value>
|
|
||||||
</data>
|
</data>
|
||||||
<data name="InvalidEmptyMetadataValue" xml:space="preserve">
|
<data name="InvalidEmptyMetadataValue" xml:space="preserve">
|
||||||
<value>Invalid {0} metadata value for {1} item '{2}'. {0} metadata must not be set to the empty string.</value>
|
<value>Invalid {0} metadata value for {1} item '{2}'. {0} metadata must not be set to the empty string.</value>
|
||||||
|
|
@ -0,0 +1,67 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||||
|
<Project>
|
||||||
|
<PropertyGroup>
|
||||||
|
<_ApiDescriptionTasksAssemblyTarget
|
||||||
|
Condition="'$(MSBuildRuntimeType)' == 'Core'">netstandard2.0</_ApiDescriptionTasksAssemblyTarget>
|
||||||
|
<_ApiDescriptionTasksAssemblyTarget
|
||||||
|
Condition="'$(MSBuildRuntimeType)' != 'Core'">net461</_ApiDescriptionTasksAssemblyTarget>
|
||||||
|
<_ApiDescriptionTasksAssemblyPath>$(MSBuildThisFileDirectory)/../tasks/$(_ApiDescriptionTasksAssemblyTarget)/Microsoft.Extensions.ApiDescription.Tasks.dll</_ApiDescriptionTasksAssemblyPath>
|
||||||
|
<_ApiDescriptionTasksAssemblyTarget />
|
||||||
|
</PropertyGroup>
|
||||||
|
<UsingTask TaskName="GetCurrentItems" AssemblyFile="$(_ApiDescriptionTasksAssemblyPath)" />
|
||||||
|
<UsingTask TaskName="GetFileReferenceMetadata" AssemblyFile="$(_ApiDescriptionTasksAssemblyPath)" />
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Settings users may update as they see fit.
|
||||||
|
-->
|
||||||
|
<PropertyGroup>
|
||||||
|
<OpenApiDefaultGeneratorOptions Condition="'$(OpenApiDefaultGeneratorOptions)' == ''"></OpenApiDefaultGeneratorOptions>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
If 'true', will generate code for OpenApiReference items during design-time builds. Otherwise, generate code only
|
||||||
|
for output files that do not yet exist during design-time builds.
|
||||||
|
-->
|
||||||
|
<OpenApiGenerateAtDesignTime Condition="'$(OpenApiGenerateAtDesignTime)' == ''">true</OpenApiGenerateAtDesignTime>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
$(OpenApiDefaultOutputDirectory) value is interpreted relative to the project folder, unless already an
|
||||||
|
absolute path.
|
||||||
|
-->
|
||||||
|
<OpenApiDefaultOutputDirectory
|
||||||
|
Condition="'$(OpenApiDefaultOutputDirectory)' == ''">$(BaseIntermediateOutputPath)</OpenApiDefaultOutputDirectory>
|
||||||
|
<OpenApiDefaultOutputDirectory>$([MSBuild]::EnsureTrailingSlash('$(OpenApiDefaultOutputDirectory)'))</OpenApiDefaultOutputDirectory>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Well-known metadata of the code generator item groups.
|
||||||
|
-->
|
||||||
|
<ItemDefinitionGroup>
|
||||||
|
<!-- OpenApiProjectReference items may also include OpenApiReference metadata. -->
|
||||||
|
<OpenApiProjectReference />
|
||||||
|
|
||||||
|
<OpenApiReference>
|
||||||
|
<!-- Name of the class to generate. Defaults to match filename in %(OutputPath). -->
|
||||||
|
<ClassName />
|
||||||
|
<!--
|
||||||
|
Code generator to use. Required and must end with "CSharp" or "TypeScript" (the currently-supported target
|
||||||
|
languages) unless %(OutputPath) is set. Builds will invoke a target named "Generate%(CodeGenerator)" to do
|
||||||
|
actual code generation.
|
||||||
|
-->
|
||||||
|
<CodeGenerator>NSwagCSharp</CodeGenerator>
|
||||||
|
<!-- Namespace to contain generated class. Default is $(RootNamespace). -->
|
||||||
|
<Namespace />
|
||||||
|
<!--
|
||||||
|
Options to pass to the code generator target then (likely) added to a tool's command line. Value is passed
|
||||||
|
along to the code generator but otherwise unused in this package.
|
||||||
|
-->
|
||||||
|
<Options>$(OpenApiDefaultGeneratorOptions)</Options>
|
||||||
|
<!--
|
||||||
|
Path to place generated code. Code generator may interpret path as a filename or directory. Default filename or
|
||||||
|
folder name is %(Filename)Client.[cs|ts]. Filenames and relative paths (if explicitly set) are combined with
|
||||||
|
$(OpenApiDefaultOutputDirectory). Final value (depending on $(OpenApiDefaultOutputDirectory)) is likely to be
|
||||||
|
a path relative to the client project.
|
||||||
|
-->
|
||||||
|
<OutputPath />
|
||||||
|
</OpenApiReference>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
</Project>
|
||||||
|
|
@ -0,0 +1,149 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||||
|
<Project>
|
||||||
|
<!-- Internal settings. Not intended for customization. -->
|
||||||
|
<PropertyGroup>
|
||||||
|
<GenerateOpenApiReferenceCodeDependsOn>
|
||||||
|
_GetMetadataForOpenApiReferences;
|
||||||
|
_GenerateOpenApiReferenceCode;
|
||||||
|
_CreateCompileItemsForOpenApiReferences
|
||||||
|
</GenerateOpenApiReferenceCodeDependsOn>
|
||||||
|
<GenerateServiceFileReferenceCodeDependsOn>
|
||||||
|
_GenerateErrorsForOldItems;
|
||||||
|
_CreateOpenApiReferenceItemsForOpenApiProjectReferences;
|
||||||
|
GenerateOpenApiReferenceCode
|
||||||
|
</GenerateServiceFileReferenceCodeDependsOn>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<!-- OpenApiProjectReference support. -->
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<!--
|
||||||
|
Do not change %(ReferenceOutputAssembly) if project contains duplicate @(ProjectReference) and
|
||||||
|
@(OpenApiProjectReference) items.
|
||||||
|
-->
|
||||||
|
<ProjectReference Include="@(OpenApiProjectReference)" Exclude="@(ProjectReference)">
|
||||||
|
<NoWarn>NU1702</NoWarn>
|
||||||
|
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||||
|
</ProjectReference>
|
||||||
|
<ProjectReference Update="@(OpenApiProjectReference)">
|
||||||
|
<OpenApiReference>true</OpenApiReference>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<Target Name="_CreateOpenApiReferenceItemsForOpenApiProjectReferences"
|
||||||
|
AfterTargets="ResolveProjectReferences"
|
||||||
|
Condition="'$(DesignTimeBuild)' != 'true' AND '$(BuildingProject)' == 'true'">
|
||||||
|
<ItemGroup>
|
||||||
|
<_Temporary Remove="@(_Temporary)" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<MSBuild Targets="OpenApiGetDocuments"
|
||||||
|
Projects="@(ProjectReferenceWithConfiguration)"
|
||||||
|
Condition="'%(ProjectReferenceWithConfiguration.OpenApiReference)' == 'true'"
|
||||||
|
Properties="%(ProjectReferenceWithConfiguration.SetConfiguration); %(ProjectReferenceWithConfiguration.SetPlatform); %(ProjectReferenceWithConfiguration.SetTargetFramework)"
|
||||||
|
RebaseOutputs="true"
|
||||||
|
RemoveProperties="%(ProjectReferenceWithConfiguration.GlobalPropertiesToRemove);TargetFrameworks;RuntimeIdentifier">
|
||||||
|
<Output TaskParameter="TargetOutputs" ItemName="_Temporary" />
|
||||||
|
</MSBuild>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<OpenApiReference Include="@(_Temporary)" Exclude="@(OpenApiReference)" RemoveMetadata="FullConfiguration" />
|
||||||
|
<_Temporary Remove="@(_Temporary)" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Target>
|
||||||
|
|
||||||
|
<!-- OpenApiReference support. -->
|
||||||
|
|
||||||
|
<Target Name="_GetMetadataForOpenApiReferences" Condition="'@(OpenApiReference)' != ''">
|
||||||
|
<ItemGroup>
|
||||||
|
<_Temporary Remove="@(_Temporary)" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<GetFileReferenceMetadata Inputs="@(OpenApiReference)"
|
||||||
|
Extension="$(DefaultLanguageSourceExtension)"
|
||||||
|
Namespace="$(RootNamespace)"
|
||||||
|
OutputDirectory="$(OpenApiDefaultOutputDirectory)">
|
||||||
|
<Output TaskParameter="Outputs" ItemName="_Temporary" />
|
||||||
|
</GetFileReferenceMetadata>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<OpenApiReference Remove="@(OpenApiReference)" />
|
||||||
|
<OpenApiReference Include="@(_Temporary)" />
|
||||||
|
<_Temporary Remove="@(_Temporary)" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Target>
|
||||||
|
|
||||||
|
<Target Name="_GetCurrentOpenApiReference">
|
||||||
|
<GetCurrentItems Input="$(GeneratorMetadata)">
|
||||||
|
<Output TaskParameter="Outputs" ItemName="CurrentOpenApiReference" />
|
||||||
|
</GetCurrentItems>
|
||||||
|
</Target>
|
||||||
|
|
||||||
|
<Target Name="_InnerGenerateOpenApiReferenceCode" DependsOnTargets="_GetCurrentOpenApiReference;$(GeneratorTarget)" />
|
||||||
|
|
||||||
|
<Target Name="_GenerateOpenApiReferenceCode"
|
||||||
|
Condition="$(OpenApiGenerateAtDesignTime) OR ('$(DesignTimeBuild)' != 'true' AND '$(BuildingProject)' == 'true')"
|
||||||
|
Inputs="@(OpenApiReference)"
|
||||||
|
Outputs="%(OutputPath)">
|
||||||
|
<MSBuild BuildInParallel="$(BuildInParallel)"
|
||||||
|
Projects="$(MSBuildProjectFullPath)"
|
||||||
|
Properties="GeneratorTargetPath=%(OpenApiReference.OutputPath);GeneratorTarget=Generate%(CodeGenerator);GeneratorMetadata=%(SerializedMetadata)"
|
||||||
|
RemoveProperties="TargetFrameworks"
|
||||||
|
Targets="_InnerGenerateOpenApiReferenceCode" />
|
||||||
|
</Target>
|
||||||
|
|
||||||
|
<Target Name="_CreateCompileItemsForOpenApiReferences" Condition="'@(OpenApiReference)' != ''">
|
||||||
|
<ItemGroup>
|
||||||
|
<_Files Remove="@(_Files)" />
|
||||||
|
<_Files Include="@(OpenApiReference -> '%(OutputPath)')"
|
||||||
|
Condition="$([System.IO.File]::Exists('%(OpenApiReference.OutputPath)'))">
|
||||||
|
<OutputPathExtension>$([System.IO.Path]::GetExtension('%(OpenApiReference.OutputPath)'))</OutputPathExtension>
|
||||||
|
</_Files>
|
||||||
|
<_Directories Remove="@(_Directories)" />
|
||||||
|
<_Directories Include="@(OpenApiReference -> '%(OutputPath)')"
|
||||||
|
Condition="Exists('%(OpenApiReference.OutputPath)') AND ! $([System.IO.File]::Exists('%(OpenApiReference.OutputPath)'))" />
|
||||||
|
|
||||||
|
<!-- If OutputPath is a file, add it directly to relevant items. -->
|
||||||
|
<TypeScriptCompile Include="@(_Files)"
|
||||||
|
Exclude="@(TypeScriptCompile)"
|
||||||
|
Condition="'%(_Files.OutputPathExtension)' == '.ts' OR '%(_Files.OutputPathExtension)' == '.tsx'">
|
||||||
|
<SourceDocument>%(_Files.FullPath)</SourceDocument>
|
||||||
|
</TypeScriptCompile>
|
||||||
|
|
||||||
|
<Compile Include="@(_Files)"
|
||||||
|
Exclude="@(Compile)"
|
||||||
|
Condition="'$(DefaultLanguageSourceExtension)' != '.ts' AND '%(_Files.OutputPathExtension)' == '$(DefaultLanguageSourceExtension)'">
|
||||||
|
<SourceDocument>%(OpenApiReference.FullPath)</SourceDocument>
|
||||||
|
</Compile>
|
||||||
|
|
||||||
|
<!-- Otherwise, add all descendant files with the expected extension. -->
|
||||||
|
<TypeScriptCompile Include="@(_Directories -> '%(Identity)/**/*.ts;%(Identity)/**/*.tsx')"
|
||||||
|
Exclude="@(TypeScriptCompile)">
|
||||||
|
<SourceDocument>%(_Directories.FullPath)</SourceDocument>
|
||||||
|
</TypeScriptCompile>
|
||||||
|
|
||||||
|
<Compile Include="@(_Directories -> '%(Identity)/**/*.$(DefaultLanguageSourceExtension)')"
|
||||||
|
Exclude="@(Compile)"
|
||||||
|
Condition="'$(DefaultLanguageSourceExtension)' != '.ts'">
|
||||||
|
<SourceDocument>%(_Directories.FullPath)</SourceDocument>
|
||||||
|
</Compile>
|
||||||
|
|
||||||
|
<_Files Remove="@(_Files)" />
|
||||||
|
<_Directories Remove="@(_Directories)" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Target>
|
||||||
|
|
||||||
|
<Target Name="GenerateOpenApiReferenceCode" DependsOnTargets="$(GenerateOpenApiReferenceCodeDependsOn)" />
|
||||||
|
|
||||||
|
<!-- Tie above code generation steps into the build. -->
|
||||||
|
|
||||||
|
<Target Name="_GenerateErrorsForOldItems">
|
||||||
|
<Error Condition="'@(ServiceProjectReference)' != ''" Text="ServiceProjectReference items are no longer supported." />
|
||||||
|
<Error Condition="'@(ServiceUriReference)' != ''" Text="ServiceUriReference items are no longer supported." />
|
||||||
|
<Error Condition="'@(ServiceFileReference)' != ''" Text="ServiceFileReference items are no longer supported." />
|
||||||
|
</Target>
|
||||||
|
|
||||||
|
<Target Name="GenerateServiceFileReferenceCode"
|
||||||
|
BeforeTargets="BeforeCompile"
|
||||||
|
DependsOnTargets="$(GenerateServiceFileReferenceCodeDependsOn)" />
|
||||||
|
</Project>
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||||
<Project>
|
<Project>
|
||||||
<Target Name="GenerateServiceFileReferenceCodes" BeforeTargets="BeforeCompile">
|
<Target Name="GenerateServiceFileReferenceCode" BeforeTargets="BeforeCompile">
|
||||||
<MsBuild Projects="$(MSBuildProjectFile)"
|
<MsBuild Projects="$(MSBuildProjectFile)"
|
||||||
Targets="GenerateServiceFileReferenceCodes"
|
Targets="GenerateServiceFileReferenceCode"
|
||||||
Properties="TargetFramework=$(TargetFrameworks.Split(';')[0])"
|
Properties="TargetFramework=$(TargetFrameworks.Split(';')[0])"
|
||||||
RemoveProperties="TargetFrameworks;RuntimeIdentifier" />
|
RemoveProperties="TargetFrameworks;RuntimeIdentifier" />
|
||||||
</Target>
|
</Target>
|
||||||
|
|
@ -1,147 +0,0 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using Microsoft.Build.Framework;
|
|
||||||
using Microsoft.Build.Utilities;
|
|
||||||
|
|
||||||
namespace Microsoft.Extensions.ApiDescription.Tasks
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Adds or corrects DocumentPath and project-related metadata in ServiceProjectReference items. Also stores final
|
|
||||||
/// metadata as SerializedMetadata.
|
|
||||||
/// </summary>
|
|
||||||
public class GetProjectReferenceMetadata : Task
|
|
||||||
{
|
|
||||||
private static readonly char[] InvalidFilenameCharacters = Path.GetInvalidFileNameChars();
|
|
||||||
private static readonly string[] InvalidFilenameStrings = new[] { ".." };
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Default directory for DocumentPath values.
|
|
||||||
/// </summary>
|
|
||||||
public string DocumentDirectory { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The ServiceFileReference items to update.
|
|
||||||
/// </summary>
|
|
||||||
[Required]
|
|
||||||
public ITaskItem[] Inputs { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The updated ServiceFileReference items. Will include Namespace and OutputPath metadata. OutputPath metadata
|
|
||||||
/// will contain full paths.
|
|
||||||
/// </summary>
|
|
||||||
[Output]
|
|
||||||
public ITaskItem[] Outputs{ get; set; }
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override bool Execute()
|
|
||||||
{
|
|
||||||
var outputs = new List<ITaskItem>(Inputs.Length);
|
|
||||||
var destinations = new HashSet<string>();
|
|
||||||
|
|
||||||
foreach (var item in Inputs)
|
|
||||||
{
|
|
||||||
var newItem = new TaskItem(item);
|
|
||||||
outputs.Add(newItem);
|
|
||||||
|
|
||||||
var documentGenerator = item.GetMetadata("DocumentGenerator");
|
|
||||||
if (string.IsNullOrEmpty(documentGenerator))
|
|
||||||
{
|
|
||||||
// This case occurs when user overrides the default metadata.
|
|
||||||
Log.LogError(Resources.FormatInvalidEmptyMetadataValue(
|
|
||||||
"DocumentGenerator",
|
|
||||||
"ServiceProjectReference",
|
|
||||||
item.ItemSpec));
|
|
||||||
}
|
|
||||||
|
|
||||||
var documentName = item.GetMetadata("DocumentName");
|
|
||||||
if (string.IsNullOrEmpty(documentName))
|
|
||||||
{
|
|
||||||
documentName = "v1";
|
|
||||||
MetadataSerializer.SetMetadata(newItem, "DocumentName", documentName);
|
|
||||||
}
|
|
||||||
|
|
||||||
var documentPath = item.GetMetadata("DocumentPath");
|
|
||||||
if (string.IsNullOrEmpty(documentPath))
|
|
||||||
{
|
|
||||||
// No need to sanitize the filename since the project file exists.
|
|
||||||
var projectFilename = item.GetMetadata("Filename");
|
|
||||||
|
|
||||||
// Default document filename matches project filename unless given a non-default document name.
|
|
||||||
if (string.IsNullOrEmpty(documentName))
|
|
||||||
{
|
|
||||||
// This is an odd (but allowed) case that would break the sanitize one-liner below. Also,
|
|
||||||
// ensure chosen name does not match the "v1" case.
|
|
||||||
documentPath = projectFilename + "_.json";
|
|
||||||
}
|
|
||||||
else if (string.Equals("v1", documentName, StringComparison.Ordinal))
|
|
||||||
{
|
|
||||||
documentPath = projectFilename + ".json";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Sanitize the document name because it may contain almost any character, including illegal
|
|
||||||
// filename characters such as '/' and '?'. (Do not treat slashes as folder separators.)
|
|
||||||
var sanitizedDocumentName = string.Join("_", documentName.Split(InvalidFilenameCharacters));
|
|
||||||
while (sanitizedDocumentName.Contains(InvalidFilenameStrings[0]))
|
|
||||||
{
|
|
||||||
sanitizedDocumentName = string.Join(
|
|
||||||
".",
|
|
||||||
sanitizedDocumentName.Split(InvalidFilenameStrings, StringSplitOptions.None));
|
|
||||||
}
|
|
||||||
|
|
||||||
documentPath = $"{projectFilename}_{sanitizedDocumentName}";
|
|
||||||
|
|
||||||
// Possible the document path already ends with .json. Don't duplicate that or a final period.
|
|
||||||
if (!documentPath.EndsWith(".json", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
if (documentPath.EndsWith(".", StringComparison.Ordinal))
|
|
||||||
{
|
|
||||||
documentPath += "json";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
documentPath += ".json";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
documentPath = GetFullPath(documentPath);
|
|
||||||
if (!destinations.Add(documentPath))
|
|
||||||
{
|
|
||||||
// This case may occur when user is experimenting e.g. with multiple generators or options.
|
|
||||||
// May also occur when user accidentally duplicates DocumentPath metadata.
|
|
||||||
Log.LogError(Resources.FormatDuplicateProjectDocumentPaths(documentPath));
|
|
||||||
}
|
|
||||||
|
|
||||||
MetadataSerializer.SetMetadata(newItem, "DocumentPath", documentPath);
|
|
||||||
|
|
||||||
// Add metadata which may be used as a property and passed to an inner build.
|
|
||||||
newItem.SetMetadata("SerializedMetadata", MetadataSerializer.SerializeMetadata(newItem));
|
|
||||||
}
|
|
||||||
|
|
||||||
Outputs = outputs.ToArray();
|
|
||||||
|
|
||||||
return !Log.HasLoggedErrors;
|
|
||||||
}
|
|
||||||
|
|
||||||
private string GetFullPath(string path)
|
|
||||||
{
|
|
||||||
if (!Path.IsPathRooted(path))
|
|
||||||
{
|
|
||||||
if (!string.IsNullOrEmpty(DocumentDirectory))
|
|
||||||
{
|
|
||||||
path = Path.Combine(DocumentDirectory, path);
|
|
||||||
}
|
|
||||||
|
|
||||||
path = Path.GetFullPath(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,124 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
|
||||||
<Project>
|
|
||||||
<PropertyGroup>
|
|
||||||
<_ApiDescriptionTasksAssemblyTarget
|
|
||||||
Condition="'$(MSBuildRuntimeType)' == 'Core'">netstandard2.0</_ApiDescriptionTasksAssemblyTarget>
|
|
||||||
<_ApiDescriptionTasksAssemblyTarget
|
|
||||||
Condition="'$(MSBuildRuntimeType)' != 'Core'">net461</_ApiDescriptionTasksAssemblyTarget>
|
|
||||||
<_ApiDescriptionTasksAssemblyPath>$(MSBuildThisFileDirectory)/../tasks/$(_ApiDescriptionTasksAssemblyTarget)/Microsoft.Extensions.ApiDescription.Tasks.dll</_ApiDescriptionTasksAssemblyPath>
|
|
||||||
<_ApiDescriptionTasksAssemblyTarget />
|
|
||||||
</PropertyGroup>
|
|
||||||
<UsingTask TaskName="GetCurrentItems" AssemblyFile="$(_ApiDescriptionTasksAssemblyPath)" />
|
|
||||||
<UsingTask TaskName="GetFileReferenceMetadata" AssemblyFile="$(_ApiDescriptionTasksAssemblyPath)" />
|
|
||||||
<UsingTask TaskName="GetProjectReferenceMetadata" AssemblyFile="$(_ApiDescriptionTasksAssemblyPath)" />
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Settings users may update as they see fit. All $(...Directory) values are interpreted relative to the client
|
|
||||||
project folder, unless already an absolute path.
|
|
||||||
-->
|
|
||||||
<PropertyGroup>
|
|
||||||
<ServiceProjectReferenceCheckIfNewer
|
|
||||||
Condition="'$(ServiceProjectReferenceCheckIfNewer)' == ''">true</ServiceProjectReferenceCheckIfNewer>
|
|
||||||
<ServiceProjectReferenceDirectory
|
|
||||||
Condition="'$(ServiceProjectReferenceDirectory)' != ''">$([MSBuild]::EnsureTrailingSlash('$(ServiceProjectReferenceDirectory)'))</ServiceProjectReferenceDirectory>
|
|
||||||
|
|
||||||
<ServiceFileReferenceCheckIfNewer
|
|
||||||
Condition="'$(ServiceFileReferenceCheckIfNewer)' == ''">true</ServiceFileReferenceCheckIfNewer>
|
|
||||||
<ServiceFileReferenceDirectory
|
|
||||||
Condition="'$(ServiceFileReferenceDirectory)' != ''">$([MSBuild]::EnsureTrailingSlash('$(ServiceFileReferenceDirectory)'))</ServiceFileReferenceDirectory>
|
|
||||||
|
|
||||||
<GenerateDefaultDocumentDefaultOptions Condition="'$(GenerateDefaultDocumentDefaultOptions)' == ''" />
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Well-known metadata of the code and document generator item groups. ServiceProjectReference items may also include
|
|
||||||
ServiceFileReference metadata.
|
|
||||||
-->
|
|
||||||
<ItemDefinitionGroup>
|
|
||||||
<ServiceProjectReference>
|
|
||||||
<!--
|
|
||||||
Name of the API description document generator. Builds will invoke a target named
|
|
||||||
"Generate%(DocumentGenerator)Document" to do actual document retrieval / generation.
|
|
||||||
-->
|
|
||||||
<DocumentGenerator>Default</DocumentGenerator>
|
|
||||||
|
|
||||||
<!-- Server project metadata which is likely applicable to all document generators. -->
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Server project's chosen configuration. Corresponds to $(Configuration) which likely matches client project's
|
|
||||||
$(Configuration).
|
|
||||||
-->
|
|
||||||
<Configuration />
|
|
||||||
<!--
|
|
||||||
Server project's extensions path. Corresponds to $(MSBuildProjectExtensionsPath). User must set this if
|
|
||||||
server project's value is not 'obj/'.
|
|
||||||
-->
|
|
||||||
<ProjectExtensionsPath />
|
|
||||||
<!-- Server project's target framework. Defaults to $(TargetFramework) or first of $(TargetFrameworks). -->
|
|
||||||
<TargetFramework />
|
|
||||||
<!--
|
|
||||||
Full path of the server project's generated assembly. Corresponds to $(TargetPath). Because common code builds
|
|
||||||
server projects, file exists prior to document generator invocation.
|
|
||||||
-->
|
|
||||||
<TargetPath />
|
|
||||||
<!--
|
|
||||||
Semicolon-separated list of targets in the server project that should be built. Default is empty, indicating
|
|
||||||
the default targets of the server project. Does not honor $(ProjectReferenceBuildTargets) because that property
|
|
||||||
is too general for these references and it's normally empty too.
|
|
||||||
-->
|
|
||||||
<Targets />
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Metadata specific to the Default document generator (though other document generators are free to use it).
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Options added to Default document generator tool's command line. Defaults to
|
|
||||||
$(GenerateDefaultDocumentDefaultOptions) if that is set in the client project.
|
|
||||||
-->
|
|
||||||
<GenerateDefaultDocumentOptions />
|
|
||||||
<!--
|
|
||||||
Name of the document to generate. Passed to the %(Method) when using Default document generator. Default is set
|
|
||||||
in server project, falling back to "v1".
|
|
||||||
-->
|
|
||||||
<DocumentName />
|
|
||||||
<!--
|
|
||||||
Full path where the API description document is placed. Default filename is %(Filename)_%(DocumentName).json.
|
|
||||||
Filenames and relative paths (if explicitly set) are combined with $(ServiceProjectReferenceDirectory).
|
|
||||||
-->
|
|
||||||
<DocumentPath />
|
|
||||||
<!--
|
|
||||||
Method Default document generator should invoke on the %(Service) to generate document.
|
|
||||||
Default is set in server project, falling back to "GenerateAsync".
|
|
||||||
-->
|
|
||||||
<Method />
|
|
||||||
<!--
|
|
||||||
Service Default document generator should retrieve from DI to generate document.
|
|
||||||
Default is set in server project, falling back to "Microsoft.Extensions.ApiDescription.IDocumentProvider".
|
|
||||||
-->
|
|
||||||
<Service />
|
|
||||||
</ServiceProjectReference>
|
|
||||||
|
|
||||||
<ServiceFileReference>
|
|
||||||
<!-- Name of the class to generate. Defaults to match final segment of %(OutputPath). -->
|
|
||||||
<ClassName />
|
|
||||||
<!--
|
|
||||||
Code generator to use. Required and must end with "CSharp" or "TypeScript" (the currently-supported target
|
|
||||||
languages) unless %(OutputPath) is set. Builds will invoke a target named "Generate%(CodeGenerator)" to do
|
|
||||||
actual code generation.
|
|
||||||
-->
|
|
||||||
<CodeGenerator />
|
|
||||||
<!--
|
|
||||||
Namespace to contain generated class. Default is $(RootNamespace).
|
|
||||||
-->
|
|
||||||
<Namespace />
|
|
||||||
<!--
|
|
||||||
Path to place generated code. Code generator may interpret path as a filename or directory. Default filename or
|
|
||||||
folder name is %(Filename)Client.[cs|ts]. Filenames and relative paths (if explicitly set) are combined with
|
|
||||||
$(ServiceFileReferenceDirectory). Final value (depending on $(ServiceFileReferenceDirectory)) is likely to be
|
|
||||||
a path relative to the client project.
|
|
||||||
-->
|
|
||||||
<OutputPath />
|
|
||||||
</ServiceFileReference>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
</Project>
|
|
||||||
|
|
@ -1,295 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
|
||||||
<Project>
|
|
||||||
<!-- Internal settings. Not intended for customization. -->
|
|
||||||
<PropertyGroup>
|
|
||||||
<GenerateServiceProjectReferenceDocumentsDependsOn>
|
|
||||||
_GetTargetFrameworkForServiceProjectReferences;
|
|
||||||
_GetTargetPathForServiceProjectReferences;
|
|
||||||
_GetMetadataForServiceProjectReferences;
|
|
||||||
_BuildServiceProjectReferences;
|
|
||||||
_GenerateServiceProjectReferenceDocuments;
|
|
||||||
_CreateFileItemsForServiceProjectReferences
|
|
||||||
</GenerateServiceProjectReferenceDocumentsDependsOn>
|
|
||||||
<GenerateServiceFileReferenceCodesDependsOn>
|
|
||||||
GenerateServiceProjectReferenceDocuments;
|
|
||||||
_GetMetadataForServiceFileReferences;
|
|
||||||
_GenerateServiceFileReferenceCodes;
|
|
||||||
_CreateCompileItemsForServiceFileReferences
|
|
||||||
</GenerateServiceFileReferenceCodesDependsOn>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<!-- ServiceProjectReference support -->
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Metadata setup phase 1: Ensure items have TargetFramework metadata. Calls GetTargetFrameworks in the target
|
|
||||||
project. Inputs and outputs cause MSBuild to run target unconditionally and to batch it (run once per project).
|
|
||||||
-->
|
|
||||||
<Target Name="_GetTargetFrameworkForServiceProjectReferences"
|
|
||||||
Inputs="%(ServiceProjectReference.FullPath)"
|
|
||||||
Outputs="<not-a-file !>">
|
|
||||||
<PropertyGroup>
|
|
||||||
<_FullPath>%(ServiceProjectReference.FullPath)</_FullPath>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<_Temporary Remove="@(_Temporary)" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<MSBuild Projects="$(_FullPath)"
|
|
||||||
RebaseOutputs="true"
|
|
||||||
RemoveProperties="TargetFramework;TargetFrameworks;RuntimeIdentifier"
|
|
||||||
Targets="GetTargetFrameworks"
|
|
||||||
UseResultsCache="true">
|
|
||||||
<Output TaskParameter="TargetOutputs" ItemName="_Temporary" />
|
|
||||||
</MSBuild>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Please excuse the mess necessary to extract information from _Temporary and use it in ServiceProjectReference.
|
|
||||||
-->
|
|
||||||
<PropertyGroup>
|
|
||||||
<_TargetFrameworks>%(_Temporary.TargetFrameworks)</_TargetFrameworks>
|
|
||||||
<_TargetFramework>$(_TargetFrameworks.Split(';')[0])</_TargetFramework>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ServiceProjectReference Update="@(ServiceProjectReference)" Condition="'%(FullPath)' == '$(_FullPath)'">
|
|
||||||
<TargetFramework Condition="'%(TargetFramework)' == ''">$(_TargetFramework)</TargetFramework>
|
|
||||||
</ServiceProjectReference>
|
|
||||||
<_Temporary Remove="@(_Temporary)" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<_FullPath />
|
|
||||||
<_TargetFramework />
|
|
||||||
<_TargetFrameworks />
|
|
||||||
</PropertyGroup>
|
|
||||||
</Target>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Metadata setup phase 2: Ensure items have TargetPath metadata. Calls GetTargetPath in the target project.
|
|
||||||
Inputs and outputs cause MSBuild to run target unconditionally and batch it (run once per TargetFramework x
|
|
||||||
project combination).
|
|
||||||
-->
|
|
||||||
<Target Name="_GetTargetPathForServiceProjectReferences"
|
|
||||||
Inputs="%(ServiceProjectReference.TargetFramework)%(FullPath)')"
|
|
||||||
Outputs="<not-a-file !>">
|
|
||||||
<PropertyGroup>
|
|
||||||
<_FullPath>%(ServiceProjectReference.FullPath)</_FullPath>
|
|
||||||
<_TargetFramework>%(ServiceProjectReference.TargetFramework)</_TargetFramework>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<_Temporary Remove="@(_Temporary)" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<MSBuild Projects="$(_FullPath)"
|
|
||||||
Properties="TargetFramework=$(_TargetFramework)"
|
|
||||||
RebaseOutputs="true"
|
|
||||||
RemoveProperties="TargetFrameworks;RuntimeIdentifier"
|
|
||||||
Targets="GetTargetPath"
|
|
||||||
UseResultsCache="true">
|
|
||||||
<Output TaskParameter="TargetOutputs" ItemName="_Temporary" />
|
|
||||||
</MSBuild>
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<_TargetPath>%(_Temporary.FullPath)</_TargetPath>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ServiceProjectReference Update="@(ServiceProjectReference)"
|
|
||||||
Condition="'%(FullPath)' == '$(_FullPath)' AND '%(TargetFramework)' == '$(_TargetFramework)'">
|
|
||||||
<TargetPath>$(_TargetPath)</TargetPath>
|
|
||||||
</ServiceProjectReference>
|
|
||||||
<_Temporary Remove="@(_Temporary)" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<_FullPath />
|
|
||||||
<_TargetPath />
|
|
||||||
<_TargetFramework />
|
|
||||||
</PropertyGroup>
|
|
||||||
</Target>
|
|
||||||
|
|
||||||
<!-- Metadata setup phase 3: Ensure items have DocumentPath metadata. -->
|
|
||||||
<Target Name="_GetMetadataForServiceProjectReferences" Condition="'@(ServiceProjectReference)' != ''">
|
|
||||||
<ItemGroup>
|
|
||||||
<_Temporary Remove="@(_Temporary)" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<GetProjectReferenceMetadata Inputs="@(ServiceProjectReference)"
|
|
||||||
DocumentDirectory="$(ServiceProjectReferenceDirectory)">
|
|
||||||
<Output TaskParameter="Outputs" ItemName="_Temporary" />
|
|
||||||
</GetProjectReferenceMetadata>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ServiceProjectReference Remove="@(ServiceProjectReference)" />
|
|
||||||
<ServiceProjectReference Include="@(_Temporary)" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<_Temporary Remove="@(_Temporary)" />
|
|
||||||
</ItemGroup>
|
|
||||||
</Target>
|
|
||||||
|
|
||||||
<Target Name="_BuildServiceProjectReferences"
|
|
||||||
Condition="'$(BuildProjectReferences)' == 'true'"
|
|
||||||
Inputs="@(ServiceProjectReference)"
|
|
||||||
Outputs="%(TargetPath)">
|
|
||||||
<MSBuild Projects="@(ServiceProjectReference -> Distinct())"
|
|
||||||
BuildInParallel="$(BuildInParallel)"
|
|
||||||
RemoveProperties="TargetFramework;TargetFrameworks;RuntimeIdentifier"
|
|
||||||
Targets="%(Targets)" />
|
|
||||||
</Target>
|
|
||||||
|
|
||||||
<Target Name="_GetCurrentServiceProjectReference">
|
|
||||||
<GetCurrentItems Input="$(GeneratorMetadata)">
|
|
||||||
<Output TaskParameter="Outputs" ItemName="CurrentServiceProjectReference" />
|
|
||||||
</GetCurrentItems>
|
|
||||||
</Target>
|
|
||||||
|
|
||||||
<Target Name="_GenerateServiceProjectReferenceDocument"
|
|
||||||
DependsOnTargets="_GetCurrentServiceProjectReference;$(GeneratorTarget)" />
|
|
||||||
|
|
||||||
<Target Name="_GenerateServiceProjectReferenceDocuments"
|
|
||||||
Inputs="@(ServiceProjectReference)"
|
|
||||||
Outputs="%(DocumentPath)">
|
|
||||||
<MSBuild BuildInParallel="$(BuildInParallel)"
|
|
||||||
Projects="$(MSBuildProjectFullPath)"
|
|
||||||
Properties="GeneratorTargetPath=%(ServiceProjectReference.DocumentPath);GeneratorTarget=Generate%(DocumentGenerator)Document;GeneratorMetadata=%(SerializedMetadata)"
|
|
||||||
RemoveProperties="TargetFrameworks"
|
|
||||||
Targets="_GenerateServiceProjectReferenceDocument" />
|
|
||||||
</Target>
|
|
||||||
|
|
||||||
<Target Name="_CreateFileItemsForServiceProjectReferences" Condition="'@(ServiceProjectReference)' != ''">
|
|
||||||
<!-- GetProjectReferenceMetadata task guarantees %(DocumentPath) values are unique. -->
|
|
||||||
<ItemGroup>
|
|
||||||
<ServiceFileReference Remove="@(ServiceProjectReference -> '%(DocumentPath)')" />
|
|
||||||
<!-- Condition here is temporary. Useful while GenerateDefaultDocument fails. -->
|
|
||||||
<ServiceFileReference Include="@(ServiceProjectReference -> '%(DocumentPath)')"
|
|
||||||
Condition="Exists('%(ServiceProjectReference.DocumentPath)')">
|
|
||||||
<SourceProject>%(ServiceProjectReference.FullPath)</SourceProject>
|
|
||||||
</ServiceFileReference>
|
|
||||||
</ItemGroup>
|
|
||||||
</Target>
|
|
||||||
|
|
||||||
<Target Name="GenerateServiceProjectReferenceDocuments"
|
|
||||||
DependsOnTargets="$(GenerateServiceProjectReferenceDocumentsDependsOn)" />
|
|
||||||
|
|
||||||
<!-- GenerateDefaultDocument -->
|
|
||||||
|
|
||||||
<Target Name="GenerateDefaultDocument">
|
|
||||||
<ItemGroup>
|
|
||||||
<!-- @(CurrentServiceProjectReference) item group will never contain more than one item. -->
|
|
||||||
<CurrentServiceProjectReference Update="@(CurrentServiceProjectReference)">
|
|
||||||
<Command>dotnet $(MSBuildThisFileDirectory)/../tools/dotnet-getdocument.dll --project "%(FullPath)"</Command>
|
|
||||||
<Configuration Condition="'%(Configuration)' == ''">$(Configuration)</Configuration>
|
|
||||||
<GenerateDefaultDocumentOptions
|
|
||||||
Condition="'%(GenerateDefaultDocumentOptions)' == ''">$(GenerateDefaultDocumentDefaultOptions)</GenerateDefaultDocumentOptions>
|
|
||||||
</CurrentServiceProjectReference>
|
|
||||||
<CurrentServiceProjectReference Update="@(CurrentServiceProjectReference)">
|
|
||||||
<Command>%(Command) --documentName "%(DocumentName)" --framework %(TargetFramework) --output "%(DocumentPath)"</Command>
|
|
||||||
</CurrentServiceProjectReference>
|
|
||||||
<CurrentServiceProjectReference Update="@(CurrentServiceProjectReference)">
|
|
||||||
<Command Condition="'%(Method)' != ''">%(Command) --method %(Method)</Command>
|
|
||||||
</CurrentServiceProjectReference>
|
|
||||||
<CurrentServiceProjectReference Update="@(CurrentServiceProjectReference)">
|
|
||||||
<Command Condition="'%(Service)' != ''">%(Command) --service %(Service)</Command>
|
|
||||||
</CurrentServiceProjectReference>
|
|
||||||
<CurrentServiceProjectReference Update="@(CurrentServiceProjectReference)">
|
|
||||||
<Command
|
|
||||||
Condition="'%(ProjectExtensionsPath)' != ''">%(Command) --projectExtensionsPath "%(ProjectExtensionsPath)"</Command>
|
|
||||||
</CurrentServiceProjectReference>
|
|
||||||
<CurrentServiceProjectReference Update="@(CurrentServiceProjectReference)">
|
|
||||||
<Command>%(Command) --configuration %(Configuration) %(GenerateDefaultDocumentOptions)</Command>
|
|
||||||
</CurrentServiceProjectReference>
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<Message Importance="high" Text="%0AGenerateDefaultDocument:" />
|
|
||||||
<Message Importance="high" Text=" %(CurrentServiceProjectReference.Command)" />
|
|
||||||
<Exec Command="%(CurrentServiceProjectReference.Command)"
|
|
||||||
IgnoreExitCode="$([System.IO.File]::Exists('%(DocumentPath)'))" />
|
|
||||||
</Target>
|
|
||||||
|
|
||||||
<!-- ServiceFileReference support -->
|
|
||||||
|
|
||||||
<Target Name="_GetMetadataForServiceFileReferences" Condition="'@(ServiceFileReference)' != ''">
|
|
||||||
<ItemGroup>
|
|
||||||
<_Temporary Remove="@(_Temporary)" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<GetFileReferenceMetadata Inputs="@(ServiceFileReference)"
|
|
||||||
Extension="$(DefaultLanguageSourceExtension)"
|
|
||||||
Namespace="$(RootNamespace)"
|
|
||||||
OutputDirectory="$(ServiceFileReferenceDirectory)">
|
|
||||||
<Output TaskParameter="Outputs" ItemName="_Temporary" />
|
|
||||||
</GetFileReferenceMetadata>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ServiceFileReference Remove="@(ServiceFileReference)" />
|
|
||||||
<ServiceFileReference Include="@(_Temporary)" />
|
|
||||||
<_Temporary Remove="@(_Temporary)" />
|
|
||||||
</ItemGroup>
|
|
||||||
</Target>
|
|
||||||
|
|
||||||
<Target Name="_GetCurrentServiceFileReference">
|
|
||||||
<GetCurrentItems Input="$(GeneratorMetadata)">
|
|
||||||
<Output TaskParameter="Outputs" ItemName="CurrentServiceFileReference" />
|
|
||||||
</GetCurrentItems>
|
|
||||||
</Target>
|
|
||||||
|
|
||||||
<Target Name="_GenerateServiceFileReferenceCode"
|
|
||||||
DependsOnTargets="_GetCurrentServiceFileReference;$(GeneratorTarget)" />
|
|
||||||
|
|
||||||
<Target Name="_GenerateServiceFileReferenceCodes" Inputs="@(ServiceFileReference)" Outputs="%(OutputPath)">
|
|
||||||
<MSBuild BuildInParallel="$(BuildInParallel)"
|
|
||||||
Projects="$(MSBuildProjectFullPath)"
|
|
||||||
Properties="GeneratorTargetPath=%(ServiceFileReference.OutputPath);GeneratorTarget=Generate%(CodeGenerator);GeneratorMetadata=%(SerializedMetadata)"
|
|
||||||
RemoveProperties="TargetFrameworks"
|
|
||||||
Targets="_GenerateServiceFileReferenceCode" />
|
|
||||||
</Target>
|
|
||||||
|
|
||||||
<Target Name="_CreateCompileItemsForServiceFileReferences" Condition="'@(ServiceFileReference)' != ''">
|
|
||||||
<!--
|
|
||||||
While %(DocumentPath) metadata may include duplicates, GetFileReferenceMetadata task guarantees %(OutputPath)
|
|
||||||
values are unique.
|
|
||||||
-->
|
|
||||||
<ItemGroup>
|
|
||||||
<_Files Remove="@(_Files)" />
|
|
||||||
<_Files Include="@(ServiceFileReference -> '%(OutputPath)')"
|
|
||||||
Condition="$([System.IO.File]::Exists('%(ServiceFileReference.OutputPath)'))">
|
|
||||||
<OutputPathExtension>$([System.IO.Path]::GetExtension('%(ServiceFileReference.OutputPath)'))</OutputPathExtension>
|
|
||||||
</_Files>
|
|
||||||
<_Directories Remove="@(_Directories)" />
|
|
||||||
<_Directories Include="@(ServiceFileReference -> '%(OutputPath)')"
|
|
||||||
Condition="Exists('%(ServiceFileReference.OutputPath)') AND ! $([System.IO.File]::Exists('%(ServiceFileReference.OutputPath)'))" />
|
|
||||||
|
|
||||||
<!-- If OutputPath is a file, add it directly to relevant items. -->
|
|
||||||
<TypeScriptCompile Remove="@(_Files)" Condition="'%(_Files.OutputPathExtension)' == '.ts'" />
|
|
||||||
<TypeScriptCompile Include="@(_Files)" Condition="'%(_Files.OutputPathExtension)' == '.ts'">
|
|
||||||
<SourceDocument>%(_Files.FullPath)</SourceDocument>
|
|
||||||
</TypeScriptCompile>
|
|
||||||
|
|
||||||
<Compile Remove="@(_Files)"
|
|
||||||
Condition="'$(DefaultLanguageSourceExtension)' != '.ts' AND '%(_Files.OutputPathExtension)' == '$(DefaultLanguageSourceExtension)'" />
|
|
||||||
<Compile Include="@(_Files)"
|
|
||||||
Condition="'$(DefaultLanguageSourceExtension)' != '.ts' AND '%(_Files.OutputPathExtension)' == '$(DefaultLanguageSourceExtension)'">
|
|
||||||
<SourceDocument>%(ServiceFileReference.FullPath)</SourceDocument>
|
|
||||||
</Compile>
|
|
||||||
|
|
||||||
<!-- Otherwise, add all descendant files with the expected extension. -->
|
|
||||||
<TypeScriptCompile Remove="@(_Directories -> '%(Identity)/**/*.ts')" />
|
|
||||||
<TypeScriptCompile Include="@(_Directories -> '%(Identity)/**/*.ts')">
|
|
||||||
<SourceDocument>%(_Directories.FullPath)</SourceDocument>
|
|
||||||
</TypeScriptCompile>
|
|
||||||
|
|
||||||
<Compile Remove="@(_Directories -> '%(Identity)/**/*.$(DefaultLanguageSourceExtension)')"
|
|
||||||
Condition="'$(DefaultLanguageSourceExtension)' != '.ts'" />
|
|
||||||
<Compile Include="@(_Directories -> '%(Identity)/**/*.$(DefaultLanguageSourceExtension)')"
|
|
||||||
Condition="'$(DefaultLanguageSourceExtension)' != '.ts'">
|
|
||||||
<SourceDocument>%(_Directories.FullPath)</SourceDocument>
|
|
||||||
</Compile>
|
|
||||||
|
|
||||||
<_Files Remove="@(_Files)" />
|
|
||||||
<_Directories Remove="@(_Directories)" />
|
|
||||||
</ItemGroup>
|
|
||||||
</Target>
|
|
||||||
|
|
||||||
<Target Name="GenerateServiceFileReferenceCodes"
|
|
||||||
BeforeTargets="BeforeCompile"
|
|
||||||
DependsOnTargets="$(GenerateServiceFileReferenceCodesDependsOn)" />
|
|
||||||
</Project>
|
|
||||||
|
|
@ -85,7 +85,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnet-getdocument", "dotne
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GetDocumentInsider", "GetDocumentInsider\src\GetDocumentInsider.csproj", "{2F683CF8-B055-46AE-BF83-9D1307F8D45F}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GetDocumentInsider", "GetDocumentInsider\src\GetDocumentInsider.csproj", "{2F683CF8-B055-46AE-BF83-9D1307F8D45F}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.ApiDescription.Design", "Extensions.ApiDescription.Design\src\Microsoft.Extensions.ApiDescription.Design.csproj", "{34E3C302-B767-40C8-B538-3EE2BD4000C4}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.ApiDescription.Client", "Extensions.ApiDescription.Client\src\Microsoft.Extensions.ApiDescription.Client.csproj", "{34E3C302-B767-40C8-B538-3EE2BD4000C4}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "_dependencies", "_dependencies", "{5FE3048A-E96B-44F8-A7C4-FC590D7E04B4}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "_dependencies", "_dependencies", "{5FE3048A-E96B-44F8-A7C4-FC590D7E04B4}"
|
||||||
EndProject
|
EndProject
|
||||||
|
|
@ -277,7 +277,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Mvc.Analyzers", "Mvc.Analyz
|
||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Mvc.Api.Analyzers", "Mvc.Api.Analyzers", "{49887FD5-2E52-4567-929E-9151DC88E4D4}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Mvc.Api.Analyzers", "Mvc.Api.Analyzers", "{49887FD5-2E52-4567-929E-9151DC88E4D4}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Extensions.ApiDescription.Design", "Extensions.ApiDescription.Design", "{62CF82C1-B75D-4041-A7E9-EF39FF7B885F}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Extensions.ApiDescription.Client", "Extensions.ApiDescription.Client", "{62CF82C1-B75D-4041-A7E9-EF39FF7B885F}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Mvc.Core.TestCommon", "shared\Mvc.Core.TestCommon\Microsoft.AspNetCore.Mvc.Core.TestCommon.csproj", "{2906BF70-82BE-4427-870A-E87281D01008}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Mvc.Core.TestCommon", "shared\Mvc.Core.TestCommon\Microsoft.AspNetCore.Mvc.Core.TestCommon.csproj", "{2906BF70-82BE-4427-870A-E87281D01008}"
|
||||||
EndProject
|
EndProject
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue