diff options
| author | Curtis.Bezault <cubezaul@microsoft.com> | 2019-04-09 15:04:44 -0700 |
|---|---|---|
| committer | Curtis.Bezault <cubezaul@microsoft.com> | 2019-04-09 15:04:44 -0700 |
| commit | 79682317c9e087dc1d1ae450e3edd03b0fa0cc59 (patch) | |
| tree | f8d8925970b5ebd31f123248e3e1472bd86e4e43 | |
| parent | e9d2a830206fac08f47e55c739a3f3fbe29855e9 (diff) | |
| download | vcpkg-79682317c9e087dc1d1ae450e3edd03b0fa0cc59.tar.gz vcpkg-79682317c9e087dc1d1ae450e3edd03b0fa0cc59.zip | |
Print what port installed confliciting files
| -rw-r--r-- | toolsrc/include/vcpkg/base/strings.h | 26 | ||||
| -rw-r--r-- | toolsrc/src/vcpkg/install.cpp | 95 |
2 files changed, 85 insertions, 36 deletions
diff --git a/toolsrc/include/vcpkg/base/strings.h b/toolsrc/include/vcpkg/base/strings.h index 4b39b0a28..04e85107e 100644 --- a/toolsrc/include/vcpkg/base/strings.h +++ b/toolsrc/include/vcpkg/base/strings.h @@ -56,12 +56,10 @@ namespace vcpkg::Strings bool case_insensitive_ascii_starts_with(const std::string& s, const std::string& pattern); bool ends_with(const std::string& s, StringLiteral pattern); - template<class Container, class Transformer> - std::string join(const char* delimiter, const Container& v, Transformer transformer) + template<class InputIterator, class 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) { return std::string(); @@ -77,6 +75,24 @@ namespace vcpkg::Strings 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> std::string join(const char* delimiter, const Container& v) { diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp index 434876871..7fc8b294b 100644 --- a/toolsrc/src/vcpkg/install.cpp +++ b/toolsrc/src/vcpkg/install.cpp @@ -19,6 +19,8 @@ namespace vcpkg::Install { using namespace Dependencies; + using file_pack = std::pair<std::string, std::string>; + InstallDir InstallDir::from_destination_root(const fs::path& destination_root, const std::string& destination_subdirectory, const fs::path& listfile) @@ -139,18 +141,12 @@ namespace vcpkg::Install fs.write_lines(listfile, output); } - static void remove_first_n_chars(std::vector<std::string>* strings, const size_t n) - { - for (std::string& s : *strings) - { - s.erase(0, n); - } - }; - - static std::vector<std::string> extract_files_in_triplet( - const std::vector<StatusParagraphAndAssociatedFiles>& pgh_and_files, const Triplet& triplet) + 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) { - std::vector<std::string> output; + std::vector<file_pack> output; for (const StatusParagraphAndAssociatedFiles& t : pgh_and_files) { if (t.pgh.package.spec.triplet() != triplet) @@ -158,10 +154,16 @@ namespace vcpkg::Install 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; } @@ -171,22 +173,21 @@ namespace vcpkg::Install 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 auto package_files = Util::fmap(package_file_paths, [package_remove_char_count](const fs::path& path) { - std::string as_string = path.generic_string(); - as_string.erase(0, package_remove_char_count); - return std::move(as_string); + return std::move(std::string(path.generic_string(), package_remove_char_count)); }); return SortedVector<std::string>(std::move(package_files)); } - static SortedVector<std::string> build_list_of_installed_files( - const std::vector<StatusParagraphAndAssociatedFiles>& pgh_and_files, const Triplet& triplet) + static SortedVector<file_pack> build_list_of_installed_files( + 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 - 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) @@ -197,25 +198,57 @@ namespace vcpkg::Install const SortedVector<std::string> package_files = 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; - std::set_intersection(package_files.begin(), - package_files.end(), - installed_files.begin(), + struct intersection_compare + { + bool operator()(const std::string &lhs, const file_pack &rhs) { return lhs < rhs.first; } + 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(), - 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()) { const fs::path triplet_install_path = paths.installed / triplet.canonical_name(); System::println(System::Color::error, - "The following files are already installed in %s and are in conflict with %s", + "The following files are already installed in %s by and are in conflict with %s\n", triplet_install_path.generic_string(), bcf.core_paragraph.spec); - System::print("\n "); - System::println(Strings::join("\n ", intersection)); - System::println(); + + auto i = intersection.begin(); + while (i != intersection.end()) { + System::println("%s:", i->second); + auto next = std::find_if(i, intersection.end(), + [i](const auto &val) + { + return i->second != val.second; + }); + + System::println(Strings::join("\n ", i, next, + [](const file_pack &file) + { + return file.first; + })); + System::println(); + + i = next; + } + return InstallResult::FILE_CONFLICTS; } |
