Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add "maybe" operations to JSON. #1520

Merged
merged 1 commit into from
Oct 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions include/vcpkg/base/json.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,15 +108,23 @@ namespace vcpkg::Json
int64_t integer(LineInfo li) const noexcept;
double number(LineInfo li) const noexcept;
StringView string(LineInfo li) const noexcept;
std::string* maybe_string() noexcept;
const std::string* maybe_string() const noexcept;

const Array& array(LineInfo li) const& noexcept;
Array& array(LineInfo li) & noexcept;
Array&& array(LineInfo li) && noexcept;

Array* maybe_array() noexcept;
const Array* maybe_array() const noexcept;

const Object& object(LineInfo li) const& noexcept;
Object& object(LineInfo li) & noexcept;
Object&& object(LineInfo li) && noexcept;

Object* maybe_object() noexcept;
const Object* maybe_object() const noexcept;

static Value null(std::nullptr_t) noexcept;
static Value boolean(bool) noexcept;
static Value integer(int64_t i) noexcept;
Expand Down
64 changes: 62 additions & 2 deletions src/vcpkg/base/json.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,26 @@ namespace vcpkg::Json
return underlying_->string;
}

std::string* Value::maybe_string() noexcept
{
if (underlying_ && underlying_->tag == VK::String)
{
return &underlying_->string;
}

return nullptr;
}

const std::string* Value::maybe_string() const noexcept
{
if (underlying_ && underlying_->tag == VK::String)
{
return &underlying_->string;
}

return nullptr;
}

const Array& Value::array(LineInfo li) const& noexcept
{
vcpkg::Checks::msg_check_exit(li, is_array(), msgJsonValueNotArray);
Expand All @@ -169,6 +189,26 @@ namespace vcpkg::Json
}
Array&& Value::array(LineInfo li) && noexcept { return std::move(this->array(li)); }

Array* Value::maybe_array() noexcept
{
if (underlying_ && underlying_->tag == VK::Array)
{
return &underlying_->array;
}

return nullptr;
}

const Array* Value::maybe_array() const noexcept
{
if (underlying_ && underlying_->tag == VK::Array)
{
return &underlying_->array;
}

return nullptr;
}

const Object& Value::object(LineInfo li) const& noexcept
{
vcpkg::Checks::msg_check_exit(li, is_object(), msgJsonValueNotObject);
Expand All @@ -181,6 +221,26 @@ namespace vcpkg::Json
}
Object&& Value::object(LineInfo li) && noexcept { return std::move(this->object(li)); }

Object* Value::maybe_object() noexcept
{
if (underlying_ && underlying_->tag == VK::Object)
{
return &underlying_->object;
}

return nullptr;
}

const Object* Value::maybe_object() const noexcept
{
if (underlying_ && underlying_->tag == VK::Object)
{
return &underlying_->object;
}

return nullptr;
}

