diff --git a/src/Cli/dotnet/Commands/Add/Package/AddPackageParser.cs b/src/Cli/dotnet/Commands/Add/Package/AddPackageParser.cs index 2251ca12a2fa..053d9dbadb89 100644 --- a/src/Cli/dotnet/Commands/Add/Package/AddPackageParser.cs +++ b/src/Cli/dotnet/Commands/Add/Package/AddPackageParser.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.CommandLine; +using Microsoft.DotNet.Cli.Extensions; using Microsoft.DotNet.Tools.Package.Add; using LocalizableStrings = Microsoft.DotNet.Tools.Package.Add.LocalizableStrings; @@ -30,7 +31,19 @@ private static CliCommand ConstructCommand() command.Options.Add(PackageAddCommandParser.PrereleaseOption); command.Options.Add(PackageCommandParser.ProjectOption); - command.SetAction((parseResult) => new AddPackageReferenceCommand(parseResult).Execute()); + 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 AddPackageReferenceCommand(parseResult, parseResult.GetValue(PackageCommandParser.ProjectOption)).Execute(); + } + else + { + return new AddPackageReferenceCommand(parseResult, parseResult.GetValue(AddCommandParser.ProjectArgument)).Execute(); + } + }); return command; } diff --git a/src/Cli/dotnet/Commands/New/DotnetCommandCallbacks.cs b/src/Cli/dotnet/Commands/New/DotnetCommandCallbacks.cs index 7ff86966b2a0..8d5ff20de3d7 100644 --- a/src/Cli/dotnet/Commands/New/DotnetCommandCallbacks.cs +++ b/src/Cli/dotnet/Commands/New/DotnetCommandCallbacks.cs @@ -20,7 +20,7 @@ internal static bool AddPackageReference(string projectPath, string packageName, { commandArgs = commandArgs.Append(PackageAddCommandParser.VersionOption.Name).Append(version); } - var addPackageReferenceCommand = new AddPackageReferenceCommand(AddCommandParser.GetCommand().Parse(commandArgs.ToArray())); + var addPackageReferenceCommand = new AddPackageReferenceCommand(AddCommandParser.GetCommand().Parse(commandArgs.ToArray()), projectPath); return addPackageReferenceCommand.Execute() == 0; } diff --git a/src/Cli/dotnet/Commands/Package/Add/LocalizableStrings.resx b/src/Cli/dotnet/Commands/Package/Add/LocalizableStrings.resx index 4825ed787675..febefad0d2bc 100644 --- a/src/Cli/dotnet/Commands/Package/Add/LocalizableStrings.resx +++ b/src/Cli/dotnet/Commands/Package/Add/LocalizableStrings.resx @@ -124,7 +124,7 @@ Command to add package reference - The package reference to add. + The package reference to add. This can be in the form of just the package identifier, for example 'Newtonsoft.Json', or a package identifier and version separated by '@', for example 'Newtonsoft.Json@13.0.3' Specify one package reference to add. @@ -165,4 +165,12 @@ Unable to generate a temporary file for project '{0}'. Cannot add package reference. Clear the temp directory and try again. + + Cannot specify --version when the package argument already contains a version. + {Locked="--version"} + + + Failed to parse "{0}" as a semantic version. + {0} is a version string that the user entered that was not parsed as a Semantic Version + diff --git a/src/Cli/dotnet/Commands/Package/Add/PackageAddCommandParser.cs b/src/Cli/dotnet/Commands/Package/Add/PackageAddCommandParser.cs index 535ec055daf3..58bd849a32be 100644 --- a/src/Cli/dotnet/Commands/Package/Add/PackageAddCommandParser.cs +++ b/src/Cli/dotnet/Commands/Package/Add/PackageAddCommandParser.cs @@ -8,15 +8,50 @@ using NuGet.Versioning; using Microsoft.DotNet.Tools.Package.Add; using Microsoft.DotNet.Cli.Extensions; +using System.CommandLine.Parsing; +using NuGet.Packaging.Core; namespace Microsoft.DotNet.Cli; internal static class PackageAddCommandParser { - public static readonly CliArgument CmdPackageArgument = new DynamicArgument(LocalizableStrings.CmdPackage) + public static NuGet.Packaging.Core.PackageIdentity ParsePackageIdentity(ArgumentResult packageArgResult) + { + // per the Arity of the CmdPackageArgument's Arity, we should have exactly one token - + // this is a safety net for if we change the Arity in the future and forget to update this parser. + if (packageArgResult.Tokens.Count != 1) + { + throw new ArgumentException($"Expected exactly one token, but got {packageArgResult.Tokens.Count}."); + } + var token = packageArgResult.Tokens[0].Value; + var indexOfAt = token.IndexOf('@'); + if (indexOfAt == -1) + { + // no version specified, so we just return the package id + return new NuGet.Packaging.Core.PackageIdentity(token, null); + } + // we have a version specified, so we need to split the token into id and version + else + { + var id = token[0..indexOfAt]; + var versionString = token[(indexOfAt + 1)..]; + if (NuGet.Versioning.SemanticVersion.TryParse(versionString, out var version)) + { + return new NuGet.Packaging.Core.PackageIdentity(id, new NuGetVersion(version.Major, version.Minor, version.Patch, version.ReleaseLabels, version.Metadata)); + } + else + { + throw new ArgumentException(string.Format(LocalizableStrings.InvalidSemVerVersionString, versionString)); + } + }; + } + + public static readonly CliArgument CmdPackageArgument = new DynamicArgument(LocalizableStrings.CmdPackage) { Description = LocalizableStrings.CmdPackageDescription, - Arity = ArgumentArity.ExactlyOne + Arity = ArgumentArity.ExactlyOne, + CustomParser = ParsePackageIdentity, + }.AddCompletions((context) => { // we should take --prerelease flags into account for version completion @@ -32,11 +67,11 @@ internal static class PackageAddCommandParser .AddCompletions((context) => { // we can only do version completion if we have a package id - if (context.ParseResult.GetValue(CmdPackageArgument) is string packageId) + if (context.ParseResult.GetValue(CmdPackageArgument) is NuGet.Packaging.Core.PackageIdentity packageId && !packageId.HasVersion) { // we should take --prerelease flags into account for version completion var allowPrerelease = context.ParseResult.GetValue(PrereleaseOption); - return QueryVersionsForPackage(packageId, context.WordToComplete, allowPrerelease, CancellationToken.None) + return QueryVersionsForPackage(packageId.Id, context.WordToComplete, allowPrerelease, CancellationToken.None) .Result .Select(version => new CompletionItem(version.ToNormalizedString())); } @@ -89,6 +124,7 @@ private static CliCommand ConstructCommand() { CliCommand command = new("add", LocalizableStrings.AppFullName); + VersionOption.Validators.Add(DisallowVersionIfPackageIdentityHasVersionValidator); command.Arguments.Add(CmdPackageArgument); command.Options.Add(VersionOption); command.Options.Add(FrameworkOption); @@ -99,11 +135,19 @@ private static CliCommand ConstructCommand() command.Options.Add(PrereleaseOption); command.Options.Add(PackageCommandParser.ProjectOption); - command.SetAction((parseResult) => new AddPackageReferenceCommand(parseResult).Execute()); + command.SetAction((parseResult) => new AddPackageReferenceCommand(parseResult, parseResult.GetValue(PackageCommandParser.ProjectOption)).Execute()); return command; } + private static void DisallowVersionIfPackageIdentityHasVersionValidator(OptionResult result) + { + if (result.Parent.GetValue(CmdPackageArgument) is PackageIdentity identity && identity.HasVersion) + { + result.AddError(LocalizableStrings.ValidationFailedDuplicateVersion); + } + } + public static async Task> QueryNuGet(string packageStem, bool allowPrerelease, CancellationToken cancellationToken) { try diff --git a/src/Cli/dotnet/Commands/Package/Add/Program.cs b/src/Cli/dotnet/Commands/Package/Add/Program.cs index 3f1011ce91e0..603f6017cfa7 100644 --- a/src/Cli/dotnet/Commands/Package/Add/Program.cs +++ b/src/Cli/dotnet/Commands/Package/Add/Program.cs @@ -7,27 +7,30 @@ using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.Tools.MSBuild; using Microsoft.DotNet.Tools.NuGet; +using NuGet.Packaging.Core; namespace Microsoft.DotNet.Tools.Package.Add; -internal class AddPackageReferenceCommand(ParseResult parseResult) : CommandBase(parseResult) +/// +/// +/// Since this command is invoked via both 'package add' and 'add package', different symbols will control what the project path to search is. +/// It's cleaner for the separate callsites to know this instead of pushing that logic here. +/// +internal class AddPackageReferenceCommand(ParseResult parseResult, string fileOrDirectory) : CommandBase(parseResult) { - private readonly string _packageId = parseResult.GetValue(PackageAddCommandParser.CmdPackageArgument); - private readonly string _fileOrDirectory = parseResult.HasOption(PackageCommandParser.ProjectOption) ? - parseResult.GetValue(PackageCommandParser.ProjectOption) : - parseResult.GetValue(AddCommandParser.ProjectArgument); + private readonly PackageIdentity _packageId = parseResult.GetValue(PackageAddCommandParser.CmdPackageArgument); public override int Execute() { var projectFilePath = string.Empty; - if (!File.Exists(_fileOrDirectory)) + if (!File.Exists(fileOrDirectory)) { - projectFilePath = MsbuildProject.GetProjectFileFromDirectory(_fileOrDirectory).FullName; + projectFilePath = MsbuildProject.GetProjectFileFromDirectory(fileOrDirectory).FullName; } else { - projectFilePath = _fileOrDirectory; + projectFilePath = fileOrDirectory; } var tempDgFilePath = string.Empty; @@ -98,17 +101,22 @@ private void DisposeTemporaryFile(string filePath) } } - private string[] TransformArgs(string packageId, string tempDgFilePath, string projectFilePath) + private string[] TransformArgs(PackageIdentity packageId, string tempDgFilePath, string projectFilePath) { - var args = new List - { + List args = [ "package", "add", "--package", - packageId, + packageId.Id, "--project", projectFilePath - }; + ]; + + if (packageId.HasVersion) + { + args.Add("--version"); + args.Add(packageId.Version.ToString()); + } args.AddRange(_parseResult .OptionValuesToBeForwarded(PackageAddCommandParser.GetCommand()) diff --git a/src/Cli/dotnet/Commands/Package/Add/xlf/LocalizableStrings.cs.xlf b/src/Cli/dotnet/Commands/Package/Add/xlf/LocalizableStrings.cs.xlf index 0abf28f2d0d9..17fcb251cc85 100644 --- a/src/Cli/dotnet/Commands/Package/Add/xlf/LocalizableStrings.cs.xlf +++ b/src/Cli/dotnet/Commands/Package/Add/xlf/LocalizableStrings.cs.xlf @@ -12,6 +12,11 @@ Příkaz pro přidání odkazu na balíček + + Failed to parse "{0}" as a semantic version. + Failed to parse "{0}" as a semantic version. + {0} is a version string that the user entered that was not parsed as a Semantic Version + Specify one package reference to add. Zadejte jeden odkaz na balíček, který chcete přidat. @@ -68,8 +73,8 @@ - The package reference to add. - Odkaz na balíček, který se má přidat + The package reference to add. This can be in the form of just the package identifier, for example 'Newtonsoft.Json', or a package identifier and version separated by '@', for example 'Newtonsoft.Json@13.0.3' + Odkaz na balíček, který se má přidat @@ -82,6 +87,11 @@ Nejde generovat dočasný soubor pro projekt {0}. Není možné přidat odkaz na balíček. Vyprázdněte dočasný adresář a zkuste to znovu. + + Cannot specify --version when the package argument already contains a version. + Cannot specify --version when the package argument already contains a version. + {Locked="--version"} + \ No newline at end of file diff --git a/src/Cli/dotnet/Commands/Package/Add/xlf/LocalizableStrings.de.xlf b/src/Cli/dotnet/Commands/Package/Add/xlf/LocalizableStrings.de.xlf index 6d40703595e1..5f96045faf21 100644 --- a/src/Cli/dotnet/Commands/Package/Add/xlf/LocalizableStrings.de.xlf +++ b/src/Cli/dotnet/Commands/Package/Add/xlf/LocalizableStrings.de.xlf @@ -12,6 +12,11 @@ Befehl zum Hinzufügen eines Paketverweises + + Failed to parse "{0}" as a semantic version. + Failed to parse "{0}" as a semantic version. + {0} is a version string that the user entered that was not parsed as a Semantic Version + Specify one package reference to add. Geben Sie einen Paketverweis an, der hinzugefügt werden soll. @@ -68,8 +73,8 @@ - The package reference to add. - Der hinzuzufügende Paketverweis. + The package reference to add. This can be in the form of just the package identifier, for example 'Newtonsoft.Json', or a package identifier and version separated by '@', for example 'Newtonsoft.Json@13.0.3' + Der hinzuzufügende Paketverweis. @@ -82,6 +87,11 @@ Für das Projekt "{0}" kann keine temporäre Datei generiert werden. Ein Paketverweis kann nicht hinzugefügt werden. Löschen Sie das temporäre Verzeichnis, und versuchen Sie es noch mal. + + Cannot specify --version when the package argument already contains a version. + Cannot specify --version when the package argument already contains a version. + {Locked="--version"} + \ No newline at end of file diff --git a/src/Cli/dotnet/Commands/Package/Add/xlf/LocalizableStrings.es.xlf b/src/Cli/dotnet/Commands/Package/Add/xlf/LocalizableStrings.es.xlf index 21cf3843118b..7bbc324dab17 100644 --- a/src/Cli/dotnet/Commands/Package/Add/xlf/LocalizableStrings.es.xlf +++ b/src/Cli/dotnet/Commands/Package/Add/xlf/LocalizableStrings.es.xlf @@ -12,6 +12,11 @@ Comando para agregar referencia de paquete + + Failed to parse "{0}" as a semantic version. + Failed to parse "{0}" as a semantic version. + {0} is a version string that the user entered that was not parsed as a Semantic Version + Specify one package reference to add. Especifique una referencia de paquete para agregar. @@ -68,8 +73,8 @@ - The package reference to add. - La referencia de paquete para agregar. + The package reference to add. This can be in the form of just the package identifier, for example 'Newtonsoft.Json', or a package identifier and version separated by '@', for example 'Newtonsoft.Json@13.0.3' + La referencia de paquete para agregar. @@ -82,6 +87,11 @@ No se puede generar un archivo temporal para el proyecto "{0}". No se puede agregar la referencia del paquete. Borre el directorio temporal e inténtelo de nuevo. + + Cannot specify --version when the package argument already contains a version. + Cannot specify --version when the package argument already contains a version. + {Locked="--version"} + \ No newline at end of file diff --git a/src/Cli/dotnet/Commands/Package/Add/xlf/LocalizableStrings.fr.xlf b/src/Cli/dotnet/Commands/Package/Add/xlf/LocalizableStrings.fr.xlf index e7d70a988079..72c178e68da9 100644 --- a/src/Cli/dotnet/Commands/Package/Add/xlf/LocalizableStrings.fr.xlf +++ b/src/Cli/dotnet/Commands/Package/Add/xlf/LocalizableStrings.fr.xlf @@ -12,6 +12,11 @@ Commande permettant d'ajouter une référence de package + + Failed to parse "{0}" as a semantic version. + Failed to parse "{0}" as a semantic version. + {0} is a version string that the user entered that was not parsed as a Semantic Version + Specify one package reference to add. Spécifiez une seule référence de package à ajouter. @@ -68,8 +73,8 @@ - The package reference to add. - Référence du package à ajouter. + The package reference to add. This can be in the form of just the package identifier, for example 'Newtonsoft.Json', or a package identifier and version separated by '@', for example 'Newtonsoft.Json@13.0.3' + Référence du package à ajouter. @@ -82,6 +87,11 @@ Impossible de générer un fichier temporaire pour le projet '{0}'. Impossible d'ajouter une référence de package. Effacez le répertoire temporaire et réessayez. + + Cannot specify --version when the package argument already contains a version. + Cannot specify --version when the package argument already contains a version. + {Locked="--version"} + \ No newline at end of file diff --git a/src/Cli/dotnet/Commands/Package/Add/xlf/LocalizableStrings.it.xlf b/src/Cli/dotnet/Commands/Package/Add/xlf/LocalizableStrings.it.xlf index 629cf76b64b8..310508b7003c 100644 --- a/src/Cli/dotnet/Commands/Package/Add/xlf/LocalizableStrings.it.xlf +++ b/src/Cli/dotnet/Commands/Package/Add/xlf/LocalizableStrings.it.xlf @@ -12,6 +12,11 @@ Comando per aggiungere il riferimento al pacchetto + + Failed to parse "{0}" as a semantic version. + Failed to parse "{0}" as a semantic version. + {0} is a version string that the user entered that was not parsed as a Semantic Version + Specify one package reference to add. Specificare almeno un riferimento al pacchetto da aggiungere. @@ -68,8 +73,8 @@ - The package reference to add. - Riferimento al pacchetto da aggiungere. + The package reference to add. This can be in the form of just the package identifier, for example 'Newtonsoft.Json', or a package identifier and version separated by '@', for example 'Newtonsoft.Json@13.0.3' + Riferimento al pacchetto da aggiungere. @@ -82,6 +87,11 @@ Non è possibile generare un file temporaneo per il progetto '{0}'. Non è possibile aggiungere il riferimento al pacchetto. Cancellare la directory temp e riprovare. + + Cannot specify --version when the package argument already contains a version. + Cannot specify --version when the package argument already contains a version. + {Locked="--version"} + \ No newline at end of file diff --git a/src/Cli/dotnet/Commands/Package/Add/xlf/LocalizableStrings.ja.xlf b/src/Cli/dotnet/Commands/Package/Add/xlf/LocalizableStrings.ja.xlf index eecc8026b1e2..d437c9bd0ad2 100644 --- a/src/Cli/dotnet/Commands/Package/Add/xlf/LocalizableStrings.ja.xlf +++ b/src/Cli/dotnet/Commands/Package/Add/xlf/LocalizableStrings.ja.xlf @@ -12,6 +12,11 @@ パッケージ参照を追加するコマンド + + Failed to parse "{0}" as a semantic version. + Failed to parse "{0}" as a semantic version. + {0} is a version string that the user entered that was not parsed as a Semantic Version + Specify one package reference to add. 追加するパッケージ参照を 1 つ指定してください。 @@ -68,8 +73,8 @@ - The package reference to add. - 追加するパッケージ参照。 + The package reference to add. This can be in the form of just the package identifier, for example 'Newtonsoft.Json', or a package identifier and version separated by '@', for example 'Newtonsoft.Json@13.0.3' + 追加するパッケージ参照。 @@ -82,6 +87,11 @@ プロジェクト '{0}' の一時ファイルを生成できません。パッケージ参照を追加できません。一時ディレクトリをクリアして、もう一度お試しください。 + + Cannot specify --version when the package argument already contains a version. + Cannot specify --version when the package argument already contains a version. + {Locked="--version"} + \ No newline at end of file diff --git a/src/Cli/dotnet/Commands/Package/Add/xlf/LocalizableStrings.ko.xlf b/src/Cli/dotnet/Commands/Package/Add/xlf/LocalizableStrings.ko.xlf index 941619ac1eaa..eb7aab5589a6 100644 --- a/src/Cli/dotnet/Commands/Package/Add/xlf/LocalizableStrings.ko.xlf +++ b/src/Cli/dotnet/Commands/Package/Add/xlf/LocalizableStrings.ko.xlf @@ -12,6 +12,11 @@ 패키지 참조를 추가하는 명령 + + Failed to parse "{0}" as a semantic version. + Failed to parse "{0}" as a semantic version. + {0} is a version string that the user entered that was not parsed as a Semantic Version + Specify one package reference to add. 추가할 패키지 참조를 하나 지정하세요. @@ -68,8 +73,8 @@ - The package reference to add. - 추가할 패키지 참조입니다. + The package reference to add. This can be in the form of just the package identifier, for example 'Newtonsoft.Json', or a package identifier and version separated by '@', for example 'Newtonsoft.Json@13.0.3' + 추가할 패키지 참조입니다. @@ -82,6 +87,11 @@ '{0}' 프로젝트에 대한 임시 파일을 생성할 수 없습니다. 패키지 참조를 추가할 수 없습니다. 임시 디렉터리를 지우고 다시 시도하세요. + + Cannot specify --version when the package argument already contains a version. + Cannot specify --version when the package argument already contains a version. + {Locked="--version"} + \ No newline at end of file diff --git a/src/Cli/dotnet/Commands/Package/Add/xlf/LocalizableStrings.pl.xlf b/src/Cli/dotnet/Commands/Package/Add/xlf/LocalizableStrings.pl.xlf index a65173ee6311..e94857545f36 100644 --- a/src/Cli/dotnet/Commands/Package/Add/xlf/LocalizableStrings.pl.xlf +++ b/src/Cli/dotnet/Commands/Package/Add/xlf/LocalizableStrings.pl.xlf @@ -12,6 +12,11 @@ Polecenie umożliwiające dodanie odwołania do pakietu + + Failed to parse "{0}" as a semantic version. + Failed to parse "{0}" as a semantic version. + {0} is a version string that the user entered that was not parsed as a Semantic Version + Specify one package reference to add. Podaj jedno odwołanie do pakietu, które ma zostać dodane. @@ -68,8 +73,8 @@ - The package reference to add. - Odwołanie do pakietu do dodania. + The package reference to add. This can be in the form of just the package identifier, for example 'Newtonsoft.Json', or a package identifier and version separated by '@', for example 'Newtonsoft.Json@13.0.3' + Odwołanie do pakietu do dodania. @@ -82,6 +87,11 @@ Nie można wygenerować pliku tymczasowego dla projektu „{0}”. Nie można dodać odwołania do pakietu. Wyczyść katalog tymczasowy i spróbuj ponownie. + + Cannot specify --version when the package argument already contains a version. + Cannot specify --version when the package argument already contains a version. + {Locked="--version"} + \ No newline at end of file diff --git a/src/Cli/dotnet/Commands/Package/Add/xlf/LocalizableStrings.pt-BR.xlf b/src/Cli/dotnet/Commands/Package/Add/xlf/LocalizableStrings.pt-BR.xlf index 75145737d113..00697f0d0b04 100644 --- a/src/Cli/dotnet/Commands/Package/Add/xlf/LocalizableStrings.pt-BR.xlf +++ b/src/Cli/dotnet/Commands/Package/Add/xlf/LocalizableStrings.pt-BR.xlf @@ -12,6 +12,11 @@ Comando para adicionar a referência do pacote + + Failed to parse "{0}" as a semantic version. + Failed to parse "{0}" as a semantic version. + {0} is a version string that the user entered that was not parsed as a Semantic Version + Specify one package reference to add. Especifique uma referência do pacote a ser adicionada. @@ -68,8 +73,8 @@ - The package reference to add. - A referência do pacote a adicionar. + The package reference to add. This can be in the form of just the package identifier, for example 'Newtonsoft.Json', or a package identifier and version separated by '@', for example 'Newtonsoft.Json@13.0.3' + A referência do pacote a adicionar. @@ -82,6 +87,11 @@ Não é possível gerar um arquivo temporário para o projeto '{0}'. Não é possível adicionar a referência do pacote. Limpe o diretório temporário e tente novamente. + + Cannot specify --version when the package argument already contains a version. + Cannot specify --version when the package argument already contains a version. + {Locked="--version"} + \ No newline at end of file diff --git a/src/Cli/dotnet/Commands/Package/Add/xlf/LocalizableStrings.ru.xlf b/src/Cli/dotnet/Commands/Package/Add/xlf/LocalizableStrings.ru.xlf index 27fa229c8a09..31bdc0396c30 100644 --- a/src/Cli/dotnet/Commands/Package/Add/xlf/LocalizableStrings.ru.xlf +++ b/src/Cli/dotnet/Commands/Package/Add/xlf/LocalizableStrings.ru.xlf @@ -12,6 +12,11 @@ Команда добавления ссылки на пакет + + Failed to parse "{0}" as a semantic version. + Failed to parse "{0}" as a semantic version. + {0} is a version string that the user entered that was not parsed as a Semantic Version + Specify one package reference to add. Укажите одну добавляемую ссылку на пакет. @@ -68,8 +73,8 @@ - The package reference to add. - Добавляемая ссылка на пакет. + The package reference to add. This can be in the form of just the package identifier, for example 'Newtonsoft.Json', or a package identifier and version separated by '@', for example 'Newtonsoft.Json@13.0.3' + Добавляемая ссылка на пакет. @@ -82,6 +87,11 @@ Не удалось создать временный файл для проекта "{0}". Невозможно добавить ссылку на пакет. Очистите временный каталог и повторите попытку. + + Cannot specify --version when the package argument already contains a version. + Cannot specify --version when the package argument already contains a version. + {Locked="--version"} + \ No newline at end of file diff --git a/src/Cli/dotnet/Commands/Package/Add/xlf/LocalizableStrings.tr.xlf b/src/Cli/dotnet/Commands/Package/Add/xlf/LocalizableStrings.tr.xlf index 0dc7404df3bd..341ae580a2f5 100644 --- a/src/Cli/dotnet/Commands/Package/Add/xlf/LocalizableStrings.tr.xlf +++ b/src/Cli/dotnet/Commands/Package/Add/xlf/LocalizableStrings.tr.xlf @@ -12,6 +12,11 @@ Paket başvurusu ekleme komutu + + Failed to parse "{0}" as a semantic version. + Failed to parse "{0}" as a semantic version. + {0} is a version string that the user entered that was not parsed as a Semantic Version + Specify one package reference to add. Eklenecek tek bir paket başvurusu belirtin. @@ -68,8 +73,8 @@ - The package reference to add. - Eklenecek paket başvurusu. + The package reference to add. This can be in the form of just the package identifier, for example 'Newtonsoft.Json', or a package identifier and version separated by '@', for example 'Newtonsoft.Json@13.0.3' + Eklenecek paket başvurusu. @@ -82,6 +87,11 @@ '{0}' projesi için geçici dosya oluşturulamıyor. Paket başvurusu eklenemiyor. Geçici dizini temizleyin ve yeniden deneyin. + + Cannot specify --version when the package argument already contains a version. + Cannot specify --version when the package argument already contains a version. + {Locked="--version"} + \ No newline at end of file diff --git a/src/Cli/dotnet/Commands/Package/Add/xlf/LocalizableStrings.zh-Hans.xlf b/src/Cli/dotnet/Commands/Package/Add/xlf/LocalizableStrings.zh-Hans.xlf index 2a5be0a652ca..15cc0709b2b4 100644 --- a/src/Cli/dotnet/Commands/Package/Add/xlf/LocalizableStrings.zh-Hans.xlf +++ b/src/Cli/dotnet/Commands/Package/Add/xlf/LocalizableStrings.zh-Hans.xlf @@ -12,6 +12,11 @@ 添加包引用的命令 + + Failed to parse "{0}" as a semantic version. + Failed to parse "{0}" as a semantic version. + {0} is a version string that the user entered that was not parsed as a Semantic Version + Specify one package reference to add. 请指定一个要添加的包引用。 @@ -68,8 +73,8 @@ - The package reference to add. - 要添加的包引用。 + The package reference to add. This can be in the form of just the package identifier, for example 'Newtonsoft.Json', or a package identifier and version separated by '@', for example 'Newtonsoft.Json@13.0.3' + 要添加的包引用。 @@ -82,6 +87,11 @@ 无法为项目“{0}”生成临时文件。无法添加包引用。请清除临时目录,然后再重试。 + + Cannot specify --version when the package argument already contains a version. + Cannot specify --version when the package argument already contains a version. + {Locked="--version"} + \ No newline at end of file diff --git a/src/Cli/dotnet/Commands/Package/Add/xlf/LocalizableStrings.zh-Hant.xlf b/src/Cli/dotnet/Commands/Package/Add/xlf/LocalizableStrings.zh-Hant.xlf index fdd3cac77090..5fb317eb33a0 100644 --- a/src/Cli/dotnet/Commands/Package/Add/xlf/LocalizableStrings.zh-Hant.xlf +++ b/src/Cli/dotnet/Commands/Package/Add/xlf/LocalizableStrings.zh-Hant.xlf @@ -12,6 +12,11 @@ 用以新增套件參考的命令 + + Failed to parse "{0}" as a semantic version. + Failed to parse "{0}" as a semantic version. + {0} is a version string that the user entered that was not parsed as a Semantic Version + Specify one package reference to add. 請指定一個要新增的套件參考。 @@ -68,8 +73,8 @@ - The package reference to add. - 要新增的套件參考。 + The package reference to add. This can be in the form of just the package identifier, for example 'Newtonsoft.Json', or a package identifier and version separated by '@', for example 'Newtonsoft.Json@13.0.3' + 要新增的套件參考。 @@ -82,6 +87,11 @@ 無法產生專案 '{0}' 的暫存檔案。無法新增套件參考。請清除該暫存目錄,然後再試一次。 + + Cannot specify --version when the package argument already contains a version. + Cannot specify --version when the package argument already contains a version. + {Locked="--version"} + \ No newline at end of file diff --git a/src/Cli/dotnet/Commands/Package/PackageCommandParser.cs b/src/Cli/dotnet/Commands/Package/PackageCommandParser.cs index ba648db24f5b..75c4637c73dc 100644 --- a/src/Cli/dotnet/Commands/Package/PackageCommandParser.cs +++ b/src/Cli/dotnet/Commands/Package/PackageCommandParser.cs @@ -10,9 +10,11 @@ internal class PackageCommandParser { private const string DocsLink = "https://aka.ms/dotnet-package"; - public static readonly CliOption ProjectOption = new("--project") + public static readonly CliOption ProjectOption = new CliOption("--project") { - Recursive = true + Recursive = true, + DefaultValueFactory = _ => Environment.CurrentDirectory, + Description = CommonLocalizableStrings.ProjectArgumentDescription }; public static CliCommand GetCommand() diff --git a/src/Cli/dotnet/Extensions/ParseResultExtensions.cs b/src/Cli/dotnet/Extensions/ParseResultExtensions.cs index 9da8a09a9c74..bb7e9353377b 100644 --- a/src/Cli/dotnet/Extensions/ParseResultExtensions.cs +++ b/src/Cli/dotnet/Extensions/ParseResultExtensions.cs @@ -261,5 +261,9 @@ public static T SafelyGetValueForOption(this ParseResult parseResult, CliOpti } } - public static bool HasOption(this ParseResult parseResult, CliOption option) => parseResult.GetResult(option) is not null; + /// + /// Checks if the option is present and not implicit (i.e. not set by default). + /// This is useful for checking if the user has explicitly set an option, as opposed to it being set by default. + /// + public static bool HasOption(this ParseResult parseResult, CliOption option) => parseResult.GetResult(option) is OptionResult or && !or.Implicit; } diff --git a/test/dotnet-completions.Tests/snapshots/pwsh/DotnetCliSnapshotTests.VerifyCompletions.verified.ps1 b/test/dotnet-completions.Tests/snapshots/pwsh/DotnetCliSnapshotTests.VerifyCompletions.verified.ps1 index 7d21b4cc4f6c..23fd703b63a1 100644 --- a/test/dotnet-completions.Tests/snapshots/pwsh/DotnetCliSnapshotTests.VerifyCompletions.verified.ps1 +++ b/test/dotnet-completions.Tests/snapshots/pwsh/DotnetCliSnapshotTests.VerifyCompletions.verified.ps1 @@ -605,7 +605,7 @@ Register-ArgumentCompleter -Native -CommandName 'testhost' -ScriptBlock { [CompletionResult]::new('--package-directory', '--package-directory', [CompletionResultType]::ParameterName, "The directory to restore packages to.") [CompletionResult]::new('--interactive', '--interactive', [CompletionResultType]::ParameterName, "Allows the command to stop and wait for user input or action (for example to complete authentication).") [CompletionResult]::new('--prerelease', '--prerelease', [CompletionResultType]::ParameterName, "Allows prerelease packages to be installed.") - [CompletionResult]::new('--project', '--project', [CompletionResultType]::ParameterName, "--project") + [CompletionResult]::new('--project', '--project', [CompletionResultType]::ParameterName, "The project file to operate on. If a file is not specified, the command will search the current directory for one.") [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, "Show command line help.") [CompletionResult]::new('--help', '-h', [CompletionResultType]::ParameterName, "Show command line help.") ) @@ -636,7 +636,7 @@ Register-ArgumentCompleter -Native -CommandName 'testhost' -ScriptBlock { [CompletionResult]::new('--interactive', '--interactive', [CompletionResultType]::ParameterName, "Allows the command to stop and wait for user input or action (for example to complete authentication).") [CompletionResult]::new('--format', '--format', [CompletionResultType]::ParameterName, "Specifies the output format type for the list packages command.") [CompletionResult]::new('--output-version', '--output-version', [CompletionResultType]::ParameterName, "Specifies the version of machine-readable output. Requires the `'--format json`' option.") - [CompletionResult]::new('--project', '--project', [CompletionResultType]::ParameterName, "--project") + [CompletionResult]::new('--project', '--project', [CompletionResultType]::ParameterName, "The project file to operate on. If a file is not specified, the command will search the current directory for one.") [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, "Show command line help.") [CompletionResult]::new('--help', '-h', [CompletionResultType]::ParameterName, "Show command line help.") ) @@ -646,7 +646,7 @@ Register-ArgumentCompleter -Native -CommandName 'testhost' -ScriptBlock { 'testhost;package;remove' { $staticCompletions = @( [CompletionResult]::new('--interactive', '--interactive', [CompletionResultType]::ParameterName, "Allows the command to stop and wait for user input or action (for example to complete authentication).") - [CompletionResult]::new('--project', '--project', [CompletionResultType]::ParameterName, "--project") + [CompletionResult]::new('--project', '--project', [CompletionResultType]::ParameterName, "The project file to operate on. If a file is not specified, the command will search the current directory for one.") [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, "Show command line help.") [CompletionResult]::new('--help', '-h', [CompletionResultType]::ParameterName, "Show command line help.") ) diff --git a/test/dotnet-completions.Tests/snapshots/zsh/DotnetCliSnapshotTests.VerifyCompletions.verified.zsh b/test/dotnet-completions.Tests/snapshots/zsh/DotnetCliSnapshotTests.VerifyCompletions.verified.zsh index 31f1aad366d5..f024fe39cb17 100644 --- a/test/dotnet-completions.Tests/snapshots/zsh/DotnetCliSnapshotTests.VerifyCompletions.verified.zsh +++ b/test/dotnet-completions.Tests/snapshots/zsh/DotnetCliSnapshotTests.VerifyCompletions.verified.zsh @@ -593,10 +593,10 @@ _testhost() { '--package-directory=[The directory to restore packages to.]:PACKAGE_DIR: ' \ '--interactive[Allows the command to stop and wait for user input or action (for example to complete authentication).]' \ '--prerelease[Allows prerelease packages to be installed.]' \ - '--project=[]: : ' \ + '--project=[The project file to operate on. If a file is not specified, the command will search the current directory for one.]: : ' \ '--help[Show command line help.]' \ '-h[Show command line help.]' \ - ':PACKAGE_NAME -- The package reference to add.:->dotnet_dynamic_complete' \ + ':PACKAGE_NAME -- The package reference to add. This can be in the form of just the package identifier, for example '\''Newtonsoft.Json'\'', or a package identifier and version separated by '\''@'\'', for example '\''Newtonsoft.Json@13.0.3'\'':->dotnet_dynamic_complete' \ && ret=0 case $state in (dotnet_dynamic_complete) @@ -629,7 +629,7 @@ _testhost() { '--interactive[Allows the command to stop and wait for user input or action (for example to complete authentication).]' \ '--format=[Specifies the output format type for the list packages command.]: :((console\:"console" json\:"json" ))' \ '--output-version=[Specifies the version of machine-readable output. Requires the '\''--format json'\'' option.]: : ' \ - '--project=[]: : ' \ + '--project=[The project file to operate on. If a file is not specified, the command will search the current directory for one.]: : ' \ '--help[Show command line help.]' \ '-h[Show command line help.]' \ && ret=0 @@ -637,7 +637,7 @@ _testhost() { (remove) _arguments "${_arguments_options[@]}" : \ '--interactive[Allows the command to stop and wait for user input or action (for example to complete authentication).]' \ - '--project=[]: : ' \ + '--project=[The project file to operate on. If a file is not specified, the command will search the current directory for one.]: : ' \ '--help[Show command line help.]' \ '-h[Show command line help.]' \ '*::PACKAGE_NAME -- The package reference to remove.: ' \