Skip to content

Allow skipping project fallback with file-based run #49808

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 3 additions & 2 deletions documentation/general/dotnet-run-file.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ The file-based build and run kicks in only when:
- if the target file exists, and has the `.cs` file extension or contents that start with `#!`.

Otherwise, project-based `dotnet run` fallback is used and you might get an error like "Couldn't find a project to run."
You can explicitly use the `--file` option to avoid the fallback behavior.

File-based programs are processed by `dotnet run` equivalently to project-based programs unless specified otherwise in this document.
For example, the remaining command-line arguments after the first argument (the target path) are passed through to the target app
Expand All @@ -88,7 +89,7 @@ If a dash (`-`) is given instead of the target path (i.e., `dotnet run -`), the
In this case, the current working directory is not used to search for other files (launch profiles, other sources in case of multi-file apps);
the compilation consists solely of the single file read from the standard input.

`dotnet path.cs` is a shortcut for `dotnet run path.cs` provided that `path.cs` is a valid [target path](#target-path) (`dotnet -` is currently not supported).
`dotnet path.cs` is a shortcut for `dotnet run --file path.cs` provided that `path.cs` is a valid [target path](#target-path) (`dotnet -` is currently not supported).

### Other commands

Expand Down Expand Up @@ -303,7 +304,7 @@ would need to search for a file-based program in the current directory instead o

We could add a universal option that works with both project-based and file-based programs,
like `dotnet run --directory ./dir/`. For inspiration, `dotnet test` also has a `--directory` option.
Furthermore, users might expect there to be a `--file` option, as well. Both could be unified as `--path`.
We already have a `--file` option. Both could be unified as `--path`.

If we want to also support [multi-entry-point scenarios](#multiple-entry-points),
we might need an option like `dotnet run --entry ./dir/name` which would work for both `./dir/name.cs` and `./dir/name/name.csproj`.
Expand Down
6 changes: 6 additions & 0 deletions src/Cli/dotnet/Commands/CliCommandStrings.resx
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,12 @@ dotnet.config is a name don't translate.</comment>
<data name="CommandOptionProjectHelpName" xml:space="preserve">
<value>PROJECT_PATH</value>
</data>
<data name="CommandOptionFileDescription" xml:space="preserve">
<value>The path to the file-based app to run (can be also passed as the first argument if there is no project in the current directory).</value>
</data>
<data name="CommandOptionFileHelpName" xml:space="preserve">
<value>FILE_PATH</value>
</data>
<data name="Commands" xml:space="preserve">
<value>SDK commands</value>
</data>
Expand Down
23 changes: 21 additions & 2 deletions src/Cli/dotnet/Commands/Run/RunCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -445,8 +445,16 @@ private static void ThrowUnableToRunError(ProjectInstance project)
project.GetPropertyValue("OutputType")));
}

private static string? DiscoverProjectFilePath(string? projectFileOrDirectoryPath, bool readCodeFromStdin, ref string[] args, out string? entryPointFilePath)
private static string? DiscoverProjectFilePath(string? filePath, string? projectFileOrDirectoryPath, bool readCodeFromStdin, ref string[] args, out string? entryPointFilePath)
{
// If `--file` is explicitly specified, just use that.
if (filePath != null)
{
Debug.Assert(projectFileOrDirectoryPath == null);
entryPointFilePath = Path.GetFullPath(filePath);
return null;
}

bool emptyProjectOption = false;
if (string.IsNullOrWhiteSpace(projectFileOrDirectoryPath))
{
Expand Down Expand Up @@ -547,9 +555,20 @@ public static RunCommand FromParseResult(ParseResult parseResult)
.Any(static t => t is { Type: TokenType.Argument, Value: "-" });

string? projectOption = parseResult.GetValue(RunCommandParser.ProjectOption);
string? fileOption = parseResult.GetValue(RunCommandParser.FileOption);

if (projectOption != null && fileOption != null)
{
throw new GracefulException(CliCommandStrings.InvalidOptionCombination, RunCommandParser.ProjectOption.Name, RunCommandParser.FileOption.Name);
}

string[] args = [.. nonBinLogArgs];
string? projectFilePath = DiscoverProjectFilePath(projectOption, readCodeFromStdin, ref args, out string? entryPointFilePath);
string? projectFilePath = DiscoverProjectFilePath(
filePath: fileOption,
projectFileOrDirectoryPath: projectOption,
readCodeFromStdin: readCodeFromStdin,
ref args,
out string? entryPointFilePath);

bool noBuild = parseResult.HasOption(RunCommandParser.NoBuildOption);

Expand Down
7 changes: 7 additions & 0 deletions src/Cli/dotnet/Commands/Run/RunCommandParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ internal static class RunCommandParser
HelpName = CliCommandStrings.CommandOptionProjectHelpName
};

public static readonly Option<string> FileOption = new("--file")
{
Description = CliCommandStrings.CommandOptionFileDescription,
HelpName = CliCommandStrings.CommandOptionFileHelpName,
};

public static readonly Option<ReadOnlyDictionary<string, string>?> PropertyOption = CommonOptions.PropertiesOption;

public static readonly Option<string> LaunchProfileOption = new("--launch-profile", "-lp")
Expand Down Expand Up @@ -85,6 +91,7 @@ private static Command ConstructCommand()
command.Options.Add(FrameworkOption);
command.Options.Add(RuntimeOption);
command.Options.Add(ProjectOption);
command.Options.Add(FileOption);
command.Options.Add(PropertyOption);
command.Options.Add(LaunchProfileOption);
command.Options.Add(NoLaunchProfileOption);
Expand Down
10 changes: 10 additions & 0 deletions src/Cli/dotnet/Commands/xlf/CliCommandStrings.cs.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions src/Cli/dotnet/Commands/xlf/CliCommandStrings.de.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions src/Cli/dotnet/Commands/xlf/CliCommandStrings.es.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions src/Cli/dotnet/Commands/xlf/CliCommandStrings.fr.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions src/Cli/dotnet/Commands/xlf/CliCommandStrings.it.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions src/Cli/dotnet/Commands/xlf/CliCommandStrings.ja.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions src/Cli/dotnet/Commands/xlf/CliCommandStrings.ko.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions src/Cli/dotnet/Commands/xlf/CliCommandStrings.pl.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions src/Cli/dotnet/Commands/xlf/CliCommandStrings.pt-BR.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions src/Cli/dotnet/Commands/xlf/CliCommandStrings.ru.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions src/Cli/dotnet/Commands/xlf/CliCommandStrings.tr.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions src/Cli/dotnet/Commands/xlf/CliCommandStrings.zh-Hans.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions src/Cli/dotnet/Commands/xlf/CliCommandStrings.zh-Hant.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading