// This is where the magic happens - returns one result per result target framework private AnalyzerResults BuildTargets(BuildEnvironment buildEnvironment, string targetFramework, string[] targetsToBuild, AnalyzerResults results) { using (CancellationTokenSource cancellation = new CancellationTokenSource()) { using (AnonymousPipeLoggerServer pipeLogger = new AnonymousPipeLoggerServer(cancellation.Token)) { using (EventProcessor eventProcessor = new EventProcessor(Manager, this, BuildLoggers, pipeLogger, results != null)) { // Run MSBuild int exitCode; string fileName = GetCommand(buildEnvironment, targetFramework, targetsToBuild, pipeLogger.GetClientHandle(), out string arguments); using (ProcessRunner processRunner = new ProcessRunner(fileName, arguments, Path.GetDirectoryName(ProjectFile.Path), GetEffectiveEnvironmentVariables(buildEnvironment), Manager.LoggerFactory)) { processRunner.Exited = () => cancellation.Cancel(); processRunner.Start(); pipeLogger.ReadAll(); processRunner.Process.WaitForExit(); exitCode = processRunner.Process.ExitCode; } // Collect the results results?.Add(eventProcessor.Results, exitCode == 0 && eventProcessor.OverallSuccess); } } } return(results); }
private string GetCommand(BuildEnvironment buildEnvironment, string targetFramework, string[] targetsToBuild, string pipeLoggerClientHandle, out string arguments) { // Get the executable and the initial set of arguments string fileName = buildEnvironment.MsBuildExePath; string initialArguments = string.Empty; if (Path.GetExtension(buildEnvironment.MsBuildExePath).Equals(".dll", StringComparison.OrdinalIgnoreCase)) { // .NET Core MSBuild .dll needs to be run with dotnet fileName = "dotnet"; initialArguments = $"\"{buildEnvironment.MsBuildExePath}\""; } // Get the logger arguments string loggerPath = typeof(BuildalyzerLogger).Assembly.Location; bool logEverything = _buildLoggers.Count > 0; string loggerArgument = $"/l:{nameof(BuildalyzerLogger)},{FormatArgument(loggerPath)};{pipeLoggerClientHandle};{logEverything}"; // Get the properties arguments Dictionary <string, string> effectiveGlobalProperties = GetEffectiveGlobalProperties(buildEnvironment); if (!string.IsNullOrEmpty(targetFramework)) { // Setting the TargetFramework MSBuild property tells MSBuild which target framework to use for the outer build effectiveGlobalProperties[MsBuildProperties.TargetFramework] = targetFramework; } string propertyArgument = effectiveGlobalProperties.Count == 0 ? string.Empty : $"/property:{(string.Join(";", effectiveGlobalProperties.Select(x => $"{x.Key}={FormatArgument(x.Value)}")))}"; // Get the target argument string targetArgument = targetsToBuild == null || targetsToBuild.Length == 0 ? string.Empty : $"/target:{string.Join(";", targetsToBuild)}"; arguments = $"{initialArguments} /noconsolelogger {targetArgument} {propertyArgument} {loggerArgument} {FormatArgument(ProjectFile.Path)}"; return(fileName); }
internal ProjectAnalyzer(AnalyzerManager manager, string projectFilePath, XDocument projectDocument, BuildEnvironment buildEnvironment) { Manager = manager; ProjectFilePath = projectFilePath; _projectDocument = TweakProjectDocument(manager, projectDocument ?? XDocument.Load(projectFilePath)); // Get the paths _buildEnvironment = buildEnvironment ?? EnvironmentFactory.GetBuildEnvironment(projectFilePath, _projectDocument); // Preload/enforce referencing some required asemblies Copy copy = new Copy(); // Set the solution directory global property string solutionDir = manager.SolutionDirectory ?? Path.GetDirectoryName(projectFilePath); SetGlobalProperty(MsBuildProperties.SolutionDir, solutionDir); // Create the logger if (manager.ProjectLogger != null) { _logger = new ConsoleLogger(manager.LoggerVerbosity, x => manager.ProjectLogger.LogInformation(x), null, null); } }