Skip to content

Commit 2567233

Browse files
authored
Add more properties controlling service reference code generation (#10641)
- `$(OpenApiGenerateCodeOnBuild)` controls if targets run before compile targets - #4924 - also correct multiple invocations when project has multiple target frameworks - `$(OpenApiBuildReferencedProjects)` controls whether `@(OpenApiProjectReference)` items build automatically - #6582 - rename a few other properties and targets also: - add symbols for Microsoft.Extensions.ApiDescription.Client task assembly - #10508 - unconditionally run `OpenApiGetDocuments` target in referenced projects - corrects compilation in design-time builds - no longer uses `@(ProjectReferenceWithConfiguration)`; referenced project chooses all property values nits: - consolidate into a single `$(GenerateOpenApiCodeDependsOn)` property - rename task assembly and namespaces in Microsoft.Extensions.ApiDesription.Client to match the project - allow `OpenApiGetDocuments` targets to run in parallel if `$(BuildInParallel)` is enabled - remove `$(OpenApiCodeDirectory)` normalization; never concatenated with anything else
1 parent 4c8ca0b commit 2567233

12 files changed

+103
-65
lines changed

eng/ProjectReferences.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
<ProjectReferenceProvider Include="Microsoft.AspNetCore.Identity.Specification.Tests" ProjectPath="$(RepoRoot)src\Identity\Specification.Tests\src\Microsoft.AspNetCore.Identity.Specification.Tests.csproj" />
99
<ProjectReferenceProvider Include="Microsoft.Web.Xdt.Extensions" ProjectPath="$(RepoRoot)src\SiteExtensions\Microsoft.Web.Xdt.Extensions\src\Microsoft.Web.Xdt.Extensions.csproj" />
1010
<ProjectReferenceProvider Include="Microsoft.AspNetCore.DeveloperCertificates.XPlat" ProjectPath="$(RepoRoot)src\Tools\FirstRunCertGenerator\src\Microsoft.AspNetCore.DeveloperCertificates.XPlat.csproj" />
11-
<ProjectReferenceProvider Include="Microsoft.Extensions.ApiDescription.Tasks" ProjectPath="$(RepoRoot)src\Mvc\Extensions.ApiDescription.Client\src\Microsoft.Extensions.ApiDescription.Client.csproj" />
11+
<ProjectReferenceProvider Include="Microsoft.Extensions.ApiDescription.Client" ProjectPath="$(RepoRoot)src\Mvc\Extensions.ApiDescription.Client\src\Microsoft.Extensions.ApiDescription.Client.csproj" />
1212
<ProjectReferenceProvider Include="Microsoft.AspNetCore.SignalR.Specification.Tests" ProjectPath="$(RepoRoot)src\SignalR\server\Specification.Tests\src\Microsoft.AspNetCore.SignalR.Specification.Tests.csproj" />
1313
<ProjectReferenceProvider Include="Microsoft.AspNetCore.Blazor.Build" ProjectPath="$(RepoRoot)src\Components\Blazor\Build\src\Microsoft.AspNetCore.Blazor.Build.csproj" />
1414
<ProjectReferenceProvider Include="Microsoft.AspNetCore" ProjectPath="$(RepoRoot)src\DefaultBuilder\src\Microsoft.AspNetCore.csproj" RefProjectPath="$(RepoRoot)src\DefaultBuilder\ref\Microsoft.AspNetCore.csproj" />

src/Mvc/Extensions.ApiDescription.Client/src/CSharpIdentifier.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
// Copied from
88
// https://github.com/aspnet/AspNetCore-Tooling/blob/master/src/Razor/src/Microsoft.AspNetCore.Razor.Language/CSharpIdentifier.cs
9-
namespace Microsoft.Extensions.ApiDescription.Tasks
9+
namespace Microsoft.Extensions.ApiDescription.Client
1010
{
1111
internal static class CSharpIdentifier
1212
{

src/Mvc/Extensions.ApiDescription.Client/src/GetCurrentItems.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
using Microsoft.Build.Framework;
55
using Microsoft.Build.Utilities;
66

7-
namespace Microsoft.Extensions.ApiDescription.Tasks
7+
namespace Microsoft.Extensions.ApiDescription.Client
88
{
99
/// <summary>
1010
/// Restore <see cref="ITaskItem"/>s from given property value.

src/Mvc/Extensions.ApiDescription.Client/src/GetFileReferenceMetadata.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
using Microsoft.Build.Framework;
88
using Microsoft.Build.Utilities;
99

10-
namespace Microsoft.Extensions.ApiDescription.Tasks
10+
namespace Microsoft.Extensions.ApiDescription.Client
1111
{
1212
/// <summary>
1313
/// Adds or corrects ClassName, FirstForGenerator, Namespace, and OutputPath metadata in OpenApiReference items.

src/Mvc/Extensions.ApiDescription.Client/src/MetadataSerializer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
using Microsoft.Build.Framework;
77
using Microsoft.Build.Utilities;
88

9-
namespace Microsoft.Extensions.ApiDescription.Tasks
9+
namespace Microsoft.Extensions.ApiDescription.Client
1010
{
1111
/// <summary>
1212
/// Utility methods to serialize and deserialize <see cref="ITaskItem"/> metadata.

src/Mvc/Extensions.ApiDescription.Client/src/Microsoft.Extensions.ApiDescription.Client.csproj

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,19 @@
66
<!-- Do not complain about lack of lib folder. -->
77
<NoPackageAnalysis>true</NoPackageAnalysis>
88

9-
<AssemblyName>Microsoft.Extensions.ApiDescription.Tasks</AssemblyName>
109
<Description>MSBuild tasks and targets for code generation</Description>
1110
<IncludeBuildOutput>false</IncludeBuildOutput>
1211
<IncludeSource>false</IncludeSource>
13-
<IncludeSymbols>false</IncludeSymbols>
1412
<NuspecFile>$(MSBuildProjectName).nuspec</NuspecFile>
1513
<PackageId>$(MSBuildProjectName)</PackageId>
1614
<PackageTags>Build Tasks;MSBuild;Swagger;Open API;code generation; Web API client</PackageTags>
1715
<IsShippingPackage>true</IsShippingPackage>
1816
<PackageVersion>$(ExperimentalPackageVersion)</PackageVersion>
19-
<RootNamespace>$(AssemblyName)</RootNamespace>
2017
<TargetFrameworks>netstandard2.0;net461</TargetFrameworks>
2118
<VerifyVersion>false</VerifyVersion>
2219
<VersionPrefix>$(ExperimentalVersionPrefix)</VersionPrefix>
2320
<VersionSuffix>$(ExperimentalVersionSuffix)</VersionSuffix>
21+
2422
<HasReferenceAssembly>false</HasReferenceAssembly>
2523
</PropertyGroup>
2624

src/Mvc/Extensions.ApiDescription.Client/src/Microsoft.Extensions.ApiDescription.Client.nuspec

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
<files>
2020
<file src="build\*" target="build" />
2121
<file src="buildMultiTargeting\*" target="buildMultiTargeting" />
22-
<file src="$baseOutputPath$\$configuration$\net461\Microsoft.Extensions.ApiDescription.Tasks.*" target="tasks\net461" />
23-
<file src="$baseOutputPath$\$configuration$\netstandard2.0\Microsoft.Extensions.ApiDescription.Tasks.*" target="tasks\netstandard2.0" />
22+
<file src="$baseOutputPath$\$configuration$\net461\Microsoft.Extensions.ApiDescription.Client.*" target="tasks\net461" />
23+
<file src="$baseOutputPath$\$configuration$\netstandard2.0\Microsoft.Extensions.ApiDescription.Client.*" target="tasks\netstandard2.0" />
2424
</files>
2525
</package>

src/Mvc/Extensions.ApiDescription.Client/src/Properties/Resources.Designer.cs

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Mvc/Extensions.ApiDescription.Client/src/build/Microsoft.Extensions.ApiDescription.Client.props

Lines changed: 49 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,60 @@
11
<?xml version="1.0" encoding="utf-8" standalone="no"?>
22
<Project>
33
<PropertyGroup>
4-
<_ApiDescriptionTasksAssemblyTarget
5-
Condition="'$(MSBuildRuntimeType)' == 'Core'">netstandard2.0</_ApiDescriptionTasksAssemblyTarget>
6-
<_ApiDescriptionTasksAssemblyTarget
7-
Condition="'$(MSBuildRuntimeType)' != 'Core'">net461</_ApiDescriptionTasksAssemblyTarget>
8-
<_ApiDescriptionTasksAssemblyPath>$(MSBuildThisFileDirectory)/../tasks/$(_ApiDescriptionTasksAssemblyTarget)/Microsoft.Extensions.ApiDescription.Tasks.dll</_ApiDescriptionTasksAssemblyPath>
9-
<_ApiDescriptionTasksAssemblyTarget />
4+
<_ApiDescriptionClientAssemblyTarget
5+
Condition="'$(MSBuildRuntimeType)' == 'Core'">netstandard2.0</_ApiDescriptionClientAssemblyTarget>
6+
<_ApiDescriptionClientAssemblyTarget
7+
Condition="'$(MSBuildRuntimeType)' != 'Core'">net461</_ApiDescriptionClientAssemblyTarget>
8+
<_ApiDescriptionClientAssemblyPath>$(MSBuildThisFileDirectory)/../tasks/$(_ApiDescriptionClientAssemblyTarget)/Microsoft.Extensions.ApiDescription.Client.dll</_ApiDescriptionClientAssemblyPath>
9+
<_ApiDescriptionClientAssemblyTarget />
1010
</PropertyGroup>
11-
<UsingTask TaskName="GetCurrentItems" AssemblyFile="$(_ApiDescriptionTasksAssemblyPath)" />
12-
<UsingTask TaskName="GetFileReferenceMetadata" AssemblyFile="$(_ApiDescriptionTasksAssemblyPath)" />
11+
<UsingTask TaskName="GetCurrentItems" AssemblyFile="$(_ApiDescriptionClientAssemblyPath)" />
12+
<UsingTask TaskName="GetFileReferenceMetadata" AssemblyFile="$(_ApiDescriptionClientAssemblyPath)" />
1313

1414
<!--
1515
Settings users may update as they see fit.
1616
-->
1717
<PropertyGroup>
18-
<OpenApiDefaultGeneratorOptions Condition="'$(OpenApiDefaultGeneratorOptions)' == ''"></OpenApiDefaultGeneratorOptions>
18+
<!--
19+
Options added to the code generator command line by default. Provides the default %(Options) metadata of
20+
@(OpenApiReference) and @(OpenApiProjectReference) items.
21+
-->
22+
<OpenApiGenerateCodeOptions Condition="'$(OpenApiGenerateCodeOptions)' == ''"></OpenApiGenerateCodeOptions>
23+
24+
<!--
25+
If 'true' (the default), generate code for @(OpenApiReference) and @(OpenApiProjectReference) items before the
26+
BeforeCompile target.
27+
28+
If 'false', the 'GenerateOpenApiCode' target is not part of the build (by default) but can run when explicitly
29+
referenced. That is, the target may be invoked from the command line or tied in through another target.
30+
-->
31+
<OpenApiGenerateCodeOnBuild Condition="'$(OpenApiGenerateCodeOnBuild)' == ''">true</OpenApiGenerateCodeOnBuild>
32+
33+
<!--
34+
If 'true' (the default), generate code for @(OpenApiReference) and @(OpenApiProjectReference) items during
35+
design-time builds. Otherwise, generate code only during a full build.
36+
-->
37+
<OpenApiGenerateCodeAtDesignTime
38+
Condition="'$(OpenApiGenerateCodeAtDesignTime)' == ''">true</OpenApiGenerateCodeAtDesignTime>
1939

2040
<!--
21-
If 'true', will generate code for OpenApiReference items during design-time builds. Otherwise, generate code only
22-
for output files that do not yet exist during design-time builds.
41+
If 'true' (the default), build projects referenced in @(OpenApiProjectReference) items before retrieving that
42+
project's Open API documents list (or generating code). Recommend setting this to 'false' when the referenced
43+
projects do not share target framework values (avoiding build errors and / or warnings).
44+
45+
If 'false', ensure the referenced projects build before this one in the solution or through other means. IDEs may
46+
be confused about the project dependency graph in this case.
2347
-->
24-
<OpenApiGenerateAtDesignTime Condition="'$(OpenApiGenerateAtDesignTime)' == ''">true</OpenApiGenerateAtDesignTime>
48+
<OpenApiBuildReferencedProjects
49+
Condition="'$(OpenApiBuildReferencedProjects)' == ''">true</OpenApiBuildReferencedProjects>
2550

2651
<!--
27-
$(OpenApiDefaultOutputDirectory) value is interpreted relative to the project folder, unless already an
28-
absolute path.
52+
Default folder to place code generated from Open API documents. Value is interpreted relative to the project
53+
folder, unless already an absolute path. Part of the default %(OutputPath) metadata of @(OpenApiReference) and
54+
@(OpenApiProjectReference) items.
2955
-->
30-
<OpenApiDefaultOutputDirectory
31-
Condition="'$(OpenApiDefaultOutputDirectory)' == ''">$(BaseIntermediateOutputPath)</OpenApiDefaultOutputDirectory>
32-
<OpenApiDefaultOutputDirectory>$([MSBuild]::EnsureTrailingSlash('$(OpenApiDefaultOutputDirectory)'))</OpenApiDefaultOutputDirectory>
56+
<OpenApiCodeDirectory
57+
Condition="'$(OpenApiCodeDirectory)' == ''">$(BaseIntermediateOutputPath)</OpenApiCodeDirectory>
3358
</PropertyGroup>
3459

3560
<!--
@@ -42,24 +67,28 @@
4267
<OpenApiReference>
4368
<!-- Name of the class to generate. Defaults to match filename in %(OutputPath). -->
4469
<ClassName />
70+
4571
<!--
4672
Code generator to use. Required and must end with "CSharp" or "TypeScript" (the currently-supported target
4773
languages) unless %(OutputPath) is set. Builds will invoke a target named "Generate%(CodeGenerator)" to do
4874
actual code generation.
4975
-->
5076
<CodeGenerator>NSwagCSharp</CodeGenerator>
77+
5178
<!-- Namespace to contain generated class. Default is $(RootNamespace). -->
5279
<Namespace />
80+
5381
<!--
5482
Options to pass to the code generator target then (likely) added to a tool's command line. Value is passed
5583
along to the code generator but otherwise unused in this package.
5684
-->
57-
<Options>$(OpenApiDefaultGeneratorOptions)</Options>
85+
<Options>$(OpenApiGenerateCodeOptions)</Options>
86+
5887
<!--
5988
Path to place generated code. Code generator may interpret path as a filename or directory. Default filename or
6089
folder name is %(Filename)Client.[cs|ts]. Filenames and relative paths (if explicitly set) are combined with
61-
$(OpenApiDefaultOutputDirectory). Final value (depending on $(OpenApiDefaultOutputDirectory)) is likely to be
62-
a path relative to the client project.
90+
$(OpenApiCodeDirectory). Final value (depending on $(OpenApiCodeDirectory)) is likely to be a path relative to
91+
the client project.
6392
-->
6493
<OutputPath />
6594
</OpenApiReference>

src/Mvc/Extensions.ApiDescription.Client/src/build/Microsoft.Extensions.ApiDescription.Client.targets

Lines changed: 31 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,18 @@
22
<Project>
33
<!-- Internal settings. Not intended for customization. -->
44
<PropertyGroup>
5-
<GenerateOpenApiReferenceCodeDependsOn>
6-
_GetMetadataForOpenApiReferences;
7-
_GenerateOpenApiReferenceCode;
8-
_CreateCompileItemsForOpenApiReferences
9-
</GenerateOpenApiReferenceCodeDependsOn>
10-
<GenerateServiceFileReferenceCodeDependsOn>
5+
<GenerateOpenApiCodeDependsOn>
116
_GenerateErrorsForOldItems;
127
_CreateOpenApiReferenceItemsForOpenApiProjectReferences;
13-
GenerateOpenApiReferenceCode
14-
</GenerateServiceFileReferenceCodeDependsOn>
8+
_GetMetadataForOpenApiReferences;
9+
_GenerateOpenApiCode;
10+
_CreateCompileItemsForOpenApiReferences
11+
</GenerateOpenApiCodeDependsOn>
1512
</PropertyGroup>
1613

1714
<!-- OpenApiProjectReference support. -->
1815

19-
<ItemGroup>
16+
<ItemGroup Condition=" '$(OpenApiBuildReferencedProjects)' == 'true' ">
2017
<!--
2118
Do not change %(ReferenceOutputAssembly) if project contains duplicate @(ProjectReference) and
2219
@(OpenApiProjectReference) items.
@@ -30,19 +27,16 @@
3027
</ProjectReference>
3128
</ItemGroup>
3229

33-
<Target Name="_CreateOpenApiReferenceItemsForOpenApiProjectReferences"
34-
AfterTargets="ResolveProjectReferences"
35-
Condition="'$(DesignTimeBuild)' != 'true' AND '$(BuildingProject)' == 'true'">
30+
<Target Name="_CreateOpenApiReferenceItemsForOpenApiProjectReferences" DependsOnTargets="ResolveProjectReferences">
3631
<ItemGroup>
3732
<_Temporary Remove="@(_Temporary)" />
3833
</ItemGroup>
3934

4035
<MSBuild Targets="OpenApiGetDocuments"
41-
Projects="@(ProjectReferenceWithConfiguration)"
42-
Condition="'%(ProjectReferenceWithConfiguration.OpenApiReference)' == 'true'"
43-
Properties="%(ProjectReferenceWithConfiguration.SetConfiguration); %(ProjectReferenceWithConfiguration.SetPlatform); %(ProjectReferenceWithConfiguration.SetTargetFramework)"
36+
BuildInParallel="$(BuildInParallel)"
37+
Projects="@(OpenApiProjectReference)"
4438
RebaseOutputs="true"
45-
RemoveProperties="%(ProjectReferenceWithConfiguration.GlobalPropertiesToRemove);TargetFrameworks;RuntimeIdentifier">
39+
RemoveProperties="Configuration;Platform;RuntimeIdentifier;TargetFramework;TargetFrameworks">
4640
<Output TaskParameter="TargetOutputs" ItemName="_Temporary" />
4741
</MSBuild>
4842

@@ -62,7 +56,7 @@
6256
<GetFileReferenceMetadata Inputs="@(OpenApiReference)"
6357
Extension="$(DefaultLanguageSourceExtension)"
6458
Namespace="$(RootNamespace)"
65-
OutputDirectory="$(OpenApiDefaultOutputDirectory)">
59+
OutputDirectory="$(OpenApiCodeDirectory)">
6660
<Output TaskParameter="Outputs" ItemName="_Temporary" />
6761
</GetFileReferenceMetadata>
6862

@@ -79,17 +73,16 @@
7973
</GetCurrentItems>
8074
</Target>
8175

82-
<Target Name="_InnerGenerateOpenApiReferenceCode" DependsOnTargets="_GetCurrentOpenApiReference;$(GeneratorTarget)" />
76+
<Target Name="_InnerGenerateOpenApiCode" DependsOnTargets="_GetCurrentOpenApiReference;$(GeneratorTarget)" />
8377

84-
<Target Name="_GenerateOpenApiReferenceCode"
85-
Condition="$(OpenApiGenerateAtDesignTime) OR ('$(DesignTimeBuild)' != 'true' AND '$(BuildingProject)' == 'true')"
78+
<Target Name="_GenerateOpenApiCode"
79+
Condition="$(OpenApiGenerateCodeAtDesignTime) OR ('$(DesignTimeBuild)' != 'true' AND '$(BuildingProject)' == 'true')"
8680
Inputs="@(OpenApiReference)"
8781
Outputs="%(OutputPath)">
88-
<MSBuild BuildInParallel="$(BuildInParallel)"
89-
Projects="$(MSBuildProjectFullPath)"
82+
<MSBuild Projects="$(MSBuildProjectFullPath)"
83+
BuildInParallel="$(BuildInParallel)"
9084
Properties="GeneratorTargetPath=%(OpenApiReference.OutputPath);GeneratorTarget=Generate%(CodeGenerator);GeneratorMetadata=%(SerializedMetadata)"
91-
RemoveProperties="TargetFrameworks"
92-
Targets="_InnerGenerateOpenApiReferenceCode" />
85+
Targets="_InnerGenerateOpenApiCode" />
9386
</Target>
9487

9588
<Target Name="_CreateCompileItemsForOpenApiReferences" Condition="'@(OpenApiReference)' != ''">
@@ -133,17 +126,26 @@
133126
</ItemGroup>
134127
</Target>
135128

136-
<Target Name="GenerateOpenApiReferenceCode" DependsOnTargets="$(GenerateOpenApiReferenceCodeDependsOn)" />
137-
138-
<!-- Tie above code generation steps into the build. -->
129+
<!-- Inform users of breaking changes in this file and Microsoft.Extensions.ApiDescription.Client.props. -->
139130

140131
<Target Name="_GenerateErrorsForOldItems">
141132
<Error Condition="'@(ServiceProjectReference)' != ''" Text="ServiceProjectReference items are no longer supported." />
142133
<Error Condition="'@(ServiceUriReference)' != ''" Text="ServiceUriReference items are no longer supported." />
143134
<Error Condition="'@(ServiceFileReference)' != ''" Text="ServiceFileReference items are no longer supported." />
144135
</Target>
145136

146-
<Target Name="GenerateServiceFileReferenceCode"
137+
<!-- Main code generation entry point. -->
138+
139+
<Target Name="GenerateOpenApiCode" DependsOnTargets="$(GenerateOpenApiCodeDependsOn)" />
140+
141+
<!--
142+
Unless this is an inner build or default timing is disabled, tie code generation into the build. Separate from
143+
GenerateOpenApiCode and not invoked from the ../buildMultiTargeting targets to prevent repeated code generation
144+
when multi-targeting.
145+
-->
146+
147+
<Target Name="_TieInGenerateOpenApiCode"
147148
BeforeTargets="BeforeCompile"
148-
DependsOnTargets="$(GenerateServiceFileReferenceCodeDependsOn)" />
149+
Condition=" '$(OpenApiGenerateCodeOnBuild)' == 'true' AND ('$(TargetFramework)' == '' OR '$(TargetFrameworks)' == '') "
150+
DependsOnTargets="GenerateOpenApiCode" />
149151
</Project>

0 commit comments

Comments
 (0)