Also inject EntityFramework package versions dynamically

This commit is contained in:
Steve Sanderson 2017-08-30 22:27:47 +01:00
parent 18dee25eb9
commit 378c93e7d6
5 changed files with 46 additions and 37 deletions

View File

@ -12,7 +12,8 @@
<PackageVersion Condition="'$(VersionSuffix)' != ''">$(VersionPrefix)-$(VersionSuffix)</PackageVersion> <PackageVersion Condition="'$(VersionSuffix)' != ''">$(VersionPrefix)-$(VersionSuffix)</PackageVersion>
<PackageOutputPath Condition="'$(PackageOutputPath)' == ''">$(MSBuildThisFileDirectory)..\artifacts\tmp\</PackageOutputPath> <PackageOutputPath Condition="'$(PackageOutputPath)' == ''">$(MSBuildThisFileDirectory)..\artifacts\tmp\</PackageOutputPath>
<NuspecProperties>version=$(PackageVersion)</NuspecProperties> <NuspecProperties>version=$(PackageVersion)</NuspecProperties>
<AspNetCoreVersionFromLineup>@(PackageReference->WithMetadataValue('Identity', 'Microsoft.AspNetCore.All')->Metadata('Version'))</AspNetCoreVersionFromLineup> <AspNetCoreVersionFromLineup>@(PackageReference->WithMetadataValue('Identity', 'Microsoft.AspNetCore')->Metadata('Version'))</AspNetCoreVersionFromLineup>
<EntityFrameworkVersionFromLineup>@(PackageReference->WithMetadataValue('Identity', 'Microsoft.EntityFrameworkCore')->Metadata('Version'))</EntityFrameworkVersionFromLineup>
<!-- <!--
These are not regular projects. They are just wrappers for the .nuspec files in each These are not regular projects. They are just wrappers for the .nuspec files in each
@ -31,11 +32,12 @@
<None Include="Content/**" /> <None Include="Content/**" />
<!-- <!--
Having this package reference causes KoreBuild to pick the applicable These references are here only so that KoreBuild will locate the applicable
ASP.NET Core version from the lineup, making it possible to declare version in the current lineup and we can then substitute it into the emitted
the AspNetCoreVersionFromLineup variable above. template .nupkg files.
--> -->
<PackageReference Include="Microsoft.AspNetCore.All" /> <PackageReference Include="Microsoft.AspNetCore" />
<PackageReference Include="Microsoft.EntityFrameworkCore" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -8,13 +8,13 @@
--> -->
<UsingTask <UsingTask
TaskName="DependencyUpdater.UpdateAspNetReference" TaskName="DependencyUpdater.SubstituteProjectFileVariables"
AssemblyFile="$(MSBuildProjectDirectory)\$(OutputPath)DependencyUpdater.dll" /> AssemblyFile="$(MSBuildProjectDirectory)\$(OutputPath)DependencyUpdater.dll" />
<Target Name="RunTask" AfterTargets="Pack"> <Target Name="RunTask" AfterTargets="Pack">
<UpdateAspNetReference <SubstituteProjectFileVariables
NupkgFile="$(PackageOutputPath)$(MSBuildProjectName).$(PackageVersion).nupkg" NupkgFile="$(PackageOutputPath)$(MSBuildProjectName).$(PackageVersion).nupkg"
AspNetVersion="$(AspNetCoreVersionFromLineup)" Substitutions="TemplateAspNetCoreVersion=$(AspNetCoreVersionFromLineup); TemplateEntityFrameworkVersion=$(EntityFrameworkVersionFromLineup)"
OutDir="$(PackageOutputPath)..\" /> OutDir="$(PackageOutputPath)..\" />
</Target> </Target>

View File

