Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve the handling of platform-suffixed target frameworks #306

Merged
merged 1 commit into from
Feb 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/NuGetizer.Tasks/AssignPackagePath.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,13 @@ ITaskItem EnsurePackagePath(ITaskItem file, IDictionary<string, ITaskItem> kindM

output.SetMetadata(MetadataName.PackageFolder, packageFolder.Replace('\\', '/'));

// NOTE: a declared TargetFramework metadata trumps TargetFrameworkMoniker,
// NOTE: a declared TargetFramework metadata trumps the DefaultTargetFramework
// which is defaulted to that of the project being built.
var targetFramework = output.GetMetadata(MetadataName.TargetFramework);
if (string.IsNullOrEmpty(targetFramework) && frameworkSpecific)
{
var frameworkMoniker = file.GetTargetFrameworkMoniker();
targetFramework = frameworkMoniker.GetShortFrameworkName() ?? "";
var nugetFramework = file.GetNuGetTargetFramework(frameworkSpecific);
targetFramework = nugetFramework?.GetShortFolderName() ?? "";
// At this point we have the correct target framework
output.SetMetadata(MetadataName.TargetFramework, targetFramework);
}
Expand Down
59 changes: 35 additions & 24 deletions src/NuGetizer.Tasks/CreatePackage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -244,36 +244,43 @@ where PackFolderKind.Dependency.Equals(item.GetMetadata(MetadataName.PackFolder)
{
Id = item.ItemSpec,
Version = VersionRange.Parse(item.GetMetadata(MetadataName.Version)),
TargetFramework = item.GetNuGetTargetFramework(),
// PackFolderKind=Dependency has FrameworkSpecific=true, so pass that along
TargetFramework = item.GetNuGetTargetFramework(true) ?? NuGetFramework.AnyFramework,
Include = item.GetNullableMetadata(MetadataName.PackInclude) ?? item.GetNullableMetadata(MetadataName.IncludeAssets),
Exclude = item.GetNullableMetadata(MetadataName.PackExclude) ?? item.GetNullableMetadata(MetadataName.ExcludeAssets)
};

var definedDependencyGroups = (from dependency in dependencies
group dependency by dependency.TargetFramework into dependenciesByFramework
select new PackageDependencyGroup
(
dependenciesByFramework.Key,
(from dependency in dependenciesByFramework
where dependency.Id != "_._"
group dependency by dependency.Id into dependenciesById
select new PackageDependency
(
dependenciesById.Key,
dependenciesById.Select(x => x.Version).Aggregate(AggregateVersions),
dependenciesById.Select(x => x.Include).Aggregate(default(List<string>), AggregateAssetsFlow),
dependenciesById.Select(x => x.Exclude).Aggregate(default(List<string>), AggregateAssetsFlow)
)).ToList()
)).ToDictionary(p => p.TargetFramework.GetFrameworkString());
let targetFramework = dependenciesByFramework.Key
let packages = (from dependency in dependenciesByFramework
where dependency.Id != "_._"
group dependency by dependency.Id into dependenciesById
select new PackageDependency
(
dependenciesById.Key,
dependenciesById.Select(x => x.Version).Aggregate(AggregateVersions),
dependenciesById.Select(x => x.Include).Aggregate(default(List<string>), AggregateAssetsFlow),
dependenciesById.Select(x => x.Exclude).Aggregate(default(List<string>), AggregateAssetsFlow)
)).ToList()
select new PackageDependencyGroup(targetFramework, packages)
//).ToList();
).ToDictionary(p => p.TargetFramework.GetFrameworkString());

var libframeworks = (from item in Contents
where PackFolderKind.Lib.Equals(item.GetMetadata(MetadataName.PackFolder), StringComparison.OrdinalIgnoreCase) &&
!"all".Equals(item.GetMetadata(MetadataName.PrivateAssets), StringComparison.OrdinalIgnoreCase)
// PackFolderKind=Lib has FrameworkSpecific=true, so pass that along
select item.GetNuGetTargetFramework(true) ?? NuGetFramework.AnyFramework
).ToList();

// include frameworks referenced by libraries, but without dependencies..
foreach (var targetFramework in (from item in Contents
where PackFolderKind.Lib.Equals(item.GetMetadata(MetadataName.PackFolder), StringComparison.OrdinalIgnoreCase) &&
!"all".Equals(item.GetMetadata(MetadataName.PrivateAssets), StringComparison.OrdinalIgnoreCase)
select item.GetNuGetTargetFramework()))
if (!definedDependencyGroups.ContainsKey(targetFramework.GetFrameworkString()))
definedDependencyGroups.Add(targetFramework.GetFrameworkString(),
new PackageDependencyGroup(targetFramework, Array.Empty<PackageDependency>()));
foreach (var targetFramework in libframeworks
.Where(f => !definedDependencyGroups.ContainsKey(f.GetFrameworkString())))
{
definedDependencyGroups.Add(targetFramework.GetFrameworkString(),
new PackageDependencyGroup(targetFramework, Array.Empty<PackageDependency>()));
}

manifest.Metadata.DependencyGroups = definedDependencyGroups.Values;
}
Expand Down Expand Up @@ -381,8 +388,12 @@ where item.GetMetadata(MetadataName.PackFolder) == PackFolderKind.FrameworkRefer
select new FrameworkAssemblyReference
(
item.ItemSpec,
new[] { NuGetFramework.Parse(item.GetTargetFrameworkMoniker().FullName) }
)).Distinct(FrameworkAssemblyReferenceComparer.Default);
// PackFolderKind=FrameworkReference has FrameworkSpecific=true, so pass that along
new[] { item.GetNuGetTargetFramework(true) ?? NuGetFramework.AnyFramework }
))
.ToList()
.Distinct(FrameworkAssemblyReferenceComparer.Default)
.ToList();

