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

Resolve runtime pack assets #2822

Merged
merged 3 commits into from
Jan 16, 2019
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
43 changes: 43 additions & 0 deletions src/Tasks/Microsoft.NET.Build.Tasks/DependencyContextBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ internal class DependencyContextBuilder
private IEnumerable<ReferenceInfo> _dependencyReferences;
private Dictionary<string, SingleProjectInfo> _referenceProjectInfos;
private IEnumerable<string> _excludeFromPublishPackageIds;
private IEnumerable<RuntimePackAssetInfo> _runtimePackAssets = Enumerable.Empty<RuntimePackAssetInfo>();
private CompilationOptions _compilationOptions;
private string _referenceAssembliesPath;
private Dictionary<PackageIdentity, string> _filteredPackages;
Expand Down Expand Up @@ -126,6 +127,12 @@ public DependencyContextBuilder WithExcludeFromPublishAssets(IEnumerable<string>
return this;
}

public DependencyContextBuilder WithRuntimePackAssets(IEnumerable<RuntimePackAssetInfo> runtimePackAssets)
{
_runtimePackAssets = runtimePackAssets;
return this;
}

public DependencyContextBuilder WithCompilationOptions(CompilationOptions compilationOptions)
{
_compilationOptions = compilationOptions;
Expand Down Expand Up @@ -177,6 +184,7 @@ public DependencyContext Build()
});
}
runtimeLibraries = runtimeLibraries
.Concat(GetRuntimePackLibraries(_runtimePackAssets))
.Concat(GetLibraries(runtimeExports, libraryLookup, dependencyLookup, runtime: true).Cast<RuntimeLibrary>())
.Concat(GetDirectReferenceRuntimeLibraries())
.Concat(GetDependencyReferenceRuntimeLibraries());
Expand Down Expand Up @@ -314,6 +322,10 @@ private RuntimeLibrary GetProjectRuntimeLibrary(
RuntimeAssetGroup[] runtimeAssemblyGroups = new[] { new RuntimeAssetGroup(string.Empty, projectInfo.OutputName) };

List<Dependency> dependencies = GetProjectDependencies(projectContext, dependencyLookup, includeCompilationLibraries);
foreach (var runtimePackGroup in _runtimePackAssets.GroupBy(asset => asset.PackageName + "/" + asset.PackageVersion))
{
dependencies.Add(new Dependency("runtimepack." + runtimePackGroup.First().PackageName, runtimePackGroup.First().PackageVersion));
}

return CreateRuntimeLibrary(
type: "project",
Expand Down Expand Up @@ -345,6 +357,37 @@ private CompilationLibrary GetProjectCompilationLibrary(
serviceable: false);
}

private IEnumerable<RuntimeLibrary> GetRuntimePackLibraries(IEnumerable<RuntimePackAssetInfo> runtimePackAssets)
{
return runtimePackAssets.GroupBy(asset => asset.PackageName + "/" + asset.PackageVersion).Select(
runtimePackAssetGroup =>
{
// Prefix paths with "./" to workaround https://github.com/dotnet/core-setup/issues/4978
List<RuntimeAssetGroup> runtimeAssemblyGroups = new List<RuntimeAssetGroup>()
{
new RuntimeAssetGroup(string.Empty,
runtimePackAssetGroup.Where(asset => asset.AssetType == AssetType.Runtime)
.Select(asset => CreateRuntimeFile("./" + asset.DestinationSubPath, asset.SourcePath)))
};
List<RuntimeAssetGroup> nativeLibraryGroups = new List<RuntimeAssetGroup>()
{
new RuntimeAssetGroup(string.Empty,
runtimePackAssetGroup.Where(asset => asset.AssetType == AssetType.Native)
.Select(asset => CreateRuntimeFile($"./" + asset.DestinationSubPath, asset.SourcePath)))
};

return new RuntimeLibrary("runtimepack",
"runtimepack." + runtimePackAssetGroup.First().PackageName,
runtimePackAssetGroup.First().PackageVersion,
hash: string.Empty,
runtimeAssemblyGroups,
nativeLibraryGroups,
resourceAssemblies: Enumerable.Empty<ResourceAssembly>(),
dependencies: Enumerable.Empty<Dependency>(),
serviceable: false);
});
}

private IEnumerable<Library> GetLibraries(
IEnumerable<LockFileTargetLibrary> exports,
LockFileLookup libraryLookup,
Expand Down
6 changes: 6 additions & 0 deletions src/Tasks/Microsoft.NET.Build.Tasks/GenerateDepsFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ public class GenerateDepsFile : TaskBase
[Required]
public ITaskItem[] FilesToSkip { get; set; }

public ITaskItem[] RuntimePackAssets { get; set; }

public ITaskItem CompilerOptions { get; set; }

public ITaskItem[] ExcludeFromPublishPackageReferences { get; set; }
Expand Down Expand Up @@ -136,6 +138,9 @@ protected override void ExecuteCore()

IEnumerable<string> excludeFromPublishAssets = PackageReferenceConverter.GetPackageIds(ExcludeFromPublishPackageReferences);

IEnumerable<RuntimePackAssetInfo> runtimePackAssets = RuntimePackAssets == null ? Enumerable.Empty<RuntimePackAssetInfo>() :
RuntimePackAssets.Select(item => RuntimePackAssetInfo.FromItem(item));

ProjectContext projectContext = lockFile.CreateProjectContext(
NuGetUtils.ParseFrameworkName(TargetFramework),
RuntimeIdentifier,
Expand All @@ -150,6 +155,7 @@ protected override void ExecuteCore()
.WithDependencyReferences(dependencyReferences)
.WithReferenceProjectInfos(referenceProjects)
.WithExcludeFromPublishAssets(excludeFromPublishAssets)
.WithRuntimePackAssets(runtimePackAssets)
.WithCompilationOptions(compilationOptions)
.WithReferenceAssembliesPath(FrameworkReferenceResolver.GetDefaultReferenceAssembliesPath())
.WithPackagesThatWhereFiltered(GetFilteredPackages())
Expand Down
31 changes: 19 additions & 12 deletions src/Tasks/Microsoft.NET.Build.Tasks/ResolveFrameworkReferences.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,15 @@ public class ResolveFrameworkReferences : TaskBase
[Output]
public ITaskItem[] PackagesToDownload { get; set; }

[Output]
public ITaskItem[] PackagesToReference { get; set; }

[Output]
public ITaskItem[] RuntimeFrameworks { get; set; }

[Output]
public ITaskItem[] TargetingPacks { get; set; }

[Output]
public ITaskItem[] RuntimePacks { get; set; }

// There should only be one AppHost item, but we use an item here so we can attach metadata to it
// (ie the apphost pack name and version, and the relative path to the apphost inside of it so
// we can resolve the full path later)
Expand All @@ -70,9 +70,9 @@ protected override void ExecuteCore()
.ToDictionary(kfr => kfr.Name);

List<ITaskItem> packagesToDownload = new List<ITaskItem>();
List<ITaskItem> packagesToReference = new List<ITaskItem>();
List<ITaskItem> runtimeFrameworks = new List<ITaskItem>();
List<ITaskItem> targetingPacks = new List<ITaskItem>();
List<ITaskItem> runtimePacks = new List<ITaskItem>();
List<string> unresolvedFrameworkReferences = new List<string>();

string appHostPackPattern = null;
Expand Down Expand Up @@ -149,10 +149,17 @@ protected override void ExecuteCore()
string runtimePackName = runtimePackNamePattern.Replace("**RID**", runtimePackRuntimeIdentifier);

TaskItem runtimePackItem = new TaskItem(runtimePackName);
runtimePackItem.SetMetadata(MetadataKeys.Version, knownFrameworkReference.LatestRuntimeFrameworkVersion);
runtimePackItem.SetMetadata(MetadataKeys.IsImplicitlyDefined, "true");
runtimePackItem.SetMetadata(MetadataKeys.PackageName, runtimePackName);
runtimePackItem.SetMetadata(MetadataKeys.PackageVersion, knownFrameworkReference.LatestRuntimeFrameworkVersion);
runtimePackItem.SetMetadata("FrameworkReference", knownFrameworkReference.Name);
runtimePackItem.SetMetadata(MetadataKeys.RuntimeIdentifier, runtimePackRuntimeIdentifier);

runtimePacks.Add(runtimePackItem);

TaskItem packageToDownload = new TaskItem(runtimePackName);
packageToDownload.SetMetadata(MetadataKeys.Version, knownFrameworkReference.LatestRuntimeFrameworkVersion);

packagesToReference.Add(runtimePackItem);
packagesToDownload.Add(packageToDownload);
}
}
}
Expand Down Expand Up @@ -228,11 +235,6 @@ protected override void ExecuteCore()
PackagesToDownload = packagesToDownload.ToArray();
}

