commit 2d6f8badda43275bb23f9a76765fa702085d8ea2
parent 0a11b104b0840b0f8c015a7b59d69cefda381ac7
Author: KEINOS <github+fork-qiita-news@keinos.com>
Date: Mon, 15 Sep 2025 21:23:12 +0000
Merge remote-tracking branch 'upstream/master'
Diffstat:
9 files changed, 80 insertions(+), 9 deletions(-)
diff --git a/src/AppInstallerCLICore/PortableInstaller.cpp b/src/AppInstallerCLICore/PortableInstaller.cpp
@@ -281,7 +281,7 @@ namespace AppInstaller::CLI::Portable
return true;
}
- void PortableInstaller::Install( Workflow::OperationType operation = Workflow::OperationType::Install)
+ void PortableInstaller::Install(Workflow::OperationType operation)
{
// If the operation is an install, the ARP entry should be created first so that a catastrophic failure
// leaves the system in a state where an uninstall may be possible
@@ -420,6 +420,19 @@ namespace AppInstaller::CLI::Portable
HelpLink = manifest.CurrentLocalization.Get<Manifest::Localization::PublisherSupportUrl>();
}
+ AppInstaller::Manifest::AppsAndFeaturesEntry PortableInstaller::GetAppsAndFeaturesEntry()
+ {
+ Manifest::AppsAndFeaturesEntry entry;
+
+ entry.DisplayName = DisplayName;
+ entry.Publisher = Publisher;
+ entry.DisplayVersion = DisplayVersion;
+ entry.InstallerType = Manifest::InstallerTypeEnum::Portable;
+ entry.ProductCode = GetProductCode();
+
+ return entry;
+ }
+
void PortableInstaller::SetExpectedState()
{
const auto& indexPath = InstallLocation / GetPortableIndexFileName();
diff --git a/src/AppInstallerCLICore/PortableInstaller.h b/src/AppInstallerCLICore/PortableInstaller.h
@@ -59,7 +59,7 @@ namespace AppInstaller::CLI::Portable
m_desiredEntries = {};
}
- void Install( AppInstaller::CLI::Workflow::OperationType operation );
+ void Install(AppInstaller::CLI::Workflow::OperationType operation = Workflow::OperationType::Install);
void Uninstall();
@@ -91,6 +91,8 @@ namespace AppInstaller::CLI::Portable
const Manifest::Manifest& manifest,
const std::vector<AppInstaller::Manifest::AppsAndFeaturesEntry>& entries);
+ AppInstaller::Manifest::AppsAndFeaturesEntry GetAppsAndFeaturesEntry();
+
private:
PortableARPEntry m_portableARPEntry;
std::vector<AppInstaller::Portable::PortableFileEntry> m_desiredEntries;
diff --git a/src/AppInstallerCLICore/Workflows/PortableFlow.cpp b/src/AppInstallerCLICore/Workflows/PortableFlow.cpp
@@ -167,7 +167,7 @@ namespace AppInstaller::CLI::Workflow
}
portableInstaller.TargetInstallLocation = targetInstallDirectory;
- portableInstaller.SetAppsAndFeaturesMetadata(context.Get<Execution::Data::Manifest>(), context.Get<Execution::Data::Installer>()->AppsAndFeaturesEntries);
+ portableInstaller.SetAppsAndFeaturesMetadata(context.Get<Execution::Data::Manifest>(), installer.AppsAndFeaturesEntries);
context.Add<Execution::Data::PortableInstaller>(std::move(portableInstaller));
}
@@ -273,7 +273,8 @@ namespace AppInstaller::CLI::Workflow
}
}
- portableInstaller.Install(installType);
+ portableInstaller.Install(installType);
+ context.Add<Execution::Data::CorrelatedAppsAndFeaturesEntries>({ portableInstaller.GetAppsAndFeaturesEntry() });
context.Add<Execution::Data::OperationReturnCode>(ERROR_SUCCESS);
context.Reporter.Warn() << portableInstaller.GetOutputMessage();
}
diff --git a/src/AppInstallerCLITests/PortableInstaller.cpp b/src/AppInstallerCLITests/PortableInstaller.cpp
@@ -47,6 +47,9 @@ TEST_CASE("PortableInstaller_InstallToRegistry", "[PortableInstaller]")
portableInstaller.Install(AppInstaller::CLI::Workflow::OperationType::Install);
+ auto entry = portableInstaller.GetAppsAndFeaturesEntry();
+ REQUIRE(entry.ProductCode == portableInstaller.GetProductCode());
+
PortableInstaller portableInstaller2 = PortableInstaller(ScopeEnum::User, Architecture::X64, "testProductCode");
REQUIRE(portableInstaller2.ARPEntryExists());
REQUIRE(std::filesystem::exists(portableInstaller2.PortableTargetFullPath));
diff --git a/src/AppInstallerCLITests/SQLiteIndex.cpp b/src/AppInstallerCLITests/SQLiteIndex.cpp
@@ -3935,3 +3935,31 @@ TEST_CASE("SQLiteIndex_AddOrUpdateManifest", "[sqliteindex]")
REQUIRE(!index.AddOrUpdateManifest(manifest, manifestPath));
}
}
+
+TEST_CASE("SQLiteIndex_VersionStringPreserved", "[sqliteindex]")
+{
+ TempFile tempFile{ "repolibtest_tempdb"s, ".db"s };
+ INFO("Using temporary file named: " << tempFile.GetPath());
+
+ Manifest manifest;
+ SQLiteIndex index = CreateTestIndex(tempFile);
+
+ string_t publisher = "Test";
+ std::string version = GENERATE("1.0", "1.10");
+
+ CreateFakeManifest(manifest, publisher, version);
+ index.AddManifest(manifest, GetPathFromManifest(manifest));
+
+ TempDirectory intermediatesDirectory{ "v2_0_intermediates" };
+ INFO("Intermediates directory: " << intermediatesDirectory.GetPath());
+
+ index.SetProperty(SQLiteIndex::Property::IntermediateFileOutputPath, intermediatesDirectory);
+ index.PrepareForPackaging();
+
+ auto results = index.Search({});
+ REQUIRE(results.Matches.size() == 1);
+
+ std::string extractedVersion = GetPropertyStringById(index, results.Matches[0].first, PackageVersionProperty::Version);
+
+ REQUIRE(extractedVersion == version);
+}
diff --git a/src/AppInstallerCLITests/SQLiteIndexSource.cpp b/src/AppInstallerCLITests/SQLiteIndexSource.cpp
@@ -14,7 +14,7 @@ using namespace AppInstaller::SQLite;
using SQLiteVersion = AppInstaller::SQLite::Version;
-static std::shared_ptr<SQLiteIndexSource> SimpleTestSetup(const std::string& filePath, SourceDetails& details, Manifest& manifest, std::string& relativePath)
+static std::shared_ptr<SQLiteIndexSource> SimpleTestSetup(const std::string& filePath, SourceDetails& details, Manifest& manifest, std::string& relativePath, const std::filesystem::path& manifestFile = "Manifest-Good.yaml")
{
SQLiteVersion latest1 = Version::LatestForMajor(1);
SQLiteVersion latest2 = Version::LatestForMajor(2);
@@ -23,7 +23,7 @@ static std::shared_ptr<SQLiteIndexSource> SimpleTestSetup(const std::string& fil
SQLiteIndex index = SQLiteIndex::CreateNew(filePath, versionToUse);
- TestDataFile testManifest("Manifest-Good.yaml");
+ TestDataFile testManifest(manifestFile);
manifest = YamlParser::CreateFromPath(testManifest);
std::filesystem::path testManifestPath = testManifest.GetPath();
@@ -259,3 +259,27 @@ TEST_CASE("SQLiteIndexSource_Package_ProductCodes", "[sqliteindexsource]")
REQUIRE(propertyPCs.size() == 1);
REQUIRE(manifestPCs[0] == propertyPCs[0].get());
}
+
+TEST_CASE("SQLiteIndexSource_VersionSelection", "[sqliteindexsource]")
+{
+ TempFile tempFile{ "repolibtest_tempdb"s, ".db"s };
+ INFO("Using temporary file named: " << tempFile.GetPath());
+
+ SourceDetails details;
+ Manifest manifest;
+ std::string relativePath;
+ std::shared_ptr<SQLiteIndexSource> source = SimpleTestSetup(tempFile, details, manifest, relativePath, "InstallFlowTest_Exe.yaml");
+
+ SearchRequest request;
+ request.Query = RequestMatch(MatchType::Exact, manifest.Id);
+
+ auto results = source->Search(request);
+ REQUIRE(results.Matches.size() == 1);
+ REQUIRE(results.Matches[0].Package);
+
+ auto package = results.Matches[0].Package->GetAvailable()[0];
+
+ PackageVersionKey key{ {}, "1", {} };
+ auto version = package->GetVersion(key);
+ REQUIRE(version);
+}
diff --git a/src/AppInstallerRepositoryCore/Microsoft/SQLiteIndexSourceV2.h b/src/AppInstallerRepositoryCore/Microsoft/SQLiteIndexSourceV2.h
@@ -45,7 +45,7 @@ namespace AppInstaller::Repository::Microsoft::details::V2
// Contains the information needed to map a version key to it's rows.
struct MapKey
{
- Utility::NormalizedString Version;
+ Utility::Version Version;
Utility::NormalizedString Channel;
bool operator<(const MapKey& other) const;
diff --git a/src/AppInstallerRepositoryCore/Microsoft/Schema/2_0/PackagesTable.cpp b/src/AppInstallerRepositoryCore/Microsoft/Schema/2_0/PackagesTable.cpp
@@ -29,7 +29,7 @@ namespace AppInstaller::Repository::Microsoft::Schema::V2_0
for (const ColumnInfo& value : values)
{
- ColumnBuilder columnBuilder(value.Name, Type::Int64);
+ ColumnBuilder columnBuilder(value.Name, value.Type);
if (!value.AllowNull)
{
diff --git a/src/AppInstallerRepositoryCore/RepositorySearch.cpp b/src/AppInstallerRepositoryCore/RepositorySearch.cpp
@@ -96,7 +96,7 @@ namespace AppInstaller::Repository
{
return
((other.SourceId.empty() || other.SourceId == SourceId) &&
- (other.Version.empty() || Utility::ICUCaseInsensitiveEquals(other.Version, Version)) &&
+ (other.Version.empty() || Utility::Version{ other.Version } == Utility::Version{ Version }) &&
(other.Channel.empty() || Utility::ICUCaseInsensitiveEquals(other.Channel, Channel)));
}