Skip to content

Implement #:package manipulation for file-based apps #49635

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 3 commits 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
6 changes: 4 additions & 2 deletions documentation/general/dotnet-run-file.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ To opt out, use `#:property PublishAot=false` directive in your `.cs` file.

Command `dotnet clean file.cs` can be used to clean build artifacts of the file-based program.

Commands `dotnet package add PackageName --file app.cs` and `dotnet package remove PackageName --file app.cs`
can be used to manipulate `#:package` directives in the C# files, similarly to what the commands do for project-based apps.

## Entry points

If a file is given to `dotnet run`, it has to be an *entry-point file*, otherwise an error is reported.
Expand Down Expand Up @@ -373,8 +376,7 @@ We could also add `dotnet compile` command that would be the equivalent of `dotn
`dotnet clean` could be extended to support cleaning all file-based app outputs,
e.g., `dotnet clean --all-file-based-apps`.

Adding references via `dotnet package add`/`dotnet reference add` could be supported for file-based programs as well,
i.e., the command would add a `#:package`/`#:project` directive to the top of a `.cs` file.
More NuGet commands (like `dotnet nuget why` or `dotnet package list`) could be supported for file-based programs as well.

### Explicit importing

Expand Down
11 changes: 10 additions & 1 deletion src/Cli/dotnet/CliStrings.resx
Original file line number Diff line number Diff line change
Expand Up @@ -273,9 +273,18 @@
<data name="ProjectArgumentName" xml:space="preserve">
<value>PROJECT</value>
</data>
<data name="ProjectOrFileArgumentName" xml:space="preserve">
<value>PROJECT | FILE</value>
</data>
<data name="ProjectArgumentDescription" xml:space="preserve">
<value>The project file to operate on. If a file is not specified, the command will search the current directory for one.</value>
</data>
<data name="ProjectOrFileArgumentDescription" xml:space="preserve">
<value>The project file or C# file-based app to operate on. If a file is not specified, the command will search the current directory for a project file.</value>
</data>
<data name="FileArgumentDescription" xml:space="preserve">
<value>The file-based app to operate on.</value>
</data>
<data name="CommonCmdFramework" xml:space="preserve">
<value>FRAMEWORK</value>
</data>
Expand Down Expand Up @@ -814,4 +823,4 @@ The default is 'false.' However, when targeting .NET 7 or lower, the default is
<data name="SDKSchemaCommandDefinition" xml:space="preserve">
<value>Display the command schema as JSON.</value>
</data>
</root>
</root>
13 changes: 9 additions & 4 deletions src/Cli/dotnet/Commands/CliCommandStrings.resx
Original file line number Diff line number Diff line change
Expand Up @@ -1251,6 +1251,11 @@ Tool '{1}' (version '{2}') was successfully installed. Entry is added to the man
<data name="PackageRemoveSpecifyExactlyOnePackageReference" xml:space="preserve">
<value>Specify only one package reference to remove.</value>
</data>
<data name="DirectivesRemoved" xml:space="preserve">
<value>Removed '{0}' directives ({1}) for '{2}' from: {3}</value>
<comment>{0} is a directive kind (like '#:package'). {1} is number of removed directives.
{2} is directive key (e.g., package name). {3} is file path from which directives were removed.</comment>
</data>
<data name="PackagesCommandNameCollisionConclusion" xml:space="preserve">
<value>Command names conflict. Command names are case insensitive.
{0}</value>
Expand Down Expand Up @@ -1530,14 +1535,14 @@ Tool '{1}' (version '{2}') was successfully installed. Entry is added to the man
<value>Duplicate directives are not supported: {0} at {1}</value>
<comment>{0} is the directive type and name. {1} is the file path and line number.</comment>
</data>
<data name="InvalidOptionCombination" xml:space="preserve">
<value>Cannot combine option '{0}' and '{1}'.</value>
<comment>{0} and {1} are option names like '--no-build'.</comment>
</data>
<data name="InvalidOptionForStdin" xml:space="preserve">
<value>Cannot specify option '{0}' when also using '-' to read the file from standard input.</value>
<comment>{0} is an option name like '--no-build'.</comment>
</data>
<data name="InvalidOptionForFileBasedApp" xml:space="preserve">
<value>Cannot specify option '{0}' when operating on a file-based app.</value>
<comment>{0} is an option name like '--source'.</comment>
</data>
<data name="NoBinaryLogBecauseUpToDate" xml:space="preserve">
<value>Warning: Binary log option was specified but build will be skipped because output is up to date, specify '--no-cache' to force build.</value>
<comment>{Locked="--no-cache"}</comment>
Expand Down
10 changes: 2 additions & 8 deletions src/Cli/dotnet/Commands/Hidden/Add/AddCommandParser.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

