winget-cli

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

commit d2a9c6d84900318da14d2706b7f44757c6f1166c
parent 603254dde60172c3924b7564e75121726e11031c
Author: JohnMcPMS <johnmcp@microsoft.com>
Date:   Thu, 24 Mar 2022 14:15:58 -0700

Use AppsAndFeatures name and publisher (#2042)


Diffstat:
Msrc/AppInstallerCLI.sln | 19-------------------
Msrc/AppInstallerCLICore/Workflows/InstallFlow.cpp | 33+++++++++++++++++++++------------
Msrc/AppInstallerCLITests/SQLiteIndex.cpp | 70++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/AppInstallerRepositoryCore/Microsoft/Schema/1_2/Interface_1_2.cpp | 54++++++++++++++++++++++++++++++++++++++++++++----------
4 files changed, 135 insertions(+), 41 deletions(-)

diff --git a/src/AppInstallerCLI.sln b/src/AppInstallerCLI.sln @@ -86,21 +86,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "spelling", "spelling", "{2A EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cpprestsdk", "cpprestsdk\cpprestsdk.vcxproj", "{866C3F06-636F-4BE8-BC24-5F86ECC606A1}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "schemas", "schemas", "{92637527-6CDA-4F4A-84FD-858793776777}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "JSON", "JSON", "{F2149997-295A-4593-9282-4C675DFEB670}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "settings", "settings", "{1487DFBB-7C53-4BD3-9B2C-9B94C6C91528}" - ProjectSection(SolutionItems) = preProject - ..\schemas\JSON\settings\settings.schema.0.2.json = ..\schemas\JSON\settings\settings.schema.0.2.json - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "packages", "packages", "{F5CED6B6-C27F-4405-9033-6C273B8B129C}" - ProjectSection(SolutionItems) = preProject - ..\schemas\JSON\packages\packages.schema.1.0.json = ..\schemas\JSON\packages\packages.schema.1.0.json - ..\schemas\JSON\packages\packages.schema.2.0.json = ..\schemas\JSON\packages\packages.schema.2.0.json - EndProjectSection -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "policy", "policy", "{1A47951F-5C7A-4D6D-BB5F-D77484437940}" ProjectSection(SolutionItems) = preProject ..\doc\admx\en-US\DesktopAppInstaller.adml = ..\doc\admx\en-US\DesktopAppInstaller.adml @@ -1020,10 +1005,6 @@ Global {952B513F-8A00-4D74-9271-925AFB3C6252} = {8D53D749-D51C-46F8-A162-9371AAA6C2E7} {2ACDE176-F13F-42FA-8159-C34FA3D37837} = {8D53D749-D51C-46F8-A162-9371AAA6C2E7} {866C3F06-636F-4BE8-BC24-5F86ECC606A1} = {60618CAC-2995-4DF9-9914-45C6FC02C995} - {92637527-6CDA-4F4A-84FD-858793776777} = {8D53D749-D51C-46F8-A162-9371AAA6C2E7} - {F2149997-295A-4593-9282-4C675DFEB670} = {92637527-6CDA-4F4A-84FD-858793776777} - {1487DFBB-7C53-4BD3-9B2C-9B94C6C91528} = {F2149997-295A-4593-9282-4C675DFEB670} - {F5CED6B6-C27F-4405-9033-6C273B8B129C} = {F2149997-295A-4593-9282-4C675DFEB670} {1A47951F-5C7A-4D6D-BB5F-D77484437940} = {8D53D749-D51C-46F8-A162-9371AAA6C2E7} {409CD681-22A4-469D-88AE-CB5E4836E07A} = {8D53D749-D51C-46F8-A162-9371AAA6C2E7} EndGlobalSection diff --git a/src/AppInstallerCLICore/Workflows/InstallFlow.cpp b/src/AppInstallerCLICore/Workflows/InstallFlow.cpp @@ -543,25 +543,24 @@ namespace AppInstaller::CLI::Workflow // Also attempt to find the entry based on the manifest data const auto& manifest = context.Get<Execution::Data::Manifest>(); - SearchRequest nameAndPublisherRequest; + SearchRequest manifestSearchRequest; + AppInstaller::Manifest::Manifest::string_t defaultPublisher; + if (manifest.DefaultLocalization.Contains(Localization::Publisher)) + { + defaultPublisher = manifest.DefaultLocalization.Get<Localization::Publisher>(); + } // The default localization must contain the name or we cannot do this lookup if (manifest.DefaultLocalization.Contains(Localization::PackageName)) { AppInstaller::Manifest::Manifest::string_t defaultName = manifest.DefaultLocalization.Get<Localization::PackageName>(); - AppInstaller::Manifest::Manifest::string_t defaultPublisher; - if (manifest.DefaultLocalization.Contains(Localization::Publisher)) - { - defaultPublisher = manifest.DefaultLocalization.Get<Localization::Publisher>(); - } - - nameAndPublisherRequest.Inclusions.emplace_back(PackageMatchFilter(PackageMatchField::NormalizedNameAndPublisher, MatchType::Exact, defaultName, defaultPublisher)); + manifestSearchRequest.Inclusions.emplace_back(PackageMatchFilter(PackageMatchField::NormalizedNameAndPublisher, MatchType::Exact, defaultName, defaultPublisher)); for (const auto& loc : manifest.Localizations) { if (loc.Contains(Localization::PackageName) || loc.Contains(Localization::Publisher)) { - nameAndPublisherRequest.Inclusions.emplace_back(PackageMatchFilter(PackageMatchField::NormalizedNameAndPublisher, MatchType::Exact, + manifestSearchRequest.Inclusions.emplace_back(PackageMatchFilter(PackageMatchField::NormalizedNameAndPublisher, MatchType::Exact, loc.Contains(Localization::PackageName) ? loc.Get<Localization::PackageName>() : defaultName, loc.Contains(Localization::Publisher) ? loc.Get<Localization::Publisher>() : defaultPublisher)); } @@ -575,18 +574,28 @@ namespace AppInstaller::CLI::Workflow { if (std::find(productCodes.begin(), productCodes.end(), installer.ProductCode) == productCodes.end()) { - nameAndPublisherRequest.Inclusions.emplace_back(PackageMatchFilter(PackageMatchField::ProductCode, MatchType::Exact, installer.ProductCode)); + manifestSearchRequest.Inclusions.emplace_back(PackageMatchFilter(PackageMatchField::ProductCode, MatchType::Exact, installer.ProductCode)); productCodes.emplace_back(installer.ProductCode); } } + + for (const auto& appsAndFeaturesEntry : installer.AppsAndFeaturesEntries) + { + if (!appsAndFeaturesEntry.DisplayName.empty()) + { + manifestSearchRequest.Inclusions.emplace_back(PackageMatchFilter(PackageMatchField::NormalizedNameAndPublisher, MatchType::Exact, + appsAndFeaturesEntry.DisplayName, + appsAndFeaturesEntry.Publisher.empty() ? defaultPublisher : appsAndFeaturesEntry.Publisher)); + } + } } SearchResult findByManifest; // Don't execute this search if it would just find everything - if (!nameAndPublisherRequest.IsForEverything()) + if (!manifestSearchRequest.IsForEverything()) { - findByManifest = arpSource.Search(nameAndPublisherRequest); + findByManifest = arpSource.Search(manifestSearchRequest); } // Cross reference the changes with the search results diff --git a/src/AppInstallerCLITests/SQLiteIndex.cpp b/src/AppInstallerCLITests/SQLiteIndex.cpp @@ -182,6 +182,36 @@ struct IndexFields ProductCodes(std::move(productCodes)) {} + IndexFields( + std::string id, + std::string name, + std::string publisher, + std::string moniker, + std::string version, + std::string channel, + std::vector<NormalizedString> tags, + std::vector<NormalizedString> commands, + std::string path, + std::vector<NormalizedString> packageFamilyNames, + std::vector<NormalizedString> productCodes, + std::string arpName, + std::string arpPublisher + ) : + Id(std::move(id)), + Name(std::move(name)), + Publisher(std::move(publisher)), + Moniker(std::move(moniker)), + Version(std::move(version)), + Channel(std::move(channel)), + Tags(std::move(tags)), + Commands(std::move(commands)), + Path(std::move(path)), + PackageFamilyNames(std::move(packageFamilyNames)), + ProductCodes(std::move(productCodes)), + ArpName(std::move(arpName)), + ArpPublisher(std::move(arpPublisher)) + {} + std::string Id; std::string Name; std::string Publisher; @@ -193,6 +223,8 @@ struct IndexFields std::string Path; std::vector<NormalizedString> PackageFamilyNames; std::vector<NormalizedString> ProductCodes; + std::string ArpName; + std::string ArpPublisher; }; SQLiteIndex SearchTestSetup(const std::string& filePath, std::initializer_list<IndexFields> data = {}, std::optional<Schema::Version> version = {}) @@ -230,6 +262,13 @@ SQLiteIndex SearchTestSetup(const std::string& filePath, std::initializer_list<I manifest.Installers[i].ProductCode = d.ProductCodes[i]; } + if (!d.ArpName.empty() || !d.ArpPublisher.empty()) + { + manifest.Installers[0].AppsAndFeaturesEntries.push_back({}); + manifest.Installers[0].AppsAndFeaturesEntries[0].DisplayName = d.ArpName; + manifest.Installers[0].AppsAndFeaturesEntries[0].Publisher = d.ArpPublisher; + } + index.AddManifest(manifest, d.Path); }; @@ -2738,6 +2777,37 @@ TEST_CASE("SQLiteIndex_NormNameAndPublisher_Complex", "[sqliteindex]") } } +TEST_CASE("SQLiteIndex_NormNameAndPublisher_AppsAndFeatures", "[sqliteindex]") +{ + TempFile tempFile{ "repolibtest_tempdb"s, ".db"s }; + INFO("Using temporary file named: " << tempFile.GetPath()); + + std::string testName = "Name"; + std::string testPublisher = "Publisher"; + std::string arpTestName = "Other Thing"; + std::string arpTestPublisher = "Big Company Name"; + + SQLiteIndex index = SearchTestSetup(tempFile, { + { "Id1", testName, testPublisher, "Moniker", "Version", "Channel", { "Tag" }, { "Command" }, "Path1", {}, { "PC1", "PC2" }, arpTestName, arpTestPublisher }, + }); + + Schema::Version testVersion = TestPrepareForRead(index); + + SearchRequest request; + request.Inclusions.emplace_back(PackageMatchFilter(PackageMatchField::NormalizedNameAndPublisher, MatchType::Exact, arpTestName, arpTestPublisher)); + + auto results = index.Search(request); + + if (AreNormalizedNameAndPublisherSupported(index, testVersion)) + { + REQUIRE(results.Matches.size() == 1); + } + else + { + REQUIRE(results.Matches.empty()); + } +} + TEST_CASE("SQLiteIndex_ManifestHash_Present", "[sqliteindex]") { TempFile tempFile{ "repolibtest_tempdb"s, ".db"s }; diff --git a/src/AppInstallerRepositoryCore/Microsoft/Schema/1_2/Interface_1_2.cpp b/src/AppInstallerRepositoryCore/Microsoft/Schema/1_2/Interface_1_2.cpp @@ -13,15 +13,29 @@ namespace AppInstaller::Repository::Microsoft::Schema::V1_2 { namespace { + void AddNormalizedName(const Utility::NameNormalizer& normalizer, const Manifest::string_t& name, std::vector<Utility::NormalizedString>& out) + { + Utility::NormalizedString value = normalizer.NormalizeName(Utility::FoldCase(name)).Name(); + if (std::find(out.begin(), out.end(), value) == out.end()) + { + out.emplace_back(std::move(value)); + } + } + void AddLocalizationNormalizedName(const Utility::NameNormalizer& normalizer, const Manifest::ManifestLocalization& localization, std::vector<Utility::NormalizedString>& out) { if (localization.Contains(Manifest::Localization::PackageName)) { - Utility::NormalizedString value = normalizer.NormalizeName(Utility::FoldCase(localization.Get<Manifest::Localization::PackageName>())).Name(); - if (std::find(out.begin(), out.end(), value) == out.end()) - { - out.emplace_back(std::move(value)); - } + AddNormalizedName(normalizer, localization.Get<Manifest::Localization::PackageName>(), out); + } + } + + void AddNormalizedPublisher(const Utility::NameNormalizer& normalizer, const Manifest::string_t& publisher, std::vector<Utility::NormalizedString>& out) + { + Utility::NormalizedString value = normalizer.NormalizePublisher(Utility::FoldCase(publisher)); + if (std::find(out.begin(), out.end(), value) == out.end()) + { + out.emplace_back(std::move(value)); } } @@ -29,11 +43,7 @@ namespace AppInstaller::Repository::Microsoft::Schema::V1_2 { if (localization.Contains(Manifest::Localization::Publisher)) { - Utility::NormalizedString value = normalizer.NormalizePublisher(Utility::FoldCase(localization.Get<Manifest::Localization::Publisher>())); - if (std::find(out.begin(), out.end(), value) == out.end()) - { - out.emplace_back(std::move(value)); - } + AddNormalizedPublisher(normalizer, localization.Get<Manifest::Localization::Publisher>(), out); } } @@ -47,6 +57,18 @@ namespace AppInstaller::Repository::Microsoft::Schema::V1_2 AddLocalizationNormalizedName(normalizer, loc, result); } + // In addition to the names used for our display, add the display names from the ARP entries + for (const auto& installer : manifest.Installers) + { + for (const auto& appsAndFeaturesEntry : installer.AppsAndFeaturesEntries) + { + if (!appsAndFeaturesEntry.DisplayName.empty()) + { + AddNormalizedName(normalizer, appsAndFeaturesEntry.DisplayName, result); + } + } + } + return result; } @@ -60,6 +82,18 @@ namespace AppInstaller::Repository::Microsoft::Schema::V1_2 AddLocalizationNormalizedPublisher(normalizer, loc, result); } + // In addition to the publishers used for our display, add the publishers from the ARP entries + for (const auto& installer : manifest.Installers) + { + for (const auto& appsAndFeaturesEntry : installer.AppsAndFeaturesEntries) + { + if (!appsAndFeaturesEntry.Publisher.empty()) + { + AddNormalizedPublisher(normalizer, appsAndFeaturesEntry.Publisher, result); + } + } + } + return result; } }