if (packagesToReference.Any())
{
PackagesToReference = packagesToReference.ToArray();
}

if (runtimeFrameworks.Any())
{
RuntimeFrameworks = runtimeFrameworks.ToArray();
Expand All @@ -243,6 +245,11 @@ protected override void ExecuteCore()
TargetingPacks = targetingPacks.ToArray();
}

if (runtimePacks.Any())
{
RuntimePacks = runtimePacks.ToArray();
}

if (unresolvedFrameworkReferences.Any())
{
UnresolvedFrameworkReferences = unresolvedFrameworkReferences.ToArray();
Expand Down
71 changes: 71 additions & 0 deletions src/Tasks/Microsoft.NET.Build.Tasks/ResolveRuntimePackAssets.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;

namespace Microsoft.NET.Build.Tasks
{
public class ResolveRuntimePackAssets : TaskBase
{
public ITaskItem[] ResolvedRuntimePacks { get; set; }

[Output]
public ITaskItem[] RuntimePackAssets { get; set; }

protected override void ExecuteCore()
{
List<TaskItem> runtimePackAssets = new List<TaskItem>();

foreach (var runtimePack in ResolvedRuntimePacks)
{
string runtimePackRoot = runtimePack.GetMetadata(MetadataKeys.PackageDirectory);
string runtimeIdentifier = runtimePack.GetMetadata(MetadataKeys.RuntimeIdentifier);

// These hard-coded paths are temporary until we have "real" runtime packs, which will likely have a flattened
// folder structure and a manifest indicating how the files should be used: https://github.com/dotnet/cli/issues/10442
string runtimeAssetsPath = Path.Combine(runtimePackRoot, "runtimes", runtimeIdentifier, "lib", "netcoreapp3.0");
string nativeAssetsPath = Path.Combine(runtimePackRoot, "runtimes", runtimeIdentifier, "native");
dsplaisted marked this conversation as resolved.
Show resolved Hide resolved

var runtimeAssets = Directory.Exists(runtimeAssetsPath) ? Directory.GetFiles(runtimeAssetsPath) : Array.Empty<string>();
var nativeAssets = Directory.Exists(nativeAssetsPath) ? Directory.GetFiles(nativeAssetsPath) : Array.Empty<string>();

void AddAsset(string assetPath, string assetType)
{
if (assetPath.EndsWith(".pdb", StringComparison.OrdinalIgnoreCase) ||
assetPath.EndsWith(".map", StringComparison.OrdinalIgnoreCase) ||
assetPath.EndsWith(".txt", StringComparison.OrdinalIgnoreCase))
{
// Don't add assets for these files (shouldn't be necessary if/once we have a manifest in the runtime pack
// https://github.com/dotnet/cli/issues/10442
return;
}

var assetItem = new TaskItem(assetPath);

assetItem.SetMetadata(MetadataKeys.CopyLocal, "true");
assetItem.SetMetadata(MetadataKeys.DestinationSubPath, Path.GetFileName(assetPath));
assetItem.SetMetadata(MetadataKeys.AssetType, assetType);
assetItem.SetMetadata(MetadataKeys.PackageName, runtimePack.GetMetadata(MetadataKeys.PackageName));
assetItem.SetMetadata(MetadataKeys.PackageVersion, runtimePack.GetMetadata(MetadataKeys.PackageVersion));
assetItem.SetMetadata(MetadataKeys.RuntimeIdentifier, runtimeIdentifier);

runtimePackAssets.Add(assetItem);
}

foreach (var asset in runtimeAssets)
{
AddAsset(asset, "runtime");
}
foreach (var asset in nativeAssets)
{
AddAsset(asset, "native");
}
}

RuntimePackAssets = runtimePackAssets.ToArray();
}
}
}
50 changes: 50 additions & 0 deletions src/Tasks/Microsoft.NET.Build.Tasks/RuntimePackAssetInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
using Microsoft.Build.Framework;

namespace Microsoft.NET.Build.Tasks
{
internal class RuntimePackAssetInfo
{
public string SourcePath { get; set; }

public string DestinationSubPath { get; set; }

public AssetType AssetType { get; set; }

public string PackageName { get; set; }

public string PackageVersion { get; set; }

public string PackageRuntimeIdentifier { get; set; }

public static RuntimePackAssetInfo FromItem(ITaskItem item)
{
var assetInfo = new RuntimePackAssetInfo();
assetInfo.SourcePath = item.ItemSpec;
assetInfo.DestinationSubPath = item.GetMetadata(MetadataKeys.DestinationSubPath);

string assetTypeString = item.GetMetadata(MetadataKeys.AssetType);
if (assetTypeString.Equals("runtime", StringComparison.OrdinalIgnoreCase))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: extract method

{
assetInfo.AssetType = AssetType.Runtime;
}
else if (assetTypeString.Equals("native", StringComparison.OrdinalIgnoreCase))
{
assetInfo.AssetType = AssetType.Native;
}
else
{
throw new InvalidOperationException("Unexpected asset type: " + item.GetMetadata(MetadataKeys.AssetType));
}

assetInfo.PackageName = item.GetMetadata(MetadataKeys.PackageName);
assetInfo.PackageVersion = item.GetMetadata(MetadataKeys.PackageVersion);
assetInfo.PackageRuntimeIdentifier = item.GetMetadata(MetadataKeys.RuntimeIdentifier);

return assetInfo;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,8 @@ Copyright (c) .NET Foundation. All rights reserved.
<Target Name="_ResolveCopyLocalAssetsForPublish"
DependsOnTargets="ResolveLockFileCopyLocalFiles;
_ComputeUseBuildDependencyFile;
_DefaultMicrosoftNETPlatformLibrary">
_DefaultMicrosoftNETPlatformLibrary;
ResolveRuntimePackAssets">

<ResolveCopyLocalAssets ProjectPath="$(MSBuildProjectFullPath)"
AssetsFilePath="$(ProjectAssetsFile)"
Expand All @@ -292,6 +293,10 @@ Copyright (c) .NET Foundation. All rights reserved.
<Output TaskParameter="ResolvedAssets" ItemName="_ResolvedCopyLocalPublishAssets" />
</ResolveCopyLocalAssets>

<ItemGroup>
<_ResolvedCopyLocalPublishAssets Include="@(RuntimePackAsset)"/>
</ItemGroup>

<ItemGroup Condition="'$(_UseBuildDependencyFile)' != 'true'">
<!-- Remove the apphost executable from publish copy local assets; we will copy the generated apphost instead -->
<_ResolvedCopyLocalPublishAssets Remove="@(_NativeRestoredAppHostNETCore)" />
Expand Down Expand Up @@ -599,7 +604,8 @@ Copyright (c) .NET Foundation. All rights reserved.
_DefaultMicrosoftNETPlatformLibrary;
_HandlePackageFileConflicts;
_HandlePackageFileConflictsForPublish;
_ComputeReferenceAssemblies"
_ComputeReferenceAssemblies;
ResolveRuntimePackAssets"
Condition="'$(GenerateDependencyFile)' == 'true' and '$(_UseBuildDependencyFile)' != 'true'">

<PropertyGroup>
Expand All @@ -618,6 +624,7 @@ Copyright (c) .NET Foundation. All rights reserved.
ReferenceDependencyPaths="@(ReferenceDependencyPaths)"
ReferenceSatellitePaths="@(ReferenceSatellitePaths)"
ReferenceAssemblies="@(_ReferenceAssemblies)"
RuntimePackAssets="@(RuntimePackAsset)"
IncludeMainProject="$(IncludeMainProjectInDepsFile)"
RuntimeIdentifier="$(RuntimeIdentifier)"
PlatformLibraryName="$(MicrosoftNETPlatformLibrary)"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,9 @@ Copyright (c) .NET Foundation. All rights reserved.
DotNetAppHostExecutableNameWithoutExtension="$(_DotNetAppHostExecutableNameWithoutExtension)">

<Output TaskParameter="PackagesToDownload" ItemName="PackageReferenceToAdd" />
<Output TaskParameter="PackagesToReference" ItemName="PackageReference" />
<Output TaskParameter="RuntimeFrameworks" ItemName="RuntimeFramework" />
<Output TaskParameter="TargetingPacks" ItemName="TargetingPack" />
<Output TaskParameter="RuntimePacks" ItemName="RuntimePack" />
<Output TaskParameter="AppHost" ItemName="AppHostPack" />

<Output TaskParameter="UnresolvedFrameworkReferences" ItemName="_UnresolvedFrameworkReference" />
Expand Down Expand Up @@ -142,6 +142,32 @@ Copyright (c) .NET Foundation. All rights reserved.
<AppHostSourcePath>@(ResolvedAppHostPack->'%(Path)')</AppHostSourcePath>
</PropertyGroup>

</Target>

<UsingTask TaskName="ResolveRuntimePackAssets" AssemblyFile="$(MicrosoftNETBuildTasksAssembly)" />

<Target Name="ResolveRuntimePackAssets" DependsOnTargets="ResolvePackageAssets"
Condition="'@(RuntimePack)' != ''">

<GetPackageDirectory
Items="@(RuntimePack)"
ProjectPath="$(MSBuildProjectFullPath)"
PackageFolders="@(AssetsFilePackageFolder)">

<Output TaskParameter="Output" ItemName="ResolvedRuntimePack" />

</GetPackageDirectory>

<ResolveRuntimePackAssets ResolvedRuntimePacks="@(ResolvedRuntimePack)">
<Output TaskParameter="RuntimePackAssets" ItemName="RuntimePackAsset" />
</ResolveRuntimePackAssets>

<ItemGroup>
<ReferenceCopyLocalPaths Include="@(RuntimePackAsset)"
Condition="'$(CopyLocalLockFileAssemblies)' == 'true'" />
</ItemGroup>


</Target>

<!--
Expand Down
Loading