[vcpkg] Use unique_ptr<> for paragraphs. Post-parser phase rework.

This commit is contained in:
Robert Schumacher 2017-06-17 02:39:14 -07:00
parent 8c4d55b8f3
commit 8741214bf6
28 changed files with 390 additions and 379 deletions

View File

@ -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);
}

View File

@ -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});
}

View File

@ -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;

View File

@ -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

View 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;
};
}

View File

@ -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; }

View File

@ -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

View File

@ -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);
}

View File

@ -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)

View File

@ -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;
}

View File

@ -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)

View File

@ -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;

View File

@ -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)

View File

@ -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)

View File

@ -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);
}

View File

@ -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));
}
}

View File

@ -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;
}

View File

@ -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))

View File

@ -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");

View File

@ -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)

View File

@ -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));

View File

@ -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)

View File

@ -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);
}

View 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;
}
}

View File

@ -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) + "...";
}
}

View File

@ -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) + "...";
}
}

View File

@ -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" />

View File

@ -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>