Skip to content

Commit 7ca819d

Browse files
baronfelChet Husk
andauthored
Ensure that --nologo adheres to DOTNET_NOLOGO if present (#51462)
Co-authored-by: Chet Husk <[email protected]>
1 parent 8bd3eb7 commit 7ca819d

File tree

65 files changed

+502
-456
lines changed

Some content is hidden

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

65 files changed

+502
-456
lines changed

.editorconfig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -511,11 +511,11 @@ dotnet_diagnostic.IDE0040.severity = warning
511511
insert_final_newline = false
512512

513513
# Verify settings
514-
[*.{received,verified}.{txt,xml,json}]
514+
[*.{received,verified}.{txt,xml,json,sh,zsh,nu,fish,ps1}]
515515
charset = "utf-8-bom"
516516
end_of_line = lf
517517
indent_size = unset
518518
indent_style = unset
519519
insert_final_newline = false
520520
tab_width = unset
521-
trim_trailing_whitespace = false
521+
trim_trailing_whitespace = false

.gitattributes

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,7 @@
6767
*.verified.txt text eol=lf working-tree-encoding=UTF-8
6868
*.verified.xml text eol=lf working-tree-encoding=UTF-8
6969
*.verified.json text eol=lf working-tree-encoding=UTF-8
70+
*.verified.sh text eol=lf working-tree-encoding=UTF-8
71+
*.verified.zsh text eol=lf working-tree-encoding=UTF-8
72+
*.verified.nu text eol=lf working-tree-encoding=UTF-8
73+
*.verified.fish text eol=lf working-tree-encoding=UTF-8

.vscode/settings.json

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
11
{
22
"dotnet.testWindow.disableAutoDiscovery": true,
3-
"dotnet.defaultSolution": "sdk.slnx"
3+
"dotnet.testWindow.disableBuildOnRun": true,
4+
"dotnet.defaultSolution": "cli.slnf",
5+
"files.associations": {
6+
"*.slnf": "json",
7+
"*.props": "xml",
8+
"*.targets": "xml",
9+
"*.*proj": "xml"
10+
}
411
}

cli.slnf

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"solution": {
3+
"path": "sdk.slnx",
4+
"projects": [
5+
"src\\BuiltInTools\\dotnet-watch\\dotnet-watch.csproj",
6+
"src\\Cli\\dotnet\\dotnet.csproj",
7+
"src\\Cli\\Microsoft.DotNet.Cli.Utils\\Microsoft.DotNet.Cli.Utils.csproj",
8+
"test\\dotnet-new.IntegrationTests\\dotnet-new.IntegrationTests.csproj",
9+
"test\\dotnet-watch.Tests\\dotnet-watch.Tests.csproj",
10+
"test\\dotnet.Tests\\dotnet.Tests.csproj",
11+
"test\\Microsoft.DotNet.Cli.Utils.Tests\\Microsoft.DotNet.Cli.Utils.Tests.csproj",
12+
"test\\Microsoft.NET.TestFramework\\Microsoft.NET.TestFramework.csproj"
13+
]
14+
}
15+
}

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4+
using System.Diagnostics.CodeAnalysis;
5+
46
namespace Microsoft.DotNet.Cli.Utils;
57

68
public static class Env
@@ -21,6 +23,9 @@ public static class Env
2123
public static bool GetEnvironmentVariableAsBool(string name, bool defaultValue = false) =>
2224
s_environment.GetEnvironmentVariableAsBool(name, defaultValue);
2325

26+
public static bool TryGetEnvironmentVariableAsBool(string name, [NotNullWhen(true)] out bool value) =>
27+
s_environment.TryGetEnvironmentVariableAsBool(name, out value);
28+
2429
public static int? GetEnvironmentVariableAsNullableInt(string name) =>
2530
s_environment.GetEnvironmentVariableAsNullableInt(name);
2631

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

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4+
using System.Diagnostics.CodeAnalysis;
45
using Microsoft.DotNet.Cli.Utils.Extensions;
56

67
namespace Microsoft.DotNet.Cli.Utils;
@@ -136,6 +137,12 @@ public bool GetEnvironmentVariableAsBool(string name, bool defaultValue)
136137
return Environment.GetEnvironmentVariable(variable, target);
137138
}
138139

140+
public bool TryGetEnvironmentVariable(string name, [NotNullWhen(true)] out string? value)
141+
{
142+
value = Environment.GetEnvironmentVariable(name);
143+
return value != null;
144+
}
145+
139146
public void SetEnvironmentVariable(string variable, string value, EnvironmentVariableTarget target)
140147
{
141148
Environment.SetEnvironmentVariable(variable, value, target);
@@ -150,4 +157,57 @@ public void SetEnvironmentVariable(string variable, string value, EnvironmentVar
150157

151158
return null;
152159
}
160+
161+
public bool TryGetEnvironmentVariableAsBool(string name, [NotNullWhen(true)] out bool value)
162+
{
163+
if (TryGetEnvironmentVariable(name, out string? strValue) &&
164+
(bool.TryParse(strValue, out bool boolValue)
165+
|| TryParseNonBoolConstantStringAsBool(strValue, out boolValue)))
166+
{
167+
value = boolValue;
168+
return true;
169+
}
170+
else
171+
{
172+
value = false;
173+
return false;
174+
}
175+
}
176+
177+
/// <summary>
178+
/// Parses non-boolean constant strings like "1", "0", "yes", "no", "on", "off" as boolean values.
179+
/// </summary>
180+
private static bool TryParseNonBoolConstantStringAsBool(string? strValue, out bool value)
181+
{
182+
switch (strValue?.ToLowerInvariant())
183+
{
184+
case "1":
185+
case "yes":
186+
case "on":
187+
value = true;
188+
return true;
189+
case "0":
190+
case "no":
191+
case "off":
192+
value = false;
193+
return true;
194+
default:
195+
value = false;
196+
return false;
197+
}
198+
}
199+
200+
public bool TryGetEnvironmentVariableAsInt(string name, [NotNullWhen(true)] out int value)
201+
{
202+
if (TryGetEnvironmentVariable(name, out string? strValue) && int.TryParse(strValue, out int intValue))
203+
{
204+
value = intValue;
205+
return true;
206+
}
207+
else
208+
{
209+
value = -1;
210+
return false;
211+
}
212+
}
153213
}

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33

44
namespace Microsoft.DotNet.Cli.Utils;
55

