Call into project in .NET SDK to create deps.json files for tools instead of doing so directly
This commit is contained in:
parent
c8a6b7b97a
commit
fa51bb43fc
13 changed files with 337 additions and 195 deletions
|
@ -8,22 +8,14 @@ namespace Microsoft.DotNet.Cli.Utils
|
|||
{
|
||||
public interface IPackagedCommandSpecFactory
|
||||
{
|
||||
CommandSpec CreateCommandSpecFromLibrary(
|
||||
LockFileTargetLibrary toolLibrary,
|
||||
string commandName,
|
||||
IEnumerable<string> commandArguments,
|
||||
IEnumerable<string> allowedExtensions,
|
||||
string nugetPackagesRoot,
|
||||
CommandResolutionStrategy commandResolutionStrategy,
|
||||
string depsFilePath,
|
||||
string runtimeConfigPath);
|
||||
// Code review TODO: Is it OK to make breaking changes to the CLI Utils API surface?
|
||||
|
||||
CommandSpec CreateCommandSpecFromLibrary(
|
||||
LockFileTargetLibrary toolLibrary,
|
||||
string commandName,
|
||||
IEnumerable<string> commandArguments,
|
||||
IEnumerable<string> allowedExtensions,
|
||||
IEnumerable<string> packageFolders,
|
||||
LockFile lockFile,
|
||||
CommandResolutionStrategy commandResolutionStrategy,
|
||||
string depsFilePath,
|
||||
string runtimeConfigPath);
|
||||
|
|
|
@ -26,5 +26,7 @@ namespace Microsoft.DotNet.Cli.Utils
|
|||
NuGetFramework DotnetCliToolTargetFramework { get; }
|
||||
|
||||
Dictionary<string, string> EnvironmentVariables { get; }
|
||||
|
||||
string ToolDepsJsonGeneratorProject { get; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -92,6 +92,19 @@ namespace Microsoft.DotNet.Cli.Utils
|
|||
}
|
||||
}
|
||||
|
||||
public string ToolDepsJsonGeneratorProject
|
||||
{
|
||||
get
|
||||
{
|
||||
var generatorProject = _project
|
||||
.AllEvaluatedProperties
|
||||
.FirstOrDefault(p => p.Name.Equals("ToolDepsJsonGeneratorProject"))
|
||||
?.EvaluatedValue;
|
||||
|
||||
return generatorProject;
|
||||
}
|
||||
}
|
||||
|
||||
public MSBuildProject(
|
||||
string msBuildProjectPath,
|
||||
NuGetFramework framework,
|
||||
|
|
|
@ -27,28 +27,7 @@ namespace Microsoft.DotNet.Cli.Utils
|
|||
string commandName,
|
||||
IEnumerable<string> commandArguments,
|
||||
IEnumerable<string> allowedExtensions,
|
||||
string nugetPackagesRoot,
|
||||
CommandResolutionStrategy commandResolutionStrategy,
|
||||
string depsFilePath,
|
||||
string runtimeConfigPath)
|
||||
{
|
||||
return CreateCommandSpecFromLibrary(
|
||||
toolLibrary,
|
||||
commandName,
|
||||
commandArguments,
|
||||
allowedExtensions,
|
||||
new List<string> { nugetPackagesRoot },
|
||||
commandResolutionStrategy,
|
||||
depsFilePath,
|
||||
runtimeConfigPath);
|
||||
}
|
||||
|
||||
public CommandSpec CreateCommandSpecFromLibrary(
|
||||
LockFileTargetLibrary toolLibrary,
|
||||
string commandName,
|
||||
IEnumerable<string> commandArguments,
|
||||
IEnumerable<string> allowedExtensions,
|
||||
IEnumerable<string> packageFolders,
|
||||
LockFile lockFile,
|
||||
CommandResolutionStrategy commandResolutionStrategy,
|
||||
string depsFilePath,
|
||||
string runtimeConfigPath)
|
||||
|
@ -72,7 +51,7 @@ namespace Microsoft.DotNet.Cli.Utils
|
|||
return null;
|
||||
}
|
||||
|
||||
var commandPath = GetCommandFilePath(packageFolders, toolLibrary, toolAssembly);
|
||||
var commandPath = GetCommandFilePath(lockFile, toolLibrary, toolAssembly);
|
||||
|
||||
if (!File.Exists(commandPath))
|
||||
{
|
||||
|
@ -89,21 +68,16 @@ namespace Microsoft.DotNet.Cli.Utils
|
|||
commandArguments,
|
||||
depsFilePath,
|
||||
commandResolutionStrategy,
|
||||
packageFolders,
|
||||
lockFile.GetNormalizedPackageFolders(),
|
||||
runtimeConfigPath);
|
||||
}
|
||||
|
||||
private string GetCommandFilePath(
|
||||
IEnumerable<string> packageFolders,
|
||||
LockFile lockFile,
|
||||
LockFileTargetLibrary toolLibrary,
|
||||
LockFileItem runtimeAssembly)
|
||||
{
|
||||
var packageFoldersCount = packageFolders.Count();
|
||||
var userPackageFolder = packageFoldersCount == 1 ? string.Empty : packageFolders.First();
|
||||
var fallbackPackageFolders = packageFoldersCount > 1 ? packageFolders.Skip(1) : packageFolders;
|
||||
|
||||
var packageDirectory = new FallbackPackagePathResolver(userPackageFolder, fallbackPackageFolders)
|
||||
.GetPackageDirectory(toolLibrary.Name, toolLibrary.Version);
|
||||
var packageDirectory = lockFile.GetPackageDirectory(toolLibrary);
|
||||
|
||||
if (packageDirectory == null)
|
||||
{
|
||||
|
|
|
@ -120,15 +120,13 @@ namespace Microsoft.DotNet.Cli.Utils
|
|||
|
||||
var lockFile = project.GetLockFile();
|
||||
var toolLibrary = GetToolLibraryForContext(lockFile, commandName, framework);
|
||||
var normalizedNugetPackagesRoot =
|
||||
PathUtility.EnsureNoTrailingDirectorySeparator(lockFile.PackageFolders.First().Path);
|
||||
|
||||
var commandSpec = _packagedCommandSpecFactory.CreateCommandSpecFromLibrary(
|
||||
toolLibrary,
|
||||
commandName,
|
||||
commandArguments,
|
||||
allowedExtensions,
|
||||
normalizedNugetPackagesRoot,
|
||||
lockFile,
|
||||
s_commandResolutionStrategy,
|
||||
depsFilePath,
|
||||
runtimeConfigPath);
|
||||
|
|
|
@ -170,10 +170,8 @@ namespace Microsoft.DotNet.Cli.Utils
|
|||
toolLibraryRange,
|
||||
toolPackageFramework,
|
||||
toolLockFile,
|
||||
depsFileRoot);
|
||||
|
||||
var packageFolders = toolLockFile.PackageFolders.Select(p =>
|
||||
PathUtility.EnsureNoTrailingDirectorySeparator(p.Path));
|
||||
depsFileRoot,
|
||||
project.ToolDepsJsonGeneratorProject);
|
||||
|
||||
Reporter.Verbose.WriteLine(string.Format(
|
||||
LocalizableStrings.AttemptingToCreateCommandSpec,
|
||||
|
@ -184,7 +182,7 @@ namespace Microsoft.DotNet.Cli.Utils
|
|||
commandName,
|
||||
args,
|
||||
_allowedCommandExtensions,
|
||||
packageFolders,
|
||||
toolLockFile,
|
||||
s_commandResolutionStrategy,
|
||||
depsFilePath,
|
||||
null);
|
||||
|
@ -281,7 +279,8 @@ namespace Microsoft.DotNet.Cli.Utils
|
|||
SingleProjectInfo toolLibrary,
|
||||
NuGetFramework framework,
|
||||
LockFile toolLockFile,
|
||||
string depsPathRoot)
|
||||
string depsPathRoot,
|
||||
string toolDepsJsonGeneratorProject)
|
||||
{
|
||||
var depsJsonPath = Path.Combine(
|
||||
depsPathRoot,
|
||||
|
@ -292,7 +291,7 @@ namespace Microsoft.DotNet.Cli.Utils
|
|||
ProjectToolsCommandResolverName,
|
||||
depsJsonPath));
|
||||
|
||||
EnsureToolJsonDepsFileExists(toolLockFile, framework, depsJsonPath, toolLibrary);
|
||||
EnsureToolJsonDepsFileExists(toolLockFile, framework, depsJsonPath, toolLibrary, toolDepsJsonGeneratorProject);
|
||||
|
||||
return depsJsonPath;
|
||||
}
|
||||
|
@ -301,11 +300,12 @@ namespace Microsoft.DotNet.Cli.Utils
|
|||
LockFile toolLockFile,
|
||||
NuGetFramework framework,
|
||||
string depsPath,
|
||||
SingleProjectInfo toolLibrary)
|
||||
SingleProjectInfo toolLibrary,
|
||||
string toolDepsJsonGeneratorProject)
|
||||
{
|
||||
if (!File.Exists(depsPath))
|
||||
{
|
||||
GenerateDepsJsonFile(toolLockFile, framework, depsPath, toolLibrary);
|
||||
GenerateDepsJsonFile(toolLockFile, framework, depsPath, toolLibrary, toolDepsJsonGeneratorProject);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -313,7 +313,8 @@ namespace Microsoft.DotNet.Cli.Utils
|
|||
LockFile toolLockFile,
|
||||
NuGetFramework framework,
|
||||
string depsPath,
|
||||
SingleProjectInfo toolLibrary)
|
||||
SingleProjectInfo toolLibrary,
|
||||
string toolDepsJsonGeneratorProject)
|
||||
{
|
||||
Reporter.Verbose.WriteLine(string.Format(
|
||||
LocalizableStrings.GeneratingDepsJson,
|
||||
|
@ -323,11 +324,52 @@ namespace Microsoft.DotNet.Cli.Utils
|
|||
.Build(toolLibrary, null, toolLockFile, framework, null);
|
||||
|
||||
var tempDepsFile = Path.GetTempFileName();
|
||||
using (var fileStream = File.Open(tempDepsFile, FileMode.Open, FileAccess.Write))
|
||||
{
|
||||
var dependencyContextWriter = new DependencyContextWriter();
|
||||
|
||||
dependencyContextWriter.Write(dependencyContext, fileStream);
|
||||
var args = new List<string>();
|
||||
|
||||
args.Add(toolDepsJsonGeneratorProject);
|
||||
args.Add($"/p:ProjectAssetsFile=\"{toolLockFile.Path}\"");
|
||||
args.Add($"/p:ToolName={toolLibrary.Name}");
|
||||
args.Add($"/p:ProjectDepsFilePath={tempDepsFile}");
|
||||
|
||||
|
||||
// Look for the .props file in the Microsoft.NETCore.App package, until NuGet
|
||||
// generates .props and .targets files for tool restores (https://github.com/NuGet/Home/issues/5037)
|
||||
var platformLibrary = toolLockFile.Targets
|
||||
.FirstOrDefault(t => framework == t.TargetFramework)
|
||||
?.GetPlatformLibrary();
|
||||
|
||||
if (platformLibrary != null)
|
||||
{
|
||||
string buildRelativePath = platformLibrary.Build.FirstOrDefault()?.Path;
|
||||
|
||||
var platformLibraryPath = toolLockFile.GetPackageDirectory(platformLibrary);
|
||||
|
||||
if (platformLibraryPath != null && buildRelativePath != null)
|
||||
{
|
||||
// Get rid of "_._" filename
|
||||
buildRelativePath = Path.GetDirectoryName(buildRelativePath);
|
||||
|
||||
string platformLibraryBuildFolderPath = Path.Combine(platformLibraryPath, buildRelativePath);
|
||||
var platformLibraryPropsFile = Directory.GetFiles(platformLibraryBuildFolderPath, "*.props").FirstOrDefault();
|
||||
|
||||
if (platformLibraryPropsFile != null)
|
||||
{
|
||||
args.Add($"/p:AdditionalImport={platformLibraryPropsFile}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Delete temporary file created by Path.GetTempFileName(), otherwise the GenerateBuildDependencyFile target
|
||||
// will think the deps file is up-to-date and skip executing
|
||||
File.Delete(tempDepsFile);
|
||||
|
||||
var result = new MSBuildForwardingAppWithoutLogging(args).Execute();
|
||||
|
||||
if (result != 0)
|
||||
{
|
||||
// TODO: Can / should we show the MSBuild output if there is a failure?
|
||||
throw new GracefulException(string.Format(LocalizableStrings.UnableToGenerateDepsJson, toolDepsJsonGeneratorProject));
|
||||
}
|
||||
|
||||
try
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
using Microsoft.DotNet.Tools.Common;
|
||||
using NuGet.Packaging;
|
||||
using NuGet.ProjectModel;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Microsoft.DotNet.Cli.Utils
|
||||
{
|
||||
static class LockFileExtensions
|
||||
{
|
||||
public static string GetPackageDirectory(this LockFile lockFile, LockFileTargetLibrary library)
|
||||
{
|
||||
var packageFolders = lockFile.GetNormalizedPackageFolders();
|
||||
|
||||
var packageFoldersCount = packageFolders.Count();
|
||||
var userPackageFolder = packageFoldersCount == 1 ? string.Empty : packageFolders.First();
|
||||
var fallbackPackageFolders = packageFoldersCount > 1 ? packageFolders.Skip(1) : packageFolders;
|
||||
|
||||
var packageDirectory = new FallbackPackagePathResolver(userPackageFolder, fallbackPackageFolders)
|
||||
.GetPackageDirectory(library.Name, library.Version);
|
||||
|
||||
return packageDirectory;
|
||||
}
|
||||
|
||||
public static IEnumerable<string> GetNormalizedPackageFolders(this LockFile lockFile)
|
||||
{
|
||||
return lockFile.PackageFolders.Select(p =>
|
||||
PathUtility.EnsureNoTrailingDirectorySeparator(p.Path));
|
||||
}
|
||||
}
|
||||
}
|
108
src/Microsoft.DotNet.Cli.Utils/ForwardingAppImplementation.cs
Normal file
108
src/Microsoft.DotNet.Cli.Utils/ForwardingAppImplementation.cs
Normal file
|
@ -0,0 +1,108 @@
|
|||
// 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 System.Diagnostics;
|
||||
using Microsoft.DotNet.Cli.Utils;
|
||||
|
||||
namespace Microsoft.DotNet.Cli.Utils
|
||||
{
|
||||
/// <summary>
|
||||
/// A class which encapsulates logic needed to forward arguments from the current process to another process
|
||||
/// invoked with the dotnet.exe host.
|
||||
/// </summary>
|
||||
internal class ForwardingAppImplementation
|
||||
{
|
||||
private const string s_hostExe = "dotnet";
|
||||
|
||||
private readonly string _forwardApplicationPath;
|
||||
private readonly IEnumerable<string> _argsToForward;
|
||||
private readonly string _depsFile;
|
||||
private readonly string _runtimeConfig;
|
||||
private readonly string _additionalProbingPath;
|
||||
private Dictionary<string, string> _environmentVariables;
|
||||
|
||||
private readonly string[] _allArgs;
|
||||
|
||||
public ForwardingAppImplementation(
|
||||
string forwardApplicationPath,
|
||||
IEnumerable<string> argsToForward,
|
||||
string depsFile = null,
|
||||
string runtimeConfig = null,
|
||||
string additionalProbingPath = null,
|
||||
Dictionary<string, string> environmentVariables = null)
|
||||
{
|
||||
_forwardApplicationPath = forwardApplicationPath;
|
||||
_argsToForward = argsToForward;
|
||||
_depsFile = depsFile;
|
||||
_runtimeConfig = runtimeConfig;
|
||||
_additionalProbingPath = additionalProbingPath;
|
||||
_environmentVariables = environmentVariables;
|
||||
|
||||
var allArgs = new List<string>();
|
||||
allArgs.Add("exec");
|
||||
|
||||
if (_depsFile != null)
|
||||
{
|
||||
allArgs.Add("--depsfile");
|
||||
allArgs.Add(_depsFile);
|
||||
}
|
||||
|
||||
if (_runtimeConfig != null)
|
||||
{
|
||||
allArgs.Add("--runtimeconfig");
|
||||
allArgs.Add(_runtimeConfig);
|
||||
}
|
||||
|
||||
if (_additionalProbingPath != null)
|
||||
{
|
||||
allArgs.Add("--additionalprobingpath");
|
||||
allArgs.Add(_additionalProbingPath);
|
||||
}
|
||||
|
||||
allArgs.Add(_forwardApplicationPath);
|
||||
allArgs.AddRange(_argsToForward);
|
||||
|
||||
_allArgs = allArgs.ToArray();
|
||||
}
|
||||
|
||||
public int Execute()
|
||||
{
|
||||
return GetProcessStartInfo().Execute();
|
||||
}
|
||||
|
||||
public ProcessStartInfo GetProcessStartInfo()
|
||||
{
|
||||
var processInfo = new ProcessStartInfo
|
||||
{
|
||||
FileName = GetHostExeName(),
|
||||
Arguments = ArgumentEscaper.EscapeAndConcatenateArgArrayForProcessStart(_allArgs),
|
||||
UseShellExecute = false
|
||||
};
|
||||
|
||||
if (_environmentVariables != null)
|
||||
{
|
||||
foreach (var entry in _environmentVariables)
|
||||
{
|
||||
processInfo.Environment[entry.Key] = entry.Value;
|
||||
}
|
||||
}
|
||||
|
||||
return processInfo;
|
||||
}
|
||||
|
||||
public ForwardingAppImplementation WithEnvironmentVariable(string name, string value)
|
||||
{
|
||||
_environmentVariables = _environmentVariables ?? new Dictionary<string, string>();
|
||||
|
||||
_environmentVariables.Add(name, value);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
private string GetHostExeName()
|
||||
{
|
||||
return $"{s_hostExe}{FileNameSuffixes.CurrentPlatform.Exe}";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace Microsoft.DotNet.Cli.Utils
|
||||
{
|
||||
internal class MSBuildForwardingAppWithoutLogging
|
||||
{
|
||||
private const string MSBuildExeName = "MSBuild.dll";
|
||||
|
||||
private const string SdksDirectoryName = "Sdks";
|
||||
|
||||
private readonly ForwardingAppImplementation _forwardingApp;
|
||||
|
||||
private readonly Dictionary<string, string> _msbuildRequiredEnvironmentVariables =
|
||||
new Dictionary<string, string>
|
||||
{
|
||||
{ "MSBuildExtensionsPath", AppContext.BaseDirectory },
|
||||
{ "CscToolExe", GetRunCscPath() },
|
||||
{ "MSBuildSDKsPath", GetMSBuildSDKsPath() }
|
||||
};
|
||||
|
||||
private readonly IEnumerable<string> _msbuildRequiredParameters =
|
||||
new List<string> { "/m", "/v:m" };
|
||||
|
||||
public MSBuildForwardingAppWithoutLogging(IEnumerable<string> argsToForward, string msbuildPath = null)
|
||||
{
|
||||
_forwardingApp = new ForwardingAppImplementation(
|
||||
msbuildPath ?? GetMSBuildExePath(),
|
||||
_msbuildRequiredParameters.Concat(argsToForward.Select(Escape)),
|
||||
environmentVariables: _msbuildRequiredEnvironmentVariables);
|
||||
}
|
||||
|
||||
public virtual ProcessStartInfo GetProcessStartInfo()
|
||||
{
|
||||
return _forwardingApp
|
||||
.GetProcessStartInfo();
|
||||
}
|
||||
|
||||
public int Execute()
|
||||
{
|
||||
return GetProcessStartInfo().Execute();
|
||||
}
|
||||
|
||||
private static string Escape(string arg) =>
|
||||
// this is a workaround for https://github.com/Microsoft/msbuild/issues/1622
|
||||
(arg.StartsWith("/p:RestoreSources=", StringComparison.OrdinalIgnoreCase)) ?
|
||||
arg.Replace(";", "%3B")
|
||||
.Replace("://", ":%2F%2F") :
|
||||
arg;
|
||||
|
||||
private static string GetMSBuildExePath()
|
||||
{
|
||||
return Path.Combine(
|
||||
AppContext.BaseDirectory,
|
||||
MSBuildExeName);
|
||||
}
|
||||
|
||||
private static string GetMSBuildSDKsPath()
|
||||
{
|
||||
var envMSBuildSDKsPath = Environment.GetEnvironmentVariable("MSBuildSDKsPath");
|
||||
|
||||
if (envMSBuildSDKsPath != null)
|
||||
{
|
||||
return envMSBuildSDKsPath;
|
||||
}
|
||||
|
||||
return Path.Combine(
|
||||
AppContext.BaseDirectory,
|
||||
SdksDirectoryName);
|
||||
}
|
||||
|
||||
private static string GetRunCscPath()
|
||||
{
|
||||
var scriptExtension = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ".cmd" : ".sh";
|
||||
return Path.Combine(AppContext.BaseDirectory, "Roslyn", $"RunCsc{scriptExtension}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Microsoft.DotNet.Cli
|
||||
namespace Microsoft.DotNet.Cli.Utils
|
||||
{
|
||||
internal static class ProcessStartInfoExtensions
|
||||
{
|
|
@ -1,28 +1,14 @@
|
|||
// 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;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using Microsoft.DotNet.Cli.Utils;
|
||||
using System.Text;
|
||||
|
||||
namespace Microsoft.DotNet.Cli
|
||||
{
|
||||
/// <summary>
|
||||
/// A class which encapsulates logic needed to forward arguments from the current process to another process
|
||||
/// invoked with the dotnet.exe host.
|
||||
/// </summary>
|
||||
public class ForwardingApp
|
||||
{
|
||||
private const string s_hostExe = "dotnet";
|
||||
|
||||
private readonly string _forwardApplicationPath;
|
||||
private readonly IEnumerable<string> _argsToForward;
|
||||
private readonly string _depsFile;
|
||||
private readonly string _runtimeConfig;
|
||||
private readonly string _additionalProbingPath;
|
||||
private Dictionary<string, string> _environmentVariables;
|
||||
|
||||
private readonly string[] _allArgs;
|
||||
ForwardingAppImplementation _implementation;
|
||||
|
||||
public ForwardingApp(
|
||||
string forwardApplicationPath,
|
||||
|
@ -32,77 +18,29 @@ namespace Microsoft.DotNet.Cli
|
|||
string additionalProbingPath = null,
|
||||
Dictionary<string, string> environmentVariables = null)
|
||||
{
|
||||
_forwardApplicationPath = forwardApplicationPath;
|
||||
_argsToForward = argsToForward;
|
||||
_depsFile = depsFile;
|
||||
_runtimeConfig = runtimeConfig;
|
||||
_additionalProbingPath = additionalProbingPath;
|
||||
_environmentVariables = environmentVariables;
|
||||
|
||||
var allArgs = new List<string>();
|
||||
allArgs.Add("exec");
|
||||
|
||||
if (_depsFile != null)
|
||||
{
|
||||
allArgs.Add("--depsfile");
|
||||
allArgs.Add(_depsFile);
|
||||
}
|
||||
|
||||
if (_runtimeConfig != null)
|
||||
{
|
||||
allArgs.Add("--runtimeconfig");
|
||||
allArgs.Add(_runtimeConfig);
|
||||
}
|
||||
|
||||
if (_additionalProbingPath != null)
|
||||
{
|
||||
allArgs.Add("--additionalprobingpath");
|
||||
allArgs.Add(_additionalProbingPath);
|
||||
}
|
||||
|
||||
allArgs.Add(_forwardApplicationPath);
|
||||
allArgs.AddRange(_argsToForward);
|
||||
|
||||
_allArgs = allArgs.ToArray();
|
||||
}
|
||||
|
||||
public int Execute()
|
||||
{
|
||||
return GetProcessStartInfo().Execute();
|
||||
_implementation = new ForwardingAppImplementation(
|
||||
forwardApplicationPath,
|
||||
argsToForward,
|
||||
depsFile,
|
||||
runtimeConfig,
|
||||
additionalProbingPath,
|
||||
environmentVariables);
|
||||
}
|
||||
|
||||
public ProcessStartInfo GetProcessStartInfo()
|
||||
{
|
||||
var processInfo = new ProcessStartInfo
|
||||
{
|
||||
FileName = GetHostExeName(),
|
||||
Arguments = ArgumentEscaper.EscapeAndConcatenateArgArrayForProcessStart(_allArgs),
|
||||
UseShellExecute = false
|
||||
};
|
||||
|
||||
if (_environmentVariables != null)
|
||||
{
|
||||
foreach (var entry in _environmentVariables)
|
||||
{
|
||||
processInfo.Environment[entry.Key] = entry.Value;
|
||||
}
|
||||
}
|
||||
|
||||
return processInfo;
|
||||
return _implementation.GetProcessStartInfo();
|
||||
}
|
||||
|
||||
public ForwardingApp WithEnvironmentVariable(string name, string value)
|
||||
{
|
||||
_environmentVariables = _environmentVariables ?? new Dictionary<string, string>();
|
||||
|
||||
_environmentVariables.Add(name, value);
|
||||
|
||||
_implementation = _implementation.WithEnvironmentVariable(name, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
private string GetHostExeName()
|
||||
public int Execute()
|
||||
{
|
||||
return $"{s_hostExe}{FileNameSuffixes.CurrentPlatform.Exe}";
|
||||
return _implementation.Execute();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Microsoft.DotNet.Cli;
|
||||
using Microsoft.DotNet.Cli.Utils;
|
||||
|
||||
namespace Microsoft.DotNet.Tools
|
||||
{
|
||||
|
|
|
@ -10,6 +10,7 @@ using System.Runtime.InteropServices;
|
|||
using Microsoft.DotNet.Cli;
|
||||
using Microsoft.DotNet.Cli.CommandLine;
|
||||
using System.Diagnostics;
|
||||
using Microsoft.DotNet.Cli.Utils;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.MSBuild
|
||||
{
|
||||
|
@ -17,24 +18,9 @@ namespace Microsoft.DotNet.Tools.MSBuild
|
|||
{
|
||||
internal const string TelemetrySessionIdEnvironmentVariableName = "DOTNET_CLI_TELEMETRY_SESSIONID";
|
||||
|
||||
private const string MSBuildExeName = "MSBuild.dll";
|
||||
private MSBuildForwardingAppWithoutLogging _forwardingAppWithoutLogging;
|
||||
|
||||
private const string SdksDirectoryName = "Sdks";
|
||||
|
||||
private readonly ForwardingApp _forwardingApp;
|
||||
|
||||
private readonly Dictionary<string, string> _msbuildRequiredEnvironmentVariables =
|
||||
new Dictionary<string, string>
|
||||
{
|
||||
{ "MSBuildExtensionsPath", AppContext.BaseDirectory },
|
||||
{ "CscToolExe", GetRunCscPath() },
|
||||
{ "MSBuildSDKsPath", GetMSBuildSDKsPath() }
|
||||
};
|
||||
|
||||
private readonly IEnumerable<string> _msbuildRequiredParameters =
|
||||
new List<string> { "/m", "/v:m" };
|
||||
|
||||
public MSBuildForwardingApp(IEnumerable<string> argsToForward, string msbuildPath = null)
|
||||
static IEnumerable<string> ConcatTelemetryLogger(IEnumerable<string> argsToForward)
|
||||
{
|
||||
if (Telemetry.CurrentSessionId != null)
|
||||
{
|
||||
|
@ -42,7 +28,7 @@ namespace Microsoft.DotNet.Tools.MSBuild
|
|||
{
|
||||
Type loggerType = typeof(MSBuildLogger);
|
||||
|
||||
argsToForward = argsToForward
|
||||
return argsToForward
|
||||
.Concat(new[]
|
||||
{
|
||||
$"/Logger:{loggerType.FullName},{loggerType.GetTypeInfo().Assembly.Location}"
|
||||
|
@ -53,57 +39,28 @@ namespace Microsoft.DotNet.Tools.MSBuild
|
|||
// Exceptions during telemetry shouldn't cause anything else to fail
|
||||
}
|
||||
}
|
||||
return argsToForward;
|
||||
}
|
||||
|
||||
_forwardingApp = new ForwardingApp(
|
||||
msbuildPath ?? GetMSBuildExePath(),
|
||||
_msbuildRequiredParameters.Concat(argsToForward.Select(Escape)),
|
||||
environmentVariables: _msbuildRequiredEnvironmentVariables);
|
||||
public MSBuildForwardingApp(IEnumerable<string> argsToForward, string msbuildPath = null)
|
||||
{
|
||||
_forwardingAppWithoutLogging = new MSBuildForwardingAppWithoutLogging(
|
||||
ConcatTelemetryLogger(argsToForward),
|
||||
msbuildPath);
|
||||
}
|
||||
|
||||
public ProcessStartInfo GetProcessStartInfo()
|
||||
{
|
||||
return _forwardingApp
|
||||
.WithEnvironmentVariable(TelemetrySessionIdEnvironmentVariableName, Telemetry.CurrentSessionId)
|
||||
.GetProcessStartInfo();
|
||||
var ret = _forwardingAppWithoutLogging.GetProcessStartInfo();
|
||||
|
||||
ret.Environment[TelemetrySessionIdEnvironmentVariableName] = Telemetry.CurrentSessionId;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public int Execute()
|
||||
{
|
||||
return GetProcessStartInfo().Execute();
|
||||
}
|
||||
|
||||
private static string Escape(string arg) =>
|
||||
// this is a workaround for https://github.com/Microsoft/msbuild/issues/1622
|
||||
(arg.StartsWith("/p:RestoreSources=", StringComparison.OrdinalIgnoreCase)) ?
|
||||
arg.Replace(";", "%3B")
|
||||
.Replace("://", ":%2F%2F") :
|
||||
arg;
|
||||
|
||||
private static string GetMSBuildExePath()
|
||||
{
|
||||
return Path.Combine(
|
||||
AppContext.BaseDirectory,
|
||||
MSBuildExeName);
|
||||
}
|
||||
|
||||
private static string GetMSBuildSDKsPath()
|
||||
{
|
||||
var envMSBuildSDKsPath = Environment.GetEnvironmentVariable("MSBuildSDKsPath");
|
||||
|
||||
if (envMSBuildSDKsPath != null)
|
||||
{
|
||||
return envMSBuildSDKsPath;
|
||||
}
|
||||
|
||||
return Path.Combine(
|
||||
AppContext.BaseDirectory,
|
||||
SdksDirectoryName);
|
||||
}
|
||||
|
||||
private static string GetRunCscPath()
|
||||
{
|
||||
var scriptExtension = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ".cmd" : ".sh";
|
||||
return Path.Combine(AppContext.BaseDirectory, "Roslyn", $"RunCsc{scriptExtension}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue