mirror of
https://github.com/microsoft/vcpkg.git
synced 2024-11-29 00:19:00 +08:00
[vcpkg] Use unique_ptr<> for paragraphs. Post-parser phase rework.
This commit is contained in:
parent
8c4d55b8f3
commit
8741214bf6
@ -1,36 +1,38 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "BinaryParagraph.h"
|
||||
#include "VcpkgPaths.h"
|
||||
#include "VersionT.h"
|
||||
#include "filesystem_fs.h"
|
||||
#include "vcpkg_Parse.h"
|
||||
#include "vcpkg_expected.h"
|
||||
#include <map>
|
||||
|
||||
namespace vcpkg::Paragraphs
|
||||
{
|
||||
using ParagraphDataMap = std::unordered_map<std::string, std::string>;
|
||||
using RawParagraph = Parse::RawParagraph;
|
||||
|
||||
Expected<ParagraphDataMap> get_single_paragraph(const Files::Filesystem& fs, const fs::path& control_path);
|
||||
Expected<std::vector<ParagraphDataMap>> get_paragraphs(const Files::Filesystem& fs, const fs::path& control_path);
|
||||
Expected<ParagraphDataMap> parse_single_paragraph(const std::string& str);
|
||||
Expected<std::vector<ParagraphDataMap>> parse_paragraphs(const std::string& str);
|
||||
Expected<RawParagraph> get_single_paragraph(const Files::Filesystem& fs, const fs::path& control_path);
|
||||
Expected<std::vector<RawParagraph>> get_paragraphs(const Files::Filesystem& fs, const fs::path& control_path);
|
||||
Expected<RawParagraph> parse_single_paragraph(const std::string& str);
|
||||
Expected<std::vector<RawParagraph>> parse_paragraphs(const std::string& str);
|
||||
|
||||
ExpectedT<SourceControlFile, ParseControlErrorInfo> try_load_port(const Files::Filesystem& fs,
|
||||
const fs::path& control_path);
|
||||
Parse::ParseExpected<SourceControlFile> try_load_port(const Files::Filesystem& fs, const fs::path& control_path);
|
||||
|
||||
Expected<BinaryParagraph> try_load_cached_package(const VcpkgPaths& paths, const PackageSpec& spec);
|
||||
|
||||
struct LoadResults
|
||||
{
|
||||
std::vector<SourceControlFile> paragraphs;
|
||||
std::vector<ParseControlErrorInfo> errors;
|
||||
std::vector<std::unique_ptr<SourceControlFile>> paragraphs;
|
||||
std::vector<std::unique_ptr<Parse::ParseControlErrorInfo>> errors;
|
||||
};
|
||||
|
||||
LoadResults try_load_all_ports(const Files::Filesystem& fs, const fs::path& ports_dir);
|
||||
|
||||
std::vector<SourceControlFile> load_all_ports(const Files::Filesystem& fs, const fs::path& ports_dir);
|
||||
std::vector<std::unique_ptr<SourceControlFile>> load_all_ports(const Files::Filesystem& fs,
|
||||
const fs::path& ports_dir);
|
||||
|
||||
std::map<std::string, VersionT> extract_port_names_and_versions(
|
||||
const std::vector<SourceParagraph>& source_paragraphs);
|
||||
std::map<std::string, VersionT> load_all_port_names_and_versions(const Files::Filesystem& fs,
|
||||
const fs::path& ports_dir);
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "Span.h"
|
||||
#include "vcpkg_Parse.h"
|
||||
#include "vcpkg_System.h"
|
||||
#include "vcpkg_expected.h"
|
||||
|
||||
@ -22,13 +23,6 @@ namespace vcpkg
|
||||
|
||||
const std::string& to_string(const Dependency& dep);
|
||||
|
||||
struct ParseControlErrorInfo
|
||||
{
|
||||
std::string name;
|
||||
std::string remaining_fields_as_string;
|
||||
std::error_code error;
|
||||
};
|
||||
|
||||
struct FeatureParagraph
|
||||
{
|
||||
std::string name;
|
||||
@ -47,23 +41,19 @@ namespace vcpkg
|
||||
std::string maintainer;
|
||||
std::vector<std::string> supports;
|
||||
std::vector<Dependency> depends;
|
||||
std::string default_features;
|
||||
std::vector<std::string> default_features;
|
||||
};
|
||||
struct SourceControlFile
|
||||
{
|
||||
static ExpectedT<SourceControlFile, ParseControlErrorInfo> parse_control_file(
|
||||
std::vector<std::unordered_map<std::string, std::string>>&& control_paragraphs);
|
||||
static Parse::ParseExpected<SourceControlFile> parse_control_file(
|
||||
std::vector<Parse::RawParagraph>&& control_paragraphs);
|
||||
|
||||
SourceParagraph core_paragraph;
|
||||
std::unique_ptr<SourceParagraph> core_paragraph;
|
||||
std::vector<std::unique_ptr<FeatureParagraph>> feature_paragraphs;
|
||||
|
||||
std::vector<ParseControlErrorInfo> errors;
|
||||
};
|
||||
|
||||
std::vector<SourceParagraph> getSourceParagraphs(const std::vector<SourceControlFile>& control_files);
|
||||
|
||||
void print_error_message(span<const ParseControlErrorInfo> error_info_list);
|
||||
inline void print_error_message(const ParseControlErrorInfo& error_info_list)
|
||||
void print_error_message(span<const std::unique_ptr<Parse::ParseControlErrorInfo>> error_info_list);
|
||||
inline void print_error_message(const std::unique_ptr<Parse::ParseControlErrorInfo>& error_info_list)
|
||||
{
|
||||
return print_error_message({&error_info_list, 1});
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ namespace vcpkg
|
||||
struct StatusParagraph
|
||||
{
|
||||
StatusParagraph();
|
||||
explicit StatusParagraph(const std::unordered_map<std::string, std::string>& fields);
|
||||
explicit StatusParagraph(std::unordered_map<std::string, std::string>&& fields);
|
||||
|
||||
BinaryParagraph package;
|
||||
Want want;
|
||||
|
@ -120,14 +120,20 @@ namespace vcpkg::Build
|
||||
COUNT,
|
||||
};
|
||||
|
||||
Optional<BuildPolicy> to_build_policy(const std::string& str);
|
||||
constexpr std::array<BuildPolicy, size_t(BuildPolicy::COUNT)> g_all_policies = {
|
||||
BuildPolicy::EMPTY_PACKAGE,
|
||||
BuildPolicy::DLLS_WITHOUT_LIBS,
|
||||
BuildPolicy::ONLY_RELEASE_CRT,
|
||||
BuildPolicy::EMPTY_INCLUDE_FOLDER,
|
||||
BuildPolicy::ALLOW_OBSOLETE_MSVCRT,
|
||||
};
|
||||
|
||||
const std::string& to_string(BuildPolicy policy);
|
||||
CStringView to_cmake_variable(BuildPolicy policy);
|
||||
|
||||
struct BuildPolicies
|
||||
{
|
||||
BuildPolicies() {}
|
||||
BuildPolicies() = default;
|
||||
BuildPolicies(std::map<BuildPolicy, bool>&& map) : m_policies(std::move(map)) {}
|
||||
|
||||
inline bool is_enabled(BuildPolicy policy) const
|
||||
|
36
toolsrc/include/vcpkg_Parse.h
Normal file
36
toolsrc/include/vcpkg_Parse.h
Normal file
@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "vcpkg_expected.h"
|
||||
#include "vcpkg_optional.h"
|
||||
|
||||
namespace vcpkg::Parse
|
||||
{
|
||||
struct ParseControlErrorInfo
|
||||
{
|
||||
std::string name;
|
||||
std::vector<std::string> missing_fields;
|
||||
std::vector<std::string> extra_fields;
|
||||
std::error_code error;
|
||||
};
|
||||
|
||||
template<class P>
|
||||
using ParseExpected = ExpectedT<std::unique_ptr<P>, std::unique_ptr<ParseControlErrorInfo>>;
|
||||
|
||||
using RawParagraph = std::unordered_map<std::string, std::string>;
|
||||
|
||||
struct ParagraphParser
|
||||
{
|
||||
ParagraphParser(RawParagraph&& fields) : fields(std::move(fields)) {}
|
||||
|
||||
void required_field(const std::string& fieldname, std::string& out);
|
||||
std::string optional_field(const std::string& fieldname);
|
||||
std::unique_ptr<ParseControlErrorInfo> error_info(const std::string& name) const;
|
||||
|
||||
private:
|
||||
RawParagraph&& fields;
|
||||
std::vector<std::string> missing_fields;
|
||||
};
|
||||
}
|
@ -9,8 +9,10 @@ namespace vcpkg
|
||||
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)) {}
|
||||
template<class U>
|
||||
ErrorHolder(U&& err) : m_is_error(true), m_err(std::forward<U>(err))
|
||||
{
|
||||
}
|
||||
|
||||
constexpr bool has_error() const { return m_is_error; }
|
||||
|
||||
|
@ -36,4 +36,5 @@ namespace vcpkg
|
||||
const fs::path& cmake_script,
|
||||
const std::vector<CMakeVariable>& pass_variables);
|
||||
|
||||
std::string shorten_description(const std::string& desc);
|
||||
} // namespace vcpkg
|
||||
|
@ -1,18 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
namespace vcpkg::details
|
||||
{
|
||||
std::string optional_field(const std::unordered_map<std::string, std::string>& fields,
|
||||
const std::string& fieldname);
|
||||
std::string remove_optional_field(std::unordered_map<std::string, std::string>* fields,
|
||||
const std::string& fieldname);
|
||||
|
||||
std::string required_field(const std::unordered_map<std::string, std::string>& fields,
|
||||
const std::string& fieldname);
|
||||
std::string remove_required_field(std::unordered_map<std::string, std::string>* fields,
|
||||
const std::string& fieldname);
|
||||
|
||||
std::string shorten_description(const std::string& desc);
|
||||
}
|
@ -2,13 +2,11 @@
|
||||
|
||||
#include "BinaryParagraph.h"
|
||||
#include "vcpkg_Checks.h"
|
||||
#include "vcpkglib_helpers.h"
|
||||
|
||||
using namespace vcpkg::details;
|
||||
#include "vcpkg_Parse.h"
|
||||
|
||||
namespace vcpkg
|
||||
{
|
||||
namespace BinaryParagraphRequiredField
|
||||
namespace Fields
|
||||
{
|
||||
static const std::string PACKAGE = "Package";
|
||||
static const std::string VERSION = "Version";
|
||||
@ -16,7 +14,7 @@ namespace vcpkg
|
||||
static const std::string MULTI_ARCH = "Multi-Arch";
|
||||
}
|
||||
|
||||
namespace BinaryParagraphOptionalField
|
||||
namespace Fields
|
||||
{
|
||||
static const std::string DESCRIPTION = "Description";
|
||||
static const std::string MAINTAINER = "Maintainer";
|
||||
@ -27,22 +25,36 @@ namespace vcpkg
|
||||
|
||||
BinaryParagraph::BinaryParagraph(std::unordered_map<std::string, std::string> fields)
|
||||
{
|
||||
const std::string name = details::remove_required_field(&fields, BinaryParagraphRequiredField::PACKAGE);
|
||||
const std::string architecture =
|
||||
details::remove_required_field(&fields, BinaryParagraphRequiredField::ARCHITECTURE);
|
||||
const Triplet triplet = Triplet::from_canonical_name(architecture);
|
||||
using namespace vcpkg::Parse;
|
||||
|
||||
this->spec = PackageSpec::from_name_and_triplet(name, triplet).value_or_exit(VCPKG_LINE_INFO);
|
||||
this->version = details::remove_required_field(&fields, BinaryParagraphRequiredField::VERSION);
|
||||
ParagraphParser parser(std::move(fields));
|
||||
|
||||
this->description = details::remove_optional_field(&fields, BinaryParagraphOptionalField::DESCRIPTION);
|
||||
this->maintainer = details::remove_optional_field(&fields, BinaryParagraphOptionalField::MAINTAINER);
|
||||
{
|
||||
std::string name;
|
||||
parser.required_field(Fields::PACKAGE, name);
|
||||
std::string architecture;
|
||||
parser.required_field(Fields::ARCHITECTURE, architecture);
|
||||
this->spec = PackageSpec::from_name_and_triplet(name, Triplet::from_canonical_name(architecture))
|
||||
.value_or_exit(VCPKG_LINE_INFO);
|
||||
}
|
||||
|
||||
std::string multi_arch = details::remove_required_field(&fields, BinaryParagraphRequiredField::MULTI_ARCH);
|
||||
parser.required_field(Fields::VERSION, this->version);
|
||||
this->description = parser.optional_field(Fields::DESCRIPTION);
|
||||
this->maintainer = parser.optional_field(Fields::MAINTAINER);
|
||||
|
||||
std::string multi_arch;
|
||||
parser.required_field(Fields::MULTI_ARCH, multi_arch);
|
||||
|
||||
this->depends = parse_comma_list(parser.optional_field(Fields::DEPENDS));
|
||||
|
||||
if (auto err = parser.error_info(this->spec.name()))
|
||||
{
|
||||
print_error_message(err);
|
||||
Checks::exit_fail(VCPKG_LINE_INFO);
|
||||
}
|
||||
|
||||
// prefer failing above when possible because it gives better information
|
||||
Checks::check_exit(VCPKG_LINE_INFO, multi_arch == "same", "Multi-Arch must be 'same' but was %s", multi_arch);
|
||||
|
||||
std::string deps = details::remove_optional_field(&fields, BinaryParagraphOptionalField::DEPENDS);
|
||||
this->depends = parse_comma_list(deps);
|
||||
}
|
||||
|
||||
BinaryParagraph::BinaryParagraph(const SourceParagraph& spgh, const Triplet& triplet)
|
||||
|
@ -4,6 +4,8 @@
|
||||
#include "Paragraphs.h"
|
||||
#include "vcpkg_Files.h"
|
||||
|
||||
using namespace vcpkg::Parse;
|
||||
|
||||
namespace vcpkg::Paragraphs
|
||||
{
|
||||
struct Parser
|
||||
@ -201,9 +203,8 @@ namespace vcpkg::Paragraphs
|
||||
return Parser(str.c_str(), str.c_str() + str.size()).get_paragraphs();
|
||||
}
|
||||
|
||||
ExpectedT<SourceControlFile, ParseControlErrorInfo> try_load_port(const Files::Filesystem& fs, const fs::path& path)
|
||||
ParseExpected<SourceControlFile> try_load_port(const Files::Filesystem& fs, const fs::path& path)
|
||||
{
|
||||
ParseControlErrorInfo error_info;
|
||||
Expected<std::vector<std::unordered_map<std::string, std::string>>> pghs = get_paragraphs(fs, path / "CONTROL");
|
||||
if (auto vector_pghs = pghs.get())
|
||||
{
|
||||
@ -212,14 +213,16 @@ namespace vcpkg::Paragraphs
|
||||
{
|
||||
if (auto ptr = csf.get())
|
||||
{
|
||||
ptr->core_paragraph.default_features.clear();
|
||||
ptr->feature_paragraphs.clear();
|
||||
Checks::check_exit(VCPKG_LINE_INFO, ptr->get() != nullptr);
|
||||
ptr->get()->core_paragraph->default_features.clear();
|
||||
ptr->get()->feature_paragraphs.clear();
|
||||
}
|
||||
}
|
||||
return csf;
|
||||
}
|
||||
error_info.name = path.filename().generic_u8string();
|
||||
error_info.error = pghs.error();
|
||||
auto error_info = std::make_unique<ParseControlErrorInfo>();
|
||||
error_info->name = path.filename().generic_u8string();
|
||||
error_info->error = pghs.error();
|
||||
return error_info;
|
||||
}
|
||||
|
||||
@ -241,20 +244,21 @@ namespace vcpkg::Paragraphs
|
||||
LoadResults ret;
|
||||
for (auto&& path : fs.get_files_non_recursive(ports_dir))
|
||||
{
|
||||
ExpectedT<SourceControlFile, ParseControlErrorInfo> source_paragraph = try_load_port(fs, path);
|
||||
if (auto srcpgh = source_paragraph.get())
|
||||
auto maybe_spgh = try_load_port(fs, path);
|
||||
if (auto spgh = maybe_spgh.get())
|
||||
{
|
||||
ret.paragraphs.emplace_back(std::move(*srcpgh));
|
||||
ret.paragraphs.emplace_back(std::move(*spgh));
|
||||
}
|
||||
else
|
||||
{
|
||||
ret.errors.emplace_back(source_paragraph.error());
|
||||
ret.errors.emplace_back(std::move(maybe_spgh).error());
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::vector<SourceControlFile> load_all_ports(const Files::Filesystem& fs, const fs::path& ports_dir)
|
||||
std::vector<std::unique_ptr<SourceControlFile>> load_all_ports(const Files::Filesystem& fs,
|
||||
const fs::path& ports_dir)
|
||||
{
|
||||
auto results = try_load_all_ports(fs, ports_dir);
|
||||
if (!results.errors.empty())
|
||||
@ -265,14 +269,14 @@ namespace vcpkg::Paragraphs
|
||||
return std::move(results.paragraphs);
|
||||
}
|
||||
|
||||
std::map<std::string, VersionT> extract_port_names_and_versions(
|
||||
const std::vector<SourceParagraph>& source_paragraphs)
|
||||
std::map<std::string, VersionT> load_all_port_names_and_versions(const Files::Filesystem& fs,
|
||||
const fs::path& ports_dir)
|
||||
{
|
||||
auto all_ports = load_all_ports(fs, ports_dir);
|
||||
|
||||
std::map<std::string, VersionT> names_and_versions;
|
||||
for (const SourceParagraph& port : source_paragraphs)
|
||||
{
|
||||
names_and_versions.emplace(port.name, port.version);
|
||||
}
|
||||
for (auto&& port : all_ports)
|
||||
names_and_versions.emplace(port->core_paragraph->name, port->core_paragraph->version);
|
||||
|
||||
return names_and_versions;
|
||||
}
|
||||
|
@ -8,73 +8,56 @@
|
||||
#include "vcpkg_Util.h"
|
||||
#include "vcpkg_expected.h"
|
||||
|
||||
#include "vcpkglib_helpers.h"
|
||||
|
||||
namespace vcpkg
|
||||
{
|
||||
bool g_feature_packages = false;
|
||||
namespace SourceParagraphRequiredField
|
||||
{
|
||||
static const std::string SOURCE = "Source";
|
||||
static const std::string VERSION = "Version";
|
||||
}
|
||||
using namespace vcpkg::Parse;
|
||||
|
||||
namespace SourceParagraphOptionalField
|
||||
bool g_feature_packages = false;
|
||||
namespace Fields
|
||||
{
|
||||
static const std::string DESCRIPTION = "Description";
|
||||
static const std::string MAINTAINER = "Maintainer";
|
||||
static const std::string BUILD_DEPENDS = "Build-Depends";
|
||||
static const std::string SUPPORTS = "Supports";
|
||||
static const std::string DEFAULTFEATURES = "Default-Features";
|
||||
static const std::string DESCRIPTION = "Description";
|
||||
static const std::string FEATURE = "Feature";
|
||||
static const std::string MAINTAINER = "Maintainer";
|
||||
static const std::string SOURCE = "Source";
|
||||
static const std::string SUPPORTS = "Supports";
|
||||
static const std::string VERSION = "Version";
|
||||
}
|
||||
|
||||
static span<const std::string> get_list_of_valid_fields()
|
||||
{
|
||||
static const std::string valid_fields[] = {SourceParagraphRequiredField::SOURCE,
|
||||
SourceParagraphRequiredField::VERSION,
|
||||
|
||||
SourceParagraphOptionalField::DESCRIPTION,
|
||||
SourceParagraphOptionalField::MAINTAINER,
|
||||
SourceParagraphOptionalField::BUILD_DEPENDS,
|
||||
SourceParagraphOptionalField::SUPPORTS};
|
||||
static const std::string valid_fields[] = {
|
||||
Fields::SOURCE, Fields::VERSION, Fields::DESCRIPTION, Fields::MAINTAINER, Fields::BUILD_DEPENDS,
|
||||
};
|
||||
|
||||
return valid_fields;
|
||||
}
|
||||
|
||||
namespace FeatureParagraphRequiredField
|
||||
{
|
||||
static const std::string FEATURE = "Feature";
|
||||
}
|
||||
|
||||
namespace FeatureParagraphOptionalField
|
||||
{
|
||||
static const std::string DESCRIPTION = "Description";
|
||||
static const std::string BUILD_DEPENDS = "Build-Depends";
|
||||
}
|
||||
|
||||
void print_error_message(span<const ParseControlErrorInfo> error_info_list)
|
||||
void print_error_message(span<const std::unique_ptr<Parse::ParseControlErrorInfo>> error_info_list)
|
||||
{
|
||||
Checks::check_exit(VCPKG_LINE_INFO, error_info_list.size() > 0);
|
||||
|
||||
for (auto&& error_info : error_info_list)
|
||||
{
|
||||
if (error_info.error)
|
||||
Checks::check_exit(VCPKG_LINE_INFO, error_info != nullptr);
|
||||
if (error_info->error)
|
||||
{
|
||||
System::println(
|
||||
System::Color::error, "Error: while loading %s: %s", error_info.name, error_info.error.message());
|
||||
System::Color::error, "Error: while loading %s: %s", error_info->name, error_info->error.message());
|
||||
}
|
||||
}
|
||||
|
||||
bool have_remaining_fields = false;
|
||||
for (auto&& error_info : error_info_list)
|
||||
{
|
||||
if (!error_info.remaining_fields_as_string.empty())
|
||||
if (!error_info->extra_fields.empty())
|
||||
{
|
||||
System::println(System::Color::error,
|
||||
"Error: There are invalid fields in the Source Paragraph of %s",
|
||||
error_info.name);
|
||||
error_info->name);
|
||||
System::println("The following fields were not expected:\n\n %s\n\n",
|
||||
error_info.remaining_fields_as_string);
|
||||
Strings::join("\n ", error_info->extra_fields));
|
||||
have_remaining_fields = true;
|
||||
}
|
||||
}
|
||||
@ -86,71 +69,75 @@ namespace vcpkg
|
||||
System::println("Different source may be available for vcpkg. Use .\\bootstrap-vcpkg.bat to update.\n");
|
||||
}
|
||||
}
|
||||
std::vector<SourceParagraph> getSourceParagraphs(const std::vector<SourceControlFile>& control_files)
|
||||
|
||||
static ParseExpected<SourceParagraph> parse_source_paragraph(RawParagraph&& fields)
|
||||
{
|
||||
return Util::fmap(control_files, [](const SourceControlFile& x) { return x.core_paragraph; });
|
||||
ParagraphParser parser(std::move(fields));
|
||||
|
||||
auto spgh = std::make_unique<SourceParagraph>();
|
||||
|
||||
parser.required_field(Fields::SOURCE, spgh->name);
|
||||
parser.required_field(Fields::VERSION, spgh->version);
|
||||
|
||||
spgh->description = parser.optional_field(Fields::DESCRIPTION);
|
||||
spgh->maintainer = parser.optional_field(Fields::MAINTAINER);
|
||||
spgh->depends = expand_qualified_dependencies(parse_comma_list(parser.optional_field(Fields::BUILD_DEPENDS)));
|
||||
spgh->supports = parse_comma_list(parser.optional_field(Fields::SUPPORTS));
|
||||
spgh->default_features = parse_comma_list(parser.optional_field(Fields::DEFAULTFEATURES));
|
||||
|
||||
auto err = parser.error_info(spgh->name);
|
||||
if (err)
|
||||
return std::move(err);
|
||||
else
|
||||
return std::move(spgh);
|
||||
}
|
||||
|
||||
ExpectedT<SourceControlFile, ParseControlErrorInfo> SourceControlFile::parse_control_file(
|
||||
static ParseExpected<FeatureParagraph> parse_feature_paragraph(RawParagraph&& fields)
|
||||
{
|
||||
ParagraphParser parser(std::move(fields));
|
||||
|
||||
auto fpgh = std::make_unique<FeatureParagraph>();
|
||||
|
||||
parser.required_field(Fields::FEATURE, fpgh->name);
|
||||
parser.required_field(Fields::DESCRIPTION, fpgh->description);
|
||||
|
||||
fpgh->depends = expand_qualified_dependencies(parse_comma_list(parser.optional_field(Fields::BUILD_DEPENDS)));
|
||||
|
||||
auto err = parser.error_info(fpgh->name);
|
||||
if (err)
|
||||
return std::move(err);
|
||||
else
|
||||
return std::move(fpgh);
|
||||
}
|
||||
|
||||
ParseExpected<SourceControlFile> SourceControlFile::parse_control_file(
|
||||
std::vector<std::unordered_map<std::string, std::string>>&& control_paragraphs)
|
||||
{
|
||||
if (control_paragraphs.size() == 0)
|
||||
{
|
||||
return ExpectedT<SourceControlFile, ParseControlErrorInfo>();
|
||||
return std::make_unique<Parse::ParseControlErrorInfo>();
|
||||
}
|
||||
auto&& fields = control_paragraphs.front();
|
||||
|
||||
SourceControlFile control_file;
|
||||
SourceParagraph& sparagraph = control_file.core_paragraph;
|
||||
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);
|
||||
auto control_file = std::make_unique<SourceControlFile>();
|
||||
|
||||
std::string deps = details::remove_optional_field(&fields, SourceParagraphOptionalField::BUILD_DEPENDS);
|
||||
sparagraph.depends = expand_qualified_dependencies(parse_comma_list(deps));
|
||||
|
||||
std::string sups = details::remove_optional_field(&fields, SourceParagraphOptionalField::SUPPORTS);
|
||||
sparagraph.supports = parse_comma_list(sups);
|
||||
|
||||
sparagraph.default_features =
|
||||
details::remove_optional_field(&fields, SourceParagraphOptionalField::DEFAULTFEATURES);
|
||||
|
||||
if (!fields.empty())
|
||||
{
|
||||
const std::vector<std::string> remaining_fields = Maps::extract_keys(fields);
|
||||
|
||||
const std::string remaining_fields_as_string = Strings::join("\n ", remaining_fields);
|
||||
|
||||
return ParseControlErrorInfo{sparagraph.name, remaining_fields_as_string};
|
||||
}
|
||||
auto maybe_source = parse_source_paragraph(std::move(control_paragraphs.front()));
|
||||
if (auto source = maybe_source.get())
|
||||
control_file->core_paragraph = std::move(*source);
|
||||
else
|
||||
return std::move(maybe_source).error();
|
||||
|
||||
control_paragraphs.erase(control_paragraphs.begin());
|
||||
|
||||
for (auto&& feature_pgh : control_paragraphs)
|
||||
{
|
||||
control_file.feature_paragraphs.emplace_back(std::make_unique<FeatureParagraph>());
|
||||
|
||||
FeatureParagraph& fparagraph = *control_file.feature_paragraphs.back();
|
||||
|
||||
fparagraph.name = details::remove_required_field(&feature_pgh, FeatureParagraphRequiredField::FEATURE);
|
||||
fparagraph.description =
|
||||
details::remove_required_field(&feature_pgh, FeatureParagraphOptionalField::DESCRIPTION);
|
||||
std::string feature_deps =
|
||||
details::remove_optional_field(&feature_pgh, FeatureParagraphOptionalField::BUILD_DEPENDS);
|
||||
fparagraph.depends = expand_qualified_dependencies(parse_comma_list(feature_deps));
|
||||
|
||||
if (!feature_pgh.empty())
|
||||
{
|
||||
const std::vector<std::string> remaining_fields = Maps::extract_keys(feature_pgh);
|
||||
|
||||
const std::string remaining_fields_as_string = Strings::join("\n ", remaining_fields);
|
||||
|
||||
return ParseControlErrorInfo{sparagraph.name, remaining_fields_as_string};
|
||||
}
|
||||
auto maybe_feature = parse_feature_paragraph(std::move(feature_pgh));
|
||||
if (auto feature = maybe_feature.get())
|
||||
control_file->feature_paragraphs.emplace_back(std::move(*feature));
|
||||
else
|
||||
return std::move(maybe_feature).error();
|
||||
}
|
||||
|
||||
return control_file;
|
||||
return std::move(control_file);
|
||||
}
|
||||
|
||||
std::vector<Dependency> vcpkg::expand_qualified_dependencies(const std::vector<std::string>& depends)
|
||||
|
@ -1,9 +1,8 @@
|
||||
#include "pch.h"
|
||||
|
||||
#include "StatusParagraph.h"
|
||||
#include "vcpkglib_helpers.h"
|
||||
|
||||
using namespace vcpkg::details;
|
||||
using namespace vcpkg::Parse;
|
||||
|
||||
namespace vcpkg
|
||||
{
|
||||
@ -24,9 +23,14 @@ namespace vcpkg
|
||||
.push_back('\n');
|
||||
}
|
||||
|
||||
StatusParagraph::StatusParagraph(const std::unordered_map<std::string, std::string>& fields) : package(fields)
|
||||
StatusParagraph::StatusParagraph(std::unordered_map<std::string, std::string>&& fields)
|
||||
{
|
||||
std::string status_field = required_field(fields, BinaryParagraphRequiredField::STATUS);
|
||||
auto status_it = fields.find(BinaryParagraphRequiredField::STATUS);
|
||||
Checks::check_exit(VCPKG_LINE_INFO, status_it != fields.end(), "Expected 'Status' field in status paragraph");
|
||||
std::string status_field = std::move(status_it->second);
|
||||
fields.erase(status_it);
|
||||
|
||||
this->package = BinaryParagraph(std::move(fields));
|
||||
|
||||
auto b = status_field.begin();
|
||||
auto mark = b;
|
||||
|
@ -11,6 +11,8 @@
|
||||
#include "vcpkglib.h"
|
||||
|
||||
using vcpkg::Build::BuildResult;
|
||||
using vcpkg::Parse::ParseControlErrorInfo;
|
||||
using vcpkg::Parse::ParseExpected;
|
||||
|
||||
namespace vcpkg::Commands::BuildCommand
|
||||
{
|
||||
@ -34,7 +36,7 @@ namespace vcpkg::Commands::BuildCommand
|
||||
Checks::exit_success(VCPKG_LINE_INFO);
|
||||
}
|
||||
|
||||
const ExpectedT<SourceControlFile, ParseControlErrorInfo> source_control_file =
|
||||
const ParseExpected<SourceControlFile> source_control_file =
|
||||
Paragraphs::try_load_port(paths.get_filesystem(), port_dir);
|
||||
|
||||
if (!source_control_file.has_value())
|
||||
@ -47,18 +49,18 @@ namespace vcpkg::Commands::BuildCommand
|
||||
{
|
||||
System::println("%s \n", str);
|
||||
}
|
||||
const SourceControlFile& scf = source_control_file.value_or_exit(VCPKG_LINE_INFO);
|
||||
const auto& scf = source_control_file.value_or_exit(VCPKG_LINE_INFO);
|
||||
Checks::check_exit(VCPKG_LINE_INFO,
|
||||
spec.name() == scf.core_paragraph.name,
|
||||
spec.name() == scf->core_paragraph->name,
|
||||
"The Name: field inside the CONTROL does not match the port directory: '%s' != '%s'",
|
||||
scf.core_paragraph.name,
|
||||
scf->core_paragraph->name,
|
||||
spec.name());
|
||||
|
||||
StatusParagraphs status_db = database_load_check(paths);
|
||||
Build::BuildPackageOptions build_package_options{Build::UseHeadVersion::NO, Build::AllowDownloads::YES};
|
||||
|
||||
const Build::BuildPackageConfig build_config{
|
||||
scf.core_paragraph, spec.triplet(), paths.port_dir(spec), build_package_options};
|
||||
*scf->core_paragraph, spec.triplet(), paths.port_dir(spec), build_package_options};
|
||||
|
||||
const auto result = Build::build_package(paths, build_config, status_db);
|
||||
if (result.code == BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES)
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "vcpkg_Files.h"
|
||||
#include "vcpkg_Input.h"
|
||||
#include "vcpkg_System.h"
|
||||
#include "vcpkg_Util.h"
|
||||
#include "vcpkglib.h"
|
||||
|
||||
namespace vcpkg::Commands::CI
|
||||
@ -21,14 +22,10 @@ namespace vcpkg::Commands::CI
|
||||
const Triplet& triplet)
|
||||
{
|
||||
auto ports = Paragraphs::load_all_ports(fs, ports_directory);
|
||||
std::vector<PackageSpec> specs;
|
||||
for (const SourceControlFile& control_file : ports)
|
||||
{
|
||||
const SourceParagraph& p = control_file.core_paragraph;
|
||||
specs.push_back(PackageSpec::from_name_and_triplet(p.name, triplet).value_or_exit(VCPKG_LINE_INFO));
|
||||
}
|
||||
|
||||
return specs;
|
||||
return Util::fmap(ports, [&](auto&& control_file) -> PackageSpec {
|
||||
return PackageSpec::from_name_and_triplet(control_file->core_paragraph->name, triplet)
|
||||
.value_or_exit(VCPKG_LINE_INFO);
|
||||
});
|
||||
}
|
||||
|
||||
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet)
|
||||
|
@ -15,9 +15,9 @@ namespace vcpkg::Commands::DependInfo
|
||||
|
||||
const auto source_control_files = Paragraphs::load_all_ports(paths.get_filesystem(), paths.ports);
|
||||
|
||||
for (const SourceControlFile& source_control_file : source_control_files)
|
||||
for (auto&& source_control_file : source_control_files)
|
||||
{
|
||||
const SourceParagraph& source_paragraph = source_control_file.core_paragraph;
|
||||
const SourceParagraph& source_paragraph = *source_control_file->core_paragraph;
|
||||
auto s = Strings::join(", ", source_paragraph.depends, [](const Dependency& d) { return d.name; });
|
||||
System::println("%s: %s", source_paragraph.name, s);
|
||||
}
|
||||
|
@ -3,7 +3,6 @@
|
||||
#include "vcpkg_Commands.h"
|
||||
#include "vcpkg_System.h"
|
||||
#include "vcpkglib.h"
|
||||
#include "vcpkglib_helpers.h"
|
||||
|
||||
namespace vcpkg::Commands::List
|
||||
{
|
||||
@ -20,7 +19,7 @@ namespace vcpkg::Commands::List
|
||||
System::println("%-27s %-16s %s",
|
||||
pgh.package.displayname(),
|
||||
pgh.package.version,
|
||||
details::shorten_description(pgh.package.description));
|
||||
vcpkg::shorten_description(pgh.package.description));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -97,10 +97,8 @@ namespace vcpkg::Commands::PortsDiff
|
||||
L".vcpkg-root",
|
||||
git_exe.native());
|
||||
System::cmd_execute_clean(cmd);
|
||||
const std::vector<SourceControlFile> source_control_files =
|
||||
Paragraphs::load_all_ports(paths.get_filesystem(), temp_checkout_path / ports_dir_name_as_string);
|
||||
const std::map<std::string, VersionT> names_and_versions =
|
||||
Paragraphs::extract_port_names_and_versions(getSourceParagraphs(source_control_files));
|
||||
const std::map<std::string, VersionT> names_and_versions = Paragraphs::load_all_port_names_and_versions(
|
||||
paths.get_filesystem(), temp_checkout_path / ports_dir_name_as_string);
|
||||
fs.remove_all(temp_checkout_path, ec);
|
||||
return names_and_versions;
|
||||
}
|
||||
|
@ -5,7 +5,6 @@
|
||||
#include "vcpkg_Commands.h"
|
||||
#include "vcpkg_System.h"
|
||||
#include "vcpkglib.h"
|
||||
#include "vcpkglib_helpers.h"
|
||||
|
||||
namespace vcpkg::Commands::Search
|
||||
{
|
||||
@ -19,16 +18,17 @@ namespace vcpkg::Commands::Search
|
||||
return output;
|
||||
}
|
||||
|
||||
static std::string create_graph_as_string(const std::vector<SourceControlFile>& source_control_files)
|
||||
static std::string create_graph_as_string(
|
||||
const std::vector<std::unique_ptr<SourceControlFile>>& source_control_files)
|
||||
{
|
||||
int empty_node_count = 0;
|
||||
|
||||
std::string s;
|
||||
s.append("digraph G{ rankdir=LR; edge [minlen=3]; overlap=false;");
|
||||
|
||||
for (const SourceControlFile& source_control_file : source_control_files)
|
||||
for (const auto& source_control_file : source_control_files)
|
||||
{
|
||||
const SourceParagraph& source_paragraph = source_control_file.core_paragraph;
|
||||
const SourceParagraph& source_paragraph = *source_control_file->core_paragraph;
|
||||
if (source_paragraph.depends.empty())
|
||||
{
|
||||
empty_node_count++;
|
||||
@ -59,7 +59,7 @@ namespace vcpkg::Commands::Search
|
||||
System::println("%-20s %-16s %s",
|
||||
source_paragraph.name,
|
||||
source_paragraph.version,
|
||||
details::shorten_description(source_paragraph.description));
|
||||
vcpkg::shorten_description(source_paragraph.description));
|
||||
}
|
||||
}
|
||||
|
||||
@ -73,7 +73,7 @@ namespace vcpkg::Commands::Search
|
||||
{
|
||||
System::println("%-37s %s",
|
||||
name + "[" + feature_paragraph.name + "]",
|
||||
details::shorten_description(feature_paragraph.description));
|
||||
vcpkg::shorten_description(feature_paragraph.description));
|
||||
}
|
||||
}
|
||||
|
||||
@ -99,7 +99,7 @@ namespace vcpkg::Commands::Search
|
||||
for (auto&& error : sources_and_errors.errors)
|
||||
{
|
||||
System::println(
|
||||
System::Color::warning, "Warning: an error occurred while parsing '%s'", error.name);
|
||||
System::Color::warning, "Warning: an error occurred while parsing '%s'", error->name);
|
||||
}
|
||||
System::println(System::Color::warning,
|
||||
"Use '--debug' to get more information about the parse failures.\n");
|
||||
@ -116,12 +116,12 @@ namespace vcpkg::Commands::Search
|
||||
|
||||
if (args.command_arguments.empty())
|
||||
{
|
||||
for (const SourceControlFile& source_control_file : source_paragraphs)
|
||||
for (const auto& source_control_file : source_paragraphs)
|
||||
{
|
||||
do_print(source_control_file.core_paragraph, options.find(OPTION_FULLDESC) != options.cend());
|
||||
for (auto&& feature_paragraph : source_control_file.feature_paragraphs)
|
||||
do_print(*source_control_file->core_paragraph, options.find(OPTION_FULLDESC) != options.cend());
|
||||
for (auto&& feature_paragraph : source_control_file->feature_paragraphs)
|
||||
{
|
||||
do_print(source_control_file.core_paragraph.name,
|
||||
do_print(source_control_file->core_paragraph->name,
|
||||
*feature_paragraph,
|
||||
options.find(OPTION_FULLDESC) != options.cend());
|
||||
}
|
||||
@ -133,9 +133,9 @@ namespace vcpkg::Commands::Search
|
||||
|
||||
// At this point there is 1 argument
|
||||
auto&& args_zero = args.command_arguments[0];
|
||||
for (const SourceControlFile& source_control_file : source_paragraphs)
|
||||
for (const auto& source_control_file : source_paragraphs)
|
||||
{
|
||||
auto&& sp = source_control_file.core_paragraph;
|
||||
auto&& sp = *source_control_file->core_paragraph;
|
||||
|
||||
bool contains_name = icontains(sp.name, args_zero);
|
||||
if (contains_name || icontains(sp.description, args_zero))
|
||||
@ -143,7 +143,7 @@ namespace vcpkg::Commands::Search
|
||||
do_print(sp, options.find(OPTION_FULLDESC) != options.cend());
|
||||
}
|
||||
|
||||
for (auto&& feature_paragraph : source_control_file.feature_paragraphs)
|
||||
for (auto&& feature_paragraph : source_control_file->feature_paragraphs)
|
||||
{
|
||||
if (contains_name || icontains(feature_paragraph->name, args_zero) ||
|
||||
icontains(feature_paragraph->description, args_zero))
|
||||
|
@ -15,10 +15,8 @@ namespace vcpkg::Commands::Update
|
||||
|
||||
std::vector<OutdatedPackage> find_outdated_packages(const VcpkgPaths& paths, const StatusParagraphs& status_db)
|
||||
{
|
||||
auto source_control_files = Paragraphs::load_all_ports(paths.get_filesystem(), paths.ports);
|
||||
const std::vector<SourceParagraph> source_paragraphs = getSourceParagraphs(source_control_files);
|
||||
const std::map<std::string, VersionT> src_names_to_versions =
|
||||
Paragraphs::extract_port_names_and_versions(source_paragraphs);
|
||||
Paragraphs::load_all_port_names_and_versions(paths.get_filesystem(), paths.ports);
|
||||
const std::vector<StatusParagraph*> installed_packages = get_installed_ports(status_db);
|
||||
|
||||
std::vector<OutdatedPackage> output;
|
||||
@ -67,7 +65,8 @@ namespace vcpkg::Commands::Update
|
||||
System::println("\n"
|
||||
"To update these packages, run\n"
|
||||
" .\\vcpkg remove --outdated\n"
|
||||
" .\\vcpkg install " + install_line);
|
||||
" .\\vcpkg install " +
|
||||
install_line);
|
||||
}
|
||||
|
||||
auto version_file = paths.get_filesystem().read_contents(paths.root / "toolsrc" / "VERSION.txt");
|
||||
|
@ -33,11 +33,11 @@ namespace UnitTest1
|
||||
Assert::IsTrue(m_pgh.has_value());
|
||||
auto& pgh = *m_pgh.get();
|
||||
|
||||
Assert::AreEqual("zlib", pgh.core_paragraph.name.c_str());
|
||||
Assert::AreEqual("1.2.8", pgh.core_paragraph.version.c_str());
|
||||
Assert::AreEqual("", pgh.core_paragraph.maintainer.c_str());
|
||||
Assert::AreEqual("", pgh.core_paragraph.description.c_str());
|
||||
Assert::AreEqual(size_t(0), pgh.core_paragraph.depends.size());
|
||||
Assert::AreEqual("zlib", pgh->core_paragraph->name.c_str());
|
||||
Assert::AreEqual("1.2.8", pgh->core_paragraph->version.c_str());
|
||||
Assert::AreEqual("", pgh->core_paragraph->maintainer.c_str());
|
||||
Assert::AreEqual("", pgh->core_paragraph->description.c_str());
|
||||
Assert::AreEqual(size_t(0), pgh->core_paragraph->depends.size());
|
||||
}
|
||||
|
||||
TEST_METHOD(SourceParagraph_Construct_Maximum)
|
||||
@ -54,14 +54,14 @@ namespace UnitTest1
|
||||
Assert::IsTrue(m_pgh.has_value());
|
||||
auto& pgh = *m_pgh.get();
|
||||
|
||||
Assert::AreEqual("s", pgh.core_paragraph.name.c_str());
|
||||
Assert::AreEqual("v", pgh.core_paragraph.version.c_str());
|
||||
Assert::AreEqual("m", pgh.core_paragraph.maintainer.c_str());
|
||||
Assert::AreEqual("d", pgh.core_paragraph.description.c_str());
|
||||
Assert::AreEqual(size_t(1), pgh.core_paragraph.depends.size());
|
||||
Assert::AreEqual("bd", pgh.core_paragraph.depends[0].name.c_str());
|
||||
Assert::AreEqual(size_t(1), pgh.core_paragraph.supports.size());
|
||||
Assert::AreEqual("x64", pgh.core_paragraph.supports[0].c_str());
|
||||
Assert::AreEqual("s", pgh->core_paragraph->name.c_str());
|
||||
Assert::AreEqual("v", pgh->core_paragraph->version.c_str());
|
||||
Assert::AreEqual("m", pgh->core_paragraph->maintainer.c_str());
|
||||
Assert::AreEqual("d", pgh->core_paragraph->description.c_str());
|
||||
Assert::AreEqual(size_t(1), pgh->core_paragraph->depends.size());
|
||||
Assert::AreEqual("bd", pgh->core_paragraph->depends[0].name.c_str());
|
||||
Assert::AreEqual(size_t(1), pgh->core_paragraph->supports.size());
|
||||
Assert::AreEqual("x64", pgh->core_paragraph->supports[0].c_str());
|
||||
}
|
||||
|
||||
TEST_METHOD(SourceParagraph_Two_Depends)
|
||||
@ -73,9 +73,9 @@ namespace UnitTest1
|
||||
Assert::IsTrue(m_pgh.has_value());
|
||||
auto& pgh = *m_pgh.get();
|
||||
|
||||
Assert::AreEqual(size_t(2), pgh.core_paragraph.depends.size());
|
||||
Assert::AreEqual("z", pgh.core_paragraph.depends[0].name.c_str());
|
||||
Assert::AreEqual("openssl", pgh.core_paragraph.depends[1].name.c_str());
|
||||
Assert::AreEqual(size_t(2), pgh->core_paragraph->depends.size());
|
||||
Assert::AreEqual("z", pgh->core_paragraph->depends[0].name.c_str());
|
||||
Assert::AreEqual("openssl", pgh->core_paragraph->depends[1].name.c_str());
|
||||
}
|
||||
|
||||
TEST_METHOD(SourceParagraph_Three_Depends)
|
||||
@ -87,10 +87,10 @@ namespace UnitTest1
|
||||
Assert::IsTrue(m_pgh.has_value());
|
||||
auto& pgh = *m_pgh.get();
|
||||
|
||||
Assert::AreEqual(size_t(3), pgh.core_paragraph.depends.size());
|
||||
Assert::AreEqual("z", pgh.core_paragraph.depends[0].name.c_str());
|
||||
Assert::AreEqual("openssl", pgh.core_paragraph.depends[1].name.c_str());
|
||||
Assert::AreEqual("xyz", pgh.core_paragraph.depends[2].name.c_str());
|
||||
Assert::AreEqual(size_t(3), pgh->core_paragraph->depends.size());
|
||||
Assert::AreEqual("z", pgh->core_paragraph->depends[0].name.c_str());
|
||||
Assert::AreEqual("openssl", pgh->core_paragraph->depends[1].name.c_str());
|
||||
Assert::AreEqual("xyz", pgh->core_paragraph->depends[2].name.c_str());
|
||||
}
|
||||
|
||||
TEST_METHOD(SourceParagraph_Three_Supports)
|
||||
@ -102,10 +102,10 @@ namespace UnitTest1
|
||||
Assert::IsTrue(m_pgh.has_value());
|
||||
auto& pgh = *m_pgh.get();
|
||||
|
||||
Assert::AreEqual(size_t(3), pgh.core_paragraph.supports.size());
|
||||
Assert::AreEqual("x64", pgh.core_paragraph.supports[0].c_str());
|
||||
Assert::AreEqual("windows", pgh.core_paragraph.supports[1].c_str());
|
||||
Assert::AreEqual("uwp", pgh.core_paragraph.supports[2].c_str());
|
||||
Assert::AreEqual(size_t(3), pgh->core_paragraph->supports.size());
|
||||
Assert::AreEqual("x64", pgh->core_paragraph->supports[0].c_str());
|
||||
Assert::AreEqual("windows", pgh->core_paragraph->supports[1].c_str());
|
||||
Assert::AreEqual("uwp", pgh->core_paragraph->supports[2].c_str());
|
||||
}
|
||||
|
||||
TEST_METHOD(SourceParagraph_Construct_Qualified_Depends)
|
||||
@ -117,15 +117,15 @@ namespace UnitTest1
|
||||
Assert::IsTrue(m_pgh.has_value());
|
||||
auto& pgh = *m_pgh.get();
|
||||
|
||||
Assert::AreEqual("zlib", pgh.core_paragraph.name.c_str());
|
||||
Assert::AreEqual("1.2.8", pgh.core_paragraph.version.c_str());
|
||||
Assert::AreEqual("", pgh.core_paragraph.maintainer.c_str());
|
||||
Assert::AreEqual("", pgh.core_paragraph.description.c_str());
|
||||
Assert::AreEqual(size_t(2), pgh.core_paragraph.depends.size());
|
||||
Assert::AreEqual("libA", pgh.core_paragraph.depends[0].name.c_str());
|
||||
Assert::AreEqual("windows", pgh.core_paragraph.depends[0].qualifier.c_str());
|
||||
Assert::AreEqual("libB", pgh.core_paragraph.depends[1].name.c_str());
|
||||
Assert::AreEqual("uwp", pgh.core_paragraph.depends[1].qualifier.c_str());
|
||||
Assert::AreEqual("zlib", pgh->core_paragraph->name.c_str());
|
||||
Assert::AreEqual("1.2.8", pgh->core_paragraph->version.c_str());
|
||||
Assert::AreEqual("", pgh->core_paragraph->maintainer.c_str());
|
||||
Assert::AreEqual("", pgh->core_paragraph->description.c_str());
|
||||
Assert::AreEqual(size_t(2), pgh->core_paragraph->depends.size());
|
||||
Assert::AreEqual("libA", pgh->core_paragraph->depends[0].name.c_str());
|
||||
Assert::AreEqual("windows", pgh->core_paragraph->depends[0].qualifier.c_str());
|
||||
Assert::AreEqual("libB", pgh->core_paragraph->depends[1].name.c_str());
|
||||
Assert::AreEqual("uwp", pgh->core_paragraph->depends[1].qualifier.c_str());
|
||||
}
|
||||
|
||||
TEST_METHOD(BinaryParagraph_Construct_Minimum)
|
||||
|
@ -11,7 +11,6 @@
|
||||
#include "vcpkg_System.h"
|
||||
#include "vcpkg_optional.h"
|
||||
#include "vcpkglib.h"
|
||||
#include "vcpkglib_helpers.h"
|
||||
|
||||
namespace vcpkg::Build
|
||||
{
|
||||
@ -218,56 +217,52 @@ namespace vcpkg::Build
|
||||
|
||||
static BuildInfo inner_create_buildinfo(std::unordered_map<std::string, std::string> pgh)
|
||||
{
|
||||
Parse::ParagraphParser parser(std::move(pgh));
|
||||
|
||||
BuildInfo build_info;
|
||||
const std::string crt_linkage_as_string =
|
||||
details::remove_required_field(&pgh, BuildInfoRequiredField::CRT_LINKAGE);
|
||||
|
||||
auto crtlinkage = to_linkage_type(crt_linkage_as_string);
|
||||
if (auto p = crtlinkage.get())
|
||||
build_info.crt_linkage = *p;
|
||||
else
|
||||
Checks::exit_with_message(VCPKG_LINE_INFO, "Invalid crt linkage type: [%s]", crt_linkage_as_string);
|
||||
|
||||
const std::string library_linkage_as_string =
|
||||
details::remove_required_field(&pgh, BuildInfoRequiredField::LIBRARY_LINKAGE);
|
||||
auto liblinkage = to_linkage_type(library_linkage_as_string);
|
||||
if (auto p = liblinkage.get())
|
||||
build_info.library_linkage = *p;
|
||||
else
|
||||
Checks::exit_with_message(VCPKG_LINE_INFO, "Invalid library linkage type: [%s]", library_linkage_as_string);
|
||||
|
||||
auto it_version = pgh.find("Version");
|
||||
if (it_version != pgh.end())
|
||||
{
|
||||
build_info.version = it_version->second;
|
||||
pgh.erase(it_version);
|
||||
std::string crt_linkage_as_string;
|
||||
parser.required_field(BuildInfoRequiredField::CRT_LINKAGE, crt_linkage_as_string);
|
||||
|
||||
auto crtlinkage = to_linkage_type(crt_linkage_as_string);
|
||||
if (auto p = crtlinkage.get())
|
||||
build_info.crt_linkage = *p;
|
||||
else
|
||||
Checks::exit_with_message(VCPKG_LINE_INFO, "Invalid crt linkage type: [%s]", crt_linkage_as_string);
|
||||
}
|
||||
|
||||
std::map<BuildPolicy, bool> policies;
|
||||
|
||||
// The remaining entries are policies
|
||||
for (const std::unordered_map<std::string, std::string>::value_type& p : pgh)
|
||||
{
|
||||
auto maybe_policy = to_build_policy(p.first);
|
||||
if (auto policy = maybe_policy.get())
|
||||
{
|
||||
Checks::check_exit(VCPKG_LINE_INFO,
|
||||
policies.find(*policy) == policies.end(),
|
||||
"Policy specified multiple times: %s",
|
||||
p.first);
|
||||
|
||||
if (p.second == "enabled")
|
||||
policies.emplace(*policy, true);
|
||||
else if (p.second == "disabled")
|
||||
policies.emplace(*policy, false);
|
||||
else
|
||||
Checks::exit_with_message(
|
||||
VCPKG_LINE_INFO, "Unknown setting for policy '%s': %s", p.first, p.second);
|
||||
}
|
||||
std::string library_linkage_as_string;
|
||||
parser.required_field(BuildInfoRequiredField::LIBRARY_LINKAGE, library_linkage_as_string);
|
||||
auto liblinkage = to_linkage_type(library_linkage_as_string);
|
||||
if (auto p = liblinkage.get())
|
||||
build_info.library_linkage = *p;
|
||||
else
|
||||
{
|
||||
Checks::exit_with_message(VCPKG_LINE_INFO, "Unknown policy found: %s", p.first);
|
||||
}
|
||||
Checks::exit_with_message(
|
||||
VCPKG_LINE_INFO, "Invalid library linkage type: [%s]", library_linkage_as_string);
|
||||
}
|
||||
build_info.version = parser.optional_field("Version");
|
||||
|
||||
std::map<BuildPolicy, bool> policies;
|
||||
for (auto policy : g_all_policies)
|
||||
{
|
||||
const auto setting = parser.optional_field(to_string(policy));
|
||||
if (setting.empty())
|
||||
continue;
|
||||
else if (setting == "enabled")
|
||||
policies.emplace(policy, true);
|
||||
else if (setting == "disabled")
|
||||
policies.emplace(policy, false);
|
||||
else
|
||||
Checks::exit_with_message(
|
||||
VCPKG_LINE_INFO, "Unknown setting for policy '%s': %s", to_string(policy), setting);
|
||||
}
|
||||
|
||||
if (auto err = parser.error_info("PostBuildInformation"))
|
||||
{
|
||||
print_error_message(err);
|
||||
Checks::exit_fail(VCPKG_LINE_INFO);
|
||||
}
|
||||
|
||||
build_info.policies = BuildPolicies(std::move(policies));
|
||||
|
@ -12,17 +12,6 @@ namespace vcpkg::Build
|
||||
static const std::string NAME_EMPTY_INCLUDE_FOLDER = "PolicyEmptyIncludeFolder";
|
||||
static const std::string NAME_ALLOW_OBSOLETE_MSVCRT = "PolicyAllowObsoleteMsvcrt";
|
||||
|
||||
Optional<BuildPolicy> to_build_policy(const std::string& s)
|
||||
{
|
||||
if (s == NAME_EMPTY_PACKAGE) return BuildPolicy::EMPTY_PACKAGE;
|
||||
if (s == NAME_DLLS_WITHOUT_LIBS) return BuildPolicy::DLLS_WITHOUT_LIBS;
|
||||
if (s == NAME_ONLY_RELEASE_CRT) return BuildPolicy::ONLY_RELEASE_CRT;
|
||||
if (s == NAME_EMPTY_INCLUDE_FOLDER) return BuildPolicy::EMPTY_INCLUDE_FOLDER;
|
||||
if (s == NAME_ALLOW_OBSOLETE_MSVCRT) return BuildPolicy::ALLOW_OBSOLETE_MSVCRT;
|
||||
|
||||
return nullopt;
|
||||
}
|
||||
|
||||
const std::string& to_string(BuildPolicy policy)
|
||||
{
|
||||
switch (policy)
|
||||
|
@ -174,12 +174,11 @@ namespace vcpkg::Dependencies
|
||||
if (auto bpgh = maybe_bpgh.get())
|
||||
return InstallPlanAction{spec, {nullopt, *bpgh, nullopt}, request_type};
|
||||
|
||||
ExpectedT<SourceControlFile, ParseControlErrorInfo> source_control_file =
|
||||
Paragraphs::try_load_port(paths.get_filesystem(), paths.port_dir(spec));
|
||||
if (auto scf = source_control_file.get())
|
||||
return InstallPlanAction{spec, {nullopt, nullopt, (*scf).core_paragraph}, request_type};
|
||||
auto maybe_scf = Paragraphs::try_load_port(paths.get_filesystem(), paths.port_dir(spec));
|
||||
if (auto scf = maybe_scf.get())
|
||||
return InstallPlanAction{spec, {nullopt, nullopt, *scf->get()->core_paragraph}, request_type};
|
||||
|
||||
print_error_message(source_control_file.error());
|
||||
print_error_message(maybe_scf.error());
|
||||
Checks::exit_fail(VCPKG_LINE_INFO);
|
||||
}
|
||||
};
|
||||
@ -284,13 +283,11 @@ namespace vcpkg::Dependencies
|
||||
if (auto bpgh = maybe_bpgh.get())
|
||||
return ExportPlanAction{spec, {nullopt, *bpgh, nullopt}, request_type};
|
||||
|
||||
ExpectedT<SourceControlFile, ParseControlErrorInfo> source_control_file =
|
||||
Paragraphs::try_load_port(paths.get_filesystem(), paths.port_dir(spec));
|
||||
if (auto scf = source_control_file.get())
|
||||
return ExportPlanAction{spec, {nullopt, nullopt, (*scf).core_paragraph}, request_type};
|
||||
|
||||
auto maybe_scf = Paragraphs::try_load_port(paths.get_filesystem(), paths.port_dir(spec));
|
||||
if (auto scf = maybe_scf.get())
|
||||
return ExportPlanAction{spec, {nullopt, nullopt, *scf->get()->core_paragraph}, request_type};
|
||||
else
|
||||
print_error_message(source_control_file.error());
|
||||
print_error_message(maybe_scf.error());
|
||||
|
||||
Checks::exit_with_message(VCPKG_LINE_INFO, "Could not find package %s", spec);
|
||||
}
|
||||
|
59
toolsrc/src/vcpkg_Parse.cpp
Normal file
59
toolsrc/src/vcpkg_Parse.cpp
Normal file
@ -0,0 +1,59 @@
|
||||
#include "pch.h"
|
||||
|
||||
#include "vcpkg_Checks.h"
|
||||
#include "vcpkg_Maps.h"
|
||||
#include "vcpkg_Parse.h"
|
||||
|
||||
namespace vcpkg::Parse
|
||||
{
|
||||
static Optional<std::string> get_field(const std::unordered_map<std::string, std::string>& fields,
|
||||
const std::string& fieldname)
|
||||
{
|
||||
auto it = fields.find(fieldname);
|
||||
if (it == fields.end())
|
||||
{
|
||||
return nullopt;
|
||||
}
|
||||
|
||||
return it->second;
|
||||
}
|
||||
|
||||
static Optional<std::string> remove_field(std::unordered_map<std::string, std::string>* fields,
|
||||
const std::string& fieldname)
|
||||
{
|
||||
auto it = fields->find(fieldname);
|
||||
if (it == fields->end())
|
||||
{
|
||||
return nullopt;
|
||||
}
|
||||
|
||||
const std::string value = std::move(it->second);
|
||||
fields->erase(it);
|
||||
return value;
|
||||
}
|
||||
|
||||
void ParagraphParser::required_field(const std::string& fieldname, std::string& out)
|
||||
{
|
||||
auto maybe_field = remove_field(&fields, fieldname);
|
||||
if (auto field = maybe_field.get())
|
||||
out = std::move(*field);
|
||||
else
|
||||
missing_fields.push_back(fieldname);
|
||||
}
|
||||
std::string ParagraphParser::optional_field(const std::string& fieldname)
|
||||
{
|
||||
return remove_field(&fields, fieldname).value_or("");
|
||||
}
|
||||
std::unique_ptr<ParseControlErrorInfo> ParagraphParser::error_info(const std::string& name) const
|
||||
{
|
||||
if (!fields.empty() || !missing_fields.empty())
|
||||
{
|
||||
auto err = std::make_unique<ParseControlErrorInfo>();
|
||||
err->name = name;
|
||||
err->extra_fields = Maps::extract_keys(fields);
|
||||
err->missing_fields = std::move(missing_fields);
|
||||
return err;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
}
|
@ -31,7 +31,7 @@ namespace vcpkg
|
||||
std::vector<std::unique_ptr<StatusParagraph>> status_pghs;
|
||||
for (auto&& p : pghs)
|
||||
{
|
||||
status_pghs.push_back(std::make_unique<StatusParagraph>(p));
|
||||
status_pghs.push_back(std::make_unique<StatusParagraph>(std::move(p)));
|
||||
}
|
||||
|
||||
return StatusParagraphs(std::move(status_pghs));
|
||||
@ -69,7 +69,7 @@ namespace vcpkg
|
||||
auto pghs = Paragraphs::get_paragraphs(fs, file).value_or_exit(VCPKG_LINE_INFO);
|
||||
for (auto&& p : pghs)
|
||||
{
|
||||
current_status_db.insert(std::make_unique<StatusParagraph>(p));
|
||||
current_status_db.insert(std::make_unique<StatusParagraph>(std::move(p)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -239,4 +239,10 @@ namespace vcpkg
|
||||
return Strings::wformat(
|
||||
LR"("%s" %s -P "%s")", cmake_exe.native(), cmd_cmake_pass_variables, cmake_script.generic_wstring());
|
||||
}
|
||||
|
||||
std::string shorten_description(const std::string& desc)
|
||||
{
|
||||
auto simple_desc = std::regex_replace(desc, std::regex("\\s+"), " ");
|
||||
return simple_desc.size() <= 52 ? simple_desc : simple_desc.substr(0, 49) + "...";
|
||||
}
|
||||
}
|
||||
|
@ -1,56 +0,0 @@
|
||||
#include "pch.h"
|
||||
|
||||
#include "vcpkg_Checks.h"
|
||||
#include "vcpkglib_helpers.h"
|
||||
|
||||
namespace vcpkg::details
|
||||
{
|
||||
std::string optional_field(const std::unordered_map<std::string, std::string>& fields, const std::string& fieldname)
|
||||
{
|
||||
auto it = fields.find(fieldname);
|
||||
if (it == fields.end())
|
||||
{
|
||||
return std::string();
|
||||
}
|
||||
|
||||
return it->second;
|
||||
}
|
||||
|
||||
std::string remove_optional_field(std::unordered_map<std::string, std::string>* fields,
|
||||
const std::string& fieldname)
|
||||
{
|
||||
auto it = fields->find(fieldname);
|
||||
if (it == fields->end())
|
||||
{
|
||||
return std::string();
|
||||
}
|
||||
|
||||
const std::string value = std::move(it->second);
|
||||
fields->erase(it);
|
||||
return value;
|
||||
}
|
||||
|
||||
std::string required_field(const std::unordered_map<std::string, std::string>& fields, const std::string& fieldname)
|
||||
{
|
||||
auto it = fields.find(fieldname);
|
||||
Checks::check_exit(VCPKG_LINE_INFO, it != fields.end(), "Required field not present: %s", fieldname);
|
||||
return it->second;
|
||||
}
|
||||
|
||||
std::string remove_required_field(std::unordered_map<std::string, std::string>* fields,
|
||||
const std::string& fieldname)
|
||||
{
|
||||
auto it = fields->find(fieldname);
|
||||
Checks::check_exit(VCPKG_LINE_INFO, it != fields->end(), "Required field not present: %s", fieldname);
|
||||
|
||||
const std::string value = std::move(it->second);
|
||||
fields->erase(it);
|
||||
return value;
|
||||
}
|
||||
|
||||
std::string shorten_description(const std::string& desc)
|
||||
{
|
||||
auto simple_desc = std::regex_replace(desc, std::regex("\\s+"), " ");
|
||||
return simple_desc.size() <= 52 ? simple_desc : simple_desc.substr(0, 49) + "...";
|
||||
}
|
||||
}
|
@ -161,7 +161,7 @@
|
||||
<ClInclude Include="..\include\vcpkg_Chrono.h" />
|
||||
<ClInclude Include="..\include\triplet.h" />
|
||||
<ClInclude Include="..\include\vcpkglib.h" />
|
||||
<ClInclude Include="..\include\vcpkglib_helpers.h" />
|
||||
<ClInclude Include="..\include\vcpkg_Parse.h" />
|
||||
<ClInclude Include="..\include\vcpkg_Checks.h" />
|
||||
<ClInclude Include="..\include\VcpkgCmdArguments.h" />
|
||||
<ClInclude Include="..\include\vcpkg_Commands.h" />
|
||||
@ -227,7 +227,7 @@
|
||||
<ClCompile Include="..\src\StatusParagraph.cpp" />
|
||||
<ClCompile Include="..\src\StatusParagraphs.cpp" />
|
||||
<ClCompile Include="..\src\triplet.cpp" />
|
||||
<ClCompile Include="..\src\vcpkglib_helpers.cpp" />
|
||||
<ClCompile Include="..\src\vcpkg_Parse.cpp" />
|
||||
<ClCompile Include="..\src\vcpkg_Checks.cpp" />
|
||||
<ClCompile Include="..\src\VcpkgCmdArguments.cpp" />
|
||||
<ClCompile Include="..\src\vcpkg_Dependencies.cpp" />
|
||||
|
@ -30,9 +30,6 @@
|
||||
<ClCompile Include="..\src\triplet.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\vcpkglib_helpers.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\Paragraphs.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
@ -177,14 +174,14 @@
|
||||
<ClCompile Include="..\src\vcpkg_Build_BuildPolicy.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\vcpkg_Parse.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\include\SourceParagraph.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\vcpkglib_helpers.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\BinaryParagraph.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
@ -302,5 +299,8 @@
|
||||
<ClInclude Include="..\include\Span.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\vcpkg_Parse.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
Loading…
Reference in New Issue
Block a user