Add reference assemblies and runtime targets support to dependency context builder.

This commit is contained in:
Pavel Krymets 2016-03-07 10:51:40 -08:00
parent 7cc90d9ad1
commit dd3c0f50db
24 changed files with 556 additions and 130 deletions

View file

@ -49,6 +49,16 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
/// </summary>
public IEnumerable<AnalyzerReference> AnalyzerReferences { get; }
/// <summary>
/// Get a list of runtime targets provided by this export.
/// </summary>
public IEnumerable<LibraryRuntimeTarget> RuntimeTargets { get; }
/// <summary>
/// Get a list of resource assemblies provided by this export.
/// </summary>
public IEnumerable<LibraryResourceAssembly> ResourceAssemblies { get; }
public LibraryExport(LibraryDescription library,
IEnumerable<LibraryAsset> compileAssemblies,
IEnumerable<LibraryAsset> sourceReferences,
@ -56,7 +66,9 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
IEnumerable<LibraryAsset> runtimeAssets,
IEnumerable<LibraryAsset> nativeLibraries,
IEnumerable<LibraryAsset> embeddedResources,
IEnumerable<AnalyzerReference> analyzers)
IEnumerable<AnalyzerReference> analyzers,
IEnumerable<LibraryRuntimeTarget> runtimeTargets,
IEnumerable<LibraryResourceAssembly> resourceAssemblies)
{
Library = library;
CompilationAssemblies = compileAssemblies;
@ -66,6 +78,8 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
NativeLibraries = nativeLibraries;
EmbeddedResources = embeddedResources;
AnalyzerReferences = analyzers;
RuntimeTargets = runtimeTargets;
ResourceAssemblies = resourceAssemblies;
}
private string DebuggerDisplay => Library.Identity.ToString();

View file

@ -26,6 +26,10 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
private IList<AnalyzerReference> _analyzerReferences;
private IList<LibraryRuntimeTarget> _runtimeTargets;
private IList<LibraryResourceAssembly> _resourceAssemblies;
public LibraryDescription Library { get; set; }
public IEnumerable<LibraryAsset> RuntimeAssemblies => _runtimeAssemblies;
@ -44,6 +48,10 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
public IEnumerable<AnalyzerReference> AnalyzerReferences => _analyzerReferences;
public IEnumerable<LibraryRuntimeTarget> RuntimeTargets => _runtimeTargets;
public IEnumerable<LibraryResourceAssembly> ResourceAssemblies => _resourceAssemblies;
public static LibraryExportBuilder Create(LibraryDescription library = null)
{
return new LibraryExportBuilder().WithLibrary(library);
@ -63,7 +71,9 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
RuntimeAssets ?? EmptyArray<LibraryAsset>.Value,
NativeLibraries ?? EmptyArray<LibraryAsset>.Value,
EmbeddedResources ?? EmptyArray<LibraryAsset>.Value,
AnalyzerReferences ?? EmptyArray<AnalyzerReference>.Value);
AnalyzerReferences ?? EmptyArray<AnalyzerReference>.Value,
RuntimeTargets ?? EmptyArray<LibraryRuntimeTarget>.Value,
ResourceAssemblies ?? EmptyArray<LibraryResourceAssembly>.Value);
}
public LibraryExportBuilder WithLibrary(LibraryDescription libraryDescription)
@ -114,6 +124,18 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
return this;
}
public LibraryExportBuilder WithRuntimeTargets(IEnumerable<LibraryRuntimeTarget> targets)
{
Replace(ref _runtimeTargets, targets);
return this;
}
public LibraryExportBuilder WithResourceAssemblies(IEnumerable<LibraryResourceAssembly> assemblies)
{
Replace(ref _resourceAssemblies, assemblies);
return this;
}
public LibraryExportBuilder AddRuntimeAssembly(LibraryAsset asset)
{
Add(ref _runtimeAssemblies, asset);
@ -156,10 +178,29 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
return this;
}
public LibraryExportBuilder AddRuntimeTarget(LibraryRuntimeTarget target)
{
Add(ref _runtimeTargets, target);
return this;
}
public LibraryExportBuilder AddResourceAssembly(LibraryResourceAssembly assembly)
{
Add(ref _resourceAssemblies, assembly);
return this;
}
private void Replace<T>(ref IList<T> list, IEnumerable<T> enumerable)
{
if (enumerable == null)
{
list = null;
}
else
{
list = new List<T>(enumerable);
}
}
private void Add<T>(ref IList<T> list, T item)
{

View file

@ -122,6 +122,8 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
.WithNativeLibraries(libraryExport.NativeLibraries)
.WithEmbedddedResources(libraryExport.EmbeddedResources)
.WithAnalyzerReference(analyzerReferences)
.WithResourceAssemblies(libraryExport.ResourceAssemblies)
.WithRuntimeTargets(libraryExport.RuntimeTargets)
.Build();
}
}
@ -199,6 +201,28 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
}
}
}
if (package.RuntimeTargets.Any())
{
foreach (var targetGroup in package.RuntimeTargets.GroupBy(t => t.Runtime))
{
var runtime = new List<LibraryAsset>();
var native = new List<LibraryAsset>();
foreach (var lockFileRuntimeTarget in targetGroup)
{
if (string.Equals(lockFileRuntimeTarget.AssetType, "native", StringComparison.OrdinalIgnoreCase))
{
native.Add(LibraryAsset.CreateFromRelativePath(package.Path, lockFileRuntimeTarget.Path));
}
else if (string.Equals(lockFileRuntimeTarget.AssetType, "runtime", StringComparison.OrdinalIgnoreCase))
{
runtime.Add(LibraryAsset.CreateFromRelativePath(package.Path, lockFileRuntimeTarget.Path));
}
}
builder.AddRuntimeTarget(new LibraryRuntimeTarget(targetGroup.Key, runtime, native));
}
}
return builder.Build();
}

