|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
#nullable disable
using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.Cli.Utils.Extensions;
using NuGet.Frameworks;
using NuGet.ProjectModel;
namespace Microsoft.DotNet.Cli.CommandFactory.CommandResolution;
public class ProjectDependenciesCommandResolver : ICommandResolver
{
private const string ProjectDependenciesCommandResolverName = "projectdependenciescommandresolver";
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)
{
Reporter.Verbose.WriteLine(string.Format(
CliStrings.AttemptingToResolve,
ProjectDependenciesCommandResolverName,
commandResolverArguments.CommandName));
if (commandResolverArguments.Framework == null
|| commandResolverArguments.ProjectDirectory == null
|| commandResolverArguments.Configuration == null
|| commandResolverArguments.CommandName == null)
{
Reporter.Verbose.WriteLine(string.Format(
CliStrings.InvalidCommandResolverArguments,
ProjectDependenciesCommandResolverName));
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 projectFactory = new ProjectFactory(_environment);
var project = projectFactory.GetProject(
projectDirectory,
framework,
configuration,
buildBasePath,
outputPath);
if (project == null)
{
Reporter.Verbose.WriteLine(string.Format(
CliStrings.DidNotFindAMatchingProject,
ProjectDependenciesCommandResolverName,
projectDirectory));
return null;
}
var depsFilePath = project.DepsJsonPath;
if (!File.Exists(depsFilePath))
{
Reporter.Verbose.WriteLine(string.Format(
CliStrings.DoesNotExist,
ProjectDependenciesCommandResolverName,
depsFilePath));
return null;
}
var runtimeConfigPath = project.RuntimeConfigJsonPath;
if (!File.Exists(runtimeConfigPath))
{
Reporter.Verbose.WriteLine(string.Format(
CliStrings.DoesNotExist,
ProjectDependenciesCommandResolverName,
runtimeConfigPath));
return null;
}
var lockFile = project.GetLockFile();
var toolLibrary = GetToolLibraryForContext(lockFile, commandName, framework);
var commandSpec = _packagedCommandSpecFactory.CreateCommandSpecFromLibrary(
toolLibrary,
commandName,
commandArguments,
allowedExtensions,
lockFile,
depsFilePath,
runtimeConfigPath);
commandSpec?.AddEnvironmentVariablesFromProject(project);
return commandSpec;
}
private static LockFileTargetLibrary GetToolLibraryForContext(
LockFile lockFile, string commandName, NuGetFramework targetFramework)
{
var toolLibraries = lockFile.Targets
.FirstOrDefault(t => t.TargetFramework.GetShortFolderName()
.Equals(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(string.Format(
CliStrings.AmbiguousCommandName,
commandName));
}
Reporter.Verbose.WriteLine(string.Format(
CliStrings.ToolLibraryFound,
ProjectDependenciesCommandResolverName,
toolLibraries?.Count() > 0));
return toolLibraries?.FirstOrDefault();
}
private static IEnumerable<string> GetAllowedCommandExtensionsFromEnvironment(IEnvironmentProvider environment)
{
var allowedCommandExtensions = new List<string>();
allowedCommandExtensions.AddRange(environment.ExecutableExtensions);
allowedCommandExtensions.Add(FileNameSuffixes.DotNet.DynamicLib);
return allowedCommandExtensions;
}
}
|