winget-cli

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 0e9711356d8d2704c15027b53f21a2950b3522a2
parent 73555181e4ae025f61d97d0e2147cdb47545d1a6
Author: JohnMcPMS <johnmcp@microsoft.com>
Date:   Wed, 27 Apr 2022 14:26:52 -0700

Require selection argument on install/show/search/uninstall (#2125)


Diffstat:
Msrc/AppInstallerCLICore/Argument.cpp | 14++++++++++++++
Msrc/AppInstallerCLICore/Argument.h | 5+++++
Msrc/AppInstallerCLICore/Commands/InstallCommand.cpp | 4+++-
Msrc/AppInstallerCLICore/Commands/SearchCommand.cpp | 5+++++
Msrc/AppInstallerCLICore/Commands/SearchCommand.h | 1+
Msrc/AppInstallerCLICore/Commands/ShowCommand.cpp | 20++++++++++++++++++++
Msrc/AppInstallerCLICore/Commands/ShowCommand.h | 1+
Msrc/AppInstallerCLICore/Commands/UninstallCommand.cpp | 2++
Msrc/AppInstallerCLICore/Resources.h | 1+
Msrc/AppInstallerCLIE2ETests/GroupPolicy.cs | 2+-
Msrc/AppInstallerCLIE2ETests/SearchCommand.cs | 5+----
Msrc/AppInstallerCLIE2ETests/ShowCommand.cs | 7+------
Msrc/AppInstallerCLIPackage/Shared/Strings/en-us/winget.resw | 3+++
13 files changed, 58 insertions(+), 12 deletions(-)

diff --git a/src/AppInstallerCLICore/Argument.cpp b/src/AppInstallerCLICore/Argument.cpp @@ -2,6 +2,7 @@ // Licensed under the MIT License. #include "pch.h" #include "Argument.h" +#include "Command.h" #include "Resources.h" #include <winget/UserSettings.h> @@ -108,6 +109,19 @@ namespace AppInstaller::CLI args.push_back(ForType(Args::Type::VerboseLogs)); } + void Argument::ValidatePackageSelectionArgumentSupplied(const Execution::Args& args) + { + for (Args::Type type : { Args::Type::Query, Args::Type::Manifest, Args::Type::Id, Args::Type::Name, Args::Type::Moniker, Args::Type::Tag, Args::Type::Command }) + { + if (args.Contains(type)) + { + return; + } + } + + throw CommandException(Resource::String::NoPackageSelectionArgumentProvided); + } + Argument::Visibility Argument::GetVisibility() const { if (!ExperimentalFeature::IsEnabled(m_feature)) diff --git a/src/AppInstallerCLICore/Argument.h b/src/AppInstallerCLICore/Argument.h @@ -81,6 +81,11 @@ namespace AppInstaller::CLI // Gets the common arguments for all commands. static void GetCommon(std::vector<Argument>& args); + // Static argument validation helpers; throw CommandException when validation fails. + + // Requires that some form of package selection argument is present + static void ValidatePackageSelectionArgumentSupplied(const Execution::Args& args); + // Arguments are not localized at this time. Utility::LocIndView Name() const { return Utility::LocIndView{ m_name }; } char Alias() const { return m_alias; } diff --git a/src/AppInstallerCLICore/Commands/InstallCommand.cpp b/src/AppInstallerCLICore/Commands/InstallCommand.cpp @@ -93,6 +93,8 @@ namespace AppInstaller::CLI void InstallCommand::ValidateArgumentsInternal(Args& execArgs) const { + Argument::ValidatePackageSelectionArgumentSupplied(execArgs); + if (execArgs.Contains(Args::Type::Manifest) && (execArgs.Contains(Args::Type::Query) || execArgs.Contains(Args::Type::Id) || @@ -115,7 +117,7 @@ namespace AppInstaller::CLI } if (execArgs.Contains(Args::Type::InstallArchitecture)) { - Utility::Architecture selectedArch = Utility::ConvertToArchitectureEnum(std::string(execArgs.GetArg(Args::Type::InstallArchitecture))); + Utility::Architecture selectedArch = Utility::ConvertToArchitectureEnum(std::string(execArgs.GetArg(Args::Type::InstallArchitecture))); if ((selectedArch == Utility::Architecture::Unknown) || (Utility::IsApplicableArchitecture(selectedArch) == Utility::InapplicableArchitecture)) { std::vector<Utility::LocIndString> applicableArchitectures; diff --git a/src/AppInstallerCLICore/Commands/SearchCommand.cpp b/src/AppInstallerCLICore/Commands/SearchCommand.cpp @@ -66,6 +66,11 @@ namespace AppInstaller::CLI return "https://aka.ms/winget-command-search"; } + void SearchCommand::ValidateArgumentsInternal(Args& execArgs) const + { + Argument::ValidatePackageSelectionArgumentSupplied(execArgs); + } + void SearchCommand::ExecuteInternal(Context& context) const { context.SetFlags(Execution::ContextFlag::TreatSourceFailuresAsWarning); diff --git a/src/AppInstallerCLICore/Commands/SearchCommand.h b/src/AppInstallerCLICore/Commands/SearchCommand.h @@ -19,6 +19,7 @@ namespace AppInstaller::CLI std::string HelpLink() const override; protected: + void ValidateArgumentsInternal(Execution::Args& execArgs) const override; void ExecuteInternal(Execution::Context& context) const override; }; } diff --git a/src/AppInstallerCLICore/Commands/ShowCommand.cpp b/src/AppInstallerCLICore/Commands/ShowCommand.cpp @@ -7,6 +7,8 @@ #include "Workflows/WorkflowBase.h" #include "Resources.h" +using namespace AppInstaller::CLI::Execution; + namespace AppInstaller::CLI { std::vector<Argument> ShowCommand::GetArguments() const @@ -49,6 +51,24 @@ namespace AppInstaller::CLI return "https://aka.ms/winget-command-show"; } + void ShowCommand::ValidateArgumentsInternal(Args& execArgs) const + { + Argument::ValidatePackageSelectionArgumentSupplied(execArgs); + + if (execArgs.Contains(Args::Type::Manifest) && + (execArgs.Contains(Args::Type::Query) || + execArgs.Contains(Args::Type::Id) || + execArgs.Contains(Args::Type::Name) || + execArgs.Contains(Args::Type::Moniker) || + execArgs.Contains(Args::Type::Version) || + execArgs.Contains(Args::Type::Channel) || + execArgs.Contains(Args::Type::Source) || + execArgs.Contains(Args::Type::Exact))) + { + throw CommandException(Resource::String::BothManifestAndSearchQueryProvided); + } + } + void ShowCommand::ExecuteInternal(Execution::Context& context) const { context.SetFlags(Execution::ContextFlag::TreatSourceFailuresAsWarning); diff --git a/src/AppInstallerCLICore/Commands/ShowCommand.h b/src/AppInstallerCLICore/Commands/ShowCommand.h @@ -19,6 +19,7 @@ namespace AppInstaller::CLI std::string HelpLink() const override; protected: + void ValidateArgumentsInternal(Execution::Args& execArgs) const override; void ExecuteInternal(AppInstaller::CLI::Execution::Context& context) const override; }; } diff --git a/src/AppInstallerCLICore/Commands/UninstallCommand.cpp b/src/AppInstallerCLICore/Commands/UninstallCommand.cpp @@ -83,6 +83,8 @@ namespace AppInstaller::CLI void UninstallCommand::ValidateArgumentsInternal(Execution::Args& execArgs) const { + Argument::ValidatePackageSelectionArgumentSupplied(execArgs); + if (execArgs.Contains(Execution::Args::Type::Manifest) && (execArgs.Contains(Execution::Args::Type::Query) || execArgs.Contains(Execution::Args::Type::Id) || diff --git a/src/AppInstallerCLICore/Resources.h b/src/AppInstallerCLICore/Resources.h @@ -187,6 +187,7 @@ namespace AppInstaller::CLI::Resource WINGET_DEFINE_RESOURCE_STRINGID(NoExperimentalFeaturesMessage); WINGET_DEFINE_RESOURCE_STRINGID(NoInstalledPackageFound); WINGET_DEFINE_RESOURCE_STRINGID(NoPackageFound); + WINGET_DEFINE_RESOURCE_STRINGID(NoPackageSelectionArgumentProvided); WINGET_DEFINE_RESOURCE_STRINGID(NoPackagesFoundInImportFile); WINGET_DEFINE_RESOURCE_STRINGID(NoUninstallInfoFound); WINGET_DEFINE_RESOURCE_STRINGID(NoVTArgumentDescription); diff --git a/src/AppInstallerCLIE2ETests/GroupPolicy.cs b/src/AppInstallerCLIE2ETests/GroupPolicy.cs @@ -29,7 +29,7 @@ namespace AppInstallerCLIE2ETests public void PolicyEnableWinget() { GroupPolicyHelper.EnableWinget.Disable(); - var result = TestCommon.RunAICLICommand("search", string.Empty); + var result = TestCommon.RunAICLICommand("search", "foo"); Assert.AreEqual(Constants.ErrorCode.ERROR_BLOCKED_BY_POLICY, result.ExitCode); } diff --git a/src/AppInstallerCLIE2ETests/SearchCommand.cs b/src/AppInstallerCLIE2ETests/SearchCommand.cs @@ -11,10 +11,7 @@ namespace AppInstallerCLIE2ETests public void SearchWithoutArgs() { var result = TestCommon.RunAICLICommand("search", ""); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains("AppInstallerTest.TestExeInstaller")); - Assert.True(result.StdOut.Contains("AppInstallerTest.TestBurnInstaller")); - Assert.True(result.StdOut.Contains("AppInstallerTest.TestExampleInstaller")); + Assert.AreEqual(Constants.ErrorCode.ERROR_INVALID_CL_ARGUMENTS, result.ExitCode); } [Test] diff --git a/src/AppInstallerCLIE2ETests/ShowCommand.cs b/src/AppInstallerCLIE2ETests/ShowCommand.cs @@ -10,13 +10,8 @@ namespace AppInstallerCLIE2ETests [Test] public void ShowWithNoArgs() { - // Show with no arg lists every app and a warning message var result = TestCommon.RunAICLICommand("show", ""); - Assert.AreEqual(Constants.ErrorCode.ERROR_MULTIPLE_APPLICATIONS_FOUND, result.ExitCode); - Assert.True(result.StdOut.Contains("Multiple packages found matching input criteria. Please refine the input.")); - Assert.True(result.StdOut.Contains("AppInstallerTest.TestExeInstaller")); - Assert.True(result.StdOut.Contains("AppInstallerTest.TestBurnInstaller")); - Assert.True(result.StdOut.Contains("AppInstallerTest.TestExampleInstaller")); + Assert.AreEqual(Constants.ErrorCode.ERROR_INVALID_CL_ARGUMENTS, result.ExitCode); } [Test] diff --git a/src/AppInstallerCLIPackage/Shared/Strings/en-us/winget.resw b/src/AppInstallerCLIPackage/Shared/Strings/en-us/winget.resw @@ -1287,4 +1287,7 @@ Please specify one of them using the `--source` option to proceed.</value> <data name="WaitArgumentDescription" xml:space="preserve"> <value>Prompts the user to press any key before exiting</value> </data> + <data name="NoPackageSelectionArgumentProvided" xml:space="preserve"> + <value>No package selection argument was provided; see the help for details about finding a package.</value> + </data> </root> \ No newline at end of file