dotnet-installer/src/Microsoft.DotNet.Cli.Utils/CommandResolution/PackagedCommandSpecFactory.cs

120 lines
4.1 KiB
C#
Raw Normal View History

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using Microsoft.DotNet.ProjectModel;
using Microsoft.DotNet.ProjectModel.Graph;
using Microsoft.Extensions.PlatformAbstractions;
using NuGet.Frameworks;
using NuGet.Packaging;
namespace Microsoft.DotNet.Cli.Utils
{
public class PackagedCommandSpecFactory : IPackagedCommandSpecFactory
{
public CommandSpec CreateCommandSpecFromLibrary(
LockFilePackageLibrary library,
string commandName,
IEnumerable<string> commandArguments,
IEnumerable<string> allowedExtensions,
string nugetPackagesRoot,
CommandResolutionStrategy commandResolutionStrategy,
string depsFilePath)
{
var packageDirectory = GetPackageDirectoryFullPath(library, nugetPackagesRoot);
if (!Directory.Exists(packageDirectory))
{
return null;
}
var commandFile = GetCommandFileRelativePath(library, commandName, allowedExtensions);
if (commandFile == null)
{
return null;
}
var commandPath = Path.Combine(packageDirectory, commandFile);
return CreateCommandSpecWrappingWithCorehostfDll(
commandPath,
commandArguments,
depsFilePath,
commandResolutionStrategy);
}
private string GetPackageDirectoryFullPath(LockFilePackageLibrary library, string nugetPackagesRoot)
{
var packageDirectory = new VersionFolderPathResolver(nugetPackagesRoot)
.GetInstallPath(library.Name, library.Version);
return packageDirectory;
}
private string GetCommandFileRelativePath(
LockFilePackageLibrary library,
string commandName,
IEnumerable<string> allowedExtensions)
{
// TODO: Should command names be case sensitive?
return library.Files
.Where(f => Path.GetFileNameWithoutExtension(f) == commandName)
.Where(e => allowedExtensions.Contains(Path.GetExtension(e)))
.FirstOrDefault();
}
private CommandSpec CreateCommandSpecWrappingWithCorehostfDll(
string commandPath,
IEnumerable<string> commandArguments,
string depsFilePath,
CommandResolutionStrategy commandResolutionStrategy)
{
var commandExtension = Path.GetExtension(commandPath);
if (commandExtension == FileNameSuffixes.DotNet.DynamicLib)
{
return CreatePackageCommandSpecUsingCorehost(
commandPath,
commandArguments,
depsFilePath,
commandResolutionStrategy);
}
return CreateCommandSpec(commandPath, commandArguments, commandResolutionStrategy);
}
private CommandSpec CreatePackageCommandSpecUsingCorehost(
string commandPath,
IEnumerable<string> commandArguments,
string depsFilePath,
CommandResolutionStrategy commandResolutionStrategy)
{
var corehost = CoreHost.HostExePath;
var arguments = new List<string>();
arguments.Add(commandPath);
if (depsFilePath != null)
{
arguments.Add($"--depsfile:{depsFilePath}");
}
arguments.AddRange(commandArguments);
return CreateCommandSpec(corehost, arguments, commandResolutionStrategy);
}
private CommandSpec CreateCommandSpec(
string commandPath,
IEnumerable<string> commandArguments,
CommandResolutionStrategy commandResolutionStrategy)
{
var escapedArgs = ArgumentEscaper.EscapeAndConcatenateArgArrayForProcessStart(commandArguments);
return new CommandSpec(commandPath, escapedArgs, commandResolutionStrategy);
}
}
}