add support for type: platform

also some refactoring of DependencyContext to properly handle
placeholders in 'runtimeTargets'.
This commit is contained in:
Andrew Stanton-Nurse 2016-03-17 11:56:57 -07:00
parent 39584c5612
commit 43512b8973
60 changed files with 870 additions and 572 deletions

View file

@ -9,8 +9,4 @@
<activePackageSource>
<add key="AspNetCIDev" value="https://www.myget.org/F/aspnetcidev/api/v3/index.json" />
</activePackageSource>
<packageRestore>
<add key="enabled" value="False" />
<add key="automatic" value="False" />
</packageRestore>
</configuration>

View file

@ -11,7 +11,7 @@
"portable-net45+win8"
],
"dependencies": {
"Microsoft.NETCore.App": "1.0.0-rc2-23911"
"Microsoft.NETCore.App": { "type": "platform", "version": "1.0.0-rc2-23911" }
}
}
}

View file

@ -5,6 +5,7 @@ using System;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Collections.Generic;
namespace Microsoft.Extensions.DependencyModel
{
@ -54,12 +55,12 @@ namespace Microsoft.Extensions.DependencyModel
foreach (var runtimeLibrary in context.RuntimeLibraries)
{
CheckMetadata(runtimeLibrary);
foreach (var runtimeAssembly in runtimeLibrary.Assemblies)
{
var assembly = Assembly.Load(runtimeAssembly.Name);
}
}
foreach (var name in context.GetDefaultAssemblyNames())
{
var assembly = Assembly.Load(new AssemblyName(name));
}
}
}
}

View file

@ -10,7 +10,7 @@
"portable-net45+win8"
],
"dependencies": {
"Microsoft.NETCore.App": "1.0.0-rc2-23911"
"Microsoft.NETCore.App": { "type": "platform", "version": "1.0.0-rc2-23911" }
}
}
}

View file

@ -6,7 +6,7 @@
"netstandard1.5": {
"imports": [ "dnxcore50", "portable-net45+win8" ],
"dependencies": {
"Microsoft.NETCore.App": "1.0.0-rc2-23911",
"Microsoft.NETCore.App": { "type": "platform", "version": "1.0.0-rc2-23911" },
"Microsoft.AspNetCore.Server.Kestrel": "1.0.0-*"
}
}

View file

