From f61db6d25ae3cd227133909858bded8d543f934b Mon Sep 17 00:00:00 2001 From: Ruben Guerrero Samaniego Date: Wed, 17 Jan 2024 14:17:59 -0800 Subject: [PATCH 1/5] Use std::any in ManifestYamlPopulator --- .../Manifest/ManifestYamlPopulator.cpp | 1981 +++++++++++++++-- .../Public/winget/ManifestYamlPopulator.h | 45 +- src/AppInstallerCommonCore/pch.h | 1 + 3 files changed, 1799 insertions(+), 228 deletions(-) diff --git a/src/AppInstallerCommonCore/Manifest/ManifestYamlPopulator.cpp b/src/AppInstallerCommonCore/Manifest/ManifestYamlPopulator.cpp index 07449013b8..1d100c5b39 100644 --- a/src/AppInstallerCommonCore/Manifest/ManifestYamlPopulator.cpp +++ b/src/AppInstallerCommonCore/Manifest/ManifestYamlPopulator.cpp @@ -137,10 +137,18 @@ namespace AppInstaller::Manifest // Common fields across versions std::vector result = { - { "ManifestVersion", [](const YAML::Node&)->ValidationErrors { /* ManifestVersion already populated. Field listed here for duplicate and PascalCase check */ return {}; } }, - { "Installers", [this](const YAML::Node& value)->ValidationErrors { m_p_installersNode = &value; return {}; } }, - { "Localization", [this](const YAML::Node& value)->ValidationErrors { m_p_localizationsNode = &value; return {}; } }, - { "Channel", [this](const YAML::Node& value)->ValidationErrors { m_p_manifest->Channel = Utility::Trim(value.as()); return {}; } }, + { "ManifestVersion", [](const YAML::Node&, std::any&)->ValidationErrors { /* ManifestVersion already populated. Field listed here for duplicate and PascalCase check */ return {}; } }, + { "Installers", [this](const YAML::Node& value, std::any&)->ValidationErrors { m_p_installersNode = &value; return {}; } }, + { "Localization", [this](const YAML::Node& value, std::any&)->ValidationErrors { m_p_localizationsNode = &value; return {}; } }, + { + "Channel", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + Manifest* manifest = std::any_cast(any); + manifest->Channel = Utility::Trim(value.as()); + return {}; + } + }, }; // Additional version specific fields @@ -148,9 +156,33 @@ namespace AppInstaller::Manifest { std::vector previewRootFields { - { "Id", [this](const YAML::Node& value)->ValidationErrors { m_p_manifest->Id = Utility::Trim(value.as()); return {}; } }, - { "Version", [this](const YAML::Node& value)->ValidationErrors { m_p_manifest->Version = Utility::Trim(value.as()); return {}; } }, - { "AppMoniker", [this](const YAML::Node& value)->ValidationErrors { m_p_manifest->Moniker = Utility::Trim(value.as()); return {}; } }, + { + "Id", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + Manifest* manifest = std::any_cast(any); + manifest->Id = Utility::Trim(value.as()); + return {}; + } + }, + { + "Version", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + Manifest* manifest = std::any_cast(any); + manifest->Version = Utility::Trim(value.as()); + return {}; + } + }, + { + "AppMoniker", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + Manifest* manifest = std::any_cast(any); + manifest->Moniker = Utility::Trim(value.as()); + return {}; + } + }, }; std::move(previewRootFields.begin(), previewRootFields.end(), std::inserter(result, result.end())); @@ -162,10 +194,34 @@ namespace AppInstaller::Manifest { std::vector v1RootFields { - { "PackageIdentifier", [this](const YAML::Node& value)->ValidationErrors { m_p_manifest->Id = Utility::Trim(value.as()); return {}; } }, - { "PackageVersion", [this](const YAML::Node& value)->ValidationErrors { m_p_manifest->Version = Utility::Trim(value.as()); return {}; } }, - { "Moniker", [this](const YAML::Node& value)->ValidationErrors { m_p_manifest->Moniker = Utility::Trim(value.as()); return {}; } }, - { "ManifestType", [](const YAML::Node&)->ValidationErrors { /* ManifestType already checked. Field listed here for duplicate and PascalCase check */ return {}; } }, + { + "PackageIdentifier", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + Manifest* manifest = std::any_cast(any); + manifest->Id = Utility::Trim(value.as()); + return {}; + } + }, + { + "PackageVersion", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + Manifest* manifest = std::any_cast(any); + manifest->Version = Utility::Trim(value.as()); + return {}; + } + }, + { + "Moniker", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + Manifest* manifest = std::any_cast(any); + manifest->Moniker = Utility::Trim(value.as()); + return {}; + } + }, + { "ManifestType", [](const YAML::Node&, std::any&)->ValidationErrors { /* ManifestType already checked. Field listed here for duplicate and PascalCase check */ return {}; } }, }; std::move(v1RootFields.begin(), v1RootFields.end(), std::inserter(result, result.end())); @@ -187,9 +243,63 @@ namespace AppInstaller::Manifest // Common fields across versions std::vector result = { - { "InstallerType", [this](const YAML::Node& value)->ValidationErrors { m_p_installer->BaseInstallerType = ConvertToInstallerTypeEnum(value.as()); return {}; } }, - { "PackageFamilyName", [this](const YAML::Node& value)->ValidationErrors { m_p_installer->PackageFamilyName = value.as(); return {}; } }, - { "ProductCode", [this](const YAML::Node& value)->ValidationErrors { m_p_installer->ProductCode = value.as(); return {}; } }, + { + "InstallerType", + [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestInstaller* installer; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + installer = &(manifest->DefaultInstallerInfo); + } + else + { + installer = std::any_cast(any); + } + + installer->BaseInstallerType = ConvertToInstallerTypeEnum(value.as()); + return {}; + } + }, + { + "PackageFamilyName", + [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestInstaller* installer; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + installer = &(manifest->DefaultInstallerInfo); + } + else + { + installer = std::any_cast(any); + } + + installer->PackageFamilyName = value.as(); + return {}; + } + }, + { + "ProductCode", + [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestInstaller* installer; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + installer = &(manifest->DefaultInstallerInfo); + } + else + { + installer = std::any_cast(any); + } + + installer->ProductCode = value.as(); + return {}; + } + }, }; // Additional version specific fields @@ -198,8 +308,44 @@ namespace AppInstaller::Manifest // Root level and Localization node level std::vector previewCommonFields = { - { "UpdateBehavior", [this](const YAML::Node& value)->ValidationErrors { m_p_installer->UpdateBehavior = ConvertToUpdateBehaviorEnum(value.as()); return {}; } }, - { "Switches", [this](const YAML::Node& value)->ValidationErrors { m_p_switches = &(m_p_installer->Switches); return ValidateAndProcessFields(value, SwitchesFieldInfos); } }, + { + "UpdateBehavior", + [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestInstaller* installer; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + installer = &(manifest->DefaultInstallerInfo); + } + else + { + installer = std::any_cast(any); + } + + installer->UpdateBehavior = ConvertToUpdateBehaviorEnum(value.as()); + return {}; + } + }, + { + "Switches", + [this, forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestInstaller* installer; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + installer = &(manifest->DefaultInstallerInfo); + } + else + { + installer = std::any_cast(any); + } + + std::any anySwitches = &(installer->Switches); + return ValidateAndProcessFields(value, SwitchesFieldInfos, anySwitches); + } + }, }; std::move(previewCommonFields.begin(), previewCommonFields.end(), std::inserter(result, result.end())); @@ -209,17 +355,72 @@ namespace AppInstaller::Manifest // Installer node only std::vector installerOnlyFields = { - { "Arch", [this](const YAML::Node& value)->ValidationErrors { m_p_installer->Arch = Utility::ConvertToArchitectureEnum(value.as()); return {}; } }, - { "Url", [this](const YAML::Node& value)->ValidationErrors { m_p_installer->Url = value.as(); return {}; } }, - { "Sha256", [this](const YAML::Node& value)->ValidationErrors { m_p_installer->Sha256 = Utility::SHA256::ConvertToBytes(value.as()); return {}; } }, - { "SignatureSha256", [this](const YAML::Node& value)->ValidationErrors { m_p_installer->SignatureSha256 = Utility::SHA256::ConvertToBytes(value.as()); return {}; } }, - { "Language", [this](const YAML::Node& value)->ValidationErrors { m_p_installer->Locale = value.as(); return {}; } }, - { "Scope", [this](const YAML::Node& value)->ValidationErrors { m_p_installer->Scope = ConvertToScopeEnum(value.as()); return {}; } }, + { + "Arch", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestInstaller* installer = std::any_cast(any); + installer->Arch = Utility::ConvertToArchitectureEnum(value.as()); + return {}; + } + }, + { + "Url", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestInstaller* installer = std::any_cast(any); + installer->Url = value.as(); + return {}; + } + }, + { + "Sha256", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestInstaller* installer = std::any_cast(any); + installer->Sha256 = Utility::SHA256::ConvertToBytes(value.as()); + return {}; + } + }, + { + "SignatureSha256", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestInstaller* installer = std::any_cast(any); + installer->SignatureSha256 = Utility::SHA256::ConvertToBytes(value.as()); + return {}; + } + }, + { + "Language", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestInstaller* installer = std::any_cast(any); + installer->Locale = value.as(); + return {}; + } + }, + { + "Scope", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestInstaller* installer = std::any_cast(any); + installer->Scope = ConvertToScopeEnum(value.as()); + return {}; + } + }, }; if (manifestVersion.HasExtension(s_MSStoreExtension)) { - installerOnlyFields.emplace_back("ProductId", [this](const YAML::Node& value)->ValidationErrors { m_p_installer->ProductId = value.as(); return {}; }); + installerOnlyFields.emplace_back( + "ProductId", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestInstaller* installer = std::any_cast(any); + installer->ProductId = value.as(); + return {}; + }); } std::move(installerOnlyFields.begin(), installerOnlyFields.end(), std::inserter(result, result.end())); @@ -229,10 +430,46 @@ namespace AppInstaller::Manifest // Root node only std::vector rootOnlyFields = { - { "MinOSVersion", [this](const YAML::Node& value)->ValidationErrors { m_p_installer->MinOSVersion = value.as(); return {}; } }, - { "Commands", [this](const YAML::Node& value)->ValidationErrors { m_p_installer->Commands = SplitMultiValueField(value.as()); return {}; } }, - { "Protocols", [this](const YAML::Node& value)->ValidationErrors { m_p_installer->Protocols = SplitMultiValueField(value.as()); return {}; } }, - { "FileExtensions", [this](const YAML::Node& value)->ValidationErrors { m_p_installer->FileExtensions = SplitMultiValueField(value.as()); return {}; } }, + { + "MinOSVersion", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + Manifest* manifest = std::any_cast(any); + ManifestInstaller* installer = &(manifest->DefaultInstallerInfo); + installer->MinOSVersion = value.as(); + return {}; + } + }, + { + "Commands", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + Manifest* manifest = std::any_cast(any); + ManifestInstaller* installer = &(manifest->DefaultInstallerInfo); + installer->Commands = SplitMultiValueField(value.as()); + return {}; + } + }, + { + "Protocols", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + Manifest* manifest = std::any_cast(any); + ManifestInstaller* installer = &(manifest->DefaultInstallerInfo); + installer->Protocols = SplitMultiValueField(value.as()); + return {}; + } + }, + { + "FileExtensions", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + Manifest* manifest = std::any_cast(any); + ManifestInstaller* installer = &(manifest->DefaultInstallerInfo); + installer->FileExtensions = SplitMultiValueField(value.as()); + return {}; + } + }, }; std::move(rootOnlyFields.begin(), rootOnlyFields.end(), std::inserter(result, result.end())); @@ -246,20 +483,272 @@ namespace AppInstaller::Manifest // Root level and Installer node level std::vector v1CommonFields = { - { "InstallerLocale", [this](const YAML::Node& value)->ValidationErrors { m_p_installer->Locale = value.as(); return {}; } }, - { "Platform", [this](const YAML::Node& value)->ValidationErrors { m_p_installer->Platform = ProcessPlatformSequenceNode(value); return {}; } }, - { "MinimumOSVersion", [this](const YAML::Node& value)->ValidationErrors { m_p_installer->MinOSVersion = value.as(); return {}; } }, - { "Scope", [this](const YAML::Node& value)->ValidationErrors { m_p_installer->Scope = ConvertToScopeEnum(value.as()); return {}; } }, - { "InstallModes", [this](const YAML::Node& value)->ValidationErrors { m_p_installer->InstallModes = ProcessInstallModeSequenceNode(value); return {}; } }, - { "InstallerSwitches", [this](const YAML::Node& value)->ValidationErrors { m_p_switches = &(m_p_installer->Switches); return ValidateAndProcessFields(value, SwitchesFieldInfos); } }, - { "InstallerSuccessCodes", [this](const YAML::Node& value)->ValidationErrors { m_p_installer->InstallerSuccessCodes = ProcessInstallerSuccessCodeSequenceNode(value); return {}; } }, - { "UpgradeBehavior", [this](const YAML::Node& value)->ValidationErrors { m_p_installer->UpdateBehavior = ConvertToUpdateBehaviorEnum(value.as()); return {}; } }, - { "Commands", [this](const YAML::Node& value)->ValidationErrors { m_p_installer->Commands = ProcessStringSequenceNode(value); return {}; } }, - { "Protocols", [this](const YAML::Node& value)->ValidationErrors { m_p_installer->Protocols = ProcessStringSequenceNode(value); return {}; } }, - { "FileExtensions", [this](const YAML::Node& value)->ValidationErrors { m_p_installer->FileExtensions = ProcessStringSequenceNode(value); return {}; } }, - { "Dependencies", [this](const YAML::Node& value)->ValidationErrors { m_p_dependencyList = &(m_p_installer->Dependencies); return ValidateAndProcessFields(value, DependenciesFieldInfos); } }, - { "Capabilities", [this](const YAML::Node& value)->ValidationErrors { m_p_installer->Capabilities = ProcessStringSequenceNode(value); return {}; } }, - { "RestrictedCapabilities", [this](const YAML::Node& value)->ValidationErrors { m_p_installer->RestrictedCapabilities = ProcessStringSequenceNode(value); return {}; } }, + { + "InstallerLocale", + [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestInstaller* installer; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + installer = &(manifest->DefaultInstallerInfo); + } + else + { + installer = std::any_cast(any); + } + + installer->Locale = value.as(); + return {}; + } + }, + { + "Platform", + [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestInstaller* installer; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + installer = &(manifest->DefaultInstallerInfo); + } + else + { + installer = std::any_cast(any); + } + + installer->Platform = ProcessPlatformSequenceNode(value); + return {}; + } + }, + { + "MinimumOSVersion", + [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestInstaller* installer; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + installer = &(manifest->DefaultInstallerInfo); + } + else + { + installer = std::any_cast(any); + } + + installer->MinOSVersion = value.as(); + return {}; + } + }, + { + "Scope", + [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestInstaller* installer; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + installer = &(manifest->DefaultInstallerInfo); + } + else + { + installer = std::any_cast(any); + } + + installer->Scope = ConvertToScopeEnum(value.as()); + return {}; + } + }, + { + "InstallModes", + [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestInstaller* installer; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + installer = &(manifest->DefaultInstallerInfo); + } + else + { + installer = std::any_cast(any); + } + + installer->InstallModes = ProcessInstallModeSequenceNode(value); + return {}; + } + }, + { + "InstallerSwitches", + [this, forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestInstaller* installer; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + installer = &(manifest->DefaultInstallerInfo); + } + else + { + installer = std::any_cast(any); + } + + std::any anySwitches = &(installer->Switches); + return ValidateAndProcessFields(value, SwitchesFieldInfos, anySwitches); + } + }, + { + "InstallerSuccessCodes", + [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestInstaller* installer; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + installer = &(manifest->DefaultInstallerInfo); + } + else + { + installer = std::any_cast(any); + } + + installer->InstallerSuccessCodes = ProcessInstallerSuccessCodeSequenceNode(value); + return {}; + } + }, + { + "UpgradeBehavior", + [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestInstaller* installer; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + installer = &(manifest->DefaultInstallerInfo); + } + else + { + installer = std::any_cast(any); + } + + installer->UpdateBehavior = ConvertToUpdateBehaviorEnum(value.as()); + return {}; + } + }, + { + "Commands", + [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestInstaller* installer; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + installer = &(manifest->DefaultInstallerInfo); + } + else + { + installer = std::any_cast(any); + } + + installer->Commands = ProcessStringSequenceNode(value); + return {}; + } + }, + { + "Protocols", + [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestInstaller* installer; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + installer = &(manifest->DefaultInstallerInfo); + } + else + { + installer = std::any_cast(any); + } + + installer->Protocols = ProcessStringSequenceNode(value); + return {}; + } + }, + { + "FileExtensions", + [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestInstaller* installer; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + installer = &(manifest->DefaultInstallerInfo); + } + else + { + installer = std::any_cast(any); + } + + installer->FileExtensions = ProcessStringSequenceNode(value); + return {}; + } + }, + { + "Dependencies", + [this, forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestInstaller* installer; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + installer = &(manifest->DefaultInstallerInfo); + } + else + { + installer = std::any_cast(any); + } + + std::any anyDependencyList = &(installer->Dependencies); + return ValidateAndProcessFields(value, DependenciesFieldInfos, anyDependencyList); + } + }, + { + "Capabilities", + [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestInstaller* installer; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + installer = &(manifest->DefaultInstallerInfo); + } + else + { + installer = std::any_cast(any); + } + + installer->Capabilities = ProcessStringSequenceNode(value); + return {}; + } + }, + { + "RestrictedCapabilities", + [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestInstaller* installer; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + installer = &(manifest->DefaultInstallerInfo); + } + else + { + installer = std::any_cast(any); + } + + installer->RestrictedCapabilities = ProcessStringSequenceNode(value); + return {}; + } + }, }; std::move(v1CommonFields.begin(), v1CommonFields.end(), std::inserter(result, result.end())); @@ -269,10 +758,42 @@ namespace AppInstaller::Manifest // Installer level only fields std::vector v1InstallerFields = { - { "Architecture", [this](const YAML::Node& value)->ValidationErrors { m_p_installer->Arch = Utility::ConvertToArchitectureEnum(value.as()); return {}; } }, - { "InstallerUrl", [this](const YAML::Node& value)->ValidationErrors { m_p_installer->Url = value.as(); return {}; } }, - { "InstallerSha256", [this](const YAML::Node& value)->ValidationErrors { m_p_installer->Sha256 = Utility::SHA256::ConvertToBytes(value.as()); return {}; } }, - { "SignatureSha256", [this](const YAML::Node& value)->ValidationErrors { m_p_installer->SignatureSha256 = Utility::SHA256::ConvertToBytes(value.as()); return {}; } }, + { + "Architecture", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestInstaller* installer = std::any_cast(any); + installer->Arch = Utility::ConvertToArchitectureEnum(value.as()); + return {}; + } + }, + { + "InstallerUrl", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestInstaller* installer = std::any_cast(any); + installer->Url = value.as(); + return {}; + } + }, + { + "InstallerSha256", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestInstaller* installer = std::any_cast(any); + installer->Sha256 = Utility::SHA256::ConvertToBytes(value.as()); + return {}; + } + }, + { + "SignatureSha256", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestInstaller* installer = std::any_cast(any); + installer->SignatureSha256 = Utility::SHA256::ConvertToBytes(value.as()); + return {}; + } + }, }; std::move(v1InstallerFields.begin(), v1InstallerFields.end(), std::inserter(result, result.end())); @@ -283,15 +804,174 @@ namespace AppInstaller::Manifest { std::vector fields_v1_1 = { - { "InstallerAbortsTerminal", [this](const YAML::Node& value)->ValidationErrors { m_p_installer->InstallerAbortsTerminal = value.as(); return {}; } }, - { "InstallLocationRequired", [this](const YAML::Node& value)->ValidationErrors { m_p_installer->InstallLocationRequired = value.as(); return {}; } }, - { "RequireExplicitUpgrade", [this](const YAML::Node& value)->ValidationErrors { m_p_installer->RequireExplicitUpgrade = value.as(); return {}; } }, - { "ReleaseDate", [this](const YAML::Node& value)->ValidationErrors { m_p_installer->ReleaseDate = Utility::Trim(value.as()); return {}; } }, - { "UnsupportedOSArchitectures", [this](const YAML::Node& value)->ValidationErrors { m_p_installer->UnsupportedOSArchitectures = ProcessArchitectureSequenceNode(value); return {}; } }, - { "ElevationRequirement", [this](const YAML::Node& value)->ValidationErrors { m_p_installer->ElevationRequirement = ConvertToElevationRequirementEnum(value.as()); return {}; } }, - { "Markets", [this](const YAML::Node& value)->ValidationErrors { return ProcessMarketsNode(value); } }, - { "AppsAndFeaturesEntries", [this](const YAML::Node& value)->ValidationErrors { return ProcessAppsAndFeaturesEntriesNode(value); } }, - { "ExpectedReturnCodes", [this](const YAML::Node& value)->ValidationErrors { return ProcessExpectedReturnCodesNode(value); } }, + { + "InstallerAbortsTerminal", + [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestInstaller* installer; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + installer = &(manifest->DefaultInstallerInfo); + } + else + { + installer = std::any_cast(any); + } + + installer->InstallerAbortsTerminal = value.as(); + return {}; + } + }, + { + "InstallLocationRequired", + [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestInstaller* installer; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + installer = &(manifest->DefaultInstallerInfo); + } + else + { + installer = std::any_cast(any); + } + + installer->InstallLocationRequired = value.as(); + return {}; + } + }, + { + "RequireExplicitUpgrade", + [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestInstaller* installer; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + installer = &(manifest->DefaultInstallerInfo); + } + else + { + installer = std::any_cast(any); + } + + installer->RequireExplicitUpgrade = value.as(); + return {}; + } + }, + { + "ReleaseDate", + [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestInstaller* installer; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + installer = &(manifest->DefaultInstallerInfo); + } + else + { + installer = std::any_cast(any); + } + + installer->ReleaseDate = Utility::Trim(value.as()); + return {}; + } + }, + { + "UnsupportedOSArchitectures", + [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestInstaller* installer; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + installer = &(manifest->DefaultInstallerInfo); + } + else + { + installer = std::any_cast(any); + } + + installer->UnsupportedOSArchitectures = ProcessArchitectureSequenceNode(value); + return {}; + } + }, + { + "ElevationRequirement", + [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestInstaller* installer; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + installer = &(manifest->DefaultInstallerInfo); + } + else + { + installer = std::any_cast(any); + } + + installer->ElevationRequirement = ConvertToElevationRequirementEnum(value.as()); + return {}; + } + }, + { + "Markets", + [this, forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestInstaller* installer; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + installer = &(manifest->DefaultInstallerInfo); + } + else + { + installer = std::any_cast(any); + } + + return ProcessMarketsNode(value, installer); + } + }, + { + "AppsAndFeaturesEntries", + [this, forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestInstaller* installer; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + installer = &(manifest->DefaultInstallerInfo); + } + else + { + installer = std::any_cast(any); + } + + return ProcessAppsAndFeaturesEntriesNode(value, installer); + } + }, + { + "ExpectedReturnCodes", + [this, forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestInstaller* installer; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + installer = &(manifest->DefaultInstallerInfo); + } + else + { + installer = std::any_cast(any); + } + + return ProcessExpectedReturnCodesNode(value, installer); + } + }, }; std::move(fields_v1_1.begin(), fields_v1_1.end(), std::inserter(result, result.end())); @@ -301,8 +981,44 @@ namespace AppInstaller::Manifest { std::vector fields_v1_2 = { - { "UnsupportedArguments", [this](const YAML::Node& value)->ValidationErrors { m_p_installer->UnsupportedArguments = ProcessUnsupportedArgumentsSequenceNode(value); return {}; } }, - { "DisplayInstallWarnings", [this](const YAML::Node& value)->ValidationErrors { m_p_installer->DisplayInstallWarnings = value.as(); return {}; } }, + { + "UnsupportedArguments", + [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestInstaller* installer; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + installer = &(manifest->DefaultInstallerInfo); + } + else + { + installer = std::any_cast(any); + } + + installer->UnsupportedArguments = ProcessUnsupportedArgumentsSequenceNode(value); + return {}; + } + }, + { + "DisplayInstallWarnings", + [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestInstaller* installer; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + installer = &(manifest->DefaultInstallerInfo); + } + else + { + installer = std::any_cast(any); + } + + installer->DisplayInstallWarnings = value.as(); + return {}; + } + }, }; std::move(fields_v1_2.begin(), fields_v1_2.end(), std::inserter(result, result.end())); @@ -312,9 +1028,62 @@ namespace AppInstaller::Manifest { std::vector fields_v1_4 = { - { "NestedInstallerType", [this](const YAML::Node& value)->ValidationErrors { m_p_installer->NestedInstallerType = ConvertToInstallerTypeEnum(value.as()); return {}; } }, - { "NestedInstallerFiles", [this](const YAML::Node& value)->ValidationErrors { return ProcessNestedInstallerFilesNode(value); } }, - { "InstallationMetadata", [this](const YAML::Node& value)->ValidationErrors { m_p_installationMetadata = &(m_p_installer->InstallationMetadata); return ValidateAndProcessFields(value, InstallationMetadataFieldInfos); } }, + { + "NestedInstallerType", + [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestInstaller* installer; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + installer = &(manifest->DefaultInstallerInfo); + } + else + { + installer = std::any_cast(any); + } + + installer->NestedInstallerType = ConvertToInstallerTypeEnum(value.as()); + return {}; + } + }, + { + "NestedInstallerFiles", + [this, forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestInstaller* installer; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + installer = &(manifest->DefaultInstallerInfo); + } + else + { + installer = std::any_cast(any); + } + + return ProcessNestedInstallerFilesNode(value, installer); + } + }, + { + "InstallationMetadata", + [this, forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestInstaller* installer; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + installer = &(manifest->DefaultInstallerInfo); + } + else + { + installer = std::any_cast(any); + } + + std::any anyInstallationMetadata = &(installer->InstallationMetadata); + return ValidateAndProcessFields(value, InstallationMetadataFieldInfos, anyInstallationMetadata); + } + }, }; std::move(fields_v1_4.begin(), fields_v1_4.end(), std::inserter(result, result.end())); @@ -324,21 +1093,29 @@ namespace AppInstaller::Manifest { std::vector fields_v1_6 = { - { "DownloadCommandProhibited", [this](const YAML::Node& value)->ValidationErrors { m_p_installer->DownloadCommandProhibited = value.as(); return {}; }, true }, + { + "DownloadCommandProhibited", + [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestInstaller* installer; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + installer = &(manifest->DefaultInstallerInfo); + } + else + { + installer = std::any_cast(any); + } + + installer->DownloadCommandProhibited = value.as(); + return {}; + }, + true }, }; std::move(fields_v1_6.begin(), fields_v1_6.end(), std::inserter(result, result.end())); } - - if (manifestVersion >= ManifestVer{ s_ManifestVersionV1_7 }) - { - std::vector fields_v1_7 = - { - { "RepairBehavior", [this](const YAML::Node& value)->ValidationErrors { m_p_installer->RepairBehavior = ConvertToRepairBehaviorEnum(value.as()); return {}; } }, - }; - - std::move(fields_v1_7.begin(), fields_v1_7.end(), std::inserter(result, result.end())); - } } return result; @@ -349,29 +1126,93 @@ namespace AppInstaller::Manifest // Common fields across versions std::vector result = { - { "Custom", [this](const YAML::Node& value)->ValidationErrors { (*m_p_switches)[InstallerSwitchType::Custom] = value.as(); return{}; } }, - { "Silent", [this](const YAML::Node& value)->ValidationErrors { (*m_p_switches)[InstallerSwitchType::Silent] = value.as(); return{}; } }, - { "SilentWithProgress", [this](const YAML::Node& value)->ValidationErrors { (*m_p_switches)[InstallerSwitchType::SilentWithProgress] = value.as(); return{}; } }, - { "Interactive", [this](const YAML::Node& value)->ValidationErrors { (*m_p_switches)[InstallerSwitchType::Interactive] = value.as(); return{}; } }, - { "Log", [this](const YAML::Node& value)->ValidationErrors { (*m_p_switches)[InstallerSwitchType::Log] = value.as(); return{}; } }, - { "InstallLocation", [this](const YAML::Node& value)->ValidationErrors { (*m_p_switches)[InstallerSwitchType::InstallLocation] = value.as(); return{}; } }, + { + "Custom", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + auto switches = std::any_cast*>(any); + (*switches)[InstallerSwitchType::Custom] = value.as(); + return{}; + } + }, + { + "Silent", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + auto switches = std::any_cast*>(any); + (*switches)[InstallerSwitchType::Silent] = value.as(); + return{}; + } + }, + { + "SilentWithProgress", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + auto switches = std::any_cast*>(any); + (*switches)[InstallerSwitchType::SilentWithProgress] = value.as(); + return{}; + } + }, + { + "Interactive", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + auto switches = std::any_cast*>(any); + (*switches)[InstallerSwitchType::Interactive] = value.as(); + return{}; + } + }, + { + "Log", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + auto switches = std::any_cast*>(any); + (*switches)[InstallerSwitchType::Log] = value.as(); + return{}; + } + }, + { + "InstallLocation", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + auto switches = std::any_cast*>(any); + (*switches)[InstallerSwitchType::InstallLocation] = value.as(); + return{}; + } + }, }; // Additional version specific fields if (manifestVersion.Major() == 0) { // Language only exists in preview manifests. Though we don't use it in our code yet, keep it here to be consistent with schema. - result.emplace_back("Language", [this](const YAML::Node& value)->ValidationErrors { (*m_p_switches)[InstallerSwitchType::Language] = value.as(); return{}; }); - result.emplace_back("Update", [this](const YAML::Node& value)->ValidationErrors { (*m_p_switches)[InstallerSwitchType::Update] = value.as(); return{}; }); + result.emplace_back( + "Language", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + auto switches = std::any_cast*>(any); + (*switches)[InstallerSwitchType::Language] = value.as(); + return{}; + }); + result.emplace_back( + "Update", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + auto switches = std::any_cast*>(any); + (*switches)[InstallerSwitchType::Update] = value.as(); + return{}; + }); } else if (manifestVersion.Major() == 1) { - result.emplace_back("Upgrade", [this](const YAML::Node& value)->ValidationErrors { (*m_p_switches)[InstallerSwitchType::Update] = value.as(); return{}; }); - - if (manifestVersion >= ManifestVer{ s_ManifestVersionV1_7 }) - { - result.emplace_back("Repair", [this](const YAML::Node& value)->ValidationErrors { (*m_p_switches)[InstallerSwitchType::Repair] = value.as(); return{}; }); - }; + result.emplace_back( + "Upgrade", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + auto switches = std::any_cast*>(any); + (*switches)[InstallerSwitchType::Update] = value.as(); + return{}; + }); } return result; @@ -383,13 +1224,34 @@ namespace AppInstaller::Manifest if (manifestVersion >= ManifestVer{ s_ManifestVersionV1_1 }) { - result.emplace_back("InstallerReturnCode", [this](const YAML::Node& value)->ValidationErrors { m_p_expectedReturnCode->InstallerReturnCode = static_cast(value.as()); return {}; }); - result.emplace_back("ReturnResponse", [this](const YAML::Node& value)->ValidationErrors { m_p_expectedReturnCode->ReturnResponse = ConvertToExpectedReturnCodeEnum(value.as()); return {}; }); + result.emplace_back( + "InstallerReturnCode", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + ExpectedReturnCode* expectedReturnCode = std::any_cast(any); + expectedReturnCode->InstallerReturnCode = static_cast(value.as()); + return {}; + }); + result.emplace_back( + "ReturnResponse", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + ExpectedReturnCode* expectedReturnCode = std::any_cast(any); + expectedReturnCode->ReturnResponse = ConvertToExpectedReturnCodeEnum(value.as()); + return {}; + }); } if (manifestVersion >= ManifestVer{ s_ManifestVersionV1_2 }) { - result.emplace_back("ReturnResponseUrl", [this](const YAML::Node& value)->ValidationErrors { m_p_expectedReturnCode->ReturnResponseUrl = value.as(); return {}; }); + result.emplace_back( + "ReturnResponseUrl", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + ExpectedReturnCode* expectedReturnCode = std::any_cast(any); + expectedReturnCode->ReturnResponseUrl = value.as(); + return {}; + }); } return result; @@ -400,31 +1262,136 @@ namespace AppInstaller::Manifest // Common fields across versions std::vector result = { - { "Description", [this](const YAML::Node& value)->ValidationErrors { m_p_localization->Add(Utility::Trim(value.as())); return {}; } }, - { "LicenseUrl", [this](const YAML::Node& value)->ValidationErrors { m_p_localization->Add(value.as()); return {}; } }, + { + "Description", + [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestLocalization* localization; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + localization = &(manifest->DefaultLocalization); + } + else + { + localization = std::any_cast(any); + } + + localization->Add(Utility::Trim(value.as())); + return {}; + } + }, + { + "LicenseUrl", + [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestLocalization* localization; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + localization = &(manifest->DefaultLocalization); + } + else + { + localization = std::any_cast(any); + } + + localization->Add(value.as()); + return {}; + } + }, }; // Additional version specific fields if (manifestVersion.Major() == 0) { // Root level and Localization node level - result.emplace_back("Homepage", [this](const YAML::Node& value)->ValidationErrors { m_p_localization->Add(value.as()); return {}; }); + result.emplace_back( + "Homepage", + [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestLocalization* localization; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + localization = &(manifest->DefaultLocalization); + } + else + { + localization = std::any_cast(any); + } + + localization->Add(value.as()); + return {}; + }); if (!forRootFields) { // Localization node only - result.emplace_back("Language", [this](const YAML::Node& value)->ValidationErrors { m_p_localization->Locale = value.as(); return {}; }); + result.emplace_back( + "Language", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestLocalization* localization = std::any_cast(any); + localization->Locale = value.as(); + return {}; + }); } else { // Root node only std::vector rootOnlyFields = { - { "Name", [this](const YAML::Node& value)->ValidationErrors { m_p_localization->Add(Utility::Trim(value.as())); return {}; } }, - { "Publisher", [this](const YAML::Node& value)->ValidationErrors { m_p_localization->Add(value.as()); return {}; } }, - { "Author", [this](const YAML::Node& value)->ValidationErrors { m_p_localization->Add(value.as()); return {}; } }, - { "License", [this](const YAML::Node& value)->ValidationErrors { m_p_localization->Add(value.as()); return {}; } }, - { "Tags", [this](const YAML::Node& value)->ValidationErrors { m_p_localization->Add(SplitMultiValueField(value.as())); return {}; } }, + { + "Name", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + Manifest* manifest = std::any_cast(any); + ManifestLocalization* localization = &(manifest->DefaultLocalization); + localization->Add(Utility::Trim(value.as())); + return {}; + } + }, + { + "Publisher", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + Manifest* manifest = std::any_cast(any); + ManifestLocalization* localization = &(manifest->DefaultLocalization); + localization->Add(value.as()); + return {}; + } + }, + { + "Author", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + Manifest* manifest = std::any_cast(any); + ManifestLocalization* localization = &(manifest->DefaultLocalization); + localization->Add(value.as()); + return {}; + } + }, + { + "License", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + Manifest* manifest = std::any_cast(any); + ManifestLocalization* localization = &(manifest->DefaultLocalization); + localization->Add(value.as()); + return {}; + } + }, + { + "Tags", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + Manifest* manifest = std::any_cast(any); + ManifestLocalization* localization = &(manifest->DefaultLocalization); + localization->Add(SplitMultiValueField(value.as())); + return {}; + } + }, }; std::move(rootOnlyFields.begin(), rootOnlyFields.end(), std::inserter(result, result.end())); @@ -438,19 +1405,253 @@ namespace AppInstaller::Manifest // Root level and Localization node level std::vector v1CommonFields = { - { "PackageLocale", [this](const YAML::Node& value)->ValidationErrors { m_p_localization->Locale = value.as(); return {}; } }, - { "Publisher", [this](const YAML::Node& value)->ValidationErrors { m_p_localization->Add(value.as()); return {}; } }, - { "PublisherUrl", [this](const YAML::Node& value)->ValidationErrors { m_p_localization->Add(value.as()); return {}; } }, - { "PublisherSupportUrl", [this](const YAML::Node& value)->ValidationErrors { m_p_localization->Add(value.as()); return {}; } }, - { "PrivacyUrl", [this](const YAML::Node& value)->ValidationErrors { m_p_localization->Add(value.as()); return {}; } }, - { "Author", [this](const YAML::Node& value)->ValidationErrors { m_p_localization->Add(value.as()); return {}; } }, - { "PackageName", [this](const YAML::Node& value)->ValidationErrors { m_p_localization->Add(Utility::Trim(value.as())); return {}; } }, - { "PackageUrl", [this](const YAML::Node& value)->ValidationErrors { m_p_localization->Add(value.as()); return {}; } }, - { "License", [this](const YAML::Node& value)->ValidationErrors { m_p_localization->Add(value.as()); return {}; } }, - { "Copyright", [this](const YAML::Node& value)->ValidationErrors { m_p_localization->Add(value.as()); return {}; } }, - { "CopyrightUrl", [this](const YAML::Node& value)->ValidationErrors { m_p_localization->Add(value.as()); return {}; } }, - { "ShortDescription", [this](const YAML::Node& value)->ValidationErrors { m_p_localization->Add(Utility::Trim(value.as())); return {}; } }, - { "Tags", [this](const YAML::Node& value)->ValidationErrors { m_p_localization->Add(ProcessStringSequenceNode(value)); return {}; } }, + { + "PackageLocale", + [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestLocalization* localization; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + localization = &(manifest->DefaultLocalization); + } + else + { + localization = std::any_cast(any); + } + + localization->Locale = value.as(); + return {}; + } + }, + { + "Publisher", + [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestLocalization* localization; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + localization = &(manifest->DefaultLocalization); + } + else + { + localization = std::any_cast(any); + } + + localization->Add(value.as()); + return {}; + } + }, + { + "PublisherUrl", + [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestLocalization* localization; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + localization = &(manifest->DefaultLocalization); + } + else + { + localization = std::any_cast(any); + } + + localization->Add(value.as()); + return {}; + } + }, + { + "PublisherSupportUrl", + [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestLocalization* localization; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + localization = &(manifest->DefaultLocalization); + } + else + { + localization = std::any_cast(any); + } + + localization->Add(value.as()); + return {}; + } + }, + { + "PrivacyUrl", + [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestLocalization* localization; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + localization = &(manifest->DefaultLocalization); + } + else + { + localization = std::any_cast(any); + } + + localization->Add(value.as()); + return {}; + } + }, + { + "Author", + [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestLocalization* localization; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + localization = &(manifest->DefaultLocalization); + } + else + { + localization = std::any_cast(any); + } + + localization->Add(value.as()); + return {}; + } + }, + { + "PackageName", + [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestLocalization* localization; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + localization = &(manifest->DefaultLocalization); + } + else + { + localization = std::any_cast(any); + } + + localization->Add(Utility::Trim(value.as())); + return {}; + } + }, + { + "PackageUrl", + [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestLocalization* localization; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + localization = &(manifest->DefaultLocalization); + } + else + { + localization = std::any_cast(any); + } + + localization->Add(value.as()); + return {}; + } + }, + { + "License", + [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestLocalization* localization; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + localization = &(manifest->DefaultLocalization); + } + else + { + localization = std::any_cast(any); + } + + localization->Add(value.as()); + return {}; + } + }, + { + "Copyright", + [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestLocalization* localization; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + localization = &(manifest->DefaultLocalization); + } + else + { + localization = std::any_cast(any); + } + + localization->Add(value.as()); + return {}; + } + }, + { + "CopyrightUrl", + [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestLocalization* localization; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + localization = &(manifest->DefaultLocalization); + } + else + { + localization = std::any_cast(any); + } + + localization->Add(value.as()); + return {}; + } + }, + { + "ShortDescription", + [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestLocalization* localization; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + localization = &(manifest->DefaultLocalization); + } + else + { + localization = std::any_cast(any); + } + + localization->Add(Utility::Trim(value.as())); + return {}; + } + }, + { + "Tags", + [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestLocalization* localization; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + localization = &(manifest->DefaultLocalization); + } + else + { + localization = std::any_cast(any); + } + + localization->Add(ProcessStringSequenceNode(value)); + return {}; + } + }, }; std::move(v1CommonFields.begin(), v1CommonFields.end(), std::inserter(result, result.end())); @@ -460,9 +1661,62 @@ namespace AppInstaller::Manifest { std::vector fields_v1_1 = { - { "Agreements", [this](const YAML::Node& value)->ValidationErrors { return ProcessAgreementsNode(value); } }, - { "ReleaseNotes", [this](const YAML::Node& value)->ValidationErrors { m_p_localization->Add(value.as()); return {}; } }, - { "ReleaseNotesUrl", [this](const YAML::Node& value)->ValidationErrors { m_p_localization->Add(value.as()); return {}; } }, + { + "Agreements", + [this, forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestLocalization* localization; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + localization = &(manifest->DefaultLocalization); + } + else + { + localization = std::any_cast(any); + } + + return ProcessAgreementsNode(value, localization); + } + }, + { + "ReleaseNotes", + [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestLocalization* localization; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + localization = &(manifest->DefaultLocalization); + } + else + { + localization = std::any_cast(any); + } + + localization->Add(value.as()); + return {}; + } + }, + { + "ReleaseNotesUrl", + [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestLocalization* localization; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + localization = &(manifest->DefaultLocalization); + } + else + { + localization = std::any_cast(any); + } + + localization->Add(value.as()); + return {}; + } + }, }; std::move(fields_v1_1.begin(), fields_v1_1.end(), std::inserter(result, result.end())); @@ -472,9 +1726,62 @@ namespace AppInstaller::Manifest { std::vector fields_v1_2 = { - { "PurchaseUrl", [this](const YAML::Node& value)->ValidationErrors { m_p_localization->Add(value.as()); return {}; } }, - { "InstallationNotes", [this](const YAML::Node& value)->ValidationErrors { m_p_localization->Add(value.as()); return {}; } }, - { "Documentations", [this](const YAML::Node& value)->ValidationErrors { return ProcessDocumentationsNode(value); }}, + { + "PurchaseUrl", + [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestLocalization* localization; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + localization = &(manifest->DefaultLocalization); + } + else + { + localization = std::any_cast(any); + } + + localization->Add(value.as()); + return {}; + } + }, + { + "InstallationNotes", + [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestLocalization* localization; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + localization = &(manifest->DefaultLocalization); + } + else + { + localization = std::any_cast(any); + } + + localization->Add(value.as()); + return {}; + } + }, + { + "Documentations", + [this, forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestLocalization* localization; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + localization = &(manifest->DefaultLocalization); + } + else + { + localization = std::any_cast(any); + } + + return ProcessDocumentationsNode(value, localization); + } + }, }; std::move(fields_v1_2.begin(), fields_v1_2.end(), std::inserter(result, result.end())); @@ -484,7 +1791,25 @@ namespace AppInstaller::Manifest { std::vector fields_v1_5 = { - { "Icons", [this](const YAML::Node& value)->ValidationErrors { return ProcessIconsNode(value); }, true }, + { + "Icons", + [this, forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestLocalization* localization; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + localization = &(manifest->DefaultLocalization); + } + else + { + localization = std::any_cast(any); + } + + return ProcessIconsNode(value, localization); + }, + true + }, }; std::move(fields_v1_5.begin(), fields_v1_5.end(), std::inserter(result, result.end())); @@ -502,22 +1827,54 @@ namespace AppInstaller::Manifest { result = { - { "WindowsFeatures", [this](const YAML::Node& value)->ValidationErrors { ProcessDependenciesNode(DependencyType::WindowsFeature, value); return {}; } }, - { "WindowsLibraries", [this](const YAML::Node& value)->ValidationErrors { ProcessDependenciesNode(DependencyType::WindowsLibrary, value); return {}; } }, - { "PackageDependencies", [this](const YAML::Node& value)->ValidationErrors { ProcessPackageDependenciesNode(value); return {}; } }, - { "ExternalDependencies", [this](const YAML::Node& value)->ValidationErrors { ProcessDependenciesNode(DependencyType::External, value); return {}; } }, + { + "WindowsFeatures", + [this](const YAML::Node& value, std::any& any)->ValidationErrors + { + DependencyList* dependencyList = std::any_cast(any); + ProcessDependenciesNode(DependencyType::WindowsFeature, value, dependencyList); + return {}; + } + }, + { + "WindowsLibraries", + [this](const YAML::Node& value, std::any& any)->ValidationErrors + { + DependencyList* dependencyList = std::any_cast(any); + ProcessDependenciesNode(DependencyType::WindowsLibrary, value, dependencyList); + return {}; + } + }, + { + "PackageDependencies", + [this](const YAML::Node& value, std::any& any)->ValidationErrors + { + DependencyList* dependencyList = std::any_cast(any); + ProcessPackageDependenciesNode(value, dependencyList); + return {}; + } + }, + { + "ExternalDependencies", + [this](const YAML::Node& value, std::any& any)->ValidationErrors + { + DependencyList* dependencyList = std::any_cast(any); + ProcessDependenciesNode(DependencyType::External, value, dependencyList); + return {}; + } + }, }; } return result; } - void ManifestYamlPopulator::ProcessDependenciesNode(DependencyType type, const YAML::Node& node) + void ManifestYamlPopulator::ProcessDependenciesNode(DependencyType type, const YAML::Node& node, DependencyList* dependencyList) { const auto& ids = ProcessStringSequenceNode(node); for (auto id : ids) { - m_p_dependencyList->Add(Dependency(type, id)); + dependencyList->Add(Dependency(type, id)); } } @@ -529,8 +1886,24 @@ namespace AppInstaller::Manifest { result = { - { "PackageIdentifier", [this](const YAML::Node& value)->ValidationErrors { m_p_packageDependency->SetId(Utility::Trim(value.as())); return {}; } }, - { "MinimumVersion", [this](const YAML::Node& value)->ValidationErrors { m_p_packageDependency->MinVersion = Utility::Version(Utility::Trim(value.as())); return {}; } }, + { + "PackageIdentifier", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + Dependency* packageDependency = std::any_cast(any); + packageDependency->SetId(Utility::Trim(value.as())); + return {}; + } + }, + { + "MinimumVersion", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + Dependency* packageDependency = std::any_cast(any); + packageDependency->MinVersion = Utility::Version(Utility::Trim(value.as())); + return {}; + } + }, }; } @@ -545,9 +1918,33 @@ namespace AppInstaller::Manifest { result = { - { "AgreementLabel", [this](const YAML::Node& value)->ValidationErrors { m_p_agreement->Label = Utility::Trim(value.as()); return {}; } }, - { "Agreement", [this](const YAML::Node& value)->ValidationErrors { m_p_agreement->AgreementText = Utility::Trim(value.as()); return {}; }, true }, - { "AgreementUrl", [this](const YAML::Node& value)->ValidationErrors { m_p_agreement->AgreementUrl = Utility::Trim(value.as()); return {}; } }, + { + "AgreementLabel", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + Agreement* agreement = std::any_cast(any); + agreement->Label = Utility::Trim(value.as()); + return {}; + } + }, + { + "Agreement", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + Agreement* agreement = std::any_cast(any); + agreement->AgreementText = Utility::Trim(value.as()); + return {}; + }, + true }, + { + "AgreementUrl", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + Agreement* agreement = std::any_cast(any); + agreement->AgreementUrl = Utility::Trim(value.as()); + return {}; + } + }, }; } @@ -562,8 +1959,24 @@ namespace AppInstaller::Manifest { result = { - { "AllowedMarkets", [this](const YAML::Node& value)->ValidationErrors { m_p_markets->AllowedMarkets = ProcessStringSequenceNode(value); return {}; } }, - { "ExcludedMarkets", [this](const YAML::Node& value)->ValidationErrors { m_p_markets->ExcludedMarkets = ProcessStringSequenceNode(value); return {}; } }, + { + "AllowedMarkets", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + MarketsInfo* markets = std::any_cast(any); + markets->AllowedMarkets = ProcessStringSequenceNode(value); + return {}; + } + }, + { + "ExcludedMarkets", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + MarketsInfo* markets = std::any_cast(any); + markets->ExcludedMarkets = ProcessStringSequenceNode(value); + return {}; + } + }, }; } @@ -578,12 +1991,60 @@ namespace AppInstaller::Manifest { result = { - { "DisplayName", [this](const YAML::Node& value)->ValidationErrors { m_p_appsAndFeaturesEntry->DisplayName = Utility::Trim(value.as()); return {}; } }, - { "Publisher", [this](const YAML::Node& value)->ValidationErrors { m_p_appsAndFeaturesEntry->Publisher = Utility::Trim(value.as()); return {}; } }, - { "DisplayVersion", [this](const YAML::Node& value)->ValidationErrors { m_p_appsAndFeaturesEntry->DisplayVersion = Utility::Trim(value.as()); return {}; } }, - { "ProductCode", [this](const YAML::Node& value)->ValidationErrors { m_p_appsAndFeaturesEntry->ProductCode = Utility::Trim(value.as()); return {}; } }, - { "UpgradeCode", [this](const YAML::Node& value)->ValidationErrors { m_p_appsAndFeaturesEntry->UpgradeCode = Utility::Trim(value.as()); return {}; } }, - { "InstallerType", [this](const YAML::Node& value)->ValidationErrors { m_p_appsAndFeaturesEntry->InstallerType = ConvertToInstallerTypeEnum(value.as()); return {}; } }, + { + "DisplayName", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + AppsAndFeaturesEntry* appsAndFeaturesEntry = std::any_cast(any); + appsAndFeaturesEntry->DisplayName = Utility::Trim(value.as()); + return {}; + } + }, + { + "Publisher", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + AppsAndFeaturesEntry* appsAndFeaturesEntry = std::any_cast(any); + appsAndFeaturesEntry->Publisher = Utility::Trim(value.as()); + return {}; + } + }, + { + "DisplayVersion", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + AppsAndFeaturesEntry* appsAndFeaturesEntry = std::any_cast(any); + appsAndFeaturesEntry->DisplayVersion = Utility::Trim(value.as()); + return {}; + } + }, + { + "ProductCode", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + AppsAndFeaturesEntry* appsAndFeaturesEntry = std::any_cast(any); + appsAndFeaturesEntry->ProductCode = Utility::Trim(value.as()); + return {}; + } + }, + { + "UpgradeCode", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + AppsAndFeaturesEntry* appsAndFeaturesEntry = std::any_cast(any); + appsAndFeaturesEntry->UpgradeCode = Utility::Trim(value.as()); + return {}; + } + }, + { + "InstallerType", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + AppsAndFeaturesEntry* appsAndFeaturesEntry = std::any_cast(any); + appsAndFeaturesEntry->InstallerType = ConvertToInstallerTypeEnum(value.as()); + return {}; + } + }, }; } @@ -598,8 +2059,24 @@ namespace AppInstaller::Manifest { result = { - { "DocumentLabel", [this](const YAML::Node& value)->ValidationErrors { m_p_documentation->DocumentLabel = Utility::Trim(value.as()); return {}; } }, - { "DocumentUrl", [this](const YAML::Node& value)->ValidationErrors { m_p_documentation->DocumentUrl = Utility::Trim(value.as()); return {}; } }, + { + "DocumentLabel", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + Documentation* documentation = std::any_cast(any); + documentation->DocumentLabel = Utility::Trim(value.as()); + return {}; + } + }, + { + "DocumentUrl", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + Documentation* documentation = std::any_cast(any); + documentation->DocumentUrl = Utility::Trim(value.as()); + return {}; + } + }, }; } @@ -614,11 +2091,50 @@ namespace AppInstaller::Manifest { result = { - { "IconUrl", [this](const YAML::Node& value)->ValidationErrors { m_p_icon->Url = Utility::Trim(value.as()); return {}; } }, - { "IconFileType", [this](const YAML::Node& value)->ValidationErrors { m_p_icon->FileType = ConvertToIconFileTypeEnum(value.as()); return {}; } }, - { "IconResolution", [this](const YAML::Node& value)->ValidationErrors { m_p_icon->Resolution = ConvertToIconResolutionEnum(value.as()); return {}; } }, - { "IconTheme", [this](const YAML::Node& value)->ValidationErrors { m_p_icon->Theme = ConvertToIconThemeEnum(value.as()); return {}; } }, - { "IconSha256", [this](const YAML::Node& value)->ValidationErrors { m_p_icon->Sha256 = Utility::SHA256::ConvertToBytes(value.as()); return {}; } }, + { + "IconUrl", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + Icon* icon = std::any_cast(any); + icon->Url = Utility::Trim(value.as()); return {}; + } + }, + { + "IconFileType", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + Icon* icon = std::any_cast(any); + icon->FileType = ConvertToIconFileTypeEnum(value.as()); + return {}; + } + }, + { + "IconResolution", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + Icon* icon = std::any_cast(any); + icon->Resolution = ConvertToIconResolutionEnum(value.as()); + return {}; + } + }, + { + "IconTheme", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + Icon* icon = std::any_cast(any); + icon->Theme = ConvertToIconThemeEnum(value.as()); + return {}; + } + }, + { + "IconSha256", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + Icon* icon = std::any_cast(any); + icon->Sha256 = Utility::SHA256::ConvertToBytes(value.as()); + return {}; + } + }, }; } @@ -633,8 +2149,24 @@ namespace AppInstaller::Manifest { result = { - { "RelativeFilePath", [this](const YAML::Node& value)->ValidationErrors { m_p_nestedInstallerFile->RelativeFilePath = Utility::Trim(value.as()); return {}; } }, - { "PortableCommandAlias", [this](const YAML::Node& value)->ValidationErrors { m_p_nestedInstallerFile->PortableCommandAlias = Utility::Trim(value.as()); return {}; } }, + { + "RelativeFilePath", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + NestedInstallerFile* nestedInstallerFile = std::any_cast(any); + nestedInstallerFile->RelativeFilePath = Utility::Trim(value.as()); + return {}; + } + }, + { + "PortableCommandAlias", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + NestedInstallerFile* nestedInstallerFile = std::any_cast(any); + nestedInstallerFile->PortableCommandAlias = Utility::Trim(value.as()); + return {}; + } + }, }; } @@ -649,8 +2181,23 @@ namespace AppInstaller::Manifest { result = { - { "DefaultInstallLocation", [this](const YAML::Node& value)->ValidationErrors { m_p_installationMetadata->DefaultInstallLocation = Utility::Trim(value.as()); return {}; } }, - { "Files", [this](const YAML::Node& value)->ValidationErrors { return ProcessInstallationMetadataFilesNode(value); } }, + { + "DefaultInstallLocation", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + InstallationMetadataInfo* installationMetadata = std::any_cast(any); + installationMetadata->DefaultInstallLocation = Utility::Trim(value.as()); + return {}; + } + }, + { + "Files", + [this](const YAML::Node& value, std::any& any)->ValidationErrors + { + InstallationMetadataInfo* installationMetadata = std::any_cast(any); + return ProcessInstallationMetadataFilesNode(value, installationMetadata); + } + }, }; } @@ -665,11 +2212,51 @@ namespace AppInstaller::Manifest { result = { - { "RelativeFilePath", [this](const YAML::Node& value)->ValidationErrors { m_p_installedFile->RelativeFilePath = Utility::Trim(value.as()); return {}; } }, - { "FileSha256", [this](const YAML::Node& value)->ValidationErrors { m_p_installedFile->FileSha256 = Utility::SHA256::ConvertToBytes(value.as()); return {}; } }, - { "FileType", [this](const YAML::Node& value)->ValidationErrors { m_p_installedFile->FileType = ConvertToInstalledFileTypeEnum(value.as()); return {}; } }, - { "InvocationParameter", [this](const YAML::Node& value)->ValidationErrors { m_p_installedFile->InvocationParameter = Utility::Trim(value.as()); return {}; } }, - { "DisplayName", [this](const YAML::Node& value)->ValidationErrors { m_p_installedFile->DisplayName = Utility::Trim(value.as()); return {}; } }, + { + "RelativeFilePath", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + InstalledFile* installedFile = std::any_cast(any); + installedFile->RelativeFilePath = Utility::Trim(value.as()); + return {}; + } + }, + { + "FileSha256", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + InstalledFile* installedFile = std::any_cast(any); + installedFile->FileSha256 = Utility::SHA256::ConvertToBytes(value.as()); + return {}; + } + }, + { + "FileType", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + InstalledFile* installedFile = std::any_cast(any); + installedFile->FileType = ConvertToInstalledFileTypeEnum(value.as()); + return {}; + } + }, + { + "InvocationParameter", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + InstalledFile* installedFile = std::any_cast(any); + installedFile->InvocationParameter = Utility::Trim(value.as()); + return {}; + } + }, + { + "DisplayName", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + InstalledFile* installedFile = std::any_cast(any); + installedFile->DisplayName = Utility::Trim(value.as()); + return {}; + } + }, }; } @@ -678,7 +2265,8 @@ namespace AppInstaller::Manifest ValidationErrors ManifestYamlPopulator::ValidateAndProcessFields( const YAML::Node& rootNode, - const std::vector& fieldInfos) + const std::vector& fieldInfos, + std::any& any) { ValidationErrors resultErrors; @@ -730,7 +2318,7 @@ namespace AppInstaller::Manifest { try { - auto errors = fieldInfo.ProcessFunc(valueNode); + auto errors = fieldInfo.ProcessFunc(valueNode, any); std::move(errors.begin(), errors.end(), std::inserter(resultErrors, resultErrors.end())); } catch (const std::exception&) @@ -752,23 +2340,23 @@ namespace AppInstaller::Manifest return resultErrors; } - ValidationErrors ManifestYamlPopulator::ProcessPackageDependenciesNode(const YAML::Node& rootNode) + ValidationErrors ManifestYamlPopulator::ProcessPackageDependenciesNode(const YAML::Node& rootNode, DependencyList* dependencyList) { ValidationErrors resultErrors; for (auto const& entry : rootNode.Sequence()) { Dependency packageDependency = Dependency(DependencyType::Package); - m_p_packageDependency = &packageDependency; - auto errors = ValidateAndProcessFields(entry, PackageDependenciesFieldInfos); + std::any any = &packageDependency; + auto errors = ValidateAndProcessFields(entry, PackageDependenciesFieldInfos, any); std::move(errors.begin(), errors.end(), std::inserter(resultErrors, resultErrors.end())); - m_p_dependencyList->Add(std::move(packageDependency)); + dependencyList->Add(std::move(packageDependency)); } return resultErrors; } - ValidationErrors ManifestYamlPopulator::ProcessAgreementsNode(const YAML::Node& agreementsNode) + ValidationErrors ManifestYamlPopulator::ProcessAgreementsNode(const YAML::Node& agreementsNode, ManifestLocalization* localization) { THROW_HR_IF(E_INVALIDARG, !agreementsNode.IsSequence()); @@ -778,30 +2366,30 @@ namespace AppInstaller::Manifest for (auto const& entry : agreementsNode.Sequence()) { Agreement agreement; - m_p_agreement = &agreement; - auto errors = ValidateAndProcessFields(entry, AgreementFieldInfos); + std::any any = &agreement; + auto errors = ValidateAndProcessFields(entry, AgreementFieldInfos, any); std::move(errors.begin(), errors.end(), std::inserter(resultErrors, resultErrors.end())); agreements.emplace_back(std::move(agreement)); } if (!agreements.empty()) { - m_p_localization->Add(std::move(agreements)); + localization->Add(std::move(agreements)); } return resultErrors; } - std::vector ManifestYamlPopulator::ProcessMarketsNode(const YAML::Node& marketsNode) + std::vector ManifestYamlPopulator::ProcessMarketsNode(const YAML::Node& marketsNode, ManifestInstaller* installer) { MarketsInfo markets; - m_p_markets = &markets; - auto errors = ValidateAndProcessFields(marketsNode, MarketsFieldInfos); - m_p_installer->Markets = markets; + std::any any = &markets; + auto errors = ValidateAndProcessFields(marketsNode, MarketsFieldInfos, any); + installer->Markets = markets; return errors; } - std::vector ManifestYamlPopulator::ProcessAppsAndFeaturesEntriesNode(const YAML::Node& appsAndFeaturesEntriesNode) + std::vector ManifestYamlPopulator::ProcessAppsAndFeaturesEntriesNode(const YAML::Node& appsAndFeaturesEntriesNode, ManifestInstaller* installer) { THROW_HR_IF(E_INVALIDARG, !appsAndFeaturesEntriesNode.IsSequence()); @@ -811,18 +2399,18 @@ namespace AppInstaller::Manifest for (auto const& entry : appsAndFeaturesEntriesNode.Sequence()) { AppsAndFeaturesEntry appsAndFeaturesEntry; - m_p_appsAndFeaturesEntry = &appsAndFeaturesEntry; - auto errors = ValidateAndProcessFields(entry, AppsAndFeaturesEntryFieldInfos); + std::any any = &appsAndFeaturesEntry; + auto errors = ValidateAndProcessFields(entry, AppsAndFeaturesEntryFieldInfos, any); std::move(errors.begin(), errors.end(), std::inserter(resultErrors, resultErrors.end())); appsAndFeaturesEntries.emplace_back(std::move(appsAndFeaturesEntry)); } - m_p_installer->AppsAndFeaturesEntries = appsAndFeaturesEntries; + installer->AppsAndFeaturesEntries = appsAndFeaturesEntries; return resultErrors; } - ValidationErrors ManifestYamlPopulator::ProcessExpectedReturnCodesNode(const YAML::Node& returnCodesNode) + ValidationErrors ManifestYamlPopulator::ProcessExpectedReturnCodesNode(const YAML::Node& returnCodesNode, ManifestInstaller* installer) { THROW_HR_IF(E_INVALIDARG, !returnCodesNode.IsSequence()); @@ -832,8 +2420,8 @@ namespace AppInstaller::Manifest for (auto const& entry : returnCodesNode.Sequence()) { ExpectedReturnCode returnCode; - m_p_expectedReturnCode = &returnCode; - auto errors = ValidateAndProcessFields(entry, ExpectedReturnCodesFieldInfos); + std::any any = &returnCode; + auto errors = ValidateAndProcessFields(entry, ExpectedReturnCodesFieldInfos, any); std::move(errors.begin(), errors.end(), std::inserter(resultErrors, resultErrors.end())); if (!returnCodes.insert({ returnCode.InstallerReturnCode, {returnCode.ReturnResponse, returnCode.ReturnResponseUrl} }).second) { @@ -841,12 +2429,12 @@ namespace AppInstaller::Manifest } } - m_p_installer->ExpectedReturnCodes = returnCodes; + installer->ExpectedReturnCodes = returnCodes; return resultErrors; } - ValidationErrors ManifestYamlPopulator::ProcessDocumentationsNode(const YAML::Node& documentationsNode) + ValidationErrors ManifestYamlPopulator::ProcessDocumentationsNode(const YAML::Node& documentationsNode, ManifestLocalization* localization) { THROW_HR_IF(E_INVALIDARG, !documentationsNode.IsSequence()); @@ -856,21 +2444,21 @@ namespace AppInstaller::Manifest for (auto const& entry : documentationsNode.Sequence()) { Documentation documentation; - m_p_documentation = &documentation; - auto errors = ValidateAndProcessFields(entry, DocumentationFieldInfos); + std::any any = &documentation; + auto errors = ValidateAndProcessFields(entry, DocumentationFieldInfos, any); std::move(errors.begin(), errors.end(), std::inserter(resultErrors, resultErrors.end())); documentations.emplace_back(std::move(documentation)); } if (!documentations.empty()) { - m_p_localization->Add(std::move(documentations)); + localization->Add(std::move(documentations)); } return resultErrors; } - std::vector ManifestYamlPopulator::ProcessIconsNode(const YAML::Node& iconsNode) + std::vector ManifestYamlPopulator::ProcessIconsNode(const YAML::Node& iconsNode, ManifestLocalization* localization) { THROW_HR_IF(E_INVALIDARG, !iconsNode.IsSequence()); @@ -880,21 +2468,21 @@ namespace AppInstaller::Manifest for (auto const& entry : iconsNode.Sequence()) { Icon icon; - m_p_icon = &icon; - auto errors = ValidateAndProcessFields(entry, IconFieldInfos); + std::any any = &icon; + auto errors = ValidateAndProcessFields(entry, IconFieldInfos, any); std::move(errors.begin(), errors.end(), std::inserter(resultErrors, resultErrors.end())); icons.emplace_back(std::move(icon)); } if (!icons.empty()) { - m_p_localization->Add(std::move(icons)); + localization->Add(std::move(icons)); } return resultErrors; } - ValidationErrors ManifestYamlPopulator::ProcessNestedInstallerFilesNode(const YAML::Node& nestedInstallerFilesNode) + ValidationErrors ManifestYamlPopulator::ProcessNestedInstallerFilesNode(const YAML::Node& nestedInstallerFilesNode, ManifestInstaller* installer) { THROW_HR_IF(E_INVALIDARG, !nestedInstallerFilesNode.IsSequence()); @@ -904,21 +2492,21 @@ namespace AppInstaller::Manifest for (auto const& entry : nestedInstallerFilesNode.Sequence()) { NestedInstallerFile nestedInstallerFile; - m_p_nestedInstallerFile = &nestedInstallerFile; - auto errors = ValidateAndProcessFields(entry, NestedInstallerFileFieldInfos); + std::any any = &nestedInstallerFile; + auto errors = ValidateAndProcessFields(entry, NestedInstallerFileFieldInfos, any); std::move(errors.begin(), errors.end(), std::inserter(resultErrors, resultErrors.end())); nestedInstallerFiles.emplace_back(std::move(nestedInstallerFile)); } if (!nestedInstallerFiles.empty()) { - m_p_installer->NestedInstallerFiles = nestedInstallerFiles; + installer->NestedInstallerFiles = nestedInstallerFiles; } return resultErrors; } - std::vector ManifestYamlPopulator::ProcessInstallationMetadataFilesNode(const YAML::Node& installedFilesNode) + std::vector ManifestYamlPopulator::ProcessInstallationMetadataFilesNode(const YAML::Node& installedFilesNode, InstallationMetadataInfo* installationMetadata) { THROW_HR_IF(E_INVALIDARG, !installedFilesNode.IsSequence()); @@ -928,15 +2516,15 @@ namespace AppInstaller::Manifest for (auto const& entry : installedFilesNode.Sequence()) { InstalledFile installedFile; - m_p_installedFile = &installedFile; - auto errors = ValidateAndProcessFields(entry, InstallationMetadataFilesFieldInfos); + std::any any = &installedFile; + auto errors = ValidateAndProcessFields(entry, InstallationMetadataFilesFieldInfos, any); std::move(errors.begin(), errors.end(), std::inserter(resultErrors, resultErrors.end())); installedFiles.emplace_back(std::move(installedFile)); } if (!installedFiles.empty()) { - m_p_installationMetadata->Files = installedFiles; + installationMetadata->Files = installedFiles; } return resultErrors; @@ -971,11 +2559,8 @@ namespace AppInstaller::Manifest InstallationMetadataFieldInfos = GetInstallationMetadataFieldProcessInfo(manifestVersion); InstallationMetadataFilesFieldInfos = GetInstallationMetadataFilesFieldProcessInfo(manifestVersion); - // Populate root - m_p_manifest = &manifest; - m_p_installer = &(manifest.DefaultInstallerInfo); - m_p_localization = &(manifest.DefaultLocalization); - resultErrors = ValidateAndProcessFields(rootNode, RootFieldInfos); + std::any anyManifest = &manifest; + resultErrors = ValidateAndProcessFields(rootNode, RootFieldInfos, anyManifest); if (!m_p_installersNode) { @@ -997,8 +2582,8 @@ namespace AppInstaller::Manifest installer.NestedInstallerType = InstallerTypeEnum::Unknown; installer.NestedInstallerFiles.clear(); - m_p_installer = &installer; - auto errors = ValidateAndProcessFields(entry, InstallerFieldInfos); + std::any anyInstaller = &installer; + auto errors = ValidateAndProcessFields(entry, InstallerFieldInfos, anyInstaller); std::move(errors.begin(), errors.end(), std::inserter(resultErrors, resultErrors.end())); // Copy in system reference strings from the root if not set in the installer and appropriate @@ -1066,8 +2651,8 @@ namespace AppInstaller::Manifest for (auto const& entry : m_p_localizationsNode->Sequence()) { ManifestLocalization localization; - m_p_localization = &localization; - auto errors = ValidateAndProcessFields(entry, LocalizationFieldInfos); + std::any any = &localization; + auto errors = ValidateAndProcessFields(entry, LocalizationFieldInfos, any); std::move(errors.begin(), errors.end(), std::inserter(resultErrors, resultErrors.end())); manifest.Localizations.emplace_back(std::move(std::move(localization))); } diff --git a/src/AppInstallerCommonCore/Public/winget/ManifestYamlPopulator.h b/src/AppInstallerCommonCore/Public/winget/ManifestYamlPopulator.h index f426f08073..67a30ec3ef 100644 --- a/src/AppInstallerCommonCore/Public/winget/ManifestYamlPopulator.h +++ b/src/AppInstallerCommonCore/Public/winget/ManifestYamlPopulator.h @@ -23,11 +23,11 @@ namespace AppInstaller::Manifest // Struct mapping a manifest field to its population logic struct FieldProcessInfo { - FieldProcessInfo(std::string name, std::function(const YAML::Node&)> func, bool requireVerifiedPublisher = false) : + FieldProcessInfo(std::string name, std::function(const YAML::Node&, std::any&)> func, bool requireVerifiedPublisher = false) : Name(std::move(name)), ProcessFunc(func), RequireVerifiedPublisher(requireVerifiedPublisher) {} std::string Name; - std::function(const YAML::Node&)> ProcessFunc; + std::function(const YAML::Node&, std::any& any)> ProcessFunc; bool RequireVerifiedPublisher = false; }; @@ -47,22 +47,6 @@ namespace AppInstaller::Manifest std::vector InstallationMetadataFieldInfos; std::vector InstallationMetadataFilesFieldInfos; - // These pointers are referenced in the processing functions in manifest field process info table. - AppInstaller::Manifest::Manifest* m_p_manifest = nullptr; - AppInstaller::Manifest::ManifestInstaller* m_p_installer = nullptr; - std::map* m_p_switches = nullptr; - AppInstaller::Manifest::ExpectedReturnCode* m_p_expectedReturnCode = nullptr; - AppInstaller::Manifest::DependencyList* m_p_dependencyList = nullptr; - AppInstaller::Manifest::Dependency* m_p_packageDependency = nullptr; - AppInstaller::Manifest::ManifestLocalization* m_p_localization = nullptr; - AppInstaller::Manifest::Agreement* m_p_agreement = nullptr; - AppInstaller::Manifest::MarketsInfo* m_p_markets = nullptr; - AppInstaller::Manifest::AppsAndFeaturesEntry* m_p_appsAndFeaturesEntry = nullptr; - AppInstaller::Manifest::Documentation* m_p_documentation = nullptr; - AppInstaller::Manifest::Icon* m_p_icon = nullptr; - AppInstaller::Manifest::NestedInstallerFile* m_p_nestedInstallerFile = nullptr; - AppInstaller::Manifest::InstallationMetadataInfo* m_p_installationMetadata = nullptr; - AppInstaller::Manifest::InstalledFile* m_p_installedFile = nullptr; // Cache of Installers node and Localization node YAML::Node const* m_p_installersNode = nullptr; @@ -90,18 +74,19 @@ namespace AppInstaller::Manifest // pair ourselves. This also helps with generating aggregated error rather than throwing on first failure. std::vector ValidateAndProcessFields( const YAML::Node& rootNode, - const std::vector& fieldInfos); + const std::vector& fieldInfos, + std::any& any); - void ProcessDependenciesNode(DependencyType type, const YAML::Node& rootNode); - std::vector ProcessPackageDependenciesNode(const YAML::Node& rootNode); - std::vector ProcessAgreementsNode(const YAML::Node& agreementsNode); - std::vector ProcessMarketsNode(const YAML::Node& marketsNode); - std::vector ProcessAppsAndFeaturesEntriesNode(const YAML::Node& appsAndFeaturesEntriesNode); - std::vector ProcessExpectedReturnCodesNode(const YAML::Node& returnCodesNode); - std::vector ProcessDocumentationsNode(const YAML::Node& documentationsNode); - std::vector ProcessIconsNode(const YAML::Node& iconsNode); - std::vector ProcessNestedInstallerFilesNode(const YAML::Node& nestedInstallerFilesNode); - std::vector ProcessInstallationMetadataFilesNode(const YAML::Node& installedFilesNode); + void ProcessDependenciesNode(DependencyType type, const YAML::Node& rootNode, DependencyList* dependencyList); + std::vector ProcessPackageDependenciesNode(const YAML::Node& rootNode, DependencyList* dependencyList); + std::vector ProcessAgreementsNode(const YAML::Node& agreementsNode, ManifestLocalization* localization); + std::vector ProcessMarketsNode(const YAML::Node& marketsNode, AppInstaller::Manifest::ManifestInstaller* installer); + std::vector ProcessAppsAndFeaturesEntriesNode(const YAML::Node& appsAndFeaturesEntriesNode, AppInstaller::Manifest::ManifestInstaller* installer); + std::vector ProcessExpectedReturnCodesNode(const YAML::Node& returnCodesNode, AppInstaller::Manifest::ManifestInstaller* installer); + std::vector ProcessDocumentationsNode(const YAML::Node& documentationsNode, ManifestLocalization* localization); + std::vector ProcessIconsNode(const YAML::Node& iconsNode, ManifestLocalization* localization); + std::vector ProcessNestedInstallerFilesNode(const YAML::Node& nestedInstallerFilesNode, AppInstaller::Manifest::ManifestInstaller* installer); + std::vector ProcessInstallationMetadataFilesNode(const YAML::Node& installedFilesNode, InstallationMetadataInfo* installationMetadata); std::vector PopulateManifestInternal( const YAML::Node& rootNode, @@ -109,4 +94,4 @@ namespace AppInstaller::Manifest const ManifestVer& manifestVersion, ManifestValidateOption validateOption); }; -} \ No newline at end of file +} diff --git a/src/AppInstallerCommonCore/pch.h b/src/AppInstallerCommonCore/pch.h index 5bda4d89d8..47e2699b2c 100644 --- a/src/AppInstallerCommonCore/pch.h +++ b/src/AppInstallerCommonCore/pch.h @@ -59,6 +59,7 @@ #include #include #include +#include #pragma warning( push ) #pragma warning ( disable : 6001 6285 6287 6340 6387 6388 26451 26495 28196 ) From 6a85407a4073b07d4f650bb6d814e3687e88152c Mon Sep 17 00:00:00 2001 From: Ruben Guerrero Samaniego Date: Wed, 17 Jan 2024 16:59:54 -0800 Subject: [PATCH 2/5] of course --- .../Manifest/ManifestYamlPopulator.cpp | 40 +++++++++++++++++++ .../APIUnitTests/SQLiteIndexUnitTests.cs | 2 +- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/AppInstallerCommonCore/Manifest/ManifestYamlPopulator.cpp b/src/AppInstallerCommonCore/Manifest/ManifestYamlPopulator.cpp index 1d100c5b39..298e3b3fac 100644 --- a/src/AppInstallerCommonCore/Manifest/ManifestYamlPopulator.cpp +++ b/src/AppInstallerCommonCore/Manifest/ManifestYamlPopulator.cpp @@ -1116,6 +1116,34 @@ namespace AppInstaller::Manifest std::move(fields_v1_6.begin(), fields_v1_6.end(), std::inserter(result, result.end())); } + + if (manifestVersion >= ManifestVer{ s_ManifestVersionV1_7 }) + { + std::vector fields_v1_7 = + { + { + "RepairBehavior", + [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors + { + ManifestInstaller* installer; + if (forRootFields) + { + Manifest* manifest = std::any_cast(any); + installer = &(manifest->DefaultInstallerInfo); + } + else + { + installer = std::any_cast(any); + } + + installer->RepairBehavior = ConvertToRepairBehaviorEnum(value.as()); + return {}; + } + }, + }; + + std::move(fields_v1_7.begin(), fields_v1_7.end(), std::inserter(result, result.end())); + } } return result; @@ -1213,6 +1241,18 @@ namespace AppInstaller::Manifest (*switches)[InstallerSwitchType::Update] = value.as(); return{}; }); + + if (manifestVersion >= ManifestVer{ s_ManifestVersionV1_7 }) + { + result.emplace_back( + "Repair", + [](const YAML::Node& value, std::any& any)->ValidationErrors + { + auto switches = std::any_cast*>(any); + (*switches)[InstallerSwitchType::Repair] = value.as(); + return{}; + }); + }; } return result; diff --git a/src/WinGetUtilInterop.UnitTests/APIUnitTests/SQLiteIndexUnitTests.cs b/src/WinGetUtilInterop.UnitTests/APIUnitTests/SQLiteIndexUnitTests.cs index bc93dbc37c..a764412ac1 100644 --- a/src/WinGetUtilInterop.UnitTests/APIUnitTests/SQLiteIndexUnitTests.cs +++ b/src/WinGetUtilInterop.UnitTests/APIUnitTests/SQLiteIndexUnitTests.cs @@ -85,7 +85,7 @@ public void OpenIndex() [DisplayTestMethodName] public void OpenIndexFileDontExist() { - // Verify fails with non existent file. + // Verify fails with fake file. var exception = Assert.Throws( () => { From f145305bebab14587a6231e1aa48618de2a608f5 Mon Sep 17 00:00:00 2001 From: Ruben Guerrero Samaniego Date: Thu, 18 Jan 2024 17:56:10 -0800 Subject: [PATCH 3/5] less code --- .../Manifest/ManifestYamlPopulator.cpp | 1985 ++--------------- .../Public/winget/ManifestYamlPopulator.h | 3 +- 2 files changed, 194 insertions(+), 1794 deletions(-) diff --git a/src/AppInstallerCommonCore/Manifest/ManifestYamlPopulator.cpp b/src/AppInstallerCommonCore/Manifest/ManifestYamlPopulator.cpp index 298e3b3fac..c6b3965ae8 100644 --- a/src/AppInstallerCommonCore/Manifest/ManifestYamlPopulator.cpp +++ b/src/AppInstallerCommonCore/Manifest/ManifestYamlPopulator.cpp @@ -11,6 +11,45 @@ namespace AppInstaller::Manifest namespace { + template + Ptr* any_ptr(std::any& any) { return std::any_cast(any); } + + ManifestInstaller* GetManifestInstallerPtrFromManifest(std::any& any) + { + Manifest* manifest = std::any_cast(any); + return &(manifest->DefaultInstallerInfo); + } + + ManifestLocalization* GetManifestLocalizationPtrFromManifest(std::any& any) + { + Manifest* manifest = std::any_cast(any); + return &(manifest->DefaultLocalization); + } + + ManifestInstaller* GetManifestInstallerPtr(std::any& any) + { + try + { + return std::any_cast(any); + } + catch (const std::bad_any_cast&) + { + return GetManifestInstallerPtrFromManifest(any); + } + } + + ManifestLocalization* GetManifestLocalizationPtr(std::any& any) + { + try + { + return std::any_cast(any); + } + catch (const std::bad_any_cast&) + { + return GetManifestLocalizationPtrFromManifest(any); + } + } + // Only used in preview manifest std::vector SplitMultiValueField(const std::string& input) { @@ -130,6 +169,15 @@ namespace AppInstaller::Manifest return result; } + + void ProcessDependenciesNode(DependencyType type, const YAML::Node& node, DependencyList* dependencyList) + { + const auto& ids = ProcessStringSequenceNode(node); + for (auto id : ids) + { + dependencyList->Add(Dependency(type, id)); + } + } } std::vector ManifestYamlPopulator::GetRootFieldProcessInfo(const ManifestVer& manifestVersion) @@ -140,14 +188,7 @@ namespace AppInstaller::Manifest { "ManifestVersion", [](const YAML::Node&, std::any&)->ValidationErrors { /* ManifestVersion already populated. Field listed here for duplicate and PascalCase check */ return {}; } }, { "Installers", [this](const YAML::Node& value, std::any&)->ValidationErrors { m_p_installersNode = &value; return {}; } }, { "Localization", [this](const YAML::Node& value, std::any&)->ValidationErrors { m_p_localizationsNode = &value; return {}; } }, - { - "Channel", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - Manifest* manifest = std::any_cast(any); - manifest->Channel = Utility::Trim(value.as()); - return {}; - } + { "Channel", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->Channel = Utility::Trim(value.as()); return {}; } }, }; @@ -156,33 +197,9 @@ namespace AppInstaller::Manifest { std::vector previewRootFields { - { - "Id", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - Manifest* manifest = std::any_cast(any); - manifest->Id = Utility::Trim(value.as()); - return {}; - } - }, - { - "Version", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - Manifest* manifest = std::any_cast(any); - manifest->Version = Utility::Trim(value.as()); - return {}; - } - }, - { - "AppMoniker", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - Manifest* manifest = std::any_cast(any); - manifest->Moniker = Utility::Trim(value.as()); - return {}; - } - }, + { "Id", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->Id = Utility::Trim(value.as()); return {}; } }, + { "Version", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->Version = Utility::Trim(value.as()); return {}; } }, + { "AppMoniker", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->Moniker = Utility::Trim(value.as()); return {}; } }, }; std::move(previewRootFields.begin(), previewRootFields.end(), std::inserter(result, result.end())); @@ -194,33 +211,9 @@ namespace AppInstaller::Manifest { std::vector v1RootFields { - { - "PackageIdentifier", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - Manifest* manifest = std::any_cast(any); - manifest->Id = Utility::Trim(value.as()); - return {}; - } - }, - { - "PackageVersion", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - Manifest* manifest = std::any_cast(any); - manifest->Version = Utility::Trim(value.as()); - return {}; - } - }, - { - "Moniker", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - Manifest* manifest = std::any_cast(any); - manifest->Moniker = Utility::Trim(value.as()); - return {}; - } - }, + { "PackageIdentifier", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->Id = Utility::Trim(value.as()); return {}; } }, + { "PackageVersion", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->Version = Utility::Trim(value.as()); return {}; } }, + { "Moniker", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->Moniker = Utility::Trim(value.as()); return {}; } }, { "ManifestType", [](const YAML::Node&, std::any&)->ValidationErrors { /* ManifestType already checked. Field listed here for duplicate and PascalCase check */ return {}; } }, }; @@ -243,63 +236,9 @@ namespace AppInstaller::Manifest // Common fields across versions std::vector result = { - { - "InstallerType", - [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestInstaller* installer; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - installer = &(manifest->DefaultInstallerInfo); - } - else - { - installer = std::any_cast(any); - } - - installer->BaseInstallerType = ConvertToInstallerTypeEnum(value.as()); - return {}; - } - }, - { - "PackageFamilyName", - [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestInstaller* installer; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - installer = &(manifest->DefaultInstallerInfo); - } - else - { - installer = std::any_cast(any); - } - - installer->PackageFamilyName = value.as(); - return {}; - } - }, - { - "ProductCode", - [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestInstaller* installer; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - installer = &(manifest->DefaultInstallerInfo); - } - else - { - installer = std::any_cast(any); - } - - installer->ProductCode = value.as(); - return {}; - } - }, + { "InstallerType", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtr(any)->BaseInstallerType = ConvertToInstallerTypeEnum(value.as()); return {}; } }, + { "PackageFamilyName", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtr(any)->PackageFamilyName = value.as(); return {}; } }, + { "ProductCode", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtr(any)->ProductCode = value.as(); return {}; } }, }; // Additional version specific fields @@ -308,44 +247,8 @@ namespace AppInstaller::Manifest // Root level and Localization node level std::vector previewCommonFields = { - { - "UpdateBehavior", - [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestInstaller* installer; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - installer = &(manifest->DefaultInstallerInfo); - } - else - { - installer = std::any_cast(any); - } - - installer->UpdateBehavior = ConvertToUpdateBehaviorEnum(value.as()); - return {}; - } - }, - { - "Switches", - [this, forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestInstaller* installer; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - installer = &(manifest->DefaultInstallerInfo); - } - else - { - installer = std::any_cast(any); - } - - std::any anySwitches = &(installer->Switches); - return ValidateAndProcessFields(value, SwitchesFieldInfos, anySwitches); - } - }, + { "UpdateBehavior", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtr(any)->UpdateBehavior = ConvertToUpdateBehaviorEnum(value.as()); return {}; } }, + { "Switches", [this](const YAML::Node& value, std::any& any)->ValidationErrors { std::any anySwitches = &(GetManifestInstallerPtr(any)->Switches); return ValidateAndProcessFields(value, SwitchesFieldInfos, anySwitches); } }, }; std::move(previewCommonFields.begin(), previewCommonFields.end(), std::inserter(result, result.end())); @@ -355,72 +258,17 @@ namespace AppInstaller::Manifest // Installer node only std::vector installerOnlyFields = { - { - "Arch", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestInstaller* installer = std::any_cast(any); - installer->Arch = Utility::ConvertToArchitectureEnum(value.as()); - return {}; - } - }, - { - "Url", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestInstaller* installer = std::any_cast(any); - installer->Url = value.as(); - return {}; - } - }, - { - "Sha256", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestInstaller* installer = std::any_cast(any); - installer->Sha256 = Utility::SHA256::ConvertToBytes(value.as()); - return {}; - } - }, - { - "SignatureSha256", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestInstaller* installer = std::any_cast(any); - installer->SignatureSha256 = Utility::SHA256::ConvertToBytes(value.as()); - return {}; - } - }, - { - "Language", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestInstaller* installer = std::any_cast(any); - installer->Locale = value.as(); - return {}; - } - }, - { - "Scope", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestInstaller* installer = std::any_cast(any); - installer->Scope = ConvertToScopeEnum(value.as()); - return {}; - } - }, + { "Arch", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->Arch = Utility::ConvertToArchitectureEnum(value.as()); return {}; } }, + { "Url", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->Url = value.as(); return {}; } }, + { "Sha256", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->Sha256 = Utility::SHA256::ConvertToBytes(value.as()); return {}; } }, + { "SignatureSha256", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->SignatureSha256 = Utility::SHA256::ConvertToBytes(value.as()); return {}; } }, + { "Language", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->Locale = value.as(); return {}; } }, + { "Scope", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->Scope = ConvertToScopeEnum(value.as()); return {}; } }, }; if (manifestVersion.HasExtension(s_MSStoreExtension)) { - installerOnlyFields.emplace_back( - "ProductId", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestInstaller* installer = std::any_cast(any); - installer->ProductId = value.as(); - return {}; - }); + installerOnlyFields.emplace_back("ProductId", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->ProductId = value.as(); return {}; }); } std::move(installerOnlyFields.begin(), installerOnlyFields.end(), std::inserter(result, result.end())); @@ -430,46 +278,10 @@ namespace AppInstaller::Manifest // Root node only std::vector rootOnlyFields = { - { - "MinOSVersion", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - Manifest* manifest = std::any_cast(any); - ManifestInstaller* installer = &(manifest->DefaultInstallerInfo); - installer->MinOSVersion = value.as(); - return {}; - } - }, - { - "Commands", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - Manifest* manifest = std::any_cast(any); - ManifestInstaller* installer = &(manifest->DefaultInstallerInfo); - installer->Commands = SplitMultiValueField(value.as()); - return {}; - } - }, - { - "Protocols", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - Manifest* manifest = std::any_cast(any); - ManifestInstaller* installer = &(manifest->DefaultInstallerInfo); - installer->Protocols = SplitMultiValueField(value.as()); - return {}; - } - }, - { - "FileExtensions", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - Manifest* manifest = std::any_cast(any); - ManifestInstaller* installer = &(manifest->DefaultInstallerInfo); - installer->FileExtensions = SplitMultiValueField(value.as()); - return {}; - } - }, + { "MinOSVersion", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtrFromManifest(any)->MinOSVersion = value.as(); return {}; } }, + { "Commands", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtrFromManifest(any)->Commands = SplitMultiValueField(value.as()); return {}; } }, + { "Protocols", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtrFromManifest(any)->Protocols = SplitMultiValueField(value.as()); return {}; } }, + { "FileExtensions", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtrFromManifest(any)->FileExtensions = SplitMultiValueField(value.as()); return {}; } }, }; std::move(rootOnlyFields.begin(), rootOnlyFields.end(), std::inserter(result, result.end())); @@ -483,272 +295,20 @@ namespace AppInstaller::Manifest // Root level and Installer node level std::vector v1CommonFields = { - { - "InstallerLocale", - [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestInstaller* installer; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - installer = &(manifest->DefaultInstallerInfo); - } - else - { - installer = std::any_cast(any); - } - - installer->Locale = value.as(); - return {}; - } - }, - { - "Platform", - [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestInstaller* installer; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - installer = &(manifest->DefaultInstallerInfo); - } - else - { - installer = std::any_cast(any); - } - - installer->Platform = ProcessPlatformSequenceNode(value); - return {}; - } - }, - { - "MinimumOSVersion", - [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestInstaller* installer; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - installer = &(manifest->DefaultInstallerInfo); - } - else - { - installer = std::any_cast(any); - } - - installer->MinOSVersion = value.as(); - return {}; - } - }, - { - "Scope", - [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestInstaller* installer; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - installer = &(manifest->DefaultInstallerInfo); - } - else - { - installer = std::any_cast(any); - } - - installer->Scope = ConvertToScopeEnum(value.as()); - return {}; - } - }, - { - "InstallModes", - [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestInstaller* installer; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - installer = &(manifest->DefaultInstallerInfo); - } - else - { - installer = std::any_cast(any); - } - - installer->InstallModes = ProcessInstallModeSequenceNode(value); - return {}; - } - }, - { - "InstallerSwitches", - [this, forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestInstaller* installer; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - installer = &(manifest->DefaultInstallerInfo); - } - else - { - installer = std::any_cast(any); - } - - std::any anySwitches = &(installer->Switches); - return ValidateAndProcessFields(value, SwitchesFieldInfos, anySwitches); - } - }, - { - "InstallerSuccessCodes", - [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestInstaller* installer; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - installer = &(manifest->DefaultInstallerInfo); - } - else - { - installer = std::any_cast(any); - } - - installer->InstallerSuccessCodes = ProcessInstallerSuccessCodeSequenceNode(value); - return {}; - } - }, - { - "UpgradeBehavior", - [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestInstaller* installer; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - installer = &(manifest->DefaultInstallerInfo); - } - else - { - installer = std::any_cast(any); - } - - installer->UpdateBehavior = ConvertToUpdateBehaviorEnum(value.as()); - return {}; - } - }, - { - "Commands", - [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestInstaller* installer; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - installer = &(manifest->DefaultInstallerInfo); - } - else - { - installer = std::any_cast(any); - } - - installer->Commands = ProcessStringSequenceNode(value); - return {}; - } - }, - { - "Protocols", - [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestInstaller* installer; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - installer = &(manifest->DefaultInstallerInfo); - } - else - { - installer = std::any_cast(any); - } - - installer->Protocols = ProcessStringSequenceNode(value); - return {}; - } - }, - { - "FileExtensions", - [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestInstaller* installer; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - installer = &(manifest->DefaultInstallerInfo); - } - else - { - installer = std::any_cast(any); - } - - installer->FileExtensions = ProcessStringSequenceNode(value); - return {}; - } - }, - { - "Dependencies", - [this, forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestInstaller* installer; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - installer = &(manifest->DefaultInstallerInfo); - } - else - { - installer = std::any_cast(any); - } - - std::any anyDependencyList = &(installer->Dependencies); - return ValidateAndProcessFields(value, DependenciesFieldInfos, anyDependencyList); - } - }, - { - "Capabilities", - [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestInstaller* installer; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - installer = &(manifest->DefaultInstallerInfo); - } - else - { - installer = std::any_cast(any); - } - - installer->Capabilities = ProcessStringSequenceNode(value); - return {}; - } - }, - { - "RestrictedCapabilities", - [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestInstaller* installer; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - installer = &(manifest->DefaultInstallerInfo); - } - else - { - installer = std::any_cast(any); - } - - installer->RestrictedCapabilities = ProcessStringSequenceNode(value); - return {}; - } - }, + { "InstallerLocale", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtr(any)->Locale = value.as(); return {}; } }, + { "Platform", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtr(any)->Platform = ProcessPlatformSequenceNode(value); return {}; } }, + { "MinimumOSVersion", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtr(any)->MinOSVersion = value.as(); return {}; } }, + { "Scope", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtr(any)->Scope = ConvertToScopeEnum(value.as()); return {}; } }, + { "InstallModes", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtr(any)->InstallModes = ProcessInstallModeSequenceNode(value); return {}; } }, + { "InstallerSwitches", [this](const YAML::Node& value, std::any& any)->ValidationErrors { std::any anySwitches = &(GetManifestInstallerPtr(any)->Switches); return ValidateAndProcessFields(value, SwitchesFieldInfos, anySwitches); } }, + { "InstallerSuccessCodes", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtr(any)->InstallerSuccessCodes = ProcessInstallerSuccessCodeSequenceNode(value); return {}; } }, + { "UpgradeBehavior", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtr(any)->UpdateBehavior = ConvertToUpdateBehaviorEnum(value.as()); return {}; } }, + { "Commands", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtr(any)->Commands = ProcessStringSequenceNode(value); return {}; } }, + { "Protocols", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtr(any)->Protocols = ProcessStringSequenceNode(value); return {}; } }, + { "FileExtensions", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtr(any)->FileExtensions = ProcessStringSequenceNode(value); return {}; } }, + { "Dependencies", [this](const YAML::Node& value, std::any& any)->ValidationErrors { std::any anyDependencyList = &(GetManifestInstallerPtr(any)->Dependencies); return ValidateAndProcessFields(value, DependenciesFieldInfos, anyDependencyList); } }, + { "Capabilities", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtr(any)->Capabilities = ProcessStringSequenceNode(value); return {}; } }, + { "RestrictedCapabilities", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtr(any)->RestrictedCapabilities = ProcessStringSequenceNode(value); return {}; } }, }; std::move(v1CommonFields.begin(), v1CommonFields.end(), std::inserter(result, result.end())); @@ -758,42 +318,10 @@ namespace AppInstaller::Manifest // Installer level only fields std::vector v1InstallerFields = { - { - "Architecture", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestInstaller* installer = std::any_cast(any); - installer->Arch = Utility::ConvertToArchitectureEnum(value.as()); - return {}; - } - }, - { - "InstallerUrl", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestInstaller* installer = std::any_cast(any); - installer->Url = value.as(); - return {}; - } - }, - { - "InstallerSha256", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestInstaller* installer = std::any_cast(any); - installer->Sha256 = Utility::SHA256::ConvertToBytes(value.as()); - return {}; - } - }, - { - "SignatureSha256", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestInstaller* installer = std::any_cast(any); - installer->SignatureSha256 = Utility::SHA256::ConvertToBytes(value.as()); - return {}; - } - }, + { "Architecture", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->Arch = Utility::ConvertToArchitectureEnum(value.as()); return {}; } }, + { "InstallerUrl", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->Url = value.as(); return {}; } }, + { "InstallerSha256", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->Sha256 = Utility::SHA256::ConvertToBytes(value.as()); return {}; } }, + { "SignatureSha256", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->SignatureSha256 = Utility::SHA256::ConvertToBytes(value.as()); return {}; } }, }; std::move(v1InstallerFields.begin(), v1InstallerFields.end(), std::inserter(result, result.end())); @@ -804,174 +332,15 @@ namespace AppInstaller::Manifest { std::vector fields_v1_1 = { - { - "InstallerAbortsTerminal", - [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestInstaller* installer; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - installer = &(manifest->DefaultInstallerInfo); - } - else - { - installer = std::any_cast(any); - } - - installer->InstallerAbortsTerminal = value.as(); - return {}; - } - }, - { - "InstallLocationRequired", - [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestInstaller* installer; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - installer = &(manifest->DefaultInstallerInfo); - } - else - { - installer = std::any_cast(any); - } - - installer->InstallLocationRequired = value.as(); - return {}; - } - }, - { - "RequireExplicitUpgrade", - [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestInstaller* installer; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - installer = &(manifest->DefaultInstallerInfo); - } - else - { - installer = std::any_cast(any); - } - - installer->RequireExplicitUpgrade = value.as(); - return {}; - } - }, - { - "ReleaseDate", - [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestInstaller* installer; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - installer = &(manifest->DefaultInstallerInfo); - } - else - { - installer = std::any_cast(any); - } - - installer->ReleaseDate = Utility::Trim(value.as()); - return {}; - } - }, - { - "UnsupportedOSArchitectures", - [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestInstaller* installer; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - installer = &(manifest->DefaultInstallerInfo); - } - else - { - installer = std::any_cast(any); - } - - installer->UnsupportedOSArchitectures = ProcessArchitectureSequenceNode(value); - return {}; - } - }, - { - "ElevationRequirement", - [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestInstaller* installer; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - installer = &(manifest->DefaultInstallerInfo); - } - else - { - installer = std::any_cast(any); - } - - installer->ElevationRequirement = ConvertToElevationRequirementEnum(value.as()); - return {}; - } - }, - { - "Markets", - [this, forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestInstaller* installer; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - installer = &(manifest->DefaultInstallerInfo); - } - else - { - installer = std::any_cast(any); - } - - return ProcessMarketsNode(value, installer); - } - }, - { - "AppsAndFeaturesEntries", - [this, forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestInstaller* installer; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - installer = &(manifest->DefaultInstallerInfo); - } - else - { - installer = std::any_cast(any); - } - - return ProcessAppsAndFeaturesEntriesNode(value, installer); - } - }, - { - "ExpectedReturnCodes", - [this, forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestInstaller* installer; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - installer = &(manifest->DefaultInstallerInfo); - } - else - { - installer = std::any_cast(any); - } - - return ProcessExpectedReturnCodesNode(value, installer); - } - }, + { "InstallerAbortsTerminal", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtr(any)->InstallerAbortsTerminal = value.as(); return {}; } }, + { "InstallLocationRequired", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtr(any)->InstallLocationRequired = value.as(); return {}; } }, + { "RequireExplicitUpgrade", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtr(any)->RequireExplicitUpgrade = value.as(); return {}; } }, + { "ReleaseDate", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtr(any)->ReleaseDate = Utility::Trim(value.as()); return {}; } }, + { "UnsupportedOSArchitectures", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtr(any)->UnsupportedOSArchitectures = ProcessArchitectureSequenceNode(value); return {}; } }, + { "ElevationRequirement", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtr(any)->ElevationRequirement = ConvertToElevationRequirementEnum(value.as()); return {}; } }, + { "Markets", [this](const YAML::Node& value, std::any& any)->ValidationErrors { return ProcessMarketsNode(value, GetManifestInstallerPtr(any)); } }, + { "AppsAndFeaturesEntries", [this](const YAML::Node& value, std::any& any)->ValidationErrors { return ProcessAppsAndFeaturesEntriesNode(value, GetManifestInstallerPtr(any)); } }, + { "ExpectedReturnCodes", [this](const YAML::Node& value, std::any& any)->ValidationErrors { return ProcessExpectedReturnCodesNode(value, GetManifestInstallerPtr(any)); } }, }; std::move(fields_v1_1.begin(), fields_v1_1.end(), std::inserter(result, result.end())); @@ -981,44 +350,8 @@ namespace AppInstaller::Manifest { std::vector fields_v1_2 = { - { - "UnsupportedArguments", - [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestInstaller* installer; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - installer = &(manifest->DefaultInstallerInfo); - } - else - { - installer = std::any_cast(any); - } - - installer->UnsupportedArguments = ProcessUnsupportedArgumentsSequenceNode(value); - return {}; - } - }, - { - "DisplayInstallWarnings", - [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestInstaller* installer; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - installer = &(manifest->DefaultInstallerInfo); - } - else - { - installer = std::any_cast(any); - } - - installer->DisplayInstallWarnings = value.as(); - return {}; - } - }, + { "UnsupportedArguments", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtr(any)->UnsupportedArguments = ProcessUnsupportedArgumentsSequenceNode(value); return {}; } }, + { "DisplayInstallWarnings", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtr(any)->DisplayInstallWarnings = value.as(); return {}; } }, }; std::move(fields_v1_2.begin(), fields_v1_2.end(), std::inserter(result, result.end())); @@ -1028,62 +361,9 @@ namespace AppInstaller::Manifest { std::vector fields_v1_4 = { - { - "NestedInstallerType", - [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestInstaller* installer; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - installer = &(manifest->DefaultInstallerInfo); - } - else - { - installer = std::any_cast(any); - } - - installer->NestedInstallerType = ConvertToInstallerTypeEnum(value.as()); - return {}; - } - }, - { - "NestedInstallerFiles", - [this, forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestInstaller* installer; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - installer = &(manifest->DefaultInstallerInfo); - } - else - { - installer = std::any_cast(any); - } - - return ProcessNestedInstallerFilesNode(value, installer); - } - }, - { - "InstallationMetadata", - [this, forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestInstaller* installer; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - installer = &(manifest->DefaultInstallerInfo); - } - else - { - installer = std::any_cast(any); - } - - std::any anyInstallationMetadata = &(installer->InstallationMetadata); - return ValidateAndProcessFields(value, InstallationMetadataFieldInfos, anyInstallationMetadata); - } - }, + { "NestedInstallerType", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtr(any)->NestedInstallerType = ConvertToInstallerTypeEnum(value.as()); return {}; } }, + { "NestedInstallerFiles", [this](const YAML::Node& value, std::any& any)->ValidationErrors { return ProcessNestedInstallerFilesNode(value, GetManifestInstallerPtr(any)); } }, + { "InstallationMetadata", [this](const YAML::Node& value, std::any& any)->ValidationErrors { std::any installerMetadata = &(GetManifestInstallerPtr(any)->InstallationMetadata); return ValidateAndProcessFields(value, InstallationMetadataFieldInfos, installerMetadata); } }, }; std::move(fields_v1_4.begin(), fields_v1_4.end(), std::inserter(result, result.end())); @@ -1093,25 +373,7 @@ namespace AppInstaller::Manifest { std::vector fields_v1_6 = { - { - "DownloadCommandProhibited", - [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestInstaller* installer; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - installer = &(manifest->DefaultInstallerInfo); - } - else - { - installer = std::any_cast(any); - } - - installer->DownloadCommandProhibited = value.as(); - return {}; - }, - true }, + { "DownloadCommandProhibited", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtr(any)->DownloadCommandProhibited = value.as(); return {}; }, true }, }; std::move(fields_v1_6.begin(), fields_v1_6.end(), std::inserter(result, result.end())); @@ -1121,25 +383,7 @@ namespace AppInstaller::Manifest { std::vector fields_v1_7 = { - { - "RepairBehavior", - [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestInstaller* installer; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - installer = &(manifest->DefaultInstallerInfo); - } - else - { - installer = std::any_cast(any); - } - - installer->RepairBehavior = ConvertToRepairBehaviorEnum(value.as()); - return {}; - } - }, + { "RepairBehavior", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtr(any)->RepairBehavior = ConvertToRepairBehaviorEnum(value.as()); return {}; } }, }; std::move(fields_v1_7.begin(), fields_v1_7.end(), std::inserter(result, result.end())); @@ -1154,104 +398,28 @@ namespace AppInstaller::Manifest // Common fields across versions std::vector result = { - { - "Custom", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - auto switches = std::any_cast*>(any); - (*switches)[InstallerSwitchType::Custom] = value.as(); - return{}; - } - }, - { - "Silent", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - auto switches = std::any_cast*>(any); - (*switches)[InstallerSwitchType::Silent] = value.as(); - return{}; - } - }, - { - "SilentWithProgress", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - auto switches = std::any_cast*>(any); - (*switches)[InstallerSwitchType::SilentWithProgress] = value.as(); - return{}; - } - }, - { - "Interactive", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - auto switches = std::any_cast*>(any); - (*switches)[InstallerSwitchType::Interactive] = value.as(); - return{}; - } - }, - { - "Log", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - auto switches = std::any_cast*>(any); - (*switches)[InstallerSwitchType::Log] = value.as(); - return{}; - } - }, - { - "InstallLocation", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - auto switches = std::any_cast*>(any); - (*switches)[InstallerSwitchType::InstallLocation] = value.as(); - return{}; - } - }, + { "Custom", [](const YAML::Node& value, std::any& any)->ValidationErrors { (*any_ptr>(any))[InstallerSwitchType::Custom] = value.as(); return{}; } }, + { "Silent", [](const YAML::Node& value, std::any& any)->ValidationErrors { (*any_ptr>(any))[InstallerSwitchType::Silent] = value.as(); return{}; } }, + { "SilentWithProgress", [](const YAML::Node& value, std::any& any)->ValidationErrors { (*any_ptr>(any))[InstallerSwitchType::SilentWithProgress] = value.as(); return{}; } }, + { "Interactive", [](const YAML::Node& value, std::any& any)->ValidationErrors { (*any_ptr>(any))[InstallerSwitchType::Interactive] = value.as(); return{}; } }, + { "Log", [](const YAML::Node& value, std::any& any)->ValidationErrors { (*any_ptr>(any))[InstallerSwitchType::Log] = value.as(); return{}; } }, + { "InstallLocation", [](const YAML::Node& value, std::any& any)->ValidationErrors { (*any_ptr>(any))[InstallerSwitchType::InstallLocation] = value.as(); return{}; } }, }; // Additional version specific fields if (manifestVersion.Major() == 0) { // Language only exists in preview manifests. Though we don't use it in our code yet, keep it here to be consistent with schema. - result.emplace_back( - "Language", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - auto switches = std::any_cast*>(any); - (*switches)[InstallerSwitchType::Language] = value.as(); - return{}; - }); - result.emplace_back( - "Update", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - auto switches = std::any_cast*>(any); - (*switches)[InstallerSwitchType::Update] = value.as(); - return{}; - }); + result.emplace_back("Language", [](const YAML::Node& value, std::any& any)->ValidationErrors { (*any_ptr>(any))[InstallerSwitchType::Language] = value.as(); return{}; }); + result.emplace_back("Update", [](const YAML::Node& value, std::any& any)->ValidationErrors { (*any_ptr>(any))[InstallerSwitchType::Update] = value.as(); return{}; }); } else if (manifestVersion.Major() == 1) { - result.emplace_back( - "Upgrade", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - auto switches = std::any_cast*>(any); - (*switches)[InstallerSwitchType::Update] = value.as(); - return{}; - }); + result.emplace_back("Upgrade", [](const YAML::Node& value, std::any& any)->ValidationErrors { (*any_ptr>(any))[InstallerSwitchType::Update] = value.as(); return{}; }); if (manifestVersion >= ManifestVer{ s_ManifestVersionV1_7 }) { - result.emplace_back( - "Repair", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - auto switches = std::any_cast*>(any); - (*switches)[InstallerSwitchType::Repair] = value.as(); - return{}; - }); + result.emplace_back("Repair", [](const YAML::Node& value, std::any& any)->ValidationErrors { (*any_ptr>(any))[InstallerSwitchType::Repair] = value.as(); return{}; }); }; } @@ -1264,34 +432,13 @@ namespace AppInstaller::Manifest if (manifestVersion >= ManifestVer{ s_ManifestVersionV1_1 }) { - result.emplace_back( - "InstallerReturnCode", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - ExpectedReturnCode* expectedReturnCode = std::any_cast(any); - expectedReturnCode->InstallerReturnCode = static_cast(value.as()); - return {}; - }); - result.emplace_back( - "ReturnResponse", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - ExpectedReturnCode* expectedReturnCode = std::any_cast(any); - expectedReturnCode->ReturnResponse = ConvertToExpectedReturnCodeEnum(value.as()); - return {}; - }); + result.emplace_back("InstallerReturnCode", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->InstallerReturnCode = static_cast(value.as()); return {}; }); + result.emplace_back("ReturnResponse", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->ReturnResponse = ConvertToExpectedReturnCodeEnum(value.as()); return {}; }); } if (manifestVersion >= ManifestVer{ s_ManifestVersionV1_2 }) { - result.emplace_back( - "ReturnResponseUrl", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - ExpectedReturnCode* expectedReturnCode = std::any_cast(any); - expectedReturnCode->ReturnResponseUrl = value.as(); - return {}; - }); + result.emplace_back("ReturnResponseUrl", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->ReturnResponseUrl = value.as(); return {}; }); } return result; @@ -1302,136 +449,31 @@ namespace AppInstaller::Manifest // Common fields across versions std::vector result = { - { - "Description", - [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestLocalization* localization; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - localization = &(manifest->DefaultLocalization); - } - else - { - localization = std::any_cast(any); - } - - localization->Add(Utility::Trim(value.as())); - return {}; - } - }, - { - "LicenseUrl", - [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestLocalization* localization; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - localization = &(manifest->DefaultLocalization); - } - else - { - localization = std::any_cast(any); - } - - localization->Add(value.as()); - return {}; - } - }, + { "Description", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestLocalizationPtr(any)->Add(Utility::Trim(value.as())); return {}; } }, + { "LicenseUrl", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestLocalizationPtr(any)->Add(value.as()); return {}; } }, }; // Additional version specific fields if (manifestVersion.Major() == 0) { // Root level and Localization node level - result.emplace_back( - "Homepage", - [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestLocalization* localization; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - localization = &(manifest->DefaultLocalization); - } - else - { - localization = std::any_cast(any); - } - - localization->Add(value.as()); - return {}; - }); + result.emplace_back("Homepage", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestLocalizationPtr(any)->Add(value.as()); return {}; }); if (!forRootFields) { // Localization node only - result.emplace_back( - "Language", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestLocalization* localization = std::any_cast(any); - localization->Locale = value.as(); - return {}; - }); + result.emplace_back("Language", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->Locale = value.as(); return {}; }); } else { // Root node only std::vector rootOnlyFields = { - { - "Name", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - Manifest* manifest = std::any_cast(any); - ManifestLocalization* localization = &(manifest->DefaultLocalization); - localization->Add(Utility::Trim(value.as())); - return {}; - } - }, - { - "Publisher", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - Manifest* manifest = std::any_cast(any); - ManifestLocalization* localization = &(manifest->DefaultLocalization); - localization->Add(value.as()); - return {}; - } - }, - { - "Author", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - Manifest* manifest = std::any_cast(any); - ManifestLocalization* localization = &(manifest->DefaultLocalization); - localization->Add(value.as()); - return {}; - } - }, - { - "License", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - Manifest* manifest = std::any_cast(any); - ManifestLocalization* localization = &(manifest->DefaultLocalization); - localization->Add(value.as()); - return {}; - } - }, - { - "Tags", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - Manifest* manifest = std::any_cast(any); - ManifestLocalization* localization = &(manifest->DefaultLocalization); - localization->Add(SplitMultiValueField(value.as())); - return {}; - } - }, + { "Name", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestLocalizationPtrFromManifest(any)->Add(Utility::Trim(value.as())); return {}; } }, + { "Publisher", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestLocalizationPtrFromManifest(any)->Add(value.as()); return {}; } }, + { "Author", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestLocalizationPtrFromManifest(any)->Add(value.as()); return {}; } }, + { "License", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestLocalizationPtrFromManifest(any)->Add(value.as()); return {}; } }, + { "Tags", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestLocalizationPtrFromManifest(any)->Add(SplitMultiValueField(value.as())); return {}; } }, }; std::move(rootOnlyFields.begin(), rootOnlyFields.end(), std::inserter(result, result.end())); @@ -1445,253 +487,19 @@ namespace AppInstaller::Manifest // Root level and Localization node level std::vector v1CommonFields = { - { - "PackageLocale", - [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestLocalization* localization; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - localization = &(manifest->DefaultLocalization); - } - else - { - localization = std::any_cast(any); - } - - localization->Locale = value.as(); - return {}; - } - }, - { - "Publisher", - [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestLocalization* localization; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - localization = &(manifest->DefaultLocalization); - } - else - { - localization = std::any_cast(any); - } - - localization->Add(value.as()); - return {}; - } - }, - { - "PublisherUrl", - [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestLocalization* localization; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - localization = &(manifest->DefaultLocalization); - } - else - { - localization = std::any_cast(any); - } - - localization->Add(value.as()); - return {}; - } - }, - { - "PublisherSupportUrl", - [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestLocalization* localization; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - localization = &(manifest->DefaultLocalization); - } - else - { - localization = std::any_cast(any); - } - - localization->Add(value.as()); - return {}; - } - }, - { - "PrivacyUrl", - [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestLocalization* localization; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - localization = &(manifest->DefaultLocalization); - } - else - { - localization = std::any_cast(any); - } - - localization->Add(value.as()); - return {}; - } - }, - { - "Author", - [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestLocalization* localization; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - localization = &(manifest->DefaultLocalization); - } - else - { - localization = std::any_cast(any); - } - - localization->Add(value.as()); - return {}; - } - }, - { - "PackageName", - [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestLocalization* localization; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - localization = &(manifest->DefaultLocalization); - } - else - { - localization = std::any_cast(any); - } - - localization->Add(Utility::Trim(value.as())); - return {}; - } - }, - { - "PackageUrl", - [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestLocalization* localization; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - localization = &(manifest->DefaultLocalization); - } - else - { - localization = std::any_cast(any); - } - - localization->Add(value.as()); - return {}; - } - }, - { - "License", - [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestLocalization* localization; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - localization = &(manifest->DefaultLocalization); - } - else - { - localization = std::any_cast(any); - } - - localization->Add(value.as()); - return {}; - } - }, - { - "Copyright", - [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestLocalization* localization; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - localization = &(manifest->DefaultLocalization); - } - else - { - localization = std::any_cast(any); - } - - localization->Add(value.as()); - return {}; - } - }, - { - "CopyrightUrl", - [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestLocalization* localization; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - localization = &(manifest->DefaultLocalization); - } - else - { - localization = std::any_cast(any); - } - - localization->Add(value.as()); - return {}; - } - }, - { - "ShortDescription", - [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestLocalization* localization; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - localization = &(manifest->DefaultLocalization); - } - else - { - localization = std::any_cast(any); - } - - localization->Add(Utility::Trim(value.as())); - return {}; - } - }, - { - "Tags", - [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestLocalization* localization; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - localization = &(manifest->DefaultLocalization); - } - else - { - localization = std::any_cast(any); - } - - localization->Add(ProcessStringSequenceNode(value)); - return {}; - } - }, + { "PackageLocale", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestLocalizationPtr(any)->Locale = value.as(); return {}; } }, + { "Publisher", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestLocalizationPtr(any)->Add(value.as()); return {}; } }, + { "PublisherUrl", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestLocalizationPtr(any)->Add(value.as()); return {}; } }, + { "PublisherSupportUrl", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestLocalizationPtr(any)->Add(value.as()); return {}; } }, + { "PrivacyUrl", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestLocalizationPtr(any)->Add(value.as()); return {}; } }, + { "Author", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestLocalizationPtr(any)->Add(value.as()); return {}; } }, + { "PackageName", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestLocalizationPtr(any)->Add(Utility::Trim(value.as())); return {}; } }, + { "PackageUrl", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestLocalizationPtr(any)->Add(value.as()); return {}; } }, + { "License", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestLocalizationPtr(any)->Add(value.as()); return {}; } }, + { "Copyright", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestLocalizationPtr(any)->Add(value.as()); return {}; } }, + { "CopyrightUrl", [](const YAML::Node& value, std::any& any)->ValidationErrors{ GetManifestLocalizationPtr(any)->Add(value.as()); return {}; } }, + { "ShortDescription", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestLocalizationPtr(any)->Add(Utility::Trim(value.as())); return {}; } }, + { "Tags", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestLocalizationPtr(any)->Add(ProcessStringSequenceNode(value)); return {}; } }, }; std::move(v1CommonFields.begin(), v1CommonFields.end(), std::inserter(result, result.end())); @@ -1701,62 +509,9 @@ namespace AppInstaller::Manifest { std::vector fields_v1_1 = { - { - "Agreements", - [this, forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestLocalization* localization; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - localization = &(manifest->DefaultLocalization); - } - else - { - localization = std::any_cast(any); - } - - return ProcessAgreementsNode(value, localization); - } - }, - { - "ReleaseNotes", - [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestLocalization* localization; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - localization = &(manifest->DefaultLocalization); - } - else - { - localization = std::any_cast(any); - } - - localization->Add(value.as()); - return {}; - } - }, - { - "ReleaseNotesUrl", - [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestLocalization* localization; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - localization = &(manifest->DefaultLocalization); - } - else - { - localization = std::any_cast(any); - } - - localization->Add(value.as()); - return {}; - } - }, + { "Agreements", [this](const YAML::Node& value, std::any& any)->ValidationErrors { return ProcessAgreementsNode(value, GetManifestLocalizationPtr(any)); } }, + { "ReleaseNotes", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestLocalizationPtr(any)->Add(value.as()); return {}; } }, + { "ReleaseNotesUrl", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestLocalizationPtr(any)->Add(value.as()); return {}; } }, }; std::move(fields_v1_1.begin(), fields_v1_1.end(), std::inserter(result, result.end())); @@ -1766,62 +521,9 @@ namespace AppInstaller::Manifest { std::vector fields_v1_2 = { - { - "PurchaseUrl", - [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestLocalization* localization; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - localization = &(manifest->DefaultLocalization); - } - else - { - localization = std::any_cast(any); - } - - localization->Add(value.as()); - return {}; - } - }, - { - "InstallationNotes", - [forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestLocalization* localization; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - localization = &(manifest->DefaultLocalization); - } - else - { - localization = std::any_cast(any); - } - - localization->Add(value.as()); - return {}; - } - }, - { - "Documentations", - [this, forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestLocalization* localization; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - localization = &(manifest->DefaultLocalization); - } - else - { - localization = std::any_cast(any); - } - - return ProcessDocumentationsNode(value, localization); - } - }, + { "PurchaseUrl", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestLocalizationPtr(any)->Add(value.as()); return {}; } }, + { "InstallationNotes", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestLocalizationPtr(any)->Add(value.as()); return {}; } }, + { "Documentations", [this](const YAML::Node& value, std::any& any)->ValidationErrors { return ProcessDocumentationsNode(value, GetManifestLocalizationPtr(any)); } }, }; std::move(fields_v1_2.begin(), fields_v1_2.end(), std::inserter(result, result.end())); @@ -1831,25 +533,7 @@ namespace AppInstaller::Manifest { std::vector fields_v1_5 = { - { - "Icons", - [this, forRootFields](const YAML::Node& value, std::any& any)->ValidationErrors - { - ManifestLocalization* localization; - if (forRootFields) - { - Manifest* manifest = std::any_cast(any); - localization = &(manifest->DefaultLocalization); - } - else - { - localization = std::any_cast(any); - } - - return ProcessIconsNode(value, localization); - }, - true - }, + { "Icons", [this](const YAML::Node& value, std::any& any)->ValidationErrors { return ProcessIconsNode(value, GetManifestLocalizationPtr(any)); }, true }, }; std::move(fields_v1_5.begin(), fields_v1_5.end(), std::inserter(result, result.end())); @@ -1867,57 +551,16 @@ namespace AppInstaller::Manifest { result = { - { - "WindowsFeatures", - [this](const YAML::Node& value, std::any& any)->ValidationErrors - { - DependencyList* dependencyList = std::any_cast(any); - ProcessDependenciesNode(DependencyType::WindowsFeature, value, dependencyList); - return {}; - } - }, - { - "WindowsLibraries", - [this](const YAML::Node& value, std::any& any)->ValidationErrors - { - DependencyList* dependencyList = std::any_cast(any); - ProcessDependenciesNode(DependencyType::WindowsLibrary, value, dependencyList); - return {}; - } - }, - { - "PackageDependencies", - [this](const YAML::Node& value, std::any& any)->ValidationErrors - { - DependencyList* dependencyList = std::any_cast(any); - ProcessPackageDependenciesNode(value, dependencyList); - return {}; - } - }, - { - "ExternalDependencies", - [this](const YAML::Node& value, std::any& any)->ValidationErrors - { - DependencyList* dependencyList = std::any_cast(any); - ProcessDependenciesNode(DependencyType::External, value, dependencyList); - return {}; - } - }, + { "WindowsFeatures", [](const YAML::Node& value, std::any& any)->ValidationErrors { ProcessDependenciesNode(DependencyType::WindowsFeature, value, any_ptr(any)); return {}; } }, + { "WindowsLibraries", [](const YAML::Node& value, std::any& any)->ValidationErrors { ProcessDependenciesNode(DependencyType::WindowsLibrary, value, any_ptr(any)); return {}; } }, + { "PackageDependencies", [this](const YAML::Node& value, std::any& any)->ValidationErrors { ProcessPackageDependenciesNode(value, any_ptr(any)); return {}; } }, + { "ExternalDependencies", [](const YAML::Node& value, std::any& any)->ValidationErrors { ProcessDependenciesNode(DependencyType::External, value, any_ptr(any)); return {}; } }, }; } return result; } - void ManifestYamlPopulator::ProcessDependenciesNode(DependencyType type, const YAML::Node& node, DependencyList* dependencyList) - { - const auto& ids = ProcessStringSequenceNode(node); - for (auto id : ids) - { - dependencyList->Add(Dependency(type, id)); - } - } - std::vector ManifestYamlPopulator::GetPackageDependenciesFieldProcessInfo(const ManifestVer& manifestVersion) { std::vector result = {}; @@ -1926,24 +569,8 @@ namespace AppInstaller::Manifest { result = { - { - "PackageIdentifier", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - Dependency* packageDependency = std::any_cast(any); - packageDependency->SetId(Utility::Trim(value.as())); - return {}; - } - }, - { - "MinimumVersion", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - Dependency* packageDependency = std::any_cast(any); - packageDependency->MinVersion = Utility::Version(Utility::Trim(value.as())); - return {}; - } - }, + { "PackageIdentifier", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->SetId(Utility::Trim(value.as())); return {}; } }, + { "MinimumVersion", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->MinVersion = Utility::Version(Utility::Trim(value.as())); return {}; } }, }; } @@ -1958,33 +585,9 @@ namespace AppInstaller::Manifest { result = { - { - "AgreementLabel", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - Agreement* agreement = std::any_cast(any); - agreement->Label = Utility::Trim(value.as()); - return {}; - } - }, - { - "Agreement", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - Agreement* agreement = std::any_cast(any); - agreement->AgreementText = Utility::Trim(value.as()); - return {}; - }, - true }, - { - "AgreementUrl", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - Agreement* agreement = std::any_cast(any); - agreement->AgreementUrl = Utility::Trim(value.as()); - return {}; - } - }, + { "AgreementLabel", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->Label = Utility::Trim(value.as()); return {}; } }, + { "Agreement", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->AgreementText = Utility::Trim(value.as()); return {}; }, true }, + { "AgreementUrl", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->AgreementUrl = Utility::Trim(value.as()); return {}; } }, }; } @@ -1999,24 +602,8 @@ namespace AppInstaller::Manifest { result = { - { - "AllowedMarkets", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - MarketsInfo* markets = std::any_cast(any); - markets->AllowedMarkets = ProcessStringSequenceNode(value); - return {}; - } - }, - { - "ExcludedMarkets", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - MarketsInfo* markets = std::any_cast(any); - markets->ExcludedMarkets = ProcessStringSequenceNode(value); - return {}; - } - }, + { "AllowedMarkets", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->AllowedMarkets = ProcessStringSequenceNode(value); return {}; } }, + { "ExcludedMarkets", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->ExcludedMarkets = ProcessStringSequenceNode(value); return {}; } }, }; } @@ -2031,60 +618,12 @@ namespace AppInstaller::Manifest { result = { - { - "DisplayName", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - AppsAndFeaturesEntry* appsAndFeaturesEntry = std::any_cast(any); - appsAndFeaturesEntry->DisplayName = Utility::Trim(value.as()); - return {}; - } - }, - { - "Publisher", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - AppsAndFeaturesEntry* appsAndFeaturesEntry = std::any_cast(any); - appsAndFeaturesEntry->Publisher = Utility::Trim(value.as()); - return {}; - } - }, - { - "DisplayVersion", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - AppsAndFeaturesEntry* appsAndFeaturesEntry = std::any_cast(any); - appsAndFeaturesEntry->DisplayVersion = Utility::Trim(value.as()); - return {}; - } - }, - { - "ProductCode", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - AppsAndFeaturesEntry* appsAndFeaturesEntry = std::any_cast(any); - appsAndFeaturesEntry->ProductCode = Utility::Trim(value.as()); - return {}; - } - }, - { - "UpgradeCode", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - AppsAndFeaturesEntry* appsAndFeaturesEntry = std::any_cast(any); - appsAndFeaturesEntry->UpgradeCode = Utility::Trim(value.as()); - return {}; - } - }, - { - "InstallerType", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - AppsAndFeaturesEntry* appsAndFeaturesEntry = std::any_cast(any); - appsAndFeaturesEntry->InstallerType = ConvertToInstallerTypeEnum(value.as()); - return {}; - } - }, + { "DisplayName", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->DisplayName = Utility::Trim(value.as()); return {}; } }, + { "Publisher", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->Publisher = Utility::Trim(value.as()); return {}; } }, + { "DisplayVersion", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->DisplayVersion = Utility::Trim(value.as()); return {}; } }, + { "ProductCode", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->ProductCode = Utility::Trim(value.as()); return {}; } }, + { "UpgradeCode", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->UpgradeCode = Utility::Trim(value.as()); return {}; } }, + { "InstallerType", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->InstallerType = ConvertToInstallerTypeEnum(value.as()); return {}; } }, }; } @@ -2099,24 +638,8 @@ namespace AppInstaller::Manifest { result = { - { - "DocumentLabel", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - Documentation* documentation = std::any_cast(any); - documentation->DocumentLabel = Utility::Trim(value.as()); - return {}; - } - }, - { - "DocumentUrl", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - Documentation* documentation = std::any_cast(any); - documentation->DocumentUrl = Utility::Trim(value.as()); - return {}; - } - }, + { "DocumentLabel", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->DocumentLabel = Utility::Trim(value.as()); return {}; } }, + { "DocumentUrl", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->DocumentUrl = Utility::Trim(value.as()); return {}; } }, }; } @@ -2131,50 +654,11 @@ namespace AppInstaller::Manifest { result = { - { - "IconUrl", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - Icon* icon = std::any_cast(any); - icon->Url = Utility::Trim(value.as()); return {}; - } - }, - { - "IconFileType", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - Icon* icon = std::any_cast(any); - icon->FileType = ConvertToIconFileTypeEnum(value.as()); - return {}; - } - }, - { - "IconResolution", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - Icon* icon = std::any_cast(any); - icon->Resolution = ConvertToIconResolutionEnum(value.as()); - return {}; - } - }, - { - "IconTheme", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - Icon* icon = std::any_cast(any); - icon->Theme = ConvertToIconThemeEnum(value.as()); - return {}; - } - }, - { - "IconSha256", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - Icon* icon = std::any_cast(any); - icon->Sha256 = Utility::SHA256::ConvertToBytes(value.as()); - return {}; - } - }, + { "IconUrl", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->Url = Utility::Trim(value.as()); return {}; } }, + { "IconFileType", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->FileType = ConvertToIconFileTypeEnum(value.as()); return {}; } }, + { "IconResolution", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->Resolution = ConvertToIconResolutionEnum(value.as()); return {}; } }, + { "IconTheme", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->Theme = ConvertToIconThemeEnum(value.as()); return {}; } }, + { "IconSha256", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->Sha256 = Utility::SHA256::ConvertToBytes(value.as()); return {}; } }, }; } @@ -2189,24 +673,8 @@ namespace AppInstaller::Manifest { result = { - { - "RelativeFilePath", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - NestedInstallerFile* nestedInstallerFile = std::any_cast(any); - nestedInstallerFile->RelativeFilePath = Utility::Trim(value.as()); - return {}; - } - }, - { - "PortableCommandAlias", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - NestedInstallerFile* nestedInstallerFile = std::any_cast(any); - nestedInstallerFile->PortableCommandAlias = Utility::Trim(value.as()); - return {}; - } - }, + { "RelativeFilePath", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->RelativeFilePath = Utility::Trim(value.as()); return {}; } }, + { "PortableCommandAlias", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->PortableCommandAlias = Utility::Trim(value.as()); return {}; } }, }; } @@ -2221,23 +689,8 @@ namespace AppInstaller::Manifest { result = { - { - "DefaultInstallLocation", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - InstallationMetadataInfo* installationMetadata = std::any_cast(any); - installationMetadata->DefaultInstallLocation = Utility::Trim(value.as()); - return {}; - } - }, - { - "Files", - [this](const YAML::Node& value, std::any& any)->ValidationErrors - { - InstallationMetadataInfo* installationMetadata = std::any_cast(any); - return ProcessInstallationMetadataFilesNode(value, installationMetadata); - } - }, + { "DefaultInstallLocation", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->DefaultInstallLocation = Utility::Trim(value.as()); return {}; } }, + { "Files", [this](const YAML::Node& value, std::any& any)->ValidationErrors { InstallationMetadataInfo* installationMetadata = std::any_cast(any); return ProcessInstallationMetadataFilesNode(value, installationMetadata); } }, }; } @@ -2252,51 +705,11 @@ namespace AppInstaller::Manifest { result = { - { - "RelativeFilePath", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - InstalledFile* installedFile = std::any_cast(any); - installedFile->RelativeFilePath = Utility::Trim(value.as()); - return {}; - } - }, - { - "FileSha256", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - InstalledFile* installedFile = std::any_cast(any); - installedFile->FileSha256 = Utility::SHA256::ConvertToBytes(value.as()); - return {}; - } - }, - { - "FileType", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - InstalledFile* installedFile = std::any_cast(any); - installedFile->FileType = ConvertToInstalledFileTypeEnum(value.as()); - return {}; - } - }, - { - "InvocationParameter", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - InstalledFile* installedFile = std::any_cast(any); - installedFile->InvocationParameter = Utility::Trim(value.as()); - return {}; - } - }, - { - "DisplayName", - [](const YAML::Node& value, std::any& any)->ValidationErrors - { - InstalledFile* installedFile = std::any_cast(any); - installedFile->DisplayName = Utility::Trim(value.as()); - return {}; - } - }, + { "RelativeFilePath", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->RelativeFilePath = Utility::Trim(value.as()); return {}; } }, + { "FileSha256", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->FileSha256 = Utility::SHA256::ConvertToBytes(value.as()); return {}; } }, + { "FileType", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->FileType = ConvertToInstalledFileTypeEnum(value.as()); return {}; } }, + { "InvocationParameter", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->InvocationParameter = Utility::Trim(value.as()); return {}; } }, + { "DisplayName", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->DisplayName = Utility::Trim(value.as()); return {}; } }, }; } @@ -2306,7 +719,7 @@ namespace AppInstaller::Manifest ValidationErrors ManifestYamlPopulator::ValidateAndProcessFields( const YAML::Node& rootNode, const std::vector& fieldInfos, - std::any& any) + std::any any) { ValidationErrors resultErrors; @@ -2387,8 +800,7 @@ namespace AppInstaller::Manifest for (auto const& entry : rootNode.Sequence()) { Dependency packageDependency = Dependency(DependencyType::Package); - std::any any = &packageDependency; - auto errors = ValidateAndProcessFields(entry, PackageDependenciesFieldInfos, any); + auto errors = ValidateAndProcessFields(entry, PackageDependenciesFieldInfos, std::any(&packageDependency)); std::move(errors.begin(), errors.end(), std::inserter(resultErrors, resultErrors.end())); dependencyList->Add(std::move(packageDependency)); } @@ -2406,8 +818,7 @@ namespace AppInstaller::Manifest for (auto const& entry : agreementsNode.Sequence()) { Agreement agreement; - std::any any = &agreement; - auto errors = ValidateAndProcessFields(entry, AgreementFieldInfos, any); + auto errors = ValidateAndProcessFields(entry, AgreementFieldInfos, std::any(&agreement)); std::move(errors.begin(), errors.end(), std::inserter(resultErrors, resultErrors.end())); agreements.emplace_back(std::move(agreement)); } @@ -2423,8 +834,7 @@ namespace AppInstaller::Manifest std::vector ManifestYamlPopulator::ProcessMarketsNode(const YAML::Node& marketsNode, ManifestInstaller* installer) { MarketsInfo markets; - std::any any = &markets; - auto errors = ValidateAndProcessFields(marketsNode, MarketsFieldInfos, any); + auto errors = ValidateAndProcessFields(marketsNode, MarketsFieldInfos, std::any(&markets)); installer->Markets = markets; return errors; } @@ -2439,8 +849,7 @@ namespace AppInstaller::Manifest for (auto const& entry : appsAndFeaturesEntriesNode.Sequence()) { AppsAndFeaturesEntry appsAndFeaturesEntry; - std::any any = &appsAndFeaturesEntry; - auto errors = ValidateAndProcessFields(entry, AppsAndFeaturesEntryFieldInfos, any); + auto errors = ValidateAndProcessFields(entry, AppsAndFeaturesEntryFieldInfos, std::any(&appsAndFeaturesEntry)); std::move(errors.begin(), errors.end(), std::inserter(resultErrors, resultErrors.end())); appsAndFeaturesEntries.emplace_back(std::move(appsAndFeaturesEntry)); } @@ -2460,8 +869,7 @@ namespace AppInstaller::Manifest for (auto const& entry : returnCodesNode.Sequence()) { ExpectedReturnCode returnCode; - std::any any = &returnCode; - auto errors = ValidateAndProcessFields(entry, ExpectedReturnCodesFieldInfos, any); + auto errors = ValidateAndProcessFields(entry, ExpectedReturnCodesFieldInfos, std::any(&returnCode)); std::move(errors.begin(), errors.end(), std::inserter(resultErrors, resultErrors.end())); if (!returnCodes.insert({ returnCode.InstallerReturnCode, {returnCode.ReturnResponse, returnCode.ReturnResponseUrl} }).second) { @@ -2484,8 +892,7 @@ namespace AppInstaller::Manifest for (auto const& entry : documentationsNode.Sequence()) { Documentation documentation; - std::any any = &documentation; - auto errors = ValidateAndProcessFields(entry, DocumentationFieldInfos, any); + auto errors = ValidateAndProcessFields(entry, DocumentationFieldInfos, std::any(&documentation)); std::move(errors.begin(), errors.end(), std::inserter(resultErrors, resultErrors.end())); documentations.emplace_back(std::move(documentation)); } @@ -2508,8 +915,7 @@ namespace AppInstaller::Manifest for (auto const& entry : iconsNode.Sequence()) { Icon icon; - std::any any = &icon; - auto errors = ValidateAndProcessFields(entry, IconFieldInfos, any); + auto errors = ValidateAndProcessFields(entry, IconFieldInfos, std::any(&icon)); std::move(errors.begin(), errors.end(), std::inserter(resultErrors, resultErrors.end())); icons.emplace_back(std::move(icon)); } @@ -2532,8 +938,7 @@ namespace AppInstaller::Manifest for (auto const& entry : nestedInstallerFilesNode.Sequence()) { NestedInstallerFile nestedInstallerFile; - std::any any = &nestedInstallerFile; - auto errors = ValidateAndProcessFields(entry, NestedInstallerFileFieldInfos, any); + auto errors = ValidateAndProcessFields(entry, NestedInstallerFileFieldInfos, std::any(&nestedInstallerFile)); std::move(errors.begin(), errors.end(), std::inserter(resultErrors, resultErrors.end())); nestedInstallerFiles.emplace_back(std::move(nestedInstallerFile)); } @@ -2556,8 +961,7 @@ namespace AppInstaller::Manifest for (auto const& entry : installedFilesNode.Sequence()) { InstalledFile installedFile; - std::any any = &installedFile; - auto errors = ValidateAndProcessFields(entry, InstallationMetadataFilesFieldInfos, any); + auto errors = ValidateAndProcessFields(entry, InstallationMetadataFilesFieldInfos, std::any(&installedFile)); std::move(errors.begin(), errors.end(), std::inserter(resultErrors, resultErrors.end())); installedFiles.emplace_back(std::move(installedFile)); } @@ -2599,8 +1003,7 @@ namespace AppInstaller::Manifest InstallationMetadataFieldInfos = GetInstallationMetadataFieldProcessInfo(manifestVersion); InstallationMetadataFilesFieldInfos = GetInstallationMetadataFilesFieldProcessInfo(manifestVersion); - std::any anyManifest = &manifest; - resultErrors = ValidateAndProcessFields(rootNode, RootFieldInfos, anyManifest); + resultErrors = ValidateAndProcessFields(rootNode, RootFieldInfos, std::any(&manifest)); if (!m_p_installersNode) { @@ -2622,8 +1025,7 @@ namespace AppInstaller::Manifest installer.NestedInstallerType = InstallerTypeEnum::Unknown; installer.NestedInstallerFiles.clear(); - std::any anyInstaller = &installer; - auto errors = ValidateAndProcessFields(entry, InstallerFieldInfos, anyInstaller); + auto errors = ValidateAndProcessFields(entry, InstallerFieldInfos, std::any(&installer)); std::move(errors.begin(), errors.end(), std::inserter(resultErrors, resultErrors.end())); // Copy in system reference strings from the root if not set in the installer and appropriate @@ -2691,8 +1093,7 @@ namespace AppInstaller::Manifest for (auto const& entry : m_p_localizationsNode->Sequence()) { ManifestLocalization localization; - std::any any = &localization; - auto errors = ValidateAndProcessFields(entry, LocalizationFieldInfos, any); + auto errors = ValidateAndProcessFields(entry, LocalizationFieldInfos, std::any(&localization)); std::move(errors.begin(), errors.end(), std::inserter(resultErrors, resultErrors.end())); manifest.Localizations.emplace_back(std::move(std::move(localization))); } diff --git a/src/AppInstallerCommonCore/Public/winget/ManifestYamlPopulator.h b/src/AppInstallerCommonCore/Public/winget/ManifestYamlPopulator.h index 67a30ec3ef..635377a5a6 100644 --- a/src/AppInstallerCommonCore/Public/winget/ManifestYamlPopulator.h +++ b/src/AppInstallerCommonCore/Public/winget/ManifestYamlPopulator.h @@ -75,9 +75,8 @@ namespace AppInstaller::Manifest std::vector ValidateAndProcessFields( const YAML::Node& rootNode, const std::vector& fieldInfos, - std::any& any); + std::any any); - void ProcessDependenciesNode(DependencyType type, const YAML::Node& rootNode, DependencyList* dependencyList); std::vector ProcessPackageDependenciesNode(const YAML::Node& rootNode, DependencyList* dependencyList); std::vector ProcessAgreementsNode(const YAML::Node& agreementsNode, ManifestLocalization* localization); std::vector ProcessMarketsNode(const YAML::Node& marketsNode, AppInstaller::Manifest::ManifestInstaller* installer); From f6466a494c83dabedfcf8354bae1fed8f17cfd0b Mon Sep 17 00:00:00 2001 From: Ruben Guerrero Samaniego Date: Tue, 23 Jan 2024 11:59:10 -0800 Subject: [PATCH 4/5] the name of the branch doesnt make sense anymore --- .../Manifest/ManifestYamlPopulator.cpp | 338 +++++++++--------- .../Public/winget/ManifestYamlPopulator.h | 9 +- 2 files changed, 169 insertions(+), 178 deletions(-) diff --git a/src/AppInstallerCommonCore/Manifest/ManifestYamlPopulator.cpp b/src/AppInstallerCommonCore/Manifest/ManifestYamlPopulator.cpp index c6b3965ae8..cd648a729a 100644 --- a/src/AppInstallerCommonCore/Manifest/ManifestYamlPopulator.cpp +++ b/src/AppInstallerCommonCore/Manifest/ManifestYamlPopulator.cpp @@ -12,42 +12,30 @@ namespace AppInstaller::Manifest namespace { template - Ptr* any_ptr(std::any& any) { return std::any_cast(any); } + Ptr* variant_ptr(const VariantManifestPtr& v) { return std::get(v); } - ManifestInstaller* GetManifestInstallerPtrFromManifest(std::any& any) - { - Manifest* manifest = std::any_cast(any); - return &(manifest->DefaultInstallerInfo); - } + ManifestInstaller* GetManifestInstallerPtrFromManifest(const VariantManifestPtr& v) { return &(variant_ptr(v)->DefaultInstallerInfo); } - ManifestLocalization* GetManifestLocalizationPtrFromManifest(std::any& any) - { - Manifest* manifest = std::any_cast(any); - return &(manifest->DefaultLocalization); - } + ManifestLocalization* GetManifestLocalizationPtrFromManifest(const VariantManifestPtr& v) { return &(variant_ptr(v)->DefaultLocalization); } - ManifestInstaller* GetManifestInstallerPtr(std::any& any) + ManifestInstaller* GetManifestInstallerPtr(const VariantManifestPtr& v) { - try - { - return std::any_cast(any); - } - catch (const std::bad_any_cast&) + if (auto installer = std::get_if(&v)) { - return GetManifestInstallerPtrFromManifest(any); + return *installer; } + + return GetManifestInstallerPtrFromManifest(v); } - ManifestLocalization* GetManifestLocalizationPtr(std::any& any) + ManifestLocalization* GetManifestLocalizationPtr(const VariantManifestPtr& v) { - try + if (auto localization = std::get_if(&v)) { - return std::any_cast(any); - } - catch (const std::bad_any_cast&) - { - return GetManifestLocalizationPtrFromManifest(any); + return *localization; } + + return GetManifestLocalizationPtrFromManifest(v); } // Only used in preview manifest @@ -185,10 +173,10 @@ namespace AppInstaller::Manifest // Common fields across versions std::vector result = { - { "ManifestVersion", [](const YAML::Node&, std::any&)->ValidationErrors { /* ManifestVersion already populated. Field listed here for duplicate and PascalCase check */ return {}; } }, - { "Installers", [this](const YAML::Node& value, std::any&)->ValidationErrors { m_p_installersNode = &value; return {}; } }, - { "Localization", [this](const YAML::Node& value, std::any&)->ValidationErrors { m_p_localizationsNode = &value; return {}; } }, - { "Channel", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->Channel = Utility::Trim(value.as()); return {}; } + { "ManifestVersion", [](const YAML::Node&, const VariantManifestPtr&)->ValidationErrors { /* ManifestVersion already populated. Field listed here for duplicate and PascalCase check */ return {}; } }, + { "Installers", [this](const YAML::Node& value, const VariantManifestPtr&)->ValidationErrors { m_p_installersNode = &value; return {}; } }, + { "Localization", [this](const YAML::Node& value, const VariantManifestPtr&)->ValidationErrors { m_p_localizationsNode = &value; return {}; } }, + { "Channel", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr(v)->Channel = Utility::Trim(value.as()); return {}; } }, }; @@ -197,9 +185,9 @@ namespace AppInstaller::Manifest { std::vector previewRootFields { - { "Id", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->Id = Utility::Trim(value.as()); return {}; } }, - { "Version", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->Version = Utility::Trim(value.as()); return {}; } }, - { "AppMoniker", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->Moniker = Utility::Trim(value.as()); return {}; } }, + { "Id", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr(v)->Id = Utility::Trim(value.as()); return {}; } }, + { "Version", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr(v)->Version = Utility::Trim(value.as()); return {}; } }, + { "AppMoniker", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr(v)->Moniker = Utility::Trim(value.as()); return {}; } }, }; std::move(previewRootFields.begin(), previewRootFields.end(), std::inserter(result, result.end())); @@ -211,10 +199,10 @@ namespace AppInstaller::Manifest { std::vector v1RootFields { - { "PackageIdentifier", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->Id = Utility::Trim(value.as()); return {}; } }, - { "PackageVersion", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->Version = Utility::Trim(value.as()); return {}; } }, - { "Moniker", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->Moniker = Utility::Trim(value.as()); return {}; } }, - { "ManifestType", [](const YAML::Node&, std::any&)->ValidationErrors { /* ManifestType already checked. Field listed here for duplicate and PascalCase check */ return {}; } }, + { "PackageIdentifier", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr(v)->Id = Utility::Trim(value.as()); return {}; } }, + { "PackageVersion", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr(v)->Version = Utility::Trim(value.as()); return {}; } }, + { "Moniker", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr(v)->Moniker = Utility::Trim(value.as()); return {}; } }, + { "ManifestType", [](const YAML::Node&, const VariantManifestPtr&)->ValidationErrors { /* ManifestType already checked. Field listed here for duplicate and PascalCase check */ return {}; } }, }; std::move(v1RootFields.begin(), v1RootFields.end(), std::inserter(result, result.end())); @@ -236,9 +224,9 @@ namespace AppInstaller::Manifest // Common fields across versions std::vector result = { - { "InstallerType", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtr(any)->BaseInstallerType = ConvertToInstallerTypeEnum(value.as()); return {}; } }, - { "PackageFamilyName", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtr(any)->PackageFamilyName = value.as(); return {}; } }, - { "ProductCode", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtr(any)->ProductCode = value.as(); return {}; } }, + { "InstallerType", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->BaseInstallerType = ConvertToInstallerTypeEnum(value.as()); return {}; } }, + { "PackageFamilyName", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->PackageFamilyName = value.as(); return {}; } }, + { "ProductCode", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->ProductCode = value.as(); return {}; } }, }; // Additional version specific fields @@ -247,8 +235,8 @@ namespace AppInstaller::Manifest // Root level and Localization node level std::vector previewCommonFields = { - { "UpdateBehavior", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtr(any)->UpdateBehavior = ConvertToUpdateBehaviorEnum(value.as()); return {}; } }, - { "Switches", [this](const YAML::Node& value, std::any& any)->ValidationErrors { std::any anySwitches = &(GetManifestInstallerPtr(any)->Switches); return ValidateAndProcessFields(value, SwitchesFieldInfos, anySwitches); } }, + { "UpdateBehavior", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->UpdateBehavior = ConvertToUpdateBehaviorEnum(value.as()); return {}; } }, + { "Switches", [this](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { return ValidateAndProcessFields(value, SwitchesFieldInfos, VariantManifestPtr(&(GetManifestInstallerPtr(v)->Switches))); }}, }; std::move(previewCommonFields.begin(), previewCommonFields.end(), std::inserter(result, result.end())); @@ -258,17 +246,17 @@ namespace AppInstaller::Manifest // Installer node only std::vector installerOnlyFields = { - { "Arch", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->Arch = Utility::ConvertToArchitectureEnum(value.as()); return {}; } }, - { "Url", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->Url = value.as(); return {}; } }, - { "Sha256", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->Sha256 = Utility::SHA256::ConvertToBytes(value.as()); return {}; } }, - { "SignatureSha256", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->SignatureSha256 = Utility::SHA256::ConvertToBytes(value.as()); return {}; } }, - { "Language", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->Locale = value.as(); return {}; } }, - { "Scope", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->Scope = ConvertToScopeEnum(value.as()); return {}; } }, + { "Arch", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr(v)->Arch = Utility::ConvertToArchitectureEnum(value.as()); return {}; } }, + { "Url", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr(v)->Url = value.as(); return {}; } }, + { "Sha256", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr(v)->Sha256 = Utility::SHA256::ConvertToBytes(value.as()); return {}; } }, + { "SignatureSha256", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr(v)->SignatureSha256 = Utility::SHA256::ConvertToBytes(value.as()); return {}; } }, + { "Language", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr(v)->Locale = value.as(); return {}; } }, + { "Scope", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr(v)->Scope = ConvertToScopeEnum(value.as()); return {}; } }, }; if (manifestVersion.HasExtension(s_MSStoreExtension)) { - installerOnlyFields.emplace_back("ProductId", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->ProductId = value.as(); return {}; }); + installerOnlyFields.emplace_back("ProductId", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr(v)->ProductId = value.as(); return {}; }); } std::move(installerOnlyFields.begin(), installerOnlyFields.end(), std::inserter(result, result.end())); @@ -278,10 +266,10 @@ namespace AppInstaller::Manifest // Root node only std::vector rootOnlyFields = { - { "MinOSVersion", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtrFromManifest(any)->MinOSVersion = value.as(); return {}; } }, - { "Commands", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtrFromManifest(any)->Commands = SplitMultiValueField(value.as()); return {}; } }, - { "Protocols", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtrFromManifest(any)->Protocols = SplitMultiValueField(value.as()); return {}; } }, - { "FileExtensions", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtrFromManifest(any)->FileExtensions = SplitMultiValueField(value.as()); return {}; } }, + { "MinOSVersion", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtrFromManifest(v)->MinOSVersion = value.as(); return {}; } }, + { "Commands", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtrFromManifest(v)->Commands = SplitMultiValueField(value.as()); return {}; } }, + { "Protocols", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtrFromManifest(v)->Protocols = SplitMultiValueField(value.as()); return {}; } }, + { "FileExtensions", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtrFromManifest(v)->FileExtensions = SplitMultiValueField(value.as()); return {}; } }, }; std::move(rootOnlyFields.begin(), rootOnlyFields.end(), std::inserter(result, result.end())); @@ -295,20 +283,20 @@ namespace AppInstaller::Manifest // Root level and Installer node level std::vector v1CommonFields = { - { "InstallerLocale", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtr(any)->Locale = value.as(); return {}; } }, - { "Platform", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtr(any)->Platform = ProcessPlatformSequenceNode(value); return {}; } }, - { "MinimumOSVersion", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtr(any)->MinOSVersion = value.as(); return {}; } }, - { "Scope", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtr(any)->Scope = ConvertToScopeEnum(value.as()); return {}; } }, - { "InstallModes", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtr(any)->InstallModes = ProcessInstallModeSequenceNode(value); return {}; } }, - { "InstallerSwitches", [this](const YAML::Node& value, std::any& any)->ValidationErrors { std::any anySwitches = &(GetManifestInstallerPtr(any)->Switches); return ValidateAndProcessFields(value, SwitchesFieldInfos, anySwitches); } }, - { "InstallerSuccessCodes", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtr(any)->InstallerSuccessCodes = ProcessInstallerSuccessCodeSequenceNode(value); return {}; } }, - { "UpgradeBehavior", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtr(any)->UpdateBehavior = ConvertToUpdateBehaviorEnum(value.as()); return {}; } }, - { "Commands", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtr(any)->Commands = ProcessStringSequenceNode(value); return {}; } }, - { "Protocols", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtr(any)->Protocols = ProcessStringSequenceNode(value); return {}; } }, - { "FileExtensions", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtr(any)->FileExtensions = ProcessStringSequenceNode(value); return {}; } }, - { "Dependencies", [this](const YAML::Node& value, std::any& any)->ValidationErrors { std::any anyDependencyList = &(GetManifestInstallerPtr(any)->Dependencies); return ValidateAndProcessFields(value, DependenciesFieldInfos, anyDependencyList); } }, - { "Capabilities", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtr(any)->Capabilities = ProcessStringSequenceNode(value); return {}; } }, - { "RestrictedCapabilities", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtr(any)->RestrictedCapabilities = ProcessStringSequenceNode(value); return {}; } }, + { "InstallerLocale", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->Locale = value.as(); return {}; } }, + { "Platform", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->Platform = ProcessPlatformSequenceNode(value); return {}; } }, + { "MinimumOSVersion", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->MinOSVersion = value.as(); return {}; } }, + { "Scope", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->Scope = ConvertToScopeEnum(value.as()); return {}; } }, + { "InstallModes", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->InstallModes = ProcessInstallModeSequenceNode(value); return {}; } }, + { "InstallerSwitches", [this](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { return ValidateAndProcessFields(value, SwitchesFieldInfos, VariantManifestPtr(&(GetManifestInstallerPtr(v)->Switches))); }}, + { "InstallerSuccessCodes", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->InstallerSuccessCodes = ProcessInstallerSuccessCodeSequenceNode(value); return {}; } }, + { "UpgradeBehavior", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->UpdateBehavior = ConvertToUpdateBehaviorEnum(value.as()); return {}; } }, + { "Commands", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->Commands = ProcessStringSequenceNode(value); return {}; } }, + { "Protocols", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->Protocols = ProcessStringSequenceNode(value); return {}; } }, + { "FileExtensions", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->FileExtensions = ProcessStringSequenceNode(value); return {}; } }, + { "Dependencies", [this](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { return ValidateAndProcessFields(value, DependenciesFieldInfos, VariantManifestPtr(&(GetManifestInstallerPtr(v)->Dependencies))); }}, + { "Capabilities", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->Capabilities = ProcessStringSequenceNode(value); return {}; } }, + { "RestrictedCapabilities", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->RestrictedCapabilities = ProcessStringSequenceNode(value); return {}; } }, }; std::move(v1CommonFields.begin(), v1CommonFields.end(), std::inserter(result, result.end())); @@ -318,10 +306,10 @@ namespace AppInstaller::Manifest // Installer level only fields std::vector v1InstallerFields = { - { "Architecture", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->Arch = Utility::ConvertToArchitectureEnum(value.as()); return {}; } }, - { "InstallerUrl", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->Url = value.as(); return {}; } }, - { "InstallerSha256", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->Sha256 = Utility::SHA256::ConvertToBytes(value.as()); return {}; } }, - { "SignatureSha256", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->SignatureSha256 = Utility::SHA256::ConvertToBytes(value.as()); return {}; } }, + { "Architecture", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr(v)->Arch = Utility::ConvertToArchitectureEnum(value.as()); return {}; } }, + { "InstallerUrl", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr(v)->Url = value.as(); return {}; } }, + { "InstallerSha256", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr(v)->Sha256 = Utility::SHA256::ConvertToBytes(value.as()); return {}; } }, + { "SignatureSha256", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr(v)->SignatureSha256 = Utility::SHA256::ConvertToBytes(value.as()); return {}; } }, }; std::move(v1InstallerFields.begin(), v1InstallerFields.end(), std::inserter(result, result.end())); @@ -332,15 +320,15 @@ namespace AppInstaller::Manifest { std::vector fields_v1_1 = { - { "InstallerAbortsTerminal", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtr(any)->InstallerAbortsTerminal = value.as(); return {}; } }, - { "InstallLocationRequired", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtr(any)->InstallLocationRequired = value.as(); return {}; } }, - { "RequireExplicitUpgrade", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtr(any)->RequireExplicitUpgrade = value.as(); return {}; } }, - { "ReleaseDate", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtr(any)->ReleaseDate = Utility::Trim(value.as()); return {}; } }, - { "UnsupportedOSArchitectures", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtr(any)->UnsupportedOSArchitectures = ProcessArchitectureSequenceNode(value); return {}; } }, - { "ElevationRequirement", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtr(any)->ElevationRequirement = ConvertToElevationRequirementEnum(value.as()); return {}; } }, - { "Markets", [this](const YAML::Node& value, std::any& any)->ValidationErrors { return ProcessMarketsNode(value, GetManifestInstallerPtr(any)); } }, - { "AppsAndFeaturesEntries", [this](const YAML::Node& value, std::any& any)->ValidationErrors { return ProcessAppsAndFeaturesEntriesNode(value, GetManifestInstallerPtr(any)); } }, - { "ExpectedReturnCodes", [this](const YAML::Node& value, std::any& any)->ValidationErrors { return ProcessExpectedReturnCodesNode(value, GetManifestInstallerPtr(any)); } }, + { "InstallerAbortsTerminal", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->InstallerAbortsTerminal = value.as(); return {}; } }, + { "InstallLocationRequired", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->InstallLocationRequired = value.as(); return {}; } }, + { "RequireExplicitUpgrade", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->RequireExplicitUpgrade = value.as(); return {}; } }, + { "ReleaseDate", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->ReleaseDate = Utility::Trim(value.as()); return {}; } }, + { "UnsupportedOSArchitectures", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->UnsupportedOSArchitectures = ProcessArchitectureSequenceNode(value); return {}; } }, + { "ElevationRequirement", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->ElevationRequirement = ConvertToElevationRequirementEnum(value.as()); return {}; } }, + { "Markets", [this](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { return ProcessMarketsNode(value, GetManifestInstallerPtr(v)); } }, + { "AppsAndFeaturesEntries", [this](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { return ProcessAppsAndFeaturesEntriesNode(value, GetManifestInstallerPtr(v)); } }, + { "ExpectedReturnCodes", [this](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { return ProcessExpectedReturnCodesNode(value, GetManifestInstallerPtr(v)); } }, }; std::move(fields_v1_1.begin(), fields_v1_1.end(), std::inserter(result, result.end())); @@ -350,8 +338,8 @@ namespace AppInstaller::Manifest { std::vector fields_v1_2 = { - { "UnsupportedArguments", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtr(any)->UnsupportedArguments = ProcessUnsupportedArgumentsSequenceNode(value); return {}; } }, - { "DisplayInstallWarnings", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtr(any)->DisplayInstallWarnings = value.as(); return {}; } }, + { "UnsupportedArguments", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->UnsupportedArguments = ProcessUnsupportedArgumentsSequenceNode(value); return {}; } }, + { "DisplayInstallWarnings", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->DisplayInstallWarnings = value.as(); return {}; } }, }; std::move(fields_v1_2.begin(), fields_v1_2.end(), std::inserter(result, result.end())); @@ -361,9 +349,9 @@ namespace AppInstaller::Manifest { std::vector fields_v1_4 = { - { "NestedInstallerType", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtr(any)->NestedInstallerType = ConvertToInstallerTypeEnum(value.as()); return {}; } }, - { "NestedInstallerFiles", [this](const YAML::Node& value, std::any& any)->ValidationErrors { return ProcessNestedInstallerFilesNode(value, GetManifestInstallerPtr(any)); } }, - { "InstallationMetadata", [this](const YAML::Node& value, std::any& any)->ValidationErrors { std::any installerMetadata = &(GetManifestInstallerPtr(any)->InstallationMetadata); return ValidateAndProcessFields(value, InstallationMetadataFieldInfos, installerMetadata); } }, + { "NestedInstallerType", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->NestedInstallerType = ConvertToInstallerTypeEnum(value.as()); return {}; } }, + { "NestedInstallerFiles", [this](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { return ProcessNestedInstallerFilesNode(value, GetManifestInstallerPtr(v)); } }, + { "InstallationMetadata", [this](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { return ValidateAndProcessFields(value, InstallationMetadataFieldInfos, VariantManifestPtr(&(GetManifestInstallerPtr(v)->InstallationMetadata))); }}, }; std::move(fields_v1_4.begin(), fields_v1_4.end(), std::inserter(result, result.end())); @@ -373,7 +361,7 @@ namespace AppInstaller::Manifest { std::vector fields_v1_6 = { - { "DownloadCommandProhibited", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtr(any)->DownloadCommandProhibited = value.as(); return {}; }, true }, + { "DownloadCommandProhibited", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->DownloadCommandProhibited = value.as(); return {}; }, true }, }; std::move(fields_v1_6.begin(), fields_v1_6.end(), std::inserter(result, result.end())); @@ -383,7 +371,7 @@ namespace AppInstaller::Manifest { std::vector fields_v1_7 = { - { "RepairBehavior", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestInstallerPtr(any)->RepairBehavior = ConvertToRepairBehaviorEnum(value.as()); return {}; } }, + { "RepairBehavior", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->RepairBehavior = ConvertToRepairBehaviorEnum(value.as()); return {}; } }, }; std::move(fields_v1_7.begin(), fields_v1_7.end(), std::inserter(result, result.end())); @@ -398,28 +386,28 @@ namespace AppInstaller::Manifest // Common fields across versions std::vector result = { - { "Custom", [](const YAML::Node& value, std::any& any)->ValidationErrors { (*any_ptr>(any))[InstallerSwitchType::Custom] = value.as(); return{}; } }, - { "Silent", [](const YAML::Node& value, std::any& any)->ValidationErrors { (*any_ptr>(any))[InstallerSwitchType::Silent] = value.as(); return{}; } }, - { "SilentWithProgress", [](const YAML::Node& value, std::any& any)->ValidationErrors { (*any_ptr>(any))[InstallerSwitchType::SilentWithProgress] = value.as(); return{}; } }, - { "Interactive", [](const YAML::Node& value, std::any& any)->ValidationErrors { (*any_ptr>(any))[InstallerSwitchType::Interactive] = value.as(); return{}; } }, - { "Log", [](const YAML::Node& value, std::any& any)->ValidationErrors { (*any_ptr>(any))[InstallerSwitchType::Log] = value.as(); return{}; } }, - { "InstallLocation", [](const YAML::Node& value, std::any& any)->ValidationErrors { (*any_ptr>(any))[InstallerSwitchType::InstallLocation] = value.as(); return{}; } }, + { "Custom", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { (*variant_ptr>(v))[InstallerSwitchType::Custom] = value.as(); return{}; } }, + { "Silent", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { (*variant_ptr>(v))[InstallerSwitchType::Silent] = value.as(); return{}; } }, + { "SilentWithProgress", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { (*variant_ptr>(v))[InstallerSwitchType::SilentWithProgress] = value.as(); return{}; } }, + { "Interactive", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { (*variant_ptr>(v))[InstallerSwitchType::Interactive] = value.as(); return{}; } }, + { "Log", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { (*variant_ptr>(v))[InstallerSwitchType::Log] = value.as(); return{}; } }, + { "InstallLocation", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { (*variant_ptr>(v))[InstallerSwitchType::InstallLocation] = value.as(); return{}; } }, }; // Additional version specific fields if (manifestVersion.Major() == 0) { // Language only exists in preview manifests. Though we don't use it in our code yet, keep it here to be consistent with schema. - result.emplace_back("Language", [](const YAML::Node& value, std::any& any)->ValidationErrors { (*any_ptr>(any))[InstallerSwitchType::Language] = value.as(); return{}; }); - result.emplace_back("Update", [](const YAML::Node& value, std::any& any)->ValidationErrors { (*any_ptr>(any))[InstallerSwitchType::Update] = value.as(); return{}; }); + result.emplace_back("Language", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { (*variant_ptr>(v))[InstallerSwitchType::Language] = value.as(); return{}; }); + result.emplace_back("Update", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { (*variant_ptr>(v))[InstallerSwitchType::Update] = value.as(); return{}; }); } else if (manifestVersion.Major() == 1) { - result.emplace_back("Upgrade", [](const YAML::Node& value, std::any& any)->ValidationErrors { (*any_ptr>(any))[InstallerSwitchType::Update] = value.as(); return{}; }); + result.emplace_back("Upgrade", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { (*variant_ptr>(v))[InstallerSwitchType::Update] = value.as(); return{}; }); if (manifestVersion >= ManifestVer{ s_ManifestVersionV1_7 }) { - result.emplace_back("Repair", [](const YAML::Node& value, std::any& any)->ValidationErrors { (*any_ptr>(any))[InstallerSwitchType::Repair] = value.as(); return{}; }); + result.emplace_back("Repair", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { (*variant_ptr>(v))[InstallerSwitchType::Repair] = value.as(); return{}; }); }; } @@ -432,13 +420,13 @@ namespace AppInstaller::Manifest if (manifestVersion >= ManifestVer{ s_ManifestVersionV1_1 }) { - result.emplace_back("InstallerReturnCode", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->InstallerReturnCode = static_cast(value.as()); return {}; }); - result.emplace_back("ReturnResponse", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->ReturnResponse = ConvertToExpectedReturnCodeEnum(value.as()); return {}; }); + result.emplace_back("InstallerReturnCode", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr(v)->InstallerReturnCode = static_cast(value.as()); return {}; }); + result.emplace_back("ReturnResponse", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr(v)->ReturnResponse = ConvertToExpectedReturnCodeEnum(value.as()); return {}; }); } if (manifestVersion >= ManifestVer{ s_ManifestVersionV1_2 }) { - result.emplace_back("ReturnResponseUrl", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->ReturnResponseUrl = value.as(); return {}; }); + result.emplace_back("ReturnResponseUrl", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr(v)->ReturnResponseUrl = value.as(); return {}; }); } return result; @@ -449,31 +437,31 @@ namespace AppInstaller::Manifest // Common fields across versions std::vector result = { - { "Description", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestLocalizationPtr(any)->Add(Utility::Trim(value.as())); return {}; } }, - { "LicenseUrl", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestLocalizationPtr(any)->Add(value.as()); return {}; } }, + { "Description", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestLocalizationPtr(v)->Add(Utility::Trim(value.as())); return {}; } }, + { "LicenseUrl", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestLocalizationPtr(v)->Add(value.as()); return {}; } }, }; // Additional version specific fields if (manifestVersion.Major() == 0) { // Root level and Localization node level - result.emplace_back("Homepage", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestLocalizationPtr(any)->Add(value.as()); return {}; }); + result.emplace_back("Homepage", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestLocalizationPtr(v)->Add(value.as()); return {}; }); if (!forRootFields) { // Localization node only - result.emplace_back("Language", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->Locale = value.as(); return {}; }); + result.emplace_back("Language", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr(v)->Locale = value.as(); return {}; }); } else { // Root node only std::vector rootOnlyFields = { - { "Name", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestLocalizationPtrFromManifest(any)->Add(Utility::Trim(value.as())); return {}; } }, - { "Publisher", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestLocalizationPtrFromManifest(any)->Add(value.as()); return {}; } }, - { "Author", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestLocalizationPtrFromManifest(any)->Add(value.as()); return {}; } }, - { "License", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestLocalizationPtrFromManifest(any)->Add(value.as()); return {}; } }, - { "Tags", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestLocalizationPtrFromManifest(any)->Add(SplitMultiValueField(value.as())); return {}; } }, + { "Name", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestLocalizationPtrFromManifest(v)->Add(Utility::Trim(value.as())); return {}; } }, + { "Publisher", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestLocalizationPtrFromManifest(v)->Add(value.as()); return {}; } }, + { "Author", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestLocalizationPtrFromManifest(v)->Add(value.as()); return {}; } }, + { "License", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestLocalizationPtrFromManifest(v)->Add(value.as()); return {}; } }, + { "Tags", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestLocalizationPtrFromManifest(v)->Add(SplitMultiValueField(value.as())); return {}; } }, }; std::move(rootOnlyFields.begin(), rootOnlyFields.end(), std::inserter(result, result.end())); @@ -487,19 +475,19 @@ namespace AppInstaller::Manifest // Root level and Localization node level std::vector v1CommonFields = { - { "PackageLocale", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestLocalizationPtr(any)->Locale = value.as(); return {}; } }, - { "Publisher", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestLocalizationPtr(any)->Add(value.as()); return {}; } }, - { "PublisherUrl", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestLocalizationPtr(any)->Add(value.as()); return {}; } }, - { "PublisherSupportUrl", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestLocalizationPtr(any)->Add(value.as()); return {}; } }, - { "PrivacyUrl", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestLocalizationPtr(any)->Add(value.as()); return {}; } }, - { "Author", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestLocalizationPtr(any)->Add(value.as()); return {}; } }, - { "PackageName", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestLocalizationPtr(any)->Add(Utility::Trim(value.as())); return {}; } }, - { "PackageUrl", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestLocalizationPtr(any)->Add(value.as()); return {}; } }, - { "License", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestLocalizationPtr(any)->Add(value.as()); return {}; } }, - { "Copyright", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestLocalizationPtr(any)->Add(value.as()); return {}; } }, - { "CopyrightUrl", [](const YAML::Node& value, std::any& any)->ValidationErrors{ GetManifestLocalizationPtr(any)->Add(value.as()); return {}; } }, - { "ShortDescription", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestLocalizationPtr(any)->Add(Utility::Trim(value.as())); return {}; } }, - { "Tags", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestLocalizationPtr(any)->Add(ProcessStringSequenceNode(value)); return {}; } }, + { "PackageLocale", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestLocalizationPtr(v)->Locale = value.as(); return {}; } }, + { "Publisher", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestLocalizationPtr(v)->Add(value.as()); return {}; } }, + { "PublisherUrl", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestLocalizationPtr(v)->Add(value.as()); return {}; } }, + { "PublisherSupportUrl", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestLocalizationPtr(v)->Add(value.as()); return {}; } }, + { "PrivacyUrl", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestLocalizationPtr(v)->Add(value.as()); return {}; } }, + { "Author", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestLocalizationPtr(v)->Add(value.as()); return {}; } }, + { "PackageName", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestLocalizationPtr(v)->Add(Utility::Trim(value.as())); return {}; } }, + { "PackageUrl", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestLocalizationPtr(v)->Add(value.as()); return {}; } }, + { "License", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestLocalizationPtr(v)->Add(value.as()); return {}; } }, + { "Copyright", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestLocalizationPtr(v)->Add(value.as()); return {}; } }, + { "CopyrightUrl", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors{ GetManifestLocalizationPtr(v)->Add(value.as()); return {}; } }, + { "ShortDescription", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestLocalizationPtr(v)->Add(Utility::Trim(value.as())); return {}; } }, + { "Tags", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestLocalizationPtr(v)->Add(ProcessStringSequenceNode(value)); return {}; } }, }; std::move(v1CommonFields.begin(), v1CommonFields.end(), std::inserter(result, result.end())); @@ -509,9 +497,9 @@ namespace AppInstaller::Manifest { std::vector fields_v1_1 = { - { "Agreements", [this](const YAML::Node& value, std::any& any)->ValidationErrors { return ProcessAgreementsNode(value, GetManifestLocalizationPtr(any)); } }, - { "ReleaseNotes", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestLocalizationPtr(any)->Add(value.as()); return {}; } }, - { "ReleaseNotesUrl", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestLocalizationPtr(any)->Add(value.as()); return {}; } }, + { "Agreements", [this](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { return ProcessAgreementsNode(value, GetManifestLocalizationPtr(v)); } }, + { "ReleaseNotes", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestLocalizationPtr(v)->Add(value.as()); return {}; } }, + { "ReleaseNotesUrl", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestLocalizationPtr(v)->Add(value.as()); return {}; } }, }; std::move(fields_v1_1.begin(), fields_v1_1.end(), std::inserter(result, result.end())); @@ -521,9 +509,9 @@ namespace AppInstaller::Manifest { std::vector fields_v1_2 = { - { "PurchaseUrl", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestLocalizationPtr(any)->Add(value.as()); return {}; } }, - { "InstallationNotes", [](const YAML::Node& value, std::any& any)->ValidationErrors { GetManifestLocalizationPtr(any)->Add(value.as()); return {}; } }, - { "Documentations", [this](const YAML::Node& value, std::any& any)->ValidationErrors { return ProcessDocumentationsNode(value, GetManifestLocalizationPtr(any)); } }, + { "PurchaseUrl", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestLocalizationPtr(v)->Add(value.as()); return {}; } }, + { "InstallationNotes", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestLocalizationPtr(v)->Add(value.as()); return {}; } }, + { "Documentations", [this](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { return ProcessDocumentationsNode(value, GetManifestLocalizationPtr(v)); } }, }; std::move(fields_v1_2.begin(), fields_v1_2.end(), std::inserter(result, result.end())); @@ -533,7 +521,7 @@ namespace AppInstaller::Manifest { std::vector fields_v1_5 = { - { "Icons", [this](const YAML::Node& value, std::any& any)->ValidationErrors { return ProcessIconsNode(value, GetManifestLocalizationPtr(any)); }, true }, + { "Icons", [this](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { return ProcessIconsNode(value, GetManifestLocalizationPtr(v)); }, true }, }; std::move(fields_v1_5.begin(), fields_v1_5.end(), std::inserter(result, result.end())); @@ -551,10 +539,10 @@ namespace AppInstaller::Manifest { result = { - { "WindowsFeatures", [](const YAML::Node& value, std::any& any)->ValidationErrors { ProcessDependenciesNode(DependencyType::WindowsFeature, value, any_ptr(any)); return {}; } }, - { "WindowsLibraries", [](const YAML::Node& value, std::any& any)->ValidationErrors { ProcessDependenciesNode(DependencyType::WindowsLibrary, value, any_ptr(any)); return {}; } }, - { "PackageDependencies", [this](const YAML::Node& value, std::any& any)->ValidationErrors { ProcessPackageDependenciesNode(value, any_ptr(any)); return {}; } }, - { "ExternalDependencies", [](const YAML::Node& value, std::any& any)->ValidationErrors { ProcessDependenciesNode(DependencyType::External, value, any_ptr(any)); return {}; } }, + { "WindowsFeatures", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { ProcessDependenciesNode(DependencyType::WindowsFeature, value, variant_ptr(v)); return {}; } }, + { "WindowsLibraries", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { ProcessDependenciesNode(DependencyType::WindowsLibrary, value, variant_ptr(v)); return {}; } }, + { "PackageDependencies", [this](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { ProcessPackageDependenciesNode(value, variant_ptr(v)); return {}; } }, + { "ExternalDependencies", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { ProcessDependenciesNode(DependencyType::External, value, variant_ptr(v)); return {}; } }, }; } @@ -569,8 +557,8 @@ namespace AppInstaller::Manifest { result = { - { "PackageIdentifier", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->SetId(Utility::Trim(value.as())); return {}; } }, - { "MinimumVersion", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->MinVersion = Utility::Version(Utility::Trim(value.as())); return {}; } }, + { "PackageIdentifier", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr(v)->SetId(Utility::Trim(value.as())); return {}; } }, + { "MinimumVersion", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr(v)->MinVersion = Utility::Version(Utility::Trim(value.as())); return {}; } }, }; } @@ -585,9 +573,9 @@ namespace AppInstaller::Manifest { result = { - { "AgreementLabel", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->Label = Utility::Trim(value.as()); return {}; } }, - { "Agreement", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->AgreementText = Utility::Trim(value.as()); return {}; }, true }, - { "AgreementUrl", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->AgreementUrl = Utility::Trim(value.as()); return {}; } }, + { "AgreementLabel", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr(v)->Label = Utility::Trim(value.as()); return {}; } }, + { "Agreement", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr(v)->AgreementText = Utility::Trim(value.as()); return {}; }, true }, + { "AgreementUrl", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr(v)->AgreementUrl = Utility::Trim(value.as()); return {}; } }, }; } @@ -602,8 +590,8 @@ namespace AppInstaller::Manifest { result = { - { "AllowedMarkets", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->AllowedMarkets = ProcessStringSequenceNode(value); return {}; } }, - { "ExcludedMarkets", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->ExcludedMarkets = ProcessStringSequenceNode(value); return {}; } }, + { "AllowedMarkets", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr(v)->AllowedMarkets = ProcessStringSequenceNode(value); return {}; } }, + { "ExcludedMarkets", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr(v)->ExcludedMarkets = ProcessStringSequenceNode(value); return {}; } }, }; } @@ -618,12 +606,12 @@ namespace AppInstaller::Manifest { result = { - { "DisplayName", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->DisplayName = Utility::Trim(value.as()); return {}; } }, - { "Publisher", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->Publisher = Utility::Trim(value.as()); return {}; } }, - { "DisplayVersion", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->DisplayVersion = Utility::Trim(value.as()); return {}; } }, - { "ProductCode", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->ProductCode = Utility::Trim(value.as()); return {}; } }, - { "UpgradeCode", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->UpgradeCode = Utility::Trim(value.as()); return {}; } }, - { "InstallerType", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->InstallerType = ConvertToInstallerTypeEnum(value.as()); return {}; } }, + { "DisplayName", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr(v)->DisplayName = Utility::Trim(value.as()); return {}; } }, + { "Publisher", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr(v)->Publisher = Utility::Trim(value.as()); return {}; } }, + { "DisplayVersion", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr(v)->DisplayVersion = Utility::Trim(value.as()); return {}; } }, + { "ProductCode", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr(v)->ProductCode = Utility::Trim(value.as()); return {}; } }, + { "UpgradeCode", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr(v)->UpgradeCode = Utility::Trim(value.as()); return {}; } }, + { "InstallerType", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr(v)->InstallerType = ConvertToInstallerTypeEnum(value.as()); return {}; } }, }; } @@ -638,8 +626,8 @@ namespace AppInstaller::Manifest { result = { - { "DocumentLabel", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->DocumentLabel = Utility::Trim(value.as()); return {}; } }, - { "DocumentUrl", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->DocumentUrl = Utility::Trim(value.as()); return {}; } }, + { "DocumentLabel", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr(v)->DocumentLabel = Utility::Trim(value.as()); return {}; } }, + { "DocumentUrl", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr(v)->DocumentUrl = Utility::Trim(value.as()); return {}; } }, }; } @@ -654,11 +642,11 @@ namespace AppInstaller::Manifest { result = { - { "IconUrl", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->Url = Utility::Trim(value.as()); return {}; } }, - { "IconFileType", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->FileType = ConvertToIconFileTypeEnum(value.as()); return {}; } }, - { "IconResolution", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->Resolution = ConvertToIconResolutionEnum(value.as()); return {}; } }, - { "IconTheme", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->Theme = ConvertToIconThemeEnum(value.as()); return {}; } }, - { "IconSha256", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->Sha256 = Utility::SHA256::ConvertToBytes(value.as()); return {}; } }, + { "IconUrl", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr(v)->Url = Utility::Trim(value.as()); return {}; } }, + { "IconFileType", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr(v)->FileType = ConvertToIconFileTypeEnum(value.as()); return {}; } }, + { "IconResolution", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr(v)->Resolution = ConvertToIconResolutionEnum(value.as()); return {}; } }, + { "IconTheme", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr(v)->Theme = ConvertToIconThemeEnum(value.as()); return {}; } }, + { "IconSha256", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr(v)->Sha256 = Utility::SHA256::ConvertToBytes(value.as()); return {}; } }, }; } @@ -673,8 +661,8 @@ namespace AppInstaller::Manifest { result = { - { "RelativeFilePath", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->RelativeFilePath = Utility::Trim(value.as()); return {}; } }, - { "PortableCommandAlias", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->PortableCommandAlias = Utility::Trim(value.as()); return {}; } }, + { "RelativeFilePath", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr(v)->RelativeFilePath = Utility::Trim(value.as()); return {}; } }, + { "PortableCommandAlias", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr(v)->PortableCommandAlias = Utility::Trim(value.as()); return {}; } }, }; } @@ -689,8 +677,8 @@ namespace AppInstaller::Manifest { result = { - { "DefaultInstallLocation", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->DefaultInstallLocation = Utility::Trim(value.as()); return {}; } }, - { "Files", [this](const YAML::Node& value, std::any& any)->ValidationErrors { InstallationMetadataInfo* installationMetadata = std::any_cast(any); return ProcessInstallationMetadataFilesNode(value, installationMetadata); } }, + { "DefaultInstallLocation", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr(v)->DefaultInstallLocation = Utility::Trim(value.as()); return {}; } }, + { "Files", [this](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { return ProcessInstallationMetadataFilesNode(value, variant_ptr(v)); } }, }; } @@ -705,11 +693,11 @@ namespace AppInstaller::Manifest { result = { - { "RelativeFilePath", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->RelativeFilePath = Utility::Trim(value.as()); return {}; } }, - { "FileSha256", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->FileSha256 = Utility::SHA256::ConvertToBytes(value.as()); return {}; } }, - { "FileType", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->FileType = ConvertToInstalledFileTypeEnum(value.as()); return {}; } }, - { "InvocationParameter", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->InvocationParameter = Utility::Trim(value.as()); return {}; } }, - { "DisplayName", [](const YAML::Node& value, std::any& any)->ValidationErrors { any_ptr(any)->DisplayName = Utility::Trim(value.as()); return {}; } }, + { "RelativeFilePath", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr(v)->RelativeFilePath = Utility::Trim(value.as()); return {}; } }, + { "FileSha256", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr(v)->FileSha256 = Utility::SHA256::ConvertToBytes(value.as()); return {}; } }, + { "FileType", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr(v)->FileType = ConvertToInstalledFileTypeEnum(value.as()); return {}; } }, + { "InvocationParameter", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr(v)->InvocationParameter = Utility::Trim(value.as()); return {}; } }, + { "DisplayName", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr(v)->DisplayName = Utility::Trim(value.as()); return {}; } }, }; } @@ -719,7 +707,7 @@ namespace AppInstaller::Manifest ValidationErrors ManifestYamlPopulator::ValidateAndProcessFields( const YAML::Node& rootNode, const std::vector& fieldInfos, - std::any any) + const VariantManifestPtr& v) { ValidationErrors resultErrors; @@ -771,7 +759,7 @@ namespace AppInstaller::Manifest { try { - auto errors = fieldInfo.ProcessFunc(valueNode, any); + auto errors = fieldInfo.ProcessFunc(valueNode, v); std::move(errors.begin(), errors.end(), std::inserter(resultErrors, resultErrors.end())); } catch (const std::exception&) @@ -800,7 +788,7 @@ namespace AppInstaller::Manifest for (auto const& entry : rootNode.Sequence()) { Dependency packageDependency = Dependency(DependencyType::Package); - auto errors = ValidateAndProcessFields(entry, PackageDependenciesFieldInfos, std::any(&packageDependency)); + auto errors = ValidateAndProcessFields(entry, PackageDependenciesFieldInfos, VariantManifestPtr(&packageDependency)); std::move(errors.begin(), errors.end(), std::inserter(resultErrors, resultErrors.end())); dependencyList->Add(std::move(packageDependency)); } @@ -818,7 +806,7 @@ namespace AppInstaller::Manifest for (auto const& entry : agreementsNode.Sequence()) { Agreement agreement; - auto errors = ValidateAndProcessFields(entry, AgreementFieldInfos, std::any(&agreement)); + auto errors = ValidateAndProcessFields(entry, AgreementFieldInfos, VariantManifestPtr(&agreement)); std::move(errors.begin(), errors.end(), std::inserter(resultErrors, resultErrors.end())); agreements.emplace_back(std::move(agreement)); } @@ -834,7 +822,7 @@ namespace AppInstaller::Manifest std::vector ManifestYamlPopulator::ProcessMarketsNode(const YAML::Node& marketsNode, ManifestInstaller* installer) { MarketsInfo markets; - auto errors = ValidateAndProcessFields(marketsNode, MarketsFieldInfos, std::any(&markets)); + auto errors = ValidateAndProcessFields(marketsNode, MarketsFieldInfos, VariantManifestPtr(&markets)); installer->Markets = markets; return errors; } @@ -849,7 +837,7 @@ namespace AppInstaller::Manifest for (auto const& entry : appsAndFeaturesEntriesNode.Sequence()) { AppsAndFeaturesEntry appsAndFeaturesEntry; - auto errors = ValidateAndProcessFields(entry, AppsAndFeaturesEntryFieldInfos, std::any(&appsAndFeaturesEntry)); + auto errors = ValidateAndProcessFields(entry, AppsAndFeaturesEntryFieldInfos, VariantManifestPtr(&appsAndFeaturesEntry)); std::move(errors.begin(), errors.end(), std::inserter(resultErrors, resultErrors.end())); appsAndFeaturesEntries.emplace_back(std::move(appsAndFeaturesEntry)); } @@ -869,7 +857,7 @@ namespace AppInstaller::Manifest for (auto const& entry : returnCodesNode.Sequence()) { ExpectedReturnCode returnCode; - auto errors = ValidateAndProcessFields(entry, ExpectedReturnCodesFieldInfos, std::any(&returnCode)); + auto errors = ValidateAndProcessFields(entry, ExpectedReturnCodesFieldInfos, VariantManifestPtr(&returnCode)); std::move(errors.begin(), errors.end(), std::inserter(resultErrors, resultErrors.end())); if (!returnCodes.insert({ returnCode.InstallerReturnCode, {returnCode.ReturnResponse, returnCode.ReturnResponseUrl} }).second) { @@ -892,7 +880,7 @@ namespace AppInstaller::Manifest for (auto const& entry : documentationsNode.Sequence()) { Documentation documentation; - auto errors = ValidateAndProcessFields(entry, DocumentationFieldInfos, std::any(&documentation)); + auto errors = ValidateAndProcessFields(entry, DocumentationFieldInfos, VariantManifestPtr(&documentation)); std::move(errors.begin(), errors.end(), std::inserter(resultErrors, resultErrors.end())); documentations.emplace_back(std::move(documentation)); } @@ -915,7 +903,7 @@ namespace AppInstaller::Manifest for (auto const& entry : iconsNode.Sequence()) { Icon icon; - auto errors = ValidateAndProcessFields(entry, IconFieldInfos, std::any(&icon)); + auto errors = ValidateAndProcessFields(entry, IconFieldInfos, VariantManifestPtr(&icon)); std::move(errors.begin(), errors.end(), std::inserter(resultErrors, resultErrors.end())); icons.emplace_back(std::move(icon)); } @@ -938,7 +926,7 @@ namespace AppInstaller::Manifest for (auto const& entry : nestedInstallerFilesNode.Sequence()) { NestedInstallerFile nestedInstallerFile; - auto errors = ValidateAndProcessFields(entry, NestedInstallerFileFieldInfos, std::any(&nestedInstallerFile)); + auto errors = ValidateAndProcessFields(entry, NestedInstallerFileFieldInfos, VariantManifestPtr(&nestedInstallerFile)); std::move(errors.begin(), errors.end(), std::inserter(resultErrors, resultErrors.end())); nestedInstallerFiles.emplace_back(std::move(nestedInstallerFile)); } @@ -961,7 +949,7 @@ namespace AppInstaller::Manifest for (auto const& entry : installedFilesNode.Sequence()) { InstalledFile installedFile; - auto errors = ValidateAndProcessFields(entry, InstallationMetadataFilesFieldInfos, std::any(&installedFile)); + auto errors = ValidateAndProcessFields(entry, InstallationMetadataFilesFieldInfos, VariantManifestPtr(&installedFile)); std::move(errors.begin(), errors.end(), std::inserter(resultErrors, resultErrors.end())); installedFiles.emplace_back(std::move(installedFile)); } @@ -1003,7 +991,7 @@ namespace AppInstaller::Manifest InstallationMetadataFieldInfos = GetInstallationMetadataFieldProcessInfo(manifestVersion); InstallationMetadataFilesFieldInfos = GetInstallationMetadataFilesFieldProcessInfo(manifestVersion); - resultErrors = ValidateAndProcessFields(rootNode, RootFieldInfos, std::any(&manifest)); + resultErrors = ValidateAndProcessFields(rootNode, RootFieldInfos, VariantManifestPtr(&manifest)); if (!m_p_installersNode) { @@ -1025,7 +1013,7 @@ namespace AppInstaller::Manifest installer.NestedInstallerType = InstallerTypeEnum::Unknown; installer.NestedInstallerFiles.clear(); - auto errors = ValidateAndProcessFields(entry, InstallerFieldInfos, std::any(&installer)); + auto errors = ValidateAndProcessFields(entry, InstallerFieldInfos, VariantManifestPtr(&installer)); std::move(errors.begin(), errors.end(), std::inserter(resultErrors, resultErrors.end())); // Copy in system reference strings from the root if not set in the installer and appropriate @@ -1093,7 +1081,7 @@ namespace AppInstaller::Manifest for (auto const& entry : m_p_localizationsNode->Sequence()) { ManifestLocalization localization; - auto errors = ValidateAndProcessFields(entry, LocalizationFieldInfos, std::any(&localization)); + auto errors = ValidateAndProcessFields(entry, LocalizationFieldInfos, VariantManifestPtr(&localization)); std::move(errors.begin(), errors.end(), std::inserter(resultErrors, resultErrors.end())); manifest.Localizations.emplace_back(std::move(std::move(localization))); } diff --git a/src/AppInstallerCommonCore/Public/winget/ManifestYamlPopulator.h b/src/AppInstallerCommonCore/Public/winget/ManifestYamlPopulator.h index 635377a5a6..9f2e19e66b 100644 --- a/src/AppInstallerCommonCore/Public/winget/ManifestYamlPopulator.h +++ b/src/AppInstallerCommonCore/Public/winget/ManifestYamlPopulator.h @@ -7,6 +7,9 @@ namespace AppInstaller::Manifest { + // Add here new manifest pointer types. + using VariantManifestPtr = std::variant*>; + struct ManifestYamlPopulator { static std::vector PopulateManifest( @@ -23,11 +26,11 @@ namespace AppInstaller::Manifest // Struct mapping a manifest field to its population logic struct FieldProcessInfo { - FieldProcessInfo(std::string name, std::function(const YAML::Node&, std::any&)> func, bool requireVerifiedPublisher = false) : + FieldProcessInfo(std::string name, std::function(const YAML::Node&, const VariantManifestPtr& v)> func, bool requireVerifiedPublisher = false) : Name(std::move(name)), ProcessFunc(func), RequireVerifiedPublisher(requireVerifiedPublisher) {} std::string Name; - std::function(const YAML::Node&, std::any& any)> ProcessFunc; + std::function(const YAML::Node&, const VariantManifestPtr& v)> ProcessFunc; bool RequireVerifiedPublisher = false; }; @@ -75,7 +78,7 @@ namespace AppInstaller::Manifest std::vector ValidateAndProcessFields( const YAML::Node& rootNode, const std::vector& fieldInfos, - std::any any); + const VariantManifestPtr& v); std::vector ProcessPackageDependenciesNode(const YAML::Node& rootNode, DependencyList* dependencyList); std::vector ProcessAgreementsNode(const YAML::Node& agreementsNode, ManifestLocalization* localization); From a2c07d84357fe6b91bd9f2cf852a75606930d615 Mon Sep 17 00:00:00 2001 From: Ruben Guerrero Samaniego Date: Tue, 23 Jan 2024 17:39:38 -0800 Subject: [PATCH 5/5] variant --- src/AppInstallerCommonCore/pch.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AppInstallerCommonCore/pch.h b/src/AppInstallerCommonCore/pch.h index 47e2699b2c..e025e87897 100644 --- a/src/AppInstallerCommonCore/pch.h +++ b/src/AppInstallerCommonCore/pch.h @@ -59,7 +59,7 @@ #include #include #include -#include +#include #pragma warning( push ) #pragma warning ( disable : 6001 6285 6287 6340 6387 6388 26451 26495 28196 )