Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public static Argument<string> CreateSlnOrProjectArgument(string name, string de
Arity = ArgumentArity.ZeroOrOne
}.DefaultToCurrentDirectory();

public readonly Argument<string> SlnOrProjectArgument = CreateSlnOrProjectArgument(CommandDefinitionStrings.SolutionOrProjectArgumentName, CommandDefinitionStrings.SolutionOrProjectArgumentDescription);
public readonly Argument<string> SlnOrProjectOrFileArgument = CreateSlnOrProjectArgument(CommandDefinitionStrings.SolutionOrProjectOrFileArgumentName, CommandDefinitionStrings.SolutionOrProjectOrFileArgumentDescription);

public readonly ListPackageCommandDefinition PackageCommand = new();
public readonly ListReferenceCommandDefinition ReferenceCommand = new();
Expand All @@ -31,7 +31,7 @@ public ListCommandDefinition()
Hidden = true;
this.DocsLink = Link;

Arguments.Add(SlnOrProjectArgument);
Arguments.Add(SlnOrProjectOrFileArgument);
Subcommands.Add(PackageCommand);
Subcommands.Add(ReferenceCommand);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@ internal sealed class ListPackageCommandDefinition() : PackageListCommandDefinit

public ListCommandDefinition Parent => (ListCommandDefinition)Parents.Single();

public override string? GetFileOrDirectory(ParseResult parseResult)
=> parseResult.GetValue(Parent.SlnOrProjectArgument);
public override Argument<string>? GetProjectOrFileArgument()
=> Parent.SlnOrProjectOrFileArgument;
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public ListReferenceCommandDefinition() : base(Name)
public ListCommandDefinition Parent => (ListCommandDefinition)Parents.Single();

internal override string? GetFileOrDirectory(ParseResult parseResult)
=> parseResult.GetValue(Parent.SlnOrProjectArgument);
=> parseResult.GetValue(Parent.SlnOrProjectOrFileArgument);
}

internal abstract class ListReferenceCommandDefinitionBase : Command
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,12 @@

namespace Microsoft.DotNet.Cli.Commands.Package.List;

internal sealed class PackageListCommandDefinition : PackageListCommandDefinitionBase
internal sealed class PackageListCommandDefinition() : PackageListCommandDefinitionBase(Name)
{
public new const string Name = "list";

public readonly Option<string?> ProjectOption = PackageCommandDefinition.CreateProjectOption();

public PackageListCommandDefinition()
: base(Name)
{
Options.Add(ProjectOption);
}

public override string? GetFileOrDirectory(ParseResult parseResult)
=> parseResult.GetValue(ProjectOption);
public override Argument<string>? GetProjectOrFileArgument()
=> null;
}

internal abstract class PackageListCommandDefinitionBase : Command
Expand Down Expand Up @@ -110,6 +102,9 @@ internal abstract class PackageListCommandDefinitionBase : Command
Description = CommandDefinitionStrings.CmdOutputVersionDescription
}.ForwardAsSingle(o => $"--output-version:{o}");

public readonly Option<string?> ProjectOption = PackageCommandDefinition.CreateProjectOption();
public readonly Option<string?> FileOption = PackageCommandDefinition.CreateFileOption();

public PackageListCommandDefinitionBase(string name)
: base(name, CommandDefinitionStrings.PackageListAppFullName)
{
Expand All @@ -128,9 +123,11 @@ public PackageListCommandDefinitionBase(string name)
Options.Add(FormatOption);
Options.Add(OutputVersionOption);
Options.Add(NoRestore);
Options.Add(ProjectOption);
Options.Add(FileOption);
}

public abstract string? GetFileOrDirectory(ParseResult parseResult);
public abstract Argument<string>? GetProjectOrFileArgument();