@ -99,7 +99,7 @@ namespace Microsoft.DotNet.Cli.Build.Framework
{
if (target == null)
{
throw new ArgumentNullException("target");
throw new ArgumentNullException(nameof(target));
}
if (target.Conditions == null)
@ -122,7 +122,7 @@ namespace Microsoft.DotNet.Cli.Build.Framework
{
if (target == null)
{
throw new ArgumentNullException("target");
throw new ArgumentNullException(nameof(target));
}
var sectionName = $"{target.Name.PadRight(_maxTargetLen + 2).Yellow()} ({target.Source.White()})";

View file

@ -12,7 +12,7 @@ namespace Microsoft.DotNet.Cli.Build.Framework
{
if (architectures == null)
{
throw new ArgumentNullException("architectures");
throw new ArgumentNullException(nameof(architectures));
}
_buildArchitectures = architectures;

View file

@ -12,7 +12,7 @@ namespace Microsoft.DotNet.Cli.Build.Framework
{
if (platforms == null)
{
throw new ArgumentNullException("platforms");
throw new ArgumentNullException(nameof(platforms));
}
_buildPlatforms = platforms;

View file

@ -15,17 +15,17 @@ namespace Microsoft.DotNet.Cli.Utils
protected IEnvironmentProvider _environment;
protected IPlatformCommandSpecFactory _commandSpecFactory;
public AbstractPathBasedCommandResolver(IEnvironmentProvider environment,
public AbstractPathBasedCommandResolver(IEnvironmentProvider environment,
IPlatformCommandSpecFactory commandSpecFactory)
{
if (environment == null)
{
throw new ArgumentNullException("environment");
throw new ArgumentNullException(nameof(environment));
}
if (commandSpecFactory == null)
{
throw new ArgumentNullException("commandSpecFactory");
throw new ArgumentNullException(nameof(commandSpecFactory));
}
_environment = environment;

View file

@ -7,10 +7,10 @@
"dependencies": {
"Microsoft.DotNet.ProjectModel": "1.0.0-*",
"Microsoft.Extensions.PlatformAbstractions": "1.0.0-rc2-16537",
"NuGet.Versioning": "3.4.0-rtm-0763",
"NuGet.Packaging": "3.4.0-rtm-0763",
"NuGet.Frameworks": "3.4.0-rtm-0763",
"NuGet.ProjectModel": "3.4.0-rtm-0763"
"NuGet.Versioning": "3.5.0-beta-1034",
"NuGet.Packaging": "3.5.0-beta-1034",
"NuGet.Frameworks": "3.5.0-beta-1034",
"NuGet.ProjectModel": "3.5.0-beta-1034"
},
"frameworks": {
"net451": {

View file

@ -109,7 +109,11 @@ namespace Microsoft.DotNet.Cli.Compiler.Common
private static AssemblyRedirect[] CollectRedirects(IEnumerable<LibraryExport> dependencies)
{
var allRuntimeAssemblies = dependencies.SelectMany(d => d.RuntimeAssemblies).Select(GetAssemblyInfo).ToArray();
var allRuntimeAssemblies = dependencies
.SelectMany(d => d.RuntimeAssemblyGroups.GetDefaultAssets())
.Select(GetAssemblyInfo)
.ToArray();
var assemblyLookup = allRuntimeAssemblies.ToDictionary(r => r.Identity.ToLookupKey());
var redirectAssemblies = new HashSet<AssemblyRedirect>();

View file

@ -21,9 +21,6 @@ namespace Microsoft.Dotnet.Cli.Compiler.Common
{
public class Executable
{
// GROOOOOSS
private static readonly string RedistPackageName = "Microsoft.NETCore.App";
private readonly ProjectContext _context;
private readonly LibraryExporter _exporter;
@ -94,8 +91,8 @@ namespace Microsoft.Dotnet.Cli.Compiler.Common
{
foreach (var libraryExport in libraryExports)
{
libraryExport.RuntimeAssemblies.CopyTo(_runtimeOutputPath);
libraryExport.NativeLibraries.CopyTo(_runtimeOutputPath);
libraryExport.RuntimeAssemblyGroups.GetDefaultAssets().CopyTo(_runtimeOutputPath);
libraryExport.NativeLibraryGroups.GetDefaultAssets().CopyTo(_runtimeOutputPath);
}
}
@ -133,15 +130,30 @@ namespace Microsoft.Dotnet.Cli.Compiler.Common
var runtimeOptions = new JObject();
json.Add("runtimeOptions", runtimeOptions);
var redistExport = exporter
.GetAllExports()
.FirstOrDefault(l => l.Library.Identity.Name.Equals(RedistPackageName, StringComparison.OrdinalIgnoreCase));
if (redistExport != null)
var redistPackage = _context.RootProject.Dependencies
.Where(r => r.Type.Equals(LibraryDependencyType.Platform))
.ToList();
if(redistPackage.Count > 0)
{
var framework = new JObject(
new JProperty("name", redistExport.Library.Identity.Name),
new JProperty("version", redistExport.Library.Identity.Version.ToNormalizedString()));
runtimeOptions.Add("framework", framework);
if(redistPackage.Count > 1)
{
throw new InvalidOperationException("Multiple packages with type: \"platform\" were specified!");
}
var packageName = redistPackage.Single().Name;
var redistExport = exporter.GetAllExports()
.FirstOrDefault(e => e.Library.Identity.Name.Equals(packageName));
if (redistExport == null)
{
throw new InvalidOperationException($"Platform package '{packageName}' was not present in the graph.");
}
else
{
var framework = new JObject(
new JProperty("name", redistExport.Library.Identity.Name),
new JProperty("version", redistExport.Library.Identity.Version.ToNormalizedString()));
runtimeOptions.Add("framework", framework);
}
}
var runtimeConfigJsonFile =
@ -214,8 +226,8 @@ namespace Microsoft.Dotnet.Cli.Compiler.Common
private static IEnumerable<string> GenerateLines(LibraryExport export)
{
return GenerateLines(export, export.RuntimeAssemblies, "runtime")
.Union(GenerateLines(export, export.NativeLibraries, "native"));
return GenerateLines(export, export.RuntimeAssemblyGroups.GetDefaultAssets(), "runtime")
.Union(GenerateLines(export, export.NativeLibraryGroups.GetDefaultAssets(), "native"));
}
private static IEnumerable<string> GenerateLines(LibraryExport export, IEnumerable<LibraryAsset> items, string type)

View file

@ -5,7 +5,7 @@
},
"dependencies": {
"NETStandard.Library": "1.5.0-rc2-23911",
"System.CommandLine": "0.1.0-e160119-1",
"System.CommandLine": "0.1.0-e160323-1",
"Microsoft.CodeAnalysis.CSharp": "1.2.0-beta1-20160202-02",
"Microsoft.DotNet.ProjectModel": "1.0.0-*",
"Microsoft.DotNet.Cli.Utils": "1.0.0-*",

View file

@ -22,7 +22,7 @@ namespace Microsoft.DotNet.ProjectModel.Loader
foreach (var export in exporter.GetAllExports())
{
// TODO: Handle resource assemblies
foreach (var asset in export.RuntimeAssemblies)
foreach (var asset in export.RuntimeAssemblyGroups.GetDefaultAssets())
{
// REVIEW: Should we use the following?
// AssemblyLoadContext.GetAssemblyName(asset.ResolvedPath);
@ -30,7 +30,7 @@ namespace Microsoft.DotNet.ProjectModel.Loader
assemblies[assemblyName] = asset.ResolvedPath;
}
foreach (var asset in export.NativeLibraries)
foreach (var asset in export.NativeLibraryGroups.GetDefaultAssets())
{
dllImports[asset.Name] = asset.ResolvedPath;
}

View file

@ -0,0 +1,29 @@
// 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 LibraryAssetGroup
{
public LibraryAssetGroup(string runtime, params LibraryAsset[] assets) : this(runtime, (IEnumerable<LibraryAsset>)assets) { }
public LibraryAssetGroup(params LibraryAsset[] assets) : this(string.Empty, (IEnumerable<LibraryAsset>)assets) { }
public LibraryAssetGroup(IEnumerable<LibraryAsset> assets) : this(string.Empty, assets) { }
public LibraryAssetGroup(string runtime,
IEnumerable<LibraryAsset> assets)
{
Runtime = runtime;
Assets = assets.ToArray();
}
public string Runtime { get; }
/// <summary>
/// Gets a list of assets provided in this runtime group
/// </summary>
public IReadOnlyList<LibraryAsset> Assets { get; }
}
}

View file

@ -15,9 +15,9 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
public LibraryDescription Library { get; }
/// <summary>
/// Gets a list of fully-qualified paths to MSIL binaries required to run
/// Gets a list of MSIL binaries required to run
/// </summary>
public IEnumerable<LibraryAsset> RuntimeAssemblies { get; }
public IEnumerable<LibraryAssetGroup> RuntimeAssemblyGroups { get; }
/// <summary>
/// Non assembly runtime assets.
@ -25,9 +25,9 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
public IEnumerable<LibraryAsset> RuntimeAssets { get; }
/// <summary>
/// Gets a list of fully-qualified paths to native binaries required to run
/// Gets a list of native binaries required to run
/// </summary>
public IEnumerable<LibraryAsset> NativeLibraries { get; }
public IEnumerable<LibraryAssetGroup> NativeLibraryGroups { get; }
/// <summary>
/// Gets a list of fully-qualified paths to MSIL metadata references
@ -49,11 +49,6 @@ 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>
@ -62,23 +57,21 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
public LibraryExport(LibraryDescription library,
IEnumerable<LibraryAsset> compileAssemblies,
IEnumerable<LibraryAsset> sourceReferences,
IEnumerable<LibraryAsset> runtimeAssemblies,
IEnumerable<LibraryAssetGroup> runtimeAssemblyGroups,
IEnumerable<LibraryAsset> runtimeAssets,
IEnumerable<LibraryAsset> nativeLibraries,
IEnumerable<LibraryAssetGroup> nativeLibraryGroups,
IEnumerable<LibraryAsset> embeddedResources,
IEnumerable<AnalyzerReference> analyzers,
IEnumerable<LibraryRuntimeTarget> runtimeTargets,
IEnumerable<LibraryResourceAssembly> resourceAssemblies)
{
Library = library;
CompilationAssemblies = compileAssemblies;
SourceReferences = sourceReferences;
RuntimeAssemblies = runtimeAssemblies;
RuntimeAssemblyGroups = runtimeAssemblyGroups;
RuntimeAssets = runtimeAssets;
NativeLibraries = nativeLibraries;
NativeLibraryGroups = nativeLibraryGroups;
EmbeddedResources = embeddedResources;
AnalyzerReferences = analyzers;
RuntimeTargets = runtimeTargets;
ResourceAssemblies = resourceAssemblies;
}

View file

@ -8,7 +8,7 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
{
public class LibraryExportBuilder
{
private IList<LibraryAsset> _runtimeAssemblies;
private IList<LibraryAssetGroup> _runtimeAssemblyGroups;
private IList<LibraryAsset> _runtimeAssets;
@ -18,19 +18,17 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
private IList<LibraryAsset> _sourceReferences;
private IList<LibraryAsset> _nativeLibraries;
private IList<LibraryAssetGroup> _nativeLibraryGroups;
private IList<LibraryAsset> _embeddedResources;
private IList<AnalyzerReference> _analyzerReferences;
private IList<LibraryRuntimeTarget> _runtimeTargets;
private IList<LibraryResourceAssembly> _resourceAssemblies;
public LibraryDescription Library { get; set; }
public IEnumerable<LibraryAsset> RuntimeAssemblies => _runtimeAssemblies;
public IEnumerable<LibraryAssetGroup> RuntimeAssemblyGroups => _runtimeAssemblyGroups;
public IEnumerable<LibraryAsset> RuntimeAssets => _runtimeAssets;
@ -40,14 +38,12 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
public IEnumerable<LibraryAsset> SourceReferences => _sourceReferences;
public IEnumerable<LibraryAsset> NativeLibraries => _nativeLibraries;
public IEnumerable<LibraryAssetGroup> NativeLibraryGroups => _nativeLibraryGroups;
public IEnumerable<LibraryAsset> EmbeddedResources => _embeddedResources;
public IEnumerable<AnalyzerReference> AnalyzerReferences => _analyzerReferences;
public IEnumerable<LibraryRuntimeTarget> RuntimeTargets => _runtimeTargets;
public IEnumerable<LibraryResourceAssembly> ResourceAssemblies => _resourceAssemblies;
public static LibraryExportBuilder Create(LibraryDescription library = null)
@ -65,12 +61,11 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
Library,
CompilationAssemblies ?? EmptyArray<LibraryAsset>.Value,
SourceReferences ?? EmptyArray<LibraryAsset>.Value,
RuntimeAssemblies ?? EmptyArray<LibraryAsset>.Value,
RuntimeAssemblyGroups ?? EmptyArray<LibraryAssetGroup>.Value,
RuntimeAssets ?? EmptyArray<LibraryAsset>.Value,
NativeLibraries ?? EmptyArray<LibraryAsset>.Value,
NativeLibraryGroups ?? EmptyArray<LibraryAssetGroup>.Value,
EmbeddedResources ?? EmptyArray<LibraryAsset>.Value,
AnalyzerReferences ?? EmptyArray<AnalyzerReference>.Value,
RuntimeTargets ?? EmptyArray<LibraryRuntimeTarget>.Value,
ResourceAssemblies ?? EmptyArray<LibraryResourceAssembly>.Value);
}
@ -80,9 +75,9 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
return this;
}
public LibraryExportBuilder WithRuntimeAssemblies(IEnumerable<LibraryAsset> assets)
public LibraryExportBuilder WithRuntimeAssemblyGroups(IEnumerable<LibraryAssetGroup> assets)
{
Replace(ref _runtimeAssemblies, assets);
Replace(ref _runtimeAssemblyGroups, assets);
return this;
}
@ -104,9 +99,9 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
return this;
}
public LibraryExportBuilder WithNativeLibraries(IEnumerable<LibraryAsset> assets)
public LibraryExportBuilder WithNativeLibraryGroups(IEnumerable<LibraryAssetGroup> assets)
{
Replace(ref _nativeLibraries, assets);
Replace(ref _nativeLibraryGroups, assets);
return this;
}
@ -122,21 +117,15 @@ 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)
public LibraryExportBuilder AddRuntimeAssemblyGroup(LibraryAssetGroup asset)
{
Add(ref _runtimeAssemblies, asset);
Add(ref _runtimeAssemblyGroups, asset);
return this;
}
@ -158,9 +147,9 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
return this;
}
public LibraryExportBuilder AddNativeLibrary(LibraryAsset asset)
public LibraryExportBuilder AddNativeLibraryGroup(LibraryAssetGroup asset)
{
Add(ref _compilationAssets, asset);
Add(ref _nativeLibraryGroups, asset);
return this;
}
@ -176,12 +165,6 @@ 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);

View file

@ -117,13 +117,12 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
yield return LibraryExportBuilder.Create(library)
.WithCompilationAssemblies(compilationAssemblies)
.WithSourceReferences(sourceReferences)
.WithRuntimeAssemblies(libraryExport.RuntimeAssemblies)
.WithRuntimeAssemblyGroups(libraryExport.RuntimeAssemblyGroups)
.WithRuntimeAssets(libraryExport.RuntimeAssets)
.WithNativeLibraries(libraryExport.NativeLibraries)
.WithNativeLibraryGroups(libraryExport.NativeLibraryGroups)
.WithEmbedddedResources(libraryExport.EmbeddedResources)
.WithAnalyzerReference(analyzerReferences)
.WithResourceAssemblies(libraryExport.ResourceAssemblies)
.WithRuntimeTargets(libraryExport.RuntimeTargets)
.Build();
}
}
@ -158,8 +157,8 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
private LibraryExport ExportPackage(PackageDescription package)
{
var builder = LibraryExportBuilder.Create(package);
builder.WithNativeLibraries(PopulateAssets(package, package.NativeLibraries));
builder.WithRuntimeAssemblies(PopulateAssets(package, package.RuntimeAssemblies));
builder.AddNativeLibraryGroup(new LibraryAssetGroup(PopulateAssets(package, package.NativeLibraries)));
builder.AddRuntimeAssemblyGroup(new LibraryAssetGroup(PopulateAssets(package, package.RuntimeAssemblies)));
builder.WithCompilationAssemblies(PopulateAssets(package, package.CompileTimeAssemblies));
builder.WithSourceReferences(GetSharedSources(package));
builder.WithAnalyzerReference(GetAnalyzerReferences(package));
@ -220,7 +219,15 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
}
}
builder.AddRuntimeTarget(new LibraryRuntimeTarget(targetGroup.Key, runtime, native));
if (runtime.Any())
{
builder.AddRuntimeAssemblyGroup(new LibraryAssetGroup(targetGroup.Key, runtime));
}
if (native.Any())
{
builder.AddNativeLibraryGroup(new LibraryAssetGroup(targetGroup.Key, native));
}
}
}
@ -243,7 +250,7 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
assemblyPath);
builder.AddCompilationAssembly(compileAsset);
builder.AddRuntimeAssembly(compileAsset);
builder.AddRuntimeAssemblyGroup(new LibraryAssetGroup(new[] { compileAsset }));
if (File.Exists(pdbPath))
{
builder.AddRuntimeAsset(new LibraryAsset(Path.GetFileName(pdbPath), Path.GetFileName(pdbPath), pdbPath));
@ -266,12 +273,12 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
outputPaths.RuntimeFiles.BasePath,
outputPaths.RuntimeFiles.Assembly);
builder.AddRuntimeAssembly(runtimeAssemblyAsset);
builder.AddRuntimeAssemblyGroup(new LibraryAssetGroup(new[] { runtimeAssemblyAsset }));
builder.WithRuntimeAssets(CollectAssets(outputPaths.RuntimeFiles));
}
else
{
builder.AddRuntimeAssembly(compilationAssemblyAsset);
builder.AddRuntimeAssemblyGroup(new LibraryAssetGroup(new[] { compilationAssemblyAsset }));
builder.WithRuntimeAssets(CollectAssets(outputPaths.CompilationFiles));
}
}
@ -324,7 +331,7 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
var builder = LibraryExportBuilder.Create(library);
if (!string.IsNullOrEmpty(library.Path))
{
builder.WithCompilationAssemblies(new []
builder.WithCompilationAssemblies(new[]
{
new LibraryAsset(library.Identity.Name, null, library.Path)
});

View file

@ -1,32 +0,0 @@
// 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

@ -1,6 +1,7 @@
// 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;
using System.Linq;
@ -90,16 +91,10 @@ namespace Microsoft.Extensions.DependencyModel
var serviceable = (export.Library as PackageDescription)?.Library.IsServiceable ?? false;
var libraryDependencies = new HashSet<Dependency>();
var libraryAssets = runtime ? export.RuntimeAssemblies : export.CompilationAssemblies;
foreach (var libraryDependency in export.Library.Dependencies)
{
// skip build time dependencies
if (!libraryDependency.Type.HasFlag(
LibraryDependencyTypeFlag.MainReference |
LibraryDependencyTypeFlag.MainExport |
LibraryDependencyTypeFlag.RuntimeComponent |
LibraryDependencyTypeFlag.BecomesNupkgDependency))
if (libraryDependency.Type.Equals(LibraryDependencyType.Build))
{
continue;
}
@ -111,16 +106,6 @@ namespace Microsoft.Extensions.DependencyModel
}
}
IEnumerable<string> assemblies;
if (type == LibraryType.ReferenceAssembly)
{
assemblies = ResolveReferenceAssembliesPath(libraryAssets);
}
else
{
assemblies = libraryAssets.Select(libraryAsset => libraryAsset.RelativePath);
}
if (runtime)
{
return new RuntimeLibrary(
@ -128,16 +113,25 @@ namespace Microsoft.Extensions.DependencyModel
export.Library.Identity.Name,
export.Library.Identity.Version.ToString(),
export.Library.Hash,
assemblies.Select(RuntimeAssembly.Create),
export.NativeLibraries.Select(l => l.RelativePath),
export.RuntimeAssemblyGroups.Select(CreateRuntimeAssetGroup).ToArray(),
export.NativeLibraryGroups.Select(CreateRuntimeAssetGroup).ToArray(),
export.ResourceAssemblies.Select(CreateResourceAssembly),
export.RuntimeTargets.Select(CreateRuntimeTarget),
libraryDependencies,
serviceable
);
}
else
{
IEnumerable<string> assemblies;
if (type == LibraryType.ReferenceAssembly)
{
assemblies = ResolveReferenceAssembliesPath(export.CompilationAssemblies);
}
else
{
assemblies = export.CompilationAssemblies.Select(libraryAsset => libraryAsset.RelativePath);
}
return new CompilationLibrary(
type.ToString().ToLowerInvariant(),
export.Library.Identity.Name,
@ -145,11 +139,17 @@ namespace Microsoft.Extensions.DependencyModel
export.Library.Hash,
assemblies,
libraryDependencies,
serviceable
);
serviceable);
}
}
private RuntimeAssetGroup CreateRuntimeAssetGroup(LibraryAssetGroup libraryAssetGroup)
{
return new RuntimeAssetGroup(
libraryAssetGroup.Runtime,
libraryAssetGroup.Assets.Select(a => a.RelativePath));
}
private ResourceAssembly CreateResourceAssembly(LibraryResourceAssembly resourceAssembly)
{
return new ResourceAssembly(
@ -158,15 +158,6 @@ namespace Microsoft.Extensions.DependencyModel
);
}
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 referenceAssembliesPath =

