Merge pull request #4300 from livarcocc/support_for_toolsref
Support for toolsref
This commit is contained in:
commit
7a0dff8a96
25 changed files with 840 additions and 80 deletions
|
@ -21,5 +21,11 @@
|
|||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<DotNetCliToolsReference Include="dotnet-portable">
|
||||
<Version>1.0.0</Version>
|
||||
</DotNetCliToolsReference>
|
||||
</ItemGroup>
|
||||
|
||||
<Import Project="$(MSBuildExtensionsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
|
@ -63,7 +63,28 @@ namespace Microsoft.DotNet.Cli.Utils
|
|||
string outputPath = null,
|
||||
string applicationName = null)
|
||||
{
|
||||
var commandSpec = CommandResolver.TryResolveCommandSpec(commandName,
|
||||
return Create(
|
||||
new DefaultCommandResolverPolicy(),
|
||||
commandName,
|
||||
args,
|
||||
framework,
|
||||
configuration,
|
||||
outputPath,
|
||||
applicationName);
|
||||
}
|
||||
|
||||
public static Command Create(
|
||||
ICommandResolverPolicy commandResolverPolicy,
|
||||
string commandName,
|
||||
IEnumerable<string> args,
|
||||
NuGetFramework framework = null,
|
||||
string configuration = Constants.DefaultConfiguration,
|
||||
string outputPath = null,
|
||||
string applicationName = null)
|
||||
{
|
||||
var commandSpec = CommandResolver.TryResolveCommandSpec(
|
||||
commandResolverPolicy,
|
||||
commandName,
|
||||
args,
|
||||
framework,
|
||||
configuration: configuration,
|
||||
|
|
|
@ -2,8 +2,13 @@ using Microsoft.DotNet.PlatformAbstractions;
|
|||
|
||||
namespace Microsoft.DotNet.Cli.Utils
|
||||
{
|
||||
public class DefaultCommandResolverPolicy
|
||||
public class DefaultCommandResolverPolicy : ICommandResolverPolicy
|
||||
{
|
||||
public CompositeCommandResolver CreateCommandResolver()
|
||||
{
|
||||
return Create();
|
||||
}
|
||||
|
||||
public static CompositeCommandResolver Create()
|
||||
{
|
||||
var environment = new EnvironmentProvider();
|
||||
|
@ -37,7 +42,6 @@ namespace Microsoft.DotNet.Cli.Utils
|
|||
|
||||
compositeCommandResolver.AddCommandResolver(new MuxerCommandResolver());
|
||||
compositeCommandResolver.AddCommandResolver(new RootedCommandResolver());
|
||||
compositeCommandResolver.AddCommandResolver(new ProjectToolsCommandResolver(packagedCommandSpecFactory));
|
||||
compositeCommandResolver.AddCommandResolver(new AppBaseDllCommandResolver());
|
||||
compositeCommandResolver.AddCommandResolver(
|
||||
new AppBaseCommandResolver(environment, platformCommandSpecFactory));
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
namespace Microsoft.DotNet.Cli.Utils
|
||||
{
|
||||
public interface ICommandResolverPolicy
|
||||
{
|
||||
CompositeCommandResolver CreateCommandResolver();
|
||||
}
|
||||
}
|
|
@ -5,7 +5,7 @@ using NuGet.Frameworks;
|
|||
|
||||
namespace Microsoft.DotNet.Cli.Utils
|
||||
{
|
||||
internal static class CommandResolver
|
||||
internal class CommandResolver
|
||||
{
|
||||
public static CommandSpec TryResolveCommandSpec(
|
||||
string commandName,
|
||||
|
@ -14,6 +14,25 @@ namespace Microsoft.DotNet.Cli.Utils
|
|||
string configuration = Constants.DefaultConfiguration,
|
||||
string outputPath = null,
|
||||
string applicationName = null)
|
||||
{
|
||||
return TryResolveCommandSpec(
|
||||
new DefaultCommandResolverPolicy(),
|
||||
commandName,
|
||||
args,
|
||||
framework,
|
||||
configuration,
|
||||
outputPath,
|
||||
applicationName);
|
||||
}
|
||||
|
||||
public static CommandSpec TryResolveCommandSpec(
|
||||
ICommandResolverPolicy commandResolverPolicy,
|
||||
string commandName,
|
||||
IEnumerable<string> args,
|
||||
NuGetFramework framework = null,
|
||||
string configuration = Constants.DefaultConfiguration,
|
||||
string outputPath = null,
|
||||
string applicationName = null)
|
||||
{
|
||||
var commandResolverArgs = new CommandResolverArguments
|
||||
{
|
||||
|
@ -26,7 +45,7 @@ namespace Microsoft.DotNet.Cli.Utils
|
|||
ApplicationName = applicationName
|
||||
};
|
||||
|
||||
var defaultCommandResolver = DefaultCommandResolverPolicy.Create();
|
||||
var defaultCommandResolver = commandResolverPolicy.CreateCommandResolver();
|
||||
|
||||
return defaultCommandResolver.Resolve(commandResolverArgs);
|
||||
}
|
||||
|
|
315
src/dotnet/CommandResolution/DepsJsonBuilder.cs
Normal file
315
src/dotnet/CommandResolution/DepsJsonBuilder.cs
Normal file
|
@ -0,0 +1,315 @@
|
|||
// 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.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using Microsoft.Extensions.DependencyModel;
|
||||
using NuGet.Frameworks;
|
||||
using NuGet.Packaging;
|
||||
using NuGet.Packaging.Core;
|
||||
using NuGet.ProjectModel;
|
||||
|
||||
namespace Microsoft.DotNet.Cli.CommandResolution
|
||||
{
|
||||
internal class DepsJsonBuilder
|
||||
{
|
||||
private readonly VersionFolderPathResolver _versionFolderPathResolver;
|
||||
|
||||
public DepsJsonBuilder()
|
||||
{
|
||||
// This resolver is only used for building file names, so that base path is not required.
|
||||
_versionFolderPathResolver = new VersionFolderPathResolver(path: null);
|
||||
}
|
||||
|
||||
public DependencyContext Build(
|
||||
SingleProjectInfo mainProjectInfo,
|
||||
CompilationOptions compilationOptions,
|
||||
LockFile lockFile,
|
||||
NuGetFramework framework,
|
||||
string runtime)
|
||||
{
|
||||
bool includeCompilationLibraries = compilationOptions != null;
|
||||
|
||||
LockFileTarget lockFileTarget = lockFile.GetTarget(framework, runtime);
|
||||
|
||||
IEnumerable<LockFileTargetLibrary> runtimeExports = lockFileTarget.GetRuntimeLibraries();
|
||||
IEnumerable<LockFileTargetLibrary> compilationExports =
|
||||
includeCompilationLibraries ?
|
||||
lockFileTarget.GetCompileLibraries() :
|
||||
Enumerable.Empty<LockFileTargetLibrary>();
|
||||
|
||||
var dependencyLookup = compilationExports
|
||||
.Concat(runtimeExports)
|
||||
.Distinct()
|
||||
.Select(library => new Dependency(library.Name, library.Version.ToString()))
|
||||
.ToDictionary(dependency => dependency.Name, StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
var libraryLookup = lockFile.Libraries.ToDictionary(l => l.Name, StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
var runtimeSignature = GenerateRuntimeSignature(runtimeExports);
|
||||
|
||||
IEnumerable<RuntimeLibrary> runtimeLibraries =
|
||||
GetLibraries(runtimeExports, libraryLookup, dependencyLookup, runtime: true).Cast<RuntimeLibrary>();
|
||||
|
||||
IEnumerable<CompilationLibrary> compilationLibraries;
|
||||
if (includeCompilationLibraries)
|
||||
{
|
||||
CompilationLibrary projectCompilationLibrary = GetProjectCompilationLibrary(
|
||||
mainProjectInfo,
|
||||
lockFile,
|
||||
lockFileTarget,
|
||||
dependencyLookup);
|
||||
compilationLibraries = new[] { projectCompilationLibrary }
|
||||
.Concat(
|
||||
GetLibraries(compilationExports, libraryLookup, dependencyLookup, runtime: false)
|
||||
.Cast<CompilationLibrary>());
|
||||
}
|
||||
else
|
||||
{
|
||||
compilationLibraries = Enumerable.Empty<CompilationLibrary>();
|
||||
}
|
||||
|
||||
return new DependencyContext(
|
||||
new TargetInfo(framework.DotNetFrameworkName, runtime, runtimeSignature, lockFileTarget.IsPortable()),
|
||||
compilationOptions ?? CompilationOptions.Default,
|
||||
compilationLibraries,
|
||||
runtimeLibraries,
|
||||
new RuntimeFallbacks[] { });
|
||||
}
|
||||
|
||||
private static string GenerateRuntimeSignature(IEnumerable<LockFileTargetLibrary> runtimeExports)
|
||||
{
|
||||
var sha1 = SHA1.Create();
|
||||
var builder = new StringBuilder();
|
||||
var packages = runtimeExports
|
||||
.Where(libraryExport => libraryExport.Type == "package");
|
||||
var separator = "|";
|
||||
foreach (var libraryExport in packages)
|
||||
{
|
||||
builder.Append(libraryExport.Name);
|
||||
builder.Append(separator);
|
||||
builder.Append(libraryExport.Version.ToString());
|
||||
builder.Append(separator);
|
||||
}
|
||||
var hash = sha1.ComputeHash(Encoding.UTF8.GetBytes(builder.ToString()));
|
||||
|
||||
builder.Clear();
|
||||
foreach (var hashByte in hash)
|
||||
{
|
||||
builder.AppendFormat("{0:x2}", hashByte);
|
||||
}
|
||||
return builder.ToString();
|
||||
}
|
||||
|
||||
private List<Dependency> GetProjectDependencies(
|
||||
LockFile lockFile,
|
||||
LockFileTarget lockFileTarget,
|
||||
Dictionary<string, Dependency> dependencyLookup)
|
||||
{
|
||||
|
||||
List<Dependency> dependencies = new List<Dependency>();
|
||||
|
||||
IEnumerable<ProjectFileDependencyGroup> projectFileDependencies = lockFile
|
||||
.ProjectFileDependencyGroups
|
||||
.Where(dg => dg.FrameworkName == string.Empty ||
|
||||
dg.FrameworkName == lockFileTarget.TargetFramework.DotNetFrameworkName);
|
||||
|
||||
foreach (string projectFileDependency in projectFileDependencies.SelectMany(dg => dg.Dependencies))
|
||||
{
|
||||
int separatorIndex = projectFileDependency.IndexOf(' ');
|
||||
string dependencyName = separatorIndex > 0 ?
|
||||
projectFileDependency.Substring(0, separatorIndex) :
|
||||
projectFileDependency;
|
||||
|
||||
Dependency dependency;
|
||||
if (dependencyLookup.TryGetValue(dependencyName, out dependency))
|
||||
{
|
||||
dependencies.Add(dependency);
|
||||
}
|
||||
}
|
||||
|
||||
return dependencies;
|
||||
}
|
||||
|
||||
private RuntimeLibrary GetProjectRuntimeLibrary(
|
||||
SingleProjectInfo projectInfo,
|
||||
LockFile lockFile,
|
||||
LockFileTarget lockFileTarget,
|
||||
Dictionary<string, Dependency> dependencyLookup)
|
||||
{
|
||||
|
||||
RuntimeAssetGroup[] runtimeAssemblyGroups = new[] { new RuntimeAssetGroup(string.Empty, projectInfo.GetOutputName()) };
|
||||
|
||||
List<Dependency> dependencies = GetProjectDependencies(lockFile, lockFileTarget, dependencyLookup);
|
||||
|
||||
ResourceAssembly[] resourceAssemblies = projectInfo
|
||||
.ResourceAssemblies
|
||||
.Select(r => new ResourceAssembly(r.RelativePath, r.Culture))
|
||||
.ToArray();
|
||||
|
||||
return new RuntimeLibrary(
|
||||
type: "project",
|
||||
name: projectInfo.Name,
|
||||
version: projectInfo.Version,
|
||||
hash: string.Empty,
|
||||
runtimeAssemblyGroups: runtimeAssemblyGroups,
|
||||
nativeLibraryGroups: new RuntimeAssetGroup[] { },
|
||||
resourceAssemblies: resourceAssemblies,
|
||||
dependencies: dependencies.ToArray(),
|
||||
serviceable: false);
|
||||
}
|
||||
|
||||
private CompilationLibrary GetProjectCompilationLibrary(
|
||||
SingleProjectInfo projectInfo,
|
||||
LockFile lockFile,
|
||||
LockFileTarget lockFileTarget,
|
||||
Dictionary<string, Dependency> dependencyLookup)
|
||||
{
|
||||
List<Dependency> dependencies = GetProjectDependencies(lockFile, lockFileTarget, dependencyLookup);
|
||||
|
||||
return new CompilationLibrary(
|
||||
type: "project",
|
||||
name: projectInfo.Name,
|
||||
version: projectInfo.Version,
|
||||
hash: string.Empty,
|
||||
assemblies: new[] { projectInfo.GetOutputName() },
|
||||
dependencies: dependencies.ToArray(),
|
||||
serviceable: false);
|
||||
}
|
||||
|
||||
private IEnumerable<Library> GetLibraries(
|
||||
IEnumerable<LockFileTargetLibrary> exports,
|
||||
IDictionary<string, LockFileLibrary> libraryLookup,
|
||||
IDictionary<string, Dependency> dependencyLookup,
|
||||
bool runtime)
|
||||
{
|
||||
return exports.Select(export => GetLibrary(export, libraryLookup, dependencyLookup, runtime));
|
||||
}
|
||||
|
||||
private Library GetLibrary(
|
||||
LockFileTargetLibrary export,
|
||||
IDictionary<string, LockFileLibrary> libraryLookup,
|
||||
IDictionary<string, Dependency> dependencyLookup,
|
||||
bool runtime)
|
||||
{
|
||||
var type = export.Type;
|
||||
|
||||
// TEMPORARY: All packages are serviceable in RC2
|
||||
// See https://github.com/dotnet/cli/issues/2569
|
||||
var serviceable = export.Type == "package";
|
||||
var libraryDependencies = new HashSet<Dependency>();
|
||||
|
||||
foreach (PackageDependency libraryDependency in export.Dependencies)
|
||||
{
|
||||
Dependency dependency;
|
||||
if (dependencyLookup.TryGetValue(libraryDependency.Id, out dependency))
|
||||
{
|
||||
libraryDependencies.Add(dependency);
|
||||
}
|
||||
}
|
||||
|
||||
string hash = string.Empty;
|
||||
string path = null;
|
||||
string hashPath = null;
|
||||
LockFileLibrary library;
|
||||
if (libraryLookup.TryGetValue(export.Name, out library))
|
||||
{
|
||||
if (!string.IsNullOrEmpty(library.Sha512))
|
||||
{
|
||||
hash = "sha512-" + library.Sha512;
|
||||
hashPath = _versionFolderPathResolver.GetHashFileName(export.Name, export.Version);
|
||||
}
|
||||
|
||||
path = library.Path;
|
||||
}
|
||||
|
||||
if (runtime)
|
||||
{
|
||||
return new RuntimeLibrary(
|
||||
type.ToLowerInvariant(),
|
||||
export.Name,
|
||||
export.Version.ToString(),
|
||||
hash,
|
||||
CreateRuntimeAssemblyGroups(export),
|
||||
CreateNativeLibraryGroups(export),
|
||||
export.ResourceAssemblies.FilterPlaceHolderFiles().Select(CreateResourceAssembly),
|
||||
libraryDependencies,
|
||||
serviceable,
|
||||
path,
|
||||
hashPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
IEnumerable<string> assemblies = export
|
||||
.CompileTimeAssemblies
|
||||
.FilterPlaceHolderFiles()
|
||||
.Select(libraryAsset => libraryAsset.Path);
|
||||
|
||||
return new CompilationLibrary(
|
||||
type.ToString().ToLowerInvariant(),
|
||||
export.Name,
|
||||
export.Version.ToString(),
|
||||
hash,
|
||||
assemblies,
|
||||
libraryDependencies,
|
||||
serviceable,
|
||||
path,
|
||||
hashPath);
|
||||
}
|
||||
}
|
||||
|
||||
private IReadOnlyList<RuntimeAssetGroup> CreateRuntimeAssemblyGroups(LockFileTargetLibrary export)
|
||||
{
|
||||
List<RuntimeAssetGroup> assemblyGroups = new List<RuntimeAssetGroup>();
|
||||
|
||||
assemblyGroups.Add(
|
||||
new RuntimeAssetGroup(
|
||||
string.Empty,
|
||||
export.RuntimeAssemblies.FilterPlaceHolderFiles().Select(a => a.Path)));
|
||||
|
||||
foreach (var runtimeTargetsGroup in export.GetRuntimeTargetsGroups("runtime"))
|
||||
{
|
||||
assemblyGroups.Add(
|
||||
new RuntimeAssetGroup(
|
||||
runtimeTargetsGroup.Key,
|
||||
runtimeTargetsGroup.Select(t => t.Path)));
|
||||
}
|
||||
|
||||
return assemblyGroups;
|
||||
}
|
||||
|
||||
private IReadOnlyList<RuntimeAssetGroup> CreateNativeLibraryGroups(LockFileTargetLibrary export)
|
||||
{
|
||||
List<RuntimeAssetGroup> nativeGroups = new List<RuntimeAssetGroup>();
|
||||
|
||||
nativeGroups.Add(
|
||||
new RuntimeAssetGroup(
|
||||
string.Empty,
|
||||
export.NativeLibraries.FilterPlaceHolderFiles().Select(a => a.Path)));
|
||||
|
||||
foreach (var runtimeTargetsGroup in export.GetRuntimeTargetsGroups("native"))
|
||||
{
|
||||
nativeGroups.Add(
|
||||
new RuntimeAssetGroup(
|
||||
runtimeTargetsGroup.Key,
|
||||
runtimeTargetsGroup.Select(t => t.Path)));
|
||||
}
|
||||
|
||||
return nativeGroups;
|
||||
}
|
||||
|
||||
private ResourceAssembly CreateResourceAssembly(LockFileItem resourceAssembly)
|
||||
{
|
||||
string locale;
|
||||
if (!resourceAssembly.Properties.TryGetValue("locale", out locale))
|
||||
{
|
||||
locale = null;
|
||||
}
|
||||
|
||||
return new ResourceAssembly(resourceAssembly.Path, locale);
|
||||
}
|
||||
}
|
||||
}
|
15
src/dotnet/CommandResolution/IProject.cs
Normal file
15
src/dotnet/CommandResolution/IProject.cs
Normal file
|
@ -0,0 +1,15 @@
|
|||
// 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.Collections.Generic;
|
||||
using NuGet.ProjectModel;
|
||||
|
||||
namespace Microsoft.DotNet.Cli.CommandResolution
|
||||
{
|
||||
internal interface IProject
|
||||
{
|
||||
LockFile GetLockFile();
|
||||
|
||||
IEnumerable<SingleProjectInfo> GetTools();
|
||||
}
|
||||
}
|
101
src/dotnet/CommandResolution/LockFileTargetExtensions.cs
Normal file
101
src/dotnet/CommandResolution/LockFileTargetExtensions.cs
Normal file
|
@ -0,0 +1,101 @@
|
|||
// 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.Linq;
|
||||
using NuGet.Packaging.Core;
|
||||
using NuGet.ProjectModel;
|
||||
|
||||
namespace Microsoft.DotNet.Cli.CommandResolution
|
||||
{
|
||||
internal static class LockFileTargetExtensions
|
||||
{
|
||||
public static bool IsPortable(this LockFileTarget lockFileTarget)
|
||||
{
|
||||
return string.IsNullOrEmpty(lockFileTarget.RuntimeIdentifier) &&
|
||||
lockFileTarget.GetPlatformLibrary() != null;
|
||||
}
|
||||
|
||||
public static LockFileTargetLibrary GetPlatformLibrary(this LockFileTarget lockFileTarget)
|
||||
{
|
||||
// TODO: https://github.com/dotnet/sdk/issues/17 get this from the lock file
|
||||
var platformPackageName = "Microsoft.NETCore.App";
|
||||
var platformLibrary = lockFileTarget
|
||||
.Libraries
|
||||
.FirstOrDefault(e => e.Name.Equals(platformPackageName, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
return platformLibrary;
|
||||
}
|
||||
|
||||
public static HashSet<string> GetPlatformExclusionList(
|
||||
this LockFileTarget lockFileTarget,
|
||||
IDictionary<string, LockFileTargetLibrary> libraryLookup)
|
||||
{
|
||||
var platformLibrary = lockFileTarget.GetPlatformLibrary();
|
||||
var exclusionList = new HashSet<string>();
|
||||
|
||||
exclusionList.Add(platformLibrary.Name);
|
||||
CollectDependencies(libraryLookup, platformLibrary.Dependencies, exclusionList);
|
||||
|
||||
return exclusionList;
|
||||
}
|
||||
|
||||
public static IEnumerable<LockFileTargetLibrary> GetRuntimeLibraries(this LockFileTarget lockFileTarget)
|
||||
{
|
||||
IEnumerable<LockFileTargetLibrary> runtimeLibraries = lockFileTarget.Libraries;
|
||||
Dictionary<string, LockFileTargetLibrary> libraryLookup =
|
||||
runtimeLibraries.ToDictionary(e => e.Name, StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
HashSet<string> allExclusionList = new HashSet<string>();
|
||||
|
||||
if (lockFileTarget.IsPortable())
|
||||
{
|
||||
allExclusionList.UnionWith(lockFileTarget.GetPlatformExclusionList(libraryLookup));
|
||||
}
|
||||
|
||||
return runtimeLibraries.Filter(allExclusionList).ToArray();
|
||||
}
|
||||
|
||||
public static IEnumerable<LockFileTargetLibrary> GetCompileLibraries(this LockFileTarget lockFileTarget)
|
||||
{
|
||||
return lockFileTarget.Libraries;
|
||||
}
|
||||
|
||||
public static IEnumerable<LockFileTargetLibrary> Filter(
|
||||
this IEnumerable<LockFileTargetLibrary> libraries,
|
||||
HashSet<string> exclusionList)
|
||||
{
|
||||
return libraries.Where(e => !exclusionList.Contains(e.Name));
|
||||
}
|
||||
|
||||
public static IEnumerable<IGrouping<string, LockFileRuntimeTarget>> GetRuntimeTargetsGroups(
|
||||
this LockFileTargetLibrary library,
|
||||
string assetType)
|
||||
{
|
||||
return library.RuntimeTargets
|
||||
.FilterPlaceHolderFiles()
|
||||
.Cast<LockFileRuntimeTarget>()
|
||||
.Where(t => string.Equals(t.AssetType, assetType, StringComparison.OrdinalIgnoreCase))
|
||||
.GroupBy(t => t.Runtime);
|
||||
}
|
||||
|
||||
private static void CollectDependencies(
|
||||
IDictionary<string, LockFileTargetLibrary> libraryLookup,
|
||||
IEnumerable<PackageDependency> dependencies,
|
||||
HashSet<string> exclusionList)
|
||||
{
|
||||
foreach (PackageDependency dependency in dependencies)
|
||||
{
|
||||
LockFileTargetLibrary library = libraryLookup[dependency.Id];
|
||||
if (library.Version.Equals(dependency.VersionRange.MinVersion))
|
||||
{
|
||||
if (exclusionList.Add(library.Name))
|
||||
{
|
||||
CollectDependencies(libraryLookup, library.Dependencies, exclusionList);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
48
src/dotnet/CommandResolution/MSBuildProject.cs
Normal file
48
src/dotnet/CommandResolution/MSBuildProject.cs
Normal file
|
@ -0,0 +1,48 @@
|
|||
// 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;
|
||||
using Microsoft.Build.Evaluation;
|
||||
using NuGet.ProjectModel;
|
||||
|
||||
namespace Microsoft.DotNet.Cli.CommandResolution
|
||||
{
|
||||
internal class MSBuildProject : IProject
|
||||
{
|
||||
private Project _project;
|
||||
|
||||
public MSBuildProject(string msBuildProjectPath)
|
||||
{
|
||||
var globalProperties = new Dictionary<string, string>()
|
||||
{
|
||||
{ "MSBuildExtensionsPath", AppContext.BaseDirectory }
|
||||
};
|
||||
|
||||
_project = new Project(msBuildProjectPath, globalProperties, null);
|
||||
}
|
||||
|
||||
public LockFile GetLockFile()
|
||||
{
|
||||
var intermediateOutputPath = _project
|
||||
.AllEvaluatedProperties
|
||||
.FirstOrDefault(p => p.Name.Equals("BaseIntermediateOutputPath"))
|
||||
.EvaluatedValue;
|
||||
var lockFilePath = Path.Combine(intermediateOutputPath, "project.assets.json");
|
||||
return new LockFileFormat().Read(lockFilePath);
|
||||
}
|
||||
|
||||
public IEnumerable<SingleProjectInfo> GetTools()
|
||||
{
|
||||
var toolsReferences = _project.AllEvaluatedItems.Where(i => i.ItemType.Equals("DotNetCliToolsReference"));
|
||||
var tools = toolsReferences.Select(t => new SingleProjectInfo(
|
||||
t.EvaluatedInclude,
|
||||
t.GetMetadataValue("Version"),
|
||||
Enumerable.Empty<ResourceAssemblyInfo>()));
|
||||
|
||||
return tools;
|
||||
}
|
||||
}
|
||||
}
|
25
src/dotnet/CommandResolution/NuGetUtils.cs
Normal file
25
src/dotnet/CommandResolution/NuGetUtils.cs
Normal file
|
@ -0,0 +1,25 @@
|
|||
// 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;
|
||||
using NuGet.Packaging.Core;
|
||||
using NuGet.ProjectModel;
|
||||
|
||||
namespace Microsoft.DotNet.Cli.CommandResolution
|
||||
{
|
||||
internal static class NuGetUtils
|
||||
{
|
||||
public static bool IsPlaceholderFile(string path)
|
||||
{
|
||||
return string.Equals(Path.GetFileName(path), PackagingCoreConstants.EmptyFolder, StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
public static IEnumerable<LockFileItem> FilterPlaceHolderFiles(this IEnumerable<LockFileItem> files)
|
||||
{
|
||||
return files.Where(f => !IsPlaceholderFile(f.Path));
|
||||
}
|
||||
}
|
||||
}
|
50
src/dotnet/CommandResolution/ProjectFactory.cs
Normal file
50
src/dotnet/CommandResolution/ProjectFactory.cs
Normal file
|
@ -0,0 +1,50 @@
|
|||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Microsoft.DotNet.Cli.CommandResolution
|
||||
{
|
||||
internal class ProjectFactory
|
||||
{
|
||||
public IProject GetProject(string projectDirectory)
|
||||
{
|
||||
return GetMSBuildProj(projectDirectory) ??
|
||||
GetProjectJsonProject(projectDirectory);
|
||||
}
|
||||
|
||||
private IProject GetMSBuildProj(string projectDirectory)
|
||||
{
|
||||
string msBuildProjectPath = GetMSBuildProjPath(projectDirectory);
|
||||
if(msBuildProjectPath == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return new MSBuildProject(msBuildProjectPath);
|
||||
}
|
||||
|
||||
private IProject GetProjectJsonProject(string projectDirectory)
|
||||
{
|
||||
return new ProjectJsonProject(projectDirectory);
|
||||
}
|
||||
|
||||
private string GetMSBuildProjPath(string projectDirectory)
|
||||
{
|
||||
string[] projectFiles = Directory.GetFiles(projectDirectory, "*.*proj");
|
||||
|
||||
if (projectFiles.Length == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else if (projectFiles.Length > 1)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"Specify which project file to use because this '{projectDirectory}' contains more than one project file.");
|
||||
}
|
||||
|
||||
return projectFiles[0];
|
||||
}
|
||||
}
|
||||
}
|
37
src/dotnet/CommandResolution/ProjectJsonProject.cs
Normal file
37
src/dotnet/CommandResolution/ProjectJsonProject.cs
Normal file
|
@ -0,0 +1,37 @@
|
|||
// 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;
|
||||
using NuGet.ProjectModel;
|
||||
|
||||
namespace Microsoft.DotNet.Cli.CommandResolution
|
||||
{
|
||||
internal class ProjectJsonProject : IProject
|
||||
{
|
||||
private LockFile _lockFile;
|
||||
|
||||
public ProjectJsonProject(string projectDirectory)
|
||||
{
|
||||
var lockFilePath = Path.Combine(projectDirectory, LockFileFormat.LockFileName);
|
||||
_lockFile = new LockFileFormat().Read(lockFilePath);
|
||||
}
|
||||
|
||||
public LockFile GetLockFile()
|
||||
{
|
||||
return _lockFile;
|
||||
}
|
||||
|
||||
public IEnumerable<SingleProjectInfo> GetTools()
|
||||
{
|
||||
var tools = _lockFile.Tools.Where(t => t.Name.Contains(".NETCoreApp")).SelectMany(t => t.Libraries);
|
||||
|
||||
return tools.Select(t => new SingleProjectInfo(
|
||||
t.Name,
|
||||
t.Version.ToFullString(),
|
||||
Enumerable.Empty<ResourceAssemblyInfo>()));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,17 +1,21 @@
|
|||
using System;
|
||||
// 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;
|
||||
using Microsoft.DotNet.Cli.Utils;
|
||||
using Microsoft.DotNet.InternalAbstractions;
|
||||
using Microsoft.DotNet.ProjectModel;
|
||||
using Microsoft.DotNet.Tools.Common;
|
||||
using Microsoft.Extensions.DependencyModel;
|
||||
using NuGet.Frameworks;
|
||||
using NuGet.LibraryModel;
|
||||
using NuGet.ProjectModel;
|
||||
using NuGet.Versioning;
|
||||
using FileFormatException = Microsoft.DotNet.ProjectModel.FileFormatException;
|
||||
|
||||
namespace Microsoft.DotNet.Cli.Utils
|
||||
namespace Microsoft.DotNet.Cli.CommandResolution
|
||||
{
|
||||
public class ProjectToolsCommandResolver : ICommandResolver
|
||||
{
|
||||
|
@ -52,31 +56,26 @@ namespace Microsoft.DotNet.Cli.Utils
|
|||
IEnumerable<string> args,
|
||||
string projectDirectory)
|
||||
{
|
||||
var projectContext = GetProjectContextFromDirectoryForFirstTarget(projectDirectory);
|
||||
|
||||
if (projectContext == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var toolsLibraries = projectContext.ProjectFile.Tools.OrEmptyIfNull();
|
||||
var projectFactory = new ProjectFactory();
|
||||
var project = projectFactory.GetProject(projectDirectory);
|
||||
var tools = project.GetTools();
|
||||
|
||||
return ResolveCommandSpecFromAllToolLibraries(
|
||||
toolsLibraries,
|
||||
tools,
|
||||
commandName,
|
||||
args,
|
||||
projectContext);
|
||||
project.GetLockFile());
|
||||
}
|
||||
|
||||
private CommandSpec ResolveCommandSpecFromAllToolLibraries(
|
||||
IEnumerable<LibraryDependency> toolsLibraries,
|
||||
IEnumerable<SingleProjectInfo> toolsLibraries,
|
||||
string commandName,
|
||||
IEnumerable<string> args,
|
||||
ProjectContext projectContext)
|
||||
LockFile lockFile)
|
||||
{
|
||||
foreach (var toolLibrary in toolsLibraries)
|
||||
{
|
||||
var commandSpec = ResolveCommandSpecFromToolLibrary(toolLibrary.LibraryRange, commandName, args, projectContext);
|
||||
var commandSpec = ResolveCommandSpecFromToolLibrary(toolLibrary, commandName, args, lockFile);
|
||||
|
||||
if (commandSpec != null)
|
||||
{
|
||||
|
@ -88,17 +87,18 @@ namespace Microsoft.DotNet.Cli.Utils
|
|||
}
|
||||
|
||||
private CommandSpec ResolveCommandSpecFromToolLibrary(
|
||||
LibraryRange toolLibraryRange,
|
||||
SingleProjectInfo toolLibraryRange,
|
||||
string commandName,
|
||||
IEnumerable<string> args,
|
||||
ProjectContext projectContext)
|
||||
LockFile lockFile)
|
||||
{
|
||||
var nugetPackagesRoot = projectContext.PackagesDirectory;
|
||||
var nugetPackagesRoot = lockFile.PackageFolders.First().Path;
|
||||
|
||||
var lockFile = GetToolLockFile(toolLibraryRange, nugetPackagesRoot);
|
||||
var toolLockFile = GetToolLockFile(toolLibraryRange, nugetPackagesRoot);
|
||||
|
||||
var toolLibrary = lockFile.Targets
|
||||
.FirstOrDefault(t => t.TargetFramework.GetShortFolderName().Equals(s_toolPackageFramework.GetShortFolderName()))
|
||||
var toolLibrary = toolLockFile.Targets
|
||||
.FirstOrDefault(
|
||||
t => t.TargetFramework.GetShortFolderName().Equals(s_toolPackageFramework.GetShortFolderName()))
|
||||
?.Libraries.FirstOrDefault(l => l.Name == toolLibraryRange.Name);
|
||||
|
||||
if (toolLibrary == null)
|
||||
|
@ -106,8 +106,8 @@ namespace Microsoft.DotNet.Cli.Utils
|
|||
return null;
|
||||
}
|
||||
|
||||
var depsFileRoot = Path.GetDirectoryName(lockFile.Path);
|
||||
var depsFilePath = GetToolDepsFilePath(toolLibraryRange, lockFile, depsFileRoot);
|
||||
var depsFileRoot = Path.GetDirectoryName(toolLockFile.Path);
|
||||
var depsFilePath = GetToolDepsFilePath(toolLibraryRange, toolLockFile, depsFileRoot);
|
||||
|
||||
var normalizedNugetPackagesRoot = PathUtility.EnsureNoTrailingDirectorySeparator(nugetPackagesRoot);
|
||||
|
||||
|
@ -123,7 +123,7 @@ namespace Microsoft.DotNet.Cli.Utils
|
|||
}
|
||||
|
||||
private LockFile GetToolLockFile(
|
||||
LibraryRange toolLibrary,
|
||||
SingleProjectInfo toolLibrary,
|
||||
string nugetPackagesRoot)
|
||||
{
|
||||
var lockFilePath = GetToolLockFilePath(toolLibrary, nugetPackagesRoot);
|
||||
|
@ -148,36 +148,19 @@ namespace Microsoft.DotNet.Cli.Utils
|
|||
}
|
||||
|
||||
private string GetToolLockFilePath(
|
||||
LibraryRange toolLibrary,
|
||||
SingleProjectInfo toolLibrary,
|
||||
string nugetPackagesRoot)
|
||||
{
|
||||
var toolPathCalculator = new ToolPathCalculator(nugetPackagesRoot);
|
||||
|
||||
return toolPathCalculator.GetBestLockFilePath(
|
||||
toolLibrary.Name,
|
||||
toolLibrary.VersionRange,
|
||||
new VersionRange(new NuGetVersion(toolLibrary.Version)),
|
||||
s_toolPackageFramework);
|
||||
}
|
||||
|
||||
private ProjectContext GetProjectContextFromDirectoryForFirstTarget(string projectRootPath)
|
||||
{
|
||||
if (projectRootPath == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!File.Exists(Path.Combine(projectRootPath, Project.FileName)))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var projectContext = ProjectContext.CreateContextForEachTarget(projectRootPath).FirstOrDefault();
|
||||
|
||||
return projectContext;
|
||||
}
|
||||
|
||||
private string GetToolDepsFilePath(
|
||||
LibraryRange toolLibrary,
|
||||
SingleProjectInfo toolLibrary,
|
||||
LockFile toolLockFile,
|
||||
string depsPathRoot)
|
||||
{
|
||||
|
@ -185,42 +168,32 @@ namespace Microsoft.DotNet.Cli.Utils
|
|||
depsPathRoot,
|
||||
toolLibrary.Name + FileNameSuffixes.DepsJson);
|
||||
|
||||
EnsureToolJsonDepsFileExists(toolLockFile, depsJsonPath);
|
||||
EnsureToolJsonDepsFileExists(toolLockFile, depsJsonPath, toolLibrary);
|
||||
|
||||
return depsJsonPath;
|
||||
}
|
||||
|
||||
private void EnsureToolJsonDepsFileExists(
|
||||
LockFile toolLockFile,
|
||||
string depsPath)
|
||||
string depsPath,
|
||||
SingleProjectInfo toolLibrary)
|
||||
{
|
||||
if (!File.Exists(depsPath))
|
||||
{
|
||||
GenerateDepsJsonFile(toolLockFile, depsPath);
|
||||
GenerateDepsJsonFile(toolLockFile, depsPath, toolLibrary);
|
||||
}
|
||||
}
|
||||
|
||||
// Need to unit test this, so public
|
||||
public void GenerateDepsJsonFile(
|
||||
internal void GenerateDepsJsonFile(
|
||||
LockFile toolLockFile,
|
||||
string depsPath)
|
||||
string depsPath,
|
||||
SingleProjectInfo toolLibrary)
|
||||
{
|
||||
Reporter.Verbose.WriteLine($"Generating deps.json at: {depsPath}");
|
||||
|
||||
var projectContext = new ProjectContextBuilder()
|
||||
.WithLockFile(toolLockFile)
|
||||
.WithTargetFramework(s_toolPackageFramework.ToString())
|
||||
.Build();
|
||||
|
||||
var exporter = projectContext.CreateExporter(Constants.DefaultConfiguration);
|
||||
|
||||
var dependencyContext = new DependencyContextBuilder()
|
||||
.Build(null,
|
||||
null,
|
||||
exporter.GetAllExports(),
|
||||
true,
|
||||
s_toolPackageFramework,
|
||||
string.Empty);
|
||||
var dependencyContext = new DepsJsonBuilder()
|
||||
.Build(toolLibrary, null, toolLockFile, s_toolPackageFramework, null);
|
||||
|
||||
var tempDepsFile = Path.GetTempFileName();
|
||||
using (var fileStream = File.Open(tempDepsFile, FileMode.Open, FileAccess.Write))
|
|
@ -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.
|
||||
|
||||
using Microsoft.DotNet.Cli.Utils;
|
||||
|
||||
namespace Microsoft.DotNet.Cli.CommandResolution
|
||||
{
|
||||
public class ProjectToolsCommandResolverPolicy : ICommandResolverPolicy
|
||||
{
|
||||
public CompositeCommandResolver CreateCommandResolver()
|
||||
{
|
||||
var defaultCommandResolverPolicy = new DefaultCommandResolverPolicy();
|
||||
var compositeCommandResolver = defaultCommandResolverPolicy.CreateCommandResolver();
|
||||
var packagedCommandSpecFactory = new PackagedCommandSpecFactory();
|
||||
|
||||
compositeCommandResolver.AddCommandResolver(new ProjectToolsCommandResolver(packagedCommandSpecFactory));
|
||||
|
||||
return compositeCommandResolver;
|
||||
}
|
||||
}
|
||||
}
|
17
src/dotnet/CommandResolution/ResourceAssemblyInfo.cs
Normal file
17
src/dotnet/CommandResolution/ResourceAssemblyInfo.cs
Normal file
|
@ -0,0 +1,17 @@
|
|||
// 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.Cli.CommandResolution
|
||||
{
|
||||
internal class ResourceAssemblyInfo
|
||||
{
|
||||
public string Culture { get; }
|
||||
public string RelativePath { get; }
|
||||
|
||||
public ResourceAssemblyInfo(string culture, string relativePath)
|
||||
{
|
||||
Culture = culture;
|
||||
RelativePath = relativePath;
|
||||
}
|
||||
}
|
||||
}
|
27
src/dotnet/CommandResolution/SingleProjectInfo.cs
Normal file
27
src/dotnet/CommandResolution/SingleProjectInfo.cs
Normal file
|
@ -0,0 +1,27 @@
|
|||
// 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.Collections.Generic;
|
||||
|
||||
namespace Microsoft.DotNet.Cli.CommandResolution
|
||||
{
|
||||
internal class SingleProjectInfo
|
||||
{
|
||||
public string Name { get; }
|
||||
public string Version { get; }
|
||||
|
||||
public IEnumerable<ResourceAssemblyInfo> ResourceAssemblies { get; }
|
||||
|
||||
public SingleProjectInfo(string name, string version, IEnumerable<ResourceAssemblyInfo> resourceAssemblies)
|
||||
{
|
||||
Name = name;
|
||||
Version = version;
|
||||
ResourceAssemblies = resourceAssemblies;
|
||||
}
|
||||
|
||||
public string GetOutputName()
|
||||
{
|
||||
return $"{Name}.dll";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,6 +6,7 @@ using System.Collections.Generic;
|
|||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Microsoft.DotNet.Cli.CommandResolution;
|
||||
using Microsoft.DotNet.Cli.Utils;
|
||||
using Microsoft.DotNet.Configurer;
|
||||
using Microsoft.DotNet.PlatformAbstractions;
|
||||
|
@ -188,7 +189,12 @@ namespace Microsoft.DotNet.Cli
|
|||
}
|
||||
else
|
||||
{
|
||||
CommandResult result = Command.Create("dotnet-" + command, appArgs, FrameworkConstants.CommonFrameworks.NetStandardApp15)
|
||||
var projectToolsCommandResolver = new ProjectToolsCommandResolverPolicy();
|
||||
CommandResult result = Command.Create(
|
||||
projectToolsCommandResolver,
|
||||
"dotnet-" + command,
|
||||
appArgs,
|
||||
FrameworkConstants.CommonFrameworks.NetStandardApp15)
|
||||
.Execute();
|
||||
exitCode = result.ExitCode;
|
||||
}
|
||||
|
|
|
@ -43,5 +43,29 @@ namespace Microsoft.DotNet.Tests.EndToEnd
|
|||
.HaveStdOutContaining("Hello World!");
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ItCanRunToolsInACSProj()
|
||||
{
|
||||
var testAppName = "MSBuildTestApp";
|
||||
var testInstance = TestAssetsManager
|
||||
.CreateTestInstance(testAppName);
|
||||
|
||||
var testProjectDirectory = testInstance.TestRoot;
|
||||
|
||||
new Restore3Command()
|
||||
.WithWorkingDirectory(testProjectDirectory)
|
||||
.Execute()
|
||||
.Should()
|
||||
.Pass();
|
||||
|
||||
new DotnetCommand()
|
||||
.WithWorkingDirectory(testInstance.TestRoot)
|
||||
.ExecuteWithCapturedOutput("portable")
|
||||
.Should()
|
||||
.Pass()
|
||||
.And
|
||||
.HaveStdOutContaining("Hello Portable World!");;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ namespace Microsoft.DotNet.Cli.Utils.Tests
|
|||
|
||||
var resolvers = defaultCommandResolver.OrderedCommandResolvers;
|
||||
|
||||
resolvers.Should().HaveCount(7);
|
||||
resolvers.Should().HaveCount(6);
|
||||
|
||||
resolvers.Select(r => r.GetType())
|
||||
.Should()
|
||||
|
@ -25,7 +25,6 @@ namespace Microsoft.DotNet.Cli.Utils.Tests
|
|||
new []{
|
||||
typeof(MuxerCommandResolver),
|
||||
typeof(RootedCommandResolver),
|
||||
typeof(ProjectToolsCommandResolver),
|
||||
typeof(AppBaseDllCommandResolver),
|
||||
typeof(AppBaseCommandResolver),
|
||||
typeof(PathCommandResolver),
|
||||
|
|
|
@ -20,10 +20,10 @@
|
|||
},
|
||||
"System.Diagnostics.TraceSource": "4.0.0",
|
||||
"System.Runtime.Serialization.Primitives": "4.1.1",
|
||||
"NuGet.Versioning": "3.6.0-beta.1.msbuild.15",
|
||||
"NuGet.Packaging": "3.6.0-beta.1.msbuild.15",
|
||||
"NuGet.Frameworks": "3.6.0-beta.1.msbuild.15",
|
||||
"NuGet.ProjectModel": "3.6.0-beta.1.msbuild.15",
|
||||
"NuGet.Versioning": "3.6.0-beta.1.msbuild.17",
|
||||
"NuGet.Packaging": "3.6.0-beta.1.msbuild.17",
|
||||
"NuGet.Frameworks": "3.6.0-beta.1.msbuild.17",
|
||||
"NuGet.ProjectModel": "3.6.0-beta.1.msbuild.17",
|
||||
"Microsoft.DotNet.ProjectModel": {
|
||||
"target": "project"
|
||||
},
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
},
|
||||
"xunit": "2.2.0-beta3-build3330",
|
||||
"dotnet-test-xunit": "1.0.0-rc2-350904-49",
|
||||
"NuGet.ProjectModel": "3.6.0-beta.1.msbuild.15"
|
||||
"NuGet.ProjectModel": "3.6.0-beta.1.msbuild.17"
|
||||
},
|
||||
"frameworks": {
|
||||
"netcoreapp1.0": {
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
using System.IO;
|
||||
using System.Linq;
|
||||
using FluentAssertions;
|
||||
using Microsoft.DotNet.Cli.CommandResolution;
|
||||
using Microsoft.DotNet.Cli.Utils;
|
||||
using Microsoft.DotNet.ProjectModel;
|
||||
using Microsoft.DotNet.TestFramework;
|
||||
using Microsoft.DotNet.Tools.Test.Utilities;
|
||||
|
@ -12,7 +14,7 @@ using NuGet.ProjectModel;
|
|||
using NuGet.Versioning;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.DotNet.Cli.Utils.Tests
|
||||
namespace Microsoft.DotNet.Tests
|
||||
{
|
||||
public class GivenAProjectToolsCommandResolver : TestBase
|
||||
{
|
||||
|
@ -220,7 +222,10 @@ namespace Microsoft.DotNet.Cli.Utils.Tests
|
|||
File.WriteAllText(depsJsonFile, "temp");
|
||||
|
||||
var projectToolsCommandResolver = SetupProjectToolsCommandResolver();
|
||||
projectToolsCommandResolver.GenerateDepsJsonFile(lockFile, depsJsonFile);
|
||||
projectToolsCommandResolver.GenerateDepsJsonFile(
|
||||
lockFile,
|
||||
depsJsonFile,
|
||||
new SingleProjectInfo("dotnet-portable", "1.0.0", Enumerable.Empty<ResourceAssemblyInfo>()));
|
||||
|
||||
File.ReadAllText(depsJsonFile).Should().Be("temp");
|
||||
File.Delete(depsJsonFile);
|
39
test/dotnet.Tests/GivenAProjectToolsCommandResolverPolicy.cs
Normal file
39
test/dotnet.Tests/GivenAProjectToolsCommandResolverPolicy.cs
Normal file
|
@ -0,0 +1,39 @@
|
|||
// 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 FluentAssertions;
|
||||
using Microsoft.DotNet.Cli.CommandResolution;
|
||||
using Microsoft.DotNet.Cli.Utils;
|
||||
using Microsoft.DotNet.Tools.Test.Utilities;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.DotNet.Tests
|
||||
{
|
||||
public class GivenAProjectToolsCommandResolverPolicy
|
||||
{
|
||||
[Fact]
|
||||
public void It_contains_resolvers_in_the_right_order()
|
||||
{
|
||||
var projectToolsCommandResolverPolicy = new ProjectToolsCommandResolverPolicy();
|
||||
var defaultCommandResolver = projectToolsCommandResolverPolicy.CreateCommandResolver();
|
||||
|
||||
var resolvers = defaultCommandResolver.OrderedCommandResolvers;
|
||||
|
||||
resolvers.Should().HaveCount(7);
|
||||
|
||||
resolvers.Select(r => r.GetType())
|
||||
.Should()
|
||||
.ContainInOrder(
|
||||
new []{
|
||||
typeof(MuxerCommandResolver),
|
||||
typeof(RootedCommandResolver),
|
||||
typeof(AppBaseDllCommandResolver),
|
||||
typeof(AppBaseCommandResolver),
|
||||
typeof(PathCommandResolver),
|
||||
typeof(PublishedPathCommandResolver),
|
||||
typeof(ProjectToolsCommandResolver)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -26,6 +26,7 @@ namespace Microsoft.DotNet.Tests
|
|||
.HaveFile("project.lock.json");
|
||||
|
||||
new DotnetCommand()
|
||||
.WithWorkingDirectory(testInstance.TestRoot)
|
||||
.ExecuteWithCapturedOutput("crash")
|
||||
.Should()
|
||||
.Fail()
|
||||
|
|
|
@ -178,7 +178,7 @@ namespace Microsoft.DotNet.Tests
|
|||
[Fact]
|
||||
public void ToolsCanAccessDependencyContextProperly()
|
||||
{
|
||||
var testInstance = TestAssetsManager.CreateTestInstance("DependencyContextFromTool");
|
||||
var testInstance = TestAssetsManager.CreateTestInstance("DependencyContextFromTool").WithLockFiles();
|
||||
|
||||
var appDirectory = testInstance.Path;
|
||||
|
||||
|
|
Loading…
Reference in a new issue