manifest.Metadata.FrameworkReferences = frameworkReferences;
}
Expand Down
45 changes: 6 additions & 39 deletions src/NuGetizer.Tasks/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,55 +85,22 @@ public static Manifest GetManifest(this IPackageCoreReader packageReader)
}
}

public static NuGetFramework GetNuGetTargetFramework(this ITaskItem taskItem)
public static NuGetFramework? GetNuGetTargetFramework(this ITaskItem taskItem, bool? frameworkSpecific = default)
{
if (bool.TryParse(taskItem.GetMetadata(MetadataName.FrameworkSpecific), out var frameworkSpecific) &&
!frameworkSpecific)
return NuGetFramework.AnyFramework;
if (bool.TryParse(taskItem.GetMetadata(MetadataName.FrameworkSpecific), out var fws))
frameworkSpecific = fws;

var metadataValue = taskItem.GetMetadata(MetadataName.TargetFramework);
if (string.IsNullOrEmpty(metadataValue))
metadataValue = taskItem.GetMetadata(MetadataName.TargetFrameworkMoniker);

if (!string.IsNullOrEmpty(metadataValue))
return NuGetFramework.Parse(metadataValue);
else
if (frameworkSpecific != true)
return NuGetFramework.AnyFramework;
}

public static FrameworkName GetTargetFramework(this ITaskItem taskItem)
{
var metadataValue = taskItem.GetMetadata(MetadataName.TargetFramework);
if (string.IsNullOrEmpty(metadataValue))
metadataValue = taskItem.GetMetadata(MetadataName.TargetFrameworkMoniker);
metadataValue = taskItem.GetMetadata(MetadataName.DefaultTargetFramework);

if (!string.IsNullOrEmpty(metadataValue))
return new FrameworkName(NuGetFramework.Parse(metadataValue).DotNetFrameworkName);
return NuGetFramework.Parse(metadataValue);
else
return NullFramework;
}

public static FrameworkName GetTargetFrameworkMoniker(this ITaskItem item)
{
var value = item.GetMetadata(MetadataName.TargetFrameworkMoniker);
// \o/: Turn .NETPortable,Version=v5.0 into .NETPlatform,Version=v5.0, hardcoded for now?
// TODO: should be able to get .NETStandard,Version=v1.x from the item metadata somehow.

return string.IsNullOrEmpty(value) ?
NullFramework :
new FrameworkName(value);
}

public static string GetShortFrameworkName(this FrameworkName frameworkName)
{
if (frameworkName == null || frameworkName == NullFramework)
return null;

// In this case, NuGet returns portable50, is that correct?
//if (frameworkName.Identifier == ".NETPortable" && frameworkName.Version.Major == 5 && frameworkName.Version.Minor == 0)
// return "dotnet";

return NuGetFramework.Parse(frameworkName.FullName).GetShortFolderName();
}

public static void LogErrorCode(this TaskLoggingHelper log, string code, string message, params object[] messageArgs) =>
Expand Down
8 changes: 7 additions & 1 deletion src/NuGetizer.Tasks/MetadataName.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,15 @@ public static class MetadataName
/// </summary>
public const string FrameworkSpecific = nameof(FrameworkSpecific);

/// <summary>
/// The target framework of an item.
/// </summary>
public const string TargetFramework = nameof(TargetFramework);

public const string TargetFrameworkMoniker = nameof(TargetFrameworkMoniker);
/// <summary>
/// The original (and therefore default) target framework of the project that declared an item.
/// </summary>
public const string DefaultTargetFramework = nameof(DefaultTargetFramework);

