winget-cli

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

Manifest.cpp (8505B)


      1 // Copyright (c) Microsoft Corporation.
      2 // Licensed under the MIT License.
      3 #include "pch.h"
      4 #include "winget/Manifest.h"
      5 #include "winget/Locale.h"
      6 #include "winget/UserSettings.h"
      7 
      8 namespace AppInstaller::Manifest
      9 {
     10     namespace
     11     {
     12         void AddFoldedStringToSetIfNotEmpty(std::set<string_t>& set, const string_t& value)
     13         {
     14             if (!value.empty())
     15             {
     16                 set.emplace(Utility::FoldCase(value));
     17             }
     18         }
     19     }
     20 
     21     void Manifest::ApplyLocale(const std::string& locale)
     22     {
     23         CurrentLocalization = DefaultLocalization;
     24 
     25         // Get target locale from Preferred Languages settings if applicable
     26         std::vector<std::string> targetLocales;
     27         if (locale.empty())
     28         {
     29             targetLocales = Locale::GetUserPreferredLanguages();
     30         }
     31         else
     32         {
     33             targetLocales.emplace_back(locale);
     34         }
     35 
     36         for (auto const& targetLocale : targetLocales)
     37         {
     38             const ManifestLocalization* bestLocalization = nullptr;
     39             double bestScore = Locale::GetDistanceOfLanguage(targetLocale, DefaultLocalization.Locale);
     40 
     41             for (auto const& localization : Localizations)
     42             {
     43                 double score = Locale::GetDistanceOfLanguage(targetLocale, localization.Locale);
     44                 if (score > bestScore)
     45                 {
     46                     bestLocalization = &localization;
     47                     bestScore = score;
     48                 }
     49             }
     50 
     51             // If there's better locale than default And is compatible with target locale, merge and return;
     52             if (bestScore >= Locale::MinimumDistanceScoreAsCompatibleMatch)
     53             {
     54                 if (bestLocalization != nullptr)
     55                 {
     56                     CurrentLocalization.ReplaceOrMergeWith(*bestLocalization);
     57                 }
     58                 break;
     59             }
     60         }
     61     }
     62 
     63     std::vector<string_t> Manifest::GetAggregatedTags() const
     64     {
     65         std::vector<string_t> resultTags = DefaultLocalization.Get<Localization::Tags>();
     66 
     67         for (const auto& locale : Localizations)
     68         {
     69             auto tags = locale.Get<Localization::Tags>();
     70             for (const auto& tag : tags)
     71             {
     72                 if (std::find(resultTags.begin(), resultTags.end(), tag) == resultTags.end())
     73                 {
     74                     resultTags.emplace_back(tag);
     75                 }
     76             }
     77         }
     78 
     79         return resultTags;
     80     }
     81 
     82     std::vector<string_t> Manifest::GetAggregatedCommands() const
     83     {
     84         std::vector<string_t> resultCommands;
     85 
     86         for (const auto& installer : Installers)
     87         {
     88             for (const auto& command : installer.Commands)
     89             {
     90                 if (std::find(resultCommands.begin(), resultCommands.end(), command) == resultCommands.end())
     91                 {
     92                     resultCommands.emplace_back(command);
     93                 }
     94             }
     95         }
     96 
     97         return resultCommands;
     98     }
     99 
    100     Utility::VersionRange Manifest::GetArpVersionRange() const
    101     {
    102         bool arpVersionFound = false;
    103         Utility::Version minVersion;
    104         Utility::Version maxVersion;
    105 
    106         for (auto const& installer : Installers)
    107         {
    108             if (DoesInstallerTypeSupportArpVersionRange(installer.EffectiveInstallerType()))
    109             {
    110                 for (auto const& entry : installer.AppsAndFeaturesEntries)
    111                 {
    112                     if (!entry.DisplayVersion.empty())
    113                     {
    114                         Utility::Version arpVersion{ entry.DisplayVersion };
    115 
    116                         if (!arpVersionFound)
    117                         {
    118                             // This is the first arp version found, populate both min and max version
    119                             minVersion = arpVersion;
    120                             maxVersion = arpVersion;
    121                             arpVersionFound = true;
    122                             continue;
    123                         }
    124 
    125                         if (arpVersion < minVersion)
    126                         {
    127                             minVersion = arpVersion;
    128                         }
    129                         else if (arpVersion > maxVersion)
    130                         {
    131                             maxVersion = arpVersion;
    132                         }
    133                     }
    134                 }
    135             }
    136         }
    137 
    138         return arpVersionFound ? Utility::VersionRange{ minVersion, maxVersion } : Utility::VersionRange{};
    139     }
    140 
    141     std::vector<string_t> Manifest::GetPackageFamilyNames() const
    142     {
    143         return GetSystemReferenceStrings(
    144             [](const ManifestInstaller& i) -> const Utility::NormalizedString& { return i.PackageFamilyName; });
    145     }
    146 
    147     std::vector<string_t> Manifest::GetProductCodes() const
    148     {
    149         return GetSystemReferenceStrings(
    150             [](const ManifestInstaller& i) -> const Utility::NormalizedString& { return i.ProductCode; },
    151             [](const AppsAndFeaturesEntry& e) -> const Utility::NormalizedString& { return e.ProductCode; });
    152     }
    153 
    154     std::vector<string_t> Manifest::GetUpgradeCodes() const
    155     {
    156         return GetSystemReferenceStrings(
    157             {},
    158             [](const AppsAndFeaturesEntry& e) -> const Utility::NormalizedString& { return e.UpgradeCode; });
    159     }
    160 
    161     std::vector<string_t> Manifest::GetPackageNames() const
    162     {
    163         std::set<string_t> set;
    164 
    165         AddFoldedStringToSetIfNotEmpty(set, DefaultLocalization.Get<Localization::PackageName>());
    166         for (const auto& loc : Localizations)
    167         {
    168             AddFoldedStringToSetIfNotEmpty(set, loc.Get<Localization::PackageName>());
    169         }
    170 
    171         // In addition to the names used for our display, add the display names from the ARP entries
    172         for (const auto& installer : Installers)
    173         {
    174             for (const auto& appsAndFeaturesEntry : installer.AppsAndFeaturesEntries)
    175             {
    176                 AddFoldedStringToSetIfNotEmpty(set, appsAndFeaturesEntry.DisplayName);
    177             }
    178         }
    179 
    180         std::vector<Utility::NormalizedString> result(
    181             std::make_move_iterator(set.begin()),
    182             std::make_move_iterator(set.end()));
    183 
    184         return result;
    185     }
    186 
    187     std::vector<string_t> Manifest::GetPublishers() const
    188     {
    189         std::set<string_t> set;
    190 
    191         AddFoldedStringToSetIfNotEmpty(set, DefaultLocalization.Get<Localization::Publisher>());
    192         for (const auto& loc : Localizations)
    193         {
    194             AddFoldedStringToSetIfNotEmpty(set, loc.Get<Localization::Publisher>());
    195         }
    196 
    197         // In addition to the publishers used for our display, add the publisher from the ARP entries
    198         for (const auto& installer : Installers)
    199         {
    200             for (const auto& appsAndFeaturesEntry : installer.AppsAndFeaturesEntries)
    201             {
    202                 AddFoldedStringToSetIfNotEmpty(set, appsAndFeaturesEntry.Publisher);
    203             }
    204         }
    205 
    206         std::vector<Utility::NormalizedString> result(
    207             std::make_move_iterator(set.begin()),
    208             std::make_move_iterator(set.end()));
    209 
    210         return result;
    211     }
    212 
    213     std::vector<string_t> Manifest::GetSystemReferenceStrings(
    214         std::function<const string_t& (const ManifestInstaller&)> extractStringFromInstaller,
    215         std::function<const string_t& (const AppsAndFeaturesEntry&)> extractStringFromAppsAndFeaturesEntry) const
    216     {
    217         std::set<string_t> set;
    218 
    219         for (const auto& installer : Installers)
    220         {
    221             if (extractStringFromInstaller)
    222             {
    223                 const auto& installerString = extractStringFromInstaller(installer);
    224                 AddFoldedStringToSetIfNotEmpty(set, installerString);
    225             }
    226 
    227             if (extractStringFromAppsAndFeaturesEntry)
    228             {
    229                 for (const auto& entry : installer.AppsAndFeaturesEntries)
    230                 {
    231                     const auto& entryString = extractStringFromAppsAndFeaturesEntry(entry);
    232                     AddFoldedStringToSetIfNotEmpty(set, entryString);
    233                 }
    234             }
    235         }
    236 
    237         std::vector<Utility::NormalizedString> result(
    238             std::make_move_iterator(set.begin()),
    239             std::make_move_iterator(set.end()));
    240 
    241         return result;
    242     }
    243 }