Skip to content

Commit

Permalink
Winget client rest source parsing for 1.7 manifest (#4155)
Browse files Browse the repository at this point in the history
  • Loading branch information
yao-msft authored Feb 9, 2024
1 parent 30e54e4 commit 4d51b5f
Show file tree
Hide file tree
Showing 8 changed files with 490 additions and 11 deletions.
375 changes: 375 additions & 0 deletions src/AppInstallerCLITests/RestInterface_1_7.cpp

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,7 @@
<ClInclude Include="Rest\Schema\1_6\Interface.h" />
<ClInclude Include="Rest\Schema\1_6\Json\ManifestDeserializer.h" />
<ClInclude Include="Rest\Schema\1_7\Interface.h" />
<ClInclude Include="Rest\Schema\1_7\Json\ManifestDeserializer.h" />
<ClInclude Include="Rest\Schema\AuthenticationInfoParser.h" />
<ClInclude Include="Rest\Schema\CommonRestConstants.h" />
<ClInclude Include="Rest\Schema\HttpClientHelper.h" />
Expand Down Expand Up @@ -515,6 +516,7 @@
<ClCompile Include="Rest\Schema\1_5\RestInterface_1_5.cpp" />
<ClCompile Include="Rest\Schema\1_6\Json\ManifestDeserializer_1_6.cpp" />
<ClCompile Include="Rest\Schema\1_6\RestInterface_1_6.cpp" />
<ClCompile Include="Rest\Schema\1_7\Json\ManifestDeserializer_1_7.cpp" />
<ClCompile Include="Rest\Schema\1_7\RestInterface_1_7.cpp" />
<ClCompile Include="Rest\Schema\AuthenticationInfoParser.cpp" />
<ClCompile Include="Rest\Schema\HttpClientHelper.cpp" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@
<Filter Include="Rest\Schema\1_7">
<UniqueIdentifier>{f42acfce-4fc0-435b-a9a2-bf5528aecbcc}</UniqueIdentifier>
</Filter>
<Filter Include="Rest\Schema\1_7\Json">
<UniqueIdentifier>{7fd6c265-81c0-4c6e-87b2-24bef117e21d}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="pch.h">
Expand Down Expand Up @@ -402,6 +405,9 @@
<ClInclude Include="Rest\Schema\AuthenticationInfoParser.h">
<Filter>Rest\Schema</Filter>
</ClInclude>
<ClInclude Include="Rest\Schema\1_7\Json\ManifestDeserializer.h">
<Filter>Rest\Schema\1_7\Json</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="pch.cpp">
Expand Down Expand Up @@ -632,6 +638,9 @@
<ClCompile Include="Rest\Schema\AuthenticationInfoParser.cpp">
<Filter>Rest\Schema</Filter>
</ClCompile>
<ClCompile Include="Rest\Schema\1_7\Json\ManifestDeserializer_1_7.cpp">
<Filter>Rest\Schema\1_7\Json</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="PropertySheet.props" />
Expand Down
9 changes: 7 additions & 2 deletions src/AppInstallerRepositoryCore/ManifestJSONParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "Rest/Schema/1_4/Json/ManifestDeserializer.h"
#include "Rest/Schema/1_5/Json/ManifestDeserializer.h"
#include "Rest/Schema/1_6/Json/ManifestDeserializer.h"
#include "Rest/Schema/1_7/Json/ManifestDeserializer.h"

namespace AppInstaller::Repository::JSON
{
Expand Down Expand Up @@ -37,14 +38,18 @@ namespace AppInstaller::Repository::JSON
{
m_pImpl->m_deserializer = std::make_unique<Rest::Schema::V1_4::Json::ManifestDeserializer>();
}
else if (parts.size() > 1 && parts[1].Integer < 6)
else if (parts.size() > 1 && parts[1].Integer < 6)
{
m_pImpl->m_deserializer = std::make_unique<Rest::Schema::V1_5::Json::ManifestDeserializer>();
}
else
else if (parts.size() > 1 && parts[1].Integer < 7)
{
m_pImpl->m_deserializer = std::make_unique<Rest::Schema::V1_6::Json::ManifestDeserializer>();
}
else
{
m_pImpl->m_deserializer = std::make_unique<Rest::Schema::V1_7::Json::ManifestDeserializer>();
}
}
else
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ namespace AppInstaller::Repository::Rest::Schema::V1_0::Json

virtual std::optional<Manifest::ManifestInstaller> DeserializeInstaller(const web::json::value& installerJsonObject) const;

virtual std::map<Manifest::InstallerSwitchType, Manifest::string_t> DeserializeInstallerSwitches(const web::json::value& installerSwitchesJsonObject) const;

std::optional<Manifest::DependencyList> DeserializeDependency(const web::json::value& dependenciesJsonObject) const;

virtual Manifest::InstallerTypeEnum ConvertToInstallerType(std::string_view in) const;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,16 @@ namespace AppInstaller::Repository::Rest::Schema::V1_0::Json
std::optional<Manifest::ManifestInstaller> installerObject = DeserializeInstaller(installer);
if (installerObject)
{
// Merge default switches after parsing.
auto defaultSwitches = Manifest::GetDefaultKnownSwitches(installerObject->EffectiveInstallerType());
for (auto const& defaultSwitch : defaultSwitches)
{
if (installerObject->Switches.find(defaultSwitch.first) == installerObject->Switches.end())
{
installerObject->Switches[defaultSwitch.first] = defaultSwitch.second;
}
}

manifest.Installers.emplace_back(std::move(installerObject.value()));
}
}
Expand Down Expand Up @@ -374,19 +384,11 @@ namespace AppInstaller::Repository::Rest::Schema::V1_0::Json
}

