sdk/Sdk/ExtensionsCsprojGenerator.cs (82 lines of code) (raw):
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace Microsoft.Azure.Functions.Worker.Sdk
{
internal class ExtensionsCsprojGenerator
{
private readonly IDictionary<string, string> _extensions;
private readonly string _outputPath;
private readonly string _targetFrameworkIdentifier;
private readonly string _targetFrameworkVersion;
private readonly string _azureFunctionsVersion;
public ExtensionsCsprojGenerator(IDictionary<string, string> extensions, string outputPath, string azureFunctionsVersion, string targetFrameworkIdentifier, string targetFrameworkVersion)
{
_extensions = extensions ?? throw new ArgumentNullException(nameof(extensions));
_outputPath = outputPath ?? throw new ArgumentNullException(nameof(outputPath));
_targetFrameworkIdentifier = targetFrameworkIdentifier ?? throw new ArgumentNullException(nameof(targetFrameworkIdentifier));
_targetFrameworkVersion = targetFrameworkVersion ?? throw new ArgumentNullException(nameof(targetFrameworkVersion));
_azureFunctionsVersion = azureFunctionsVersion ?? throw new ArgumentNullException(nameof(azureFunctionsVersion));
}
public void Generate()
{
string csproj = GetCsProjContent();
if (File.Exists(_outputPath))
{
string existing = File.ReadAllText(_outputPath);
if (string.Equals(csproj, existing, StringComparison.Ordinal))
{
// If contents are the same, only touch the file to update timestamp.
File.SetLastWriteTimeUtc(_outputPath, DateTime.UtcNow);
return;
}
}
Directory.CreateDirectory(Path.GetDirectoryName(_outputPath));
File.WriteAllText(_outputPath, csproj);
}
internal string GetCsProjContent()
{
string extensionReferences = GetExtensionReferences();
string targetFramework = Constants.Net80;
if (_targetFrameworkIdentifier.Equals(Constants.NetCoreApp, StringComparison.OrdinalIgnoreCase))
{
if (_azureFunctionsVersion.StartsWith(Constants.AzureFunctionsVersion3, StringComparison.OrdinalIgnoreCase) || _targetFrameworkVersion.Equals(Constants.NetCoreVersion31, StringComparison.OrdinalIgnoreCase))
{
targetFramework = Constants.NetCoreApp31;
}
}
string netSdkVersion = _azureFunctionsVersion.StartsWith(Constants.AzureFunctionsVersion3, StringComparison.OrdinalIgnoreCase) ? "3.1.2" : "4.6.0";
return $@"
<Project Sdk=""Microsoft.NET.Sdk"">
<PropertyGroup>
<TargetFramework>{targetFramework}</TargetFramework>
<AssemblyName>Microsoft.Azure.Functions.Worker.Extensions</AssemblyName>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
</PropertyGroup>
<ItemGroup>
<PackageReference Include=""Microsoft.NETCore.Targets"" Version=""3.0.0"" PrivateAssets=""all"" />
<PackageReference Include=""Microsoft.NET.Sdk.Functions"" Version=""{netSdkVersion}"" />
{extensionReferences} </ItemGroup>
<Target Name=""_VerifyTargetFramework"" BeforeTargets=""Build"">
<!-- It is possible to override our TFM via global properties. This can lead to successful builds, but runtime errors due to incompatible dependencies being brought in. -->
<Error Condition=""'$(TargetFramework)' != '{targetFramework}'"" Text=""The target framework '$(TargetFramework)' must be '{targetFramework}'. Verify if target framework has been overridden by a global property."" />
</Target>
</Project>
";
}
private string GetExtensionReferences()
{
var packages = new StringBuilder();
foreach (KeyValuePair<string, string> extensionPair in _extensions)
{
packages.AppendLine(GetPackageReferenceFromExtension(name: extensionPair.Key, version: extensionPair.Value));
}
return packages.ToString();
}
private static string GetPackageReferenceFromExtension(string name, string version)
{
return $" <PackageReference Include=\"{name}\" Version=\"{version}\" />";
}
}
}