Skip to content

Commit f9748c8

Browse files
authored
Remove interactive special case for logger verbosity in dotnet run (#47389)
1 parent 460bff1 commit f9748c8

File tree

62 files changed

+305
-209
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+305
-209
lines changed

src/Cli/Microsoft.DotNet.Cli.Utils/MSBuildArgs.cs

Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,12 @@ namespace Microsoft.DotNet.Cli.Utils;
1212
/// </summary>
1313
public sealed class MSBuildArgs
1414
{
15-
private MSBuildArgs(ReadOnlyDictionary<string, string>? properties, ReadOnlyDictionary<string, string>? restoreProperties, string[]? targets, string[]? otherMSBuildArgs)
15+
private MSBuildArgs(ReadOnlyDictionary<string, string>? properties, ReadOnlyDictionary<string, string>? restoreProperties, string[]? targets, VerbosityOptions? verbosity, string[]? otherMSBuildArgs)
1616
{
1717
GlobalProperties = properties;
1818
RestoreGlobalProperties = restoreProperties;
1919
RequestedTargets = targets;
20+
Verbosity = verbosity;
2021
OtherMSBuildArgs = otherMSBuildArgs is not null
2122
? [.. otherMSBuildArgs]
2223
: new List<string>();
@@ -36,9 +37,11 @@ private MSBuildArgs(ReadOnlyDictionary<string, string>? properties, ReadOnlyDict
3637
/// The ordered list of targets that should be passed to MSBuild.
3738
/// </summary>
3839
public string[]? RequestedTargets { get; }
40+
public VerbosityOptions? Verbosity { get; }
3941

4042
/// <summary>
41-
/// All non <c>-p</c> and <c>-rp</c> arguments that should be passed to MSBuild.
43+
/// All other arguments that aren't already explicitly modeled by this structure.
44+
/// The main categories of these today are logger configurations
4245
/// </summary>
4346
public List<string> OtherMSBuildArgs { get; }
4447

@@ -64,26 +67,34 @@ public static MSBuildArgs AnalyzeMSBuildArguments(IEnumerable<string> forwardedA
6467
var globalProperties = parseResult.GetResult("--property") is OptionResult propResult ? propResult.GetValueOrDefault<ReadOnlyDictionary<string, string>?>() : null;
6568
var restoreProperties = parseResult.GetResult("--restoreProperty") is OptionResult restoreResult ? restoreResult.GetValueOrDefault<ReadOnlyDictionary<string, string>?>() : null;
6669
var requestedTargets = parseResult.GetResult("--target") is OptionResult targetResult ? targetResult.GetValueOrDefault<string[]?>() : null;
70+
var verbosity = parseResult.GetResult("--verbosity") is OptionResult verbosityResult
71+
? verbosityResult.GetValueOrDefault<VerbosityOptions?>()
72+
: null;
6773
var otherMSBuildArgs = parseResult.UnmatchedTokens.ToArray();
6874
return new MSBuildArgs(
6975
properties: globalProperties,
7076
restoreProperties: restoreProperties,
7177
targets: requestedTargets,
72-
otherMSBuildArgs: otherMSBuildArgs);
78+
otherMSBuildArgs: otherMSBuildArgs,
79+
verbosity: verbosity);
7380
}
7481

7582

7683
public static MSBuildArgs FromProperties(ReadOnlyDictionary<string, string>? properties)
7784
{
78-
return new MSBuildArgs(properties, null, null, null);
85+
return new MSBuildArgs(properties, null, null, null, null);
7986
}
8087

8188
public static MSBuildArgs FromOtherArgs(params ReadOnlySpan<string> args)
8289
{
83-
return new MSBuildArgs(null, null, null, args.ToArray());
90+
return new MSBuildArgs(null, null, null, null, args.ToArray());
91+
}
92+
public static MSBuildArgs FromVerbosity(VerbosityOptions verbosity)
93+
{
94+
return new MSBuildArgs(null, null, null, verbosity, null);
8495
}
8596

86-
public static readonly MSBuildArgs ForHelp = new(null, null, null, ["--help"]);
97+
public static readonly MSBuildArgs ForHelp = new(null, null, null, null, ["--help"]);
8798

8899
/// <summary>
89100
/// Completely replaces the MSBuild arguments with the provided <paramref name="newArgs"/>.
@@ -94,7 +105,8 @@ public MSBuildArgs CloneWithExplicitArgs(string[] newArgs)
94105
properties: GlobalProperties,
95106
restoreProperties: RestoreGlobalProperties,
96107
targets: RequestedTargets,
97-
otherMSBuildArgs: newArgs);
108+
otherMSBuildArgs: newArgs,
109+
verbosity: Verbosity);
98110
}
99111