// Installer Switches
installer.Switches = Manifest::GetDefaultKnownSwitches(installer.EffectiveInstallerType());
std::optional<std::reference_wrapper<const web::json::value>> switches =
JSON::GetJsonValueFromNode(installerJsonObject, JSON::GetUtilityString(InstallerSwitches));
if (switches)
{
const auto& installerSwitches = switches.value().get();
TryParseInstallerSwitchField(installer.Switches, InstallerSwitchType::Silent, installerSwitches, Silent);
TryParseInstallerSwitchField(installer.Switches, InstallerSwitchType::SilentWithProgress, installerSwitches, SilentWithProgress);
TryParseInstallerSwitchField(installer.Switches, InstallerSwitchType::Interactive, installerSwitches, Interactive);
TryParseInstallerSwitchField(installer.Switches, InstallerSwitchType::InstallLocation, installerSwitches, InstallLocation);
TryParseInstallerSwitchField(installer.Switches, InstallerSwitchType::Log, installerSwitches, Log);
TryParseInstallerSwitchField(installer.Switches, InstallerSwitchType::Update, installerSwitches, Upgrade);
TryParseInstallerSwitchField(installer.Switches, InstallerSwitchType::Custom, installerSwitches, Custom);
installer.Switches = DeserializeInstallerSwitches(switches.value().get());
}

// Installer SuccessCodes
Expand Down Expand Up @@ -433,6 +435,21 @@ namespace AppInstaller::Repository::Rest::Schema::V1_0::Json
return installer;
}

std::map<Manifest::InstallerSwitchType, Manifest::string_t> ManifestDeserializer::DeserializeInstallerSwitches(const web::json::value& installerSwitchesJsonObject) const
{
std::map<Manifest::InstallerSwitchType, Manifest::string_t> installerSwitches;

TryParseInstallerSwitchField(installerSwitches, InstallerSwitchType::Silent, installerSwitchesJsonObject, Silent);
TryParseInstallerSwitchField(installerSwitches, InstallerSwitchType::SilentWithProgress, installerSwitchesJsonObject, SilentWithProgress);
TryParseInstallerSwitchField(installerSwitches, InstallerSwitchType::Interactive, installerSwitchesJsonObject, Interactive);
TryParseInstallerSwitchField(installerSwitches, InstallerSwitchType::InstallLocation, installerSwitchesJsonObject, InstallLocation);
TryParseInstallerSwitchField(installerSwitches, InstallerSwitchType::Log, installerSwitchesJsonObject, Log);
TryParseInstallerSwitchField(installerSwitches, InstallerSwitchType::Update, installerSwitchesJsonObject, Upgrade);
TryParseInstallerSwitchField(installerSwitches, InstallerSwitchType::Custom, installerSwitchesJsonObject, Custom);

return installerSwitches;
}

std::optional<Manifest::DependencyList> ManifestDeserializer::DeserializeDependency(const web::json::value& dependenciesObject) const
{
if (dependenciesObject.is_null())
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
#pragma once
#include "Rest/Schema/1_6/Json/ManifestDeserializer.h"

namespace AppInstaller::Repository::Rest::Schema::V1_7::Json
{
// Manifest Deserializer.
struct ManifestDeserializer : public V1_6::Json::ManifestDeserializer
{
protected:

std::optional<Manifest::ManifestInstaller> DeserializeInstaller(const web::json::value& installerJsonObject) const override;

std::map<Manifest::InstallerSwitchType, Manifest::string_t> DeserializeInstallerSwitches(const web::json::value& installerSwitchesJsonObject) const override;

Manifest::ManifestVer GetManifestVersion() const override;
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
#include "pch.h"
#include "ManifestDeserializer.h"
#include <winget/JsonUtil.h>

using namespace AppInstaller::Manifest;

namespace AppInstaller::Repository::Rest::Schema::V1_7::Json
{
namespace
{
// Installer
constexpr std::string_view InstallerSwitchRepair = "Repair"sv;
constexpr std::string_view RepairBehavior = "RepairBehavior"sv;
}

std::optional<Manifest::ManifestInstaller> ManifestDeserializer::DeserializeInstaller(const web::json::value& installerJsonObject) const
{
auto result = V1_6::Json::ManifestDeserializer::DeserializeInstaller(installerJsonObject);

if (result)
{
auto& installer = result.value();

installer.RepairBehavior = Manifest::ConvertToRepairBehaviorEnum(JSON::GetRawStringValueFromJsonNode(installerJsonObject, JSON::GetUtilityString(RepairBehavior)).value_or(""));
}

return result;
}

std::map<Manifest::InstallerSwitchType, Manifest::string_t> ManifestDeserializer::DeserializeInstallerSwitches(const web::json::value& installerSwitchesJsonObject) const
{
auto installerSwitches = V1_6::Json::ManifestDeserializer::DeserializeInstallerSwitches(installerSwitchesJsonObject);

auto repairValue = JSON::GetRawStringValueFromJsonNode(installerSwitchesJsonObject, JSON::GetUtilityString(InstallerSwitchRepair));

if (JSON::IsValidNonEmptyStringValue(repairValue))
{
installerSwitches[Manifest::InstallerSwitchType::Repair] = repairValue.value();
}

return installerSwitches;
}

Manifest::ManifestVer ManifestDeserializer::GetManifestVersion() const
{
return Manifest::s_ManifestVersionV1_7;
}
}

0 comments on commit 4d51b5f

Please sign in to comment.