@ -11,7 +11,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup Condition="'$(TargetFrameworkOverride)' == ''"> <ItemGroup Condition="'$(TargetFrameworkOverride)' == ''">
<PackageReference Include="Microsoft.AspNetCore.All" Version="$(TemplateAspNetCoreVersion)" /> <PackageReference Include="Microsoft.AspNetCore.All" Version="$(TemplateAspNetCoreVersion)" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="2.0.0" PrivateAssets="All" Condition="'$(IndividualAuth)' == 'True'" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="$(TemplateEntityFrameworkVersion)" PrivateAssets="All" Condition="'$(IndividualAuth)' == 'True'" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.0.0" PrivateAssets="All" Condition="'$(IndividualAuth)' == 'True'" /> <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.0.0" PrivateAssets="All" Condition="'$(IndividualAuth)' == 'True'" />
</ItemGroup> </ItemGroup>
<ItemGroup Condition="'$(TargetFrameworkOverride)' != ''"> <ItemGroup Condition="'$(TargetFrameworkOverride)' != ''">
@ -23,15 +23,15 @@
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="$(TemplateAspNetCoreVersion)" /> <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="$(TemplateAspNetCoreVersion)" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.ViewCompilation" Version="$(TemplateAspNetCoreVersion)" PrivateAssets="All" /> <PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.ViewCompilation" Version="$(TemplateAspNetCoreVersion)" PrivateAssets="All" />
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="$(TemplateAspNetCoreVersion)" /> <PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="$(TemplateAspNetCoreVersion)" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.0.0" PrivateAssets="All" Condition="'$(IndividualLocalAuth)' == 'True'" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="$(TemplateEntityFrameworkVersion)" PrivateAssets="All" Condition="'$(IndividualLocalAuth)' == 'True'" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.0.0" Condition=" '$(IndividualLocalAuth)' == 'True' AND '$(UseLocalDB)' != 'True'" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="$(TemplateEntityFrameworkVersion)" Condition=" '$(IndividualLocalAuth)' == 'True' AND '$(UseLocalDB)' != 'True'" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.0.0" Condition=" '$(IndividualLocalAuth)' == 'True' AND '$(UseLocalDB)' == 'True'" /> <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="$(TemplateEntityFrameworkVersion)" Condition=" '$(IndividualLocalAuth)' == 'True' AND '$(UseLocalDB)' == 'True'" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="2.0.0" PrivateAssets="All" Condition="'$(IndividualLocalAuth)' == 'True'" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="$(TemplateEntityFrameworkVersion)" PrivateAssets="All" Condition="'$(IndividualLocalAuth)' == 'True'" />
<PackageReference Include="Microsoft.VisualStudio.Web.BrowserLink" Version="2.0.0" Condition="'$(UseBrowserLink)' == 'True'" /> <PackageReference Include="Microsoft.VisualStudio.Web.BrowserLink" Version="2.0.0" Condition="'$(UseBrowserLink)' == 'True'" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.0.0" PrivateAssets="All" Condition="'$(IndividualAuth)' == 'True'" /> <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.0.0" PrivateAssets="All" Condition="'$(IndividualAuth)' == 'True'" />
</ItemGroup> </ItemGroup>
<ItemGroup Condition="'$(NoTools)' != 'True'"> <ItemGroup Condition="'$(NoTools)' != 'True'">
<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.0" Condition="'$(IndividualLocalAuth)' == 'True'" /> <DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="$(TemplateEntityFrameworkVersion)" Condition="'$(IndividualLocalAuth)' == 'True'" />
<DotNetCliToolReference Include="Microsoft.Extensions.SecretManager.Tools" Version="2.0.0" Condition="'$(IndividualAuth)' == 'True' OR '$(OrganizationalAuth)' == 'True'" /> <DotNetCliToolReference Include="Microsoft.Extensions.SecretManager.Tools" Version="2.0.0" Condition="'$(IndividualAuth)' == 'True' OR '$(OrganizationalAuth)' == 'True'" />
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0" /> <DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0" />
</ItemGroup> </ItemGroup>

View File

