blob: 8732c034271cb29a9561139f69c386d5e65aae39 [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "peridot/lib/module_manifest/module_facet_reader_impl.h"
#include "lib/cmx_facet_parser/cmx_facet_parser.h"
#include "lib/component/cpp/startup_context.h"
#include "lib/fsl/io/fd.h"
#include "lib/json/json_parser.h"
#include "lib/pkg_url/fuchsia_pkg_url.h"
#include "lib/pkg_url/url_resolver.h"
#include "peridot/lib/fidl/json_xdr.h"
#include "peridot/lib/module_manifest/module_manifest_xdr.h"
namespace modular {
namespace {
constexpr char kModuleFacetName[] = "fuchsia.module";
} // namespace
ModuleFacetReaderImpl::ModuleFacetReaderImpl(fuchsia::sys::LoaderPtr loader)
: loader_(std::move(loader)) {}
ModuleFacetReaderImpl::~ModuleFacetReaderImpl() {}
void ModuleFacetReaderImpl::GetModuleManifest(
const std::string& module_url, GetModuleManifestCallback callback) {
auto canonical_url = component::CanonicalizeURL(module_url);
loader_->LoadUrl(canonical_url, [canonical_url,
callback](fuchsia::sys::PackagePtr package) {
if (!package) {
FXL_LOG(ERROR) << "Could not resolve URL: " << canonical_url;
callback({});
return;
}
fxl::UniqueFD fd =
fsl::OpenChannelAsFileDescriptor(std::move(package->directory));
component::FuchsiaPkgUrl pkg_url;
std::string cmx_path;
if (pkg_url.Parse(package->resolved_url)) {
if (!pkg_url.resource_path().empty()) {
// If the url has a resource, assume that's the cmx.
cmx_path = pkg_url.resource_path();
} else {
// It's possible the url does not have a resource, in which case either
// the cmx exists at meta/<package_name.cmx> or it does not exist.
cmx_path = pkg_url.GetDefaultComponentCmxPath();
}
} else {
FXL_LOG(ERROR) << "Could not parse package URL: "
<< package->resolved_url;
callback({});
}
component::CmxFacetParser facet_parser;
json::JSONParser json_parser;
if (!facet_parser.ParseFromFileAt(fd.get(), cmx_path, &json_parser)) {
FXL_LOG(ERROR) << "Could not parse CMX manifest " << cmx_path << ": "
<< json_parser.error_str();
callback({});
return;
}
const auto& mod_facet = facet_parser.GetSection(kModuleFacetName);
if (mod_facet.IsNull()) {
FXL_LOG(INFO) << "No module facet declared for module="
<< package->resolved_url;
callback({});
return;
}
fuchsia::modular::ModuleManifestPtr module_manifest;
auto mod_facet_str = JsonValueToString(mod_facet);
if (!XdrRead(mod_facet_str, &module_manifest, XdrModuleManifest)) {
FXL_LOG(WARNING) << "Unable to parse manifest module facet for "
<< package->resolved_url << ": " << mod_facet_str;
callback({});
return;
}
// TODO(MF-94): Deprecate ModuleManfiest.binary in favour of getting it from
// the cmx manifest.
module_manifest->binary = canonical_url;
callback(std::move(module_manifest));
});
}
} // namespace modular