in src/Amazon.Lambda.Tools/LambdaUtilities.cs [714:832]
public static ConvertManifestContentToSdkManifestResult ConvertManifestContentToSdkManifest(string targetFramework, string packageManifestContent)
{
var originalDoc = XDocument.Parse(packageManifestContent);
var sdkType = originalDoc.Root.Attribute("Sdk")?.Value ?? "Microsoft.NET.Sdk";
var isWebSdk = string.Equals(sdkType, "Microsoft.NET.Sdk.Web", StringComparison.OrdinalIgnoreCase);
if (string.Equals("netcoreapp2.1", targetFramework) && !isWebSdk)
return new ConvertManifestContentToSdkManifestResult(false, packageManifestContent);
var root = new XElement("Project");
root.SetAttributeValue("Sdk", "Microsoft.NET.Sdk");
var itemGroup = new XElement("ItemGroup");
root.Add(itemGroup);
Version dotnetSdkVersion;
try
{
dotnetSdkVersion = Amazon.Common.DotNetCli.Tools.DotNetCLIWrapper.GetSdkVersion();
}
catch (Exception e)
{
throw new LambdaToolsException("Error detecting .NET SDK version: \n\t" + e.Message, LambdaToolsException.LambdaErrorCode.FailedToDetectSdkVersion, e );
}
if (isWebSdk)
{
if(string.Equals("netcoreapp2.1", targetFramework, StringComparison.OrdinalIgnoreCase))
{
if (dotnetSdkVersion < LambdaConstants.MINIMUM_DOTNET_SDK_VERSION_FOR_ASPNET_LAYERS)
{
throw new LambdaToolsException($"To create a runtime package store layer for an ASP.NET Core project " +
$"version {LambdaConstants.MINIMUM_DOTNET_SDK_VERSION_FOR_ASPNET_LAYERS} " +
"or above of the .NET Core SDK must be installed. " +
"If a 2.1.X SDK is used then the \"dotnet store\" command will include all " +
"of the ASP.NET Core dependencies that are already available in Lambda.",
LambdaToolsException.LambdaErrorCode.LayerNetSdkVersionMismatch);
}
// These were added to make sure the ASP.NET Core dependencies are filter if any of the packages
// depend on them.
// See issue for more info: https://github.com/dotnet/cli/issues/10784
var aspNerCorePackageReference = new XElement("PackageReference");
aspNerCorePackageReference.SetAttributeValue("Include", "Microsoft.AspNetCore.App");
itemGroup.Add(aspNerCorePackageReference);
var aspNerCoreUpdatePackageReference = new XElement("PackageReference");
aspNerCoreUpdatePackageReference.SetAttributeValue("Update", "Microsoft.NETCore.App");
aspNerCoreUpdatePackageReference.SetAttributeValue("Publish", "false");
itemGroup.Add(aspNerCoreUpdatePackageReference);
}
else
{
var frameworkReference = new XElement("FrameworkReference");
frameworkReference.SetAttributeValue("Include", "Microsoft.AspNetCore.App");
var frameworkReferenceGroupItemGroup = new XElement("ItemGroup");
frameworkReferenceGroupItemGroup.Add(frameworkReference);
root.Add(frameworkReferenceGroupItemGroup);
}
}
foreach (var packageReference in originalDoc.XPathSelectElements("//ItemGroup/PackageReference"))
{
var packageName = packageReference.Attribute("Include")?.Value;
var version = packageReference.Attribute("Version")?.Value;
if (string.Equals(packageName, "Microsoft.AspNetCore.App", StringComparison.OrdinalIgnoreCase) ||
string.Equals(packageName, "Microsoft.AspNetCore.All", StringComparison.OrdinalIgnoreCase))
continue;
var newRef = new XElement("PackageReference");
newRef.SetAttributeValue("Include", packageName);
newRef.SetAttributeValue("Version", version);
itemGroup.Add(newRef);
}
// In .NET Core 3.1 the dotnet store command will include system dependencies like System.Runtime if
// any of the packages referenced in the packages included explicit references system dependencies.
// This is common on older packages or versions of packages before .NET Core 2.1. Newtonsoft.Json version 9.0.1
// is an example of this behavior.
//
// To avoid these system dependencies getting added to the layer we need to inject the list of system
// dependency to prune from the store graph.
//
// For further information on the issue check out this GitHub issue: https://github.com/dotnet/sdk/issues/10973
if (string.Equals(targetFramework, "netcoreapp3.1", StringComparison.OrdinalIgnoreCase))
{
var lambdaAssembly = typeof(LambdaUtilities).Assembly;
string manifestName;
if (isWebSdk)
{
manifestName = lambdaAssembly.GetManifestResourceNames().FirstOrDefault(x => x.EndsWith(LambdaConstants.PRUNE_LIST_SDKWEB_XML));
}
else
{
manifestName = lambdaAssembly.GetManifestResourceNames().FirstOrDefault(x => x.EndsWith(LambdaConstants.PRUNE_LIST_SDK_XML));
}
string pruneListString;
using (var stream = lambdaAssembly.GetManifestResourceStream(manifestName))
{
pruneListString = new StreamReader(stream).ReadToEnd();
}
var pruneListElement = XElement.Parse(pruneListString);
root.Add(pruneListElement);
}
var updatedDoc = new XDocument(root);
var updatedContent = updatedDoc.ToString();
return new ConvertManifestContentToSdkManifestResult(true, updatedContent);
}