158 lines
5.9 KiB
C#
158 lines
5.9 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using Microsoft.DotNet.InternalAbstractions;
|
|
using Microsoft.DotNet.ProjectModel;
|
|
using Microsoft.DotNet.Tools.Common;
|
|
using NuGet.Frameworks;
|
|
using NuGet.ProjectModel;
|
|
|
|
namespace Microsoft.DotNet.Cli.Utils
|
|
{
|
|
public class ProjectDependenciesCommandResolver : ICommandResolver
|
|
{
|
|
private static readonly CommandResolutionStrategy s_commandResolutionStrategy =
|
|
CommandResolutionStrategy.ProjectDependenciesPackage;
|
|
|
|
private readonly IEnvironmentProvider _environment;
|
|
private readonly IPackagedCommandSpecFactory _packagedCommandSpecFactory;
|
|
|
|
public ProjectDependenciesCommandResolver(
|
|
IEnvironmentProvider environment,
|
|
IPackagedCommandSpecFactory packagedCommandSpecFactory)
|
|
{
|
|
if (environment == null)
|
|
{
|
|
throw new ArgumentNullException(nameof(environment));
|
|
}
|
|
|
|
if (packagedCommandSpecFactory == null)
|
|
{
|
|
throw new ArgumentNullException(nameof(packagedCommandSpecFactory));
|
|
}
|
|
|
|
_environment = environment;
|
|
_packagedCommandSpecFactory = packagedCommandSpecFactory;
|
|
}
|
|
|
|
public CommandSpec Resolve(CommandResolverArguments commandResolverArguments)
|
|
{
|
|
if (commandResolverArguments.Framework == null
|
|
|| commandResolverArguments.ProjectDirectory == null
|
|
|| commandResolverArguments.Configuration == null
|
|
|| commandResolverArguments.CommandName == null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
return ResolveFromProjectDependencies(
|
|
commandResolverArguments.ProjectDirectory,
|
|
commandResolverArguments.Framework,
|
|
commandResolverArguments.Configuration,
|
|
commandResolverArguments.CommandName,
|
|
commandResolverArguments.CommandArguments.OrEmptyIfNull(),
|
|
commandResolverArguments.OutputPath,
|
|
commandResolverArguments.BuildBasePath);
|
|
}
|
|
|
|
private CommandSpec ResolveFromProjectDependencies(
|
|
string projectDirectory,
|
|
NuGetFramework framework,
|
|
string configuration,
|
|
string commandName,
|
|
IEnumerable<string> commandArguments,
|
|
string outputPath,
|
|
string buildBasePath)
|
|
{
|
|
var allowedExtensions = GetAllowedCommandExtensionsFromEnvironment(_environment);
|
|
|
|
var projectContext = GetProjectContextFromDirectory(
|
|
projectDirectory,
|
|
framework);
|
|
|
|
if (projectContext == null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
var depsFilePath =
|
|
projectContext.GetOutputPaths(configuration, buildBasePath, outputPath).RuntimeFiles.DepsJson;
|
|
|
|
if (! File.Exists(depsFilePath))
|
|
{
|
|
Reporter.Verbose.WriteLine($"projectdependenciescommandresolver: {depsFilePath} does not exist");
|
|
return null;
|
|
}
|
|
|
|
var runtimeConfigPath =
|
|
projectContext.GetOutputPaths(configuration, buildBasePath, outputPath).RuntimeFiles.RuntimeConfigJson;
|
|
|
|
if (! File.Exists(runtimeConfigPath))
|
|
{
|
|
Reporter.Verbose.WriteLine($"projectdependenciescommandresolver: {runtimeConfigPath} does not exist");
|
|
return null;
|
|
}
|
|
|
|
var toolLibrary = GetToolLibraryForContext(projectContext, commandName);
|
|
var nugetPackagesRoot = PathUtility.EnsureNoTrailingDirectorySeparator(projectContext.PackagesDirectory);
|
|
|
|
return _packagedCommandSpecFactory.CreateCommandSpecFromLibrary(
|
|
toolLibrary,
|
|
commandName,
|
|
commandArguments,
|
|
allowedExtensions,
|
|
nugetPackagesRoot,
|
|
s_commandResolutionStrategy,
|
|
depsFilePath,
|
|
runtimeConfigPath);
|
|
}
|
|
|
|
private LockFileTargetLibrary GetToolLibraryForContext(
|
|
ProjectContext projectContext, string commandName)
|
|
{
|
|
var toolLibraries = projectContext.LockFile.Targets
|
|
.FirstOrDefault(t => t.TargetFramework.GetShortFolderName()
|
|
.Equals(projectContext.TargetFramework.GetShortFolderName()))
|
|
?.Libraries.Where(l => l.Name == commandName ||
|
|
l.RuntimeAssemblies.Any(r => Path.GetFileNameWithoutExtension(r.Path) == commandName)).ToList();
|
|
|
|
if (toolLibraries?.Count() > 1)
|
|
{
|
|
throw new InvalidOperationException($"Ambiguous command name: {commandName}");
|
|
}
|
|
|
|
return toolLibraries?.FirstOrDefault();
|
|
}
|
|
|
|
private ProjectContext GetProjectContextFromDirectory(string directory, NuGetFramework framework)
|
|
{
|
|
if (directory == null || framework == null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
var projectRootPath = directory;
|
|
|
|
if (!File.Exists(Path.Combine(projectRootPath, Project.FileName)))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
return ProjectContext.Create(
|
|
projectRootPath,
|
|
framework,
|
|
RuntimeEnvironmentRidExtensions.GetAllCandidateRuntimeIdentifiers());
|
|
|
|
}
|
|
|
|
private IEnumerable<string> GetAllowedCommandExtensionsFromEnvironment(IEnvironmentProvider environment)
|
|
{
|
|
var allowedCommandExtensions = new List<string>();
|
|
allowedCommandExtensions.AddRange(environment.ExecutableExtensions);
|
|
allowedCommandExtensions.Add(FileNameSuffixes.DotNet.DynamicLib);
|
|
|
|
return allowedCommandExtensions;
|
|
}
|
|
}
|
|
}
|