View file

@ -0,0 +1,18 @@
// 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.
namespace Microsoft.DotNet.ProjectModel.Compilation
{
public class LibraryResourceAssembly
{
public LibraryResourceAssembly(LibraryAsset asset, string locale)
{
Asset = asset;
Locale = locale;
}
public LibraryAsset Asset { get; }
public string Locale { get; }
}
}

View file

@ -0,0 +1,32 @@
// 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.Linq;
using System.Collections.Generic;
namespace Microsoft.DotNet.ProjectModel.Compilation
{
public class LibraryRuntimeTarget
{
public LibraryRuntimeTarget(string runtime,
IEnumerable<LibraryAsset> runtimeAssemblies,
IEnumerable<LibraryAsset> nativeLibraries)
{
Runtime = runtime;
RuntimeAssemblies = runtimeAssemblies.ToArray();
NativeLibraries = nativeLibraries.ToArray();
}
public string Runtime { get; }
/// <summary>
/// Gets a list of fully-qualified paths to MSIL binaries required to run
/// </summary>
public IReadOnlyList<LibraryAsset> RuntimeAssemblies { get; }
/// <summary>
/// Gets a list of fully-qualified paths to native binaries required to run
/// </summary>
public IReadOnlyList<LibraryAsset> NativeLibraries { get; }
}
}

View file

@ -49,8 +49,8 @@ namespace Microsoft.Extensions.DependencyModel
runtime,
false,
GetCompilationOptions(compilerOptions),
GetLibraries(compilationExports, dependencyLookup, runtime: false).Cast<CompilationLibrary>().ToArray(),
GetLibraries(runtimeExports, dependencyLookup, runtime: true).Cast<RuntimeLibrary>().ToArray(),
GetLibraries(compilationExports, dependencyLookup, runtime: false).Cast<CompilationLibrary>(),
GetLibraries(runtimeExports, dependencyLookup, runtime: true).Cast<RuntimeLibrary>(),
new KeyValuePair<string, string[]>[0]);
}
@ -107,14 +107,14 @@ namespace Microsoft.Extensions.DependencyModel
}
}
string[] assemblies;
IEnumerable<string> assemblies;
if (type == LibraryType.ReferenceAssembly)
{
assemblies = ResolveReferenceAssembliesPath(libraryAssets);
}
else
{
assemblies = libraryAssets.Select(libraryAsset => libraryAsset.RelativePath).ToArray();
assemblies = libraryAssets.Select(libraryAsset => libraryAsset.RelativePath);
}
if (runtime)
@ -124,9 +124,10 @@ namespace Microsoft.Extensions.DependencyModel
export.Library.Identity.Name,
export.Library.Identity.Version.ToString(),
export.Library.Hash,
assemblies.Select(RuntimeAssembly.Create).ToArray(),
new RuntimeTarget[0],
libraryDependencies.ToArray(),
assemblies.Select(RuntimeAssembly.Create),
export.ResourceAssemblies.Select(CreateResourceAssembly),
export.RuntimeTargets.Select(CreateRuntimeTarget),
libraryDependencies,
serviceable
);
}
@ -138,15 +139,31 @@ namespace Microsoft.Extensions.DependencyModel
export.Library.Identity.Version.ToString(),
export.Library.Hash,
assemblies,
libraryDependencies.ToArray(),
libraryDependencies,
serviceable
);
}
}
private string[] ResolveReferenceAssembliesPath(IEnumerable<LibraryAsset> libraryAssets)
private ResourceAssembly CreateResourceAssembly(LibraryResourceAssembly resourceAssembly)
{
return new ResourceAssembly(
path: resourceAssembly.Asset.RelativePath,
locale: resourceAssembly.Locale
);
}
private RuntimeTarget CreateRuntimeTarget(LibraryRuntimeTarget runtimeTarget)
{
return new RuntimeTarget(
runtime: runtimeTarget.Runtime,
assemblies: runtimeTarget.RuntimeAssemblies.Select(a => RuntimeAssembly.Create(a.RelativePath)),
nativeLibraries: runtimeTarget.NativeLibraries.Select(l => l.RelativePath)
);
}
private IEnumerable<string> ResolveReferenceAssembliesPath(IEnumerable<LibraryAsset> libraryAssets)
{
var resolvedPaths = new List<string>();
var referenceAssembliesPath =
PathUtility.EnsureTrailingSlash(_referenceAssembliesPath);
foreach (var libraryAsset in libraryAssets)
@ -155,14 +172,13 @@ namespace Microsoft.Extensions.DependencyModel
// if not, save only assembly name and try to find it somehow later
if (libraryAsset.ResolvedPath.StartsWith(referenceAssembliesPath))
{
resolvedPaths.Add(libraryAsset.ResolvedPath.Substring(referenceAssembliesPath.Length));
yield return libraryAsset.ResolvedPath.Substring(referenceAssembliesPath.Length);
}
else
{
resolvedPaths.Add(Path.GetFileName(libraryAsset.ResolvedPath));
yield return Path.GetFileName(libraryAsset.ResolvedPath);
}
}
return resolvedPaths.ToArray();
}
}
}

