mirror of
https://github.com/microsoft/vcpkg.git
synced 2024-11-29 02:39:00 +08:00
ExpectedT factory class
This commit is contained in:
parent
7b4d83c444
commit
264cd050e6
@ -1,5 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace vcpkg
|
namespace vcpkg
|
||||||
{
|
{
|
||||||
struct LineInfo
|
struct LineInfo
|
||||||
|
@ -7,9 +7,11 @@ namespace vcpkg
|
|||||||
{
|
{
|
||||||
struct PackageSpec
|
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 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;
|
const std::string& name() const;
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <system_error>
|
|
||||||
|
#include "vcpkg_expected.h"
|
||||||
|
|
||||||
namespace vcpkg
|
namespace vcpkg
|
||||||
{
|
{
|
||||||
@ -10,27 +11,21 @@ namespace vcpkg
|
|||||||
INVALID_CHARACTERS
|
INVALID_CHARACTERS
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PackageSpecParseResultCategoryImpl final : std::error_category
|
CStringView to_string(PackageSpecParseResult ev) noexcept;
|
||||||
{
|
|
||||||
virtual const char* name() const noexcept override;
|
|
||||||
|
|
||||||
virtual std::string message(int ev) const noexcept override;
|
|
||||||
};
|
|
||||||
|
|
||||||
const std::error_category& package_spec_parse_result_category();
|
|
||||||
|
|
||||||
std::error_code make_error_code(PackageSpecParseResult e);
|
|
||||||
|
|
||||||
PackageSpecParseResult to_package_spec_parse_result(int i);
|
|
||||||
|
|
||||||
PackageSpecParseResult to_package_spec_parse_result(std::error_code ec);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enable implicit conversion to std::error_code
|
|
||||||
namespace std
|
|
||||||
{
|
|
||||||
template<>
|
template<>
|
||||||
struct is_error_code_enum<vcpkg::PackageSpecParseResult> : ::std::true_type
|
struct ErrorHolder<PackageSpecParseResult>
|
||||||
{
|
{
|
||||||
|
ErrorHolder() : m_err(PackageSpecParseResult::SUCCESS) {}
|
||||||
|
ErrorHolder(PackageSpecParseResult err) : m_err(err) {}
|
||||||
|
|
||||||
|
constexpr bool has_error() const { return m_err != PackageSpecParseResult::SUCCESS; }
|
||||||
|
|
||||||
|
PackageSpecParseResult error() const { return m_err; }
|
||||||
|
|
||||||
|
CStringView to_string() const { return vcpkg::to_string(m_err); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
PackageSpecParseResult m_err;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,8 @@ namespace vcpkg::Paragraphs
|
|||||||
Expected<ParagraphDataMap> parse_single_paragraph(const std::string& str);
|
Expected<ParagraphDataMap> parse_single_paragraph(const std::string& str);
|
||||||
Expected<std::vector<ParagraphDataMap>> parse_paragraphs(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);
|
Expected<BinaryParagraph> try_load_cached_package(const VcpkgPaths& paths, const PackageSpec& spec);
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "vcpkg_expected.h"
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -15,14 +16,23 @@ namespace vcpkg
|
|||||||
|
|
||||||
const std::string& to_string(const Dependency& dep);
|
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>
|
/// <summary>
|
||||||
/// Port metadata (CONTROL file)
|
/// Port metadata (CONTROL file)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
struct SourceParagraph
|
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 name;
|
||||||
std::string version;
|
std::string version;
|
||||||
@ -31,6 +41,9 @@ namespace vcpkg
|
|||||||
std::vector<Dependency> depends;
|
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<std::string> filter_dependencies(const std::vector<Dependency>& deps, const Triplet& t);
|
||||||
|
|
||||||
std::vector<Dependency> expand_qualified_dependencies(const std::vector<std::string>& depends);
|
std::vector<Dependency> expand_qualified_dependencies(const std::vector<std::string>& depends);
|
||||||
|
@ -5,27 +5,63 @@
|
|||||||
|
|
||||||
namespace vcpkg
|
namespace vcpkg
|
||||||
{
|
{
|
||||||
template<class T>
|
template<class Err>
|
||||||
class Expected
|
struct ErrorHolder
|
||||||
|
{
|
||||||
|
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); }
|
||||||
|
|
||||||
|
const std::error_code& error() const { return m_err; }
|
||||||
|
std::error_code& error() { return m_err; }
|
||||||
|
|
||||||
|
CStringView to_string() const { return "value was error"; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::error_code m_err;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T, class S>
|
||||||
|
class ExpectedT
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
constexpr ExpectedT() = default;
|
||||||
|
|
||||||
// Constructors are intentionally implicit
|
// Constructors are intentionally implicit
|
||||||
Expected(const std::error_code& ec) : m_error_code(ec), m_t() {}
|
|
||||||
|
|
||||||
Expected(std::errc ec) : Expected(std::make_error_code(ec)) {}
|
ExpectedT(const S& s) : m_s(s) {}
|
||||||
|
ExpectedT(S&& s) : m_s(std::move(s)) {}
|
||||||
|
|
||||||
Expected(const T& t) : m_error_code(), m_t(t) {}
|
ExpectedT(const T& t) : m_t(t) {}
|
||||||
|
ExpectedT(T&& t) : m_t(std::move(t)) {}
|
||||||
|
|
||||||
Expected(T&& t) : m_error_code(), m_t(std::move(t)) {}
|
ExpectedT(const ExpectedT&) = default;
|
||||||
|
ExpectedT(ExpectedT&&) = default;
|
||||||
|
ExpectedT& operator=(const ExpectedT&) = default;
|
||||||
|
ExpectedT& operator=(ExpectedT&&) = default;
|
||||||
|
|
||||||
Expected() : Expected(std::error_code(), T()) {}
|
explicit constexpr operator bool() const noexcept { return !m_s.has_error(); }
|
||||||
|
constexpr bool has_value() const noexcept { return !m_s.has_error(); }
|
||||||
Expected(const Expected&) = default;
|
|
||||||
Expected(Expected&&) = default;
|
|
||||||
Expected& operator=(const Expected&) = default;
|
|
||||||
Expected& operator=(Expected&&) = default;
|
|
||||||
|
|
||||||
std::error_code error_code() const { return this->m_error_code; }
|
|
||||||
|
|
||||||
T&& value_or_exit(const LineInfo& line_info) &&
|
T&& value_or_exit(const LineInfo& line_info) &&
|
||||||
{
|
{
|
||||||
@ -39,9 +75,13 @@ namespace vcpkg
|
|||||||
return this->m_t;
|
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
|
const T* get() const
|
||||||
{
|
{
|
||||||
if (m_error_code)
|
if (!this->has_value())
|
||||||
{
|
{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -50,7 +90,7 @@ namespace vcpkg
|
|||||||
|
|
||||||
T* get()
|
T* get()
|
||||||
{
|
{
|
||||||
if (m_error_code)
|
if (!this->has_value())
|
||||||
{
|
{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -60,10 +100,13 @@ namespace vcpkg
|
|||||||
private:
|
private:
|
||||||
void exit_if_error(const LineInfo& line_info) const
|
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;
|
T m_t;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
using Expected = ExpectedT<T, std::error_code>;
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,8 @@ namespace vcpkg
|
|||||||
{
|
{
|
||||||
static bool is_valid_package_spec_char(char c) { return (c == '-') || isdigit(c) || (isalpha(c) && islower(c)); }
|
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(':');
|
auto pos = spec_as_string.find(':');
|
||||||
if (pos == std::string::npos)
|
if (pos == std::string::npos)
|
||||||
@ -18,7 +19,7 @@ namespace vcpkg
|
|||||||
auto pos2 = spec_as_string.find(':', pos + 1);
|
auto pos2 = spec_as_string.find(':', pos + 1);
|
||||||
if (pos2 != std::string::npos)
|
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);
|
const std::string name = spec_as_string.substr(0, pos);
|
||||||
@ -26,11 +27,12 @@ namespace vcpkg
|
|||||||
return from_name_and_triplet(name, triplet);
|
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())
|
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;
|
PackageSpec p;
|
||||||
|
@ -5,11 +5,9 @@
|
|||||||
|
|
||||||
namespace vcpkg
|
namespace vcpkg
|
||||||
{
|
{
|
||||||
const char* PackageSpecParseResultCategoryImpl::name() const noexcept { return "PackageSpecParseResult"; }
|
CStringView to_string(PackageSpecParseResult ev) noexcept
|
||||||
|
|
||||||
std::string PackageSpecParseResultCategoryImpl::message(int ev) const noexcept
|
|
||||||
{
|
{
|
||||||
switch (static_cast<PackageSpecParseResult>(ev))
|
switch (ev)
|
||||||
{
|
{
|
||||||
case PackageSpecParseResult::SUCCESS: return "OK";
|
case PackageSpecParseResult::SUCCESS: return "OK";
|
||||||
case PackageSpecParseResult::TOO_MANY_COLONS: return "Too many colons";
|
case PackageSpecParseResult::TOO_MANY_COLONS: return "Too many colons";
|
||||||
@ -19,22 +17,4 @@ namespace vcpkg
|
|||||||
default: Checks::unreachable(VCPKG_LINE_INFO);
|
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());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -168,7 +168,7 @@ namespace vcpkg::Paragraphs
|
|||||||
return parse_single_paragraph(*spgh);
|
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,
|
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 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)
|
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();
|
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");
|
Expected<std::unordered_map<std::string, std::string>> pghs = get_single_paragraph(fs, path / "CONTROL");
|
||||||
if (auto p = pghs.get())
|
if (auto p = pghs.get())
|
||||||
{
|
{
|
||||||
return SourceParagraph(*p);
|
return SourceParagraph::parse_control_file(*p);
|
||||||
}
|
}
|
||||||
|
error_info.error = pghs.error();
|
||||||
return pghs.error_code();
|
return error_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
Expected<BinaryParagraph> try_load_cached_package(const VcpkgPaths& paths, const PackageSpec& spec)
|
Expected<BinaryParagraph> try_load_cached_package(const VcpkgPaths& paths, const PackageSpec& spec)
|
||||||
@ -222,20 +223,26 @@ namespace vcpkg::Paragraphs
|
|||||||
return BinaryParagraph(*p);
|
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> load_all_ports(const Files::Filesystem& fs, const fs::path& ports_dir)
|
||||||
{
|
{
|
||||||
std::vector<SourceParagraph> output;
|
std::vector<SourceParagraph> output;
|
||||||
|
std::vector<ParseControlErrorInfo> port_errors;
|
||||||
for (auto&& path : fs.get_files_non_recursive(ports_dir))
|
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())
|
if (auto srcpgh = source_paragraph.get())
|
||||||
{
|
{
|
||||||
output.emplace_back(std::move(*srcpgh));
|
output.emplace_back(std::move(*srcpgh));
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
port_errors.emplace_back(source_paragraph.error());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
print_error_message(port_errors);
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
#include "vcpkg_Checks.h"
|
#include "vcpkg_Checks.h"
|
||||||
#include "vcpkg_Maps.h"
|
#include "vcpkg_Maps.h"
|
||||||
#include "vcpkg_System.h"
|
#include "vcpkg_System.h"
|
||||||
|
#include "vcpkg_expected.h"
|
||||||
|
|
||||||
#include "vcpkglib_helpers.h"
|
#include "vcpkglib_helpers.h"
|
||||||
|
|
||||||
namespace vcpkg
|
namespace vcpkg
|
||||||
@ -37,15 +39,41 @@ namespace vcpkg
|
|||||||
|
|
||||||
SourceParagraph::SourceParagraph() = default;
|
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);
|
System::println(
|
||||||
this->version = details::remove_required_field(&fields, SourceParagraphRequiredField::VERSION);
|
System::Color::error, "Error: There are invalid fields in the Source Paragraph of %s", info.name);
|
||||||
this->description = details::remove_optional_field(&fields, SourceParagraphOptionalField::DESCRIPTION);
|
System::println("The following fields were not expected:\n\n %s\n\n", info.remaining_fields_as_string);
|
||||||
this->maintainer = details::remove_optional_field(&fields, SourceParagraphOptionalField::MAINTAINER);
|
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);
|
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())
|
if (!fields.empty())
|
||||||
{
|
{
|
||||||
@ -55,12 +83,9 @@ namespace vcpkg
|
|||||||
const std::string remaining_fields_as_string = Strings::join("\n ", remaining_fields);
|
const std::string remaining_fields_as_string = Strings::join("\n ", remaining_fields);
|
||||||
const std::string valid_fields_as_string = Strings::join("\n ", valid_fields);
|
const std::string valid_fields_as_string = Strings::join("\n ", valid_fields);
|
||||||
|
|
||||||
System::println(
|
return ParseControlErrorInfo{sparagraph.name, remaining_fields_as_string, valid_fields_as_string};
|
||||||
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 sparagraph;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Dependency> vcpkg::expand_qualified_dependencies(const std::vector<std::string>& depends)
|
std::vector<Dependency> vcpkg::expand_qualified_dependencies(const std::vector<std::string>& depends)
|
||||||
|
@ -33,13 +33,16 @@ namespace vcpkg::Commands::BuildCommand
|
|||||||
Checks::exit_success(VCPKG_LINE_INFO);
|
Checks::exit_success(VCPKG_LINE_INFO);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Expected<SourceParagraph> maybe_spgh = Paragraphs::try_load_port(paths.get_filesystem(), port_dir);
|
const ExpectedT<SourceParagraph, ParseControlErrorInfo> maybe_spgh =
|
||||||
Checks::check_exit(VCPKG_LINE_INFO,
|
Paragraphs::try_load_port(paths.get_filesystem(), port_dir);
|
||||||
!maybe_spgh.error_code(),
|
// why do we add a const here
|
||||||
"Could not find package %s: %s",
|
if (!maybe_spgh)
|
||||||
spec,
|
{
|
||||||
maybe_spgh.error_code().message());
|
print_error_message(maybe_spgh.error());
|
||||||
const SourceParagraph& spgh = *maybe_spgh.get();
|
Checks::exit_fail(VCPKG_LINE_INFO);
|
||||||
|
}
|
||||||
|
|
||||||
|
const SourceParagraph& spgh = maybe_spgh.value_or_exit(VCPKG_LINE_INFO);
|
||||||
Checks::check_exit(VCPKG_LINE_INFO,
|
Checks::check_exit(VCPKG_LINE_INFO,
|
||||||
spec.name() == spgh.name,
|
spec.name() == spgh.name,
|
||||||
"The Name: field inside the CONTROL does not match the port directory: '%s' != '%s'",
|
"The Name: field inside the CONTROL does not match the port directory: '%s' != '%s'",
|
||||||
|
@ -25,7 +25,10 @@ namespace UnitTest1
|
|||||||
{
|
{
|
||||||
TEST_METHOD(SourceParagraph_Construct_Minimum)
|
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("zlib", pgh.name.c_str());
|
||||||
Assert::AreEqual("1.2.8", pgh.version.c_str());
|
Assert::AreEqual("1.2.8", pgh.version.c_str());
|
||||||
@ -36,11 +39,12 @@ namespace UnitTest1
|
|||||||
|
|
||||||
TEST_METHOD(SourceParagraph_Construct_Maximum)
|
TEST_METHOD(SourceParagraph_Construct_Maximum)
|
||||||
{
|
{
|
||||||
vcpkg::SourceParagraph pgh({{"Source", "s"},
|
auto m_pgh = vcpkg::SourceParagraph::parse_control_file({
|
||||||
{"Version", "v"},
|
{"Source", "s"}, {"Version", "v"}, {"Maintainer", "m"}, {"Description", "d"}, {"Build-Depends", "bd"},
|
||||||
{"Maintainer", "m"},
|
});
|
||||||
{"Description", "d"},
|
Assert::IsTrue(m_pgh.has_value());
|
||||||
{"Build-Depends", "bd"}});
|
auto& pgh = *m_pgh.get();
|
||||||
|
|
||||||
Assert::AreEqual("s", pgh.name.c_str());
|
Assert::AreEqual("s", pgh.name.c_str());
|
||||||
Assert::AreEqual("v", pgh.version.c_str());
|
Assert::AreEqual("v", pgh.version.c_str());
|
||||||
Assert::AreEqual("m", pgh.maintainer.c_str());
|
Assert::AreEqual("m", pgh.maintainer.c_str());
|
||||||
@ -51,7 +55,11 @@ namespace UnitTest1
|
|||||||
|
|
||||||
TEST_METHOD(SourceParagraph_Two_Depends)
|
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(size_t(2), pgh.depends.size());
|
||||||
Assert::AreEqual("z", pgh.depends[0].name.c_str());
|
Assert::AreEqual("z", pgh.depends[0].name.c_str());
|
||||||
@ -60,8 +68,11 @@ namespace UnitTest1
|
|||||||
|
|
||||||
TEST_METHOD(SourceParagraph_Three_Depends)
|
TEST_METHOD(SourceParagraph_Three_Depends)
|
||||||
{
|
{
|
||||||
vcpkg::SourceParagraph pgh(
|
auto m_pgh = vcpkg::SourceParagraph::parse_control_file({
|
||||||
{{"Source", "zlib"}, {"Version", "1.2.8"}, {"Build-Depends", "z, openssl, xyz"}});
|
{"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(size_t(3), pgh.depends.size());
|
||||||
Assert::AreEqual("z", pgh.depends[0].name.c_str());
|
Assert::AreEqual("z", pgh.depends[0].name.c_str());
|
||||||
@ -71,8 +82,11 @@ namespace UnitTest1
|
|||||||
|
|
||||||
TEST_METHOD(SourceParagraph_Construct_Qualified_Depends)
|
TEST_METHOD(SourceParagraph_Construct_Qualified_Depends)
|
||||||
{
|
{
|
||||||
vcpkg::SourceParagraph pgh(
|
auto m_pgh = vcpkg::SourceParagraph::parse_control_file({
|
||||||
{{"Source", "zlib"}, {"Version", "1.2.8"}, {"Build-Depends", "libA [windows], libB [uwp]"}});
|
{"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("zlib", pgh.name.c_str());
|
||||||
Assert::AreEqual("1.2.8", pgh.version.c_str());
|
Assert::AreEqual("1.2.8", pgh.version.c_str());
|
||||||
@ -101,13 +115,15 @@ namespace UnitTest1
|
|||||||
|
|
||||||
TEST_METHOD(BinaryParagraph_Construct_Maximum)
|
TEST_METHOD(BinaryParagraph_Construct_Maximum)
|
||||||
{
|
{
|
||||||
vcpkg::BinaryParagraph pgh({{"Package", "s"},
|
vcpkg::BinaryParagraph pgh({
|
||||||
{"Version", "v"},
|
{"Package", "s"},
|
||||||
{"Architecture", "x86-windows"},
|
{"Version", "v"},
|
||||||
{"Multi-Arch", "same"},
|
{"Architecture", "x86-windows"},
|
||||||
{"Maintainer", "m"},
|
{"Multi-Arch", "same"},
|
||||||
{"Description", "d"},
|
{"Maintainer", "m"},
|
||||||
{"Depends", "bd"}});
|
{"Description", "d"},
|
||||||
|
{"Depends", "bd"},
|
||||||
|
});
|
||||||
Assert::AreEqual("s", pgh.spec.name().c_str());
|
Assert::AreEqual("s", pgh.spec.name().c_str());
|
||||||
Assert::AreEqual("v", pgh.version.c_str());
|
Assert::AreEqual("v", pgh.version.c_str());
|
||||||
Assert::AreEqual("m", pgh.maintainer.c_str());
|
Assert::AreEqual("m", pgh.maintainer.c_str());
|
||||||
@ -327,28 +343,26 @@ namespace UnitTest1
|
|||||||
|
|
||||||
TEST_METHOD(package_spec_parse)
|
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);
|
vcpkg::PackageSpec::from_string("zlib", vcpkg::Triplet::X86_WINDOWS);
|
||||||
Assert::AreEqual(vcpkg::PackageSpecParseResult::SUCCESS,
|
Assert::AreEqual(vcpkg::PackageSpecParseResult::SUCCESS, spec.error());
|
||||||
vcpkg::to_package_spec_parse_result(spec.error_code()));
|
|
||||||
Assert::AreEqual("zlib", spec.get()->name().c_str());
|
Assert::AreEqual("zlib", spec.get()->name().c_str());
|
||||||
Assert::AreEqual(vcpkg::Triplet::X86_WINDOWS.canonical_name(), spec.get()->triplet().canonical_name());
|
Assert::AreEqual(vcpkg::Triplet::X86_WINDOWS.canonical_name(), spec.get()->triplet().canonical_name());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_METHOD(package_spec_parse_with_arch)
|
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);
|
vcpkg::PackageSpec::from_string("zlib:x64-uwp", vcpkg::Triplet::X86_WINDOWS);
|
||||||
Assert::AreEqual(vcpkg::PackageSpecParseResult::SUCCESS,
|
Assert::AreEqual(vcpkg::PackageSpecParseResult::SUCCESS, spec.error());
|
||||||
vcpkg::to_package_spec_parse_result(spec.error_code()));
|
|
||||||
Assert::AreEqual("zlib", spec.get()->name().c_str());
|
Assert::AreEqual("zlib", spec.get()->name().c_str());
|
||||||
Assert::AreEqual(vcpkg::Triplet::X64_UWP.canonical_name(), spec.get()->triplet().canonical_name());
|
Assert::AreEqual(vcpkg::Triplet::X64_UWP.canonical_name(), spec.get()->triplet().canonical_name());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_METHOD(package_spec_parse_with_multiple_colon)
|
TEST_METHOD(package_spec_parse_with_multiple_colon)
|
||||||
{
|
{
|
||||||
auto ec = vcpkg::PackageSpec::from_string("zlib:x86-uwp:", vcpkg::Triplet::X86_WINDOWS).error_code();
|
auto ec = vcpkg::PackageSpec::from_string("zlib:x86-uwp:", vcpkg::Triplet::X86_WINDOWS).error();
|
||||||
Assert::AreEqual(vcpkg::PackageSpecParseResult::TOO_MANY_COLONS, vcpkg::to_package_spec_parse_result(ec));
|
Assert::AreEqual(vcpkg::PackageSpecParseResult::TOO_MANY_COLONS, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_METHOD(utf8_to_utf16)
|
TEST_METHOD(utf8_to_utf16)
|
||||||
|
@ -61,10 +61,10 @@ static void inner(const VcpkgCmdArguments& args)
|
|||||||
|
|
||||||
const Expected<VcpkgPaths> expected_paths = VcpkgPaths::create(vcpkg_root_dir);
|
const Expected<VcpkgPaths> expected_paths = VcpkgPaths::create(vcpkg_root_dir);
|
||||||
Checks::check_exit(VCPKG_LINE_INFO,
|
Checks::check_exit(VCPKG_LINE_INFO,
|
||||||
!expected_paths.error_code(),
|
!expected_paths.error(),
|
||||||
"Error: Invalid vcpkg root directory %s: %s",
|
"Error: Invalid vcpkg root directory %s: %s",
|
||||||
vcpkg_root_dir.string(),
|
vcpkg_root_dir.string(),
|
||||||
expected_paths.error_code().message());
|
expected_paths.error().message());
|
||||||
const VcpkgPaths paths = expected_paths.value_or_exit(VCPKG_LINE_INFO);
|
const VcpkgPaths paths = expected_paths.value_or_exit(VCPKG_LINE_INFO);
|
||||||
int exit_code = _wchdir(paths.root.c_str());
|
int exit_code = _wchdir(paths.root.c_str());
|
||||||
Checks::check_exit(VCPKG_LINE_INFO, exit_code == 0, "Changing the working dir failed");
|
Checks::check_exit(VCPKG_LINE_INFO, exit_code == 0, "Changing the working dir failed");
|
||||||
|
@ -174,11 +174,14 @@ namespace vcpkg::Dependencies
|
|||||||
if (auto bpgh = maybe_bpgh.get())
|
if (auto bpgh = maybe_bpgh.get())
|
||||||
return InstallPlanAction{spec, {nullopt, *bpgh, nullopt}, request_type};
|
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));
|
Paragraphs::try_load_port(paths.get_filesystem(), paths.port_dir(spec));
|
||||||
if (auto spgh = maybe_spgh.get())
|
if (auto spgh = maybe_spgh.get())
|
||||||
return InstallPlanAction{spec, {nullopt, nullopt, *spgh}, request_type};
|
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);
|
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())
|
if (auto bpgh = maybe_bpgh.get())
|
||||||
return ExportPlanAction{spec, {nullopt, *bpgh, nullopt}, request_type};
|
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));
|
Paragraphs::try_load_port(paths.get_filesystem(), paths.port_dir(spec));
|
||||||
if (auto spgh = maybe_spgh.get())
|
if (auto spgh = maybe_spgh.get())
|
||||||
return ExportPlanAction{spec, {nullopt, nullopt, *spgh}, request_type};
|
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);
|
Checks::exit_with_message(VCPKG_LINE_INFO, "Could not find package %s", spec);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -15,7 +15,7 @@ namespace vcpkg::Files
|
|||||||
std::fstream file_stream(file_path, std::ios_base::in | std::ios_base::binary);
|
std::fstream file_stream(file_path, std::ios_base::in | std::ios_base::binary);
|
||||||
if (file_stream.fail())
|
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);
|
file_stream.seekg(0, file_stream.end);
|
||||||
@ -24,7 +24,7 @@ namespace vcpkg::Files
|
|||||||
|
|
||||||
if (length > SIZE_MAX)
|
if (length > SIZE_MAX)
|
||||||
{
|
{
|
||||||
return std::errc::file_too_large;
|
return std::make_error_code(std::errc::file_too_large);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string output;
|
std::string output;
|
||||||
@ -39,7 +39,7 @@ namespace vcpkg::Files
|
|||||||
std::fstream file_stream(file_path, std::ios_base::in | std::ios_base::binary);
|
std::fstream file_stream(file_path, std::ios_base::in | std::ios_base::binary);
|
||||||
if (file_stream.fail())
|
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;
|
std::vector<std::string> output;
|
||||||
|
@ -12,14 +12,14 @@ namespace vcpkg::Input
|
|||||||
CStringView example_text)
|
CStringView example_text)
|
||||||
{
|
{
|
||||||
const std::string as_lowercase = Strings::ascii_to_lowercase(package_spec_as_string);
|
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())
|
if (auto spec = expected_spec.get())
|
||||||
{
|
{
|
||||||
return *spec;
|
return *spec;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Intentionally show the lowercased string
|
// 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);
|
System::print(example_text);
|
||||||
Checks::exit_fail(VCPKG_LINE_INFO);
|
Checks::exit_fail(VCPKG_LINE_INFO);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user