View file

@ -10,5 +10,8 @@ namespace Microsoft.DotNet.ProjectModel
// Reference assemblies location not specified
public static readonly string DOTNET1012 = nameof(DOTNET1012);
// Multiple libraries marked as "platform"
public static readonly string DOTNET1013 = nameof(DOTNET1013);
}
}

View file

@ -5,45 +5,28 @@ using System;
namespace Microsoft.DotNet.ProjectModel.Graph
{
public struct LibraryDependencyType
public struct LibraryDependencyType : IEquatable<LibraryDependencyType>, IEquatable<string>
{
public static LibraryDependencyType Default = LibraryDependencyType.Parse("default");
public static LibraryDependencyType Empty = new LibraryDependencyType();
public static LibraryDependencyType Default = new LibraryDependencyType("default");
public static LibraryDependencyType Build = new LibraryDependencyType("build");
public static LibraryDependencyType Platform = new LibraryDependencyType("platform");
public static LibraryDependencyType Build = LibraryDependencyType.Parse("build");
public string Value { get; }
public LibraryDependencyTypeFlag Flags { get; private set; }
private LibraryDependencyType(LibraryDependencyTypeFlag flags)
private LibraryDependencyType(string value)
{
Flags = flags;
Value = value;
}
public static LibraryDependencyType Parse(string keyword)
{
if (string.Equals(keyword, "default", StringComparison.OrdinalIgnoreCase) ||
string.IsNullOrEmpty(keyword)) // Need the default value of the struct to behave like "default"
{
return new LibraryDependencyType(
LibraryDependencyTypeFlag.MainReference |
LibraryDependencyTypeFlag.MainSource |
LibraryDependencyTypeFlag.MainExport |
LibraryDependencyTypeFlag.RuntimeComponent |
LibraryDependencyTypeFlag.BecomesNupkgDependency);
}
public static LibraryDependencyType Parse(string value) => new LibraryDependencyType(value.ToLowerInvariant());
if (string.Equals(keyword, "build", StringComparison.OrdinalIgnoreCase))
{
return new LibraryDependencyType(
LibraryDependencyTypeFlag.MainSource |
LibraryDependencyTypeFlag.PreprocessComponent);
}
public override int GetHashCode() => Value.GetHashCode();
throw new InvalidOperationException(string.Format("unknown keyword {0}", keyword));
}
public override bool Equals(object obj) => obj is LibraryDependencyType && Equals((LibraryDependencyType)obj);
public bool HasFlag(LibraryDependencyTypeFlag flag)
{
return (Flags & flag) != 0;
}
public bool Equals(string other) => string.Equals(Value, other, StringComparison.Ordinal);
public bool Equals(LibraryDependencyType other) => string.Equals(Value, other.Value, StringComparison.Ordinal);
}
}

View file

@ -1,21 +0,0 @@
// 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;
namespace Microsoft.DotNet.ProjectModel.Graph
{
[Flags]
public enum LibraryDependencyTypeFlag
{
None = 0,
MainReference = 1 << 0,
MainSource = 1 << 1,
MainExport = 1 << 2,
PreprocessReference = 1 << 3,
RuntimeComponent = 1 << 4,
DevComponent = 1 << 5,
PreprocessComponent = 1 << 6,
BecomesNupkgDependency = 1 << 7,
}
}

View file

@ -145,10 +145,5 @@ namespace Microsoft.DotNet.ProjectModel.Graph
return sb.ToString();
}
public bool HasFlag(LibraryDependencyTypeFlag flag)
{
return Type.HasFlag(flag);
}
}
}

View file

