winget-cli

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

commit cfd8b296f3339f6ef6b714af8d4f9959a78fc9c1
parent 64378e18e4c3955592bc8571b1960382b3824e57
Author: Chacón <lechacon@users.noreply.github.com>
Date:   Wed,  5 Jan 2022 11:07:02 -0800

Add support for UnsupportedOSArchitecture manifest entry (#1807)


Diffstat:
Msrc/AppInstallerCLICore/Workflows/ManifestComparator.cpp | 22+++++++++++++++++++---
Msrc/AppInstallerCLICore/Workflows/WorkflowBase.cpp | 2--
Msrc/AppInstallerCLITests/ManifestComparator.cpp | 50+++++++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 68 insertions(+), 6 deletions(-)

diff --git a/src/AppInstallerCLICore/Workflows/ManifestComparator.cpp b/src/AppInstallerCLICore/Workflows/ManifestComparator.cpp @@ -104,11 +104,12 @@ namespace AppInstaller::CLI::Workflow InapplicabilityFlags IsApplicable(const Manifest::ManifestInstaller& installer) override { - if (CheckAllowedArchitecture(installer.Arch) == Utility::InapplicableArchitecture) + if (CheckAllowedArchitecture(installer.Arch) == Utility::InapplicableArchitecture || + IsSystemArchitectureUnsupportedByInstaller(installer)) { return InapplicabilityFlags::MachineArchitecture; } - + return InapplicabilityFlags::None; } @@ -118,12 +119,18 @@ namespace AppInstaller::CLI::Workflow if (Utility::IsApplicableArchitecture(installer.Arch) == Utility::InapplicableArchitecture) { result = "Machine is not compatible with "; + result += Utility::ToString(installer.Arch); + } + else if (IsSystemArchitectureUnsupportedByInstaller(installer)) + { + result = "System architecture is unsupported by installer"; } else { result = "Architecture was excluded by caller : "; + result += Utility::ToString(installer.Arch); } - result += Utility::ToString(installer.Arch); + return result; } @@ -153,6 +160,15 @@ namespace AppInstaller::CLI::Workflow } } + bool IsSystemArchitectureUnsupportedByInstaller(const ManifestInstaller& installer) + { + auto unsupportedItr = std::find( + installer.UnsupportedOSArchitectures.begin(), + installer.UnsupportedOSArchitectures.end(), + Utility::GetSystemArchitecture()); + return unsupportedItr != installer.UnsupportedOSArchitectures.end(); + } + std::string GetAllowedArchitecturesString() { std::stringstream result; diff --git a/src/AppInstallerCLICore/Workflows/WorkflowBase.cpp b/src/AppInstallerCLICore/Workflows/WorkflowBase.cpp @@ -989,7 +989,6 @@ namespace AppInstaller::CLI::Workflow std::vector<Utility::Architecture> requiredArchitectures = Settings::User().Get<Settings::Setting::InstallArchitectureRequirement>(); std::vector<Utility::Architecture> optionalArchitectures = Settings::User().Get<Settings::Setting::InstallArchitecturePreference>(); - if (!requiredArchitectures.empty()) { context.Add<Execution::Data::AllowedArchitectures>({ requiredArchitectures.begin(), requiredArchitectures.end() }); @@ -998,7 +997,6 @@ namespace AppInstaller::CLI::Workflow { optionalArchitectures.emplace_back(Utility::Architecture::Unknown); context.Add<Execution::Data::AllowedArchitectures>({ optionalArchitectures.begin(), optionalArchitectures.end() }); - } } ManifestComparator manifestComparator(context, installationMetadata); diff --git a/src/AppInstallerCLITests/ManifestComparator.cpp b/src/AppInstallerCLITests/ManifestComparator.cpp @@ -24,7 +24,14 @@ struct ManifestComparatorTestContext : public NullStream, Context ManifestComparatorTestContext() : NullStream(), Context(*m_nullOut, *m_nullIn) {} }; -const ManifestInstaller& AddInstaller(Manifest& manifest, Architecture architecture, InstallerTypeEnum installerType, ScopeEnum scope = ScopeEnum::Unknown, std::string minOSVersion = {}, std::string locale = {}) +const ManifestInstaller& AddInstaller( + Manifest& manifest, + Architecture architecture, + InstallerTypeEnum installerType, + ScopeEnum scope = ScopeEnum::Unknown, + std::string minOSVersion = {}, + std::string locale = {}, + std::vector<Architecture> unsupportedOSArchitectures = {}) { ManifestInstaller toAdd; toAdd.Arch = architecture; @@ -32,6 +39,7 @@ const ManifestInstaller& AddInstaller(Manifest& manifest, Architecture architect toAdd.Scope = scope; toAdd.MinOSVersion = minOSVersion; toAdd.Locale = locale; + toAdd.UnsupportedOSArchitectures = unsupportedOSArchitectures; manifest.Installers.emplace_back(std::move(toAdd)); @@ -511,6 +519,46 @@ TEST_CASE("ManifestComparator_AllowedArchitecture", "[manifest_comparator]") } } +TEST_CASE("ManifestComparator_UnsupportedOSArchitecture", "[manifest_comparator]") +{ + auto systemArchitecture = GetSystemArchitecture(); + auto applicableArchitectures = GetApplicableArchitectures(); + + // Try to find an applicable architecture that is not the system architecture + auto itr = std::find_if(applicableArchitectures.begin(), applicableArchitectures.end(), [&](const auto& arch) { return arch != systemArchitecture; }); + if (itr == applicableArchitectures.end()) + { + // This test requires having an applicable architecture different from the system one. + // TODO: Does this actually happen in any arch we use? + return; + } + + auto applicableArchitecture = *itr; + + Manifest manifest; + + SECTION("System is unsupported") + { + ManifestInstaller installer = AddInstaller(manifest, applicableArchitecture, InstallerTypeEnum::Msi, {}, {}, {}, { systemArchitecture }); + + ManifestComparator mc(ManifestComparatorTestContext{}, {}); + auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest); + + REQUIRE(!result); + RequireInapplicabilities(inapplicabilities, { InapplicabilityFlags::MachineArchitecture }); + } + SECTION("Other is unsupported") + { + ManifestInstaller installer = AddInstaller(manifest, applicableArchitecture, InstallerTypeEnum::Msi, {}, {}, {}, { applicableArchitecture }); + + ManifestComparator mc(ManifestComparatorTestContext{}, {}); + auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest); + + RequireInstaller(result, installer); + REQUIRE(inapplicabilities.empty()); + } +} + TEST_CASE("ManifestComparator_Inapplicabilities", "[manifest_comparator]") { Manifest manifest;