View file

@ -170,6 +170,21 @@ namespace Microsoft.DotNet.ProjectModel.Graph
return library;
}
private static LockFileRuntimeTarget ReadRuntimeTarget(string property, JsonValue json)
{
var jsonObject = json as JsonObject;
if (jsonObject == null)
{
throw FileFormatException.Create("The value type is not an object.", json);
}
return new LockFileRuntimeTarget(
path: property,
runtime: jsonObject.ValueAsString("runtime"),
assetType: jsonObject.ValueAsString("assetType")
);
}
private static LockFileContentFile ReadContentFile(string property, JsonValue json)
{
var contentFile = new LockFileContentFile()

View file

@ -0,0 +1,21 @@
// 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.
namespace Microsoft.DotNet.ProjectModel.Graph
{
public class LockFileRuntimeTarget
{
public LockFileRuntimeTarget(string path, string runtime, string assetType)
{
Path = path;
Runtime = runtime;
AssetType = assetType;
}
public string Path { get; }
public string Runtime { get; }
public string AssetType { get; }
}
}

View file

@ -32,5 +32,7 @@ namespace Microsoft.DotNet.ProjectModel.Graph
public IList<LockFileItem> NativeLibraries { get; set; } = new List<LockFileItem>();
public IList<LockFileContentFile> ContentFiles { get; set; } = new List<LockFileContentFile>();
public IList<LockFileRuntimeTarget> RuntimeTargets { get; set; } = new List<LockFileRuntimeTarget>();
}
}

View file

@ -45,6 +45,8 @@ namespace Microsoft.DotNet.ProjectModel
public IEnumerable<LockFileContentFile> ContentFiles => Target.ContentFiles;
public IEnumerable<LockFileRuntimeTarget> RuntimeTargets => Target.RuntimeTargets;
private IEnumerable<LockFileItem> FilterPlaceholders(IList<LockFileItem> items)
{
return items.Where(a => !PackageDependencyProvider.IsPlaceholderFile(a));

View file

@ -3,16 +3,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Extensions.DependencyModel.Resolution;
namespace Microsoft.Extensions.DependencyModel
{
public class CompilationLibrary : Library
{
public CompilationLibrary(string type, string name, string version, string hash, string[] assemblies, Dependency[] dependencies, bool serviceable)
public CompilationLibrary(string type,
string name,
string version,
string hash,
IEnumerable<string> assemblies,
IEnumerable<Dependency> dependencies,
bool serviceable)
: base(type, name, version, hash, dependencies, serviceable)
{
Assemblies = assemblies;
Assemblies = assemblies.ToArray();
}
public IReadOnlyList<string> Assemblies { get; }

View file

@ -46,9 +46,10 @@ namespace Microsoft.Extensions.DependencyModel
name: identity.Item2,
version: identity.Item3,
hash: identity.Item4,
assemblies: packageGroup.Select(l => RuntimeAssembly.Create(l.AssetPath)).ToArray(),
subTargets: new RuntimeTarget[0],
dependencies: new Dependency[] { },
assemblies: packageGroup.Select(l => RuntimeAssembly.Create(l.AssetPath)),
resourceAssemblies: Enumerable.Empty<ResourceAssembly>(),
subTargets: Enumerable.Empty<RuntimeTarget>(),
dependencies: Enumerable.Empty<Dependency>(),
serviceable: false
));
}
@ -58,9 +59,9 @@ namespace Microsoft.Extensions.DependencyModel
runtime: string.Empty,
isPortable: false,
compilationOptions: CompilationOptions.Default,
compileLibraries: new CompilationLibrary[] {},
compileLibraries: Enumerable.Empty<CompilationLibrary>(),
runtimeLibraries: runtimeLibraries.ToArray(),
runtimeGraph: new KeyValuePair<string, string[]>[0]);
runtimeGraph: Enumerable.Empty<KeyValuePair<string, string[]>>());
}
private Tuple<string, string, string, string> PackageIdentity(DepsFileLine line)

View file

