Skip to content
5 changes: 3 additions & 2 deletions src/BuiltInTools/dotnet-watch/Build/EvaluationResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System.Collections.Immutable;
using Microsoft.Build.Graph;
using Microsoft.DotNet.Cli.Extensions;
using Microsoft.Extensions.Logging;

namespace Microsoft.DotNet.Watch;
Expand Down Expand Up @@ -75,7 +76,7 @@ public void WatchFiles(FileWatcher fileWatcher)
{
using (var loggers = buildReporter.GetLoggers(rootNode.ProjectInstance.FullPath, "Restore"))
{
if (!rootNode.ProjectInstance.Build([TargetNames.Restore], loggers))
if (!rootNode.ProjectInstance.BuildWithTelemetry([TargetNames.Restore], loggers))
{
logger.LogError("Failed to restore project '{Path}'.", rootProjectPath);
loggers.ReportOutput();
Expand Down Expand Up @@ -103,7 +104,7 @@ public void WatchFiles(FileWatcher fileWatcher)

using (var loggers = buildReporter.GetLoggers(projectInstance.FullPath, "DesignTimeBuild"))
{
if (!projectInstance.Build([TargetNames.Compile, .. customCollectWatchItems], loggers))
if (!projectInstance.BuildWithTelemetry([TargetNames.Compile, .. customCollectWatchItems], loggers))
{
logger.LogError("Failed to build project '{Path}'.", projectInstance.FullPath);
loggers.ReportOutput();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Diagnostics;
using Microsoft.Build.Graph;
using Microsoft.CodeAnalysis;
using Microsoft.DotNet.Cli.Extensions;
using Microsoft.DotNet.HotReload;
using Microsoft.Extensions.Logging;

Expand Down Expand Up @@ -578,7 +579,7 @@ private void DeployProjectDependencies(ProjectGraph graph, ImmutableArray<string
}

using var loggers = buildReporter.GetLoggers(projectPath, targetName);
if (!node.ProjectInstance.Build([targetName], loggers, out var targetOutputs))
if (!node.ProjectInstance.BuildWithTelemetry([targetName], loggers, null, out var targetOutputs))
{
_context.Logger.LogDebug("{TargetName} target failed", targetName);
loggers.ReportOutput();
Expand Down Expand Up @@ -793,7 +794,7 @@ void Report(ChangeKind kind)
}

string GetMessage(IReadOnlyList<ChangedFile> items, ChangeKind kind)
=> items is [{Item: var item }]
=> items is [{ Item: var item }]
? GetSingularMessage(kind) + ": " + GetRelativeFilePath(item.FilePath)
: GetPluralMessage(kind) + ": " + string.Join(", ", items.Select(f => GetRelativeFilePath(f.Item.FilePath)));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@


using Microsoft.Build.Graph;
using Microsoft.DotNet.Cli.Extensions;
using Microsoft.Extensions.Logging;

namespace Microsoft.DotNet.Watch
Expand Down Expand Up @@ -61,7 +62,7 @@ public async ValueTask HandleFileChangesAsync(IReadOnlyList<ChangedFile> files,
using var loggers = buildReporter.GetLoggers(projectNode.ProjectInstance.FullPath, BuildTargetName);

// Deep copy so that we don't pollute the project graph:
if (!projectNode.ProjectInstance.DeepCopy().Build(BuildTargetName, loggers))
if (!projectNode.ProjectInstance.DeepCopy().BuildWithTelemetry([BuildTargetName], loggers))
{
loggers.ReportOutput();
return null;
Expand Down
5 changes: 4 additions & 1 deletion src/Cli/dotnet/Commands/Package/Add/PackageAddCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,10 @@ private int ExecuteForFileBasedApp(string path)
NoCache = true,
NoBuild = true,
};
var projectCollection = new ProjectCollection();

// Include telemetry logger for project evaluation
var (loggersWithTelemetry, _) = ProjectInstanceExtensions.CreateLoggersWithTelemetry([]);
var projectCollection = new ProjectCollection(globalProperties: null, loggersWithTelemetry, ToolsetDefinitionLocations.Default);
var projectInstance = command.CreateProjectInstance(projectCollection);

// Set initial version to Directory.Packages.props and/or C# file
Expand Down
25 changes: 16 additions & 9 deletions src/Cli/dotnet/Commands/Run/RunCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -402,29 +402,36 @@ internal ICommand GetTargetCommand(Func<ProjectCollection, ProjectInstance>? pro

Reporter.Verbose.WriteLine("Getting target command: evaluating project.");
FacadeLogger? logger = LoggerUtility.DetermineBinlogger([.. MSBuildArgs.OtherMSBuildArgs], "dotnet-run");
var project = EvaluateProject(ProjectFileFullPath, projectFactory, MSBuildArgs, logger);
var (project, telemetryCentralLogger) = EvaluateProject(ProjectFileFullPath, projectFactory, MSBuildArgs, logger);
ValidatePreconditions(project);
InvokeRunArgumentsTarget(project, NoBuild, logger, MSBuildArgs);
InvokeRunArgumentsTarget(project, NoBuild, logger, MSBuildArgs, telemetryCentralLogger);
logger?.ReallyShutdown();
var runProperties = RunProperties.FromProject(project).WithApplicationArguments(ApplicationArgs);
var command = CreateCommandFromRunProperties(runProperties);
return command;

static ProjectInstance EvaluateProject(string? projectFilePath, Func<ProjectCollection, ProjectInstance>? projectFactory, MSBuildArgs msbuildArgs, ILogger? binaryLogger)
static (ProjectInstance project, ILogger? telemetryCentralLogger) EvaluateProject(string? projectFilePath, Func<ProjectCollection, ProjectInstance>? projectFactory, MSBuildArgs msbuildArgs, ILogger? binaryLogger)
{
Debug.Assert(projectFilePath is not null || projectFactory is not null);

var globalProperties = CommonRunHelpers.GetGlobalPropertiesFromArgs(msbuildArgs);

var collection = new ProjectCollection(globalProperties: globalProperties, loggers: binaryLogger is null ? null : [binaryLogger], toolsetDefinitionLocations: ToolsetDefinitionLocations.Default);
// Include telemetry logger for evaluation and capture it for reuse in builds
var (loggers, telemetryCentralLogger) = ProjectInstanceExtensions.CreateLoggersWithTelemetry(binaryLogger is null ? null : [binaryLogger]);
var collection = new ProjectCollection(globalProperties: globalProperties, loggers: loggers, toolsetDefinitionLocations: ToolsetDefinitionLocations.Default);

ProjectInstance projectInstance;
if (projectFilePath is not null)
{
return collection.LoadProject(projectFilePath).CreateProjectInstance();
projectInstance = collection.LoadProject(projectFilePath).CreateProjectInstance();
}
else
{
Debug.Assert(projectFactory is not null);
projectInstance = projectFactory(collection);
}

Debug.Assert(projectFactory is not null);
return projectFactory(collection);
return (projectInstance, telemetryCentralLogger);
}

static void ValidatePreconditions(ProjectInstance project)
Expand Down Expand Up @@ -480,7 +487,7 @@ static ICommand CreateCommandForCscBuiltProgram(string entryPointFileFullPath, s
return command;
}

static void InvokeRunArgumentsTarget(ProjectInstance project, bool noBuild, FacadeLogger? binaryLogger, MSBuildArgs buildArgs)
static void InvokeRunArgumentsTarget(ProjectInstance project, bool noBuild, FacadeLogger? binaryLogger, MSBuildArgs buildArgs, ILogger? telemetryCentralLogger)
{
List<ILogger> loggersForBuild = [
TerminalLogger.CreateTerminalOrConsoleLogger([$"--verbosity:{LoggerVerbosity.Quiet.ToString().ToLowerInvariant()}", ..buildArgs.OtherMSBuildArgs])
Expand All @@ -490,7 +497,7 @@ static void InvokeRunArgumentsTarget(ProjectInstance project, bool noBuild, Faca
loggersForBuild.Add(binaryLogger);
}

if (!project.Build([Constants.ComputeRunArguments], loggers: loggersForBuild, remoteLoggers: null, out _))
if (!project.BuildWithTelemetry([Constants.ComputeRunArguments], loggersForBuild, null, out _, telemetryCentralLogger))
{
throw new GracefulException(CliCommandStrings.RunCommandEvaluationExceptionBuildFailed, Constants.ComputeRunArguments);
}
Expand Down
10 changes: 7 additions & 3 deletions src/Cli/dotnet/Commands/Run/VirtualProjectBuildingCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
using Microsoft.CodeAnalysis.Text;
using Microsoft.DotNet.Cli.Commands.Clean.FileBasedAppArtifacts;
using Microsoft.DotNet.Cli.Commands.Restore;
using Microsoft.DotNet.Cli.Extensions;
using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.Cli.Utils.Extensions;

Expand Down Expand Up @@ -297,14 +298,17 @@ public override int Execute()

// Set up MSBuild.
ReadOnlySpan<ILogger> binaryLoggers = binaryLogger is null ? [] : [binaryLogger.Value];
IEnumerable<ILogger> loggers = [.. binaryLoggers, consoleLogger];
IEnumerable<ILogger> existingLoggers = [.. binaryLoggers, consoleLogger];

// Include telemetry logger for evaluation and capture it for potential future use
var (loggersWithTelemetry, telemetryCentralLogger) = ProjectInstanceExtensions.CreateLoggersWithTelemetry(existingLoggers);
var projectCollection = new ProjectCollection(
MSBuildArgs.GlobalProperties,
loggers,
loggersWithTelemetry,
ToolsetDefinitionLocations.Default);
var parameters = new BuildParameters(projectCollection)
{
Loggers = loggers,
Loggers = loggersWithTelemetry,
LogTaskInputs = binaryLoggers.Length != 0,
};

Expand Down
17 changes: 11 additions & 6 deletions src/Cli/dotnet/Commands/Test/MTP/MSBuildUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using Microsoft.Build.Evaluation;
using Microsoft.Build.Evaluation.Context;
using Microsoft.Build.Execution;
using Microsoft.Build.Framework;
using Microsoft.DotNet.Cli.Commands.Restore;
using Microsoft.DotNet.Cli.Commands.Run;
using Microsoft.DotNet.Cli.Extensions;
Expand Down Expand Up @@ -37,9 +38,11 @@ public static (IEnumerable<ParallelizableTestModuleGroupWithSequentialInnerModul

var msbuildArgs = MSBuildArgs.AnalyzeMSBuildArguments(buildOptions.MSBuildArgs, CommonOptions.PropertiesOption, CommonOptions.RestorePropertiesOption, CommonOptions.MSBuildTargetOption(), CommonOptions.VerbosityOption());

using var collection = new ProjectCollection(globalProperties: CommonRunHelpers.GetGlobalPropertiesFromArgs(msbuildArgs), loggers: logger is null ? null : [logger], toolsetDefinitionLocations: ToolsetDefinitionLocations.Default);
// Include telemetry logger for evaluation and capture it for reuse in builds
var (loggers, telemetryCentralLogger) = ProjectInstanceExtensions.CreateLoggersWithTelemetry(logger is null ? null : [logger]);
using var collection = new ProjectCollection(globalProperties: CommonRunHelpers.GetGlobalPropertiesFromArgs(msbuildArgs), loggers: loggers, toolsetDefinitionLocations: ToolsetDefinitionLocations.Default);
var evaluationContext = EvaluationContext.Create(EvaluationContext.SharingPolicy.Shared);
ConcurrentBag<ParallelizableTestModuleGroupWithSequentialInnerModules> projects = GetProjectsProperties(collection, evaluationContext, solutionModel.SolutionProjects.Select(p => Path.Combine(rootDirectory, p.FilePath)), buildOptions);
ConcurrentBag<ParallelizableTestModuleGroupWithSequentialInnerModules> projects = GetProjectsProperties(collection, evaluationContext, solutionModel.SolutionProjects.Select(p => Path.Combine(rootDirectory, p.FilePath)), buildOptions, telemetryCentralLogger);
logger?.ReallyShutdown();
collection.UnloadAllProjects();

Expand All @@ -59,9 +62,11 @@ public static (IEnumerable<ParallelizableTestModuleGroupWithSequentialInnerModul

var msbuildArgs = MSBuildArgs.AnalyzeMSBuildArguments(buildOptions.MSBuildArgs, CommonOptions.PropertiesOption, CommonOptions.RestorePropertiesOption, CommonOptions.MSBuildTargetOption(), CommonOptions.VerbosityOption());

using var collection = new ProjectCollection(globalProperties: CommonRunHelpers.GetGlobalPropertiesFromArgs(msbuildArgs), logger is null ? null : [logger], toolsetDefinitionLocations: ToolsetDefinitionLocations.Default);
// Include telemetry logger for evaluation and capture it for reuse in builds
var (loggers, telemetryCentralLogger) = ProjectInstanceExtensions.CreateLoggersWithTelemetry(logger is null ? null : [logger]);
using var collection = new ProjectCollection(globalProperties: CommonRunHelpers.GetGlobalPropertiesFromArgs(msbuildArgs), loggers, toolsetDefinitionLocations: ToolsetDefinitionLocations.Default);
var evaluationContext = EvaluationContext.Create(EvaluationContext.SharingPolicy.Shared);
IEnumerable<ParallelizableTestModuleGroupWithSequentialInnerModules> projects = SolutionAndProjectUtility.GetProjectProperties(projectFilePath, collection, evaluationContext, buildOptions);
IEnumerable<ParallelizableTestModuleGroupWithSequentialInnerModules> projects = SolutionAndProjectUtility.GetProjectProperties(projectFilePath, collection, evaluationContext, buildOptions, telemetryCentralLogger);
logger?.ReallyShutdown();
collection.UnloadAllProjects();
return (projects, isBuiltOrRestored);
Expand Down Expand Up @@ -130,7 +135,7 @@ private static bool BuildOrRestoreProjectOrSolution(string filePath, BuildOption
return result == (int)BuildResultCode.Success;
}

private static ConcurrentBag<ParallelizableTestModuleGroupWithSequentialInnerModules> GetProjectsProperties(ProjectCollection projectCollection, EvaluationContext evaluationContext, IEnumerable<string> projects, BuildOptions buildOptions)
private static ConcurrentBag<ParallelizableTestModuleGroupWithSequentialInnerModules> GetProjectsProperties(ProjectCollection projectCollection, EvaluationContext evaluationContext, IEnumerable<string> projects, BuildOptions buildOptions, ILogger? telemetryCentralLogger)
{
var allProjects = new ConcurrentBag<ParallelizableTestModuleGroupWithSequentialInnerModules>();

Expand All @@ -141,7 +146,7 @@ private static ConcurrentBag<ParallelizableTestModuleGroupWithSequentialInnerMod
new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount },
(project) =>
{
IEnumerable<ParallelizableTestModuleGroupWithSequentialInnerModules> projectsMetadata = SolutionAndProjectUtility.GetProjectProperties(project, projectCollection, evaluationContext, buildOptions);
IEnumerable<ParallelizableTestModuleGroupWithSequentialInnerModules> projectsMetadata = SolutionAndProjectUtility.GetProjectProperties(project, projectCollection, evaluationContext, buildOptions, telemetryCentralLogger);
foreach (var projectMetadata in projectsMetadata)
{
allProjects.Add(projectMetadata);
Expand Down
Loading