100112
/// <summary>
@@ -105,60 +117,71 @@ public MSBuildArgs CloneWithAdditionalArgs(params string[] additionalArgs)
105117
if (additionalArgs is null || additionalArgs.Length == 0)
106118
{
107119
// If there are no additional args, we can just return the current instance.
108-
return new MSBuildArgs(GlobalProperties, RestoreGlobalProperties, RequestedTargets, OtherMSBuildArgs.ToArray());
120+
return new MSBuildArgs(GlobalProperties, RestoreGlobalProperties, RequestedTargets, Verbosity, OtherMSBuildArgs.ToArray());
109121
}
110122

111-
return new MSBuildArgs(GlobalProperties, RestoreGlobalProperties, RequestedTargets, [.. OtherMSBuildArgs, .. additionalArgs]);
123+
return new MSBuildArgs(GlobalProperties, RestoreGlobalProperties, RequestedTargets, Verbosity, [.. OtherMSBuildArgs, .. additionalArgs]);
112124
}
113125

114126
public MSBuildArgs CloneWithAdditionalRestoreProperties(ReadOnlyDictionary<string, string>? additionalRestoreProperties)
115127
{
116128
if (additionalRestoreProperties is null || additionalRestoreProperties.Count == 0)
117129
{
118130
// If there are no additional restore properties, we can just return the current instance.
119-
return new MSBuildArgs(GlobalProperties, RestoreGlobalProperties, RequestedTargets, OtherMSBuildArgs.ToArray());
131+
return new MSBuildArgs(GlobalProperties, RestoreGlobalProperties, RequestedTargets, Verbosity, OtherMSBuildArgs.ToArray());
120132
}
121133
if (RestoreGlobalProperties is null)
122134
{
123-
return new MSBuildArgs(GlobalProperties, additionalRestoreProperties, RequestedTargets, OtherMSBuildArgs.ToArray());
135+
return new MSBuildArgs(GlobalProperties, additionalRestoreProperties, RequestedTargets, Verbosity, OtherMSBuildArgs.ToArray());
124136
}
125137

126138
var newRestoreProperties = new Dictionary<string, string>(RestoreGlobalProperties, StringComparer.OrdinalIgnoreCase);
127139
foreach (var kvp in additionalRestoreProperties)
128140
{
129141
newRestoreProperties[kvp.Key] = kvp.Value;
130142
}
131-
return new MSBuildArgs(GlobalProperties, new(newRestoreProperties), RequestedTargets, OtherMSBuildArgs.ToArray());
143+
return new MSBuildArgs(GlobalProperties, new(newRestoreProperties), RequestedTargets, Verbosity, OtherMSBuildArgs.ToArray());
132144
}
133145

134146
public MSBuildArgs CloneWithAdditionalProperties(ReadOnlyDictionary<string, string>? additionalProperties)
135147
{
136148
if (additionalProperties is null || additionalProperties.Count == 0)
137149
{
138150
// If there are no additional properties, we can just return the current instance.
139-
return new MSBuildArgs(GlobalProperties, RestoreGlobalProperties, RequestedTargets, OtherMSBuildArgs.ToArray());
151+
return new MSBuildArgs(GlobalProperties, RestoreGlobalProperties, RequestedTargets, Verbosity, OtherMSBuildArgs.ToArray());
140152
}
141153
if (GlobalProperties is null)
142154
{
143-
return new MSBuildArgs(additionalProperties, RestoreGlobalProperties, RequestedTargets, OtherMSBuildArgs.ToArray());
155+
return new MSBuildArgs(additionalProperties, RestoreGlobalProperties, RequestedTargets, Verbosity, OtherMSBuildArgs.ToArray());
144156
}
145157

146158
var newProperties = new Dictionary<string, string>(GlobalProperties, StringComparer.OrdinalIgnoreCase);
147159
foreach (var kvp in additionalProperties)
148160
{
149161
newProperties[kvp.Key] = kvp.Value;
150162
}
151-
return new MSBuildArgs(new(newProperties), RestoreGlobalProperties, RequestedTargets, OtherMSBuildArgs.ToArray());
163+
return new MSBuildArgs(new(newProperties), RestoreGlobalProperties, RequestedTargets, Verbosity, OtherMSBuildArgs.ToArray());
152164
}
153165