public void EnforceOptionRules(ParseResult parseResult)
{
Expand Down
5 changes: 0 additions & 5 deletions src/Cli/dotnet/Commands/CliCommandStrings.resx
Original file line number Diff line number Diff line change
Expand Up @@ -651,11 +651,6 @@ 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
44 changes: 39 additions & 5 deletions src/Cli/dotnet/Commands/NuGet/NuGetCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,36 @@
using System.CommandLine;
using Microsoft.DotNet.Cli.Extensions;
using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.ProjectTools;

namespace Microsoft.DotNet.Cli.Commands.NuGet;

public class NuGetCommand
internal class NuGetCommand
{
public static int Run(string[] args)
public static int Run(string[] args, bool isFileBasedApp = false)
{
return Run(args, new NuGetCommandRunner());
return Run(args, isFileBasedApp
? new InProcessNuGetCommandRunner(NuGetVirtualProjectBuilder.Instance)
: new NuGetCommandRunner());
}

public static int Run(ParseResult parseResult)
{
return Run(parseResult.GetArguments(), new NuGetCommandRunner());
ICommandRunner runner;

if (parseResult.CommandResult.Command.Name == "why"
&& parseResult.CommandResult.Command.Arguments.FirstOrDefault() is Argument<string> pathArg
&& parseResult.GetValue(pathArg) is { } path
&& VirtualProjectBuilder.IsValidEntryPointPath(path))
{
runner = new InProcessNuGetCommandRunner(NuGetVirtualProjectBuilder.Instance);
}
else
{
runner = new NuGetCommandRunner();
}

return Run(parseResult.GetArguments(), runner);
}
Comment thread
jjonescz marked this conversation as resolved.

public static int Run(string[] args, ICommandRunner nugetCommandRunner)
Expand All @@ -43,11 +60,28 @@ private class NuGetCommandRunner : ICommandRunner
public int Run(string[] args)
{
var nugetApp = new NuGetForwardingApp(args);
nugetApp.WithEnvironmentVariable("DOTNET_HOST_PATH", GetDotnetPath());
nugetApp.WithEnvironmentVariable(EnvironmentVariableNames.DOTNET_HOST_PATH, GetDotnetPath());
return nugetApp.Execute();
}
}

private class InProcessNuGetCommandRunner(NuGetVirtualProjectBuilder virtualProjectBuilder) : ICommandRunner
{
public int Run(string[] args)
{
var originalDotNetHostPath = Environment.GetEnvironmentVariable(EnvironmentVariableNames.DOTNET_HOST_PATH);
Environment.SetEnvironmentVariable(EnvironmentVariableNames.DOTNET_HOST_PATH, GetDotnetPath());
try
{
return global::NuGet.CommandLine.XPlat.Program.Run(args, virtualProjectBuilder);
Comment thread
MiYanni marked this conversation as resolved.
}
finally
{
Environment.SetEnvironmentVariable(EnvironmentVariableNames.DOTNET_HOST_PATH, originalDotNetHostPath);
}
}
}

private static string GetDotnetPath()
{
return new Muxer().MuxerPath;
Expand Down
47 changes: 47 additions & 0 deletions src/Cli/dotnet/Commands/NuGet/NuGetVirtualProjectBuilder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using Microsoft.Build.Construction;
using Microsoft.Build.Evaluation;
using Microsoft.DotNet.Cli.Commands.Package;
using Microsoft.DotNet.Cli.Commands.Run;
using Microsoft.DotNet.FileBasedPrograms;
using Microsoft.DotNet.ProjectTools;
using NuGet.CommandLine.XPlat;

namespace Microsoft.DotNet.Cli.Commands.NuGet;

internal sealed class NuGetVirtualProjectBuilder : IVirtualProjectBuilder
{
public static NuGetVirtualProjectBuilder Instance => field ??= new();

private NuGetVirtualProjectBuilder() { }

public bool IsValidEntryPointPath(string entryPointFilePath) => VirtualProjectBuilder.IsValidEntryPointPath(entryPointFilePath);

public string GetVirtualProjectPath(string entryPointFilePath) => VirtualProjectBuilder.GetVirtualProjectPath(entryPointFilePath);

public ProjectRootElement CreateProjectRootElement(string entryPointFilePath, ProjectCollection projectCollection)
{
if (!Path.IsPathFullyQualified(entryPointFilePath))
{
throw new ArgumentException($"'{entryPointFilePath}' is not a fully qualified path.", paramName: nameof(entryPointFilePath));
}

var builder = new VirtualProjectBuilder(entryPointFilePath, VirtualProjectBuildingCommand.TargetFramework);

builder.CreateProjectInstance(
projectCollection,
ErrorReporters.IgnoringReporter,
project: out _,
out var projectRootElement,
evaluatedDirectives: out _);

return projectRootElement;
}

public void SaveProject(string entryPointFilePath, ProjectRootElement projectRootElement)
{
VirtualProjectPackageReflector.ReflectChangesToDirectives(projectRootElement, entryPointFilePath);
}
}
Loading
Loading