Merge branch 'master' into master

This commit is contained in:
Curtis J Bezault 2019-04-09 15:22:49 -07:00 committed by GitHub
commit b1b7ec5c0b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 106 additions and 46 deletions

View File

@ -112,12 +112,10 @@ namespace vcpkg::Strings
bool ends_with(StringView s, StringView pattern); bool ends_with(StringView s, StringView pattern);
bool starts_with(StringView s, StringView pattern); bool starts_with(StringView s, StringView pattern);
template<class Container, class Transformer> template<class InputIterator, class Transformer>
std::string join(const char* delimiter, const Container& v, Transformer transformer) std::string join(const char* delimiter, InputIterator begin, InputIterator end,
Transformer transformer)
{ {
const auto begin = v.begin();
const auto end = v.end();
if (begin == end) if (begin == end)
{ {
return std::string(); return std::string();
@ -133,6 +131,24 @@ namespace vcpkg::Strings
return output; return output;
} }
template<class Container, class Transformer>
std::string join(const char* delimiter, const Container& v, Transformer transformer)
{
const auto begin = v.begin();
const auto end = v.end();
return join(delimiter, begin, end, transformer);
}
template<class InputIterator>
std::string join(const char* delimiter, InputIterator begin, InputIterator end)
{
using Element = decltype(*begin);
return join(delimiter, begin, end,
[](const Element& x) -> const Element& { return x; });
}
template<class Container> template<class Container>
std::string join(const char* delimiter, const Container& v) std::string join(const char* delimiter, const Container& v)
{ {

View File

@ -479,13 +479,13 @@ namespace vcpkg::Build
const int max_port_file_count = 100; const int max_port_file_count = 100;
// the order of recursive_directory_iterator is undefined so save the names to sort // the order of recursive_directory_iterator is undefined so save the names to sort
std::vector<fs::path> port_files; std::vector<fs::path> hashed_files;
for (auto &port_file : fs::stdfs::recursive_directory_iterator(config.port_dir)) for (auto &port_file : fs::stdfs::recursive_directory_iterator(config.port_dir))
{ {
if (fs::is_regular_file(status(port_file))) if (fs::is_regular_file(status(port_file)))
{ {
port_files.push_back(port_file); hashed_files.push_back(port_file);
if (port_files.size() > max_port_file_count) if (hashed_files.size() > max_port_file_count)
{ {
abi_tag_entries.emplace_back(AbiEntry{ "no_hash_max_portfile", "" }); abi_tag_entries.emplace_back(AbiEntry{ "no_hash_max_portfile", "" });
break; break;
@ -493,12 +493,20 @@ namespace vcpkg::Build
} }
} }
if (port_files.size() <= max_port_file_count) if (hashed_files.size() <= max_port_file_count)
{ {
std::sort(port_files.begin(), port_files.end()); for (auto &script_file : fs::stdfs::recursive_directory_iterator(paths.scripts))
{
if (fs::is_regular_file(status(script_file)))
{
hashed_files.push_back(script_file);
}
}
std::sort(hashed_files.begin(), hashed_files.end());
int counter = 0; int counter = 0;
for (auto & port_file : port_files) for (auto & hashed_file : hashed_files)
{ {
// When vcpkg takes a dependency on C++17 it can use fs::relative, // When vcpkg takes a dependency on C++17 it can use fs::relative,
// which will give a stable ordering and better names in the key entry. // which will give a stable ordering and better names in the key entry.
@ -508,13 +516,13 @@ namespace vcpkg::Build
{ {
System::print2("[DEBUG] mapping ", key, " from ", port_file.u8string(), "\n"); System::print2("[DEBUG] mapping ", key, " from ", port_file.u8string(), "\n");
} }
abi_tag_entries.emplace_back(AbiEntry{ key, vcpkg::Hash::get_file_hash(fs, port_file, "SHA1") }); abi_tag_entries.emplace_back(AbiEntry{ key, vcpkg::Hash::get_file_hash(fs, hashed_file, "SHA1") });
} }
} }
abi_tag_entries.emplace_back(AbiEntry{ abi_tag_entries.emplace_back(AbiEntry{
"vcpkg_fixup_cmake_targets", "vcpkg",
vcpkg::Hash::get_file_hash(fs, paths.scripts / "cmake" / "vcpkg_fixup_cmake_targets.cmake", "SHA1")}); vcpkg::Hash::get_file_hash(fs, paths.scripts / "buildsystems" / "vcpkg.cmake", "SHA1")});
abi_tag_entries.emplace_back(AbiEntry{"triplet", pre_build_info.triplet_abi_tag}); abi_tag_entries.emplace_back(AbiEntry{"triplet", pre_build_info.triplet_abi_tag});

View File

@ -19,6 +19,8 @@ namespace vcpkg::Install
{ {
using namespace Dependencies; using namespace Dependencies;
using file_pack = std::pair<std::string, std::string>;
InstallDir InstallDir::from_destination_root(const fs::path& destination_root, InstallDir InstallDir::from_destination_root(const fs::path& destination_root,
const std::string& destination_subdirectory, const std::string& destination_subdirectory,
const fs::path& listfile) const fs::path& listfile)
@ -139,18 +141,12 @@ namespace vcpkg::Install
fs.write_lines(listfile, output); fs.write_lines(listfile, output);
} }
static void remove_first_n_chars(std::vector<std::string>* strings, const size_t n) static std::vector<file_pack> extract_files_in_triplet(
const std::vector<StatusParagraphAndAssociatedFiles>& pgh_and_files,
const Triplet& triplet,
const size_t remove_chars = 0)
{ {
for (std::string& s : *strings) std::vector<file_pack> output;
{
s.erase(0, n);
}
};
static std::vector<std::string> extract_files_in_triplet(
const std::vector<StatusParagraphAndAssociatedFiles>& pgh_and_files, const Triplet& triplet)
{
std::vector<std::string> output;
for (const StatusParagraphAndAssociatedFiles& t : pgh_and_files) for (const StatusParagraphAndAssociatedFiles& t : pgh_and_files)
{ {
if (t.pgh.package.spec.triplet() != triplet) if (t.pgh.package.spec.triplet() != triplet)
@ -158,10 +154,16 @@ namespace vcpkg::Install
continue; continue;
} }
Util::Vectors::concatenate(&output, t.files); const std::string name = t.pgh.package.displayname();
for (const std::string &file : t.files)
{
output.emplace_back(file_pack{std::string(file, remove_chars), name});
}
} }
std::sort(output.begin(), output.end()); std::sort(output.begin(), output.end(),
[](const file_pack &lhs, const file_pack &rhs) { return lhs.first < rhs.first; });
return output; return output;
} }
@ -171,22 +173,21 @@ namespace vcpkg::Install
const std::vector<fs::path> package_file_paths = fs.get_files_recursive(package_dir); const std::vector<fs::path> package_file_paths = fs.get_files_recursive(package_dir);
const size_t package_remove_char_count = package_dir.generic_string().size() + 1; // +1 for the slash const size_t package_remove_char_count = package_dir.generic_string().size() + 1; // +1 for the slash
auto package_files = Util::fmap(package_file_paths, [package_remove_char_count](const fs::path& path) { auto package_files = Util::fmap(package_file_paths, [package_remove_char_count](const fs::path& path) {
std::string as_string = path.generic_string(); return std::move(std::string(path.generic_string(), package_remove_char_count));
as_string.erase(0, package_remove_char_count);
return std::move(as_string);
}); });
return SortedVector<std::string>(std::move(package_files)); return SortedVector<std::string>(std::move(package_files));
} }
static SortedVector<std::string> build_list_of_installed_files( static SortedVector<file_pack> build_list_of_installed_files(
const std::vector<StatusParagraphAndAssociatedFiles>& pgh_and_files, const Triplet& triplet) const std::vector<StatusParagraphAndAssociatedFiles>& pgh_and_files,
const Triplet& triplet)
{ {
std::vector<std::string> installed_files = extract_files_in_triplet(pgh_and_files, triplet);
const size_t installed_remove_char_count = triplet.canonical_name().size() + 1; // +1 for the slash const size_t installed_remove_char_count = triplet.canonical_name().size() + 1; // +1 for the slash
remove_first_n_chars(&installed_files, installed_remove_char_count); std::vector<file_pack> installed_files =
extract_files_in_triplet(pgh_and_files, triplet, installed_remove_char_count);
return SortedVector<std::string>(std::move(installed_files)); return SortedVector<file_pack>(std::move(installed_files));
} }
InstallResult install_package(const VcpkgPaths& paths, const BinaryControlFile& bcf, StatusParagraphs* status_db) InstallResult install_package(const VcpkgPaths& paths, const BinaryControlFile& bcf, StatusParagraphs* status_db)
@ -197,23 +198,58 @@ namespace vcpkg::Install
const SortedVector<std::string> package_files = const SortedVector<std::string> package_files =
build_list_of_package_files(paths.get_filesystem(), package_dir); build_list_of_package_files(paths.get_filesystem(), package_dir);
const SortedVector<std::string> installed_files = build_list_of_installed_files(pgh_and_files, triplet); const SortedVector<file_pack> installed_files =
build_list_of_installed_files(pgh_and_files, triplet);
std::vector<std::string> intersection; struct intersection_compare
std::set_intersection(package_files.begin(), {
package_files.end(), bool operator()(const std::string &lhs, const file_pack &rhs) { return lhs < rhs.first; }
installed_files.begin(), bool operator()(const file_pack &lhs, const std::string &rhs) { return lhs.first < rhs; }
};
std::vector<file_pack> intersection;
std::set_intersection(installed_files.begin(),
installed_files.end(), installed_files.end(),
std::back_inserter(intersection)); package_files.begin(),
package_files.end(),
std::back_inserter(intersection),
intersection_compare());
std::sort(intersection.begin(), intersection.end(),
[](const file_pack &lhs, const file_pack &rhs)
{
return lhs.second < rhs.second;
});
if (!intersection.empty()) if (!intersection.empty())
{ {
const fs::path triplet_install_path = paths.installed / triplet.canonical_name(); const fs::path triplet_install_path = paths.installed / triplet.canonical_name();
System::printf(System::Color::error,
"The following files are already installed in %s and are in conflict with %s\n", System::println(System::Color::error,
triplet_install_path.generic_string(), "The following files are already installed in %s by and are in conflict with %s\n",
bcf.core_paragraph.spec); triplet_install_path.generic_string(),
System::print2("\n ", Strings::join("\n ", intersection), "\n\n"); bcf.core_paragraph.spec);
auto i = intersection.begin();
while (i != intersection.end()) {
System::printf("%s:\n ", i->second);
auto next = std::find_if(i, intersection.end(),
[i](const auto &val)
{
return i->second != val.second;
});
System::print2(Strings::join("\n ", i, next,
[](const file_pack &file)
{
return file.first;
}));
System::println();
i = next;
}
return InstallResult::FILE_CONFLICTS; return InstallResult::FILE_CONFLICTS;
} }