@ -173,7 +173,18 @@ namespace Microsoft.Extensions.DependencyModel
.Select(RuntimeAssembly.Create)
.ToArray();
return new RuntimeLibrary(stub.Type, name, version, stub.Hash, assemblies, runtimeTargets.ToArray(), dependencies, stub.Serviceable);
var resourceAssemblies = ReadResourceAssemblies((JObject)libraryObject[DependencyContextStrings.ResourceAssembliesPropertyName]);
return new RuntimeLibrary(
type: stub.Type,
name: name,
version: version,
hash: stub.Hash,
assemblies: assemblies,
resourceAssemblies: resourceAssemblies,
subTargets: runtimeTargets.ToArray(),
dependencies: dependencies,
serviceable: stub.Serviceable);
}
else
{
@ -182,6 +193,21 @@ namespace Microsoft.Extensions.DependencyModel
}
}
private IEnumerable<ResourceAssembly> ReadResourceAssemblies(JObject resourcesObject)
{
if (resourcesObject == null)
{
yield break;
}
foreach (var resourceProperty in resourcesObject)
{
yield return new ResourceAssembly(
locale: resourceProperty.Value[DependencyContextStrings.LocalePropertyName]?.Value<string>(),
path: resourceProperty.Key
);
}
}
private static IEnumerable<RuntimeTargetEntryStub> ReadRuntimeTargetEntries(JObject runtimeTargetObject)
{
if (runtimeTargetObject == null)

View file

@ -66,5 +66,9 @@ namespace Microsoft.Extensions.DependencyModel
internal const string RuntimeAssetType = "runtime";
internal const string NativeAssetType = "native";
internal const string ResourceAssembliesPropertyName = "resources";
internal const string LocalePropertyName = "locale";
}
}

View file