@ -41,6 +41,7 @@ namespace Microsoft.DotNet.ProjectModel.Resolution
var dependencies = new Dictionary<string, List<DependencyItem>>();
var topLevel = new List<LibraryItem>();
var platformLibraries = new List<LibraryDescription>();
foreach (var library in GetLibraries())
{
if (!library.Resolved)
@ -67,6 +68,11 @@ namespace Microsoft.DotNet.ProjectModel.Resolution
}
else
{
var isPlatform = library.RequestedRanges.Any(r => r.Type.Equals(LibraryDependencyType.Platform));
if (isPlatform)
{
platformLibraries.Add(library);
}
// Store dependency -> library for later
// J.N -> [(R1, P1), (R2, P2)]
foreach (var dependency in library.Dependencies)
@ -128,6 +134,20 @@ namespace Microsoft.DotNet.ProjectModel.Resolution
}
}
if (platformLibraries.Count > 1)
{
foreach (var platformLibrary in platformLibraries)
{
AddDiagnostics(
messages,
platformLibrary,
"The following dependencies are marked with type 'platform', however only one dependency can have this type: " +
string.Join(", ", platformLibraries.Select(l => l.Identity.Name).ToArray()),
DiagnosticMessageSeverity.Error,
ErrorCodes.DOTNET1013);
}
}
// Version conflicts
foreach (var libraryItem in topLevel)
{
@ -186,10 +206,10 @@ namespace Microsoft.DotNet.ProjectModel.Resolution
return range.Name + " " + VersionUtility.RenderVersion(range.VersionRange);
}
private void AddDiagnostics(List<DiagnosticMessage> messages,
LibraryDescription library,
string message,
DiagnosticMessageSeverity severity,
private void AddDiagnostics(List<DiagnosticMessage> messages,
LibraryDescription library,
string message,
DiagnosticMessageSeverity severity,
string errorCode)
{
// A (in project.json) -> B (unresolved) (not in project.json)

View file

@ -0,0 +1,40 @@
using Microsoft.DotNet.ProjectModel.Compilation;
using System.Linq;
namespace System.Collections.Generic
{
public static class CollectionExtensions
{
public static LibraryAssetGroup GetDefaultGroup(this IEnumerable<LibraryAssetGroup> self) => GetGroup(self, string.Empty);
public static LibraryAssetGroup GetRuntimeGroup(this IEnumerable<LibraryAssetGroup> self, string runtime)
{
if(string.IsNullOrEmpty(runtime))
{
throw new ArgumentNullException(nameof(runtime));
}
return GetGroup(self, runtime);
}
private static LibraryAssetGroup GetGroup(IEnumerable<LibraryAssetGroup> groups, string runtime)
{
return groups.FirstOrDefault(g => g.Runtime == runtime);
}
public static IEnumerable<LibraryAsset> GetDefaultAssets(this IEnumerable<LibraryAssetGroup> self) => GetAssets(self, string.Empty);
public static IEnumerable<LibraryAsset> GetRuntimeAssets(this IEnumerable<LibraryAssetGroup> self, string runtime)
{
if(string.IsNullOrEmpty(runtime))
{
throw new ArgumentNullException(nameof(runtime));
}
return GetAssets(self, runtime);
}
private static IEnumerable<LibraryAsset> GetAssets(IEnumerable<LibraryAssetGroup> self, string runtime)
{
return self
.Where(a => string.Equals(a.Runtime, runtime, StringComparison.Ordinal))
.SelectMany(a => a.Assets);
}
}
}

View file

@ -5,8 +5,8 @@
},
"description": "Types to model a .NET Project",
"dependencies": {
"System.Reflection.Metadata": "1.2.0-rc2-23911",
"NuGet.Packaging": "3.4.0-rtm-0763",
"System.Reflection.Metadata": "1.2.0-rc2-23904",
"NuGet.Packaging": "3.5.0-beta-1034",
"Microsoft.Extensions.FileSystemGlobbing": "1.0.0-rc2-15996",
"Microsoft.Extensions.JsonParser.Sources": {
"type": "build",
@ -37,8 +37,9 @@
"dependencies": {
"NETStandard.Library": "1.5.0-rc2-23911",
"System.Dynamic.Runtime": "4.0.11-rc2-23911",
"System.Threading.Thread": "4.0.0-rc2-23911",
"System.Runtime.Loader": "4.0.0-rc2-23911",
"System.Security.Cryptography.Algorithms": "4.0.0-rc2-23911",
"System.Security.Cryptography.Algorithms": "4.1.0-rc2-23911",
"Microsoft.CSharp": "4.0.1-rc2-23911",
"System.Xml.XDocument": "4.0.11-rc2-23911"
}

View file

@ -0,0 +1,40 @@
using Microsoft.Extensions.DependencyModel;
using System.Linq;
namespace System.Collections.Generic
{
public static class CollectionExtensions
{
public static RuntimeAssetGroup GetDefaultGroup(this IEnumerable<RuntimeAssetGroup> self) => GetGroup(self, string.Empty);
public static RuntimeAssetGroup GetRuntimeGroup(this IEnumerable<RuntimeAssetGroup> self, string runtime)
{
if(string.IsNullOrEmpty(runtime))
{
throw new ArgumentNullException(nameof(runtime));
}
return GetGroup(self, runtime);
}
private static RuntimeAssetGroup GetGroup(IEnumerable<RuntimeAssetGroup> groups, string runtime)
{
return groups.FirstOrDefault(g => g.Runtime == runtime);
}
public static IEnumerable<string> GetDefaultAssets(this IEnumerable<RuntimeAssetGroup> self) => GetAssets(self, string.Empty);
public static IEnumerable<string> GetRuntimeAssets(this IEnumerable<RuntimeAssetGroup> self, string runtime)
{
if(string.IsNullOrEmpty(runtime))
{
throw new ArgumentNullException(nameof(runtime));
}
return GetAssets(self, runtime);
}
private static IEnumerable<string> GetAssets(IEnumerable<RuntimeAssetGroup> groups, string runtime)
{
return groups
.Where(a => string.Equals(a.Runtime, runtime, StringComparison.Ordinal))
.SelectMany(a => a.AssetPaths);
}
}
}

View file

@ -6,6 +6,7 @@ using System.IO;
using System.Reflection;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Extensions.PlatformAbstractions;
namespace Microsoft.Extensions.DependencyModel
{
@ -95,7 +96,7 @@ namespace Microsoft.Extensions.DependencyModel
return DependencyContextLoader.Default.Load(assembly);
}
private class LibraryMergeEqualityComparer<T>: IEqualityComparer<T> where T:Library
private class LibraryMergeEqualityComparer<T> : IEqualityComparer<T> where T : Library
{
public bool Equals(T x, T y)
{

View file

@ -0,0 +1,71 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace Microsoft.Extensions.DependencyModel
{
public static class DependencyContextExtensions
{
private const string NativeImageSufix = ".ni";
public static IEnumerable<string> GetDefaultNativeAssets(this DependencyContext self)
{
return ResolveAssets(self, string.Empty, l => l.NativeLibraryGroups);
}
public static IEnumerable<string> GetRuntimeNativeAssets(this DependencyContext self, string runtimeIdentifier)
{
return ResolveAssets(self, runtimeIdentifier, l => l.NativeLibraryGroups);
}
public static IEnumerable<string> GetDefaultAssemblyNames(this DependencyContext self)
{
return ResolveAssets(self, string.Empty, l => l.RuntimeAssemblyGroups).Select(GetAssemblyName);
}
public static IEnumerable<string> GetRuntimeAssemblyNames(this DependencyContext self, string runtimeIdentifier)
{
return ResolveAssets(self, runtimeIdentifier, l => l.RuntimeAssemblyGroups).Select(GetAssemblyName);
}
private static string GetAssemblyName(string assetPath)
{
var name = Path.GetFileNameWithoutExtension(assetPath);
if (name == null)
{
throw new ArgumentException($"Provided path has empty file name '{assetPath}'", nameof(assetPath));
}
if (name.EndsWith(NativeImageSufix))
{
name = name.Substring(0, name.Length - NativeImageSufix.Length);
}
return name;
}
private static IEnumerable<string> ResolveAssets(DependencyContext context, string runtimeIdentifier, Func<RuntimeLibrary, IEnumerable<RuntimeAssetGroup>> groupSelector)
{
var fallbacks = context.RuntimeGraph.FirstOrDefault(f => f.Runtime == runtimeIdentifier);
var rids = Enumerable.Concat(new[] { runtimeIdentifier }, fallbacks?.Fallbacks ?? Enumerable.Empty<string>());
return context.RuntimeLibraries.SelectMany(l => SelectAssets(rids, groupSelector(l)));
}
private static IEnumerable<string> SelectAssets(IEnumerable<string> rids, IEnumerable<RuntimeAssetGroup> groups)
{
foreach (var rid in rids)
{
var group = groups.FirstOrDefault(g => g.Runtime == rid);
if (group != null)
{
return group.AssetPaths;
}
}
// Return the RID-agnostic group
return groups.GetDefaultAssets();
}
}
}

View file

@ -10,7 +10,7 @@ using Newtonsoft.Json.Linq;
namespace Microsoft.Extensions.DependencyModel
{
public class DependencyContextJsonReader: IDependencyContextReader
public class DependencyContextJsonReader : IDependencyContextReader
{
public DependencyContext Read(Stream stream)
{
@ -38,8 +38,8 @@ namespace Microsoft.Extensions.DependencyModel
var runtimeTargetName = root[DependencyContextStrings.RuntimeTargetPropertyName]?.Value<string>();
var libraryStubs = ReadLibraryStubs((JObject) root[DependencyContextStrings.LibrariesPropertyName]);
var targetsObject = (JObject) root[DependencyContextStrings.TargetsPropertyName];
var libraryStubs = ReadLibraryStubs((JObject)root[DependencyContextStrings.LibrariesPropertyName]);
var targetsObject = (JObject)root[DependencyContextStrings.TargetsPropertyName];
JObject runtimeTarget = null;
JObject compileTarget = null;
@ -51,7 +51,7 @@ namespace Microsoft.Extensions.DependencyModel
if (!string.IsNullOrEmpty(runtimeTargetName))
{
runtimeTarget = (JObject) targetsObject[runtimeTargetName];
runtimeTarget = (JObject)targetsObject[runtimeTargetName];
if (runtimeTarget == null)
{
throw new FormatException($"Target with name {runtimeTargetName} not found");
@ -168,39 +168,56 @@ namespace Microsoft.Extensions.DependencyModel
var name = nameWithVersion.Substring(0, seperatorPosition);
var version = nameWithVersion.Substring(seperatorPosition + 1);
var libraryObject = (JObject) property.Value;
var libraryObject = (JObject)property.Value;
var dependencies = ReadDependencies(libraryObject);
if (runtime)
{
var runtimeTargets = new List<RuntimeTarget>();
var runtimeTargetsObject = (JObject)libraryObject[DependencyContextStrings.RuntimeTargetsPropertyName];
var entries = ReadRuntimeTargetEntries(runtimeTargetsObject).ToArray();
var runtimeAssemblyGroups = new List<RuntimeAssetGroup>();
var nativeLibraryGroups = new List<RuntimeAssetGroup>();
foreach (var ridGroup in entries.GroupBy(e => e.Rid))
{
var runtimeAssets = entries.Where(e => e.Type == DependencyContextStrings.RuntimeAssetType)
.Select(e => RuntimeAssembly.Create(e.Path))
.ToArray();
var nativeAssets = entries.Where(e => e.Type == DependencyContextStrings.NativeAssetType)
var groupRuntimeAssemblies = entries.Where(e => e.Type == DependencyContextStrings.RuntimeAssetType)
.Select(e => e.Path)
.ToArray();
runtimeTargets.Add(new RuntimeTarget(
ridGroup.Key,
runtimeAssets,
nativeAssets
));
if (groupRuntimeAssemblies.Any())
{
runtimeAssemblyGroups.Add(new RuntimeAssetGroup(
ridGroup.Key,
groupRuntimeAssemblies.Where(a => Path.GetFileName(a) != "_._")));
}
var groupNativeLibraries = entries.Where(e => e.Type == DependencyContextStrings.NativeAssetType)
.Select(e => e.Path)
.ToArray();
if (groupNativeLibraries.Any())
{
nativeLibraryGroups.Add(new RuntimeAssetGroup(
ridGroup.Key,
groupNativeLibraries.Where(a => Path.GetFileName(a) != "_._")));
}
}
var assemblies = ReadAssetList(libraryObject, DependencyContextStrings.RuntimeAssembliesKey)
.Select(RuntimeAssembly.Create)
var runtimeAssemblies = ReadAssetList(libraryObject, DependencyContextStrings.RuntimeAssembliesKey)
.ToArray();
if (runtimeAssemblies.Any())
{
runtimeAssemblyGroups.Add(new RuntimeAssetGroup(string.Empty, runtimeAssemblies));
}
var nativeLibraries = ReadAssetList(libraryObject, DependencyContextStrings.NativeLibrariesKey);
var nativeLibraries = ReadAssetList(libraryObject, DependencyContextStrings.NativeLibrariesKey)
.ToArray();
if(nativeLibraries.Any())
{
nativeLibraryGroups.Add(new RuntimeAssetGroup(string.Empty, nativeLibraries));
}
var resourceAssemblies = ReadResourceAssemblies((JObject)libraryObject[DependencyContextStrings.ResourceAssembliesPropertyName]);
@ -209,10 +226,9 @@ namespace Microsoft.Extensions.DependencyModel
name: name,
version: version,
hash: stub.Hash,
assemblies: assemblies,
nativeLibraries: nativeLibraries,
runtimeAssemblyGroups: runtimeAssemblyGroups,
nativeLibraryGroups: nativeLibraryGroups,
resourceAssemblies: resourceAssemblies,
subTargets: runtimeTargets.ToArray(),
dependencies: dependencies,
serviceable: stub.Serviceable);
}
@ -258,11 +274,11 @@ namespace Microsoft.Extensions.DependencyModel
private static string[] ReadAssetList(JObject libraryObject, string name)
{
var assembliesObject = (JObject) libraryObject[name];
var assembliesObject = (JObject)libraryObject[name];
if (assembliesObject == null)
{
return new string[] {};
return new string[] { };
}
return assembliesObject.Properties().Select(property => property.Name).ToArray();
@ -270,15 +286,15 @@ namespace Microsoft.Extensions.DependencyModel
private static Dependency[] ReadDependencies(JObject libraryObject)
{
var dependenciesObject = (JObject) libraryObject[DependencyContextStrings.DependenciesPropertyName];
var dependenciesObject = (JObject)libraryObject[DependencyContextStrings.DependenciesPropertyName];
if (dependenciesObject == null)
{
return new Dependency[]{ };
return new Dependency[] { };
}
return dependenciesObject.Properties()
.Select(property => new Dependency(property.Name, (string) property.Value)).ToArray();
.Select(property => new Dependency(property.Name, (string)property.Value)).ToArray();
}
private Dictionary<string, LibraryStub> ReadLibraryStubs(JObject librariesObject)
@ -288,7 +304,7 @@ namespace Microsoft.Extensions.DependencyModel
{
foreach (var libraryProperty in librariesObject)
{
var value = (JObject) libraryProperty.Value;
var value = (JObject)libraryProperty.Value;
var stub = new LibraryStub
{
Name = libraryProperty.Key,

View file

@ -35,7 +35,7 @@ namespace Microsoft.Extensions.DependencyModel
private JObject Write(DependencyContext context)
{
var contextObject = new JObject(
var contextObject = new JObject(
new JProperty(DependencyContextStrings.RuntimeTargetPropertyName, WriteRuntimeTargetInfo(context)),
new JProperty(DependencyContextStrings.CompilationOptionsPropertName, WriteCompilationOptions(context.CompilationOptions)),
new JProperty(DependencyContextStrings.TargetsPropertyName, WriteTargets(context)),
@ -50,7 +50,7 @@ namespace Microsoft.Extensions.DependencyModel
private string WriteRuntimeTargetInfo(DependencyContext context)
{
return context.IsPortable?
return context.IsPortable ?
context.TargetFramework :
context.TargetFramework + DependencyContextStrings.VersionSeperator + context.Runtime;
}
@ -84,12 +84,12 @@ namespace Microsoft.Extensions.DependencyModel
}
private void AddPropertyIfNotNull<T>(JObject o, string name, T value)
{
{
if (value != null)
{
o.Add(new JProperty(name, value));
}
}
}
private JObject WriteTargets(DependencyContext context)
{
@ -159,14 +159,14 @@ namespace Microsoft.Extensions.DependencyModel
);
}
private void AddRuntimeAssemblies(JObject libraryObject, IEnumerable<RuntimeAssembly> runtimeAssemblies)
private void AddAssets(JObject libraryObject, string key, RuntimeAssetGroup group)
{
if (!runtimeAssemblies.Any())
if (group == null || !group.AssetPaths.Any())
{
return;
}
libraryObject.Add(new JProperty(DependencyContextStrings.RuntimeAssembliesKey,
WriteAssetList(runtimeAssemblies.Select(a => a.Path)))
libraryObject.Add(new JProperty(key,
WriteAssetList(group.AssetPaths))
);
}
@ -203,13 +203,11 @@ namespace Microsoft.Extensions.DependencyModel
{
var libraryObject = new JObject();
AddDependencies(libraryObject, runtimeLibrary.Dependencies);
AddRuntimeAssemblies(libraryObject, runtimeLibrary.Assemblies);
AddResourceAssemblies(libraryObject, runtimeLibrary.ResourceAssemblies);
if (runtimeLibrary.NativeLibraries.Any())
{
libraryObject.Add(DependencyContextStrings.NativeLibrariesKey, WriteAssetList(runtimeLibrary.NativeLibraries));
}
// Add runtime-agnostic assets
AddAssets(libraryObject, DependencyContextStrings.RuntimeAssembliesKey, runtimeLibrary.RuntimeAssemblyGroups.GetDefaultGroup());
AddAssets(libraryObject, DependencyContextStrings.NativeLibrariesKey, runtimeLibrary.NativeLibraryGroups.GetDefaultGroup());
AddResourceAssemblies(libraryObject, runtimeLibrary.ResourceAssemblies);
return libraryObject;
}
@ -232,17 +230,19 @@ namespace Microsoft.Extensions.DependencyModel
var dependencies = new HashSet<Dependency>();
if (runtimeLibrary != null)
{
if (runtimeLibrary.RuntimeTargets.Any())
{
libraryObject.Add(new JProperty(
DependencyContextStrings.RuntimeTargetsPropertyName,
new JObject(runtimeLibrary.RuntimeTargets.SelectMany(WriteRuntimeTarget)))
);
}
AddRuntimeAssemblies(libraryObject, runtimeLibrary.Assemblies);
// Add runtime-agnostic assets
AddAssets(libraryObject, DependencyContextStrings.RuntimeAssembliesKey, runtimeLibrary.RuntimeAssemblyGroups.GetDefaultGroup());
AddAssets(libraryObject, DependencyContextStrings.NativeLibrariesKey, runtimeLibrary.NativeLibraryGroups.GetDefaultGroup());
AddResourceAssemblies(libraryObject, runtimeLibrary.ResourceAssemblies);
libraryObject.Add(DependencyContextStrings.NativeLibrariesKey, WriteAssetList(runtimeLibrary.NativeLibraries));
// Add runtime-specific assets
var runtimeTargets = new JObject();
AddRuntimeSpecificAssetGroups(runtimeTargets, DependencyContextStrings.RuntimeAssetType, runtimeLibrary.RuntimeAssemblyGroups);
AddRuntimeSpecificAssetGroups(runtimeTargets, DependencyContextStrings.NativeAssetType, runtimeLibrary.NativeLibraryGroups);
if (runtimeTargets.Count > 0)
{
libraryObject.Add(DependencyContextStrings.RuntimeTargetsPropertyName, runtimeTargets);
}
dependencies.UnionWith(runtimeLibrary.Dependencies);
}
@ -258,31 +258,39 @@ namespace Microsoft.Extensions.DependencyModel
return libraryObject;
}
private IEnumerable<JProperty> WriteRuntimeTarget(RuntimeTarget target)
private void AddRuntimeSpecificAssetGroups(JObject runtimeTargets, string assetType, IEnumerable<RuntimeAssetGroup> assetGroups)
{
var runtime = WriteRuntimeTargetAssemblies(
target.Assemblies.Select(a => a.Path),
target.Runtime,
DependencyContextStrings.RuntimeAssetType);
var native = WriteRuntimeTargetAssemblies(
target.NativeLibraries,
target.Runtime,
DependencyContextStrings.NativeAssetType);
return runtime.Concat(native);
foreach (var group in assetGroups.Where(g => !string.IsNullOrEmpty(g.Runtime)))
{
if (group.AssetPaths.Any())
{
AddRuntimeSpecificAssets(runtimeTargets, group.AssetPaths, group.Runtime, assetType);
}
else
{
// Add a placeholder item
// We need to generate a pseudo-path because there could be multiple different asset groups with placeholders
// Only the last path segment matters, the rest is basically just a GUID.
var pseudoPathFolder = assetType == DependencyContextStrings.RuntimeAssetType ?
"lib" :
"native";
runtimeTargets[$"runtime/{group.Runtime}/{pseudoPathFolder}/_._"] = new JObject(
new JProperty(DependencyContextStrings.RidPropertyName, group.Runtime),
new JProperty(DependencyContextStrings.AssetTypePropertyName, assetType));
}
}
}
private IEnumerable<JProperty> WriteRuntimeTargetAssemblies(IEnumerable<string> assemblies, string runtime, string assetType)
private void AddRuntimeSpecificAssets(JObject target, IEnumerable<string> assets, string runtime, string assetType)
{
foreach (var assembly in assemblies)
foreach (var asset in assets)
{
yield return new JProperty(NormalizePath(assembly),
target.Add(new JProperty(NormalizePath(asset),
new JObject(
new JProperty(DependencyContextStrings.RidPropertyName, runtime),
new JProperty(DependencyContextStrings.AssetTypePropertyName, assetType)
)
);
));
}
}
@ -297,7 +305,7 @@ namespace Microsoft.Extensions.DependencyModel
context.RuntimeLibraries.Cast<Library>().Concat(context.CompileLibraries)
.GroupBy(library => library.Name + DependencyContextStrings.VersionSeperator + library.Version);
return new JObject(allLibraries.Select(libraries=> new JProperty(libraries.Key, WriteLibrary(libraries.First()))));
return new JObject(allLibraries.Select(libraries => new JProperty(libraries.Key, WriteLibrary(libraries.First()))));
}
private JObject WriteLibrary(Library library)

View file

@ -2,8 +2,6 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
namespace Microsoft.Extensions.DependencyModel

View file

@ -0,0 +1,29 @@
// 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 RuntimeAssetGroup
{
public RuntimeAssetGroup(string runtime, params string[] assetPaths) : this(runtime, (IEnumerable<string>)assetPaths) { }
public RuntimeAssetGroup(string runtime, IEnumerable<string> assetPaths)
{
Runtime = runtime;
AssetPaths = assetPaths.ToArray();
}
/// <summary>
/// The runtime ID associated with this group (may be empty if the group is runtime-agnostic)
/// </summary>
public string Runtime { get; }
/// <summary>
/// Gets a list of assets provided in this runtime group
/// </summary>
public IReadOnlyList<string> AssetPaths { get; }
}
}

View file

@ -12,6 +12,7 @@ namespace Microsoft.Extensions.DependencyModel
public string Runtime { get; set; }
public IReadOnlyList<string> Fallbacks { get; set; }
public RuntimeFallbacks(string runtime, params string[] fallbacks) : this(runtime, (IEnumerable<string>)fallbacks) { }
public RuntimeFallbacks(string runtime, IEnumerable<string> fallbacks)
{
if (string.IsNullOrEmpty(runtime))

View file

@ -14,42 +14,41 @@ namespace Microsoft.Extensions.DependencyModel
string name,
string version,
string hash,
IEnumerable<RuntimeAssembly> assemblies,
IEnumerable<string> nativeLibraries,
IReadOnlyList<RuntimeAssetGroup> runtimeAssemblyGroups,
IReadOnlyList<RuntimeAssetGroup> nativeLibraryGroups,
IEnumerable<ResourceAssembly> resourceAssemblies,
IEnumerable<RuntimeTarget> subTargets,
IEnumerable<Dependency> dependencies,
bool serviceable)
: base(type, name, version, hash, dependencies, serviceable)
{
if (assemblies == null)
if (runtimeAssemblyGroups == null)
{
throw new ArgumentNullException(nameof(assemblies));
throw new ArgumentNullException(nameof(runtimeAssemblyGroups));
}
if (nativeLibraries == null)
if (nativeLibraryGroups == null)
{
throw new ArgumentNullException(nameof(nativeLibraries));
throw new ArgumentNullException(nameof(nativeLibraryGroups));
}
if (resourceAssemblies == null)
{
throw new ArgumentNullException(nameof(resourceAssemblies));
}
if (subTargets == null)
{
throw new ArgumentNullException(nameof(subTargets));
}
Assemblies = assemblies.ToArray();
RuntimeAssemblyGroups = runtimeAssemblyGroups;
ResourceAssemblies = resourceAssemblies.ToArray();
RuntimeTargets = subTargets.ToArray();
NativeLibraries = nativeLibraries.ToArray();
NativeLibraryGroups = nativeLibraryGroups;
Assemblies = new RuntimeAssembly[0];
NativeLibraries = new string[0];
}
// Temporary (legacy) properties: https://github.com/dotnet/cli/issues/1998
public IReadOnlyList<RuntimeAssembly> Assemblies { get; }
public IReadOnlyList<string> NativeLibraries { get; }
public IReadOnlyList<ResourceAssembly> ResourceAssemblies { get; }
public IReadOnlyList<RuntimeAssetGroup> RuntimeAssemblyGroups { get; }
public IReadOnlyList<RuntimeTarget> RuntimeTargets { get; }
public IReadOnlyList<RuntimeAssetGroup> NativeLibraryGroups { get; }
public IReadOnlyList<ResourceAssembly> ResourceAssemblies { get; }
}
}

View file

@ -1,34 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace Microsoft.Extensions.DependencyModel
{
public class RuntimeTarget
{
public RuntimeTarget(string runtime, IEnumerable<RuntimeAssembly> assemblies, IEnumerable<string> nativeLibraries)
{
if (string.IsNullOrEmpty(runtime))
{
throw new ArgumentException(nameof(runtime));
}
if (assemblies == null)
{
throw new ArgumentNullException(nameof(assemblies));
}
if (nativeLibraries == null)
{
throw new ArgumentNullException(nameof(nativeLibraries));
}
Runtime = runtime;
Assemblies = assemblies.ToArray();
NativeLibraries = nativeLibraries.ToArray();
}
public string Runtime { get; }
public IReadOnlyList<RuntimeAssembly> Assemblies { get; }
public IReadOnlyList<string> NativeLibraries { get; }
}
}

View file

@ -27,8 +27,8 @@
"imports": "dnxcore50",
"dependencies": {
"System.IO.FileSystem": "4.0.1-rc2-23911",
"System.Linq": "4.0.1-rc2-23911",
"System.Runtime": "4.0.21-rc2-23911",
"System.Linq": "4.1.0-rc2-23911",
"System.Runtime": "4.1.0-rc2-23911",
"System.Reflection": "4.1.0-rc2-23911",
"System.Dynamic.Runtime": "4.0.11-rc2-23911"
}

View file

@ -440,31 +440,6 @@ namespace Microsoft.DotNet.Tools.Build
var executable = new Executable(runtimeContext, outputPaths, libraryExporter, _args.ConfigValue);
executable.MakeCompilationOutputRunnable();
PatchMscorlibNextToCoreClr(runtimeContext, _args.ConfigValue);
}
// Workaround: CoreCLR packaging doesn't include side by side mscorlib, so copy it at build
// time. See: https://github.com/dotnet/cli/issues/1374
private static void PatchMscorlibNextToCoreClr(ProjectContext context, string config)
{
foreach (var exp in context.CreateExporter(config).GetAllExports())
{
var coreclrLib = exp.NativeLibraries.FirstOrDefault(nLib =>
string.Equals(Constants.LibCoreClrFileName, nLib.Name));
if (string.IsNullOrEmpty(coreclrLib.ResolvedPath))
{
continue;
}
var coreclrDir = Path.GetDirectoryName(coreclrLib.ResolvedPath);
if (File.Exists(Path.Combine(coreclrDir, "mscorlib.dll")) ||
File.Exists(Path.Combine(coreclrDir, "mscorlib.ni.dll")))
{
continue;
}
var mscorlibFile = exp.RuntimeAssemblies.FirstOrDefault(r => r.Name.Equals("mscorlib") || r.Name.Equals("mscorlib.ni")).ResolvedPath;
File.Copy(mscorlibFile, Path.Combine(coreclrDir, Path.GetFileName(mscorlibFile)), overwrite: true);
}
}
private static ISet<ProjectDescription> Sort(Dictionary<string, ProjectDescription> projects)

View file

@ -30,7 +30,7 @@ namespace Microsoft.DotNet.Tools.Compiler
// Runtime assemblies.
// TODO: native assets/resources.
var references = exports
.SelectMany(export => export.RuntimeAssemblies)
.SelectMany(export => export.RuntimeAssemblyGroups.GetDefaultAssets())
.Select(r => r.ResolvedPath)
.ToList();

View file

@ -4,7 +4,7 @@
"emitEntryPoint": true
},
"dependencies": {
"Microsoft.NETCore.App": "1.0.0-rc2-23911"
"Microsoft.NETCore.App": { "type": "platform", "version": "1.0.0-rc2-23911" }
},
"frameworks": {
"netstandard1.5": {

View file

@ -9,7 +9,7 @@
],
"dependencies": {
"Microsoft.FSharp.Core.netcore": "1.0.0-alpha-160316",
"Microsoft.NETCore.App": "1.0.0-rc2-23911"
"Microsoft.NETCore.App": { "type": "platform", "version": "1.0.0-rc2-23911" }
},
"frameworks": {
"netstandard1.5": {

View file

@ -17,7 +17,7 @@ namespace NuGet
{
if (directoryPathInPackage == null)
{
throw new ArgumentNullException("directoryPathInPackage");
throw new ArgumentNullException(nameof(directoryPathInPackage));
}
TargetPath = System.IO.Path.Combine(directoryPathInPackage, Constants.PackageEmptyFileName);

View file

@ -17,7 +17,7 @@ namespace NuGet
{
if (packageId == null)
{
throw new ArgumentNullException("packageId");
throw new ArgumentNullException(nameof(packageId));
}
return _idRegex.IsMatch(packageId);
}

View file

@ -258,7 +258,7 @@ namespace Microsoft.DotNet.Tools.Compiler
foreach (var dependency in project.Dependencies)
{
if (!dependency.HasFlag(LibraryDependencyTypeFlag.BecomesNupkgDependency))
if (dependency.Type.Equals(LibraryDependencyType.Build))
{
continue;
}

View file

@ -152,20 +152,15 @@ namespace Microsoft.DotNet.Tools.Publish
// Use a library exporter to collect publish assets
var exporter = context.CreateExporter(configuration);
var isPortable = string.IsNullOrEmpty(context.RuntimeIdentifier);
foreach (var export in exporter.GetAllExports())
{
Reporter.Verbose.WriteLine($"Publishing {export.Library.Identity.ToString().Green().Bold()} ...");
PublishFiles(export.RuntimeAssemblies, outputPath, nativeSubdirectories: false, preserveRelativePath: false);
PublishFiles(export.NativeLibraries, outputPath, nativeSubdirectories, preserveRelativePath: false);
PublishAssetGroups(export.RuntimeAssemblyGroups, outputPath, nativeSubdirectories: false, includeRuntimeGroups: isPortable);
PublishAssetGroups(export.NativeLibraryGroups, outputPath, nativeSubdirectories, includeRuntimeGroups: isPortable);
export.RuntimeAssets.StructuredCopyTo(outputPath, outputPaths.IntermediateOutputDirectoryPath);
if (string.IsNullOrEmpty(context.RuntimeIdentifier))
{
var assets = export.RuntimeTargets.SelectMany(t => Enumerable.Concat(t.NativeLibraries, t.RuntimeAssemblies));
PublishFiles(assets, outputPath, nativeSubdirectories: false, preserveRelativePath: true);
}
if (options.PreserveCompilationContext.GetValueOrDefault())
{
PublishRefs(export, outputPath);
@ -212,7 +207,7 @@ namespace Microsoft.DotNet.Tools.Publish
}
// Do not copy compilation assembly if it's in runtime assemblies
var runtimeAssemblies = new HashSet<LibraryAsset>(export.RuntimeAssemblies);
var runtimeAssemblies = new HashSet<LibraryAsset>(export.RuntimeAssemblyGroups.GetDefaultAssets());
foreach (var compilationAssembly in export.CompilationAssemblies)
{
if (!runtimeAssemblies.Contains(compilationAssembly))
@ -259,23 +254,26 @@ namespace Microsoft.DotNet.Tools.Publish
}
}
private static void PublishFiles(IEnumerable<LibraryAsset> files, string outputPath, bool nativeSubdirectories, bool preserveRelativePath)
private void PublishAssetGroups(IEnumerable<LibraryAssetGroup> groups, string outputPath, bool nativeSubdirectories, bool includeRuntimeGroups)
{
foreach (var file in files)
foreach (var group in groups.Where(g => includeRuntimeGroups || string.IsNullOrEmpty(g.Runtime)))
{
var destinationDirectory = DetermineFileDestinationDirectory(file, outputPath, nativeSubdirectories);
if (preserveRelativePath)
foreach (var file in group.Assets)
{
destinationDirectory = Path.Combine(destinationDirectory, Path.GetDirectoryName(file.RelativePath));
}
var destinationDirectory = DetermineFileDestinationDirectory(file, outputPath, nativeSubdirectories);
if (!Directory.Exists(destinationDirectory))
{
Directory.CreateDirectory(destinationDirectory);
}
if (!string.IsNullOrEmpty(group.Runtime))
{
destinationDirectory = Path.Combine(destinationDirectory, Path.GetDirectoryName(file.RelativePath));
}
File.Copy(file.ResolvedPath, Path.Combine(destinationDirectory, file.FileName), overwrite: true);
if (!Directory.Exists(destinationDirectory))
{
Directory.CreateDirectory(destinationDirectory);
}
File.Copy(file.ResolvedPath, Path.Combine(destinationDirectory, file.FileName), overwrite: true);
}
}
}

View file

@ -86,9 +86,9 @@ namespace Microsoft.DotNet.Tools.Repl.Csi
foreach (var projectDependency in projectDependencies)
{
var runtimeAssemblies = projectDependency.RuntimeAssemblies;
var runtimeAssemblies = projectDependency.RuntimeAssemblyGroups;
foreach (var runtimeAssembly in runtimeAssemblies)
foreach (var runtimeAssembly in runtimeAssemblies.GetDefaultAssets())
{
var runtimeAssemblyPath = runtimeAssembly.ResolvedPath;
runtimeDependencies.Add(runtimeAssemblyPath);

View file

@ -16,21 +16,26 @@
"commands/dotnet-new/FSharp_Console/project.json.template"
],
"dependencies": {
"NuGet.Commands": {
"version": "3.5.0-beta-1034",
"exclude": "compile"
},
"NuGet.CommandLine.XPlat": "3.5.0-beta-1034",
"Newtonsoft.Json": "7.0.1",
"Microsoft.Net.Compilers.netcore": "1.3.0-beta1-20160225-02",
"Microsoft.FSharp.Compiler.netcore": "1.0.0-alpha-160316",
"Microsoft.FSharp.Compiler.netcore": "1.0.0-alpha-151218",
"Microsoft.Net.CSharp.Interactive.netcore": "1.3.0-beta1-20160225-02",
"Microsoft.CodeAnalysis.CSharp": "1.3.0-beta1-20160225-02",
"Microsoft.DiaSymReader.Native": "1.3.3",
"NuGet.CommandLine.XPlat": "3.4.0-rtm-0763",
"System.CommandLine": "0.1.0-e160119-1",
"System.CommandLine": "0.1.0-e160323-1",
"Microsoft.DotNet.ProjectModel": "1.0.0-*",
"Microsoft.DotNet.Compiler.Common": "1.0.0-*",
"Microsoft.DotNet.Cli.Utils": "1.0.0-*",
"Microsoft.DotNet.ILCompiler.SDK": "1.0.6-prerelease-00003",
"Microsoft.Extensions.Logging": "1.0.0-rc2-16040",
"Microsoft.Extensions.Logging.Console": "1.0.0-rc2-16040",
"Microsoft.Extensions.PlatformAbstractions": "1.0.0-rc2-16537",
"Microsoft.Extensions.PlatformAbstractions": "1.0.0-rc2-20100",
"Microsoft.Extensions.CommandLineUtils.Sources": {
"type": "build",
"version": "1.0.0-rc2-16453"
@ -57,7 +62,7 @@
"System.Threading.ThreadPool": "4.0.10-rc2-23911",
"Microsoft.Win32.Registry": {
"version": "4.0.0-rc2-23911",
"exclude": "Compile"
"exclude": "compile"
},
"System.Net.NameResolution": "4.0.0-rc2-23911"
},
@ -69,5 +74,5 @@
]
}
},
"scripts": {}
"scripts": { }
}

View file

@ -5,11 +5,11 @@
},
"dependencies": {
"NETStandard.Library": "1.5.0-rc2-23911",
"NuGet.Versioning": "3.4.0-rtm-0763",
"NuGet.Packaging": "3.4.0-rtm-0763",
"NuGet.Frameworks": "3.4.0-rtm-0763",
"NuGet.ProjectModel": "3.4.0-rtm-0763",
"NuGet.Versioning": "3.5.0-beta-1034",
"NuGet.Packaging": "3.5.0-beta-1034",
"NuGet.Frameworks": "3.5.0-beta-1034",
"NuGet.ProjectModel": "3.5.0-beta-1034",
"Microsoft.DotNet.ProjectModel": {
"target": "project"
},

View file

@ -39,9 +39,9 @@ namespace Microsoft.DotNet.ProjectModel.Tests
});
var result = ExportSingle(description);
result.NativeLibraries.Should().HaveCount(1);
result.NativeLibraryGroups.Should().HaveCount(1);
var libraryAsset = result.NativeLibraries.First();
var libraryAsset = result.NativeLibraryGroups.GetDefaultAssets().First();
libraryAsset.Name.Should().Be("Native");
libraryAsset.Transform.Should().BeNull();
libraryAsset.RelativePath.Should().Be("lib/Native.so");
@ -83,15 +83,49 @@ namespace Microsoft.DotNet.ProjectModel.Tests
});
var result = ExportSingle(description);
result.RuntimeAssemblies.Should().HaveCount(1);
result.RuntimeAssemblyGroups.Should().HaveCount(1);
var libraryAsset = result.RuntimeAssemblies.First();
var libraryAsset = result.RuntimeAssemblyGroups.GetDefaultAssets().First();
libraryAsset.Name.Should().Be("Native");
libraryAsset.Transform.Should().BeNull();
libraryAsset.RelativePath.Should().Be("ref/Native.dll");
libraryAsset.ResolvedPath.Should().Be(Path.Combine(PackagePath, "ref/Native.dll"));
}
[Fact]
public void ExportsPackageRuntimeTargets()
{
var description = CreateDescription(
new LockFileTargetLibrary()
{
RuntimeTargets = new List<LockFileRuntimeTarget>()
{
new LockFileRuntimeTarget("native/native.dylib", "osx", "native"),
new LockFileRuntimeTarget("lib/Something.OSX.dll", "osx", "runtime")
}
});
var result = ExportSingle(description);
result.RuntimeAssemblyGroups.Should().HaveCount(2);
result.RuntimeAssemblyGroups.First(g => g.Runtime == string.Empty).Assets.Should().HaveCount(0);
result.RuntimeAssemblyGroups.First(g => g.Runtime == "osx").Assets.Should().HaveCount(1);
result.NativeLibraryGroups.Should().HaveCount(2);
result.NativeLibraryGroups.First(g => g.Runtime == string.Empty).Assets.Should().HaveCount(0);
result.NativeLibraryGroups.First(g => g.Runtime == "osx").Assets.Should().HaveCount(1);
var nativeAsset = result.NativeLibraryGroups.GetRuntimeAssets("osx").First();
nativeAsset.Name.Should().Be("native");
nativeAsset.Transform.Should().BeNull();
nativeAsset.RelativePath.Should().Be("native/native.dylib");
nativeAsset.ResolvedPath.Should().Be(Path.Combine(PackagePath, "native/native.dylib"));
var runtimeAsset = result.RuntimeAssemblyGroups.GetRuntimeAssets("osx").First();
runtimeAsset.Name.Should().Be("Something.OSX");
runtimeAsset.Transform.Should().BeNull();
runtimeAsset.RelativePath.Should().Be("lib/Something.OSX.dll");
runtimeAsset.ResolvedPath.Should().Be(Path.Combine(PackagePath, "lib/Something.OSX.dll"));
}
[Fact]
public void ExportsSources()
{
@ -269,54 +303,6 @@ namespace Microsoft.DotNet.ProjectModel.Tests
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()

View file

@ -112,17 +112,19 @@ namespace Microsoft.Extensions.DependencyModel.Tests
{
var context = Build(runtimeExports: new[]
{
Export(PackageDescription("Pack.Age",
servicable: true,
hash: "Hash",
version: new NuGetVersion(1, 2, 3),
dependencies: new[]
{
new LibraryRange("System.Collections",
new VersionRange(new NuGetVersion(2, 1, 2)),
LibraryType.ReferenceAssembly,
LibraryDependencyType.Default)
}),
Export(
PackageDescription(
"Pack.Age",
servicable: true,
hash: "Hash",
version: new NuGetVersion(1, 2, 3),
dependencies: new[]
{
new LibraryRange("System.Collections",
new VersionRange(new NuGetVersion(2, 1, 2)),
LibraryType.ReferenceAssembly,
LibraryDependencyType.Default)
}),
resourceAssemblies: new[]
{
new LibraryResourceAssembly(
@ -130,25 +132,26 @@ namespace Microsoft.Extensions.DependencyModel.Tests
"en-US"
)
},
runtimeAssemblies: new[]
runtimeAssemblyGroups: new[]
{
new LibraryAsset("Dll", "lib/Pack.Age.dll", ""),
new LibraryAssetGroup(
new LibraryAsset("Dll", "lib/Pack.Age.dll", "")),
new LibraryAssetGroup("win8-x64",
new LibraryAsset("Dll", "win8-x64/Pack.Age.dll", ""))
},
runtimeTargets: new []
nativeLibraryGroups: 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",
version: new NuGetVersion(3, 3, 3)),
runtimeAssemblies: new[]
{
new LibraryAsset("Dll", "", "System.Collections.dll"),
})
new LibraryAssetGroup("win8-x64",
new LibraryAsset("Dll", "win8-x64/Pack.Age.native.dll", ""))
}),
Export(
ReferenceAssemblyDescription("System.Collections",
version: new NuGetVersion(3, 3, 3)),
runtimeAssemblyGroups: new[]
{
new LibraryAssetGroup(
new LibraryAsset("Dll", "System.Collections.dll", "System.Collections.dll"))
})
});
context.RuntimeLibraries.Should().HaveCount(2);
@ -159,19 +162,18 @@ namespace Microsoft.Extensions.DependencyModel.Tests
lib.Hash.Should().Be("sha512-Hash");
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");
lib.RuntimeAssemblyGroups.GetDefaultAssets().Should().OnlyContain(l => l == "lib/Pack.Age.dll");
lib.RuntimeAssemblyGroups.GetRuntimeAssets("win8-x64").Should().OnlyContain(l => l == "win8-x64/Pack.Age.dll");
lib.NativeLibraryGroups.GetRuntimeAssets("win8-x64").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");
asm.Version.Should().Be("3.3.3");
asm.Hash.Should().BeEmpty();
asm.Dependencies.Should().BeEmpty();
asm.Assemblies.Should().OnlyContain(l => l.Path == "System.Collections.dll");
asm.RuntimeAssemblyGroups.GetDefaultAssets().Should().OnlyContain(l => l == "System.Collections.dll");
}
[Fact]
@ -292,14 +294,14 @@ namespace Microsoft.Extensions.DependencyModel.Tests
private LibraryExport Export(
LibraryDescription description,
IEnumerable<LibraryAsset> compilationAssemblies = null,
IEnumerable<LibraryAsset> runtimeAssemblies = null,
IEnumerable<LibraryRuntimeTarget> runtimeTargets = null,
IEnumerable<LibraryAssetGroup> runtimeAssemblyGroups = null,
IEnumerable<LibraryAssetGroup> nativeLibraryGroups = null,
IEnumerable<LibraryResourceAssembly> resourceAssemblies = null)
{
return LibraryExportBuilder.Create(description)
.WithCompilationAssemblies(compilationAssemblies)
.WithRuntimeAssemblies(runtimeAssemblies)
.WithRuntimeTargets(runtimeTargets)
.WithRuntimeAssemblyGroups(runtimeAssemblyGroups)
.WithNativeLibraryGroups(nativeLibraryGroups)
.WithResourceAssemblies(resourceAssemblies)
.Build();
}

View file

@ -6,6 +6,7 @@ using System.Text;
using System.Threading.Tasks;
using FluentAssertions;
using Xunit;
using System.Diagnostics;
namespace Microsoft.Extensions.DependencyModel.Tests
{
@ -193,7 +194,7 @@ namespace Microsoft.Extensions.DependencyModel.Tests
context.CompileLibraries.Should().HaveCount(2);
var project = context.RuntimeLibraries.Should().Contain(l => l.Name == "MyApp").Subject;
project.Version.Should().Be("1.0.1");
project.Assemblies.Should().Contain(a => a.Path == "MyApp.dll");
project.RuntimeAssemblyGroups.GetDefaultAssets().Should().Contain("MyApp.dll");
project.Type.Should().Be("project");
@ -202,13 +203,46 @@ namespace Microsoft.Extensions.DependencyModel.Tests
package.Hash.Should().Be("HASH-System.Banana");
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");
target.NativeLibraries.Should().Contain("lib/win7/Banana.dll");
package.RuntimeAssemblyGroups.GetDefaultAssets().Should().Contain("lib/dotnet5.4/System.Banana.dll");
package.RuntimeAssemblyGroups.GetRuntimeAssets("win7-x64").Should().Contain("lib/win7/System.Banana.dll");
package.NativeLibraryGroups.GetRuntimeAssets("win7-x64").Should().Contain("lib/win7/Banana.dll");
}
[Fact]
public void ReadsRuntimeTargetPlaceholdersAsEmptyGroups()
{
var context = Read(
@"{
""runtimeTarget"": "".NETStandardApp,Version=v1.5"",
""targets"": {
"".NETStandardApp,Version=v1.5"": {
""System.Banana/1.0.0"": {
""runtimeTargets"": {
""runtime/win7-x64/lib/_._"": { ""assetType"": ""runtime"", ""rid"": ""win7-x64""},
""runtime/linux-x64/native/_._"": { ""assetType"": ""native"", ""rid"": ""linux-x64""},
},
}
}
},
""libraries"":{
""System.Banana/1.0.0"": {
""type"": ""package"",
""serviceable"": false,
""sha512"": ""HASH-System.Banana""
},
}
}");
context.CompileLibraries.Should().HaveCount(1);
var package = context.RuntimeLibraries.Should().Contain(l => l.Name == "System.Banana").Subject;
package.RuntimeAssemblyGroups.Should().Contain(g => g.Runtime == "win7-x64")
.Which.AssetPaths.Should().BeEmpty();
package.NativeLibraryGroups.Should().Contain(g => g.Runtime == "linux-x64")
.Which.AssetPaths.Should().BeEmpty();
}
[Fact]

View file

@ -150,16 +150,15 @@ namespace Microsoft.Extensions.DependencyModel.Tests
"PackageName",
"1.2.3",
"HASH",
new [] { RuntimeAssembly.Create("Banana.dll")},
new [] { "runtimes\\linux\\native\\native.so" },
new [] { new ResourceAssembly("en-US\\Banana.Resource.dll", "en-US")},
new []
{
new RuntimeTarget("win7-x64",
new [] { RuntimeAssembly.Create("Banana.Win7-x64.dll") },
new [] { "native\\Banana.Win7-x64.so" }
)
new [] {
new RuntimeAssetGroup(string.Empty, "Banana.dll"),
new RuntimeAssetGroup("win7-x64", "Banana.Win7-x64.dll")
},
new [] {
new RuntimeAssetGroup(string.Empty, "runtimes\\linux\\native\\native.so"),
new RuntimeAssetGroup("win7-x64", "native\\Banana.Win7-x64.so")
},
new [] { new ResourceAssembly("en-US\\Banana.Resource.dll", "en-US")},
new [] {
new Dependency("Fruits.Abstract.dll","2.0.0")
},
@ -229,16 +228,15 @@ namespace Microsoft.Extensions.DependencyModel.Tests
"PackageName",
"1.2.3",
"HASH",
new [] { RuntimeAssembly.Create("Banana.dll")},
new [] { "native.dll" },
new ResourceAssembly[] {},
new []
{
new RuntimeTarget("win7-x64",
new [] { RuntimeAssembly.Create("Banana.Win7-x64.dll") },
new [] { "Banana.Win7-x64.so" }
)
new [] {
new RuntimeAssetGroup(string.Empty, "Banana.dll"),
new RuntimeAssetGroup("win7-x64", "Banana.Win7-x64.dll")
},
new [] {
new RuntimeAssetGroup(string.Empty, "native.dll"),
new RuntimeAssetGroup("win7-x64", "Banana.Win7-x64.so")
},
new ResourceAssembly[] {},
new [] {
new Dependency("Fruits.Abstract.dll","2.0.0")
},
@ -293,10 +291,13 @@ namespace Microsoft.Extensions.DependencyModel.Tests
"PackageName",
"1.2.3",
"HASH",
new [] { RuntimeAssembly.Create("Banana.dll")},
new [] { "runtimes\\osx\\native\\native.dylib" },
new [] {
new RuntimeAssetGroup(string.Empty, "Banana.dll")
},
new [] {
new RuntimeAssetGroup(string.Empty, "runtimes\\osx\\native\\native.dylib")
},
new ResourceAssembly[] {},
new RuntimeTarget[] {},
new [] {
new Dependency("Fruits.Abstract.dll","2.0.0")
},
@ -323,6 +324,58 @@ namespace Microsoft.Extensions.DependencyModel.Tests
library.Should().HavePropertyValue("serviceable", true);
}
[Fact]
public void WritesPlaceholderRuntimeTargetsForEmptyGroups()
{
var result = Save(Create(
"Target",
"runtime",
true,
runtimeLibraries: new[]
{
new RuntimeLibrary(
"package",
"PackageName",
"1.2.3",
"HASH",
new [] {
new RuntimeAssetGroup("win7-x64"),
new RuntimeAssetGroup("win7-x86", "lib\\x86Support.dll")
},
new [] {
new RuntimeAssetGroup("linux-x64"),
new RuntimeAssetGroup("osx", "native\\OSXSupport.dylib")
},
new ResourceAssembly[] { },
new Dependency[] { },
true
),
}));
// targets
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 runtimeTargets = library.Should().HavePropertyAsObject("runtimeTargets").Subject;
var winPlaceholder = runtimeTargets.Should().HavePropertyAsObject("runtime/win7-x64/lib/_._").Subject;
winPlaceholder.Should().HavePropertyValue("rid", "win7-x64");
winPlaceholder.Should().HavePropertyValue("assetType", "runtime");
var winRuntime = runtimeTargets.Should().HavePropertyAsObject("lib/x86Support.dll").Subject;
winPlaceholder.Should().HavePropertyValue("rid", "win7-x64");
winPlaceholder.Should().HavePropertyValue("assetType", "runtime");
var linuxPlaceholder = runtimeTargets.Should().HavePropertyAsObject("runtime/linux-x64/native/_._").Subject;
linuxPlaceholder.Should().HavePropertyValue("rid", "linux-x64");
linuxPlaceholder.Should().HavePropertyValue("assetType", "native");
var osxNative = runtimeTargets.Should().HavePropertyAsObject("native/OSXSupport.dylib").Subject;
osxNative.Should().HavePropertyValue("rid", "osx");
osxNative.Should().HavePropertyValue("assetType", "native");
}
[Fact]
public void WritesResourceAssembliesForNonPortable()
{
@ -337,13 +390,12 @@ namespace Microsoft.Extensions.DependencyModel.Tests
"PackageName",
"1.2.3",
"HASH",
new RuntimeAssembly[] { },
new string[] { },
new RuntimeAssetGroup[] { },
new RuntimeAssetGroup[] { },
new []
{
new ResourceAssembly("en-US/Fruits.resources.dll", "en-US")
},
new RuntimeTarget[] { },
new Dependency[] { },
true
),
@ -372,13 +424,12 @@ namespace Microsoft.Extensions.DependencyModel.Tests
"PackageName",
"1.2.3",
"HASH",
new RuntimeAssembly[] { },
new string[] { },
new RuntimeAssetGroup[] { },
new RuntimeAssetGroup[] { },
new []
{
new ResourceAssembly("en-US/Fruits.resources.dll", "en-US")
},
new RuntimeTarget[] { },
new Dependency[] { },
true
),
@ -397,7 +448,7 @@ namespace Microsoft.Extensions.DependencyModel.Tests
public void WritesCompilationOptions()
{
var result = Save(Create(compilationOptions: new CompilationOptions(
defines: new[] {"MY", "DEFINES"},
defines: new[] { "MY", "DEFINES" },
languageVersion: "C#8",
platform: "Platform",
allowUnsafe: true,
@ -422,7 +473,7 @@ namespace Microsoft.Extensions.DependencyModel.Tests
options.Should().HavePropertyValue("languageVersion", "C#8");
options.Should().HavePropertyValue("keyFile", "Key.snk");
options.Should().HaveProperty("defines")
.Subject.Values<string>().Should().BeEquivalentTo(new [] {"MY", "DEFINES" });
.Subject.Values<string>().Should().BeEquivalentTo(new[] { "MY", "DEFINES" });
}
}
}

View file

@ -9,7 +9,7 @@ using Xunit;
namespace Microsoft.Extensions.DependencyModel.Tests
{
public class DependencyContextTests
public class DependencyContextLoaderTests
{
[Fact]
public void MergeMergesLibraries()
@ -125,10 +125,9 @@ namespace Microsoft.Extensions.DependencyModel.Tests
name,
"1.1.1",
"HASH",
new RuntimeAssembly[] { },
new string[] { },
new RuntimeAssetGroup[] { },
new RuntimeAssetGroup[] { },
new ResourceAssembly[] { },
new RuntimeTarget[] { },
new Dependency[] {},
false);
}

View file

@ -0,0 +1,140 @@
using FluentAssertions;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Xunit;
namespace Microsoft.Extensions.DependencyModel.Tests
{
public class DependencyContextTests
{
[Theory]
[InlineData("System.Banana.dll", "System.Banana")]
[InlineData("System.Banana.ni.dll", "System.Banana")]
[InlineData("FlibbidyFlob", "FlibbidyFlob")]
public void GetRuntimeAssemblyNamesExtractsCorrectAssemblyName(string path, string expected)
{
var context = new DependencyContext(
".NETStandard,Version=v1.3",
string.Empty,
isPortable: true,
compilationOptions: CompilationOptions.Default,
compileLibraries: new CompilationLibrary[] { },
runtimeLibraries: new[] {
new RuntimeLibrary("package", "System.Banana", "1.0.0", "hash",
new [] {
new RuntimeAssetGroup(string.Empty, Path.Combine("lib", path))
},
new RuntimeAssetGroup[] { },
new ResourceAssembly[] { },
new Dependency[] { },
serviceable: false)
},
runtimeGraph: new RuntimeFallbacks[] { });
var assets = context.GetDefaultAssemblyNames();
assets.Should().BeEquivalentTo(expected);
}
[Fact]
public void GetRuntimeAssemblyNamesReturnsRIDLessAssetsIfNoRIDSpecificAssetsInLibrary()
{
var context = BuildTestContext();
var assets = context.GetRuntimeAssemblyNames("win7-x64");
assets.Should().BeEquivalentTo("System.Banana");
}
[Fact]
public void GetRuntimeAssemblyNamesReturnsMostSpecificAssetIfRIDSpecificAssetInLibrary()
{
var context = BuildTestContext();
var assets = context.GetRuntimeAssemblyNames("win81-x64");
assets.Should().BeEquivalentTo("System.Banana");
}
[Fact]
public void GetRuntimeAssemblyNamesReturnsEmptyIfEmptyRuntimeGroupPresent()
{
var context = BuildTestContext();
var assets = context.GetRuntimeAssemblyNames("win10-x64");
assets.Should().BeEmpty();
}
[Fact]
public void GetRuntimeNativeAssetsReturnsEmptyIfNoGroupsMatch()
{
var context = BuildTestContext();
var assets = context.GetRuntimeNativeAssets("win7-x64");
assets.Should().BeEmpty();
}
[Fact]
public void GetRuntimeNativeAssetsReturnsMostSpecificAssetIfRIDSpecificAssetInLibrary()
{
var context = BuildTestContext();
var assets = context.GetRuntimeNativeAssets("linux-x64");
assets.Should().BeEquivalentTo(Path.Combine("runtimes", "linux-x64", "native", "System.Banana.Native.so"));
}
[Fact]
public void GetRuntimeNativeAssetsReturnsEmptyIfEmptyRuntimeGroupPresent()
{
var context = BuildTestContext();
var assets = context.GetRuntimeNativeAssets("rhel-x64");
assets.Should().BeEmpty();
}
private DependencyContext BuildTestContext()
{
return new DependencyContext(
".NETStandard,Version=v1.3",
string.Empty,
isPortable: true,
compilationOptions: CompilationOptions.Default,
compileLibraries: new[]
{
new CompilationLibrary("package", "System.Banana", "1.0.0", "hash",
new [] { Path.Combine("ref", "netstandard1.3", "System.Banana.dll") },
new Dependency[] { },
serviceable: false)
},
runtimeLibraries: new[] {
new RuntimeLibrary("package", "System.Banana", "1.0.0", "hash",
new [] {
new RuntimeAssetGroup(string.Empty, Path.Combine("lib", "netstandard1.3", "System.Banana.dll")),
new RuntimeAssetGroup("win10"),
new RuntimeAssetGroup("win8", Path.Combine("runtimes", "win8", "lib", "netstandard1.3", "System.Banana.dll"))
},
new [] {
new RuntimeAssetGroup("rhel"),
new RuntimeAssetGroup("linux-x64", Path.Combine("runtimes", "linux-x64", "native", "System.Banana.Native.so")),
new RuntimeAssetGroup("osx-x64", Path.Combine("runtimes", "osx-x64", "native", "System.Banana.Native.dylib")),
// Just here to test we don't fall back through it for the other cases. There's
// no such thing as a "unix" native asset since there's no common executable format :)
new RuntimeAssetGroup("unix", Path.Combine("runtimes", "osx-x64", "native", "System.Banana.Native"))
},
new ResourceAssembly[] { },
new Dependency[] { },
serviceable: false)
},
runtimeGraph: new[] {
new RuntimeFallbacks("win10-x64", "win10", "win81-x64", "win81", "win8-x64", "win8", "win7-x64", "win7", "win-x64", "win", "any", "base"),
new RuntimeFallbacks("win81-x64", "win81", "win8-x64", "win8", "win7-x64", "win7", "win-x64", "win", "any", "base"),
new RuntimeFallbacks("win8-x64", "win8", "win7-x64", "win7", "win-x64", "win", "any", "base"),
new RuntimeFallbacks("win7-x64", "win7", "win-x64", "win", "any", "base"),
new RuntimeFallbacks("ubuntu-x64", "ubuntu", "linux-x64", "linux", "unix", "any", "base"),
new RuntimeFallbacks("rhel-x64", "rhel", "linux-x64", "linux", "unix", "any", "base"),
new RuntimeFallbacks("osx-x64", "osx", "unix", "any", "base"),
});
}
}
}

View file

@ -36,7 +36,7 @@ namespace Microsoft.Extensions.DependencyModel.Tests
{
var runtime = new Mock<IRuntimeEnvironment>();
runtime.SetupGet(r => r.OperatingSystemPlatform).Returns(Platform.Windows);
var environment = EnvironmentMockBuilder.Create()
.AddVariable("DOTNET_REFERENCE_ASSEMBLIES_PATH", ReferencePath)
.Build();

View file

@ -1,27 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using FluentAssertions;
using Xunit;
namespace Microsoft.Extensions.DependencyModel.Tests
{
public class RuntimeAssemblyTests
{
[Fact]
public void UsesFileNameAsAssemblyNameInCreate()
{
var assembly = RuntimeAssembly.Create("path/to/System.Collections.dll");
assembly.Name.Name.Should().Be("System.Collections");
}
[Fact]
public void TrimsDotNiFromDllNames()
{
var assembly = RuntimeAssembly.Create("path/to/System.Collections.ni.dll");
assembly.Name.Name.Should().Be("System.Collections");
}
}
}

View file

@ -32,7 +32,8 @@ namespace Microsoft.Dotnet.Tools.Test.Tests
}
//ISSUE https://github.com/dotnet/cli/issues/1935
[WindowsOnlyFact]
// This fact technically succeeds on Windows, but it causes a crash dialog to pop, which interrupts the build.
//[WindowsOnlyFact]
public void It_returns_a_failure_when_it_fails_to_run_the_tests()
{
var testCommand = new DotnetTestCommand();

View file

@ -27,7 +27,7 @@ namespace MultiProjectValidator
{
projects = ProjectLoader.Load(rootPath);
}
catch(Exception e)
catch(Exception)
{
Console.WriteLine("Failed to load projects from path: " + rootPath);
return 1;

View file

@ -4,8 +4,8 @@
"emitEntryPoint": true
},
"dependencies": {
"NuGet.RuntimeModel": "3.4.0-rtm-0763",
"NuGet.Versioning": "3.4.0-rtm-0763",
"NuGet.RuntimeModel": "3.5.0-beta-1034",
"NuGet.Versioning": "3.5.0-beta-1034",
"System.CommandLine": "0.1.0-e160119-1",
"System.Runtime.Serialization.Json": "1.0.0-rc2-23911",
"Microsoft.DotNet.ProjectModel": "1.0.0-*",