@ -16,7 +16,7 @@
<ItemGroup Condition="'$(TargetFrameworkOverride)' == ''"> <ItemGroup Condition="'$(TargetFrameworkOverride)' == ''">
<PackageReference Include="Microsoft.AspNetCore.All" Version="$(TemplateAspNetCoreVersion)" /> <PackageReference Include="Microsoft.AspNetCore.All" Version="$(TemplateAspNetCoreVersion)" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="2.0.0" PrivateAssets="All" Condition="'$(IndividualAuth)' == 'True'" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="$(TemplateEntityFrameworkVersion)" PrivateAssets="All" Condition="'$(IndividualAuth)' == 'True'" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.0.0" PrivateAssets="All" Condition="'$(IndividualAuth)' == 'True'" /> <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.0.0" PrivateAssets="All" Condition="'$(IndividualAuth)' == 'True'" />
</ItemGroup> </ItemGroup>
<ItemGroup Condition="'$(TargetFrameworkOverride)' != ''"> <ItemGroup Condition="'$(TargetFrameworkOverride)' != ''">
@ -28,16 +28,16 @@
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="$(TemplateAspNetCoreVersion)" /> <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="$(TemplateAspNetCoreVersion)" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.ViewCompilation" Version="$(TemplateAspNetCoreVersion)" PrivateAssets="All" /> <PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.ViewCompilation" Version="$(TemplateAspNetCoreVersion)" PrivateAssets="All" />
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="$(TemplateAspNetCoreVersion)" /> <PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="$(TemplateAspNetCoreVersion)" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.0.0" PrivateAssets="All" Condition="'$(IndividualLocalAuth)' == 'True'" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="$(TemplateEntityFrameworkVersion)" PrivateAssets="All" Condition="'$(IndividualLocalAuth)' == 'True'" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.0.0" Condition=" '$(IndividualLocalAuth)' == 'True' AND '$(UseLocalDB)' != 'True'" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="$(TemplateEntityFrameworkVersion)" Condition=" '$(IndividualLocalAuth)' == 'True' AND '$(UseLocalDB)' != 'True'" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.0.0" Condition=" '$(IndividualLocalAuth)' == 'True' AND '$(UseLocalDB)' == 'True'" /> <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="$(TemplateEntityFrameworkVersion)" Condition=" '$(IndividualLocalAuth)' == 'True' AND '$(UseLocalDB)' == 'True'" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="2.0.0" PrivateAssets="All" Condition="'$(IndividualLocalAuth)' == 'True'" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="$(TemplateEntityFrameworkVersion)" PrivateAssets="All" Condition="'$(IndividualLocalAuth)' == 'True'" />
<PackageReference Include="Microsoft.VisualStudio.Web.BrowserLink" Version="2.0.0" Condition="'$(UseBrowserLink)' == 'True'" /> <PackageReference Include="Microsoft.VisualStudio.Web.BrowserLink" Version="2.0.0" Condition="'$(UseBrowserLink)' == 'True'" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.0.0" PrivateAssets="All" Condition="'$(IndividualAuth)' == 'True'" /> <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.0.0" PrivateAssets="All" Condition="'$(IndividualAuth)' == 'True'" />
</ItemGroup> </ItemGroup>
<ItemGroup Condition="'$(NoTools)' != 'True'"> <ItemGroup Condition="'$(NoTools)' != 'True'">
<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.0" Condition="'$(IndividualLocalAuth)' == 'True'" /> <DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="$(TemplateEntityFrameworkVersion)" Condition="'$(IndividualLocalAuth)' == 'True'" />
<DotNetCliToolReference Include="Microsoft.Extensions.SecretManager.Tools" Version="2.0.0" Condition="'$(IndividualAuth)' == 'True' OR '$(OrganizationalAuth)' == 'True'" /> <DotNetCliToolReference Include="Microsoft.Extensions.SecretManager.Tools" Version="2.0.0" Condition="'$(IndividualAuth)' == 'True' OR '$(OrganizationalAuth)' == 'True'" />
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0" /> <DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0" />
</ItemGroup> </ItemGroup>