/// <summary>
/// Available optional metadata values of contentFiles.
Expand Down
7 changes: 4 additions & 3 deletions src/NuGetizer.Tasks/NuGetizer.Inference.targets
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ Copyright (c) .NET Foundation. All rights reserved.
<GetPackageContentsDependsOn>
$(GetPackageContentsDependsOn);
_SetDefaultPackageReferencePack;
_SetPackTargetFramework;
InferPackageContents
</GetPackageContentsDependsOn>
</PropertyGroup>
Expand Down Expand Up @@ -303,14 +304,12 @@ Copyright (c) .NET Foundation. All rights reserved.
@(_SatelliteDllsProjectOutputGroupOutput -> '%(FinalOutputPath)')">
<PackFolder>$(PackFolder)</PackFolder>
<FrameworkSpecific>$(BuildOutputFrameworkSpecific)</FrameworkSpecific>
<TargetFramework Condition="'$(IsPackagingProject)' != 'true' or '$(BuildOutputFrameworkSpecific)' == 'true'">$(TargetFramework)</TargetFramework>
</_InferredProjectOutput>

<_InferredProjectOutput Include="@(DebugSymbolsProjectOutputGroupOutput -> '%(FinalOutputPath)')"
Condition="'$(PackSymbols)' != 'false'">
<PackFolder>$(PackFolder)</PackFolder>
<FrameworkSpecific>$(BuildOutputFrameworkSpecific)</FrameworkSpecific>
<TargetFramework Condition="'$(IsPackagingProject)' != 'true' or '$(BuildOutputFrameworkSpecific)' == 'true'">$(TargetFramework)</TargetFramework>
</_InferredProjectOutput>

<_InferredPackageFile Include="@(_InferredProjectOutput -> Distinct())" />
Expand All @@ -324,6 +323,7 @@ Copyright (c) .NET Foundation. All rights reserved.
'%(PackageReference.PrivateAssets)' != 'all' and
'%(PackageReference.Pack)' != 'false'">
<PackFolder>Dependency</PackFolder>
<!--<FrameworkSpecific Condition="'$(BuildOutputFrameworkSpecific)' == 'true'">true</FrameworkSpecific>-->
</_InferredPackageFile>

<!-- We can't use %(FrameworkFile)==true because it's not defined for raw file references and
Expand All @@ -346,7 +346,8 @@ Copyright (c) .NET Foundation. All rights reserved.
<Source>Implicit</Source>
<PackageId Condition="'$(IsPackable)' == 'true'">$(PackageId)</PackageId>
<Platform>$(Platform)</Platform>
<TargetFrameworkMoniker Condition="'$(IsPackagingProject)' != 'true' or '$(BuildOutputFrameworkSpecific)' == 'true'">$(TargetFrameworkMoniker)</TargetFrameworkMoniker>
<OriginalTargetFramework>$(PackTargetFramework)</OriginalTargetFramework>
<DefaultTargetFramework Condition="'$(IsPackagingProject)' != 'true' or '$(BuildOutputFrameworkSpecific)' == 'true'">$(PackTargetFramework)</DefaultTargetFramework>
</PackageFile>
</ItemGroup>
</Target>
Expand Down
6 changes: 4 additions & 2 deletions src/NuGetizer.Tasks/NuGetizer.MultiTargeting.targets
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,16 @@ Copyright (c) .NET Foundation. All rights reserved.
<Output ItemName="_PackageContent" TaskParameter="TargetOutputs" />
</MSBuild>

<!-- _AddPackageManifest adds per-TFM, so deduplicate and remove the TFM -->
<!-- _AddPackageManifest adds per-TFM, so deduplicate and remove the TF(M) -->
<ItemGroup Condition="'$(IsPackable)' == 'true'">
<_PackageMetadataContent Include="@(_PackageContent -> WithMetadataValue('PackFolder', 'Metadata'))" />
<_PackageContent Remove="@(_PackageMetadataContent)" />
<_PackageContent Include="@(_PackageMetadataContent -> Distinct())">
<AdditionalProperties />
<Platform>$(Platform)</Platform>
<TargetFrameworkMoniker />
<TargetFramework />
<DefaultTargetFramework />
<OriginalTargetFramework />
</_PackageContent>
</ItemGroup>

Expand Down
5 changes: 4 additions & 1 deletion src/NuGetizer.Tasks/NuGetizer.props
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,10 @@ Copyright (c) .NET Foundation. All rights reserved.
<!-- Don't show package files in project explorer by default -->
<Visible>false</Visible>
<TargetFramework />
<TargetFrameworkMoniker />
<!-- The (pack) target framework of the originating project -->
<OriginalTargetFramework />
<!-- The determined default (pack) target framework of an inferred item -->
<DefaultTargetFramework />
</PackageFile>
<PackageReference>
<!-- See https://github.com/NuGet/Home/wiki/PackageReference-Specification -->
Expand Down
Loading