ExpectedT factory class
MODIFY
include/LineInfo.h
include/LineInfo.h
#pragma once
+#include <string>
+
namespace vcpkg
{
struct LineInfo

MODIFY
include/PackageSpec.h
include/PackageSpec.h
@@ -7,9 +7,11 @@ namespace vcpkg
{
struct PackageSpec
{
- static Expected<PackageSpec> from_string(const std::string& spec_as_string, const Triplet& default_triplet);
+ static ExpectedT<PackageSpec, PackageSpecParseResult> from_string(const std::string& spec_as_string,
+ const Triplet& default_triplet);
static std::string to_string(const std::string& name, const Triplet& triplet);
- static Expected<PackageSpec> from_name_and_triplet(const std::string& name, const Triplet& triplet);
+ static ExpectedT<PackageSpec, PackageSpecParseResult> from_name_and_triplet(const std::string& name,
+ const Triplet& triplet);
const std::string& name() const;

MODIFY
include/PackageSpecParseResult.h
include/PackageSpecParseResult.h
#pragma once
-#include <system_error>
+
+#include "vcpkg_expected.h"
namespace vcpkg
{
@@ -10,27 +11,21 @@ namespace vcpkg
INVALID_CHARACTERS
};
- struct PackageSpecParseResultCategoryImpl final : std::error_category
- {
- virtual const char* name() const noexcept override;
+ CStringView to_string(PackageSpecParseResult ev) noexcept;
- virtual std::string message(int ev) const noexcept override;
- };
-
- const std::error_category& package_spec_parse_result_category();
+ template<>
+ struct ErrorHolder<PackageSpecParseResult>
+ {
+ ErrorHolder() : m_err(PackageSpecParseResult::SUCCESS) {}
+ ErrorHolder(PackageSpecParseResult err) : m_err(err) {}
- std::error_code make_error_code(PackageSpecParseResult e);
+ constexpr bool has_error() const { return m_err != PackageSpecParseResult::SUCCESS; }
- PackageSpecParseResult to_package_spec_parse_result(int i);
+ PackageSpecParseResult error() const { return m_err; }
- PackageSpecParseResult to_package_spec_parse_result(std::error_code ec);
-}
+ CStringView to_string() const { return vcpkg::to_string(m_err); }
-// Enable implicit conversion to std::error_code
-namespace std
-{
- template<>
- struct is_error_code_enum<vcpkg::PackageSpecParseResult> : ::std::true_type
- {
+ private:
+ PackageSpecParseResult m_err;
};
}

MODIFY
include/Paragraphs.h
include/Paragraphs.h
@@ -16,7 +16,8 @@ namespace vcpkg::Paragraphs
Expected<ParagraphDataMap> parse_single_paragraph(const std::string& str);
Expected<std::vector<ParagraphDataMap>> parse_paragraphs(const std::string& str);
- Expected<SourceParagraph> try_load_port(const Files::Filesystem& fs, const fs::path& control_path);
+ ExpectedT<SourceParagraph, ParseControlErrorInfo> try_load_port(const Files::Filesystem& fs,
+ const fs::path& control_path);
Expected<BinaryParagraph> try_load_cached_package(const VcpkgPaths& paths, const PackageSpec& spec);

MODIFY
include/SourceParagraph.h
include/SourceParagraph.h
#pragma once
+#include "vcpkg_expected.h"
#include <unordered_map>
#include <vector>
@@ -15,14 +16,23 @@ namespace vcpkg
const std::string& to_string(const Dependency& dep);
+ struct ParseControlErrorInfo
+ {
+ std::string name;
+ std::string remaining_fields_as_string;
+ std::string valid_fields_as_string;
+ std::error_code error;
+ };
+
/// <summary>
/// Port metadata (CONTROL file)
/// </summary>
struct SourceParagraph
{
- SourceParagraph();
+ static ExpectedT<SourceParagraph, ParseControlErrorInfo> parse_control_file(
+ std::unordered_map<std::string, std::string> fields);
- explicit SourceParagraph(std::unordered_map<std::string, std::string> fields);
+ SourceParagraph();
std::string name;
std::string version;
@@ -31,6 +41,9 @@ namespace vcpkg
std::vector<Dependency> depends;
};
+ void print_error_message(const ParseControlErrorInfo& info);
+ void print_error_message(std::vector<ParseControlErrorInfo> error_info_list);
+
std::vector<std::string> filter_dependencies(const std::vector<Dependency>& deps, const Triplet& t);
std::vector<Dependency> expand_qualified_dependencies(const std::vector<std::string>& depends);

MODIFY
include/vcpkg_expected.h
include/vcpkg_expected.h
namespace vcpkg
{
- template<class T>
- class Expected
+ template<class Err>
+ struct ErrorHolder
{
- public:
- // Constructors are intentionally implicit
- Expected(const std::error_code& ec) : m_error_code(ec), m_t() {}
+ ErrorHolder() : m_is_error(false) {}
+ ErrorHolder(const Err& err) : m_is_error(true), m_err(err) {}
+ ErrorHolder(Err&& err) : m_is_error(true), m_err(std::move(err)) {}
+
+ constexpr bool has_error() const { return m_is_error; }
+
+ const Err& error() const { return m_err; }
+ Err& error() { return m_err; }
+
+ CStringView to_string() const { return "value was error"; }
+
+ private:
+ bool m_is_error;
+ Err m_err;
+ };
+
+ template<>
+ struct ErrorHolder<std::error_code>
+ {
+ ErrorHolder() = default;
+ ErrorHolder(const std::error_code& err) : m_err(err) {}
+
+ constexpr bool has_error() const { return bool(m_err); }
- Expected(std::errc ec) : Expected(std::make_error_code(ec)) {}
+ const std::error_code& error() const { return m_err; }
+ std::error_code& error() { return m_err; }
- Expected(const T& t) : m_error_code(), m_t(t) {}
+ CStringView to_string() const { return "value was error"; }
- Expected(T&& t) : m_error_code(), m_t(std::move(t)) {}
+ private:
+ std::error_code m_err;
+ };
+
+ template<class T, class S>
+ class ExpectedT
+ {
+ public:
+ constexpr ExpectedT() = default;
+
+ // Constructors are intentionally implicit
+
+ ExpectedT(const S& s) : m_s(s) {}
+ ExpectedT(S&& s) : m_s(std::move(s)) {}
- Expected() : Expected(std::error_code(), T()) {}
+ ExpectedT(const T& t) : m_t(t) {}
+ ExpectedT(T&& t) : m_t(std::move(t)) {}
- Expected(const Expected&) = default;
- Expected(Expected&&) = default;
- Expected& operator=(const Expected&) = default;
- Expected& operator=(Expected&&) = default;
+ ExpectedT(const ExpectedT&) = default;
+ ExpectedT(ExpectedT&&) = default;
+ ExpectedT& operator=(const ExpectedT&) = default;
+ ExpectedT& operator=(ExpectedT&&) = default;
- std::error_code error_code() const { return this->m_error_code; }
+ explicit constexpr operator bool() const noexcept { return !m_s.has_error(); }
+ constexpr bool has_value() const noexcept { return !m_s.has_error(); }
T&& value_or_exit(const LineInfo& line_info) &&
{
@@ -39,9 +75,13 @@ namespace vcpkg
return this->m_t;
}
+ const S& error() const & { return this->m_s.error(); }
+
+ S&& error() && { return std::move(this->m_s.error()); }
+
const T* get() const
{
- if (m_error_code)
+ if (!this->has_value())
{
return nullptr;
}
@@ -50,7 +90,7 @@ namespace vcpkg
T* get()
{
- if (m_error_code)
+ if (!this->has_value())
{
return nullptr;
}
@@ -60,10 +100,13 @@ namespace vcpkg
private:
void exit_if_error(const LineInfo& line_info) const
{
- Checks::check_exit(line_info, !this->m_error_code, this->m_error_code.message());
+ Checks::check_exit(line_info, !m_s.has_error(), m_s.to_string());
}
- std::error_code m_error_code;
+ ErrorHolder<S> m_s;
T m_t;
};
+
+ template<class T>
+ using Expected = ExpectedT<T, std::error_code>;
}

MODIFY
src/PackageSpec.cpp
src/PackageSpec.cpp
@@ -7,7 +7,8 @@ namespace vcpkg
{
static bool is_valid_package_spec_char(char c) { return (c == '-') || isdigit(c) || (isalpha(c) && islower(c)); }
- Expected<PackageSpec> PackageSpec::from_string(const std::string& spec_as_string, const Triplet& default_triplet)
+ ExpectedT<PackageSpec, PackageSpecParseResult> PackageSpec::from_string(const std::string& spec_as_string,
+ const Triplet& default_triplet)
{
auto pos = spec_as_string.find(':');
if (pos == std::string::npos)
@@ -18,7 +19,7 @@ namespace vcpkg
auto pos2 = spec_as_string.find(':', pos + 1);
if (pos2 != std::string::npos)
{
- return std::error_code(PackageSpecParseResult::TOO_MANY_COLONS);
+ return PackageSpecParseResult::TOO_MANY_COLONS;
}
const std::string name = spec_as_string.substr(0, pos);
@@ -26,11 +27,12 @@ namespace vcpkg
return from_name_and_triplet(name, triplet);
}
- Expected<PackageSpec> PackageSpec::from_name_and_triplet(const std::string& name, const Triplet& triplet)
+ ExpectedT<PackageSpec, PackageSpecParseResult> PackageSpec::from_name_and_triplet(const std::string& name,
+ const Triplet& triplet)
{
if (Util::find_if_not(name, is_valid_package_spec_char) != name.end())
{
- return std::error_code(PackageSpecParseResult::INVALID_CHARACTERS);
+ return PackageSpecParseResult::INVALID_CHARACTERS;
}
PackageSpec p;

MODIFY
src/PackageSpecParseResult.cpp
src/PackageSpecParseResult.cpp
namespace vcpkg
{
- const char* PackageSpecParseResultCategoryImpl::name() const noexcept { return "PackageSpecParseResult"; }
-
- std::string PackageSpecParseResultCategoryImpl::message(int ev) const noexcept
+ CStringView to_string(PackageSpecParseResult ev) noexcept
{
- switch (static_cast<PackageSpecParseResult>(ev))
+ switch (ev)
{
case PackageSpecParseResult::SUCCESS: return "OK";
case PackageSpecParseResult::TOO_MANY_COLONS: return "Too many colons";
@@ -19,22 +17,4 @@ namespace vcpkg
default: Checks::unreachable(VCPKG_LINE_INFO);
}
}
-
- const std::error_category& package_spec_parse_result_category()
- {
- static PackageSpecParseResultCategoryImpl instance;
- return instance;
- }
-
- std::error_code make_error_code(PackageSpecParseResult e)
- {
- return std::error_code(static_cast<int>(e), package_spec_parse_result_category());
- }
-
- PackageSpecParseResult to_package_spec_parse_result(int i) { return static_cast<PackageSpecParseResult>(i); }
-
- PackageSpecParseResult to_package_spec_parse_result(std::error_code ec)
- {
- return to_package_spec_parse_result(ec.value());
- }
}

MODIFY
src/Paragraphs.cpp
src/Paragraphs.cpp
@@ -168,7 +168,7 @@ namespace vcpkg::Paragraphs
return parse_single_paragraph(*spgh);
}
- return contents.error_code();
+ return contents.error();
}
Expected<std::vector<std::unordered_map<std::string, std::string>>> get_paragraphs(const Files::Filesystem& fs,
@@ -180,7 +180,7 @@ namespace vcpkg::Paragraphs
return parse_paragraphs(*spgh);
}
- return contents.error_code();
+ return contents.error();
}
Expected<std::unordered_map<std::string, std::string>> parse_single_paragraph(const std::string& str)
@@ -201,15 +201,16 @@ namespace vcpkg::Paragraphs
return Parser(str.c_str(), str.c_str() + str.size()).get_paragraphs();
}
- Expected<SourceParagraph> try_load_port(const Files::Filesystem& fs, const fs::path& path)
+ ExpectedT<SourceParagraph, ParseControlErrorInfo> try_load_port(const Files::Filesystem& fs, const fs::path& path)
{
+ ParseControlErrorInfo error_info;
Expected<std::unordered_map<std::string, std::string>> pghs = get_single_paragraph(fs, path / "CONTROL");
if (auto p = pghs.get())
{
- return SourceParagraph(*p);
+ return SourceParagraph::parse_control_file(*p);
}
-
- return pghs.error_code();
+ error_info.error = pghs.error();
+ return error_info;
}
Expected<BinaryParagraph> try_load_cached_package(const VcpkgPaths& paths, const PackageSpec& spec)
@@ -222,20 +223,26 @@ namespace vcpkg::Paragraphs
return BinaryParagraph(*p);
}
- return pghs.error_code();
+ return pghs.error();
}
std::vector<SourceParagraph> load_all_ports(const Files::Filesystem& fs, const fs::path& ports_dir)
{
std::vector<SourceParagraph> output;
+ std::vector<ParseControlErrorInfo> port_errors;
for (auto&& path : fs.get_files_non_recursive(ports_dir))
{
- Expected<SourceParagraph> source_paragraph = try_load_port(fs, path);
+ ExpectedT<SourceParagraph, ParseControlErrorInfo> source_paragraph = try_load_port(fs, path);
if (auto srcpgh = source_paragraph.get())
{
output.emplace_back(std::move(*srcpgh));
}
+ else
+ {
+ port_errors.emplace_back(source_paragraph.error());
+ }
}
+ print_error_message(port_errors);
return output;
}

MODIFY
src/SourceParagraph.cpp
src/SourceParagraph.cpp
#include "vcpkg_Checks.h"
#include "vcpkg_Maps.h"
#include "vcpkg_System.h"
+#include "vcpkg_expected.h"
+
#include "vcpkglib_helpers.h"
namespace vcpkg
@@ -37,15 +39,41 @@ namespace vcpkg
SourceParagraph::SourceParagraph() = default;
- SourceParagraph::SourceParagraph(std::unordered_map<std::string, std::string> fields)
+ void print_error_message(const ParseControlErrorInfo& info)
{
- this->name = details::remove_required_field(&fields, SourceParagraphRequiredField::SOURCE);
- this->version = details::remove_required_field(&fields, SourceParagraphRequiredField::VERSION);
- this->description = details::remove_optional_field(&fields, SourceParagraphOptionalField::DESCRIPTION);
- this->maintainer = details::remove_optional_field(&fields, SourceParagraphOptionalField::MAINTAINER);
+ System::println(
+ System::Color::error, "Error: There are invalid fields in the Source Paragraph of %s", info.name);
+ System::println("The following fields were not expected:\n\n %s\n\n", info.remaining_fields_as_string);
+ System::println("This is the list of valid fields (case-sensitive): \n\n %s\n", info.valid_fields_as_string);
+ System::println("Different source may be available for vcpkg. Use .\\bootstrap-vcpkg.bat to update.\n");
+ }
+
+ void print_error_message(std::vector<ParseControlErrorInfo> error_info_list)
+ {
+ for (ParseControlErrorInfo error_info : error_info_list)
+ {
+ System::println(
+ System::Color::error, "Error: There are invalid fields in the Source Paragraph of %s", error_info.name);
+ System::println("The following fields were not expected:\n\n %s\n\n",
+ error_info.remaining_fields_as_string);
+ }
+
+ System::println("This is the list of valid fields (case-sensitive): \n\n %s\n",
+ error_info_list.front().valid_fields_as_string);
+ System::println("Different source may be available for vcpkg. Use .\\bootstrap-vcpkg.bat to update.\n");
+ }
+
+ ExpectedT<SourceParagraph, ParseControlErrorInfo> SourceParagraph::parse_control_file(
+ std::unordered_map<std::string, std::string> fields)
+ {
+ SourceParagraph sparagraph;
+ sparagraph.name = details::remove_required_field(&fields, SourceParagraphRequiredField::SOURCE);
+ sparagraph.version = details::remove_required_field(&fields, SourceParagraphRequiredField::VERSION);
+ sparagraph.description = details::remove_optional_field(&fields, SourceParagraphOptionalField::DESCRIPTION);
+ sparagraph.maintainer = details::remove_optional_field(&fields, SourceParagraphOptionalField::MAINTAINER);
std::string deps = details::remove_optional_field(&fields, SourceParagraphOptionalField::BUILD_DEPENDS);
- this->depends = expand_qualified_dependencies(parse_depends(deps));
+ sparagraph.depends = expand_qualified_dependencies(parse_depends(deps));
if (!fields.empty())
{
@@ -55,12 +83,9 @@ namespace vcpkg
const std::string remaining_fields_as_string = Strings::join("\n ", remaining_fields);
const std::string valid_fields_as_string = Strings::join("\n ", valid_fields);
- System::println(
- System::Color::error, "Error: There are invalid fields in the Source Paragraph of %s", this->name);
- System::println("The following fields were not expected:\n\n %s\n\n", remaining_fields_as_string);
- System::println("This is the list of valid fields (case-sensitive): \n\n %s\n", valid_fields_as_string);
- Checks::exit_fail(VCPKG_LINE_INFO);
+ return ParseControlErrorInfo{sparagraph.name, remaining_fields_as_string, valid_fields_as_string};
}
+ return sparagraph;
}
std::vector<Dependency> vcpkg::expand_qualified_dependencies(const std::vector<std::string>& depends)

MODIFY
src/commands_build.cpp
src/commands_build.cpp
@@ -33,13 +33,16 @@ namespace vcpkg::Commands::BuildCommand
Checks::exit_success(VCPKG_LINE_INFO);
}
- const Expected<SourceParagraph> maybe_spgh = Paragraphs::try_load_port(paths.get_filesystem(), port_dir);
- Checks::check_exit(VCPKG_LINE_INFO,
- !maybe_spgh.error_code(),
- "Could not find package %s: %s",
- spec,
- maybe_spgh.error_code().message());
- const SourceParagraph& spgh = *maybe_spgh.get();
+ const ExpectedT<SourceParagraph, ParseControlErrorInfo> maybe_spgh =
+ Paragraphs::try_load_port(paths.get_filesystem(), port_dir);
+ // why do we add a const here
+ if (!maybe_spgh)
+ {
+ print_error_message(maybe_spgh.error());
+ Checks::exit_fail(VCPKG_LINE_INFO);
+ }
+
+ const SourceParagraph& spgh = maybe_spgh.value_or_exit(VCPKG_LINE_INFO);
Checks::check_exit(VCPKG_LINE_INFO,
spec.name() == spgh.name,
"The Name: field inside the CONTROL does not match the port directory: '%s' != '%s'",

MODIFY
src/tests_paragraph.cpp
src/tests_paragraph.cpp
@@ -25,7 +25,10 @@ namespace UnitTest1
{
TEST_METHOD(SourceParagraph_Construct_Minimum)
{
- vcpkg::SourceParagraph pgh({{"Source", "zlib"}, {"Version", "1.2.8"}});
+ auto m_pgh = vcpkg::SourceParagraph::parse_control_file({{"Source", "zlib"}, {"Version", "1.2.8"}});
+
+ Assert::IsTrue(m_pgh.has_value());
+ auto& pgh = *m_pgh.get();
Assert::AreEqual("zlib", pgh.name.c_str());
Assert::AreEqual("1.2.8", pgh.version.c_str());
@@ -36,11 +39,12 @@ namespace UnitTest1
TEST_METHOD(SourceParagraph_Construct_Maximum)
{
- vcpkg::SourceParagraph pgh({{"Source", "s"},
- {"Version", "v"},
- {"Maintainer", "m"},
- {"Description", "d"},
- {"Build-Depends", "bd"}});
+ auto m_pgh = vcpkg::SourceParagraph::parse_control_file({
+ {"Source", "s"}, {"Version", "v"}, {"Maintainer", "m"}, {"Description", "d"}, {"Build-Depends", "bd"},
+ });
+ Assert::IsTrue(m_pgh.has_value());
+ auto& pgh = *m_pgh.get();
+
Assert::AreEqual("s", pgh.name.c_str());
Assert::AreEqual("v", pgh.version.c_str());
Assert::AreEqual("m", pgh.maintainer.c_str());
@@ -51,7 +55,11 @@ namespace UnitTest1
TEST_METHOD(SourceParagraph_Two_Depends)
{
- vcpkg::SourceParagraph pgh({{"Source", "zlib"}, {"Version", "1.2.8"}, {"Build-Depends", "z, openssl"}});
+ auto m_pgh = vcpkg::SourceParagraph::parse_control_file({
+ {"Source", "zlib"}, {"Version", "1.2.8"}, {"Build-Depends", "z, openssl"},
+ });
+ Assert::IsTrue(m_pgh.has_value());
+ auto& pgh = *m_pgh.get();
Assert::AreEqual(size_t(2), pgh.depends.size());
Assert::AreEqual("z", pgh.depends[0].name.c_str());
@@ -60,8 +68,11 @@ namespace UnitTest1
TEST_METHOD(SourceParagraph_Three_Depends)
{
- vcpkg::SourceParagraph pgh(
- {{"Source", "zlib"}, {"Version", "1.2.8"}, {"Build-Depends", "z, openssl, xyz"}});
+ auto m_pgh = vcpkg::SourceParagraph::parse_control_file({
+ {"Source", "zlib"}, {"Version", "1.2.8"}, {"Build-Depends", "z, openssl, xyz"},
+ });
+ Assert::IsTrue(m_pgh.has_value());
+ auto& pgh = *m_pgh.get();
Assert::AreEqual(size_t(3), pgh.depends.size());
Assert::AreEqual("z", pgh.depends[0].name.c_str());
@@ -71,8 +82,11 @@ namespace UnitTest1
TEST_METHOD(SourceParagraph_Construct_Qualified_Depends)
{
- vcpkg::SourceParagraph pgh(
- {{"Source", "zlib"}, {"Version", "1.2.8"}, {"Build-Depends", "libA [windows], libB [uwp]"}});
+ auto m_pgh = vcpkg::SourceParagraph::parse_control_file({
+ {"Source", "zlib"}, {"Version", "1.2.8"}, {"Build-Depends", "libA [windows], libB [uwp]"},
+ });
+ Assert::IsTrue(m_pgh.has_value());
+ auto& pgh = *m_pgh.get();
Assert::AreEqual("zlib", pgh.name.c_str());
Assert::AreEqual("1.2.8", pgh.version.c_str());
@@ -101,13 +115,15 @@ namespace UnitTest1
TEST_METHOD(BinaryParagraph_Construct_Maximum)
{
- vcpkg::BinaryParagraph pgh({{"Package", "s"},
+ vcpkg::BinaryParagraph pgh({
+ {"Package", "s"},
{"Version", "v"},
{"Architecture", "x86-windows"},
{"Multi-Arch", "same"},
{"Maintainer", "m"},
{"Description", "d"},
- {"Depends", "bd"}});
+ {"Depends", "bd"},
+ });
Assert::AreEqual("s", pgh.spec.name().c_str());
Assert::AreEqual("v", pgh.version.c_str());
Assert::AreEqual("m", pgh.maintainer.c_str());
@@ -327,28 +343,26 @@ namespace UnitTest1
TEST_METHOD(package_spec_parse)
{
- vcpkg::Expected<vcpkg::PackageSpec> spec =
+ vcpkg::ExpectedT<vcpkg::PackageSpec, vcpkg::PackageSpecParseResult> spec =
vcpkg::PackageSpec::from_string("zlib", vcpkg::Triplet::X86_WINDOWS);
- Assert::AreEqual(vcpkg::PackageSpecParseResult::SUCCESS,
- vcpkg::to_package_spec_parse_result(spec.error_code()));
+ Assert::AreEqual(vcpkg::PackageSpecParseResult::SUCCESS, spec.error());
Assert::AreEqual("zlib", spec.get()->name().c_str());
Assert::AreEqual(vcpkg::Triplet::X86_WINDOWS.canonical_name(), spec.get()->triplet().canonical_name());
}
TEST_METHOD(package_spec_parse_with_arch)
{
- vcpkg::Expected<vcpkg::PackageSpec> spec =
+ vcpkg::ExpectedT<vcpkg::PackageSpec, vcpkg::PackageSpecParseResult> spec =
vcpkg::PackageSpec::from_string("zlib:x64-uwp", vcpkg::Triplet::X86_WINDOWS);
- Assert::AreEqual(vcpkg::PackageSpecParseResult::SUCCESS,
- vcpkg::to_package_spec_parse_result(spec.error_code()));
+ Assert::AreEqual(vcpkg::PackageSpecParseResult::SUCCESS, spec.error());
Assert::AreEqual("zlib", spec.get()->name().c_str());
Assert::AreEqual(vcpkg::Triplet::X64_UWP.canonical_name(), spec.get()->triplet().canonical_name());
}
TEST_METHOD(package_spec_parse_with_multiple_colon)
{
- auto ec = vcpkg::PackageSpec::from_string("zlib:x86-uwp:", vcpkg::Triplet::X86_WINDOWS).error_code();
- Assert::AreEqual(vcpkg::PackageSpecParseResult::TOO_MANY_COLONS, vcpkg::to_package_spec_parse_result(ec));
+ auto ec = vcpkg::PackageSpec::from_string("zlib:x86-uwp:", vcpkg::Triplet::X86_WINDOWS).error();
+ Assert::AreEqual(vcpkg::PackageSpecParseResult::TOO_MANY_COLONS, ec);
}
TEST_METHOD(utf8_to_utf16)

MODIFY
src/vcpkg.cpp
src/vcpkg.cpp
@@ -61,10 +61,10 @@ static void inner(const VcpkgCmdArguments& args)
const Expected<VcpkgPaths> expected_paths = VcpkgPaths::create(vcpkg_root_dir);
Checks::check_exit(VCPKG_LINE_INFO,
- !expected_paths.error_code(),
+ !expected_paths.error(),
"Error: Invalid vcpkg root directory %s: %s",
vcpkg_root_dir.string(),
- expected_paths.error_code().message());
+ expected_paths.error().message());
const VcpkgPaths paths = expected_paths.value_or_exit(VCPKG_LINE_INFO);
int exit_code = _wchdir(paths.root.c_str());
Checks::check_exit(VCPKG_LINE_INFO, exit_code == 0, "Changing the working dir failed");

MODIFY
src/vcpkg_Dependencies.cpp
src/vcpkg_Dependencies.cpp
@@ -174,11 +174,14 @@ namespace vcpkg::Dependencies
if (auto bpgh = maybe_bpgh.get())
return InstallPlanAction{spec, {nullopt, *bpgh, nullopt}, request_type};
- Expected<SourceParagraph> maybe_spgh =
+ ExpectedT<SourceParagraph, ParseControlErrorInfo> maybe_spgh =
Paragraphs::try_load_port(paths.get_filesystem(), paths.port_dir(spec));
if (auto spgh = maybe_spgh.get())
return InstallPlanAction{spec, {nullopt, nullopt, *spgh}, request_type};
+ else
+ print_error_message(maybe_spgh.error());
+
Checks::exit_with_message(VCPKG_LINE_INFO, "Could not find package %s", spec);
}
};
@@ -283,11 +286,14 @@ namespace vcpkg::Dependencies
if (auto bpgh = maybe_bpgh.get())
return ExportPlanAction{spec, {nullopt, *bpgh, nullopt}, request_type};
- Expected<SourceParagraph> maybe_spgh =
+ ExpectedT<SourceParagraph, ParseControlErrorInfo> maybe_spgh =
Paragraphs::try_load_port(paths.get_filesystem(), paths.port_dir(spec));
if (auto spgh = maybe_spgh.get())
return ExportPlanAction{spec, {nullopt, nullopt, *spgh}, request_type};
+ else
+ print_error_message(maybe_spgh.error());
+
Checks::exit_with_message(VCPKG_LINE_INFO, "Could not find package %s", spec);
}
};

MODIFY
src/vcpkg_Files.cpp
src/vcpkg_Files.cpp
@@ -15,7 +15,7 @@ namespace vcpkg::Files
std::fstream file_stream(file_path, std::ios_base::in | std::ios_base::binary);
if (file_stream.fail())
{
- return std::errc::no_such_file_or_directory;
+ return std::make_error_code(std::errc::no_such_file_or_directory);
}
file_stream.seekg(0, file_stream.end);
@@ -24,7 +24,7 @@ namespace vcpkg::Files
if (length > SIZE_MAX)
{
- return std::errc::file_too_large;
+ return std::make_error_code(std::errc::file_too_large);
}
std::string output;
@@ -39,7 +39,7 @@ namespace vcpkg::Files
std::fstream file_stream(file_path, std::ios_base::in | std::ios_base::binary);
if (file_stream.fail())
{
- return std::errc::no_such_file_or_directory;
+ return std::make_error_code(std::errc::no_such_file_or_directory);
}
std::vector<std::string> output;

MODIFY
src/vcpkg_Input.cpp
src/vcpkg_Input.cpp
@@ -12,14 +12,14 @@ namespace vcpkg::Input
CStringView example_text)
{
const std::string as_lowercase = Strings::ascii_to_lowercase(package_spec_as_string);
- Expected<PackageSpec> expected_spec = PackageSpec::from_string(as_lowercase, default_triplet);
+ auto expected_spec = PackageSpec::from_string(as_lowercase, default_triplet);
if (auto spec = expected_spec.get())
{
return *spec;
}
// Intentionally show the lowercased string
- System::println(System::Color::error, "Error: %s: %s", expected_spec.error_code().message(), as_lowercase);
+ System::println(System::Color::error, "Error: %s: %s", vcpkg::to_string(expected_spec.error()), as_lowercase);
System::print(example_text);
Checks::exit_fail(VCPKG_LINE_INFO);
}

ExpectedT factory class