Value::Value() noexcept = default;
Value::Value(Value&&) noexcept = default;
Value& Value::operator=(Value&&) noexcept = default;
Expand Down Expand Up @@ -1120,9 +1180,9 @@ namespace vcpkg::Json
{
return parse(text, origin).then([&](ParsedJson&& mabeValueIsh) -> ExpectedL<Json::Object> {
auto& asValue = mabeValueIsh.value;
if (asValue.is_object())
if (auto as_object = asValue.maybe_object())
{
return std::move(asValue).object(VCPKG_LINE_INFO);
return std::move(*as_object);
}

return msg::format(msgJsonErrorMustBeAnObject, msg::path = origin);
Expand Down
8 changes: 5 additions & 3 deletions src/vcpkg/binarycaching.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -812,10 +812,12 @@ namespace
auto maybe_json = Json::parse_object(*p, m_url);
if (auto json = maybe_json.get())
{
auto archive_location = json->get(JsonIdArchiveCapitalLocation);
if (archive_location && archive_location->is_string())
if (auto archive_location = json->get(JsonIdArchiveCapitalLocation))
{
return archive_location->string(VCPKG_LINE_INFO).to_string();
if (auto archive_location_string = archive_location->maybe_string())
{
return *archive_location_string;
}
}
}
}
Expand Down
13 changes: 6 additions & 7 deletions src/vcpkg/bundlesettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,17 @@ namespace

bool parse_optional_json_string(const Json::Object& doc, StringLiteral field_name, Optional<std::string>& output)
{
auto value = doc.get(field_name);
if (!value)
if (auto value = doc.get(field_name))
{
return true;
}
if (auto value_string = value->maybe_string())
{
output = *value_string;
return true;
}

if (!value->is_string())
{
return false;
}

output = value->string(VCPKG_LINE_INFO).to_string();
return true;
}
}
Expand Down
42 changes: 23 additions & 19 deletions src/vcpkg/commands.set-installed.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,24 +50,27 @@ namespace vcpkg
Optional<Json::Object> create_dependency_graph_snapshot(const VcpkgCmdArguments& args,
const ActionPlan& action_plan)
{
if (args.github_ref.has_value() && args.github_sha.has_value() && args.github_job.has_value() &&
args.github_workflow.has_value() && args.github_run_id.has_value())
const auto github_ref = args.github_ref.get();
const auto github_sha = args.github_sha.get();
const auto github_job = args.github_job.get();
const auto github_workflow = args.github_workflow.get();
const auto github_run_id = args.github_run_id.get();
if (github_ref && github_sha && github_job && github_workflow && github_run_id)
{
Json::Object detector;
detector.insert(JsonIdName, Json::Value::string("vcpkg"));
detector.insert(JsonIdUrl, Json::Value::string("https://github.com/microsoft/vcpkg"));
detector.insert(JsonIdVersion, Json::Value::string("1.0.0"));

Json::Object job;
job.insert(JsonIdId, Json::Value::string(*args.github_run_id.get()));
job.insert(JsonIdCorrelator,
Json::Value::string(*args.github_workflow.get() + "-" + *args.github_job.get()));
job.insert(JsonIdId, Json::Value::string(*github_run_id));
job.insert(JsonIdCorrelator, Json::Value::string(fmt::format("{}-{}", *github_workflow, *github_run_id)));

Json::Object snapshot;
snapshot.insert(JsonIdJob, job);
snapshot.insert(JsonIdVersion, Json::Value::integer(0));
snapshot.insert(JsonIdSha, Json::Value::string(*args.github_sha.get()));
snapshot.insert(JsonIdRef, Json::Value::string(*args.github_ref.get()));
snapshot.insert(JsonIdSha, Json::Value::string(*github_sha));
snapshot.insert(JsonIdRef, Json::Value::string(*github_ref));
snapshot.insert(JsonIdScanned, Json::Value::string(CTime::now_string()));
snapshot.insert(JsonIdDetector, detector);

Expand All @@ -77,44 +80,45 @@ namespace vcpkg
std::unordered_map<std::string, std::string> map;
for (auto&& action : action_plan.install_actions)
{
if (!action.source_control_file_and_location.has_value())
const auto scfl = action.source_control_file_and_location.get();
if (!scfl)
{
return nullopt;
}
const auto& scf = *action.source_control_file_and_location.get();
auto version = scf.to_version().to_string();
auto s = action.spec.to_string();
auto pkg_url = Strings::concat("pkg:github/vcpkg/", s, "@", version);
map.insert({s, pkg_url});
auto spec = action.spec.to_string();
map.insert(
{spec, fmt::format("pkg:github/vcpkg/{}@{}", spec, scfl->source_control_file->to_version())});
}

Json::Object resolved;
for (auto&& action : action_plan.install_actions)
{
Json::Object resolved_item;
if (map.find(action.spec.to_string()) != map.end())
auto spec = action.spec.to_string();
const auto found = map.find(spec);
if (found != map.end())
{
auto pkg_url = map.at(action.spec.to_string());
const auto& pkg_url = found->second;
resolved_item.insert(JsonIdPackageUnderscoreUrl, pkg_url);
resolved_item.insert(JsonIdRelationship, Json::Value::string(JsonIdDirect));
Json::Array deps_list;
for (auto&& dep : action.package_dependencies)
{
if (map.find(dep.to_string()) != map.end())
const auto found_dep = map.find(dep.to_string());
if (found_dep != map.end())
{
auto dep_pkg_url = map.at(dep.to_string());
deps_list.push_back(dep_pkg_url);
deps_list.push_back(found_dep->second);
}
}
resolved_item.insert(JsonIdDependencies, deps_list);
resolved.insert(pkg_url, resolved_item);
}
}

manifest.insert(JsonIdResolved, resolved);
Json::Object manifests;
manifests.insert(JsonIdVcpkgDotJson, manifest);
snapshot.insert(JsonIdManifests, manifests);

Debug::print(Json::stringify(snapshot));
return snapshot;
}
Expand Down
30 changes: 16 additions & 14 deletions src/vcpkg/configuration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -441,20 +441,20 @@ namespace
continue;
}

if (!el.second.is_object())
auto maybe_demand_obj = el.second.maybe_object();
if (!maybe_demand_obj)
{
r.add_generic_error(type_name(), msg::format(msgJsonFieldNotObject, msg::json_field = key));
continue;
}

const auto& demand_obj = el.second.object(VCPKG_LINE_INFO);
if (demand_obj.contains(JsonIdDemands))
if (maybe_demand_obj->contains(JsonIdDemands))
{
r.add_generic_error(type_name(),
msg::format(msgConfigurationNestedDemands, msg::json_field = el.first));
}

auto maybe_demand = r.visit(demand_obj, CeMetadataDeserializer::instance);
auto maybe_demand = r.visit(*maybe_demand_obj, CeMetadataDeserializer::instance);
if (maybe_demand.has_value())
{
ret.insert_or_replace(key, maybe_demand.value_or_exit(VCPKG_LINE_INFO));
Expand Down Expand Up @@ -602,13 +602,14 @@ namespace
auto serialize_demands = [](const Json::Object& obj, Json::Object& put_into) {
if (auto demands = obj.get(JsonIdDemands))
{
if (!demands->is_object())
auto demands_obj = demands->maybe_object();
if (!demands_obj)
{
return;
}

Json::Object serialized_demands;
for (const auto& el : demands->object(VCPKG_LINE_INFO))
for (const auto& el : *demands_obj)
{
auto key = el.first;
if (Strings::starts_with(key, "$"))
Expand All @@ -617,10 +618,10 @@ namespace
continue;
}

if (el.second.is_object())
if (auto demand_obj = el.second.maybe_object())
{
auto& inserted = serialized_demands.insert_or_replace(key, Json::Object{});
serialize_ce_metadata(el.second.object(VCPKG_LINE_INFO), inserted);
serialize_ce_metadata(*demand_obj, inserted);
}
}
put_into.insert_or_replace(JsonIdDemands, serialized_demands);
Expand Down Expand Up @@ -667,12 +668,13 @@ namespace

if (el.first == JsonIdDemands)
{
if (!el.second.is_object())
auto maybe_demands_object = el.second.maybe_object();
if (!maybe_demands_object)
{
continue;
}

for (const auto& demand : el.second.object(VCPKG_LINE_INFO))
for (const auto& demand : *maybe_demands_object)
{
if (Strings::starts_with(demand.first, "$"))
{
Expand Down Expand Up @@ -840,13 +842,13 @@ namespace vcpkg
}

auto conf_value = std::move(conf).value(VCPKG_LINE_INFO).value;
if (!conf_value.is_object())
if (auto conf_value_object = conf_value.maybe_object())
{
messageSink.println(msgFailedToParseNoTopLevelObj, msg::path = origin);
return nullopt;
return parse_configuration(std::move(*conf_value_object), origin, messageSink);
}

return parse_configuration(std::move(conf_value).object(VCPKG_LINE_INFO), origin, messageSink);
messageSink.println(msgFailedToParseNoTopLevelObj, msg::path = origin);
return nullopt;
}

Optional<Configuration> parse_configuration(const Json::Object& obj, StringView origin, MessageSink& messageSink)
Expand Down
26 changes: 14 additions & 12 deletions src/vcpkg/configure-environment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,30 +42,32 @@ namespace
return;
}

auto acquired_artifacts = pparsed->get(JsonIdAcquiredArtifacts);
if (acquired_artifacts)
if (auto acquired_artifacts = pparsed->get(JsonIdAcquiredArtifacts))
{
if (acquired_artifacts->is_string())
if (auto maybe_acquired_string = acquired_artifacts->maybe_string())
{
get_global_metrics_collector().track_string(StringMetric::AcquiredArtifacts,
acquired_artifacts->string(VCPKG_LINE_INFO));
get_global_metrics_collector().track_string(StringMetric::AcquiredArtifacts, *maybe_acquired_string);
}
else
{
Debug::println("Acquired artifacts was not a string.");
}
Debug::println("Acquired artifacts was not a string.");
}
else
{
Debug::println("No artifacts acquired.");
}

auto activated_artifacts = pparsed->get(JsonIdActivatedArtifacts);
if (activated_artifacts)
if (auto activated_artifacts = pparsed->get(JsonIdActivatedArtifacts))
{
if (activated_artifacts->is_string())
if (auto maybe_activated_string = activated_artifacts->maybe_string())
{
get_global_metrics_collector().track_string(StringMetric::ActivatedArtifacts, *maybe_activated_string);
}
else
{
get_global_metrics_collector().track_string(StringMetric::ActivatedArtifacts,
activated_artifacts->string(VCPKG_LINE_INFO));
Debug::println("Activated artifacts was not a string.");
}
Debug::println("Activated artifacts was not a string.");
}
else
{
Expand Down
4 changes: 2 additions & 2 deletions src/vcpkg/sourceparagraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1194,9 +1194,9 @@ namespace vcpkg

if (auto configuration = obj.get(JsonIdVcpkgConfiguration))
{
if (configuration->is_object())
if (auto configuration_object = configuration->maybe_object())
{
spgh.vcpkg_configuration.emplace(configuration->object(VCPKG_LINE_INFO));
spgh.vcpkg_configuration.emplace(*configuration_object);
}
else
{
Expand Down
Loading
Loading