winget-cli

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

commit bc473baf1b9e622bca486db903ecf83b00f96826
parent 5c6ba966b1661b2399f8c7f26380e19b951b49a2
Author: Flor Chacón <14323496+florelis@users.noreply.github.com>
Date:   Tue, 10 Jan 2023 14:10:53 -0800

Copy install behavior flags on upgrade --all (#2794)


Diffstat:
Msrc/AppInstallerCLICore/ExecutionArgs.h | 1+
Msrc/AppInstallerCLICore/ExecutionContext.cpp | 32++++++++++++++++++++++++++++++++
Msrc/AppInstallerCLICore/ExecutionContext.h | 3+++
Msrc/AppInstallerCLITests/UpdateFlow.cpp | 40++++++++++++++++++++++++++++++++++++++++
Msrc/AppInstallerCLITests/WorkflowCommon.cpp | 1+
5 files changed, 77 insertions(+), 0 deletions(-)

diff --git a/src/AppInstallerCLICore/ExecutionArgs.h b/src/AppInstallerCLICore/ExecutionArgs.h @@ -31,6 +31,7 @@ namespace AppInstaller::CLI::Execution Channel, // Install behavior + // When adding a new flag, we may need to copy it in Context::CreateSubContext() Interactive, Silent, Locale, diff --git a/src/AppInstallerCLICore/ExecutionContext.cpp b/src/AppInstallerCLICore/ExecutionContext.cpp @@ -128,9 +128,41 @@ namespace AppInstaller::CLI::Execution { clone->EnableCtrlHandler(); } + CopyArgsToSubContext(clone.get()); return clone; } + void Context::CopyArgsToSubContext(Context* subContext) + { + // Copy over install behavior flags from the parent context. + for (auto flag : { + Args::Type::Interactive, + Args::Type::Silent, + Args::Type::HashOverride, + Args::Type::IgnoreLocalArchiveMalwareScan, + Args::Type::NoUpgrade, + Args::Type::Force, + }) + { + if (Args.Contains(flag)) + { + subContext->Args.AddArg(flag); + } + } + + for (auto arg : { + Args::Type::Locale, + Args::Type::InstallScope, + Args::Type::InstallArchitecture, + }) + { + if (Args.Contains(arg)) + { + subContext->Args.AddArg(arg, Args.GetArg(arg)); + } + } + } + void Context::EnableCtrlHandler(bool enabled) { SetCtrlHandlerContext(enabled, this); diff --git a/src/AppInstallerCLICore/ExecutionContext.h b/src/AppInstallerCLICore/ExecutionContext.h @@ -155,6 +155,9 @@ namespace AppInstaller::CLI::Execution #endif protected: + // Copies the args that are also needed in a sub-context. E.g., silent + void CopyArgsToSubContext(Context* subContext); + // Neither virtual functions nor member fields can be inside AICLI_DISABLE_TEST_HOOKS // or we could have ODR violations that lead to nasty bugs. So we will simply never // use this if AICLI_DISABLE_TEST_HOOKS is defined. diff --git a/src/AppInstallerCLITests/UpdateFlow.cpp b/src/AppInstallerCLITests/UpdateFlow.cpp @@ -909,3 +909,42 @@ TEST_CASE("InstallFlow_FoundInstalledAndUpgradeNotAvailable", "[UpdateFlow][work REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::UpdateNotApplicable).get()) != std::string::npos); REQUIRE(context.GetTerminationHR() == APPINSTALLER_CLI_ERROR_UPDATE_NOT_APPLICABLE); } + +TEST_CASE("UpdateFlow_UpdateAll_ForwardArgs", "[UpdateFlow][workflow]") +{ + TestCommon::TempFile updateExeResultPath("TestExeInstalled.txt"); + TestCommon::TempFile updateMsixResultPath("TestMsixInstalled.txt"); + TestCommon::TempFile updateMSStoreResultPath("TestMSStoreUpdated.txt"); + TestCommon::TempFile updatePortableResultPath("TestPortableInstalled.txt"); + + std::ostringstream updateOutput; + TestContext context{ updateOutput, std::cin }; + auto previousThreadGlobals = context.SetForCurrentThread(); + OverrideForCompositeInstalledSource(context, CreateTestSource({ + TSR::TestInstaller_Exe, + TSR::TestInstaller_Msix, + TSR::TestInstaller_MSStore, + TSR::TestInstaller_Portable, + })); + OverrideForShellExecute(context); + OverrideForMSIX(context); + OverrideForMSStore(context, true); + OverrideForPortableInstall(context); + context.Args.AddArg(Execution::Args::Type::All); + context.Args.AddArg(Execution::Args::Type::Silent); + + UpgradeCommand update({}); + update.Execute(context); + INFO(updateOutput.str()); + + // Verify installers are called with the silent flags + REQUIRE(std::filesystem::exists(updateExeResultPath.GetPath())); + std::ifstream updateExeResultFile(updateExeResultPath.GetPath()); + std::string updateExeResultStr; + std::getline(updateExeResultFile, updateExeResultStr); + REQUIRE(updateExeResultStr.find("/silence") != std::string::npos); + + REQUIRE(std::filesystem::exists(updateMsixResultPath.GetPath())); + REQUIRE(std::filesystem::exists(updateMSStoreResultPath.GetPath())); + REQUIRE(std::filesystem::exists(updatePortableResultPath.GetPath())); +}+ \ No newline at end of file diff --git a/src/AppInstallerCLITests/WorkflowCommon.cpp b/src/AppInstallerCLITests/WorkflowCommon.cpp @@ -483,6 +483,7 @@ namespace TestCommon { auto clone = std::make_unique<TestContext>(m_out, m_in, true, m_overrides); clone->SetFlags(this->GetFlags()); + CopyArgsToSubContext(clone.get()); return clone; }