diff options
| author | Robert Schumacher <roschuma@microsoft.com> | 2017-04-08 20:19:35 -0700 |
|---|---|---|
| committer | Robert Schumacher <roschuma@microsoft.com> | 2017-04-08 20:19:35 -0700 |
| commit | b34c40a4e674f5db538e84ca2b9509482ac140e7 (patch) | |
| tree | 48a09d41e4760d97a20386dce00105cae54b1f17 | |
| parent | c434dc99868989ca55aef5e445ac6a0a4c3430f7 (diff) | |
| download | vcpkg-b34c40a4e674f5db538e84ca2b9509482ac140e7.tar.gz vcpkg-b34c40a4e674f5db538e84ca2b9509482ac140e7.zip | |
[vcpkg] Further work on filesystem abstraction layer.
| -rw-r--r-- | toolsrc/include/Paragraphs.h | 8 | ||||
| -rw-r--r-- | toolsrc/include/PostBuildLint_BuildInfo.h | 2 | ||||
| -rw-r--r-- | toolsrc/include/vcpkg_Files.h | 57 | ||||
| -rw-r--r-- | toolsrc/include/vcpkg_Util.h | 6 | ||||
| -rw-r--r-- | toolsrc/src/Paragraphs.cpp | 8 | ||||
| -rw-r--r-- | toolsrc/src/PostBuildLint.cpp | 204 | ||||
| -rw-r--r-- | toolsrc/src/PostBuildLint_BuildInfo.cpp | 2 | ||||
| -rw-r--r-- | toolsrc/src/VcpkgPaths.cpp | 17 | ||||
| -rw-r--r-- | toolsrc/src/commands_import.cpp | 59 | ||||
| -rw-r--r-- | toolsrc/src/commands_install.cpp | 35 | ||||
| -rw-r--r-- | toolsrc/src/vcpkg.cpp | 2 | ||||
| -rw-r--r-- | toolsrc/src/vcpkg_Files.cpp | 175 | ||||
| -rw-r--r-- | toolsrc/src/vcpkglib.cpp | 62 |
13 files changed, 339 insertions, 298 deletions
diff --git a/toolsrc/include/Paragraphs.h b/toolsrc/include/Paragraphs.h index cdd35e425..cf21635d7 100644 --- a/toolsrc/include/Paragraphs.h +++ b/toolsrc/include/Paragraphs.h @@ -11,16 +11,16 @@ namespace vcpkg::Paragraphs { using ParagraphDataMap = std::unordered_map<std::string, std::string>; - Expected<ParagraphDataMap> get_single_paragraph(Files::Filesystem& fs, const fs::path& control_path); - Expected<std::vector<ParagraphDataMap>> get_paragraphs(Files::Filesystem& fs, const fs::path& control_path); + 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<SourceParagraph> try_load_port(Files::Filesystem& fs, const fs::path& control_path); + Expected<SourceParagraph> try_load_port(const Files::Filesystem& fs, const fs::path& control_path); Expected<BinaryParagraph> try_load_cached_package(const VcpkgPaths& paths, const PackageSpec& spec); - std::vector<SourceParagraph> load_all_ports(Files::Filesystem& fs, const fs::path& ports_dir); + std::vector<SourceParagraph> 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); } diff --git a/toolsrc/include/PostBuildLint_BuildInfo.h b/toolsrc/include/PostBuildLint_BuildInfo.h index c54ea0fa5..44776d918 100644 --- a/toolsrc/include/PostBuildLint_BuildInfo.h +++ b/toolsrc/include/PostBuildLint_BuildInfo.h @@ -18,5 +18,5 @@ namespace vcpkg::PostBuildLint std::map<BuildPolicies::Type, OptBoolT> policies; }; - BuildInfo read_build_info(Files::Filesystem& fs, const fs::path& filepath); + BuildInfo read_build_info(const Files::Filesystem& fs, const fs::path& filepath); } diff --git a/toolsrc/include/vcpkg_Files.h b/toolsrc/include/vcpkg_Files.h index a114354bc..339b64364 100644 --- a/toolsrc/include/vcpkg_Files.h +++ b/toolsrc/include/vcpkg_Files.h @@ -2,13 +2,27 @@ #include "vcpkg_expected.h" #include "filesystem_fs.h" -#include <iterator> namespace vcpkg::Files { __interface Filesystem { - virtual Expected<std::string> read_contents(const fs::path& file_path) noexcept = 0; + virtual Expected<std::string> read_contents(const fs::path& file_path) const = 0; + virtual Expected<std::vector<std::string>> read_all_lines(const fs::path& file_path) const = 0; + virtual fs::path find_file_recursively_up(const fs::path& starting_dir, const std::string& filename) const = 0; + virtual std::vector<fs::path> recursive_find_all_files_in_dir(const fs::path& dir) const = 0; + virtual std::vector<fs::path> non_recursive_find_all_files_in_dir(const fs::path& dir) const = 0; + + virtual void write_all_lines(const fs::path& file_path, const std::vector<std::string>& lines) = 0; + virtual void rename(const fs::path& oldpath, const fs::path& newpath) = 0; + virtual void remove(const fs::path& path) = 0; + virtual bool exists(const fs::path& path) const = 0; + virtual bool is_directory(const fs::path& path) const = 0; + virtual bool is_regular_file(const fs::path& path) const = 0; + virtual bool is_empty(const fs::path& path) const = 0; + virtual bool create_directory(const fs::path& path, std::error_code& ec) = 0; + virtual void copy(const fs::path& oldpath, const fs::path& newpath, fs::copy_options opts) = 0; + virtual void copy_file(const fs::path& oldpath, const fs::path& newpath, fs::copy_options opts, std::error_code& ec) = 0; }; Filesystem& get_real_filesystem(); @@ -17,44 +31,5 @@ namespace vcpkg::Files bool has_invalid_chars_for_filesystem(const std::string& s); - - Expected<std::vector<std::string>> read_all_lines(const fs::path& file_path); - - void write_all_lines(const fs::path& file_path, const std::vector<std::string>& lines); - - fs::path find_file_recursively_up(const fs::path& starting_dir, const std::string& filename); - - template <class Pred> - void non_recursive_find_matching_paths_in_dir(const fs::path& dir, const Pred predicate, std::vector<fs::path>* output) - { - std::copy_if(fs::directory_iterator(dir), fs::directory_iterator(), std::back_inserter(*output), predicate); - } - - template <class Pred> - void recursive_find_matching_paths_in_dir(const fs::path& dir, const Pred predicate, std::vector<fs::path>* output) - { - std::copy_if(fs::recursive_directory_iterator(dir), fs::recursive_directory_iterator(), std::back_inserter(*output), predicate); - } - - template <class Pred> - std::vector<fs::path> recursive_find_matching_paths_in_dir(const fs::path& dir, const Pred predicate) - { - std::vector<fs::path> v; - recursive_find_matching_paths_in_dir(dir, predicate, &v); - return v; - } - - void recursive_find_files_with_extension_in_dir(const fs::path& dir, const std::string& extension, std::vector<fs::path>* output); - - std::vector<fs::path> recursive_find_files_with_extension_in_dir(const fs::path& dir, const std::string& extension); - - void recursive_find_all_files_in_dir(const fs::path& dir, std::vector<fs::path>* output); - - std::vector<fs::path> recursive_find_all_files_in_dir(const fs::path& dir); - - void non_recursive_find_all_files_in_dir(const fs::path& dir, std::vector<fs::path>* output); - - std::vector<fs::path> non_recursive_find_all_files_in_dir(const fs::path& dir); - void print_paths(const std::vector<fs::path>& paths); } diff --git a/toolsrc/include/vcpkg_Util.h b/toolsrc/include/vcpkg_Util.h index 4ebb2a802..cd8dab437 100644 --- a/toolsrc/include/vcpkg_Util.h +++ b/toolsrc/include/vcpkg_Util.h @@ -21,4 +21,10 @@ namespace vcpkg::Util return ret; } + + template<class Container, class Pred> + void unstable_keep_if(Container& cont, Pred pred) + { + cont.erase(std::partition(cont.begin(), cont.end(), pred), cont.end()); + } }
\ No newline at end of file diff --git a/toolsrc/src/Paragraphs.cpp b/toolsrc/src/Paragraphs.cpp index e94478041..48095848d 100644 --- a/toolsrc/src/Paragraphs.cpp +++ b/toolsrc/src/Paragraphs.cpp @@ -172,7 +172,7 @@ namespace vcpkg::Paragraphs } }; - Expected<std::unordered_map<std::string, std::string>> get_single_paragraph(Files::Filesystem& fs, const fs::path& control_path) + Expected<std::unordered_map<std::string, std::string>> get_single_paragraph(const Files::Filesystem& fs, const fs::path& control_path) { const Expected<std::string> contents = fs.read_contents(control_path); if (auto spgh = contents.get()) @@ -183,7 +183,7 @@ namespace vcpkg::Paragraphs return contents.error_code(); } - Expected<std::vector<std::unordered_map<std::string, std::string>>> get_paragraphs(Files::Filesystem& fs, const fs::path& control_path) + Expected<std::vector<std::unordered_map<std::string, std::string>>> get_paragraphs(const Files::Filesystem& fs, const fs::path& control_path) { const Expected<std::string> contents = fs.read_contents(control_path); if (auto spgh = contents.get()) @@ -211,7 +211,7 @@ namespace vcpkg::Paragraphs return Parser(str.c_str(), str.c_str() + str.size()).get_paragraphs(); } - Expected<SourceParagraph> try_load_port(Files::Filesystem& fs, const fs::path& path) + Expected<SourceParagraph> try_load_port(const Files::Filesystem& fs, const fs::path& path) { Expected<std::unordered_map<std::string, std::string>> pghs = get_single_paragraph(fs, path / "CONTROL"); if (auto p = pghs.get()) @@ -234,7 +234,7 @@ namespace vcpkg::Paragraphs return pghs.error_code(); } - std::vector<SourceParagraph> load_all_ports(Files::Filesystem& fs, const fs::path& ports_dir) + std::vector<SourceParagraph> load_all_ports(const Files::Filesystem& fs, const fs::path& ports_dir) { std::vector<SourceParagraph> output; for (auto it = fs::directory_iterator(ports_dir); it != fs::directory_iterator(); ++it) diff --git a/toolsrc/src/PostBuildLint.cpp b/toolsrc/src/PostBuildLint.cpp index d3acaefbb..2229c6843 100644 --- a/toolsrc/src/PostBuildLint.cpp +++ b/toolsrc/src/PostBuildLint.cpp @@ -2,6 +2,7 @@ #include "VcpkgPaths.h" #include "PackageSpec.h" #include "vcpkg_Files.h" +#include "vcpkg_Util.h" #include "vcpkg_System.h" #include "coff_file_reader.h" #include "PostBuildLint_BuildInfo.h" @@ -10,6 +11,14 @@ namespace vcpkg::PostBuildLint { + static auto has_extension_pred(const Files::Filesystem& fs, const std::string& ext) + { + return [&fs, ext](const fs::path& path) + { + return !fs.is_directory(path) && path.extension() == ext; + }; + } + enum class LintStatus { SUCCESS = 0, @@ -81,15 +90,16 @@ namespace vcpkg::PostBuildLint return LintStatus::SUCCESS; } - static LintStatus check_for_files_in_debug_include_directory(const fs::path& package_dir) + static LintStatus check_for_files_in_debug_include_directory(const Files::Filesystem& fs, const fs::path& package_dir) { const fs::path debug_include_dir = package_dir / "debug" / "include"; - std::vector<fs::path> files_found; - Files::recursive_find_matching_paths_in_dir(debug_include_dir, [&](const fs::path& current) - { - return !fs::is_directory(current) && current.extension() != ".ifc"; - }, &files_found); + std::vector<fs::path> files_found = fs.recursive_find_all_files_in_dir(debug_include_dir); + + Util::unstable_keep_if(files_found, [&fs](const fs::path& path) + { + return !fs.is_directory(path) && path.extension() != ".ifc"; + }); if (!files_found.empty()) { @@ -102,11 +112,11 @@ namespace vcpkg::PostBuildLint return LintStatus::SUCCESS; } - static LintStatus check_for_files_in_debug_share_directory(const fs::path& package_dir) + static LintStatus check_for_files_in_debug_share_directory(const Files::Filesystem& fs, const fs::path& package_dir) { const fs::path debug_share = package_dir / "debug" / "share"; - if (fs::exists(debug_share) && !fs::is_empty(debug_share)) + if (fs.exists(debug_share)) { System::println(System::Color::warning, "/debug/share should not exist. Please reorganize any important files, then use\n" " file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/debug/share)"); @@ -116,25 +126,38 @@ namespace vcpkg::PostBuildLint return LintStatus::SUCCESS; } - static LintStatus check_folder_lib_cmake(const fs::path& package_dir, const PackageSpec& spec) + static LintStatus check_folder_lib_cmake(const Files::Filesystem& fs, const fs::path& package_dir, const PackageSpec& spec) { const fs::path lib_cmake = package_dir / "lib" / "cmake"; - if (fs::exists(lib_cmake)) + if (fs.exists(lib_cmake)) { - System::println(System::Color::warning, "The /lib/cmake folder should be moved to /share/%s/cmake.", spec.name()); + System::println(System::Color::warning, "The /lib/cmake folder should be merged with /debug/lib/cmake and moved to /share/%s/cmake.", spec.name()); return LintStatus::ERROR_DETECTED; } return LintStatus::SUCCESS; } - static LintStatus check_for_misplaced_cmake_files(const fs::path& package_dir, const PackageSpec& spec) + static LintStatus check_for_misplaced_cmake_files(const Files::Filesystem& fs, const fs::path& package_dir, const PackageSpec& spec) { + std::vector<fs::path> dirs = + { + package_dir / "cmake", + package_dir / "debug" / "cmake", + package_dir / "lib" / "cmake", + package_dir / "debug" / "lib" / "cmake", + }; + std::vector<fs::path> misplaced_cmake_files; - Files::recursive_find_files_with_extension_in_dir(package_dir / "cmake", ".cmake", &misplaced_cmake_files); - Files::recursive_find_files_with_extension_in_dir(package_dir / "debug" / "cmake", ".cmake", &misplaced_cmake_files); - Files::recursive_find_files_with_extension_in_dir(package_dir / "lib" / "cmake", ".cmake", &misplaced_cmake_files); - Files::recursive_find_files_with_extension_in_dir(package_dir / "debug" / "lib" / "cmake", ".cmake", &misplaced_cmake_files); + for (auto&& dir : dirs) + { + auto files = fs.recursive_find_all_files_in_dir(dir); + for (auto&& file : files) + { + if (!fs.is_directory(file) && file.extension() == ".cmake") + misplaced_cmake_files.push_back(std::move(file)); + } + } if (!misplaced_cmake_files.empty()) { @@ -146,27 +169,26 @@ namespace vcpkg::PostBuildLint return LintStatus::SUCCESS; } - static LintStatus check_folder_debug_lib_cmake(const fs::path& package_dir) + static LintStatus check_folder_debug_lib_cmake(const Files::Filesystem& fs, const fs::path& package_dir, const PackageSpec& spec) { const fs::path lib_cmake_debug = package_dir / "debug" / "lib" / "cmake"; - if (fs::exists(lib_cmake_debug)) + if (fs.exists(lib_cmake_debug)) { - System::println(System::Color::warning, "The /debug/lib/cmake folder should be moved to just /debug/cmake"); + System::println(System::Color::warning, "The /debug/lib/cmake folder should be merged with /lib/cmake into /share/%s", spec.name()); return LintStatus::ERROR_DETECTED; } return LintStatus::SUCCESS; } - static LintStatus check_for_dlls_in_lib_dirs(const fs::path& package_dir) + static LintStatus check_for_dlls_in_lib_dir(const Files::Filesystem& fs, const fs::path& package_dir) { - std::vector<fs::path> dlls; - Files::recursive_find_files_with_extension_in_dir(package_dir / "lib", ".dll", &dlls); - Files::recursive_find_files_with_extension_in_dir(package_dir / "debug" / "lib", ".dll", &dlls); + std::vector<fs::path> dlls = fs.recursive_find_all_files_in_dir(package_dir / "lib"); + Util::unstable_keep_if(dlls, has_extension_pred(fs, ".dll")); if (!dlls.empty()) { - System::println(System::Color::warning, "\nThe following dlls were found in /lib and /debug/lib. Please move them to /bin or /debug/bin, respectively."); + System::println(System::Color::warning, "\nThe following dlls were found in /lib or /debug/lib. Please move them to /bin or /debug/bin, respectively."); Files::print_paths(dlls); return LintStatus::ERROR_DETECTED; } @@ -174,11 +196,11 @@ namespace vcpkg::PostBuildLint return LintStatus::SUCCESS; } - static LintStatus check_for_copyright_file(const PackageSpec& spec, const VcpkgPaths& paths) + static LintStatus check_for_copyright_file(const Files::Filesystem& fs, const PackageSpec& spec, const VcpkgPaths& paths) { const fs::path packages_dir = paths.packages / spec.dir(); const fs::path copyright_file = packages_dir / "share" / spec.name() / "copyright"; - if (fs::exists(copyright_file)) + if (fs.exists(copyright_file)) { return LintStatus::SUCCESS; } @@ -186,22 +208,26 @@ namespace vcpkg::PostBuildLint const fs::path current_buildtrees_dir_src = current_buildtrees_dir / "src"; std::vector<fs::path> potential_copyright_files; - // Only searching one level deep - for (auto it = fs::recursive_directory_iterator(current_buildtrees_dir_src); it != fs::recursive_directory_iterator(); ++it) + // We only search in the root of each unpacked source archive to reduce false positives + auto src_dirs = fs.non_recursive_find_all_files_in_dir(current_buildtrees_dir_src); + for (auto&& src_dir : src_dirs) { - if (it.depth() > 1) - { + if (!fs.is_directory(src_dir)) continue; - } - const std::string filename = it->path().filename().string(); - if (filename == "LICENSE" || filename == "LICENSE.txt" || filename == "COPYING") + auto src_files = fs.non_recursive_find_all_files_in_dir(src_dir); + for (auto&& src_file : src_files) { - potential_copyright_files.push_back(it->path()); + const std::string filename = src_file.filename().string(); + + if (filename == "LICENSE" || filename == "LICENSE.txt" || filename == "COPYING") + { + potential_copyright_files.push_back(src_file); + } } } - System::println(System::Color::warning, "The software license must be available at ${CURRENT_PACKAGES_DIR}/share/%s/copyright .", spec.name()); + System::println(System::Color::warning, "The software license must be available at ${CURRENT_PACKAGES_DIR}/share/%s/copyright", spec.name()); if (potential_copyright_files.size() == 1) // if there is only one candidate, provide the cmake lines needed to place it in the proper location { const fs::path found_file = potential_copyright_files[0]; @@ -209,28 +235,23 @@ namespace vcpkg::PostBuildLint System::println("\n file(COPY ${CURRENT_BUILDTREES_DIR}/%s DESTINATION ${CURRENT_PACKAGES_DIR}/share/%s)\n" " file(RENAME ${CURRENT_PACKAGES_DIR}/share/%s/%s ${CURRENT_PACKAGES_DIR}/share/%s/copyright)", relative_path.generic_string(), spec.name(), spec.name(), found_file.filename().generic_string(), spec.name()); - return LintStatus::ERROR_DETECTED; } - - if (potential_copyright_files.size() > 1) + else if (potential_copyright_files.size() > 1) { System::println(System::Color::warning, "The following files are potential copyright files:"); Files::print_paths(potential_copyright_files); } - - System::println(" %s/share/%s/copyright", packages_dir.generic_string(), spec.name()); return LintStatus::ERROR_DETECTED; } - static LintStatus check_for_exes(const fs::path& package_dir) + static LintStatus check_for_exes(const Files::Filesystem& fs, const fs::path& package_dir) { - std::vector<fs::path> exes; - Files::recursive_find_files_with_extension_in_dir(package_dir / "bin", ".exe", &exes); - Files::recursive_find_files_with_extension_in_dir(package_dir / "debug" / "bin", ".exe", &exes); + std::vector<fs::path> exes = fs.recursive_find_all_files_in_dir(package_dir / "bin"); + Util::unstable_keep_if(exes, has_extension_pred(fs, ".exe")); if (!exes.empty()) { - System::println(System::Color::warning, "The following EXEs were found in /bin and /debug/bin. EXEs are not valid distribution targets."); + System::println(System::Color::warning, "The following EXEs were found in /bin or /debug/bin. EXEs are not valid distribution targets."); Files::print_paths(exes); return LintStatus::ERROR_DETECTED; } @@ -433,7 +454,7 @@ namespace vcpkg::PostBuildLint if (lib_count == 0 && dll_count != 0) { - System::println(System::Color::warning, "Import libs were not present in %s", lib_dir.generic_string()); + System::println(System::Color::warning, "Import libs were not present in %s", lib_dir.u8string()); System::println(System::Color::warning, "If this is intended, add the following line in the portfile:\n" " SET(%s enabled)", BuildPolicies::DLLS_WITHOUT_LIBS.cmake_variable()); @@ -443,24 +464,24 @@ namespace vcpkg::PostBuildLint return LintStatus::SUCCESS; } - static LintStatus check_bin_folders_are_not_present_in_static_build(const fs::path& package_dir) + static LintStatus check_bin_folders_are_not_present_in_static_build(const Files::Filesystem& fs, const fs::path& package_dir) { const fs::path bin = package_dir / "bin"; const fs::path debug_bin = package_dir / "debug" / "bin"; - if (!fs::exists(bin) && !fs::exists(debug_bin)) + if (!fs.exists(bin) && !fs.exists(debug_bin)) { return LintStatus::SUCCESS; } - if (fs::exists(bin)) + if (fs.exists(bin)) { - System::println(System::Color::warning, R"(There should be no bin\ directory in a static build, but %s is present.)", bin.generic_string()); + System::println(System::Color::warning, R"(There should be no bin\ directory in a static build, but %s is present.)", bin.u8string()); } - if (fs::exists(debug_bin)) + if (fs.exists(debug_bin)) { - System::println(System::Color::warning, R"(There should be no debug\bin\ directory in a static build, but %s is present.)", debug_bin.generic_string()); + System::println(System::Color::warning, R"(There should be no debug\bin\ directory in a static build, but %s is present.)", debug_bin.u8string()); } System::println(System::Color::warning, R"(If the creation of bin\ and/or debug\bin\ cannot be disabled, use this in the portfile to remove them)" "\n" @@ -474,12 +495,14 @@ namespace vcpkg::PostBuildLint return LintStatus::ERROR_DETECTED; } - static LintStatus check_no_empty_folders(const fs::path& dir) + static LintStatus check_no_empty_folders(const Files::Filesystem& fs, const fs::path& dir) { - const std::vector<fs::path> empty_directories = Files::recursive_find_matching_paths_in_dir(dir, [](const fs::path& current) - { - return fs::is_directory(current) && fs::is_empty(current); - }); + std::vector<fs::path> empty_directories = fs.recursive_find_all_files_in_dir(dir); + + Util::unstable_keep_if(empty_directories, [&fs](const fs::path& current) + { + return fs.is_directory(current) && fs.is_empty(current); + }); if (!empty_directories.empty()) { @@ -590,22 +613,20 @@ namespace vcpkg::PostBuildLint return LintStatus::SUCCESS; } - static LintStatus check_no_files_in_package_dir_and_debug_dir(const fs::path& package_dir) + static LintStatus check_no_files_in_dir(const Files::Filesystem& fs, const fs::path& dir) { - std::vector<fs::path> misplaced_files; - - Files::non_recursive_find_matching_paths_in_dir(package_dir, [](const fs::path& current) - { - const std::string filename = current.filename().generic_string(); - return !fs::is_directory(current) && !((_stricmp(filename.c_str(), "CONTROL") == 0 || _stricmp(filename.c_str(), "BUILD_INFO") == 0)); - }, &misplaced_files); - - const fs::path debug_dir = package_dir / "debug"; - Files::non_recursive_find_all_files_in_dir(debug_dir, &misplaced_files); + std::vector<fs::path> misplaced_files = fs.non_recursive_find_all_files_in_dir(dir); + Util::unstable_keep_if(misplaced_files, [&fs](const fs::path& path) + { + const std::string filename = path.filename().generic_string(); + if (_stricmp(filename.c_str(), "CONTROL") == 0 || _stricmp(filename.c_str(), "BUILD_INFO") == 0) + return false; + return !fs.is_directory(path); + }); if (!misplaced_files.empty()) { - System::println(System::Color::warning, "The following files are placed in\n%s and\n%s: ", package_dir.generic_string(), debug_dir.generic_string()); + System::println(System::Color::warning, "The following files are placed in\n%s: ", dir.u8string()); Files::print_paths(misplaced_files); System::println(System::Color::warning, "Files cannot be present in those directories.\n"); return LintStatus::ERROR_DETECTED; @@ -621,10 +642,12 @@ namespace vcpkg::PostBuildLint static size_t perform_all_checks_and_return_error_count(const PackageSpec& spec, const VcpkgPaths& paths) { + const auto& fs = paths.get_filesystem(); + // for dumpbin const Toolset& toolset = paths.get_toolset(); - BuildInfo build_info = read_build_info(paths.get_filesystem(), paths.build_info_file_path(spec)); + BuildInfo build_info = read_build_info(fs, paths.build_info_file_path(spec)); const fs::path package_dir = paths.package_dir(spec); size_t error_count = 0; @@ -635,22 +658,26 @@ namespace vcpkg::PostBuildLint } error_count += check_for_files_in_include_directory(build_info.policies, package_dir); - error_count += check_for_files_in_debug_include_directory(package_dir); - error_count += check_for_files_in_debug_share_directory(package_dir); - error_count += check_folder_lib_cmake(package_dir, spec); - error_count += check_for_misplaced_cmake_files(package_dir, spec); - error_count += check_folder_debug_lib_cmake(package_dir); - error_count += check_for_dlls_in_lib_dirs(package_dir); - error_count += check_for_copyright_file(spec, paths); - error_count += check_for_exes(package_dir); + error_count += check_for_files_in_debug_include_directory(fs, package_dir); + error_count += check_for_files_in_debug_share_directory(fs, package_dir); + error_count += check_folder_lib_cmake(fs, package_dir, spec); + error_count += check_for_misplaced_cmake_files(fs, package_dir, spec); + error_count += check_folder_debug_lib_cmake(fs, package_dir, spec); + error_count += check_for_dlls_in_lib_dir(fs, package_dir); + error_count += check_for_dlls_in_lib_dir(fs, package_dir / "debug"); + error_count += check_for_copyright_file(fs, spec, paths); + error_count += check_for_exes(fs, package_dir); + error_count += check_for_exes(fs, package_dir / "debug"); const fs::path debug_lib_dir = package_dir / "debug" / "lib"; const fs::path release_lib_dir = package_dir / "lib"; const fs::path debug_bin_dir = package_dir / "debug" / "bin"; const fs::path release_bin_dir = package_dir / "bin"; - const std::vector<fs::path> debug_libs = Files::recursive_find_files_with_extension_in_dir(debug_lib_dir, ".lib"); - const std::vector<fs::path> release_libs = Files::recursive_find_files_with_extension_in_dir(release_lib_dir, ".lib"); + std::vector<fs::path> debug_libs = fs.recursive_find_all_files_in_dir(debug_lib_dir); + Util::unstable_keep_if(debug_libs, has_extension_pred(fs, ".lib")); + std::vector<fs::path> release_libs = fs.recursive_find_all_files_in_dir(release_lib_dir); + Util::unstable_keep_if(release_libs, has_extension_pred(fs, ".lib")); error_count += check_matching_debug_and_release_binaries(debug_libs, release_libs); @@ -664,8 +691,10 @@ namespace vcpkg::PostBuildLint { case LinkageType::BackingEnum::DYNAMIC: { - const std::vector<fs::path> debug_dlls = Files::recursive_find_files_with_extension_in_dir(debug_bin_dir, ".dll"); - const std::vector<fs::path> release_dlls = Files::recursive_find_files_with_extension_in_dir(release_bin_dir, ".dll"); + std::vector<fs::path> debug_dlls = fs.recursive_find_all_files_in_dir(debug_bin_dir); + Util::unstable_keep_if(debug_dlls, has_extension_pred(fs, ".dll")); + std::vector<fs::path> release_dlls = fs.recursive_find_all_files_in_dir(release_bin_dir); + Util::unstable_keep_if(release_dlls, has_extension_pred(fs, ".dll")); error_count += check_matching_debug_and_release_binaries(debug_dlls, release_dlls); @@ -685,11 +714,11 @@ namespace vcpkg::PostBuildLint } case LinkageType::BackingEnum::STATIC: { - std::vector<fs::path> dlls; - Files::recursive_find_files_with_extension_in_dir(package_dir, ".dll", &dlls); + std::vector<fs::path> dlls = fs.recursive_find_all_files_in_dir(package_dir); + Util::unstable_keep_if(dlls, has_extension_pred(fs, ".dll")); error_count += check_no_dlls_present(dlls); - error_count += check_bin_folders_are_not_present_in_static_build(package_dir); + error_count += check_bin_folders_are_not_present_in_static_build(fs, package_dir); if (!contains_and_enabled(build_info.policies, BuildPolicies::ONLY_RELEASE_CRT)) { @@ -703,8 +732,9 @@ namespace vcpkg::PostBuildLint Checks::unreachable(VCPKG_LINE_INFO); } - error_count += check_no_empty_folders(package_dir); - error_count += check_no_files_in_package_dir_and_debug_dir(package_dir); + error_count += check_no_empty_folders(fs, package_dir); + error_count += check_no_files_in_dir(fs, package_dir); + error_count += check_no_files_in_dir(fs, package_dir / "debug"); return error_count; } diff --git a/toolsrc/src/PostBuildLint_BuildInfo.cpp b/toolsrc/src/PostBuildLint_BuildInfo.cpp index d44719fe3..c129cedca 100644 --- a/toolsrc/src/PostBuildLint_BuildInfo.cpp +++ b/toolsrc/src/PostBuildLint_BuildInfo.cpp @@ -37,7 +37,7 @@ namespace vcpkg::PostBuildLint return build_info; } - BuildInfo read_build_info(Files::Filesystem& fs, const fs::path& filepath) + BuildInfo read_build_info(const Files::Filesystem& fs, const fs::path& filepath) { const Expected<std::unordered_map<std::string, std::string>> pghs = Paragraphs::get_single_paragraph(fs, filepath); Checks::check_exit(VCPKG_LINE_INFO, pghs.get() != nullptr, "Invalid BUILD_INFO file for package"); diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp index 152f8bf4b..84343a727 100644 --- a/toolsrc/src/VcpkgPaths.cpp +++ b/toolsrc/src/VcpkgPaths.cpp @@ -265,6 +265,8 @@ namespace vcpkg static Toolset find_toolset_instance(const VcpkgPaths& paths) { + const auto& fs = paths.get_filesystem(); + const std::vector<std::string> vs2017_installation_instances = get_VS2017_installation_instances(paths); // Note: this will contain a mix of vcvarsall.bat locations and dumpbin.exe locations. std::vector<fs::path> paths_examined; @@ -282,11 +284,10 @@ namespace vcpkg // Locate the "best" MSVC toolchain version const fs::path msvc_path = vc_dir / "Tools" / "MSVC"; - std::vector<fs::path> msvc_subdirectories; - Files::non_recursive_find_matching_paths_in_dir(msvc_path, [](const fs::path& current) - { - return fs::is_directory(current); - }, &msvc_subdirectories); + std::vector<fs::path> msvc_subdirectories = paths.get_filesystem().non_recursive_find_all_files_in_dir(msvc_path); + Util::unstable_keep_if(msvc_subdirectories, [&fs](const fs::path& path) { + return fs.is_directory(path); + }); // Sort them so that latest comes first std::sort(msvc_subdirectories.begin(), msvc_subdirectories.end(), [](const fs::path& left, const fs::path& right) @@ -298,7 +299,7 @@ namespace vcpkg { const fs::path dumpbin_path = subdir / "bin" / "HostX86" / "x86" / "dumpbin.exe"; paths_examined.push_back(dumpbin_path); - if (fs::exists(dumpbin_path)) + if (fs.exists(dumpbin_path)) { return { dumpbin_path, vcvarsall_bat , L"v141" }; } @@ -312,11 +313,11 @@ namespace vcpkg const fs::path vs2015_vcvarsall_bat = *v / "VC" / "vcvarsall.bat"; paths_examined.push_back(vs2015_vcvarsall_bat); - if (fs::exists(vs2015_vcvarsall_bat)) + if (fs.exists(vs2015_vcvarsall_bat)) { const fs::path vs2015_dumpbin_exe = *v / "VC" / "bin" / "dumpbin.exe"; paths_examined.push_back(vs2015_dumpbin_exe); - if (fs::exists(vs2015_dumpbin_exe)) + if (fs.exists(vs2015_dumpbin_exe)) { return { vs2015_dumpbin_exe, vs2015_vcvarsall_bat, L"v140" }; } diff --git a/toolsrc/src/commands_import.cpp b/toolsrc/src/commands_import.cpp index 0a128943d..1fcc3b3a8 100644 --- a/toolsrc/src/commands_import.cpp +++ b/toolsrc/src/commands_import.cpp @@ -13,56 +13,69 @@ namespace vcpkg::Commands::Import }; - void check_is_directory(const LineInfo& line_info, const fs::path& dirpath) + static void check_is_directory(const LineInfo& line_info, const Files::Filesystem& fs, const fs::path& dirpath) { - Checks::check_exit(line_info, fs::is_directory(dirpath), "The path %s is not a directory", dirpath.string()); + Checks::check_exit(line_info, fs.is_directory(dirpath), "The path %s is not a directory", dirpath.string()); } - static Binaries find_binaries_in_dir(const fs::path& path) + static Binaries find_binaries_in_dir(const Files::Filesystem& fs, const fs::path& path) { - check_is_directory(VCPKG_LINE_INFO, path); + auto files = fs.recursive_find_all_files_in_dir(path); + + check_is_directory(VCPKG_LINE_INFO, fs, path); Binaries binaries; - binaries.dlls = Files::recursive_find_files_with_extension_in_dir(path, ".dll"); - binaries.libs = Files::recursive_find_files_with_extension_in_dir(path, ".lib"); + for (auto&& file : files) + { + if (fs.is_directory(file)) + continue; + auto ext = file.extension(); + if (ext == ".dll") + binaries.dlls.push_back(std::move(file)); + else if (ext == ".lib") + binaries.libs.push_back(std::move(file)); + } return binaries; } - static void copy_files_into_directory(const std::vector<fs::path>& files, const fs::path& destination_folder) + static void copy_files_into_directory(Files::Filesystem& fs, const std::vector<fs::path>& files, const fs::path& destination_folder) { - fs::create_directory(destination_folder); + std::error_code ec; + fs.create_directory(destination_folder, ec); for (auto const& src_path : files) { fs::path dest_path = destination_folder / src_path.filename(); - fs::copy(src_path, dest_path, fs::copy_options::overwrite_existing); + fs.copy(src_path, dest_path, fs::copy_options::overwrite_existing); } } - static void place_library_files_in(const fs::path& include_directory, const fs::path& project_directory, const fs::path& destination_path) + static void place_library_files_in(Files::Filesystem& fs, const fs::path& include_directory, const fs::path& project_directory, const fs::path& destination_path) { - check_is_directory(VCPKG_LINE_INFO, include_directory); - check_is_directory(VCPKG_LINE_INFO, project_directory); - check_is_directory(VCPKG_LINE_INFO, destination_path); - Binaries debug_binaries = find_binaries_in_dir(project_directory / "Debug"); - Binaries release_binaries = find_binaries_in_dir(project_directory / "Release"); + check_is_directory(VCPKG_LINE_INFO, fs, include_directory); + check_is_directory(VCPKG_LINE_INFO, fs, project_directory); + check_is_directory(VCPKG_LINE_INFO, fs, destination_path); + Binaries debug_binaries = find_binaries_in_dir(fs, project_directory / "Debug"); + Binaries release_binaries = find_binaries_in_dir(fs, project_directory / "Release"); fs::path destination_include_directory = destination_path / "include"; - fs::copy(include_directory, destination_include_directory, fs::copy_options::recursive | fs::copy_options::overwrite_existing); + fs.copy(include_directory, destination_include_directory, fs::copy_options::recursive | fs::copy_options::overwrite_existing); - copy_files_into_directory(release_binaries.dlls, destination_path / "bin"); - copy_files_into_directory(release_binaries.libs, destination_path / "lib"); + copy_files_into_directory(fs, release_binaries.dlls, destination_path / "bin"); + copy_files_into_directory(fs, release_binaries.libs, destination_path / "lib"); - fs::create_directory(destination_path / "debug"); - copy_files_into_directory(debug_binaries.dlls, destination_path / "debug" / "bin"); - copy_files_into_directory(debug_binaries.libs, destination_path / "debug" / "lib"); + std::error_code ec; + fs.create_directory(destination_path / "debug", ec); + copy_files_into_directory(fs, debug_binaries.dlls, destination_path / "debug" / "bin"); + copy_files_into_directory(fs, debug_binaries.libs, destination_path / "debug" / "lib"); } static void do_import(const VcpkgPaths& paths, const fs::path& include_directory, const fs::path& project_directory, const BinaryParagraph& control_file_data) { fs::path library_destination_path = paths.package_dir(control_file_data.spec); - fs::create_directory(library_destination_path); - place_library_files_in(include_directory, project_directory, library_destination_path); + std::error_code ec; + paths.get_filesystem().create_directory(library_destination_path, ec); + place_library_files_in(paths.get_filesystem(), include_directory, project_directory, library_destination_path); fs::path control_file_path = library_destination_path / "CONTROL"; std::ofstream(control_file_path) << control_file_data; diff --git a/toolsrc/src/commands_install.cpp b/toolsrc/src/commands_install.cpp index 2c57404de..bc253aaf2 100644 --- a/toolsrc/src/commands_install.cpp +++ b/toolsrc/src/commands_install.cpp @@ -17,6 +17,8 @@ namespace vcpkg::Commands::Install static void install_and_write_listfile(const VcpkgPaths& paths, const BinaryParagraph& bpgh) { + auto&& fs = paths.get_filesystem(); + std::vector<std::string> output; const fs::path package_prefix_path = paths.package_dir(bpgh.spec); @@ -25,13 +27,21 @@ namespace vcpkg::Commands::Install const Triplet& target_triplet = bpgh.spec.target_triplet(); const std::string& target_triplet_as_string = target_triplet.canonical_name(); std::error_code ec; - fs::create_directory(paths.installed / target_triplet_as_string, ec); + fs.create_directory(paths.installed / target_triplet_as_string, ec); output.push_back(Strings::format(R"(%s/)", target_triplet_as_string)); + // TODO: replace use of recursive_directory_iterator with filesystem abstraction. for (auto it = fs::recursive_directory_iterator(package_prefix_path); it != fs::recursive_directory_iterator(); ++it) { + auto status = it->status(ec); + if (ec) + { + System::println(System::Color::error, "failed: %s: %s", it->path().u8string(), ec.message()); + continue; + } + const std::string filename = it->path().filename().generic_string(); - if (fs::is_regular_file(it->status()) && (_stricmp(filename.c_str(), "CONTROL") == 0 || _stricmp(filename.c_str(), "BUILD_INFO") == 0)) + if (fs::is_regular_file(status) && (_stricmp(filename.c_str(), "CONTROL") == 0 || _stricmp(filename.c_str(), "BUILD_INFO") == 0)) { // Do not copy the control file continue; @@ -40,16 +50,9 @@ namespace vcpkg::Commands::Install const std::string suffix = it->path().generic_u8string().substr(prefix_length + 1); const fs::path target = paths.installed / target_triplet_as_string / suffix; - auto status = it->status(ec); - if (ec) - { - System::println(System::Color::error, "failed: %s: %s", it->path().u8string(), ec.message()); - continue; - } - if (fs::is_directory(status)) { - fs::create_directory(target, ec); + fs.create_directory(target, ec); if (ec) { System::println(System::Color::error, "failed: %s: %s", target.u8string(), ec.message()); @@ -62,11 +65,11 @@ namespace vcpkg::Commands::Install if (fs::is_regular_file(status)) { - if (fs::exists(target)) + if (fs.exists(target)) { System::println(System::Color::warning, "File %s was already present and will be overwritten", target.u8string(), ec.message()); } - fs::copy_file(*it, target, fs::copy_options::overwrite_existing, ec); + fs.copy_file(*it, target, fs::copy_options::overwrite_existing, ec); if (ec) { System::println(System::Color::error, "failed: %s: %s", target.u8string(), ec.message()); @@ -86,7 +89,7 @@ namespace vcpkg::Commands::Install std::sort(output.begin(), output.end()); - Files::write_all_lines(paths.listfile_path(bpgh), output); + fs.write_all_lines(paths.listfile_path(bpgh), output); } static void remove_first_n_chars(std::vector<std::string>* strings, const size_t n) @@ -114,9 +117,9 @@ namespace vcpkg::Commands::Install return output; } - static SortedVector<std::string> build_list_of_package_files(const fs::path& package_dir) + static SortedVector<std::string> build_list_of_package_files(const Files::Filesystem& fs, const fs::path& package_dir) { - const std::vector<fs::path> package_file_paths = Files::recursive_find_all_files_in_dir(package_dir); + const std::vector<fs::path> package_file_paths = fs.recursive_find_all_files_in_dir(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) { @@ -188,7 +191,7 @@ namespace vcpkg::Commands::Install const Triplet& triplet = binary_paragraph.spec.target_triplet(); const std::vector<StatusParagraphAndAssociatedFiles> pgh_and_files = get_installed_files(paths, *status_db); - const SortedVector<std::string> package_files = build_list_of_package_files(package_dir); + 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); std::vector<std::string> intersection; diff --git a/toolsrc/src/vcpkg.cpp b/toolsrc/src/vcpkg.cpp index 5ba4cb5ba..b2942603f 100644 --- a/toolsrc/src/vcpkg.cpp +++ b/toolsrc/src/vcpkg.cpp @@ -52,7 +52,7 @@ static void inner(const VcpkgCmdArguments& args) } else { - vcpkg_root_dir = Files::find_file_recursively_up(fs::absolute(System::get_exe_path_of_current_process()), ".vcpkg-root"); + vcpkg_root_dir = Files::get_real_filesystem().find_file_recursively_up(fs::absolute(System::get_exe_path_of_current_process()), ".vcpkg-root"); } } diff --git a/toolsrc/src/vcpkg_Files.cpp b/toolsrc/src/vcpkg_Files.cpp index ece6ed474..4e83300f4 100644 --- a/toolsrc/src/vcpkg_Files.cpp +++ b/toolsrc/src/vcpkg_Files.cpp @@ -8,7 +8,7 @@ namespace vcpkg::Files struct RealFilesystem : Filesystem { - Expected<std::string> read_contents(const fs::path& file_path) noexcept override + virtual Expected<std::string> read_contents(const fs::path& file_path) const override { std::fstream file_stream(file_path, std::ios_base::in | std::ios_base::binary); if (file_stream.fail()) @@ -32,106 +32,121 @@ namespace vcpkg::Files return std::move(output); } - }; - - Filesystem & get_real_filesystem() - { - static RealFilesystem real_fs; - return real_fs; - } + virtual Expected<std::vector<std::string>> read_all_lines(const fs::path& file_path) const override + { + std::fstream file_stream(file_path, std::ios_base::in | std::ios_base::binary); + if (file_stream.fail()) + { + return std::errc::no_such_file_or_directory; + } - bool has_invalid_chars_for_filesystem(const std::string& s) - { - return std::regex_search(s, FILESYSTEM_INVALID_CHARACTERS_REGEX); - } + std::vector<std::string> output; + std::string line; + while (std::getline(file_stream, line)) + { + output.push_back(line); + } + file_stream.close(); - Expected<std::vector<std::string>> read_all_lines(const fs::path& file_path) - { - std::fstream file_stream(file_path, std::ios_base::in | std::ios_base::binary); - if (file_stream.fail()) + return std::move(output); + } + virtual fs::path find_file_recursively_up(const fs::path & starting_dir, const std::string & filename) const override { - return std::errc::no_such_file_or_directory; + fs::path current_dir = starting_dir; + for (; !current_dir.empty(); current_dir = current_dir.parent_path()) + { + const fs::path candidate = current_dir / filename; + if (fs::exists(candidate)) + { + break; + } + } + + return current_dir; } - std::vector<std::string> output; - std::string line; - while (std::getline(file_stream, line)) + virtual std::vector<fs::path> recursive_find_all_files_in_dir(const fs::path & dir) const override { - output.push_back(line); - } - file_stream.close(); + std::vector<fs::path> ret; - return std::move(output); - } + fs::recursive_directory_iterator b(dir), e{}; + for (; b != e; ++b) + { + ret.push_back(b->path()); + } - void write_all_lines(const fs::path& file_path, const std::vector<std::string>& lines) - { - std::fstream output(file_path, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc); - for (const std::string& line : lines) + return ret; + } + virtual std::vector<fs::path> non_recursive_find_all_files_in_dir(const fs::path & dir) const override { - output << line << "\n"; + std::vector<fs::path> ret; + + fs::directory_iterator b(dir), e{}; + for (; b != e; ++b) + { + ret.push_back(b->path()); + } + + return ret; } - output.close(); - } - fs::path find_file_recursively_up(const fs::path& starting_dir, const std::string& filename) - { - fs::path current_dir = starting_dir; - for (; !current_dir.empty(); current_dir = current_dir.parent_path()) + virtual void write_all_lines(const fs::path & file_path, const std::vector<std::string>& lines) override { - const fs::path candidate = current_dir / filename; - if (fs::exists(candidate)) + std::fstream output(file_path, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc); + for (const std::string& line : lines) { - break; + output << line << "\n"; } + output.close(); } - return current_dir; - } - - void recursive_find_files_with_extension_in_dir(const fs::path& dir, const std::string& extension, std::vector<fs::path>* output) - { - recursive_find_matching_paths_in_dir(dir, [&extension](const fs::path& current) - { - return !fs::is_directory(current) && current.extension() == extension; - }, output); - } - - std::vector<fs::path> recursive_find_files_with_extension_in_dir(const fs::path& dir, const std::string& extension) - { - std::vector<fs::path> v; - recursive_find_files_with_extension_in_dir(dir, extension, &v); - return v; - } - - void recursive_find_all_files_in_dir(const fs::path& dir, std::vector<fs::path>* output) - { - recursive_find_matching_paths_in_dir(dir, [](const fs::path& current) - { - return !fs::is_directory(current); - }, output); - } - - std::vector<fs::path> recursive_find_all_files_in_dir(const fs::path& dir) - { - std::vector<fs::path> v; - recursive_find_all_files_in_dir(dir, &v); - return v; - } + virtual void rename(const fs::path & oldpath, const fs::path & newpath) override + { + fs::rename(oldpath, newpath); + } + virtual void remove(const fs::path & path) override + { + fs::remove(path); + } + virtual bool exists(const fs::path & path) const override + { + return fs::exists(path); + } + virtual bool is_directory(const fs::path & path) const override + { + return fs::is_directory(path); + } + virtual bool is_regular_file(const fs::path & path) const override + { + return fs::is_regular_file(path); + } + virtual bool is_empty(const fs::path & path) const override + { + return fs::is_empty(path); + } + virtual bool create_directory(const fs::path & path, std::error_code & ec) override + { + return fs::create_directory(path, ec); + } + virtual void copy(const fs::path & oldpath, const fs::path & newpath, fs::copy_options opts) override + { + fs::copy(oldpath, newpath, opts); + } + virtual void copy_file(const fs::path & oldpath, const fs::path & newpath, fs::copy_options opts, std::error_code & ec) override + { + fs::copy_file(oldpath, newpath, opts, ec); + } + }; - void non_recursive_find_all_files_in_dir(const fs::path& dir, std::vector<fs::path>* output) + Filesystem & get_real_filesystem() { - non_recursive_find_matching_paths_in_dir(dir, [](const fs::path& current) - { - return !fs::is_directory(current); - }, output); + static RealFilesystem real_fs; + return real_fs; } - std::vector<fs::path> non_recursive_find_all_files_in_dir(const fs::path& dir) + bool has_invalid_chars_for_filesystem(const std::string& s) { - std::vector<fs::path> v; - non_recursive_find_all_files_in_dir(dir, &v); - return v; + return std::regex_search(s, FILESYSTEM_INVALID_CHARACTERS_REGEX); } void print_paths(const std::vector<fs::path>& paths) diff --git a/toolsrc/src/vcpkglib.cpp b/toolsrc/src/vcpkglib.cpp index 71a547769..ab3c19721 100644 --- a/toolsrc/src/vcpkglib.cpp +++ b/toolsrc/src/vcpkglib.cpp @@ -3,6 +3,7 @@ #include "vcpkg_Files.h" #include "Paragraphs.h" #include "metrics.h" +#include "vcpkg_Util.h" #include "vcpkg_Strings.h" namespace vcpkg @@ -35,36 +36,36 @@ namespace vcpkg StatusParagraphs database_load_check(const VcpkgPaths& paths) { + auto& fs = paths.get_filesystem(); + auto updates_dir = paths.vcpkg_dir_updates; std::error_code ec; - fs::create_directory(paths.installed, ec); - fs::create_directory(paths.vcpkg_dir, ec); - fs::create_directory(paths.vcpkg_dir_info, ec); - fs::create_directory(updates_dir, ec); + fs.create_directory(paths.installed, ec); + fs.create_directory(paths.vcpkg_dir, ec); + fs.create_directory(paths.vcpkg_dir_info, ec); + fs.create_directory(updates_dir, ec); const fs::path& status_file = paths.vcpkg_dir_status_file; const fs::path status_file_old = status_file.parent_path() / "status-old"; const fs::path status_file_new = status_file.parent_path() / "status-new"; - StatusParagraphs current_status_db = load_current_database(paths.get_filesystem(), status_file, status_file_old); + StatusParagraphs current_status_db = load_current_database(fs, status_file, status_file_old); - auto b = fs::directory_iterator(updates_dir); - auto e = fs::directory_iterator(); - if (b == e) + auto update_files = fs.non_recursive_find_all_files_in_dir(updates_dir); + if (update_files.empty()) { // updates directory is empty, control file is up-to-date. return current_status_db; } - - for (; b != e; ++b) + for (auto&& file : update_files) { - if (!fs::is_regular_file(b->status())) + if (!fs.is_regular_file(file)) continue; - if (b->path().filename() == "incomplete") + if (file.filename() == "incomplete") continue; - auto pghs = Paragraphs::get_paragraphs(paths.get_filesystem(), b->path()).value_or_exit(VCPKG_LINE_INFO); + 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)); @@ -73,19 +74,14 @@ namespace vcpkg std::fstream(status_file_new, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc) << current_status_db; - if (fs::exists(status_file_old)) - fs::remove(status_file_old); - if (fs::exists(status_file)) - fs::rename(status_file, status_file_old); - fs::rename(status_file_new, status_file); - fs::remove(status_file_old); + fs.rename(status_file_new, status_file); - b = fs::directory_iterator(updates_dir); - for (; b != e; ++b) + for (auto&& file : update_files) { - if (!fs::is_regular_file(b->status())) + if (!fs.is_regular_file(file)) continue; - fs::remove(b->path()); + + fs.remove(file); } return current_status_db; @@ -97,13 +93,13 @@ namespace vcpkg auto my_update_id = update_id++; auto tmp_update_filename = paths.vcpkg_dir_updates / "incomplete"; auto update_filename = paths.vcpkg_dir_updates / std::to_string(my_update_id); - std::fstream fs(tmp_update_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc); - fs << p; - fs.close(); - fs::rename(tmp_update_filename, update_filename); + std::fstream file(tmp_update_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc); + file << p; + file.close(); + paths.get_filesystem().rename(tmp_update_filename, update_filename); } - static void upgrade_to_slash_terminated_sorted_format(std::vector<std::string>* lines, const fs::path& listfile_path) + static void upgrade_to_slash_terminated_sorted_format(Files::Filesystem& fs, std::vector<std::string>* lines, const fs::path& listfile_path) { static bool was_tracked = false; @@ -167,8 +163,8 @@ namespace vcpkg // Replace the listfile on disk const fs::path updated_listfile_path = listfile_path.generic_string() + "_updated"; - Files::write_all_lines(updated_listfile_path, *lines); - fs::rename(updated_listfile_path, listfile_path); + fs.write_all_lines(updated_listfile_path, *lines); + fs.rename(updated_listfile_path, listfile_path); } std::vector<StatusParagraph*> get_installed_ports(const StatusParagraphs& status_db) @@ -186,6 +182,8 @@ namespace vcpkg std::vector<StatusParagraphAndAssociatedFiles> get_installed_files(const VcpkgPaths& paths, const StatusParagraphs& status_db) { + auto& fs = paths.get_filesystem(); + std::vector<StatusParagraphAndAssociatedFiles> installed_files; for (const std::unique_ptr<StatusParagraph>& pgh : status_db) @@ -196,9 +194,9 @@ namespace vcpkg } const fs::path listfile_path = paths.listfile_path(pgh->package); - std::vector<std::string> installed_files_of_current_pgh = Files::read_all_lines(listfile_path).value_or_exit(VCPKG_LINE_INFO); + std::vector<std::string> installed_files_of_current_pgh = fs.read_all_lines(listfile_path).value_or_exit(VCPKG_LINE_INFO); Strings::trim_all_and_remove_whitespace_strings(&installed_files_of_current_pgh); - upgrade_to_slash_terminated_sorted_format(&installed_files_of_current_pgh, listfile_path); + upgrade_to_slash_terminated_sorted_format(fs, &installed_files_of_current_pgh, listfile_path); // Remove the directories installed_files_of_current_pgh.erase( |
