Skip to content
This repository was archived by the owner on Dec 12, 2020. It is now read-only.

Commit d8fa7f1

Browse files
authored
feat: Add PluginMetapackage.Sdk (#205)
1 parent 2773b16 commit d8fa7f1

16 files changed

Lines changed: 362 additions & 38 deletions

samples/Directory.Build.props

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
<LocalNuGetVersion Condition=" '$(LocalNuGetVersion)' == '' ">*</LocalNuGetVersion>
1010
<!-- Setting this is needed because we're not using actual Sdk package which defines it. -->
1111
<CodeGenerationRoslynPluginSdkVersion>$(LocalNuGetVersion)</CodeGenerationRoslynPluginSdkVersion>
12+
<CodeGenerationRoslynPluginMetapackageSdkVersion>$(LocalNuGetVersion)</CodeGenerationRoslynPluginMetapackageSdkVersion>
1213
<RestorePackagesPath>$(MSBuildThisFileDirectory)/.nuget/</RestorePackagesPath>
1314

1415
<_MainPackagesDebug>$(MSBuildThisFileDirectory)../bin/Packages/Debug/</_MainPackagesDebug>
@@ -17,6 +18,7 @@
1718
<RestoreAdditionalProjectSources>@(CustomLocalFeed);$(RestoreAdditionalProjectSources)</RestoreAdditionalProjectSources>
1819

1920
<CodeGenerationRoslynPluginSdkPath>$(MSBuildThisFileDirectory)../src/CodeGeneration.Roslyn.Plugin.Sdk/Sdk/</CodeGenerationRoslynPluginSdkPath>
21+
<CodeGenerationRoslynPluginMetapackageSdkPath>$(MSBuildThisFileDirectory)../src/CodeGeneration.Roslyn.PluginMetapackage.Sdk/Sdk/</CodeGenerationRoslynPluginMetapackageSdkPath>
2022
</PropertyGroup>
2123

2224
<ItemGroup>

samples/MetapackageSample/MetapackageSample.Attributes/MetapackageSample.Attributes.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFramework>netstandard1.0</TargetFramework>
4+
<TargetFrameworks>netstandard1.0;netstandard2.0</TargetFrameworks>
55
<RootNamespace>MetapackageSample</RootNamespace>
66
</PropertyGroup>
77

samples/MetapackageSample/MetapackageSample.sln

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MetapackageSample.Attribute
77
EndProject
88
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MetapackageSample.Generators", "MetapackageSample.Generators\MetapackageSample.Generators.csproj", "{6B5DBA1C-1FE6-4211-819D-1CD520B143F8}"
99
EndProject
10+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MetapackageSample", "MetapackageSample\MetapackageSample.csproj", "{A402B05D-7B8A-405D-BFEB-0505476A5718}"
11+
EndProject
1012
Global
1113
GlobalSection(SolutionConfigurationPlatforms) = preSolution
1214
Debug|Any CPU = Debug|Any CPU
@@ -44,5 +46,17 @@ Global
4446
{6B5DBA1C-1FE6-4211-819D-1CD520B143F8}.Release|x64.Build.0 = Release|Any CPU
4547
{6B5DBA1C-1FE6-4211-819D-1CD520B143F8}.Release|x86.ActiveCfg = Release|Any CPU
4648
{6B5DBA1C-1FE6-4211-819D-1CD520B143F8}.Release|x86.Build.0 = Release|Any CPU
49+
{A402B05D-7B8A-405D-BFEB-0505476A5718}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
50+
{A402B05D-7B8A-405D-BFEB-0505476A5718}.Debug|Any CPU.Build.0 = Debug|Any CPU
51+
{A402B05D-7B8A-405D-BFEB-0505476A5718}.Debug|x64.ActiveCfg = Debug|Any CPU
52+
{A402B05D-7B8A-405D-BFEB-0505476A5718}.Debug|x64.Build.0 = Debug|Any CPU
53+
{A402B05D-7B8A-405D-BFEB-0505476A5718}.Debug|x86.ActiveCfg = Debug|Any CPU
54+
{A402B05D-7B8A-405D-BFEB-0505476A5718}.Debug|x86.Build.0 = Debug|Any CPU
55+
{A402B05D-7B8A-405D-BFEB-0505476A5718}.Release|Any CPU.ActiveCfg = Release|Any CPU
56+
{A402B05D-7B8A-405D-BFEB-0505476A5718}.Release|Any CPU.Build.0 = Release|Any CPU
57+
{A402B05D-7B8A-405D-BFEB-0505476A5718}.Release|x64.ActiveCfg = Release|Any CPU
58+
{A402B05D-7B8A-405D-BFEB-0505476A5718}.Release|x64.Build.0 = Release|Any CPU
59+
{A402B05D-7B8A-405D-BFEB-0505476A5718}.Release|x86.ActiveCfg = Release|Any CPU
60+
{A402B05D-7B8A-405D-BFEB-0505476A5718}.Release|x86.Build.0 = Release|Any CPU
4761
EndGlobalSection
4862
EndGlobal
Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,41 @@
11
<Project Sdk="Microsoft.NET.Sdk">
2+
<!--
3+
The imports (on top and bottom) should be replaced with a single Sdk element at the top,
4+
<Sdk Name="CodeGeneration.Roslyn.PluginMetapackage.Sdk" Version="x.y.z" />
5+
6+
see https://docs.microsoft.com/en-us/visualstudio/msbuild/how-to-use-project-sdk?view=vs-2019#reference-a-project-sdk
7+
8+
But it's using local Sdk, so we can't use it like that.
9+
-->
10+
<Import Project="$(CodeGenerationRoslynPluginMetapackageSdkPath)Sdk.props" />
211

312
<PropertyGroup>
4-
<!-- Declare the TargetFramework the same as in your Attributes package -->
5-
<TargetFramework>netstandard1.0</TargetFramework>
13+
<!-- Declare the TargetFramework(s) the same as in your Attributes package -->
14+
<TargetFrameworks>netstandard1.0;netstandard2.0</TargetFrameworks>
615
<!-- This project contains no files, so building can be skipped -->
716
<NoBuild>true</NoBuild>
817
<!-- Since we don't build, there'll be no build output -->
918
<IncludeBuildOutput>false</IncludeBuildOutput>
1019
</PropertyGroup>
1120

1221
<ItemGroup>
13-
<!-- Reference your Attributes normally -->
14-
<PackageReference Include="MetapackageSample.Attributes" Version="$(PackageVersion)" />
15-
<!-- Reference your generators with PrivateAssets="none" to flow "build" assets -->
16-
<PackageReference Include="MetapackageSample.Generators" Version="$(PackageVersion)" PrivateAssets="none" />
17-
<!-- Reference CodeGeneration.Roslyn.Tool with PrivateAssets="none" to flow "build" assets -->
18-
<PackageReference Include="CodeGeneration.Roslyn.Tool" Version="$(LocalNuGetVersion)" PrivateAssets="none" />
19-
<!-- Add an empty placeholder to keep valid package structure -->
20-
<None Include="_._" Pack="true" PackagePath="lib/$(TargetFramework)/"/>
22+
<!-- Reference your Attributes project normally -->
23+
<ProjectReference Include="../MetapackageSample.Attributes/MetapackageSample.Attributes.csproj" />
24+
<!--
25+
Reference your generators package by adding an item to NupkgAdditionalDependency
26+
with IncludeAssets="all" to flow "build" assets.
27+
Version used will be the PackageVersion Pack resolves,
28+
but you can specify Version metadata to override it.
29+
30+
This is necessary to do like that, because it ensures the dependency is setup
31+
correctly (e.g. simple transient dependency), and skips validation of TFM (Plugin is a tool,
32+
it's TFM has no meaning for the consumer).
33+
-->
34+
<NupkgAdditionalDependency
35+
Include="MetapackageSample.Generators"
36+
IncludeAssets="all" />
2137
</ItemGroup>
2238

23-
</Project>
39+
<!-- See top comment -->
40+
<Import Project="$(CodeGenerationRoslynPluginMetapackageSdkPath)Sdk.targets" />
41+
</Project>

samples/MetapackageSample/README.md

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,24 @@
33
This sample demonstrates an approach to providing a nice UX for our generator consumers.
44

55
The `MetapackageSample.sln` solution builds and packs `Attributes` and `Generators` packages,
6-
and then using those packages from local folder feed, `MetapackageSample` project
7-
is packed and creates a new NuGet package that just references those packages,
8-
as well as the `CodeGeneration.Roslyn.Tool` package.
6+
and the `MetapackageSample` project which builds a metapackage that contains all package
7+
references that your consumers will need:
8+
* your `Attributes` package
9+
* your `Generators` package (via custom `NupkgAdditionalDependency` Item)
10+
* `CodeGeneration.Roslyn.Tool` package (implicitly added in the PluginMetapackage.Sdk).
911

10-
This allows your consumers to simply
12+
Using that metapackage, your generator's users only need one PackageReferece to add:
1113
> `dotnet add package MetapackageSample`
1214
and have the source generator working immediately.
1315

16+
`MetapackageConsumer` is an example consumer project that references just
17+
our single `MetapackageSample` package, and successfully runs the generator.
18+
1419
Important aspects of the `Metapackage/Metapackage.csproj`:
15-
* it's not built at the same time as Attributes and Generators because it needs
16-
their NuGets to be in the folder feed it uses.
17-
* it's not producing any dll, and so should be only `pack`ed
20+
* it's built (packed) at the same time as Attributes and Generators;
21+
* it's not producing any dll, and so should be only `pack`ed (and is packed on build)
1822
* there are important comments for every element, please read them
1923
* variables used (`$(PackageVersion)`, `$(LocalNuGetVersion)`) should be replaced
2024
with whatever you use in your setup. `LocalNuGetVersion` is the version of CG.R
2125
used across samples - you should use the same version as other CG.R packages you
22-
reference. `Directory.Build.props` is a good place to define that once.
23-
24-
`MetapackageConsumer` is an example consumer project that references just
25-
our single `MetapackageSample` package, and successfully runs the generator.
26+
reference. `Directory.Build.props` is a good place to define that once.

samples/MetapackageSample/build.ps1

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
11
#!/usr/bin/env pwsh
22

3+
function PrintAndInvoke {
4+
param ($expression)
5+
Write-Host "$expression" -ForegroundColor Green
6+
Invoke-Expression $expression
7+
}
8+
39
Write-Host "Running in $PSScriptRoot" -ForegroundColor Cyan
410
Push-Location $PSScriptRoot
511
try {
6-
# pack directory (solution), then pack Metapackage
7-
'.', 'MetapackageSample' | ForEach-Object {
8-
Write-Host "dotnet pack $_" -ForegroundColor Green
9-
dotnet pack $_
10-
}
11-
Write-Host "dotnet run -p MetapackageConsumer" -ForegroundColor Green
12-
dotnet run -p MetapackageConsumer
12+
# pack directory (solution)
13+
PrintAndInvoke "dotnet pack"
14+
# run consumer
15+
PrintAndInvoke "dotnet run -p MetapackageConsumer"
1316
}
1417
finally {
1518
Pop-Location

samples/build.ps1

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,14 @@ try {
2323
$env:LocalNuGetVersion = dotnet nbgv get-version --variable NuGetPackageVersion --project ../src
2424

2525
Write-Host "Using CG.R package version: $env:LocalNuGetVersion" -ForegroundColor Cyan
26+
27+
# check that CG.R packages for this version exist
28+
$cgrNupkg = Get-ChildItem ../bin/Packages/$env:Configuration/ -Filter *.nupkg
29+
| Where-Object BaseName -Match "$env:LocalNuGetVersion$"
30+
if (!$cgrNupkg) {
31+
Write-Host "CG.R packages for this version not found, packing..."
32+
PrintAndInvoke "dotnet pack ../src"
33+
}
2634

2735
# get generator project folders
2836
$generators = Get-ChildItem -Directory -Name | Where-Object { $_ -match 'Generator$' }

src/CodeGeneration.Roslyn.Plugin.Sdk/Sdk/Sdk.targets

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,12 @@
55
Add an implicit reference to CodeGeneration.Roslyn package if not disabled.
66
Disable by setting AddImplicitCodeGenerationRoslynReference to false.
77
8+
CodeGenerationRoslynPluginSdkVersion Property is defined in Version.props (imported in .props).
9+
810
This is Sdk-only because adding PackageReference in build/.targets doesn't actually
911
impact restore (or *shouldn't*).
1012
-->
1113
<ItemGroup Condition=" '$(AddImplicitCodeGenerationRoslynReference)' != 'false' ">
12-
<!--
13-
CodeGenerationRoslynPluginSdkVersion Property is defined in Version.props (imported in .props).
14-
This is used to add an implicit reference to the CodeGeneration.Roslyn package,
15-
so that the versions of Plugin.Sdk and CG.R dependency stay in sync.
16-
-->
1714
<PackageReference Include="CodeGeneration.Roslyn"
1815
Version="$(CodeGenerationRoslynPluginSdkVersion)"
1916
IsImplicitlyDefined="true"

src/CodeGeneration.Roslyn.Plugin.Sdk/build/CodeGeneration.Roslyn.Plugin.Sdk.props

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,8 @@
77
</PropertyGroup>
88

99
<!--
10-
Version.props defines CodeGenerationRoslynPluginSdkVersion Property in NuGet package.
11-
This is used to add an implicit reference to the CodeGeneration.Roslyn package,
12-
so that the versions of Plugin.Sdk and CG.R dependency stay in sync.
10+
Version.props defines CodeGenerationRoslynPluginSdkVersion Property
11+
with the version of the Sdk package itself.
1312
-->
1413
<Import Project="Version.props" Condition=" Exists('Version.props') " />
1514

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<Project Sdk="Microsoft.Build.NoTargets">
2+
3+
<PropertyGroup>
4+
<TargetFramework>netstandard1.0</TargetFramework>
5+
<Description>The MSBuild SDK that helps correctly create CodeGeneration.Roslyn plugins.</Description>
6+
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
7+
<DevelopmentDependency>true</DevelopmentDependency>
8+
<SymbolPackageFormat></SymbolPackageFormat>
9+
<IncludeSymbols>false</IncludeSymbols>
10+
<!--
11+
Min Version is 2.5 because that's when build/ folder support was introduced:
12+
https://docs.microsoft.com/en-us/nuget/release-notes/nuget-2.5#automatic-import-of-msbuild-targets-and-props-files
13+
-->
14+
<MinClientVersion>2.5</MinClientVersion>
15+
<IncludeBuildOutput>false</IncludeBuildOutput>
16+
<!-- Below is needed to make NuGet package TFM-oblivious -->
17+
<SuppressDependenciesWhenPacking>true</SuppressDependenciesWhenPacking>
18+
<!--
19+
Run our target to add Version.props to the nuget package before Pack
20+
using a documented extension point.
21+
-->
22+
<BeforePack>$(BeforePack);CreateVersionProps</BeforePack>
23+
</PropertyGroup>
24+
25+
<ItemGroup>
26+
<None Include="**/*.props;**/*.targets" Pack="true" PackagePath="" />
27+
</ItemGroup>
28+
29+
<!--
30+
This target adds a Sdk/Version.props file to the nuget package.
31+
That props file contains CodeGenerationRoslynPluginMetapackageSdkVersion property,
32+
so that other targets can reference correct packages and/or validate
33+
versions of the already referenced ones.
34+
35+
GetBuildVersion target is from Nerdbank.GitVersioning package and sets correct PackageVersion.
36+
-->
37+
<Target Name="CreateVersionProps" DependsOnTargets="GetBuildVersion">
38+
<PropertyGroup>
39+
<VersionPropsContent>
40+
<![CDATA[
41+
<?xml version="1.0" encoding="utf-8" ?>
42+
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
43+
<PropertyGroup>
44+
<CodeGenerationRoslynPluginMetapackageSdkVersion>$(PackageVersion)</CodeGenerationRoslynPluginMetapackageSdkVersion>
45+
</PropertyGroup>
46+
</Project>
47+
]]>
48+
</VersionPropsContent>
49+
<VersionPropsPath>$(IntermediateOutputPath)Version.props</VersionPropsPath>
50+
</PropertyGroup>
51+
<WriteLinesToFile File="$(VersionPropsPath)" Lines="$(VersionPropsContent)" Overwrite="true" />
52+
<ItemGroup>
53+
<None Include="$(VersionPropsPath)" Pack="true" PackagePath="build/" />
54+
<FileWrites Include="$(VersionPropsPath)" />
55+
</ItemGroup>
56+
</Target>
57+
58+
</Project>

0 commit comments

Comments
 (0)