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>
<PackageOutputPath Condition="'$(PackageOutputPath)' == ''">$(MSBuildThisFileDirectory)..\artifacts\tmp\</PackageOutputPath>
<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
@ -31,11 +32,12 @@
<None Include="Content/**" />
<!--
Having this package reference causes KoreBuild to pick the applicable
ASP.NET Core version from the lineup, making it possible to declare
the AspNetCoreVersionFromLineup variable above.
These references are here only so that KoreBuild will locate the applicable
version in the current lineup and we can then substitute it into the emitted
template .nupkg files.
-->
<PackageReference Include="Microsoft.AspNetCore.All" />
<PackageReference Include="Microsoft.AspNetCore" />
<PackageReference Include="Microsoft.EntityFrameworkCore" />
</ItemGroup>
</Project>

View File

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

View File

@ -11,7 +11,7 @@
</ItemGroup>
<ItemGroup Condition="'$(TargetFrameworkOverride)' == ''">
<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'" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFrameworkOverride)' != ''">
@ -23,15 +23,15 @@
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="$(TemplateAspNetCoreVersion)" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.ViewCompilation" Version="$(TemplateAspNetCoreVersion)" PrivateAssets="All" />
<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.Sqlite" Version="2.0.0" 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.Tools" 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="$(TemplateEntityFrameworkVersion)" 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="$(TemplateEntityFrameworkVersion)" PrivateAssets="All" Condition="'$(IndividualLocalAuth)' == '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'" />
</ItemGroup>
<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.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0" />
</ItemGroup>

View File

@ -16,7 +16,7 @@
<ItemGroup Condition="'$(TargetFrameworkOverride)' == ''">
<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'" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFrameworkOverride)' != ''">
@ -28,16 +28,16 @@
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="$(TemplateAspNetCoreVersion)" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.ViewCompilation" Version="$(TemplateAspNetCoreVersion)" PrivateAssets="All" />
<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.Sqlite" Version="2.0.0" 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.Tools" 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="$(TemplateEntityFrameworkVersion)" 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="$(TemplateEntityFrameworkVersion)" PrivateAssets="All" Condition="'$(IndividualLocalAuth)' == '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'" />
</ItemGroup>
<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.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0" />
</ItemGroup>

View File

@ -1,12 +1,13 @@
using Microsoft.Build.Utilities;
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
namespace DependencyUpdater
{
public class UpdateAspNetReference : Task
public class SubstituteProjectFileVariables : Task
{
private static string[] ProjectFileExtensions = new[]
{
@ -15,15 +16,12 @@ namespace DependencyUpdater
};
public string NupkgFile { get; set; }
public string AspNetVersion { get; set; }
public string Substitutions { get; set; }
public string OutDir { get; set; }
public override bool Execute()
{
if (string.IsNullOrEmpty(AspNetVersion))
{
throw new ArgumentException($"No value specified for {nameof(AspNetVersion)}.");
}
var substitutionsDict = ParseSubstitutions(Substitutions);
// 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
@ -35,20 +33,30 @@ namespace DependencyUpdater
{
foreach (var projectFile in zipFile.Entries.Where(IsProjectFile))
{
PerformVariableSubstitution(projectFile);
PerformVariableSubstitutions(projectFile, substitutionsDict);
}
}
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)
{
return ProjectFileExtensions.Any(
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())
{
@ -59,20 +67,19 @@ namespace DependencyUpdater
contents = reader.ReadToEnd();
fileStream.Seek(0, SeekOrigin.Begin);
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
// reference versions, so that's all this does. In the future,
// we could generalise this into a system for injecting
// versions for all packages based on the KoreBuild lineup.
return projectFileContents.Replace(
"$(TemplateAspNetCoreVersion)",
AspNetVersion);
foreach (var kvp in substitutions)
{
text = text.Replace($"$({kvp.Key})", kvp.Value);
}
return text;
}
}
}