#nullable disable

using System.CommandLine;
using Microsoft.DotNet.Cli.Commands.Hidden.Add.Package;
using Microsoft.DotNet.Cli.Commands.Hidden.Add.Reference;
using Microsoft.DotNet.Cli.Commands.Package;
using Microsoft.DotNet.Cli.Extensions;

namespace Microsoft.DotNet.Cli.Commands.Hidden.Add;
Expand All @@ -14,11 +13,6 @@ internal static class AddCommandParser
{
public static readonly string DocsLink = "https://aka.ms/dotnet-add";

public static readonly Argument<string> ProjectArgument = new Argument<string>(CliStrings.ProjectArgumentName)
{
Description = CliStrings.ProjectArgumentDescription
}.DefaultToCurrentDirectory();

private static readonly Command Command = ConstructCommand();

public static Command GetCommand()
Expand All @@ -33,7 +27,7 @@ private static Command ConstructCommand()
Hidden = true
};

command.Arguments.Add(ProjectArgument);
command.Arguments.Add(PackageCommandParser.ProjectOrFileArgument);
command.Subcommands.Add(AddPackageCommandParser.GetCommand());
command.Subcommands.Add(AddReferenceCommandParser.GetCommand());

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

#nullable disable

using System.CommandLine;
using Microsoft.DotNet.Cli.Commands.Package;
using Microsoft.DotNet.Cli.Commands.Package.Add;
using Microsoft.DotNet.Cli.Extensions;

namespace Microsoft.DotNet.Cli.Commands.Hidden.Add.Package;

Expand All @@ -32,20 +29,9 @@ private static Command ConstructCommand()
command.Options.Add(PackageAddCommandParser.InteractiveOption);
command.Options.Add(PackageAddCommandParser.PrereleaseOption);
command.Options.Add(PackageCommandParser.ProjectOption);
command.Options.Add(PackageCommandParser.FileOption);

command.SetAction((parseResult) =>
{
// this command can be called with an argument or an option for the project path - we prefer the option.
// if the option is not present, we use the argument value instead.
if (parseResult.HasOption(PackageCommandParser.ProjectOption))
{
return new PackageAddCommand(parseResult, parseResult.GetValue(PackageCommandParser.ProjectOption)).Execute();
}
else
{
return new PackageAddCommand(parseResult, parseResult.GetValue(AddCommandParser.ProjectArgument) ?? Directory.GetCurrentDirectory()).Execute();
}
});
command.SetAction((parseResult) => new PackageAddCommand(parseResult).Execute());

return command;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

#nullable disable

using System.CommandLine;
using Microsoft.DotNet.Cli.Commands.Package.Remove;

Expand Down
10 changes: 2 additions & 8 deletions src/Cli/dotnet/Commands/Hidden/Remove/RemoveCommandParser.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

#nullable disable

using System.CommandLine;
using Microsoft.DotNet.Cli.Commands.Hidden.Remove.Package;
using Microsoft.DotNet.Cli.Commands.Hidden.Remove.Reference;
using Microsoft.DotNet.Cli.Commands.Package;
using Microsoft.DotNet.Cli.Extensions;

namespace Microsoft.DotNet.Cli.Commands.Hidden.Remove;
Expand All @@ -14,11 +13,6 @@ internal static class RemoveCommandParser
{
public static readonly string DocsLink = "https://aka.ms/dotnet-remove";

public static readonly Argument<string> ProjectArgument = new Argument<string>(CliStrings.ProjectArgumentName)
{
Description = CliStrings.ProjectArgumentDescription
}.DefaultToCurrentDirectory();

private static readonly Command Command = ConstructCommand();

public static Command GetCommand()
Expand All @@ -33,7 +27,7 @@ private static Command ConstructCommand()
Hidden = true
};

command.Arguments.Add(ProjectArgument);
command.Arguments.Add(PackageCommandParser.ProjectOrFileArgument);
command.Subcommands.Add(RemovePackageCommandParser.GetCommand());
command.Subcommands.Add(RemoveReferenceCommandParser.GetCommand());

Expand Down
2 changes: 1 addition & 1 deletion src/Cli/dotnet/Commands/New/DotnetCommandCallbacks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ internal static bool AddPackageReference(string projectPath, string packageName,
{
commandArgs = commandArgs.Append(PackageAddCommandParser.VersionOption.Name).Append(version);
}
var addPackageReferenceCommand = new PackageAddCommand(AddCommandParser.GetCommand().Parse([.. commandArgs]), projectPath);
var addPackageReferenceCommand = new PackageAddCommand(AddCommandParser.GetCommand().Parse([.. commandArgs]));
return addPackageReferenceCommand.Execute() == 0;
}

Expand Down
Loading
Loading