@ -140,49 +140,70 @@ namespace Microsoft.Extensions.DependencyModel
return targetObject;
}
private void AddCompilationAssemblies(JObject libraryObject, IEnumerable<string> compilationAssemblies)
{
libraryObject.Add(new JProperty(DependencyContextStrings.CompileTimeAssembliesKey,
WriteAssemblies(compilationAssemblies))
);
}
private void AddRuntimeAssemblies(JObject libraryObject, IEnumerable<RuntimeAssembly> runtimeAssemblies)
{
libraryObject.Add(new JProperty(DependencyContextStrings.RuntimeAssembliesKey,
WriteAssemblies(runtimeAssemblies.Select(a => a.Path)))
);
}
private void AddDependencies(JObject libraryObject, IEnumerable<Dependency> dependencies)
{
libraryObject.Add(
new JProperty(DependencyContextStrings.DependenciesPropertyName,
new JObject(
dependencies.Select(dependency => new JProperty(dependency.Name, dependency.Version))))
);
}
private void AddResourceAssemblies(JObject libraryObject, IEnumerable<ResourceAssembly> resourceAssemblies)
{
libraryObject.Add(DependencyContextStrings.ResourceAssembliesPropertyName,
new JObject(resourceAssemblies.Select(a =>
new JProperty(a.Path, new JObject(new JProperty(DependencyContextStrings.LocalePropertyName, a.Locale))))
)
);
}
private JObject WriteTargetLibrary(Library library)
{
string propertyName;
string[] assemblies;
var runtimeLibrary = library as RuntimeLibrary;
if (runtimeLibrary != null)
{
propertyName = DependencyContextStrings.RuntimeAssembliesKey;
assemblies = runtimeLibrary.Assemblies.Select(assembly => assembly.Path).ToArray();
var libraryObject = new JObject();
AddDependencies(libraryObject, runtimeLibrary.Dependencies);
AddRuntimeAssemblies(libraryObject, runtimeLibrary.Assemblies);
AddResourceAssemblies(libraryObject, runtimeLibrary.ResourceAssemblies);
return libraryObject;
}
else
{
var compilationLibrary = library as CompilationLibrary;
if (compilationLibrary != null)
{
propertyName = DependencyContextStrings.CompileTimeAssembliesKey;
assemblies = compilationLibrary.Assemblies.ToArray();
var libraryObject = new JObject();
AddDependencies(libraryObject, compilationLibrary.Dependencies);
AddCompilationAssemblies(libraryObject, compilationLibrary.Assemblies);
return libraryObject;
}
else
{
throw new NotSupportedException();
}
}
return new JObject(
new JProperty(DependencyContextStrings.DependenciesPropertyName, WriteDependencies(library.Dependencies)),
new JProperty(propertyName,
WriteAssemblies(assemblies))
);
}
private JObject WritePortableTargetLibrary(RuntimeLibrary runtimeLibrary, CompilationLibrary compilationLibrary)
{
var libraryObject = new JObject();
var dependencies = new HashSet<Dependency>();
var libraryObject = new JObject();
var dependencies = new HashSet<Dependency>();
if (runtimeLibrary != null)
{
libraryObject.Add(new JProperty(DependencyContextStrings.RuntimeAssembliesKey,
WriteAssemblies(runtimeLibrary.Assemblies.Select(a => a.Path)))
);
if (runtimeLibrary.RuntimeTargets.Any())
{
libraryObject.Add(new JProperty(
@ -190,21 +211,20 @@ namespace Microsoft.Extensions.DependencyModel
new JObject(runtimeLibrary.RuntimeTargets.SelectMany(WriteRuntimeTarget)))
);
}
AddResourceAssemblies(libraryObject, runtimeLibrary.ResourceAssemblies);
AddRuntimeAssemblies(libraryObject, runtimeLibrary.Assemblies);
dependencies.UnionWith(runtimeLibrary.Dependencies);
}
if (compilationLibrary != null)
{
libraryObject.Add(new JProperty(DependencyContextStrings.CompileTimeAssembliesKey,
WriteAssemblies(compilationLibrary.Assemblies))
);
AddCompilationAssemblies(libraryObject, compilationLibrary.Assemblies);
dependencies.UnionWith(compilationLibrary.Dependencies);
}
libraryObject.Add(
new JProperty(DependencyContextStrings.DependenciesPropertyName, WriteDependencies(dependencies)));
AddDependencies(libraryObject, dependencies);
return libraryObject;
}
@ -241,13 +261,6 @@ namespace Microsoft.Extensions.DependencyModel
return new JObject(assemblies.Select(assembly => new JProperty(assembly, new JObject())));
}
private JObject WriteDependencies(IEnumerable<Dependency> dependencies)
{
return new JObject(
dependencies.Select(dependency => new JProperty(dependency.Name, dependency.Version))
);
}
private JObject WriteLibraries(DependencyContext context)
{
var allLibraries =

View file

@ -1,19 +1,20 @@
// 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.Linq;
using System.Collections.Generic;
namespace Microsoft.Extensions.DependencyModel
{
public class Library
{
public Library(string type, string name, string version, string hash, Dependency[] dependencies, bool serviceable)
public Library(string type, string name, string version, string hash, IEnumerable<Dependency> dependencies, bool serviceable)
{
Type = type;
Name = name;
Version = version;
Hash = hash;
Dependencies = dependencies;
Dependencies = dependencies.ToArray();
Serviceable = serviceable;
}

View file

@ -0,0 +1,19 @@
// 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.
namespace Microsoft.Extensions.DependencyModel
{
public class ResourceAssembly
{
public ResourceAssembly(string path, string locale)
{
Locale = locale;
Path = path;
}
public string Locale { get; set; }
public string Path { get; set; }
}
}

View file

@ -13,18 +13,22 @@ namespace Microsoft.Extensions.DependencyModel
string name,
string version,
string hash,
RuntimeAssembly[] assemblies,
RuntimeTarget[] subTargets,
Dependency[] dependencies,
IEnumerable<RuntimeAssembly> assemblies,
IEnumerable<ResourceAssembly> resourceAssemblies,
IEnumerable<RuntimeTarget> subTargets,
IEnumerable<Dependency> dependencies,
bool serviceable)
: base(type, name, version, hash, dependencies, serviceable)
{
Assemblies = assemblies;
RuntimeTargets = subTargets;
Assemblies = assemblies.ToArray();
ResourceAssemblies = resourceAssemblies.ToArray();
RuntimeTargets = subTargets.ToArray();
}
public IReadOnlyList<RuntimeAssembly> Assemblies { get; }
public IReadOnlyList<ResourceAssembly> ResourceAssemblies { get; }
public IReadOnlyList<RuntimeTarget> RuntimeTargets { get; }
}
}

View file

@ -1,14 +1,15 @@
using System.Collections.Generic;
using System.Linq;
namespace Microsoft.Extensions.DependencyModel
{
public class RuntimeTarget
{
public RuntimeTarget(string runtime, IReadOnlyList<RuntimeAssembly> assemblies, IReadOnlyList<string> nativeLibraries)
public RuntimeTarget(string runtime, IEnumerable<RuntimeAssembly> assemblies, IEnumerable<string> nativeLibraries)
{
Runtime = runtime;
Assemblies = assemblies;
NativeLibraries = nativeLibraries;
Assemblies = assemblies.ToArray();
NativeLibraries = nativeLibraries.ToArray();
}
public string Runtime { get; }

View file

@ -1,3 +1,6 @@
// 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 System.Collections.Generic;
using System.IO;
@ -15,36 +18,6 @@ namespace Microsoft.DotNet.ProjectModel.Tests
{
private const string PackagePath = "PackagePath";
private LibraryExport ExportSingle(LibraryDescription description = null)
{
var rootProject = new Project()
{
Name = "RootProject",
CompilerName = "csc"
};
var rootProjectDescription = new ProjectDescription(
new LibraryRange(),
rootProject,
new LibraryRange[] { },
new TargetFrameworkInformation(),
true);
if (description == null)
{
description = rootProjectDescription;
}
else
{
description.Parents.Add(rootProjectDescription);
}
var libraryManager = new LibraryManager(new[] { description }, new DiagnosticMessage[] { }, "");
var allExports = new LibraryExporter(rootProjectDescription, libraryManager, "config", "runtime", "basepath", "solutionroot").GetAllExports();
var export = allExports.Single();
return export;
}
private PackageDescription CreateDescription(LockFileTargetLibrary target = null, LockFilePackageLibrary package = null)
{
return new PackageDescription(PackagePath,
@ -54,7 +27,7 @@ namespace Microsoft.DotNet.ProjectModel.Tests
}
[Fact]
private void ExportsPackageNativeLibraries()
public void ExportsPackageNativeLibraries()
{
var description = CreateDescription(
new LockFileTargetLibrary()
@ -76,7 +49,7 @@ namespace Microsoft.DotNet.ProjectModel.Tests
}
[Fact]
private void ExportsPackageCompilationAssebmlies()
public void ExportsPackageCompilationAssebmlies()
{
var description = CreateDescription(
new LockFileTargetLibrary()
@ -98,7 +71,7 @@ namespace Microsoft.DotNet.ProjectModel.Tests
}
[Fact]
private void ExportsPackageRuntimeAssebmlies()
public void ExportsPackageRuntimeAssebmlies()
{
var description = CreateDescription(
new LockFileTargetLibrary()
@ -120,7 +93,7 @@ namespace Microsoft.DotNet.ProjectModel.Tests
}
[Fact]
private void ExportsSources()
public void ExportsSources()
{
var description = CreateDescription(
package: new LockFilePackageLibrary()
@ -142,7 +115,7 @@ namespace Microsoft.DotNet.ProjectModel.Tests
}
[Fact]
private void ExportsCopyToOutputContentFiles()
public void ExportsCopyToOutputContentFiles()
{
var description = CreateDescription(
new LockFileTargetLibrary()
@ -170,7 +143,7 @@ namespace Microsoft.DotNet.ProjectModel.Tests
[Fact]
private void ExportsResourceContentFiles()
public void ExportsResourceContentFiles()
{
var description = CreateDescription(
new LockFileTargetLibrary()
@ -196,7 +169,7 @@ namespace Microsoft.DotNet.ProjectModel.Tests
}
[Fact]
private void ExportsCompileContentFiles()
public void ExportsCompileContentFiles()
{
var description = CreateDescription(
new LockFileTargetLibrary()
@ -224,7 +197,7 @@ namespace Microsoft.DotNet.ProjectModel.Tests
[Fact]
private void SelectsContentFilesOfProjectCodeLanguage()
public void SelectsContentFilesOfProjectCodeLanguage()
{
var description = CreateDescription(
new LockFileTargetLibrary()
@ -264,7 +237,7 @@ namespace Microsoft.DotNet.ProjectModel.Tests
}
[Fact]
private void SelectsContentFilesWithNoLanguageIfProjectLanguageNotMathed()
public void SelectsContentFilesWithNoLanguageIfProjectLanguageNotMathed()
{
var description = CreateDescription(
new LockFileTargetLibrary()
@ -295,5 +268,84 @@ namespace Microsoft.DotNet.ProjectModel.Tests
libraryAsset.RelativePath.Should().Be(Path.Combine("content", "file.any"));
libraryAsset.ResolvedPath.Should().Be(Path.Combine(PackagePath, "content", "file.any"));
}
[Fact]
public void ExportsRuntimeTargets()
{
var win8Native = Path.Combine("native", "win8-x64", "Native.dll");
var win8Runtime = Path.Combine("runtime", "win8-x64", "Runtime.dll");
var linuxNative = Path.Combine("native", "linux", "Native.dll");
var description = CreateDescription(
new LockFileTargetLibrary()
{
RuntimeTargets = new List<LockFileRuntimeTarget>()
{
new LockFileRuntimeTarget(
path: win8Native,
runtime: "win8-x64",
assetType: "native"
),
new LockFileRuntimeTarget(
path: win8Runtime,
runtime: "win8-x64",
assetType: "runtime"
),
new LockFileRuntimeTarget(
path: linuxNative,
runtime: "linux",
assetType: "native"
),
}
});
var result = ExportSingle(description);
result.RuntimeTargets.Should().HaveCount(2);
var runtimeTarget = result.RuntimeTargets.Should().Contain(t => t.Runtime == "win8-x64").Subject;
var runtime = runtimeTarget.RuntimeAssemblies.Single();
runtime.RelativePath.Should().Be(win8Runtime);
runtime.ResolvedPath.Should().Be(Path.Combine(PackagePath, win8Runtime));
var native = runtimeTarget.NativeLibraries.Single();
native.RelativePath.Should().Be(win8Native);
native.ResolvedPath.Should().Be(Path.Combine(PackagePath, win8Native));
runtimeTarget = result.RuntimeTargets.Should().Contain(t => t.Runtime == "linux").Subject;
native = runtimeTarget.NativeLibraries.Single();
native.RelativePath.Should().Be(linuxNative);
native.ResolvedPath.Should().Be(Path.Combine(PackagePath, linuxNative));
}
private LibraryExport ExportSingle(LibraryDescription description = null)
{
var rootProject = new Project()
{
Name = "RootProject",
CompilerName = "csc"
};
var rootProjectDescription = new ProjectDescription(
new LibraryRange(),
rootProject,
new LibraryRange[] { },
new TargetFrameworkInformation(),
true);
if (description == null)
{
description = rootProjectDescription;
}
else
{
description.Parents.Add(rootProjectDescription);
}
var libraryManager = new LibraryManager(new[] { description }, new DiagnosticMessage[] { }, "");
var allExports = new LibraryExporter(rootProjectDescription, libraryManager, "config", "runtime", "basepath", "solutionroot").GetAllExports();
var export = allExports.Single();
return export;
}
}
}

View file

@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Extensions.DependencyModel;
using Microsoft.Extensions.DependencyModel.Resolution;
using Moq;
@ -54,7 +55,14 @@ namespace StreamForwarderTests
failTwo.Object
};
var library = new CompilationLibrary(string.Empty, string.Empty, string.Empty, string.Empty, null, null, false);
var library = new CompilationLibrary(
string.Empty,
string.Empty,
string.Empty,
string.Empty,
Enumerable.Empty<string>(),
Enumerable.Empty<Dependency>(),
false);
var resolver = new CompositeCompilationAssemblyResolver(resolvers);
var result = resolver.TryResolveAssemblyPaths(library, null);
@ -82,7 +90,14 @@ namespace StreamForwarderTests
};
var assemblies = new List<string>();
var library = new CompilationLibrary(string.Empty, string.Empty, string.Empty, string.Empty, null, null, false);
var library = new CompilationLibrary(
string.Empty,
string.Empty,
string.Empty,
string.Empty,
Enumerable.Empty<string>(),
Enumerable.Empty<Dependency>(),
false);
var resolver = new CompositeCompilationAssemblyResolver(resolvers);
var result = resolver.TryResolveAssemblyPaths(library, assemblies);

View file

@ -104,9 +104,24 @@ namespace Microsoft.Extensions.DependencyModel.Tests
LibraryType.ReferenceAssembly,
LibraryDependencyType.Default)
}),
resourceAssemblies: new[]
{
new LibraryResourceAssembly(
new LibraryAsset("Dll", "en-US/Pack.Age.resources.dll", ""),
"en-US"
)
},
runtimeAssemblies: new[]
{
new LibraryAsset("Dll", "lib/Pack.Age.dll", ""),
},
runtimeTargets: new []
{
new LibraryRuntimeTarget(
"win8-x64",
new [] { new LibraryAsset("Dll", "win8-x64/Pack.Age.dll", "") },
new [] { new LibraryAsset("Dll", "win8-x64/Pack.Age.native.dll", "") }
)
}
),
Export(ReferenceAssemblyDescription("System.Collections",
@ -126,6 +141,11 @@ namespace Microsoft.Extensions.DependencyModel.Tests
lib.Version.Should().Be("1.2.3");
lib.Dependencies.Should().OnlyContain(l => l.Name == "System.Collections" && l.Version == "3.3.3");
lib.Assemblies.Should().OnlyContain(l => l.Path == "lib/Pack.Age.dll");
lib.ResourceAssemblies.Should().OnlyContain(l => l.Path == "en-US/Pack.Age.resources.dll" && l.Locale == "en-US");
var target = lib.RuntimeTargets.Should().Contain(t => t.Runtime == "win8-x64").Subject;
target.Assemblies.Should().OnlyContain(l => l.Path == "win8-x64/Pack.Age.dll");
target.NativeLibraries.Should().OnlyContain(l => l == "win8-x64/Pack.Age.native.dll");
var asm = context.RuntimeLibraries.Should().Contain(l => l.Name == "System.Collections").Subject;
asm.Type.Should().Be("referenceassembly");
@ -225,18 +245,16 @@ namespace Microsoft.Extensions.DependencyModel.Tests
private LibraryExport Export(
LibraryDescription description,
IEnumerable<LibraryAsset> compilationAssemblies = null,
IEnumerable<LibraryAsset> runtimeAssemblies = null)
IEnumerable<LibraryAsset> runtimeAssemblies = null,
IEnumerable<LibraryRuntimeTarget> runtimeTargets = null,
IEnumerable<LibraryResourceAssembly> resourceAssemblies = null)
{
return new LibraryExport(
description,
compilationAssemblies ?? Enumerable.Empty<LibraryAsset>(),
Enumerable.Empty<LibraryAsset>(),
runtimeAssemblies ?? Enumerable.Empty<LibraryAsset>(),
Enumerable.Empty<LibraryAsset>(),
Enumerable.Empty<LibraryAsset>(),
Enumerable.Empty<LibraryAsset>(),
Enumerable.Empty<AnalyzerReference>()
);
return LibraryExportBuilder.Create(description)
.WithCompilationAssemblies(compilationAssemblies)
.WithRuntimeAssemblies(runtimeAssemblies)
.WithRuntimeTargets(runtimeTargets)
.WithResourceAssemblies(resourceAssemblies)
.Build();
}
private PackageDescription PackageDescription(

View file

@ -183,6 +183,9 @@ namespace Microsoft.Extensions.DependencyModel.Tests
""runtimeTargets"": {
""lib/win7/System.Banana.dll"": { ""assetType"": ""runtime"", ""rid"": ""win7-x64""},
""lib/win7/Banana.dll"": { ""assetType"": ""native"", ""rid"": ""win7-x64""}
},
""resources"": {
""System.Banana.resources.dll"": { ""locale"": ""en-US"" }
}
}
}
@ -211,6 +214,8 @@ namespace Microsoft.Extensions.DependencyModel.Tests
package.Type.Should().Be("package");
package.Serviceable.Should().Be(false);
package.Assemblies.Should().Contain(a => a.Path == "lib/dotnet5.4/System.Banana.dll");
package.ResourceAssemblies.Should().Contain(a => a.Path == "System.Banana.resources.dll")
.Subject.Locale.Should().Be("en-US");
var target = package.RuntimeTargets.Should().Contain(t => t.Runtime == "win7-x64").Subject;
target.Assemblies.Should().Contain(a => a.Path == "lib/win7/System.Banana.dll");

View file

@ -154,6 +154,7 @@ namespace Microsoft.Extensions.DependencyModel.Tests
"1.2.3",
"HASH",
new [] { RuntimeAssembly.Create("Banana.dll")},
new [] { new ResourceAssembly("en-US\\Banana.Resource.dll", "en-US")},
new []
{
new RuntimeTarget("win7-x64",
@ -187,6 +188,10 @@ namespace Microsoft.Extensions.DependencyModel.Tests
nativeLibrary.Should().HavePropertyValue("rid", "win7-x64");
nativeLibrary.Should().HavePropertyValue("assetType", "native");
var resourceAssemblies = library.Should().HavePropertyAsObject("resources").Subject;
var resourceAssembly = resourceAssemblies.Should().HavePropertyAsObject("en-US\\Banana.Resource.dll").Subject;
resourceAssembly.Should().HavePropertyValue("locale", "en-US");
//libraries
var libraries = result.Should().HavePropertyAsObject("libraries").Subject;
library = libraries.Should().HavePropertyAsObject("PackageName/1.2.3").Subject;
@ -224,6 +229,7 @@ namespace Microsoft.Extensions.DependencyModel.Tests
"1.2.3",
"HASH",
new [] { RuntimeAssembly.Create("Banana.dll")},
new ResourceAssembly[] {},
new []
{
new RuntimeTarget("win7-x64",
@ -283,6 +289,7 @@ namespace Microsoft.Extensions.DependencyModel.Tests
"1.2.3",
"HASH",
new [] { RuntimeAssembly.Create("Banana.dll")},
new ResourceAssembly[] {},
new RuntimeTarget[] {},
new [] {
new Dependency("Fruits.Abstract.dll","2.0.0")
@ -308,6 +315,74 @@ namespace Microsoft.Extensions.DependencyModel.Tests
library.Should().HavePropertyValue("serviceable", true);
}
[Fact]
public void WritesResourceAssembliesForNonPortable()
{
var result = Save(Create(
"Target",
"runtime",
false,
runtimeLibraries: new[]
{
new RuntimeLibrary(
"package",
"PackageName",
"1.2.3",
"HASH",
new RuntimeAssembly[] { },
new []
{
new ResourceAssembly("en-US/Fruits.resources.dll", "en-US")
},
new RuntimeTarget[] { },
new Dependency[] { },
true
),
}));
var targets = result.Should().HavePropertyAsObject("targets").Subject;
var target = targets.Should().HavePropertyAsObject("Target/runtime").Subject;
var library = target.Should().HavePropertyAsObject("PackageName/1.2.3").Subject;
var resources = library.Should().HavePropertyAsObject("resources").Subject;
var resource = resources.Should().HavePropertyAsObject("en-US/Fruits.resources.dll").Subject;
resource.Should().HavePropertyValue("locale", "en-US");
}
[Fact]
public void WritesResourceAssembliesForPortable()
{
var result = Save(Create(
"Target",
"runtime",
true,
runtimeLibraries: new[]
{
new RuntimeLibrary(
"package",
"PackageName",
"1.2.3",
"HASH",
new RuntimeAssembly[] { },
new []
{
new ResourceAssembly("en-US/Fruits.resources.dll", "en-US")
},
new RuntimeTarget[] { },
new Dependency[] { },
true
),
}));
var targets = result.Should().HavePropertyAsObject("targets").Subject;
var target = targets.Should().HavePropertyAsObject("Target").Subject;
var library = target.Should().HavePropertyAsObject("PackageName/1.2.3").Subject;
var resources = library.Should().HavePropertyAsObject("resources").Subject;
var resource = resources.Should().HavePropertyAsObject("en-US/Fruits.resources.dll").Subject;
resource.Should().HavePropertyValue("locale", "en-US");
}
[Fact]
public void WritesCompilationOptions()
{