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:
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