Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[release/9.0.1xx] Extend dotnet run to invoke a run-command-producing Target #42987

Merged
merged 41 commits into from
Aug 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
fe3257b
refactor for readability before starting work
baronfel Jul 18, 2024
c51f319
simple execution of new target during run evaluation
baronfel Jul 18, 2024
f4f6efa
refactor to push validation into S.CL instead of in Execute
baronfel Jul 18, 2024
587dcb7
refactor to use FileINfo to reduce bugs froim using just String
baronfel Jul 19, 2024
fa05cb1
Revert "refactor to use FileINfo to reduce bugs froim using just String"
baronfel Jul 22, 2024
fe3d1c2
fix directory resolution bug
baronfel Jul 22, 2024
5d92fb2
add ProjectCapability for ProjectSystem compatibility checking
baronfel Jul 31, 2024
2a2f85e
Revert back to some prior less-strict handling to green up existing t…
baronfel Jul 31, 2024
2fb3829
Correct dotnet-watch dependency
baronfel Aug 12, 2024
c019b1f
Fix run parsing tests to have a valid project file even if not direct…
baronfel Aug 12, 2024
953e9b0
Fix dotnet run tests to account for expected restore args
baronfel Aug 12, 2024
5c512f7
Make tests that check for -p project file usage green up
baronfel Aug 12, 2024
af9f51c
generate binlogs as we're testing things out
baronfel Aug 12, 2024
298cc71
remove dotnet-watch precompute hook since watch no longer gets run ar…
baronfel Aug 12, 2024
2af52dc
Fix dependent ordering of argument parsing
baronfel Aug 12, 2024
f1a6379
Fix run parsing tests in a way that doesn't impact other parsing tests.
baronfel Aug 13, 2024
2a202ae
Update expectations since we emit long-forms for forwarded properties
baronfel Aug 13, 2024
b0c02af
Remove test that has odd side effect behavior
baronfel Aug 13, 2024
02afed7
Ensure that we check project applicability to validate conditions
baronfel Aug 13, 2024
bc99659
quick change to green up parser -- test
baronfel Aug 13, 2024
72ac23c
Refactor parsing tests to make them not clobber
baronfel Aug 13, 2024
308202b
Make test invocations more isolated
baronfel Aug 13, 2024
af9856b
Add test cases and error handling
baronfel Aug 14, 2024
82ae798
Create a terminal logger for evaluation-time errors
baronfel Aug 14, 2024
c8be312
Fix verbosity check that tests caught
baronfel Aug 14, 2024
74530ec
Strip nonvisible terminal logger progress indicators when comparing o…
baronfel Aug 14, 2024
e5ede47
disable test and log issue to reenable
baronfel Aug 19, 2024
8c31d90
Try to work around errors parsing stdout from the application being run
baronfel Aug 21, 2024
c3fa9d6
Safely parse stdout
baronfel Aug 21, 2024
3243d64
Unify TerminalLogger progress stripping code
baronfel Aug 21, 2024
8ad26a1
green up watch tests by fixing stdout parsing
baronfel Aug 21, 2024
8d1aadc
Skip globbing test that works locally but fails in CI.
baronfel Aug 21, 2024
29dcf1a
Fix a few more stdout-parsing issues in the dotnet run tests
baronfel Aug 21, 2024
311c7d9
disable one more test that works on local testing
baronfel Aug 22, 2024
cf42402
disable one more test that works on local testing
baronfel Aug 22, 2024
a6fdd1c
Update GlobbingAppTests.cs
baronfel Aug 24, 2024
2798856
Update GlobbingAppTests.cs
baronfel Aug 24, 2024
229e3ce
Update GlobbingAppTests.cs
baronfel Aug 26, 2024
7421d2f
Update watch tests
baronfel Aug 26, 2024
6179993
fix regression in --property forwarding with an invalid argument (#43…
baronfel Aug 26, 2024
e560ac5
More flaky tests
baronfel Aug 26, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,6 @@ cmake/

# MSBuild Logs
**/MSBuild_Logs/MSBuild_pid-*.failure.txt

# Test results
**/*.trx
2 changes: 1 addition & 1 deletion src/Cli/dotnet/CommonOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ public static CliArgument<string> DefaultToCurrentDirectory(this CliArgument<str
{
Description = CommonLocalizableStrings.DisableBuildServersOptionDescription
}
.ForwardAsMany(_ => new string[] { "-p:UseRazorBuildServer=false", "-p:UseSharedCompilation=false", "/nodeReuse:false" });
.ForwardAsMany(_ => ["--property:UseRazorBuildServer=false", "--property:UseSharedCompilation=false", "/nodeReuse:false"]);

public static CliOption<string> ArchitectureOption =
new ForwardedOption<string>("--arch", "-a")
Expand Down
6 changes: 3 additions & 3 deletions src/Cli/dotnet/ParseResultExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public static void ShowHelpOrErrorIfAppropriate(this ParseResult parseResult)
}
}

///<summary>Splits a .NET format string by the format placeholders (the {N} parts) to get an array of the literal parts, to be used in message-checking</summary>
///<summary>Splits a .NET format string by the format placeholders (the {N} parts) to get an array of the literal parts, to be used in message-checking</summary>
static string[] DistinctFormatStringParts(string formatString)
{
return Regex.Split(formatString, @"{[0-9]+}"); // match the literal '{', followed by any of 0-9 one or more times, followed by the literal '}'
Expand Down Expand Up @@ -173,8 +173,8 @@ public static bool BothArchAndOsOptionsSpecified(this ParseResult parseResult) =

internal static string GetCommandLineRuntimeIdentifier(this ParseResult parseResult)
{
return parseResult.HasOption(RunCommandParser.RuntimeOption) ?
parseResult.GetValue(RunCommandParser.RuntimeOption) :
return parseResult.HasOption(CommonOptions.RuntimeOption) ?
parseResult.GetValue(CommonOptions.RuntimeOption) :
parseResult.HasOption(CommonOptions.OperatingSystemOption) ||
parseResult.HasOption(CommonOptions.ArchitectureOption) ||
parseResult.HasOption(CommonOptions.LongFormArchitectureOption) ?
Expand Down
60 changes: 32 additions & 28 deletions src/Cli/dotnet/commands/dotnet-run/LocalizableStrings.resx
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
<!--
Microsoft ResX Schema

Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes

The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.

Example:

... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
Expand All @@ -26,36 +26,36 @@
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple

There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the

Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not

The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can

Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.

mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.

mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.

mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
Expand Down Expand Up @@ -180,6 +180,10 @@ The current {1} is '{2}'.</value>
<value>The launch profile "{0}" could not be applied.
{1}</value>
</data>
<data name="RunCommandEvaluationExceptionBuildFailed" xml:space="preserve">
<value>Running the {0} target to discover run commands failed for this project. Fix the errors and warnings and run again.</value>
<comment>{0} is the name of an MSBuild target</comment>
</data>
<data name="DefaultLaunchProfileDisplayName" xml:space="preserve">
<value>(Default)</value>
</data>
Expand All @@ -206,7 +210,7 @@ The current {1} is '{2}'.</value>
<value>An error was encountered when reading launchSettings.json.
{0}</value>
</data>
<data name="RunCommandSpecifiecFileIsNotAValidProject" xml:space="preserve">
<data name="RunCommandSpecifiedFileIsNotAValidProject" xml:space="preserve">
<value>'{0}' is not a valid project file.</value>
</data>
<data name="CouldNotConvertToBoolean" xml:space="preserve">
Expand Down
60 changes: 53 additions & 7 deletions src/Cli/dotnet/commands/dotnet-run/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,24 +18,21 @@ public static RunCommand FromArgs(string[] args)

public static RunCommand FromParseResult(ParseResult parseResult)
{
var project = parseResult.GetValue(RunCommandParser.ProjectOption);
if (parseResult.UsingRunCommandShorthandProjectOption())
{
Reporter.Output.WriteLine(LocalizableStrings.RunCommandProjectAbbreviationDeprecated.Yellow());
project = parseResult.GetRunCommandShorthandProjectValues().FirstOrDefault();
parseResult = ModifyParseResultForShorthandProjectOption(parseResult);
}

var command = new RunCommand(
configuration: parseResult.GetValue(RunCommandParser.ConfigurationOption),
framework: parseResult.GetValue(RunCommandParser.FrameworkOption),
runtime: parseResult.GetCommandLineRuntimeIdentifier(),
noBuild: parseResult.HasOption(RunCommandParser.NoBuildOption),
project: project,
projectFileOrDirectory: parseResult.GetValue(RunCommandParser.ProjectOption),
launchProfile: parseResult.GetValue(RunCommandParser.LaunchProfileOption),
noLaunchProfile: parseResult.HasOption(RunCommandParser.NoLaunchProfileOption),
noRestore: parseResult.HasOption(RunCommandParser.NoRestoreOption) || parseResult.HasOption(RunCommandParser.NoBuildOption),
interactive: parseResult.HasOption(RunCommandParser.InteractiveOption),
restoreArgs: parseResult.OptionValuesToBeForwarded(RunCommandParser.GetCommand()),
verbosity: parseResult.HasOption(CommonOptions.VerbosityOption) ? parseResult.GetValue(CommonOptions.VerbosityOption) : null,
restoreArgs: parseResult.OptionValuesToBeForwarded(RunCommandParser.GetCommand()).ToArray(),
args: parseResult.GetValue(RunCommandParser.ApplicationArguments)
);

Expand All @@ -48,5 +45,54 @@ public static int Run(ParseResult parseResult)

return FromParseResult(parseResult).Execute();
}

public static ParseResult ModifyParseResultForShorthandProjectOption(ParseResult parseResult)
{
// we know the project is going to be one of the following forms:
// -p:project
// -p project
// so try to find those and filter them out of the arguments array
var possibleProject = parseResult.GetRunCommandShorthandProjectValues().FirstOrDefault()!;
var tokensMinusProject = new List<string>();
var nextTokenMayBeProject = false;
foreach (var token in parseResult.Tokens)
{
if (token.Value == "-p")
{
// skip this token, if the next token _is_ the project then we'll skip that too
// if the next token _isn't_ the project then we'll backfill
nextTokenMayBeProject = true;
continue;
}
else if (token.Value == possibleProject && nextTokenMayBeProject)
{
// skip, we've successfully stripped this option and value entirely
nextTokenMayBeProject = false;
continue;
}
else if (token.Value.StartsWith("-p") && token.Value.EndsWith(possibleProject))
{
// both option and value in the same token, skip and carry on
}
else
{
if (nextTokenMayBeProject)
{
//we skipped a -p, so backfill it
tokensMinusProject.Add("-p");
}
nextTokenMayBeProject = false;
}

tokensMinusProject.Add(token.Value);
}

tokensMinusProject.Add("--project");
tokensMinusProject.Add(possibleProject);

var tokensToParse = tokensMinusProject.ToArray();
var newParseResult = Parser.Instance.Parse(tokensToParse);
return newParseResult;
}
}
}
Loading