aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Schumacher <roschuma@microsoft.com>2017-04-08 20:19:35 -0700
committerRobert Schumacher <roschuma@microsoft.com>2017-04-08 20:19:35 -0700
commitb34c40a4e674f5db538e84ca2b9509482ac140e7 (patch)
tree48a09d41e4760d97a20386dce00105cae54b1f17
parentc434dc99868989ca55aef5e445ac6a0a4c3430f7 (diff)
downloadvcpkg-b34c40a4e674f5db538e84ca2b9509482ac140e7.tar.gz
vcpkg-b34c40a4e674f5db538e84ca2b9509482ac140e7.zip
[vcpkg] Further work on filesystem abstraction layer.
-rw-r--r--toolsrc/include/Paragraphs.h8
-rw-r--r--toolsrc/include/PostBuildLint_BuildInfo.h2
-rw-r--r--toolsrc/include/vcpkg_Files.h57
-rw-r--r--toolsrc/include/vcpkg_Util.h6
-rw-r--r--toolsrc/src/Paragraphs.cpp8
-rw-r--r--toolsrc/src/PostBuildLint.cpp204
-rw-r--r--toolsrc/src/PostBuildLint_BuildInfo.cpp2
-rw-r--r--toolsrc/src/VcpkgPaths.cpp17
-rw-r--r--toolsrc/src/commands_import.cpp59
-rw-r--r--toolsrc/src/commands_install.cpp35
-rw-r--r--toolsrc/src/vcpkg.cpp2
-rw-r--r--toolsrc/src/vcpkg_Files.cpp175
-rw-r--r--toolsrc/src/vcpkglib.cpp62
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(