diff --git a/src/AppInstallerCLICore/Commands/UpgradeCommand.cpp b/src/AppInstallerCLICore/Commands/UpgradeCommand.cpp
index 5ee1772210..344b33f103 100644
--- a/src/AppInstallerCLICore/Commands/UpgradeCommand.cpp
+++ b/src/AppInstallerCLICore/Commands/UpgradeCommand.cpp
@@ -17,16 +17,65 @@ namespace AppInstaller::CLI
{
namespace
{
- bool ShouldListUpgrade(Context& context)
+ // Determines whether there are any arguments only used in search queries,
+ // as opposed to listing available upgrades
+ bool HasSearchQueryArguments(Execution::Args& execArgs)
{
- for (Execution::Args::Type type : context.Args.GetTypes())
- {
- if (type != Execution::Args::Type::Source && type != Execution::Args::Type::IncludeUnknown)
- {
- return false;
- }
- }
- return true;
+ // Note that this does not include Manifest (no search) or source related args (used for listing)
+ return 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::Exact);
+ }
+
+ // Determines whether there are any arguments only used when upgrading a single package,
+ // as opposed to upgrading multiple packages or listing all available upgrades
+ bool HasArgumentsForSinglePackage(Execution::Args& execArgs)
+ {
+ return HasSearchQueryArguments(execArgs) ||
+ execArgs.Contains(Args::Type::Manifest);
+ }
+
+ // Determines whether there are any arguments only used when dealing with multiple packages,
+ // either for upgrading or for listing available upgrades.
+ bool HasArgumentsForMultiplePackages(Execution::Args& execArgs)
+ {
+ return execArgs.Contains(Args::Type::All);
+ }
+
+ // Determines whether there are any arguments only used as options during an upgrade,
+ // as opposed to listing available upgrades or selecting the packages.
+ bool HasArgumentsForInstallOptions(Execution::Args& execArgs)
+ {
+ return execArgs.Contains(Args::Type::Interactive) ||
+ execArgs.Contains(Args::Type::Silent) ||
+ execArgs.Contains(Args::Type::Log) ||
+ execArgs.Contains(Args::Type::Override) ||
+ execArgs.Contains(Args::Type::InstallLocation) ||
+ execArgs.Contains(Args::Type::HashOverride) ||
+ execArgs.Contains(Args::Type::AcceptPackageAgreements);
+ }
+
+ // Determines whether there are any arguments related to the source.
+ bool HasArgumentsForSource(Execution::Args& execArgs)
+ {
+ return execArgs.Contains(Args::Type::Source) ||
+ execArgs.Contains(Args::Type::CustomHeader) ||
+ execArgs.Contains(Args::Type::AcceptSourceAgreements);
+ }
+
+ // Determines whether we should list available upgrades, instead
+ // of performing an upgrade
+ bool ShouldListUpgrade(Execution::Args& execArgs)
+ {
+ // Valid arguments for list are only those related to the sources and which packages to include.
+ // Instead of checking for them, we check that there aren't any other arguments present.
+ return !execArgs.Contains(Args::Type::All) &&
+ !HasArgumentsForSinglePackage(execArgs) &&
+ !HasArgumentsForInstallOptions(execArgs);
}
}
@@ -109,17 +158,23 @@ namespace AppInstaller::CLI
void UpgradeCommand::ValidateArgumentsInternal(Execution::Args& execArgs) const
{
if (execArgs.Contains(Execution::Args::Type::Manifest) &&
- (execArgs.Contains(Execution::Args::Type::Query) ||
- execArgs.Contains(Execution::Args::Type::Id) ||
- execArgs.Contains(Execution::Args::Type::Name) ||
- execArgs.Contains(Execution::Args::Type::Moniker) ||
- execArgs.Contains(Execution::Args::Type::Version) ||
- execArgs.Contains(Execution::Args::Type::Channel) ||
- execArgs.Contains(Execution::Args::Type::Source) ||
- execArgs.Contains(Execution::Args::Type::Exact) ||
- execArgs.Contains(Execution::Args::Type::All)))
+ (HasSearchQueryArguments(execArgs) ||
+ HasArgumentsForMultiplePackages(execArgs) ||
+ HasArgumentsForSource(execArgs)))
+ {
+ throw CommandException(Resource::String::BothManifestAndSearchQueryProvided);
+ }
+
+
+ else if (!ShouldListUpgrade(execArgs)
+ && !HasSearchQueryArguments(execArgs)
+ && (execArgs.Contains(Args::Type::Log) ||
+ execArgs.Contains(Args::Type::Override) ||
+ execArgs.Contains(Args::Type::InstallLocation) ||
+ execArgs.Contains(Args::Type::HashOverride) ||
+ execArgs.Contains(Args::Type::AcceptPackageAgreements)))
{
- throw CommandException(Resource::String::BothManifestAndSearchQueryProvided, "");
+ throw CommandException(Resource::String::InvalidArgumentWithoutQueryError);
}
}
@@ -129,7 +184,7 @@ namespace AppInstaller::CLI
// Only allow for source failures when doing a list of available upgrades.
// We have to set it now to allow for source open failures to also just warn.
- if (ShouldListUpgrade(context))
+ if (ShouldListUpgrade(context.Args))
{
context.SetFlags(Execution::ContextFlag::TreatSourceFailuresAsWarning);
}
@@ -139,7 +194,7 @@ namespace AppInstaller::CLI
Workflow::OpenSource() <<
Workflow::OpenCompositeSource(Repository::PredefinedSource::Installed);
- if (ShouldListUpgrade(context))
+ if (ShouldListUpgrade(context.Args))
{
// Upgrade with no args list packages with updates available
context <<
diff --git a/src/AppInstallerCLICore/Resources.h b/src/AppInstallerCLICore/Resources.h
index 5f5af6ce33..9fa6921885 100644
--- a/src/AppInstallerCLICore/Resources.h
+++ b/src/AppInstallerCLICore/Resources.h
@@ -151,6 +151,7 @@ namespace AppInstaller::CLI::Resource
WINGET_DEFINE_RESOURCE_STRINGID(InvalidArgumentSpecifierError);
WINGET_DEFINE_RESOURCE_STRINGID(InvalidArgumentValueError);
WINGET_DEFINE_RESOURCE_STRINGID(InvalidArgumentValueErrorWithoutValidValues);
+ WINGET_DEFINE_RESOURCE_STRINGID(InvalidArgumentWithoutQueryError);
WINGET_DEFINE_RESOURCE_STRINGID(InvalidJsonFile);
WINGET_DEFINE_RESOURCE_STRINGID(InvalidNameError);
WINGET_DEFINE_RESOURCE_STRINGID(LicenseAgreement);
diff --git a/src/AppInstallerCLIPackage/Shared/Strings/en-us/winget.resw b/src/AppInstallerCLIPackage/Shared/Strings/en-us/winget.resw
index 3b1a323790..cced9e4e1d 100644
--- a/src/AppInstallerCLIPackage/Shared/Strings/en-us/winget.resw
+++ b/src/AppInstallerCLIPackage/Shared/Strings/en-us/winget.resw
@@ -1269,4 +1269,7 @@ Please specify one of them using the `--source` option to proceed.
package has a version number that cannot be determined. Use "--include-unknown" to see all results.
{Locked="--include-unknown"} This string is preceded by a (integer) number of packages that do not have notated versions.
+
+ The arguments provided can only be used with a query.
+
\ No newline at end of file