View File

@ -1,12 +1,13 @@
using Microsoft.Build.Utilities; using Microsoft.Build.Utilities;
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.IO.Compression; using System.IO.Compression;
using System.Linq; using System.Linq;
namespace DependencyUpdater namespace DependencyUpdater
{ {
public class UpdateAspNetReference : Task public class SubstituteProjectFileVariables : Task
{ {
private static string[] ProjectFileExtensions = new[] private static string[] ProjectFileExtensions = new[]
{ {
@ -15,15 +16,12 @@ namespace DependencyUpdater
}; };
public string NupkgFile { get; set; } public string NupkgFile { get; set; }
public string AspNetVersion { get; set; } public string Substitutions { get; set; }
public string OutDir { get; set; } public string OutDir { get; set; }
public override bool Execute() public override bool Execute()
{ {
if (string.IsNullOrEmpty(AspNetVersion)) var substitutionsDict = ParseSubstitutions(Substitutions);
{
throw new ArgumentException($"No value specified for {nameof(AspNetVersion)}.");
}
// We can't modify the .nupkg in place because the build system still // We can't modify the .nupkg in place because the build system still
// has a lock on the file. We can read it, but not write it. So copy // has a lock on the file. We can read it, but not write it. So copy
@ -35,20 +33,30 @@ namespace DependencyUpdater
{ {
foreach (var projectFile in zipFile.Entries.Where(IsProjectFile)) foreach (var projectFile in zipFile.Entries.Where(IsProjectFile))
{ {
PerformVariableSubstitution(projectFile); PerformVariableSubstitutions(projectFile, substitutionsDict);
} }
} }
return true; return true;
} }
private static IDictionary<string, string> ParseSubstitutions(string substitutions)
{
// Takes input of the form "key1=val1; key2=val2" (as is common in MSBuild)
return substitutions.Split(new[] { ';' })
.Select(pair => pair.Trim())
.Where(pair => !string.IsNullOrEmpty(pair) && pair.IndexOf('=') > 0)
.Select(pair => pair.Split('='))
.ToDictionary(splitPair => splitPair[0].Trim(), splitPair => splitPair[1].Trim());
}
private static bool IsProjectFile(ZipArchiveEntry entry) private static bool IsProjectFile(ZipArchiveEntry entry)
{ {
return ProjectFileExtensions.Any( return ProjectFileExtensions.Any(
extension => Path.GetExtension(entry.Name).Equals(extension, StringComparison.OrdinalIgnoreCase)); extension => Path.GetExtension(entry.Name).Equals(extension, StringComparison.OrdinalIgnoreCase));
} }
private void PerformVariableSubstitution(ZipArchiveEntry entry) private static void PerformVariableSubstitutions(ZipArchiveEntry entry, IDictionary<string, string> substitutions)
{ {
using (var fileStream = entry.Open()) using (var fileStream = entry.Open())
{ {
@ -59,20 +67,19 @@ namespace DependencyUpdater
contents = reader.ReadToEnd(); contents = reader.ReadToEnd();
fileStream.Seek(0, SeekOrigin.Begin); fileStream.Seek(0, SeekOrigin.Begin);
fileStream.SetLength(0); fileStream.SetLength(0);
writer.Write(SubstituteVariables(contents)); writer.Write(SubstituteVariables(contents, substitutions));
} }
} }
} }
private string SubstituteVariables(string projectFileContents) private static string SubstituteVariables(string text, IDictionary<string, string> substitutions)
{ {
// Currently we only need a way of updating ASP.NET package foreach (var kvp in substitutions)
// reference versions, so that's all this does. In the future, {
// we could generalise this into a system for injecting text = text.Replace($"$({kvp.Key})", kvp.Value);
// versions for all packages based on the KoreBuild lineup. }
return projectFileContents.Replace(
"$(TemplateAspNetCoreVersion)", return text;
AspNetVersion);
} }
} }
} }