6+
using System.Diagnostics.CodeAnalysis;
7+
8+
69
public interface IEnvironmentProvider
710
{
811
IEnumerable<string> ExecutableExtensions { get; }
@@ -19,6 +22,10 @@ public interface IEnvironmentProvider
1922

2023
string? GetEnvironmentVariable(string name);
2124

25+
bool TryGetEnvironmentVariable(string name, [NotNullWhen(true)] out string? value);
26+
bool TryGetEnvironmentVariableAsBool(string name, [NotNullWhen(true)] out bool value);
27+
bool TryGetEnvironmentVariableAsInt(string name, [NotNullWhen(true)] out int value);
28+
2229
string? GetEnvironmentVariable(string variable, EnvironmentVariableTarget target);
2330

2431
void SetEnvironmentVariable(string variable, string value, EnvironmentVariableTarget target);

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

Lines changed: 61 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ private MSBuildArgs(
2121
string[]? getTargetResult,
2222
string[]? getResultOutputFile,
2323
VerbosityOptions? verbosity,
24-
string[]? otherMSBuildArgs)
24+
bool noLogo,
25+
string[]? otherMSBuildArgs
26+
)
2527
{
2628
GlobalProperties = properties;
2729
RestoreGlobalProperties = restoreProperties;
@@ -31,6 +33,7 @@ private MSBuildArgs(
3133
GetTargetResult = getTargetResult;
3234
GetResultOutputFile = getResultOutputFile;
3335
Verbosity = verbosity;
36+
NoLogo = noLogo;
3437
OtherMSBuildArgs = otherMSBuildArgs is not null
3538
? [.. otherMSBuildArgs]
3639
: new List<string>();
@@ -51,16 +54,33 @@ private MSBuildArgs(
5154
/// </summary>
5255
public string[]? RequestedTargets { get; }
5356

57+
/// <summary>
58+
/// If specified, the list of MSBuild Property names to retrieve and report directly for this build of a single project.
59+
/// </summary>
5460
public string[]? GetProperty { get; }
5561

62+
/// <summary>
63+
/// If specified, the list of MSBuild Item names to retrieve and report directly for this build of a single project.
64+
/// </summary>
5665
public string[]? GetItem { get; }
5766

67+
/// <summary>
68+
/// If specified, the list of MSBuild Target Output/Return Items to retrieve and report directly for this build of a single project.
69+
/// </summary>
5870
public string[]? GetTargetResult { get; }
5971

72+
/// <summary>
73+
/// If specified, the list of output files to which to write --getProperty, --getItem, and --getTargetResult outputs.
74+
/// </summary>
6075
public string[]? GetResultOutputFile { get; }
6176

6277
public VerbosityOptions? Verbosity { get; }
6378

79+
/// <summary>
80+
/// Whether or not the MSBuild product header text should be emitted at the start of this build
81+
/// </summary>
82+
public bool NoLogo { get; }
83+
6484
/// <summary>
6585
/// All other arguments that aren't already explicitly modeled by this structure.
6686
/// The main categories of these today are logger configurations
@@ -89,16 +109,15 @@ public static MSBuildArgs AnalyzeMSBuildArguments(IEnumerable<string> forwardedA
89109
}
90110

91111
var parseResult = fakeCommand.Parse([.. forwardedAndUserFacingArgs], _analysisParsingConfiguration);
92-
var globalProperties = parseResult.GetResult("--property") is OptionResult propResult ? propResult.GetValueOrDefault<ReadOnlyDictionary<string, string>?>() : null;
93-
var restoreProperties = parseResult.GetResult("--restoreProperty") is OptionResult restoreResult ? restoreResult.GetValueOrDefault<ReadOnlyDictionary<string, string>?>() : null;
94-
var requestedTargets = parseResult.GetResult("--target") is OptionResult targetResult ? targetResult.GetValueOrDefault<string[]?>() : null;
112+
var globalProperties = TryGetValue<ReadOnlyDictionary<string, string>?>("--property");
113+
var restoreProperties = TryGetValue<ReadOnlyDictionary<string, string>?>("--restoreProperty");
114+
var requestedTargets = TryGetValue<string[]?>("--target");
95115
var getProperty = TryGetValue<string[]>("--getProperty");
96116
var getItem = TryGetValue<string[]?>("--getItem");
97117
var getTargetResult = TryGetValue<string[]?>("--getTargetResult");
98118
var getResultOutputFile = TryGetValue<string[]?>("--getResultOutputFile");
99-
var verbosity = parseResult.GetResult("--verbosity") is OptionResult verbosityResult
100-
? verbosityResult.GetValueOrDefault<VerbosityOptions?>()
101-
: null;
119+
var verbosity = TryGetValue<VerbosityOptions?>("--verbosity");
120+
var nologo = TryGetValue<bool?>("--no-logo") ?? true; // Default to nologo if not specified
102121
var otherMSBuildArgs = parseResult.UnmatchedTokens.ToArray();
103122
return new MSBuildArgs(
104123
properties: globalProperties,
@@ -109,8 +128,12 @@ public static MSBuildArgs AnalyzeMSBuildArguments(IEnumerable<string> forwardedA
109128
getTargetResult: getTargetResult,
110129
getResultOutputFile: getResultOutputFile,
111130
otherMSBuildArgs: otherMSBuildArgs,
112-
verbosity: verbosity);
131+
verbosity: verbosity,
132+
noLogo: nologo);
113133

134+
/// We can't use <see cref="ParseResult.GetResult(string)"/> to check if the names of the options we care
135+
/// about were specified, because if they weren't specified it throws.
136+
/// So we first check if the option was specified, and only then get its value.
114137
T? TryGetValue<T>(string name)
115138
{
116139
return options.Any(o => o.Name == name) ? parseResult.GetValue<T>(name) : default;
@@ -120,19 +143,19 @@ public static MSBuildArgs AnalyzeMSBuildArguments(IEnumerable<string> forwardedA
120143

121144
public static MSBuildArgs FromProperties(ReadOnlyDictionary<string, string>? properties)
122145
{
123-
return new MSBuildArgs(properties, null, null, null, null, null, null, null, null);
146+
return new MSBuildArgs(properties, null, null, null, null, null, null, null, noLogo: false, null);
124147
}
125148

126149
public static MSBuildArgs FromOtherArgs(params ReadOnlySpan<string> args)
127150
{
128-
return new MSBuildArgs(null, null, null, null, null, null, null, null, args.ToArray());
151+
return new MSBuildArgs(null, null, null, null, null, null, null, null, noLogo: false, args.ToArray());
129152
}
130153
public static MSBuildArgs FromVerbosity(VerbosityOptions verbosity)
131154
{
132-
return new MSBuildArgs(null, null, null, null, null, null, null, verbosity, null);
155+
return new MSBuildArgs(null, null, null, null, null, null, null, verbosity, noLogo: false, null);
133156
}
134157

135-
public static readonly MSBuildArgs ForHelp = new(null, null, null, null, null, null, null, null, ["--help"]);
158+
public static readonly MSBuildArgs ForHelp = new(null, null, null, null, null, null, null, null, noLogo: true, ["--help"]);
136159

137160
/// <summary>
138161
/// Completely replaces the MSBuild arguments with the provided <paramref name="newArgs"/>.
@@ -148,6 +171,7 @@ public MSBuildArgs CloneWithExplicitArgs(string[] newArgs)
148171
getTargetResult: GetTargetResult,
149172
getResultOutputFile: GetResultOutputFile,
150173
otherMSBuildArgs: newArgs,
174+
noLogo: NoLogo,
151175
verbosity: Verbosity);
152176
}
153177

@@ -168,6 +192,7 @@ public MSBuildArgs CloneWithAdditionalArgs(params string[] additionalArgs)
168192
GetTargetResult,
169193
GetResultOutputFile,
170194
Verbosity,
195+
NoLogo,
171196
OtherMSBuildArgs.ToArray());
172197
}
173198

@@ -180,6 +205,7 @@ public MSBuildArgs CloneWithAdditionalArgs(params string[] additionalArgs)
180205
GetTargetResult,
181206
GetResultOutputFile,
182207
Verbosity,
208+
NoLogo,
183209
[.. OtherMSBuildArgs, .. additionalArgs]);
184210
}
185211

