Remove batching requirements placed on code and document generator providers
- #8419 - perform batching and `@(ServiceFileReference)` and `@(Compile)` additions in common code - take advantage of new simplicity in `DefaultDocumentGenerator` target - add metadata serialization / deserialization in support of passing items into `<MSBuild />` - also ensure metadata values are escaped before calling `ITaskItem.SetMetadata(...)` - correct typos in Microsoft.Extensions.ApiDescription.Client.* e.g. in comments and metadata names - move last remaining `GenerationTasks` file nits: - combine `_ServiceProjectReferenceGenerator_Restore` and `_ServiceProjectReferenceGenerator_Build` targets - only build web sites projects once - remove unused `buildMultiTargeting` targets - remove qualification of metadata listed in an `<ItemDefinitionGroup />`; will always exist - add / remove a few `Condition`s that were missing / redundant - move properties users won't normally set to Microsoft.Extensions.ApiDescription.Client.targets - shorten lines in MSBuild files
This commit is contained in:
parent
3f001750ad
commit
87e304334d
|
|
@ -0,0 +1,34 @@
|
|||
// 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 Microsoft.Build.Framework;
|
||||
using Microsoft.Build.Utilities;
|
||||
|
||||
namespace Microsoft.Extensions.ApiDescription.Client
|
||||
{
|
||||
/// <summary>
|
||||
/// Restore <see cref="ITaskItem"/>s from given property value.
|
||||
/// </summary>
|
||||
public class GetCurrentItems : Task
|
||||
{
|
||||
/// <summary>
|
||||
/// The property value to deserialize.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public string Input { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The restored <see cref="ITaskItem"/>s. Will never contain more than one item.
|
||||
/// </summary>
|
||||
[Output]
|
||||
public ITaskItem[] Outputs { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool Execute()
|
||||
{
|
||||
Outputs = new[] { MetadataSerializer.DeserializeMetadata(Input) };
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -61,18 +61,21 @@ namespace Microsoft.Extensions.ApiDescription.Client
|
|||
if (string.IsNullOrEmpty(@namespace))
|
||||
{
|
||||
@namespace = isTypeScript ? CSharpNamespace : TypeScriptNamespace;
|
||||
newItem.SetMetadata("Namespace", @namespace);
|
||||
MetadataSerializer.SetMetadata(newItem, "Namespace", @namespace);
|
||||
}
|
||||
|
||||
var outputPath = item.GetMetadata("OutputPath");
|
||||
if (string.IsNullOrEmpty(outputPath))
|
||||
{
|
||||
var className = item.GetMetadata("ClassName");
|
||||
outputPath = className + (isTypeScript ? ".ts" : ".cs");
|
||||
outputPath = $"{className}{(isTypeScript ? ".ts" : ".cs")}";
|
||||
}
|
||||
|
||||
outputPath = GetFullPath(outputPath);
|
||||
newItem.SetMetadata("OutputPath", outputPath);
|
||||
MetadataSerializer.SetMetadata(newItem, "OutputPath", outputPath);
|
||||
|
||||
// Add metadata which may be used as a property and passed to an inner build.
|
||||
newItem.SetMetadata("SerializedMetadata", MetadataSerializer.SerializeMetadata(newItem));
|
||||
}
|
||||
|
||||
Outputs = outputs.ToArray();
|
||||
|
|
|
|||
|
|
@ -52,6 +52,8 @@ namespace Microsoft.Extensions.ApiDescription.Client
|
|||
outputPath = className + (isTypeScript ? ".ts" : ".cs");
|
||||
}
|
||||
|
||||
// Add metadata which may be used as a property and passed to an inner build.
|
||||
newItem.SetMetadata("SerializedMetadata", MetadataSerializer.SerializeMetadata(newItem));
|
||||
outputPath = GetFullPath(outputPath);
|
||||
newItem.SetMetadata("OutputPath", outputPath);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ namespace Microsoft.Extensions.ApiDescription.Client
|
|||
}
|
||||
|
||||
documentPath = GetFullPath(documentPath);
|
||||
newItem.SetMetadata("DocumentPath", documentPath);
|
||||
MetadataSerializer.SetMetadata(newItem, "DocumentPath", documentPath);
|
||||
}
|
||||
|
||||
Outputs = outputs.ToArray();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,147 @@
|
|||
// 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.Collections.Generic;
|
||||
using System.Text;
|
||||
using Microsoft.Build.Framework;
|
||||
using Microsoft.Build.Utilities;
|
||||
|
||||
namespace Microsoft.Extensions.ApiDescription.Client
|
||||
{
|
||||
/// <summary>
|
||||
/// Utility methods to serialize and deserialize <see cref="ITaskItem"/> metadata.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Based on and uses the same escaping as
|
||||
/// https://github.com/Microsoft/msbuild/blob/e70a3159d64f9ed6ec3b60253ef863fa883a99b1/src/Shared/EscapingUtilities.cs
|
||||
/// </remarks>
|
||||
public static class MetadataSerializer
|
||||
{
|
||||
private static readonly char[] CharsToEscape = { '%', '*', '?', '@', '$', '(', ')', ';', '\'' };
|
||||
private static readonly HashSet<char> CharsToEscapeHash = new HashSet<char>(CharsToEscape);
|
||||
|
||||
/// <summary>
|
||||
/// Add the given <paramref name="key"/> and <paramref name="value"/> to the <paramref name="item"/>. Or,
|
||||
/// modify existing value to be <paramref name="value"/>.
|
||||
/// </summary>
|
||||
/// <param name="item">The <see cref="ITaskItem"/> to update.</param>
|
||||
/// <param name="key">The name of the new metadata.</param>
|
||||
/// <param name="value">The value of the new metadata. Assumed to be unescaped.</param>
|
||||
/// <remarks>Uses same hex-encoded format as MSBuild's EscapeUtilities.</remarks>
|
||||
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());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serialize metadata for use as a property value passed into an inner build.
|
||||
/// </summary>
|
||||
/// <param name="item">The item to serialize.</param>
|
||||
/// <returns>A <see cref="string"/> containing the serialized metadata.</returns>
|
||||
/// <remarks>Uses same hex-encoded format as MSBuild's EscapeUtilities.</remarks>
|
||||
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();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recreate an <see cref="ITaskItem"/> with metadata encoded in given <paramref name="value"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The serialized metadata.</param>
|
||||
/// <returns>The deserialized <see cref="ITaskItem"/>.</returns>
|
||||
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))
|
||||
{
|
||||
builder.Append(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)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,49 +6,32 @@
|
|||
<_ApiDescriptionTasksAssemblyPath>$(MSBuildThisFileDirectory)/../tasks/$(_ApiDescriptionTasksAssemblyTarget)/Microsoft.Extensions.ApiDescription.Client.dll</_ApiDescriptionTasksAssemblyPath>
|
||||
<_ApiDescriptionTasksAssemblyTarget />
|
||||
</PropertyGroup>
|
||||
<UsingTask TaskName="GetCurrentItems" AssemblyFile="$(_ApiDescriptionTasksAssemblyPath)" />
|
||||
<UsingTask TaskName="GetFileReferenceMetadata" AssemblyFile="$(_ApiDescriptionTasksAssemblyPath)" />
|
||||
<UsingTask TaskName="GetProjectReferenceMetadata" AssemblyFile="$(_ApiDescriptionTasksAssemblyPath)" />
|
||||
<UsingTask TaskName="GetUriReferenceMetadata" AssemblyFile="$(_ApiDescriptionTasksAssemblyPath)" />
|
||||
<UsingTask TaskName="Microsoft.Extensions.ApiDescription.Client.DownloadFile" AssemblyFile="$(_ApiDescriptionTasksAssemblyPath)" />
|
||||
|
||||
<!-- Settings users may update as they see fit. -->
|
||||
<PropertyGroup>
|
||||
<ServiceProjectReferenceCheckIfNewer Condition="'$(ServiceProjectReferenceCheckIfNewer)' == ''">true</ServiceProjectReferenceCheckIfNewer>
|
||||
<ServiceProjectReferenceCheckIfNewer
|
||||
Condition="'$(ServiceProjectReferenceCheckIfNewer)' == ''">true</ServiceProjectReferenceCheckIfNewer>
|
||||
<ServiceProjectReferenceDirectory
|
||||
Condition="'$(ServiceProjectReferenceDirectory)' != ''">$([MSBuild]::EnsureTrailingSlash('$(ServiceProjectReferenceDirectory)'))</ServiceProjectReferenceDirectory>
|
||||
Condition="'$(ServiceProjectReferenceDirectory)' != ''">$([MSBuild]::EnsureTrailingSlash('$(ServiceProjectReferenceDirectory)'))</ServiceProjectReferenceDirectory>
|
||||
|
||||
<ServiceUriReferenceCheckIfNewer Condition="'$(ServiceUriReferenceCheckIfNewer)' == ''">true</ServiceUriReferenceCheckIfNewer>
|
||||
<ServiceUriReferenceCheckIfNewer
|
||||
Condition="'$(ServiceUriReferenceCheckIfNewer)' == ''">true</ServiceUriReferenceCheckIfNewer>
|
||||
<ServiceUriReferenceDirectory
|
||||
Condition="'$(ServiceUriReferenceDirectory)' != ''">$([MSBuild]::EnsureTrailingSlash('$(ServiceUriReferenceDirectory)'))</ServiceUriReferenceDirectory>
|
||||
Condition="'$(ServiceUriReferenceDirectory)' != ''">$([MSBuild]::EnsureTrailingSlash('$(ServiceUriReferenceDirectory)'))</ServiceUriReferenceDirectory>
|
||||
|
||||
<ServiceFileReferenceCheckIfNewer Condition="'$(ServiceFileReferenceCheckIfNewer)' == ''">true</ServiceFileReferenceCheckIfNewer>
|
||||
<ServiceFileReferenceCheckIfNewer
|
||||
Condition="'$(ServiceFileReferenceCheckIfNewer)' == ''">true</ServiceFileReferenceCheckIfNewer>
|
||||
<ServiceFileReferenceDirectory
|
||||
Condition="'$(ServiceFileReferenceDirectory)' != ''">$([MSBuild]::EnsureTrailingSlash('$(ServiceFileReferenceDirectory)'))</ServiceFileReferenceDirectory>
|
||||
<ServiceFileReferenceCSharpNamespace Condition="'$(ServiceFileReferenceCSharpNamespace)' == ''">$(RootNamespace)</ServiceFileReferenceCSharpNamespace>
|
||||
<ServiceFileReferenceTypeScriptNamespace Condition="'$(ServiceFileReferenceTypeScriptNamespace)' == ''">$(RootNamespace)</ServiceFileReferenceTypeScriptNamespace>
|
||||
|
||||
<DefaultDocumentGeneratorDependsOn>
|
||||
_DefaultDocumentGenerator_GetMetadata;
|
||||
_DefaultDocumentGenerator_Core;
|
||||
_DefaultDocumentGenerator_SetMetadata
|
||||
</DefaultDocumentGeneratorDependsOn>
|
||||
<ServiceProjectReferenceGeneratorDependsOn>
|
||||
_ServiceProjectReferenceGenerator_GetTargetFramework;
|
||||
_ServiceProjectReferenceGenerator_GetProjectTargetPath;
|
||||
_ServiceProjectReferenceGenerator_Restore;
|
||||
_ServiceProjectReferenceGenerator_Build;
|
||||
_ServiceProjectReferenceGenerator_Core
|
||||
</ServiceProjectReferenceGeneratorDependsOn>
|
||||
<ServiceUriReferenceGeneratorDependsOn>
|
||||
_ServiceUriReferenceGenerator_GetMetadata;
|
||||
_ServiceUriReferenceGenerator_Core
|
||||
</ServiceUriReferenceGeneratorDependsOn>
|
||||
<ServiceFileReferenceGeneratorDependsOn>
|
||||
_CheckServiceReferences;
|
||||
ServiceProjectReferenceGenerator;
|
||||
ServiceUriReferenceGenerator;
|
||||
_ServiceFileReferenceGenerator_GetMetadata;
|
||||
_ServiceFileReferenceGenerator_Core
|
||||
</ServiceFileReferenceGeneratorDependsOn>
|
||||
Condition="'$(ServiceFileReferenceDirectory)' != ''">$([MSBuild]::EnsureTrailingSlash('$(ServiceFileReferenceDirectory)'))</ServiceFileReferenceDirectory>
|
||||
<ServiceFileReferenceCSharpNamespace
|
||||
Condition="'$(ServiceFileReferenceCSharpNamespace)' == ''">$(RootNamespace)</ServiceFileReferenceCSharpNamespace>
|
||||
<ServiceFileReferenceTypeScriptNamespace
|
||||
Condition="'$(ServiceFileReferenceTypeScriptNamespace)' == ''">$(RootNamespace)</ServiceFileReferenceTypeScriptNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<!--
|
||||
|
|
@ -59,6 +42,33 @@
|
|||
<ServiceProjectReference>
|
||||
<!-- Name of the API description document generator. -->
|
||||
<DocumentGenerator>Default</DocumentGenerator>
|
||||
|
||||
<!-- Server project metadata which is likely applicable to all document generators. -->
|
||||
|
||||
<!--
|
||||
Full path of the project's generated assembly. Corresponds to $(TargetPath). Because common code builds server
|
||||
projects, file exists prior to document generator invocation.
|
||||
-->
|
||||
<ProjectAssemblyPath />
|
||||
<!-- Server project's chosen configuration. Likely matches client project's configuration. -->
|
||||
<ProjectConfiguration />
|
||||
<!--
|
||||
Server project's extensions path. Corresponds to $(MSBuildProjectExtensionsPath). User must set this if
|
||||
server project's value is not 'obj/'.
|
||||
-->
|
||||
<ProjectExtensionsPath />
|
||||
<!-- Runtime identifier to use when building the server project. -->
|
||||
<ProjectRuntimeIdentifier />
|
||||
<!-- Server project's target framework. Defaults to $(TargetFramewok) or first of $(TargetFrameworks). -->
|
||||
<ProjectTargetFramework />
|
||||
|
||||
<!-- 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
|
||||
$(DefaultDocumentGeneratorDefaultOptions) if that is set in the client project.
|
||||
-->
|
||||
<DefaultDocumentGeneratorOptions />
|
||||
<!--
|
||||
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".
|
||||
|
|
@ -84,36 +94,19 @@
|
|||
the %(Service) fails. Default is set in server project and metadata has no further fallback.
|
||||
-->
|
||||
<Uri />
|
||||
|
||||
<!--
|
||||
Full path of the project's generated assembly. Corresponds to $(TargetPath). Because common code builds server
|
||||
projects, file exists prior to document generator invocation.
|
||||
-->
|
||||
<ProjectAssemblyPath />
|
||||
<!-- Server project's chosen configuration. Likely matches client project's configuration. -->
|
||||
<ProjectConfiguration />
|
||||
<!--
|
||||
Server project's extensions path. Corresponds to $(MSBuildProjectExtensionsPath). Must set this if project's
|
||||
value is not 'obj/'.
|
||||
-->
|
||||
<ProjectExtensionsPath />
|
||||
<!-- Runtime identifier to use when building the server project. -->
|
||||
<ProjectRuntimeIdentifier />
|
||||
<!-- Server project's target framework. Defaults to $(TargetFramewok) or first of $(TargetFrameworks). -->
|
||||
<ProjectTargetFramework />
|
||||
</ServiceProjectReference>
|
||||
|
||||
<ServiceUriReference>
|
||||
<!--
|
||||
Full path where the API description document is placed. Default filename is based on %(Identity).
|
||||
Filenames and relative paths (if explicitly set) are combined with $(ServiceProjectReferenceDirectory).
|
||||
Filenames and relative paths (if explicitly set) are combined with $(ServiceUriReferenceDirectory).
|
||||
-->
|
||||
<DocumentPath />
|
||||
</ServiceUriReference>
|
||||
|
||||
<ServiceFileReference>
|
||||
<!-- Name of the class to generate. -->
|
||||
<ClassName>%(Filename)Client</ClassName>
|
||||
<!-- Name of the class to generate. Defaults to %(Filename)Client but with an uppercase first letter. -->
|
||||
<ClassName />
|
||||
<!-- Code generator to use. Required. -->
|
||||
<CodeGenerator />
|
||||
<!--
|
||||
|
|
@ -124,7 +117,7 @@
|
|||
<!--
|
||||
Path to place generated code. Code generator may interpret path as a filename or directory. Default filename or
|
||||
folder name is %(ClassName).[cs|ts]. Filenames and relative paths (if explicitly set) are combined with
|
||||
$(ServiceProjectReferenceDirectory).
|
||||
$(ServiceFileReferenceDirectory).
|
||||
-->
|
||||
<OutputPath />
|
||||
</ServiceFileReference>
|
||||
|
|
|
|||
|
|
@ -1,11 +1,34 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<Project>
|
||||
<!-- Internal settings for Microsoft.Extensions.ApiDescription.Client.targets use. Not intended for customization. -->
|
||||
<PropertyGroup>
|
||||
<ServiceProjectReferenceGeneratorDependsOn>
|
||||
_ServiceProjectReferenceGenerator_GetTargetFramework;
|
||||
_ServiceProjectReferenceGenerator_GetProjectTargetPath;
|
||||
_ServiceProjectReferenceGenerator_Build;
|
||||
_ServiceProjectReferenceGenerator_Core;
|
||||
_ServiceProjectReferenceGenerator_SetMetadata
|
||||
</ServiceProjectReferenceGeneratorDependsOn>
|
||||
<ServiceUriReferenceGeneratorDependsOn>
|
||||
_ServiceUriReferenceGenerator_GetMetadata;
|
||||
_ServiceUriReferenceGenerator_Core
|
||||
</ServiceUriReferenceGeneratorDependsOn>
|
||||
<ServiceFileReferenceGeneratorDependsOn>
|
||||
_CheckServiceReferences;
|
||||
ServiceProjectReferenceGenerator;
|
||||
ServiceUriReferenceGenerator;
|
||||
_ServiceFileReferenceGenerator_GetMetadata;
|
||||
_ServiceFileReferenceGenerator_Core;
|
||||
_ServiceFileReferenceGenerator_SetMetadata
|
||||
</ServiceFileReferenceGeneratorDependsOn>
|
||||
</PropertyGroup>
|
||||
|
||||
<Target Name="_CheckServiceReferences">
|
||||
<Error Condition="'@(ServiceProjectReference)' != '' AND '%(ServiceProjectReference.CodeGenerator)' == ''"
|
||||
<Error Condition="'@(ServiceProjectReference)' != '' AND '%(CodeGenerator)' == ''"
|
||||
Text="ServiceProjectReference items '@(ServiceProjectReference)' lack CodeGenerator metadata." />
|
||||
<Error Condition="'@(ServiceUriReference)' != '' AND '%(ServiceUriReference.CodeGenerator)' == ''"
|
||||
<Error Condition="'@(ServiceUriReference)' != '' AND '%(CodeGenerator)' == ''"
|
||||
Text="ServiceUriReference items '@(ServiceUriReference)' lack CodeGenerator metadata." />
|
||||
<Error Condition="'@(ServiceFileReference)' != '' AND '%(ServiceFileReference.CodeGenerator)' == ''"
|
||||
<Error Condition="'@(ServiceFileReference)' != '' AND '%(CodeGenerator)' == ''"
|
||||
Text="ServiceFileReference items '@(ServiceFileReference)' lack CodeGenerator metadata." />
|
||||
</Target>
|
||||
|
||||
|
|
@ -38,7 +61,7 @@
|
|||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ServiceProjectReference Update="@(ServiceProjectReference)" Condition="'%(FullPath)' == '$(_FullPath)'">
|
||||
<TargetFramework Condition="'%(ServiceProjectReference.TargetFramework)' == ''">$(_TargetFramework)</TargetFramework>
|
||||
<ProjectTargetFramework Condition="'%(ProjectTargetFramework)' == ''">$(_TargetFramework)</ProjectTargetFramework>
|
||||
</ServiceProjectReference>
|
||||
<_Temporary Remove="@(_Temporary)" />
|
||||
</ItemGroup>
|
||||
|
|
@ -53,17 +76,19 @@
|
|||
<!-- Metadata setup phase 2: Ensure items have ProjectTargetPath metadata. Call 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="_ServiceProjectReferenceGenerator_GetProjectTargetPath"
|
||||
Inputs="%(ServiceProjectReference.TargetFramework)%(FullPath)"
|
||||
Outputs="<not-a-file !>">
|
||||
Inputs="%(ServiceProjectReference.TargetFramework)%(FullPath)')"
|
||||
Outputs="<not-a-file !>">
|
||||
<PropertyGroup>
|
||||
<_FullPath>%(ServiceProjectReference.FullPath)</_FullPath>
|
||||
<_TargetFramework>%(ServiceProjectReference.TargetFramework)</_TargetFramework>
|
||||
<_TargetFramework>%(ServiceProjectReference.ProjectTargetFramework)</_TargetFramework>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<_Temporary Remove="@(_Temporary)" />
|
||||
</ItemGroup>
|
||||
|
||||
<Message Importance="high" Text="%0A_ServiceProjectReferenceGenerator_GetProjectTargetPath: '$(_FullPath)' '$(_TargetFramework)'" />
|
||||
<Message
|
||||
Importance="high"
|
||||
Text="%0A_ServiceProjectReferenceGenerator_GetProjectTargetPath: '$(_FullPath)' '$(_TargetFramework)'" />
|
||||
<MSBuild Projects="$(_FullPath)"
|
||||
Properties="TargetFramework=$(_TargetFramework)"
|
||||
RebaseOutputs="true"
|
||||
|
|
@ -78,7 +103,7 @@
|
|||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ServiceProjectReference Update="@(ServiceProjectReference)"
|
||||
Condition="'%(FullPath)' == '$(_FullPath)' AND '%(ServiceProjectReference.TargetFramework)' == '$(_TargetFramework)'">
|
||||
Condition="'%(ServiceProjectReference.FullPath)' == '$(_FullPath)' AND '%(ProjectTargetFramework)' == '$(_TargetFramework)'">
|
||||
<ProjectTargetPath>$(_ProjectTargetPath)</ProjectTargetPath>
|
||||
</ServiceProjectReference>
|
||||
<_Temporary Remove="@(_Temporary)" />
|
||||
|
|
@ -91,99 +116,85 @@
|
|||
</PropertyGroup>
|
||||
</Target>
|
||||
|
||||
<Target Name="_ServiceProjectReferenceGenerator_Restore"
|
||||
Condition="'$(BuildProjectReferences)' == 'true'"
|
||||
Inputs="@(ServiceProjectReference)"
|
||||
Outputs="@(ServiceProjectReference -> '%(Directory)obj\project.assets.json')">
|
||||
<MSBuild Projects="@(ServiceProjectReference -> '%(FullPath)')"
|
||||
BuildInParallel="$(BuildInParallel)"
|
||||
RemoveProperties="TargetFramework;TargetFrameworks;RuntimeIdentifier"
|
||||
Targets="Restore" />
|
||||
</Target>
|
||||
|
||||
<Target Name="_ServiceProjectReferenceGenerator_Build"
|
||||
Condition="'$(BuildProjectReferences)' == 'true'"
|
||||
Inputs="@(ServiceProjectReference)"
|
||||
Outputs="@(ServiceProjectReference -> '%(ProjectTargetPath)')">
|
||||
<MSBuild Projects="@(ServiceProjectReference)"
|
||||
Outputs="%(ProjectTargetPath)">
|
||||
<MSBuild Projects="@(ServiceProjectReference -> Distinct())"
|
||||
BuildInParallel="$(BuildInParallel)"
|
||||
RemoveProperties="TargetFrameworks;RuntimeIdentifier"
|
||||
Targets="Build" />
|
||||
RemoveProperties="TargetFramework;TargetFrameworks;RuntimeIdentifier"
|
||||
Targets="Restore;Build" />
|
||||
</Target>
|
||||
|
||||
<Target Name="_ServiceProjectReferenceGenerator_Core"
|
||||
Condition="'@(ServiceProjectReference)' != ''"
|
||||
DependsOnTargets="@(ServiceProjectReference -> '%(DocumentGenerator)DocumentGenerator')" />
|
||||
<Target Name="_ServiceProjectReferenceGenerator_GetItems">
|
||||
<GetCurrentItems Input="$(GeneratorMetadata)">
|
||||
<Output TaskParameter="Outputs" ItemName="CurrentServiceProjectReference" />
|
||||
</GetCurrentItems>
|
||||
</Target>
|
||||
|
||||
<Target Name="ServiceProjectReferenceGenerator"
|
||||
Condition="'@(ServiceProjectReference)' != ''"
|
||||
DependsOnTargets="$(ServiceProjectReferenceGeneratorDependsOn)" />
|
||||
<Target Name="_ServiceProjectReferenceGenerator_Inner" DependsOnTargets="_ServiceProjectReferenceGenerator_GetItems;$(GeneratorTarget)" />
|
||||
|
||||
<Target Name="_ServiceProjectReferenceGenerator_Core" Inputs="@(ServiceProjectReference)" Outputs="%(DocumentPath)">
|
||||
<Message Importance="high" Text="%0A_ServiceProjectReferenceGenerator_Core:" />
|
||||
<Message Importance="high" Text=" @(ServiceProjectReference): %(DocumentPath)" />
|
||||
|
||||
<MSBuild BuildInParallel="$(BuildInParallel)"
|
||||
Projects="$(MSBuildProjectFullPath)"
|
||||
Properties="GeneratorTargetPath=%(ServiceProjectReference.DocumentPath);GeneratorTarget=%(DocumentGenerator)DocumentGenerator;GeneratorMetadata=%(SerializedMetadata);TargetFramework=%(ProjectTargetFramework)"
|
||||
RemoveProperties="TargetFrameworks;RuntimeIdentifier"
|
||||
Targets="_ServiceProjectReferenceGenerator_Inner" />
|
||||
</Target>
|
||||
|
||||
<Target Name="_ServiceProjectReferenceGenerator_SetMetadata" Condition="'@(ServiceProjectReference)' != ''">
|
||||
<!-- _ServiceProjectReferenceGenerator_GetMetadata guarantees %(DocumentPath) values are unique. -->
|
||||
<ItemGroup>
|
||||
<ServiceFileReference Remove="@(ServiceProjectReference -> '%(DocumentPath)')" />
|
||||
<!-- Condition here is temporary. Useful while DefaultDocumentGenerator fails. -->
|
||||
<ServiceFileReference Include="@(ServiceProjectReference -> '%(DocumentPath)')"
|
||||
Condition="Exists('%(DocumentPath)')"
|
||||
SourceProject="%(FullPath)" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
<Target Name="ServiceProjectReferenceGenerator" DependsOnTargets="$(ServiceProjectReferenceGeneratorDependsOn)" />
|
||||
|
||||
<!-- DefaultDocumentGenerator -->
|
||||
|
||||
<Target Name="_DefaultDocumentGenerator_GetMetadata">
|
||||
<Target Name="DefaultDocumentGenerator">
|
||||
<Message Importance="high" Text="%0ADefaultDocumentGenerator:" />
|
||||
<Message Importance="high" Text=" @(CurrentServiceProjectReference): %(DocumentPath)" />
|
||||
|
||||
<ItemGroup>
|
||||
<_Temporary Remove="@(_Temporary)" />
|
||||
<_Temporary Include="@(ServiceProjectReference -> WithMetadataValue('DocumentGenerator', 'Default'))" />
|
||||
<!-- @(CurrentServiceProjectReference) item group will never contain more than one item. -->
|
||||
<CurrentServiceProjectReference Update="@(CurrentServiceProjectReference)">
|
||||
<Command>dotnet getdocument --no-build --project %(FullPath) --output %(DocumentPath)</Command>
|
||||
<DefaultDocumentGeneratorOptions
|
||||
Condition="'%(DefaultDocumentGeneratorOptions)' == ''">$(DefaultDocumentGeneratorDefaultOptions)</DefaultDocumentGeneratorOptions>
|
||||
</CurrentServiceProjectReference>
|
||||
<CurrentServiceProjectReference Update="@(_Temporary)">
|
||||
<Command>%(Command) --framework %(ProjectTargetFramework)</Command>
|
||||
<Command Condition="'%(ProjectConfiguration)' == ''">%(Command) --configuration $(Configuration)</Command>
|
||||
<Command Condition="'%(ProjectConfiguration)' != ''">%(Command) --configuration %(ProjectConfiguration)</Command>
|
||||
<Command Condition="'%(Method)' != ''">%(Command) --method %(Method)</Command>
|
||||
<Command Condition="'%(Service)' != ''">%(Command) --service %(Service)</Command>
|
||||
<Command Condition="'%(Uri)' != ''">%(Command) --uri %(Uri)</Command>
|
||||
<Command
|
||||
Condition="'%(DefaultDocumentGeneratorOptions)' != ''">%(Command) %(DefaultDocumentGeneratorOptions)</Command>
|
||||
</CurrentServiceProjectReference>
|
||||
</ItemGroup>
|
||||
|
||||
<Error Condition="'@(_Temporary)' != '' AND '%(_Temporary.Method)' != '' AND '%(_Temporary.Uri)' != ''"
|
||||
Text="ServiceProjectReference items '@(_Temporary)' have both Method and Uri metadata." />
|
||||
<Error Condition="'@(_Temporary)' != '' AND '%(_Temporary.Service)' != '' AND '%(_Temporary.Uri)' != ''"
|
||||
Text="ServiceProjectReference items '@(_Temporary)' have both Service and Uri metadata." />
|
||||
<Message Importance="high" Text="%0A%(CurrentServiceProjectReference.Command)" />
|
||||
<Exec IgnoreExitCode="$([System.IO.File]::Exists('%(DocumentPath)'))" Command="%(CurrentServiceProjectReference.Command)" />
|
||||
</Target>
|
||||
|
||||
<Target Name="_DefaultDocumentGenerator_Core" Inputs="%(_Temporary.ProjectTargetPath)" Outputs="%(_Temporary.DocumentPath)">
|
||||
<!-- aspnetcore2swagger -->
|
||||
<PropertyGroup>
|
||||
<_Command>dotnet getdocument --configuration $(Configuration) --no-build</_Command>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<_Temporary Update="@(_Temporary)">
|
||||
<Options
|
||||
Condition="'%(_Temporary.Options)' == '' AND '$(DefaultDocumentGeneratorDefaultOptions)' != ''">$(DefaultDocumentGeneratorDefaultOptions)</Options>
|
||||
<Command>$(_Command) --project %(FullPath) --output %(DocumentPath) --framework %(TargetFramework)</Command>
|
||||
</_Temporary>
|
||||
<_Temporary Update="@(_Temporary)">
|
||||
<Command Condition="'%(_Temporary.Uri)' != ''">%(Command) --uri %(_Temporary.Uri)</Command>
|
||||
</_Temporary>
|
||||
<_Temporary Update="@(_Temporary)">
|
||||
<Command Condition="'%(_Temporary.Service)' != ''">%(Command) --service %(_Temporary.Service) --method %(_Temporary.Method)</Command>
|
||||
</_Temporary>
|
||||
<_Temporary Update="@(_Temporary)">
|
||||
<Command Condition="'%(_Temporary.Options)' != ''">%(Command) %(_Temporary.Options)</Command>
|
||||
</_Temporary>
|
||||
</ItemGroup>
|
||||
|
||||
<Message Importance="high" Text="%0A%(_Temporary.Command)" />
|
||||
<Exec IgnoreExitCode="$([System.IO.File]::Exists('%(DocumentPath)'))" Command="%(_Temporary.Command)" />
|
||||
</Target>
|
||||
|
||||
<!--
|
||||
Separate from _DefaultDocumentGenerator_Core to ensure ServiceFileReference items are complete even if
|
||||
ServiceProjectReference items are not built in any batch.
|
||||
-->
|
||||
<Target Name="_DefaultDocumentGenerator_SetMetadata" Condition="'@(_Temporary)' != ''">
|
||||
<ItemGroup>
|
||||
<ServiceFileReference Remove="@(_Temporary -> '%(DocumentPath)')" />
|
||||
<!-- Condition here is temporary. Useful while DefaultDocumentGenerator fails. -->
|
||||
<ServiceFileReference Include="@(_Temporary -> '%(DocumentPath)')"
|
||||
Condition="Exists('%(_Temporary.DocumentPath)')"
|
||||
SourceProject="%(_Temporary.FullPath)" />
|
||||
<_Temporary Remove="@(_Temporary)" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
<Target Name="DefaultDocumentGenerator" DependsOnTargets="$(DefaultDocumentGeneratorDependsOn)" />
|
||||
|
||||
<!-- ServiceUriReference support -->
|
||||
|
||||
<Target Name="_ServiceUriReferenceGenerator_GetMetadata">
|
||||
<Target Name="_ServiceUriReferenceGenerator_GetMetadata" Condition="'@(ServiceUriReference)' != ''">
|
||||
<ItemGroup>
|
||||
<_Temporary Remove="@(_Temporary)" />
|
||||
</ItemGroup>
|
||||
|
||||
<GetUriReferenceMetadata DocumentDirectory="$(ServiceUriReferenceDirectory)" Inputs="@(ServiceUriReference)">
|
||||
<GetUriReferenceMetadata Inputs="@(ServiceUriReference)" DocumentDirectory="$(ServiceUriReferenceDirectory)">
|
||||
<Output TaskParameter="Outputs" ItemName="_Temporary" />
|
||||
</GetUriReferenceMetadata>
|
||||
|
||||
|
|
@ -199,9 +210,10 @@
|
|||
DestinationPath="%(DocumentPath)"
|
||||
Overwrite="$(ServiceUriReferenceCheckIfNewer)" />
|
||||
|
||||
<!-- _ServiceUriReferenceGenerator_GetMetadata guarantees %(DocumentPath) values are unique. -->
|
||||
<ItemGroup>
|
||||
<ServiceFileReference Remove="@(ServiceUriReference -> '%(DocumentPath)')" />
|
||||
<ServiceFileReference Include="@(ServiceUriReference -> '%(DocumentPath)')" SourceUri="%(ServiceUriReference.Identity)" />
|
||||
<ServiceFileReference Include="@(ServiceUriReference -> '%(DocumentPath)')" SourceUri="%(Identity)" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
|
|
@ -209,12 +221,15 @@
|
|||
|
||||
<!-- ServiceFileReference support -->
|
||||
|
||||
<Target Name="_ServiceFileReferenceGenerator_GetMetadata">
|
||||
<Target Name="_ServiceFileReferenceGenerator_GetMetadata" Condition="'@(ServiceFileReference)' != ''">
|
||||
<ItemGroup>
|
||||
<_Temporary Remove="@(_Temporary)" />
|
||||
</ItemGroup>
|
||||
|
||||
<GetFileReferenceMetadata DocumentDirectory="$(ServiceFileReferenceDirectory)" Inputs="@(ServiceFileReference)">
|
||||
<GetFileReferenceMetadata Inputs="@(ServiceFileReference)"
|
||||
CSharpNamespace="$(ServiceFileReferenceCSharpNamespace)"
|
||||
OutputDirectory="$(ServiceFileReferenceDirectory)"
|
||||
TypeScriptNamespace="$(ServiceFileReferenceTypeScriptNamespace)">
|
||||
<Output TaskParameter="Outputs" ItemName="_Temporary" />
|
||||
</GetFileReferenceMetadata>
|
||||
|
||||
|
|
@ -225,9 +240,38 @@
|
|||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
<Target Name="_ServiceFileReferenceGenerator_Core"
|
||||
Condition="'@(ServiceFileReference)' != ''"
|
||||
DependsOnTargets="@(ServiceFileReference -> '%(CodeGenerator)CodeGenerator')" />
|
||||
<Target Name="_ServiceFileReferenceGenerator_GetItems">
|
||||
<GetCurrentItems Input="$(GeneratorMetadata)">
|
||||
<Output TaskParameter="Outputs" ItemName="CurrentServiceFileReference" />
|
||||
</GetCurrentItems>
|
||||
</Target>
|
||||
|
||||
<Target Name="ServiceFileReferenceGenerator" BeforeTargets="BeforeCompile" DependsOnTargets="$(ServiceFileReferenceGeneratorDependsOn)" />
|
||||
<Target Name="_ServiceFileReferenceGenerator_Inner" DependsOnTargets="_ServiceFileReferenceGenerator_GetItems;$(GeneratorTarget)" />
|
||||
|
||||
<Target Name="_ServiceFileReferenceGenerator_Core" Inputs="@(ServiceFileReference)" Outputs="%(OutputPath)">
|
||||
<Message Importance="high" Text="%0A_ServiceFileReferenceGenerator_Core:" />
|
||||
<Message Importance="high" Text=" @(ServiceFileReference): %(DocumentPath)" />
|
||||
|
||||
<MSBuild BuildInParallel="$(BuildInParallel)"
|
||||
Projects="$(MSBuildProjectFullPath)"
|
||||
Properties="GeneratorTargetPath=%(ServiceProjectReference.OutputPath);GeneratorTarget=%(CodeGenerator)CodeGenerator;GeneratorMetadata=%(SerializedMetadata);TargetFramework=%(ProjectTargetFramework)"
|
||||
RemoveProperties="TargetFrameworks;RuntimeIdentifier"
|
||||
Targets="_ServiceFileReferenceGenerator_Inner" />
|
||||
</Target>
|
||||
|
||||
<Target Name="_ServiceFileReferenceGenerator_SetMetadata" Condition="'@(ServiceFileReference)' != ''">
|
||||
<!--
|
||||
While %(DocumentPath) metadata may include duplicates (due to overlaps between ServiceUriReference and
|
||||
ServiceProjectReference items), _ServiceFileReferenceGenerator_GetMetadata guarantees %(OutputPath) values are
|
||||
unique.
|
||||
-->
|
||||
<ItemGroup>
|
||||
<Compile Remove="@(ServiceFileReference -> '%(OutputPath)')" />
|
||||
<Compile Include="@(ServiceFileReference -> '%(OutputPath)')" SourceDocument="%(FullPath)" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
<Target Name="ServiceFileReferenceGenerator"
|
||||
BeforeTargets="BeforeCompile"
|
||||
DependsOnTargets="$(ServiceFileReferenceGeneratorDependsOn)" />
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -1,29 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<Project>
|
||||
<!-- ServiceProjectReference support -->
|
||||
|
||||
<Target Name="ServiceProjectReferenceGenerator">
|
||||
<MsBuild Projects="$(MSBuildProjectFile)"
|
||||
Targets="ServiceProjectReferenceGenerator"
|
||||
Properties="TargetFramework=$(TargetFrameworks.Split(';')[0])"
|
||||
RemoveProperties="TargetFrameworks;RuntimeIdentifier" />
|
||||
</Target>
|
||||
|
||||
<!-- ServiceUriReference support -->
|
||||
|
||||
<Target Name="ServiceUriReferenceGenerator">
|
||||
<MsBuild Projects="$(MSBuildProjectFile)"
|
||||
Targets="ServiceUriReferenceGenerator"
|
||||
Properties="TargetFramework=$(TargetFrameworks.Split(';')[0])"
|
||||
RemoveProperties="TargetFrameworks;RuntimeIdentifier" />
|
||||
</Target>
|
||||
|
||||
<!-- ServiceFileReference support -->
|
||||
|
||||
<Target Name="ServiceFileReferenceGenerator" BeforeTargets="BeforeCompile">
|
||||
<MsBuild Projects="$(MSBuildProjectFile)"
|
||||
Targets="ServiceFileReferenceGenerator"
|
||||
Properties="TargetFramework=$(TargetFrameworks.Split(';')[0])"
|
||||
RemoveProperties="TargetFrameworks;RuntimeIdentifier" />
|
||||
</Target>
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<Project>
|
||||
<Target Name="ServiceFileReferenceGenerator" BeforeTargets="BeforeCompile">
|
||||
<MsBuild Projects="$(MSBuildProjectFile)"
|
||||
Targets="ServiceFileReferenceGenerator"
|
||||
Properties="TargetFramework=$(TargetFrameworks.Split(';')[0])"
|
||||
RemoveProperties="TargetFrameworks;RuntimeIdentifier" />
|
||||
</Target>
|
||||
</Project>
|
||||
Loading…
Reference in New Issue