Skip to content

Commit

Permalink
Add more properties controlling service reference code generation (#1…
Browse files Browse the repository at this point in the history
…0641)

- `$(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
  • Loading branch information
dougbu authored Jun 3, 2019
1 parent 4c8ca0b commit 2567233
Show file tree
Hide file tree
Showing 12 changed files with 103 additions and 65 deletions.
2 changes: 1 addition & 1 deletion eng/ProjectReferences.props
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<ProjectReferenceProvider Include="Microsoft.AspNetCore.Identity.Specification.Tests" ProjectPath="$(RepoRoot)src\Identity\Specification.Tests\src\Microsoft.AspNetCore.Identity.Specification.Tests.csproj" />
<ProjectReferenceProvider Include="Microsoft.Web.Xdt.Extensions" ProjectPath="$(RepoRoot)src\SiteExtensions\Microsoft.Web.Xdt.Extensions\src\Microsoft.Web.Xdt.Extensions.csproj" />
<ProjectReferenceProvider Include="Microsoft.AspNetCore.DeveloperCertificates.XPlat" ProjectPath="$(RepoRoot)src\Tools\FirstRunCertGenerator\src\Microsoft.AspNetCore.DeveloperCertificates.XPlat.csproj" />
<ProjectReferenceProvider Include="Microsoft.Extensions.ApiDescription.Tasks" ProjectPath="$(RepoRoot)src\Mvc\Extensions.ApiDescription.Client\src\Microsoft.Extensions.ApiDescription.Client.csproj" />
<ProjectReferenceProvider Include="Microsoft.Extensions.ApiDescription.Client" ProjectPath="$(RepoRoot)src\Mvc\Extensions.ApiDescription.Client\src\Microsoft.Extensions.ApiDescription.Client.csproj" />
<ProjectReferenceProvider Include="Microsoft.AspNetCore.SignalR.Specification.Tests" ProjectPath="$(RepoRoot)src\SignalR\server\Specification.Tests\src\Microsoft.AspNetCore.SignalR.Specification.Tests.csproj" />
<ProjectReferenceProvider Include="Microsoft.AspNetCore.Blazor.Build" ProjectPath="$(RepoRoot)src\Components\Blazor\Build\src\Microsoft.AspNetCore.Blazor.Build.csproj" />
<ProjectReferenceProvider Include="Microsoft.AspNetCore" ProjectPath="$(RepoRoot)src\DefaultBuilder\src\Microsoft.AspNetCore.csproj" RefProjectPath="$(RepoRoot)src\DefaultBuilder\ref\Microsoft.AspNetCore.csproj" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

// Copied from
// https://github.com/aspnet/AspNetCore-Tooling/blob/master/src/Razor/src/Microsoft.AspNetCore.Razor.Language/CSharpIdentifier.cs
namespace Microsoft.Extensions.ApiDescription.Tasks
namespace Microsoft.Extensions.ApiDescription.Client
{
internal static class CSharpIdentifier
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;

namespace Microsoft.Extensions.ApiDescription.Tasks
namespace Microsoft.Extensions.ApiDescription.Client
{
/// <summary>
/// Restore <see cref="ITaskItem"/>s from given property value.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;

namespace Microsoft.Extensions.ApiDescription.Tasks
namespace Microsoft.Extensions.ApiDescription.Client
{
/// <summary>
/// Adds or corrects ClassName, FirstForGenerator, Namespace, and OutputPath metadata in OpenApiReference items.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;

namespace Microsoft.Extensions.ApiDescription.Tasks
namespace Microsoft.Extensions.ApiDescription.Client
{
/// <summary>
/// Utility methods to serialize and deserialize <see cref="ITaskItem"/> metadata.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,19 @@
<!-- Do not complain about lack of lib folder. -->
<NoPackageAnalysis>true</NoPackageAnalysis>

<AssemblyName>Microsoft.Extensions.ApiDescription.Tasks</AssemblyName>
<Description>MSBuild tasks and targets for code generation</Description>
<IncludeBuildOutput>false</IncludeBuildOutput>
<IncludeSource>false</IncludeSource>
<IncludeSymbols>false</IncludeSymbols>
<NuspecFile>$(MSBuildProjectName).nuspec</NuspecFile>
<PackageId>$(MSBuildProjectName)</PackageId>
<PackageTags>Build Tasks;MSBuild;Swagger;Open API;code generation; Web API client</PackageTags>
<IsShippingPackage>true</IsShippingPackage>
<PackageVersion>$(ExperimentalPackageVersion)</PackageVersion>
<RootNamespace>$(AssemblyName)</RootNamespace>
<TargetFrameworks>netstandard2.0;net461</TargetFrameworks>
<VerifyVersion>false</VerifyVersion>
<VersionPrefix>$(ExperimentalVersionPrefix)</VersionPrefix>
<VersionSuffix>$(ExperimentalVersionSuffix)</VersionSuffix>

<HasReferenceAssembly>false</HasReferenceAssembly>
</PropertyGroup>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<files>
<file src="build\*" target="build" />
<file src="buildMultiTargeting\*" target="buildMultiTargeting" />
<file src="$baseOutputPath$\$configuration$\net461\Microsoft.Extensions.ApiDescription.Tasks.*" target="tasks\net461" />
<file src="$baseOutputPath$\$configuration$\netstandard2.0\Microsoft.Extensions.ApiDescription.Tasks.*" target="tasks\netstandard2.0" />
<file src="$baseOutputPath$\$configuration$\net461\Microsoft.Extensions.ApiDescription.Client.*" target="tasks\net461" />
<file src="$baseOutputPath$\$configuration$\netstandard2.0\Microsoft.Extensions.ApiDescription.Client.*" target="tasks\netstandard2.0" />
</files>
</package>

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -1,35 +1,60 @@
<?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 />
<_ApiDescriptionClientAssemblyTarget
Condition="'$(MSBuildRuntimeType)' == 'Core'">netstandard2.0</_ApiDescriptionClientAssemblyTarget>
<_ApiDescriptionClientAssemblyTarget
Condition="'$(MSBuildRuntimeType)' != 'Core'">net461</_ApiDescriptionClientAssemblyTarget>
<_ApiDescriptionClientAssemblyPath>$(MSBuildThisFileDirectory)/../tasks/$(_ApiDescriptionClientAssemblyTarget)/Microsoft.Extensions.ApiDescription.Client.dll</_ApiDescriptionClientAssemblyPath>
<_ApiDescriptionClientAssemblyTarget />
</PropertyGroup>
<UsingTask TaskName="GetCurrentItems" AssemblyFile="$(_ApiDescriptionTasksAssemblyPath)" />
<UsingTask TaskName="GetFileReferenceMetadata" AssemblyFile="$(_ApiDescriptionTasksAssemblyPath)" />
<UsingTask TaskName="GetCurrentItems" AssemblyFile="$(_ApiDescriptionClientAssemblyPath)" />
<UsingTask TaskName="GetFileReferenceMetadata" AssemblyFile="$(_ApiDescriptionClientAssemblyPath)" />

<!--
Settings users may update as they see fit.
-->
<PropertyGroup>
<OpenApiDefaultGeneratorOptions Condition="'$(OpenApiDefaultGeneratorOptions)' == ''"></OpenApiDefaultGeneratorOptions>
<!--
Options added to the code generator command line by default. Provides the default %(Options) metadata of
@(OpenApiReference) and @(OpenApiProjectReference) items.
-->
<OpenApiGenerateCodeOptions Condition="'$(OpenApiGenerateCodeOptions)' == ''"></OpenApiGenerateCodeOptions>

<!--
If 'true' (the default), generate code for @(OpenApiReference) and @(OpenApiProjectReference) items before the
BeforeCompile target.
If 'false', the 'GenerateOpenApiCode' target is not part of the build (by default) but can run when explicitly
referenced. That is, the target may be invoked from the command line or tied in through another target.
-->
<OpenApiGenerateCodeOnBuild Condition="'$(OpenApiGenerateCodeOnBuild)' == ''">true</OpenApiGenerateCodeOnBuild>

<!--
If 'true' (the default), generate code for @(OpenApiReference) and @(OpenApiProjectReference) items during
design-time builds. Otherwise, generate code only during a full build.
-->
<OpenApiGenerateCodeAtDesignTime
Condition="'$(OpenApiGenerateCodeAtDesignTime)' == ''">true</OpenApiGenerateCodeAtDesignTime>

<!--
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.
If 'true' (the default), build projects referenced in @(OpenApiProjectReference) items before retrieving that
project's Open API documents list (or generating code). Recommend setting this to 'false' when the referenced
projects do not share target framework values (avoiding build errors and / or warnings).
If 'false', ensure the referenced projects build before this one in the solution or through other means. IDEs may
be confused about the project dependency graph in this case.
-->
<OpenApiGenerateAtDesignTime Condition="'$(OpenApiGenerateAtDesignTime)' == ''">true</OpenApiGenerateAtDesignTime>
<OpenApiBuildReferencedProjects
Condition="'$(OpenApiBuildReferencedProjects)' == ''">true</OpenApiBuildReferencedProjects>

<!--
$(OpenApiDefaultOutputDirectory) value is interpreted relative to the project folder, unless already an
absolute path.
Default folder to place code generated from Open API documents. Value is interpreted relative to the project
folder, unless already an absolute path. Part of the default %(OutputPath) metadata of @(OpenApiReference) and
@(OpenApiProjectReference) items.
-->
<OpenApiDefaultOutputDirectory
Condition="'$(OpenApiDefaultOutputDirectory)' == ''">$(BaseIntermediateOutputPath)</OpenApiDefaultOutputDirectory>
<OpenApiDefaultOutputDirectory>$([MSBuild]::EnsureTrailingSlash('$(OpenApiDefaultOutputDirectory)'))</OpenApiDefaultOutputDirectory>
<OpenApiCodeDirectory
Condition="'$(OpenApiCodeDirectory)' == ''">$(BaseIntermediateOutputPath)</OpenApiCodeDirectory>
</PropertyGroup>

<!--
Expand All @@ -42,24 +67,28 @@
<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>
<Options>$(OpenApiGenerateCodeOptions)</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.
$(OpenApiCodeDirectory). Final value (depending on $(OpenApiCodeDirectory)) is likely to be a path relative to
the client project.
-->
<OutputPath />
</OpenApiReference>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,18 @@
<Project>
<!-- Internal settings. Not intended for customization. -->
<PropertyGroup>
<GenerateOpenApiReferenceCodeDependsOn>
_GetMetadataForOpenApiReferences;
_GenerateOpenApiReferenceCode;
_CreateCompileItemsForOpenApiReferences
</GenerateOpenApiReferenceCodeDependsOn>
<GenerateServiceFileReferenceCodeDependsOn>
<GenerateOpenApiCodeDependsOn>
_GenerateErrorsForOldItems;
_CreateOpenApiReferenceItemsForOpenApiProjectReferences;
GenerateOpenApiReferenceCode
</GenerateServiceFileReferenceCodeDependsOn>
_GetMetadataForOpenApiReferences;
_GenerateOpenApiCode;
_CreateCompileItemsForOpenApiReferences
</GenerateOpenApiCodeDependsOn>
</PropertyGroup>

<!-- OpenApiProjectReference support. -->

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

<Target Name="_CreateOpenApiReferenceItemsForOpenApiProjectReferences"
AfterTargets="ResolveProjectReferences"
Condition="'$(DesignTimeBuild)' != 'true' AND '$(BuildingProject)' == 'true'">
<Target Name="_CreateOpenApiReferenceItemsForOpenApiProjectReferences" DependsOnTargets="ResolveProjectReferences">
<ItemGroup>
<_Temporary Remove="@(_Temporary)" />
</ItemGroup>

<MSBuild Targets="OpenApiGetDocuments"
Projects="@(ProjectReferenceWithConfiguration)"
Condition="'%(ProjectReferenceWithConfiguration.OpenApiReference)' == 'true'"
Properties="%(ProjectReferenceWithConfiguration.SetConfiguration); %(ProjectReferenceWithConfiguration.SetPlatform); %(ProjectReferenceWithConfiguration.SetTargetFramework)"
BuildInParallel="$(BuildInParallel)"
Projects="@(OpenApiProjectReference)"
RebaseOutputs="true"
RemoveProperties="%(ProjectReferenceWithConfiguration.GlobalPropertiesToRemove);TargetFrameworks;RuntimeIdentifier">
RemoveProperties="Configuration;Platform;RuntimeIdentifier;TargetFramework;TargetFrameworks">
<Output TaskParameter="TargetOutputs" ItemName="_Temporary" />
</MSBuild>

Expand All @@ -62,7 +56,7 @@
<GetFileReferenceMetadata Inputs="@(OpenApiReference)"
Extension="$(DefaultLanguageSourceExtension)"
Namespace="$(RootNamespace)"
OutputDirectory="$(OpenApiDefaultOutputDirectory)">
OutputDirectory="$(OpenApiCodeDirectory)">
<Output TaskParameter="Outputs" ItemName="_Temporary" />
</GetFileReferenceMetadata>

Expand All @@ -79,17 +73,16 @@
</GetCurrentItems>
</Target>

<Target Name="_InnerGenerateOpenApiReferenceCode" DependsOnTargets="_GetCurrentOpenApiReference;$(GeneratorTarget)" />
<Target Name="_InnerGenerateOpenApiCode" DependsOnTargets="_GetCurrentOpenApiReference;$(GeneratorTarget)" />

<Target Name="_GenerateOpenApiReferenceCode"
Condition="$(OpenApiGenerateAtDesignTime) OR ('$(DesignTimeBuild)' != 'true' AND '$(BuildingProject)' == 'true')"
<Target Name="_GenerateOpenApiCode"
Condition="$(OpenApiGenerateCodeAtDesignTime) OR ('$(DesignTimeBuild)' != 'true' AND '$(BuildingProject)' == 'true')"
Inputs="@(OpenApiReference)"
Outputs="%(OutputPath)">
<MSBuild BuildInParallel="$(BuildInParallel)"
Projects="$(MSBuildProjectFullPath)"
<MSBuild Projects="$(MSBuildProjectFullPath)"
BuildInParallel="$(BuildInParallel)"
Properties="GeneratorTargetPath=%(OpenApiReference.OutputPath);GeneratorTarget=Generate%(CodeGenerator);GeneratorMetadata=%(SerializedMetadata)"
RemoveProperties="TargetFrameworks"
Targets="_InnerGenerateOpenApiReferenceCode" />
Targets="_InnerGenerateOpenApiCode" />
</Target>

<Target Name="_CreateCompileItemsForOpenApiReferences" Condition="'@(OpenApiReference)' != ''">
Expand Down Expand Up @@ -133,17 +126,26 @@
</ItemGroup>
</Target>

<Target Name="GenerateOpenApiReferenceCode" DependsOnTargets="$(GenerateOpenApiReferenceCodeDependsOn)" />

<!-- Tie above code generation steps into the build. -->
<!-- Inform users of breaking changes in this file and Microsoft.Extensions.ApiDescription.Client.props. -->

<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"
<!-- Main code generation entry point. -->

<Target Name="GenerateOpenApiCode" DependsOnTargets="$(GenerateOpenApiCodeDependsOn)" />

<!--
Unless this is an inner build or default timing is disabled, tie code generation into the build. Separate from
GenerateOpenApiCode and not invoked from the ../buildMultiTargeting targets to prevent repeated code generation
when multi-targeting.
-->

<Target Name="_TieInGenerateOpenApiCode"
BeforeTargets="BeforeCompile"
DependsOnTargets="$(GenerateServiceFileReferenceCodeDependsOn)" />
Condition=" '$(OpenApiGenerateCodeOnBuild)' == 'true' AND ('$(TargetFramework)' == '' OR '$(TargetFrameworks)' == '') "
DependsOnTargets="GenerateOpenApiCode" />
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<Project>
<Import Project="../build/Microsoft.Extensions.ApiDescription.Client.props" />
</Project>
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<Project>
<Target Name="GenerateServiceFileReferenceCode" BeforeTargets="BeforeCompile">
<MsBuild Projects="$(MSBuildProjectFile)"
Targets="GenerateServiceFileReferenceCode"
<Target Name="GenerateOpenApiCode">
<MSBuild Projects="$(MSBuildProjectFile)"
Targets="GenerateOpenApiCode"
Properties="TargetFramework=$(TargetFrameworks.Split(';')[0])"
RemoveProperties="TargetFrameworks;RuntimeIdentifier" />
RemoveProperties="RuntimeIdentifier" />
</Target>

<Target Name="_GenerateOpenApiCode"
BeforeTargets="BeforeCompile"
Condition=" ''$(OpenApiGenerateCodeOnBuild)' == 'true' "
DependsOnTargets="GenerateOpenApiCode" />
</Project>

0 comments on commit 2567233

Please sign in to comment.