@@ -197,6 +223,7 @@ public MSBuildArgs CloneWithAdditionalRestoreProperties(ReadOnlyDictionary<strin
197223
GetTargetResult,
198224
GetResultOutputFile,
199225
Verbosity,
226+
NoLogo,
200227
OtherMSBuildArgs.ToArray());
201228
}
202229
if (RestoreGlobalProperties is null)
@@ -210,6 +237,7 @@ public MSBuildArgs CloneWithAdditionalRestoreProperties(ReadOnlyDictionary<strin
210237
GetTargetResult,
211238
GetResultOutputFile,
212239
Verbosity,
240+
NoLogo,
213241
OtherMSBuildArgs.ToArray());
214242
}
215243

@@ -227,6 +255,7 @@ public MSBuildArgs CloneWithAdditionalRestoreProperties(ReadOnlyDictionary<strin
227255
GetTargetResult,
228256
GetResultOutputFile,
229257
Verbosity,
258+
NoLogo,
230259
OtherMSBuildArgs.ToArray());
231260
}
232261

@@ -244,6 +273,7 @@ public MSBuildArgs CloneWithAdditionalProperties(ReadOnlyDictionary<string, stri
244273
GetTargetResult,
245274
GetResultOutputFile,
246275
Verbosity,
276+
NoLogo,
247277
OtherMSBuildArgs.ToArray());
248278
}
249279
if (GlobalProperties is null)
@@ -257,6 +287,7 @@ public MSBuildArgs CloneWithAdditionalProperties(ReadOnlyDictionary<string, stri
257287
GetTargetResult,
258288
GetResultOutputFile,
259289
Verbosity,
290+
NoLogo,
260291
OtherMSBuildArgs.ToArray());
261292
}
262293

@@ -274,6 +305,7 @@ public MSBuildArgs CloneWithAdditionalProperties(ReadOnlyDictionary<string, stri
274305
GetTargetResult,
275306
GetResultOutputFile,
276307
Verbosity,
308+
NoLogo,
277309
OtherMSBuildArgs.ToArray());
278310
}
279311

@@ -291,6 +323,7 @@ public MSBuildArgs CloneWithAdditionalTargets(params ReadOnlySpan<string> additi
291323
GetTargetResult,
292324
GetResultOutputFile,
293325
Verbosity,
326+
NoLogo,
294327
OtherMSBuildArgs.ToArray());
295328
}
296329

@@ -305,6 +338,22 @@ public MSBuildArgs CloneWithVerbosity(VerbosityOptions newVerbosity)
305338
GetTargetResult,
306339
GetResultOutputFile,
307340
newVerbosity,
341+
NoLogo,
342+
OtherMSBuildArgs.ToArray());
343+
}
344+
345+
public MSBuildArgs CloneWithNoLogo(bool noLogo)
346+
{
347+
return new MSBuildArgs(
348+
GlobalProperties,
349+
RestoreGlobalProperties,
350+
RequestedTargets,
351+
GetProperty,
352+
GetItem,
353+
GetTargetResult,
354+
GetResultOutputFile,
355+
Verbosity,
356+
noLogo,
308357
OtherMSBuildArgs.ToArray());
309358
}
310359

0 commit comments

Comments
 (0)