154166
public MSBuildArgs CloneWithAdditionalTarget(string additionalTarget)
155167
{
156168
string[] newTargets = RequestedTargets is not null
157169
? [.. RequestedTargets, additionalTarget]
158170
: [ additionalTarget ];
159-
return new MSBuildArgs(GlobalProperties, RestoreGlobalProperties, newTargets, OtherMSBuildArgs.ToArray());
171+
return new MSBuildArgs(GlobalProperties, RestoreGlobalProperties, newTargets, Verbosity, OtherMSBuildArgs.ToArray());
160172
}
161173

174+
public MSBuildArgs CloneWithVerbosity(VerbosityOptions newVerbosity)
175+
{
176+
return new MSBuildArgs(GlobalProperties, RestoreGlobalProperties, RequestedTargets, newVerbosity, OtherMSBuildArgs.ToArray());
177+
}
178+
179+
/// <summary>
180+
/// This mutates the <see cref="MSBuildArgs"/> instance, applying all of the current global properties
181+
/// to the restore properties dictionary. This is necessary because MSBuild's processing of restore properties
182+
/// is _exclusive_ - as soon as it sees a <c>-rp</c> flag, it will not apply any <c>-p</c> flags
183+
/// to the implicit restore operation.
184+
/// </summary>
162185
public void ApplyPropertiesToRestore()
163186
{
164187
if (RestoreGlobalProperties is null)

src/Cli/Microsoft.DotNet.Cli.Utils/MSBuildForwardingAppWithoutLogging.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public static string MSBuildVersion
4141

4242
private readonly Dictionary<string, string> _msbuildRequiredEnvironmentVariables = GetMSBuildRequiredEnvironmentVariables();
4343

44-
private readonly List<string> _msbuildRequiredParameters = [ "-maxcpucount", "-verbosity:m" ];
44+
private readonly List<string> _msbuildRequiredParameters = [ "-maxcpucount", "--verbosity:m" ];
4545

4646
public MSBuildForwardingAppWithoutLogging(MSBuildArgs msbuildArgs, string? msbuildPath = null, bool includeLogo = false, bool isRestoring = true)
4747
{
@@ -100,6 +100,7 @@ private string[] EmitMSBuildArgs(MSBuildArgs msbuildArgs) => [
100100
.. msbuildArgs.GlobalProperties?.Select(kvp => EmitProperty(kvp)) ?? [],
101101
.. msbuildArgs.RestoreGlobalProperties?.Select(kvp => EmitProperty(kvp, "restoreProperty")) ?? [],
102102
.. msbuildArgs.RequestedTargets?.Select(target => $"--target:{target}") ?? [],
103+
.. msbuildArgs.Verbosity is not null ? new string[1] { $"--verbosity:{msbuildArgs.Verbosity}" } : [],
103104
.. msbuildArgs.OtherMSBuildArgs
104105
];
105106

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
namespace Microsoft.DotNet.Cli.Utils;
2+
3+
/// <summary>
4+
/// Represents the desired verbosity level for command output.
5+
/// Maps mostly to MSBuild's verbosity levels.
6+
/// The odd naming is because we're currently leaning entirely on System.CommandLine's
7+
/// default enum parsing.
8+
/// </summary>
9+
public enum VerbosityOptions
10+
{
11+
quiet,
12+
q,
13+
minimal,
14+
m,
15+
normal,
16+
n,
17+
detailed,
18+
d,
19+
diagnostic,
20+
diag
21+
}

src/Cli/dotnet/CommandFactory/CommandResolution/ProjectToolsCommandResolver.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,7 @@ internal void GenerateDepsJsonFile(
385385
string? stdOut;
386386
string? stdErr;
387387

388-
var msbuildArgs = MSBuildArgs.AnalyzeMSBuildArguments([..args], CommonOptions.PropertiesOption, CommonOptions.RestorePropertiesOption, BuildCommandParser.TargetOption);
388+
var msbuildArgs = MSBuildArgs.AnalyzeMSBuildArguments([..args], CommonOptions.PropertiesOption, CommonOptions.RestorePropertiesOption, BuildCommandParser.TargetOption, BuildCommandParser.VerbosityOption);
389389
var forwardingAppWithoutLogging = new MSBuildForwardingAppWithoutLogging(msbuildArgs, msBuildExePath);
390390
if (forwardingAppWithoutLogging.ExecuteMSBuildOutOfProc)
391391
{

src/Cli/dotnet/Commands/Build/BuildCommand.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public static CommandBase FromParseResult(ParseResult parseResult, string? msbui
4343
noRestore: noRestore,
4444
msbuildPath: msbuildPath
4545
),
46-
[CommonOptions.PropertiesOption, CommonOptions.RestorePropertiesOption, BuildCommandParser.TargetOption],
46+
[CommonOptions.PropertiesOption, CommonOptions.RestorePropertiesOption, BuildCommandParser.TargetOption, BuildCommandParser.VerbosityOption],
4747
parseResult,
4848
msbuildPath
4949
);

src/Cli/dotnet/Commands/Build/BuildCommandParser.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ internal static class BuildCommandParser
5858
/// </summary>
5959
public static readonly Option<string[]?> TargetOption = CommonOptions.MSBuildTargetOption();
6060

61-
public static readonly Option<VerbosityOptions?> VerbosityOption = CommonOptions.VerbosityOption();
61+
public static readonly Option<Utils.VerbosityOptions?> VerbosityOption = CommonOptions.VerbosityOption();
6262

6363
private static readonly Command Command = ConstructCommand();
6464

src/Cli/dotnet/Commands/Clean/CleanCommand.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public static CommandBase FromParseResult(ParseResult result, string? msbuildPat
3434
NoBuildMarkers = true,
3535
},
3636
static (msbuildArgs, msbuildPath) => new CleanCommand(msbuildArgs, msbuildPath),
37-
[ CommonOptions.PropertiesOption, CommonOptions.RestorePropertiesOption, CleanCommandParser.TargetOption ],
37+
[ CommonOptions.PropertiesOption, CommonOptions.RestorePropertiesOption, CleanCommandParser.TargetOption, CleanCommandParser.VerbosityOption ],
3838
result,
3939
msbuildPath
4040
);

src/Cli/dotnet/Commands/Clean/CleanCommandParser.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ internal static class CleanCommandParser
3434

3535
public static readonly Option<string[]> TargetOption = CommonOptions.RequiredMSBuildTargetOption("Clean");
3636

37-
public static readonly Option<VerbosityOptions> VerbosityOption = CommonOptions.VerbosityOption(VerbosityOptions.normal);
37+
public static readonly Option<Utils.VerbosityOptions> VerbosityOption = CommonOptions.VerbosityOption(Utils.VerbosityOptions.normal);
3838

3939

4040
private static readonly Command Command = ConstructCommand();

src/Cli/dotnet/Commands/MSBuild/MSBuildCommand.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ namespace Microsoft.DotNet.Cli.Commands.MSBuild;
1010
public class MSBuildCommand(
1111
IEnumerable<string> msbuildArgs,
1212
string? msbuildPath = null
13-
) : MSBuildForwardingApp(MSBuildArgs.AnalyzeMSBuildArguments([..msbuildArgs], CommonOptions.PropertiesOption, CommonOptions.RestorePropertiesOption, MSBuildCommandParser.TargetOption), msbuildPath, includeLogo: true)
13+
) : MSBuildForwardingApp(MSBuildArgs.AnalyzeMSBuildArguments([..msbuildArgs], CommonOptions.PropertiesOption, CommonOptions.RestorePropertiesOption, MSBuildCommandParser.TargetOption, CommonOptions.VerbosityOption()), msbuildPath, includeLogo: true)
1414
{
1515
public static MSBuildCommand FromArgs(string[] args, string? msbuildPath = null)
1616
{

src/Cli/dotnet/Commands/MSBuild/MSBuildForwardingApp.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ private static MSBuildArgs ConcatTelemetryLogger(MSBuildArgs msbuildArgs)
3838
/// Mostly intended for quick/one-shot usage - most 'core' SDK commands should do more hands-on parsing.
3939
/// </summary>
4040
public MSBuildForwardingApp(IEnumerable<string> rawMSBuildArgs, string? msbuildPath = null) : this(
41-
MSBuildArgs.AnalyzeMSBuildArguments(rawMSBuildArgs.ToArray(), CommonOptions.PropertiesOption, CommonOptions.RestorePropertiesOption, CommonOptions.MSBuildTargetOption()),
41+
MSBuildArgs.AnalyzeMSBuildArguments(rawMSBuildArgs.ToArray(), CommonOptions.PropertiesOption, CommonOptions.RestorePropertiesOption, CommonOptions.MSBuildTargetOption(), CommonOptions.VerbosityOption()),
4242
msbuildPath)
4343
{
4444
}

0 commit comments

Comments
 (0)