diff --git a/include/vcpkg/base/message-data.inc.h b/include/vcpkg/base/message-data.inc.h index 4534b5665e..ac8f9acf48 100644 --- a/include/vcpkg/base/message-data.inc.h +++ b/include/vcpkg/base/message-data.inc.h @@ -2500,10 +2500,10 @@ DECLARE_MESSAGE(PortNotInBaseline, DECLARE_MESSAGE(PortsAdded, (msg::count), "", "The following {count} ports were added:") DECLARE_MESSAGE(PortsDiffHelp, (), "", "The argument should be a branch/tag/hash to checkout.") DECLARE_MESSAGE(PortDoesNotExist, (msg::package_name), "", "{package_name} does not exist") -DECLARE_MESSAGE(PortMissingManifest, - (msg::package_name, msg::path), +DECLARE_MESSAGE(PortMissingManifest2, + (msg::package_name), "", - "{package_name} has no vcpkg.json or CONTROL file in {path}") + "{package_name} port manifest missing (no vcpkg.json or CONTROL file)") DECLARE_MESSAGE(PortsNoDiff, (), "", "There were no changes in the ports between the two commits.") DECLARE_MESSAGE(PortsRemoved, (msg::count), "", "The following {count} ports were removed:") DECLARE_MESSAGE(PortsUpdated, (msg::count), "", "The following {count} ports were updated:") diff --git a/include/vcpkg/paragraphs.h b/include/vcpkg/paragraphs.h index 8e12aa80c4..c1f7e69d22 100644 --- a/include/vcpkg/paragraphs.h +++ b/include/vcpkg/paragraphs.h @@ -36,10 +36,13 @@ namespace vcpkg::Paragraphs ExpectedL> try_load_port_required(const ReadOnlyFilesystem& fs, StringView port_name, const Path& port_directory); - ExpectedL> try_load_port_text(const std::string& text, - StringView origin, - bool is_manifest, - MessageSink& warning_sink); + ExpectedL> try_load_project_manifest_text(StringView text, + StringView origin, + MessageSink& warning_sink); + ExpectedL> try_load_port_manifest_text(StringView text, + StringView origin, + MessageSink& warning_sink); + ExpectedL> try_load_control_file_text(StringView text, StringView origin); ExpectedL try_load_cached_package(const ReadOnlyFilesystem& fs, const Path& package_dir, diff --git a/locales/messages.json b/locales/messages.json index 18c764cce4..515adff7cf 100644 --- a/locales/messages.json +++ b/locales/messages.json @@ -1388,8 +1388,8 @@ "_PortDependencyConflict.comment": "An example of {package_name} is zlib.", "PortDoesNotExist": "{package_name} does not exist", "_PortDoesNotExist.comment": "An example of {package_name} is zlib.", - "PortMissingManifest": "{package_name} has no vcpkg.json or CONTROL file in {path}", - "_PortMissingManifest.comment": "An example of {package_name} is zlib. An example of {path} is /foo/bar.", + "PortMissingManifest2": "{package_name} port manifest missing (no vcpkg.json or CONTROL file)", + "_PortMissingManifest2.comment": "An example of {package_name} is zlib.", "PortNotInBaseline": "the baseline does not contain an entry for port {package_name}", "_PortNotInBaseline.comment": "An example of {package_name} is zlib.", "PortSupportsField": "(supports: \"{supports_expression}\")", diff --git a/src/vcpkg/commands.ci-verify-versions.cpp b/src/vcpkg/commands.ci-verify-versions.cpp index d067c95906..acdbb0f9a4 100644 --- a/src/vcpkg/commands.ci-verify-versions.cpp +++ b/src/vcpkg/commands.ci-verify-versions.cpp @@ -70,8 +70,9 @@ namespace if (!maybe_file) continue; const auto& file = maybe_file.value_or_exit(VCPKG_LINE_INFO); - auto maybe_scf = - Paragraphs::try_load_port_text(file, treeish, control_file == "vcpkg.json", stdout_sink); + auto maybe_scf = control_file == "vcpkg.json" + ? Paragraphs::try_load_port_manifest_text(file, treeish, stdout_sink) + : Paragraphs::try_load_control_file_text(file, treeish); auto scf = maybe_scf.get(); if (!scf) { @@ -306,8 +307,10 @@ namespace vcpkg if (!manifest_exists && !control_exists) { msg::write_unlocalized_text_to_stdout(Color::error, fmt::format("FAIL: {}\n", port_name)); - errors.emplace( - msg::format(msgPortMissingManifest, msg::package_name = port_name, msg::path = port_path)); + errors.emplace(LocalizedString::from_raw(port_path) + .append_raw(": ") + .append(msgErrorMessage) + .append(msgPortMissingManifest2, msg::package_name = port_name)); continue; } diff --git a/src/vcpkg/paragraphs.cpp b/src/vcpkg/paragraphs.cpp index 9a23b31861..acb836c2c1 100644 --- a/src/vcpkg/paragraphs.cpp +++ b/src/vcpkg/paragraphs.cpp @@ -15,6 +15,8 @@ #include +using namespace vcpkg; + static std::atomic g_load_ports_stats(0); namespace vcpkg @@ -379,46 +381,45 @@ namespace vcpkg::Paragraphs return fs.exists(maybe_directory / "CONTROL", IgnoreErrors{}) || fs.exists(maybe_directory / "vcpkg.json", IgnoreErrors{}); } +} // namespace vcpkg::Paragraphs - static ExpectedL> try_load_manifest_text(const std::string& text, - StringView origin, - MessageSink& warning_sink) +namespace +{ + ExpectedL> try_load_any_manifest_text( + StringView text, + StringView origin, + MessageSink& warning_sink, + ParseExpected (*do_parse)(StringView, const Json::Object&, MessageSink&)) { - auto res = Json::parse(text, origin); - if (auto val = res.get()) - { - if (val->value.is_object()) - { - return SourceControlFile::parse_port_manifest_object( - origin, val->value.object(VCPKG_LINE_INFO), warning_sink) - .map_error(ToLocalizedString); - } + StatsTimer timer(g_load_ports_stats); + return Json::parse_object(text, origin).then([&](Json::Object&& object) { + return do_parse(origin, std::move(object), warning_sink).map_error(ToLocalizedString); + }); + } +} - return msg::format(msgJsonValueNotObject); - } +namespace vcpkg::Paragraphs +{ + ExpectedL> try_load_project_manifest_text(StringView text, + StringView origin, + MessageSink& warning_sink) + { + return try_load_any_manifest_text(text, origin, warning_sink, SourceControlFile::parse_project_manifest_object); + } - return LocalizedString::from_raw(res.error()->to_string()); + ExpectedL> try_load_port_manifest_text(StringView text, + StringView origin, + MessageSink& warning_sink) + { + return try_load_any_manifest_text(text, origin, warning_sink, SourceControlFile::parse_port_manifest_object); } - ExpectedL> try_load_port_text(const std::string& text, - StringView origin, - bool is_manifest, - MessageSink& warning_sink) + ExpectedL> try_load_control_file_text(StringView text, StringView origin) { StatsTimer timer(g_load_ports_stats); - - if (is_manifest) - { - return try_load_manifest_text(text, origin, warning_sink); - } - - auto pghs = parse_paragraphs(StringView{text}, origin); - if (auto vector_pghs = pghs.get()) - { - return SourceControlFile::parse_control_file(origin, std::move(*vector_pghs)).map_error(ToLocalizedString); - } - - return std::move(pghs).error(); + return parse_paragraphs(text, origin).then([&](std::vector&& vector_pghs) { + return SourceControlFile::parse_control_file(origin, std::move(vector_pghs)).map_error(ToLocalizedString); + }); } ExpectedL> try_load_port(const ReadOnlyFilesystem& fs, @@ -431,39 +432,49 @@ namespace vcpkg::Paragraphs const auto control_path = port_directory / "CONTROL"; std::error_code ec; auto manifest_contents = fs.read_contents(manifest_path, ec); - if (ec) + if (!ec) { - const auto exists = ec != std::errc::no_such_file_or_directory; - if (exists) - { - return msg::format_error(msgFailedToParseManifest, msg::path = manifest_path) - .append_raw("\n") - .append(format_filesystem_call_error(ec, "read_contents", {manifest_path})); - } - if (fs.exists(control_path, IgnoreErrors{})) { - return get_paragraphs(fs, control_path).then([&](std::vector&& vector_pghs) { - return SourceControlFile::parse_control_file(control_path, std::move(vector_pghs)) - .map_error(ToLocalizedString); - }); + return msg::format_error(msgManifestConflict, msg::path = port_directory); } - if (fs.exists(port_directory, IgnoreErrors{})) - { - return msg::format_error( - msgPortMissingManifest, msg::package_name = port_name, msg::path = port_directory); - } + return try_load_port_manifest_text(manifest_contents, manifest_path, stdout_sink); + } + + auto manifest_exists = ec != std::errc::no_such_file_or_directory; + if (manifest_exists) + { + return msg::format_error(msgFailedToParseManifest, msg::path = manifest_path) + .append_raw("\n") + .append(format_filesystem_call_error(ec, "read_contents", {manifest_path})); + } - return std::unique_ptr(); + auto control_contents = fs.read_contents(control_path, ec); + if (!ec) + { + return try_load_control_file_text(control_contents, control_path); + } + + if (ec != std::errc::no_such_file_or_directory) + { + return LocalizedString::from_raw(port_directory) + .append_raw(": ") + .append(format_filesystem_call_error(ec, "read_contents", {control_path})); } - if (fs.exists(control_path, IgnoreErrors{})) + if (fs.exists(port_directory, IgnoreErrors{})) { - return msg::format_error(msgManifestConflict, msg::path = port_directory); + return LocalizedString::from_raw(port_directory) + .append_raw(": ") + .append(msgErrorMessage) + .append(msgPortMissingManifest2, msg::package_name = port_name); } - return try_load_manifest_text(manifest_contents, manifest_path, stdout_sink); + return LocalizedString::from_raw(port_directory) + .append_raw(": ") + .append(msgErrorMessage) + .append(msgPortDoesNotExist, msg::package_name = port_name); } ExpectedL> try_load_port_required(const ReadOnlyFilesystem& fs,