aboutsummaryrefslogtreecommitdiff
path: root/toolsrc/src
diff options
context:
space:
mode:
authorRobert Schumacher <roschuma@microsoft.com>2017-04-14 16:07:54 -0700
committerRobert Schumacher <roschuma@microsoft.com>2017-04-14 16:07:54 -0700
commit20397fc845fac398a1aca2ee17ce5b932fc1a83b (patch)
tree51235bc2602a81a89da9605272a37ca4fc1765a8 /toolsrc/src
parent8183671a492aa21ec20780a77f923848b0aeca41 (diff)
parent1c08a42091cb0addd1e0c1daf27d24bf4e9d237f (diff)
downloadvcpkg-20397fc845fac398a1aca2ee17ce5b932fc1a83b.tar.gz
vcpkg-20397fc845fac398a1aca2ee17ce5b932fc1a83b.zip
Merge branch 'dev/roschuma/fs-testing'
Diffstat (limited to 'toolsrc/src')
-rw-r--r--toolsrc/src/BinaryParagraph.cpp34
-rw-r--r--toolsrc/src/Paragraphs.cpp21
-rw-r--r--toolsrc/src/PostBuildLint.cpp219
-rw-r--r--toolsrc/src/PostBuildLint_BuildInfo.cpp4
-rw-r--r--toolsrc/src/SourceParagraph.cpp5
-rw-r--r--toolsrc/src/StatusParagraph.cpp7
-rw-r--r--toolsrc/src/StatusParagraphs.cpp9
-rw-r--r--toolsrc/src/VcpkgPaths.cpp31
-rw-r--r--toolsrc/src/commands_build.cpp4
-rw-r--r--toolsrc/src/commands_cache.cpp5
-rw-r--r--toolsrc/src/commands_ci.cpp6
-rw-r--r--toolsrc/src/commands_depends.cpp2
-rw-r--r--toolsrc/src/commands_edit.cpp10
-rw-r--r--toolsrc/src/commands_help.cpp5
-rw-r--r--toolsrc/src/commands_import.cpp64
-rw-r--r--toolsrc/src/commands_install.cpp54
-rw-r--r--toolsrc/src/commands_integrate.cpp42
-rw-r--r--toolsrc/src/commands_portsdiff.cpp8
-rw-r--r--toolsrc/src/commands_remove.cpp28
-rw-r--r--toolsrc/src/commands_search.cpp2
-rw-r--r--toolsrc/src/commands_update.cpp4
-rw-r--r--toolsrc/src/metrics.cpp13
-rw-r--r--toolsrc/src/tests_paragraph.cpp36
-rw-r--r--toolsrc/src/vcpkg.cpp18
-rw-r--r--toolsrc/src/vcpkg_Dependencies.cpp2
-rw-r--r--toolsrc/src/vcpkg_Files.cpp224
-rw-r--r--toolsrc/src/vcpkg_metrics_uploader.cpp2
-rw-r--r--toolsrc/src/vcpkglib.cpp75
28 files changed, 519 insertions, 415 deletions
diff --git a/toolsrc/src/BinaryParagraph.cpp b/toolsrc/src/BinaryParagraph.cpp
index 499ef54f7..99d7d230b 100644
--- a/toolsrc/src/BinaryParagraph.cpp
+++ b/toolsrc/src/BinaryParagraph.cpp
@@ -68,29 +68,23 @@ namespace vcpkg
return Strings::format("%s_%s_%s", this->spec.name(), this->version, this->spec.triplet());
}
- std::ostream& operator<<(std::ostream& os, const BinaryParagraph& p)
+ void serialize(const BinaryParagraph& pgh, std::string& out_str)
{
- os << "Package: " << p.spec.name() << "\n";
- os << "Version: " << p.version << "\n";
- if (!p.depends.empty())
+ out_str.append("Package: ").append(pgh.spec.name()).push_back('\n');
+ out_str.append("Version: ").append(pgh.version).push_back('\n');
+ if (!pgh.depends.empty())
{
- os << "Depends: " << p.depends.front();
+ out_str.append("Depends: ");
+ out_str.append(Strings::join(", ", pgh.depends));
+ out_str.push_back('\n');
+ }
- auto b = p.depends.begin() + 1;
- auto e = p.depends.end();
- for (; b != e; ++b)
- {
- os << ", " << *b;
- }
+ out_str.append("Architecture: ").append(pgh.spec.triplet().to_string()).push_back('\n');
+ out_str.append("Multi-Arch: same\n");
- os << "\n";
- }
- os << "Architecture: " << p.spec.triplet().to_string() << "\n";
- os << "Multi-Arch: same\n";
- if (!p.maintainer.empty())
- os << "Maintainer: " << p.maintainer << "\n";
- if (!p.description.empty())
- os << "Description: " << p.description << "\n";
- return os;
+ if (!pgh.maintainer.empty())
+ out_str.append("Maintainer: ").append(pgh.maintainer).push_back('\n');
+ if (!pgh.description.empty())
+ out_str.append("Description: ").append(pgh.description).push_back('\n');
}
}
diff --git a/toolsrc/src/Paragraphs.cpp b/toolsrc/src/Paragraphs.cpp
index 010da6700..f14552169 100644
--- a/toolsrc/src/Paragraphs.cpp
+++ b/toolsrc/src/Paragraphs.cpp
@@ -172,9 +172,9 @@ namespace vcpkg::Paragraphs
}
};
- Expected<std::unordered_map<std::string, std::string>> get_single_paragraph(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 = Files::read_contents(control_path);
+ const Expected<std::string> contents = fs.read_contents(control_path);
if (auto spgh = contents.get())
{
return parse_single_paragraph(*spgh);
@@ -183,9 +183,9 @@ namespace vcpkg::Paragraphs
return contents.error_code();
}
- Expected<std::vector<std::unordered_map<std::string, std::string>>> get_paragraphs(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 = Files::read_contents(control_path);
+ const Expected<std::string> contents = fs.read_contents(control_path);
if (auto spgh = contents.get())
{
return parse_paragraphs(*spgh);
@@ -211,9 +211,9 @@ namespace vcpkg::Paragraphs
return Parser(str.c_str(), str.c_str() + str.size()).get_paragraphs();
}
- Expected<SourceParagraph> try_load_port(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(path / "CONTROL");
+ Expected<std::unordered_map<std::string, std::string>> pghs = get_single_paragraph(fs, path / "CONTROL");
if (auto p = pghs.get())
{
return SourceParagraph(*p);
@@ -224,7 +224,7 @@ namespace vcpkg::Paragraphs
Expected<BinaryParagraph> try_load_cached_package(const VcpkgPaths& paths, const PackageSpec& spec)
{
- Expected<std::unordered_map<std::string, std::string>> pghs = get_single_paragraph(paths.package_dir(spec) / "CONTROL");
+ Expected<std::unordered_map<std::string, std::string>> pghs = get_single_paragraph(paths.get_filesystem(), paths.package_dir(spec) / "CONTROL");
if (auto p = pghs.get())
{
@@ -234,13 +234,12 @@ namespace vcpkg::Paragraphs
return pghs.error_code();
}
- std::vector<SourceParagraph> load_all_ports(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)
+ for (auto&& path : fs.get_files_non_recursive(ports_dir))
{
- const fs::path& path = it->path();
- Expected<SourceParagraph> source_paragraph = try_load_port(path);
+ Expected<SourceParagraph> source_paragraph = try_load_port(fs, path);
if (auto srcpgh = source_paragraph.get())
{
output.emplace_back(std::move(*srcpgh));
diff --git a/toolsrc/src/PostBuildLint.cpp b/toolsrc/src/PostBuildLint.cpp
index ace4918da..e165cf112 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,
@@ -64,7 +73,7 @@ namespace vcpkg::PostBuildLint
return false;
}
- static LintStatus check_for_files_in_include_directory(const std::map<BuildPolicies::Type, OptBoolT>& policies, const fs::path& package_dir)
+ static LintStatus check_for_files_in_include_directory(const Files::Filesystem& fs, const std::map<BuildPolicies::Type, OptBoolT>& policies, const fs::path& package_dir)
{
if (contains_and_enabled(policies, BuildPolicies::EMPTY_INCLUDE_FOLDER))
{
@@ -72,7 +81,7 @@ namespace vcpkg::PostBuildLint
}
const fs::path include_dir = package_dir / "include";
- if (!fs::exists(include_dir) || fs::is_empty(include_dir))
+ if (!fs.exists(include_dir) || fs.is_empty(include_dir))
{
System::println(System::Color::warning, "The folder /include is empty. This indicates the library was not correctly installed.");
return LintStatus::ERROR_DETECTED;
@@ -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.get_files_recursive(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.get_files_recursive(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.get_files_recursive(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,25 @@ 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.get_files_non_recursive(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")
+ for (auto&& src_file : fs.get_files_non_recursive(src_dir))
{
- 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 +234,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.get_files_recursive(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 +453,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 +463,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 +494,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.get_files_recursive(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 +612,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.get_files_non_recursive(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 +641,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.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;
@@ -634,38 +656,46 @@ namespace vcpkg::PostBuildLint
return error_count;
}
- 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_include_directory(fs, build_info.policies, 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.get_files_recursive(debug_lib_dir);
+ Util::unstable_keep_if(debug_libs, has_extension_pred(fs, ".lib"));
+ std::vector<fs::path> release_libs = fs.get_files_recursive(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);
- std::vector<fs::path> libs;
- libs.insert(libs.cend(), debug_libs.cbegin(), debug_libs.cend());
- libs.insert(libs.cend(), release_libs.cbegin(), release_libs.cend());
+ {
+ std::vector<fs::path> libs;
+ libs.insert(libs.cend(), debug_libs.cbegin(), debug_libs.cend());
+ libs.insert(libs.cend(), release_libs.cbegin(), release_libs.cend());
- error_count += check_lib_architecture(spec.triplet().architecture(), libs);
+ error_count += check_lib_architecture(spec.triplet().architecture(), libs);
+ }
switch (build_info.library_linkage)
{
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.get_files_recursive(debug_bin_dir);
+ Util::unstable_keep_if(debug_dlls, has_extension_pred(fs, ".dll"));
+ std::vector<fs::path> release_dlls = fs.get_files_recursive(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 +715,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.get_files_recursive(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 +733,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 c7f0781b7..c129cedca 100644
--- a/toolsrc/src/PostBuildLint_BuildInfo.cpp
+++ b/toolsrc/src/PostBuildLint_BuildInfo.cpp
@@ -37,9 +37,9 @@ namespace vcpkg::PostBuildLint
return build_info;
}
- BuildInfo read_build_info(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(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");
return BuildInfo::create(*pghs.get());
}
diff --git a/toolsrc/src/SourceParagraph.cpp b/toolsrc/src/SourceParagraph.cpp
index c23e220d7..11b83aedf 100644
--- a/toolsrc/src/SourceParagraph.cpp
+++ b/toolsrc/src/SourceParagraph.cpp
@@ -138,9 +138,8 @@ namespace vcpkg
return ret;
}
- std::ostream & operator<<(std::ostream & os, const Dependency & p)
+ const std::string& to_string(const Dependency& dep)
{
- os << p.name;
- return os;
+ return dep.name;
}
}
diff --git a/toolsrc/src/StatusParagraph.cpp b/toolsrc/src/StatusParagraph.cpp
index 88b4fb854..63bfb2f9b 100644
--- a/toolsrc/src/StatusParagraph.cpp
+++ b/toolsrc/src/StatusParagraph.cpp
@@ -16,11 +16,10 @@ namespace vcpkg
{
}
- std::ostream& operator<<(std::ostream& os, const StatusParagraph& p)
+ void serialize(const StatusParagraph& pgh, std::string& out_str)
{
- os << p.package;
- os << "Status: " << to_string(p.want) << " ok " << to_string(p.state) << "\n";
- return os;
+ serialize(pgh.package, out_str);
+ out_str.append("Status: ").append(to_string(pgh.want)).append(" ok ").append(to_string(pgh.state)).push_back('\n');
}
StatusParagraph::StatusParagraph(const std::unordered_map<std::string, std::string>& fields)
diff --git a/toolsrc/src/StatusParagraphs.cpp b/toolsrc/src/StatusParagraphs.cpp
index 7d09b30e9..f41630132 100644
--- a/toolsrc/src/StatusParagraphs.cpp
+++ b/toolsrc/src/StatusParagraphs.cpp
@@ -57,13 +57,12 @@ namespace vcpkg
return ptr;
}
- std::ostream& vcpkg::operator<<(std::ostream& os, const StatusParagraphs& l)
+ void serialize(const StatusParagraphs& pghs, std::string& out_str)
{
- for (auto& pgh : l.paragraphs)
+ for (auto& pgh : pghs.paragraphs)
{
- os << *pgh;
- os << "\n";
+ serialize(*pgh, out_str);
+ out_str.push_back('\n');
}
- return os;
}
}
diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp
index 6fc0538fd..ec4bb2dce 100644
--- a/toolsrc/src/VcpkgPaths.cpp
+++ b/toolsrc/src/VcpkgPaths.cpp
@@ -6,6 +6,7 @@
#include "PackageSpec.h"
#include "vcpkg_Files.h"
#include "vcpkg_Util.h"
+#include "..\include\VcpkgPaths.h"
namespace vcpkg
{
@@ -155,7 +156,7 @@ namespace vcpkg
Expected<VcpkgPaths> VcpkgPaths::create(const fs::path& vcpkg_root_dir)
{
std::error_code ec;
- const fs::path canonical_vcpkg_root_dir = fs::canonical(vcpkg_root_dir, ec);
+ const fs::path canonical_vcpkg_root_dir = fs::stdfs::canonical(vcpkg_root_dir, ec);
if (ec)
{
return ec;
@@ -213,10 +214,9 @@ namespace vcpkg
bool VcpkgPaths::is_valid_triplet(const Triplet& t) const
{
- auto it = fs::directory_iterator(this->triplets);
- for (; it != fs::directory_iterator(); ++it)
+ for (auto&& path : get_filesystem().get_files_non_recursive(this->triplets))
{
- std::string triplet_file_name = it->path().stem().generic_u8string();
+ std::string triplet_file_name = path.stem().generic_u8string();
if (t.canonical_name() == triplet_file_name) // TODO: fuzzy compare
{
//t.value = triplet_file_name; // NOTE: uncomment when implementing fuzzy compare
@@ -264,6 +264,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;
@@ -276,16 +278,15 @@ namespace vcpkg
// Skip any instances that do not have vcvarsall.
const fs::path vcvarsall_bat = vc_dir / "Auxiliary" / "Build" / "vcvarsall.bat";
paths_examined.push_back(vcvarsall_bat);
- if (!fs::exists(vcvarsall_bat))
+ if (!fs.exists(vcvarsall_bat))
continue;
// 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 = fs.get_files_non_recursive(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)
@@ -297,7 +298,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" };
}
@@ -311,11 +312,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" };
}
@@ -335,4 +336,8 @@ namespace vcpkg
{
return this->toolset.get_lazy([this]() { return find_toolset_instance(*this); });
}
+ Files::Filesystem & VcpkgPaths::get_filesystem() const
+ {
+ return Files::get_real_filesystem();
+ }
}
diff --git a/toolsrc/src/commands_build.cpp b/toolsrc/src/commands_build.cpp
index 710e108b0..ab792f1bc 100644
--- a/toolsrc/src/commands_build.cpp
+++ b/toolsrc/src/commands_build.cpp
@@ -23,7 +23,7 @@ namespace vcpkg::Commands::Build
{
const BinaryParagraph bpgh = BinaryParagraph(source_paragraph, triplet);
const fs::path binary_control_file = paths.packages / bpgh.dir() / "CONTROL";
- std::ofstream(binary_control_file) << bpgh;
+ paths.get_filesystem().write_contents(binary_control_file, Strings::serialize(bpgh));
}
std::wstring make_build_env_cmd(const Triplet& triplet, const Toolset& toolset)
@@ -141,7 +141,7 @@ namespace vcpkg::Commands::Build
Checks::exit_success(VCPKG_LINE_INFO);
}
- const Expected<SourceParagraph> maybe_spgh = Paragraphs::try_load_port(port_dir);
+ const Expected<SourceParagraph> maybe_spgh = Paragraphs::try_load_port(paths.get_filesystem(), port_dir);
Checks::check_exit(VCPKG_LINE_INFO, !maybe_spgh.error_code(), "Could not find package named %s: %s", spec, maybe_spgh.error_code().message());
const SourceParagraph& spgh = *maybe_spgh.get();
diff --git a/toolsrc/src/commands_cache.cpp b/toolsrc/src/commands_cache.cpp
index eae1d8fe3..cb26c6ef9 100644
--- a/toolsrc/src/commands_cache.cpp
+++ b/toolsrc/src/commands_cache.cpp
@@ -10,10 +10,9 @@ namespace vcpkg::Commands::Cache
static std::vector<BinaryParagraph> read_all_binary_paragraphs(const VcpkgPaths& paths)
{
std::vector<BinaryParagraph> output;
- for (auto it = fs::directory_iterator(paths.packages); it != fs::directory_iterator(); ++it)
+ for (auto&& path : paths.get_filesystem().get_files_non_recursive(paths.packages))
{
- const fs::path& path = it->path();
- const Expected<std::unordered_map<std::string, std::string>> pghs = Paragraphs::get_single_paragraph(path / "CONTROL");
+ const Expected<std::unordered_map<std::string, std::string>> pghs = Paragraphs::get_single_paragraph(paths.get_filesystem(), path / "CONTROL");
if (auto p = pghs.get())
{
const BinaryParagraph binary_paragraph = BinaryParagraph(*p);
diff --git a/toolsrc/src/commands_ci.cpp b/toolsrc/src/commands_ci.cpp
index 6c6cd8751..a40a7ed32 100644
--- a/toolsrc/src/commands_ci.cpp
+++ b/toolsrc/src/commands_ci.cpp
@@ -14,9 +14,9 @@ namespace vcpkg::Commands::CI
using Dependencies::InstallPlanType;
using Build::BuildResult;
- static std::vector<PackageSpec> load_all_package_specs(const fs::path& ports_directory, const Triplet& triplet)
+ static std::vector<PackageSpec> load_all_package_specs(Files::Filesystem& fs, const fs::path& ports_directory, const Triplet& triplet)
{
- std::vector<SourceParagraph> ports = Paragraphs::load_all_ports(ports_directory);
+ std::vector<SourceParagraph> ports = Paragraphs::load_all_ports(fs, ports_directory);
std::vector<PackageSpec> specs;
for (const SourceParagraph& p : ports)
{
@@ -33,7 +33,7 @@ namespace vcpkg::Commands::CI
const Triplet triplet = args.command_arguments.size() == 1 ? Triplet::from_canonical_name(args.command_arguments.at(0)) : default_triplet;
Input::check_triplet(triplet, paths);
args.check_and_get_optional_command_arguments({});
- const std::vector<PackageSpec> specs = load_all_package_specs(paths.ports, triplet);
+ const std::vector<PackageSpec> specs = load_all_package_specs(paths.get_filesystem(), paths.ports, triplet);
StatusParagraphs status_db = database_load_check(paths);
const std::vector<InstallPlanAction> install_plan = Dependencies::create_install_plan(paths, specs, status_db);
diff --git a/toolsrc/src/commands_depends.cpp b/toolsrc/src/commands_depends.cpp
index a61ac534e..0f0509614 100644
--- a/toolsrc/src/commands_depends.cpp
+++ b/toolsrc/src/commands_depends.cpp
@@ -12,7 +12,7 @@ namespace vcpkg::Commands::DependInfo
args.check_exact_arg_count(0, example);
args.check_and_get_optional_command_arguments({});
- const std::vector<SourceParagraph> source_paragraphs = Paragraphs::load_all_ports(paths.ports);
+ const std::vector<SourceParagraph> source_paragraphs = Paragraphs::load_all_ports(paths.get_filesystem(), paths.ports);
for (const SourceParagraph& source_paragraph : source_paragraphs)
{
diff --git a/toolsrc/src/commands_edit.cpp b/toolsrc/src/commands_edit.cpp
index 8549f5073..4679a2465 100644
--- a/toolsrc/src/commands_edit.cpp
+++ b/toolsrc/src/commands_edit.cpp
@@ -7,13 +7,15 @@ namespace vcpkg::Commands::Edit
{
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths)
{
+ auto& fs = paths.get_filesystem();
+
static const std::string example = Commands::Help::create_example_string("edit zlib");
args.check_exact_arg_count(1, example);
args.check_and_get_optional_command_arguments({});
const std::string port_name = args.command_arguments.at(0);
const fs::path portpath = paths.ports / port_name;
- Checks::check_exit(VCPKG_LINE_INFO, fs::is_directory(portpath), R"(Could not find port named "%s")", port_name);
+ Checks::check_exit(VCPKG_LINE_INFO, fs.is_directory(portpath), R"(Could not find port named "%s")", port_name);
// Find the user's selected editor
std::wstring env_EDITOR;
@@ -30,7 +32,7 @@ namespace vcpkg::Commands::Edit
if (env_EDITOR.empty())
{
const fs::path CODE_EXE_PATH = System::get_ProgramFiles_32_bit() / "Microsoft VS Code/Code.exe";
- if (fs::exists(CODE_EXE_PATH))
+ if (fs.exists(CODE_EXE_PATH))
{
env_EDITOR = CODE_EXE_PATH;
}
@@ -50,13 +52,13 @@ namespace vcpkg::Commands::Edit
if (auto c = code_installpath.get())
{
auto p = fs::path(*c) / "Code.exe";
- if (fs::exists(p))
+ if (fs.exists(p))
{
env_EDITOR = p.native();
break;
}
auto p_insiders = fs::path(*c) / "Code - Insiders.exe";
- if (fs::exists(p_insiders))
+ if (fs.exists(p_insiders))
{
env_EDITOR = p_insiders.native();
break;
diff --git a/toolsrc/src/commands_help.cpp b/toolsrc/src/commands_help.cpp
index e3c489a9d..0c6b0c766 100644
--- a/toolsrc/src/commands_help.cpp
+++ b/toolsrc/src/commands_help.cpp
@@ -7,10 +7,9 @@ namespace vcpkg::Commands::Help
void help_topic_valid_triplet(const VcpkgPaths& paths)
{
System::println("Available architecture triplets:");
- auto it = fs::directory_iterator(paths.triplets);
- for (; it != fs::directory_iterator(); ++it)
+ for (auto&& path : paths.get_filesystem().get_files_non_recursive(paths.triplets))
{
- System::println(" %s", it->path().stem().filename().string());
+ System::println(" %s", path.stem().filename().string());
}
}
diff --git a/toolsrc/src/commands_import.cpp b/toolsrc/src/commands_import.cpp
index eb140604a..95e23302d 100644
--- a/toolsrc/src/commands_import.cpp
+++ b/toolsrc/src/commands_import.cpp
@@ -13,59 +13,73 @@ 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.get_files_recursive(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)
{
+ auto& fs = paths.get_filesystem();
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;
+ fs.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;
+ fs.write_contents(control_file_path, Strings::serialize(control_file_data));
}
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths)
@@ -78,7 +92,7 @@ namespace vcpkg::Commands::Import
const fs::path include_directory(args.command_arguments[1]);
const fs::path project_directory(args.command_arguments[2]);
- const Expected<std::unordered_map<std::string, std::string>> pghs = Paragraphs::get_single_paragraph(control_file_path);
+ const Expected<std::unordered_map<std::string, std::string>> pghs = Paragraphs::get_single_paragraph(paths.get_filesystem(), control_file_path);
Checks::check_exit(VCPKG_LINE_INFO, pghs.get() != nullptr, "Invalid control file %s for package", control_file_path.generic_string());
StatusParagraph spgh;
diff --git a/toolsrc/src/commands_install.cpp b/toolsrc/src/commands_install.cpp
index a02137e40..cd35854bc 100644
--- a/toolsrc/src/commands_install.cpp
+++ b/toolsrc/src/commands_install.cpp
@@ -17,77 +17,79 @@ 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);
const size_t prefix_length = package_prefix_path.native().size();
- const Triplet& triplet = bpgh.spec.triplet();
- const std::string& triplet_subfolder = triplet.canonical_name();
- const fs::path triplet_subfolder_path = paths.installed / triplet_subfolder;
+ const std::string& triplet_string = bpgh.spec.triplet().canonical_name();
+ const fs::path installed_subfolder_path = paths.installed / triplet_string;
std::error_code ec;
- fs::create_directory(triplet_subfolder_path, ec);
- output.push_back(Strings::format(R"(%s/)", triplet_subfolder));
+ fs.create_directory(installed_subfolder_path, ec);
+ output.push_back(Strings::format(R"(%s/)", triplet_string));
- for (auto it = fs::recursive_directory_iterator(package_prefix_path); it != fs::recursive_directory_iterator(); ++it)
+ auto files = fs.get_files_recursive(package_prefix_path);
+ for (auto&& file : files)
{
- 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))
+ auto status = fs.status(file, ec);
+ if (ec)
{
- // Do not copy the control file
+ System::println(System::Color::error, "failed: %s: %s", file.u8string(), ec.message());
continue;
}
- const std::string suffix = it->path().generic_u8string().substr(prefix_length + 1);
- const fs::path target = triplet_subfolder_path / suffix;
-
- auto status = it->status(ec);
- if (ec)
+ const std::string filename = file.filename().generic_string();
+ if (fs::is_regular_file(status) && (_stricmp(filename.c_str(), "CONTROL") == 0 || _stricmp(filename.c_str(), "BUILD_INFO") == 0))
{
- System::println(System::Color::error, "failed: %s: %s", it->path().u8string(), ec.message());
+ // Do not copy the control file
continue;
}
+ const std::string suffix = file.generic_u8string().substr(prefix_length + 1);
+ const fs::path target = installed_subfolder_path / suffix;
+
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());
}
// Trailing backslash for directories
- output.push_back(Strings::format(R"(%s/%s/)", triplet_subfolder, suffix));
+ output.push_back(Strings::format(R"(%s/%s/)", triplet_string, suffix));
continue;
}
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(file, target, fs::copy_options::overwrite_existing, ec);
if (ec)
{
System::println(System::Color::error, "failed: %s: %s", target.u8string(), ec.message());
}
- output.push_back(Strings::format(R"(%s/%s)", triplet_subfolder, suffix));
+ output.push_back(Strings::format(R"(%s/%s)", triplet_string, suffix));
continue;
}
if (!fs::status_known(status))
{
- System::println(System::Color::error, "failed: %s: unknown status", it->path().u8string());
+ System::println(System::Color::error, "failed: %s: unknown status", file.u8string());
continue;
}
- System::println(System::Color::error, "failed: %s: cannot handle file type", it->path().u8string());
+ System::println(System::Color::error, "failed: %s: cannot handle file type", file.u8string());
}
std::sort(output.begin(), output.end());
- Files::write_all_lines(paths.listfile_path(bpgh), output);
+ fs.write_lines(paths.listfile_path(bpgh), output);
}
static void remove_first_n_chars(std::vector<std::string>* strings, const size_t n)
@@ -115,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.get_files_recursive(package_dir);
const size_t package_remove_char_count = package_dir.generic_string().size() + 1; // +1 for the slash
auto package_files = Util::fmap(package_file_paths, [package_remove_char_count](const fs::path& path)
{
@@ -183,7 +185,7 @@ namespace vcpkg::Commands::Install
const Triplet& triplet = binary_paragraph.spec.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/commands_integrate.cpp b/toolsrc/src/commands_integrate.cpp
index ea0682e1f..5772843df 100644
--- a/toolsrc/src/commands_integrate.cpp
+++ b/toolsrc/src/commands_integrate.cpp
@@ -139,10 +139,12 @@ namespace vcpkg::Commands::Integrate
static void integrate_install(const VcpkgPaths& paths)
{
+ auto& fs = paths.get_filesystem();
+
// TODO: This block of code should eventually be removed
for (auto&& old_system_wide_targets_file : old_system_target_files)
{
- if (fs::exists(old_system_wide_targets_file))
+ if (fs.exists(old_system_wide_targets_file))
{
const std::string param = Strings::format(R"(/c DEL "%s" /Q > nul)", old_system_wide_targets_file.string());
ElevationPromptChoice user_choice = elevated_cmd_execute(param);
@@ -159,12 +161,13 @@ namespace vcpkg::Commands::Integrate
}
}
+ std::error_code ec;
const fs::path tmp_dir = paths.buildsystems / "tmp";
- fs::create_directory(paths.buildsystems);
- fs::create_directory(tmp_dir);
+ fs.create_directory(paths.buildsystems, ec);
+ fs.create_directory(tmp_dir, ec);
bool should_install_system = true;
- const Expected<std::string> system_wide_file_contents = Files::read_contents(system_wide_targets_file);
+ const Expected<std::string> system_wide_file_contents = fs.read_contents(system_wide_targets_file);
if (auto contents_data = system_wide_file_contents.get())
{
std::regex re(R"###(<!-- version (\d+) -->)###");
@@ -181,7 +184,7 @@ namespace vcpkg::Commands::Integrate
if (should_install_system)
{
const fs::path sys_src_path = tmp_dir / "vcpkg.system.targets";
- std::ofstream(sys_src_path) << create_system_targets_shortcut();
+ fs.write_contents(sys_src_path, create_system_targets_shortcut());
const std::string param = Strings::format(R"(/c mkdir "%s" & copy "%s" "%s" /Y > nul)", system_wide_targets_file.parent_path().string(), sys_src_path.string(), system_wide_targets_file.string());
ElevationPromptChoice user_choice = elevated_cmd_execute(param);
@@ -196,14 +199,16 @@ namespace vcpkg::Commands::Integrate
Checks::unreachable(VCPKG_LINE_INFO);
}
- Checks::check_exit(VCPKG_LINE_INFO, fs::exists(system_wide_targets_file), "Error: failed to copy targets file to %s", system_wide_targets_file.string());
+ Checks::check_exit(VCPKG_LINE_INFO, fs.exists(system_wide_targets_file), "Error: failed to copy targets file to %s", system_wide_targets_file.string());
}
const fs::path appdata_src_path = tmp_dir / "vcpkg.user.targets";
- std::ofstream(appdata_src_path) << create_appdata_targets_shortcut(paths.buildsystems_msbuild_targets.string());
+ fs.write_contents(appdata_src_path, create_appdata_targets_shortcut(paths.buildsystems_msbuild_targets.string()));
auto appdata_dst_path = get_appdata_targets_path();
- if (!fs::copy_file(appdata_src_path, appdata_dst_path, fs::copy_options::overwrite_existing))
+ auto rc = fs.copy_file(appdata_src_path, appdata_dst_path, fs::copy_options::overwrite_existing, ec);
+
+ if (!rc || ec)
{
System::println(System::Color::error, "Error: Failed to copy file: %s -> %s", appdata_src_path.string(), appdata_dst_path.string());
Checks::exit_fail(VCPKG_LINE_INFO);
@@ -220,12 +225,12 @@ namespace vcpkg::Commands::Integrate
Checks::exit_success(VCPKG_LINE_INFO);
}
- static void integrate_remove()
+ static void integrate_remove(Files::Filesystem& fs)
{
const fs::path path = get_appdata_targets_path();
std::error_code ec;
- bool was_deleted = fs::remove(path, ec);
+ bool was_deleted = fs.remove(path, ec);
Checks::check_exit(VCPKG_LINE_INFO, !ec, "Error: Unable to remove user-wide integration: %d", ec.message());
@@ -243,12 +248,15 @@ namespace vcpkg::Commands::Integrate
static void integrate_project(const VcpkgPaths& paths)
{
+ auto& fs = paths.get_filesystem();
+
const fs::path& nuget_exe = paths.get_nuget_exe();
const fs::path& buildsystems_dir = paths.buildsystems;
const fs::path tmp_dir = buildsystems_dir / "tmp";
- fs::create_directory(buildsystems_dir);
- fs::create_directory(tmp_dir);
+ std::error_code ec;
+ fs.create_directory(buildsystems_dir, ec);
+ fs.create_directory(tmp_dir, ec);
const fs::path targets_file_path = tmp_dir / "vcpkg.nuget.targets";
const fs::path props_file_path = tmp_dir / "vcpkg.nuget.props";
@@ -256,9 +264,9 @@ namespace vcpkg::Commands::Integrate
const std::string nuget_id = get_nuget_id(paths.root);
const std::string nupkg_version = "1.0.0";
- std::ofstream(targets_file_path) << create_nuget_targets_file(paths.buildsystems_msbuild_targets);
- std::ofstream(props_file_path) << create_nuget_props_file();
- std::ofstream(nuspec_file_path) << create_nuspec_file(paths.root, nuget_id, nupkg_version);
+ fs.write_contents(targets_file_path, create_nuget_targets_file(paths.buildsystems_msbuild_targets));
+ fs.write_contents(props_file_path, create_nuget_props_file());
+ fs.write_contents(nuspec_file_path, create_nuspec_file(paths.root, nuget_id, nupkg_version));
// Using all forward slashes for the command line
const std::wstring cmd_line = Strings::wformat(LR"("%s" pack -OutputDirectory "%s" "%s" > nul)", nuget_exe.native(), buildsystems_dir.native(), nuspec_file_path.native());
@@ -266,7 +274,7 @@ namespace vcpkg::Commands::Integrate
const int exit_code = System::cmd_execute_clean(cmd_line);
const fs::path nuget_package = buildsystems_dir / Strings::format("%s.%s.nupkg", nuget_id, nupkg_version);
- Checks::check_exit(VCPKG_LINE_INFO, exit_code == 0 && fs::exists(nuget_package), "Error: NuGet package creation failed");
+ Checks::check_exit(VCPKG_LINE_INFO, exit_code == 0 && fs.exists(nuget_package), "Error: NuGet package creation failed");
System::println(System::Color::success, "Created nupkg: %s", nuget_package.string());
System::println(R"(
@@ -295,7 +303,7 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console
}
if (args.command_arguments[0] == "remove")
{
- return integrate_remove();
+ return integrate_remove(paths.get_filesystem());
}
if (args.command_arguments[0] == "project")
{
diff --git a/toolsrc/src/commands_portsdiff.cpp b/toolsrc/src/commands_portsdiff.cpp
index f4b828ecd..e262a8338 100644
--- a/toolsrc/src/commands_portsdiff.cpp
+++ b/toolsrc/src/commands_portsdiff.cpp
@@ -69,11 +69,13 @@ namespace vcpkg::Commands::PortsDiff
static std::map<std::string, VersionT> read_ports_from_commit(const VcpkgPaths& paths, const std::wstring& git_commit_id)
{
+ std::error_code ec;
+ auto& fs = paths.get_filesystem();
const fs::path& git_exe = paths.get_git_exe();
const fs::path dot_git_dir = paths.root / ".git";
const std::wstring ports_dir_name_as_string = paths.ports.filename().native();
const fs::path temp_checkout_path = paths.root / Strings::wformat(L"%s-%s", ports_dir_name_as_string, git_commit_id);
- fs::create_directory(temp_checkout_path);
+ fs.create_directory(temp_checkout_path, ec);
const std::wstring checkout_this_dir = Strings::wformat(LR"(.\%s)", ports_dir_name_as_string); // Must be relative to the root of the repository
const std::wstring cmd = Strings::wformat(LR"("%s" --git-dir="%s" --work-tree="%s" checkout %s -f -q -- %s %s & "%s" reset >NUL)",
@@ -85,9 +87,9 @@ namespace vcpkg::Commands::PortsDiff
L".vcpkg-root",
git_exe.native());
System::cmd_execute_clean(cmd);
- const std::vector<SourceParagraph> source_paragraphs = Paragraphs::load_all_ports(temp_checkout_path / ports_dir_name_as_string);
+ const std::vector<SourceParagraph> source_paragraphs = Paragraphs::load_all_ports(paths.get_filesystem(), temp_checkout_path / ports_dir_name_as_string);
const std::map<std::string, VersionT> names_and_versions = Paragraphs::extract_port_names_and_versions(source_paragraphs);
- fs::remove_all(temp_checkout_path);
+ fs.remove_all(temp_checkout_path, ec);
return names_and_versions;
}
diff --git a/toolsrc/src/commands_remove.cpp b/toolsrc/src/commands_remove.cpp
index 6a9f67f65..a54eda45e 100644
--- a/toolsrc/src/commands_remove.cpp
+++ b/toolsrc/src/commands_remove.cpp
@@ -13,15 +13,15 @@ namespace vcpkg::Commands::Remove
using Dependencies::RequestType;
using Update::OutdatedPackage;
- static void delete_directory(const fs::path& directory)
+ static void delete_directory(Files::Filesystem& fs, const fs::path& directory)
{
std::error_code ec;
- fs::remove_all(directory, ec);
+ fs.remove_all(directory, ec);
if (!ec)
{
System::println(System::Color::success, "Cleaned up %s", directory.string());
}
- if (fs::exists(directory))
+ if (fs.exists(directory))
{
System::println(System::Color::warning, "Some files in %s were unable to be removed. Close any editors operating in this directory and retry.", directory.string());
}
@@ -29,18 +29,19 @@ namespace vcpkg::Commands::Remove
static void remove_package(const VcpkgPaths& paths, const PackageSpec& spec, StatusParagraphs* status_db)
{
+ auto& fs = paths.get_filesystem();
StatusParagraph& pkg = **status_db->find(spec.name(), spec.triplet());
pkg.want = Want::PURGE;
pkg.state = InstallState::HALF_INSTALLED;
write_update(paths, pkg);
- std::fstream listfile(paths.listfile_path(pkg.package), std::ios_base::in | std::ios_base::binary);
- if (listfile)
+ auto maybe_lines = fs.read_lines(paths.listfile_path(pkg.package));
+
+ if (auto lines = maybe_lines.get())
{
std::vector<fs::path> dirs_touched;
- std::string suffix;
- while (std::getline(listfile, suffix))
+ for (auto&& suffix : *lines)
{
if (!suffix.empty() && suffix.back() == '\r')
suffix.pop_back();
@@ -49,7 +50,7 @@ namespace vcpkg::Commands::Remove
auto target = paths.installed / suffix;
- auto status = fs::status(target, ec);
+ auto status = fs.status(target, ec);
if (ec)
{
System::println(System::Color::error, "failed: %s", ec.message());
@@ -62,7 +63,7 @@ namespace vcpkg::Commands::Remove
}
else if (fs::is_regular_file(status))
{
- fs::remove(target, ec);
+ fs.remove(target, ec);
if (ec)
{
System::println(System::Color::error, "failed: %s: %s", target.u8string(), ec.message());
@@ -82,10 +83,10 @@ namespace vcpkg::Commands::Remove
auto e = dirs_touched.rend();
for (; b != e; ++b)
{
- if (fs::directory_iterator(*b) == fs::directory_iterator())
+ if (fs.is_empty(*b))
{
std::error_code ec;
- fs::remove(*b, ec);
+ fs.remove(*b, ec);
if (ec)
{
System::println(System::Color::error, "failed: %s", ec.message());
@@ -93,8 +94,7 @@ namespace vcpkg::Commands::Remove
}
}
- listfile.close();
- fs::remove(paths.listfile_path(pkg.package));
+ fs.remove(paths.listfile_path(pkg.package));
}
pkg.state = InstallState::NOT_INSTALLED;
@@ -221,7 +221,7 @@ namespace vcpkg::Commands::Remove
if (alsoRemoveFolderFromPackages)
{
System::println("Purging package %s... ", display_name);
- delete_directory(paths.packages / action.spec.dir());
+ delete_directory(paths.get_filesystem(), paths.packages / action.spec.dir());
System::println(System::Color::success, "Purging package %s... done", display_name);
}
}
diff --git a/toolsrc/src/commands_search.cpp b/toolsrc/src/commands_search.cpp
index 478f53a76..691a66289 100644
--- a/toolsrc/src/commands_search.cpp
+++ b/toolsrc/src/commands_search.cpp
@@ -59,7 +59,7 @@ namespace vcpkg::Commands::Search
args.check_max_arg_count(1, example);
const std::unordered_set<std::string> options = args.check_and_get_optional_command_arguments({ OPTION_GRAPH });
- const std::vector<SourceParagraph> source_paragraphs = Paragraphs::load_all_ports(paths.ports);
+ const std::vector<SourceParagraph> source_paragraphs = Paragraphs::load_all_ports(paths.get_filesystem(), paths.ports);
if (options.find(OPTION_GRAPH) != options.cend())
{
const std::string graph_as_string = create_graph_as_string(source_paragraphs);
diff --git a/toolsrc/src/commands_update.cpp b/toolsrc/src/commands_update.cpp
index fc03c0084..6fc8b1171 100644
--- a/toolsrc/src/commands_update.cpp
+++ b/toolsrc/src/commands_update.cpp
@@ -14,7 +14,7 @@ namespace vcpkg::Commands::Update
std::vector<OutdatedPackage> find_outdated_packages(const VcpkgPaths& paths, const StatusParagraphs& status_db)
{
- const std::vector<SourceParagraph> source_paragraphs = Paragraphs::load_all_ports(paths.ports);
+ const std::vector<SourceParagraph> source_paragraphs = Paragraphs::load_all_ports(paths.get_filesystem(), paths.ports);
const std::map<std::string, VersionT> src_names_to_versions = Paragraphs::extract_port_names_and_versions(source_paragraphs);
const std::vector<StatusParagraph*> installed_packages = get_installed_ports(status_db);
@@ -64,7 +64,7 @@ namespace vcpkg::Commands::Update
" vcpkg install <pkgs>...");
}
- auto version_file = Files::read_contents(paths.root / "toolsrc" / "VERSION.txt");
+ auto version_file = paths.get_filesystem().read_contents(paths.root / "toolsrc" / "VERSION.txt");
if (auto version_contents = version_file.get())
{
int maj1, min1, rev1;
diff --git a/toolsrc/src/metrics.cpp b/toolsrc/src/metrics.cpp
index 515d7e574..baefc3c35 100644
--- a/toolsrc/src/metrics.cpp
+++ b/toolsrc/src/metrics.cpp
@@ -3,6 +3,7 @@
#include "filesystem_fs.h"
#include "vcpkg_Strings.h"
#include "vcpkg_System.h"
+#include "vcpkg_Files.h"
namespace vcpkg::Metrics
{
@@ -385,30 +386,32 @@ true
const fs::path temp_folder_path = temp_folder;
const fs::path temp_folder_path_exe = temp_folder_path / "vcpkgmetricsuploader.exe";
+ auto& fs = Files::get_real_filesystem();
+
if (true)
{
- const fs::path exe_path = []() -> fs::path
+ const fs::path exe_path = [&fs]() -> fs::path
{
auto vcpkgdir = get_bindir().parent_path();
auto path = vcpkgdir / "vcpkgmetricsuploader.exe";
- if (fs::exists(path))
+ if (fs.exists(path))
return path;
path = vcpkgdir / "scripts" / "vcpkgmetricsuploader.exe";
- if (fs::exists(path))
+ if (fs.exists(path))
return path;
return L"";
}();
std::error_code ec;
- fs::copy_file(exe_path, temp_folder_path_exe, fs::copy_options::skip_existing, ec);
+ fs.copy_file(exe_path, temp_folder_path_exe, fs::copy_options::skip_existing, ec);
if (ec)
return;
}
const fs::path vcpkg_metrics_txt_path = temp_folder_path / ("vcpkg" + generate_random_UUID() + ".txt");
- std::ofstream(vcpkg_metrics_txt_path) << payload;
+ fs.write_contents(vcpkg_metrics_txt_path, payload);
const std::wstring cmdLine = Strings::wformat(L"start %s %s", temp_folder_path_exe.native(), vcpkg_metrics_txt_path.native());
System::cmd_execute_clean(cmdLine);
diff --git a/toolsrc/src/tests_paragraph.cpp b/toolsrc/src/tests_paragraph.cpp
index 58e4121a8..20bacf170 100644
--- a/toolsrc/src/tests_paragraph.cpp
+++ b/toolsrc/src/tests_paragraph.cpp
@@ -1,6 +1,7 @@
#include "CppUnitTest.h"
#include "Paragraphs.h"
#include "BinaryParagraph.h"
+#include "vcpkg_Strings.h"
#pragma comment(lib,"version")
#pragma comment(lib,"winhttp")
@@ -16,6 +17,8 @@ namespace Microsoft::VisualStudio::CppUnitTestFramework
}
}
+namespace Strings = vcpkg::Strings;
+
namespace UnitTest1
{
TEST_CLASS(ControlParsing)
@@ -289,27 +292,26 @@ namespace UnitTest1
Assert::AreEqual("v4", pghs[1]["f4"].c_str());
}
- TEST_METHOD(parse_comment_before_single_slashN)
- {
- const char* str =
- "f1: v1\r\n"
- "#comment\n";
- auto pghs = vcpkg::Paragraphs::parse_paragraphs(str).value_or_exit(VCPKG_LINE_INFO);
- Assert::AreEqual(size_t(1), pghs[0].size());
- Assert::AreEqual("v1", pghs[0]["f1"].c_str());
- }
+ TEST_METHOD(parse_comment_before_single_slashN)
+ {
+ const char* str =
+ "f1: v1\r\n"
+ "#comment\n";
+ auto pghs = vcpkg::Paragraphs::parse_paragraphs(str).value_or_exit(VCPKG_LINE_INFO);
+ Assert::AreEqual(size_t(1), pghs[0].size());
+ Assert::AreEqual("v1", pghs[0]["f1"].c_str());
+ }
TEST_METHOD(BinaryParagraph_serialize_min)
{
- std::stringstream ss;
vcpkg::BinaryParagraph pgh({
{ "Package", "zlib" },
{ "Version", "1.2.8" },
{ "Architecture", "x86-windows" },
{ "Multi-Arch", "same" },
});
- ss << pgh;
- auto pghs = vcpkg::Paragraphs::parse_paragraphs(ss.str()).value_or_exit(VCPKG_LINE_INFO);
+ std::string ss = Strings::serialize(pgh);
+ auto pghs = vcpkg::Paragraphs::parse_paragraphs(ss).value_or_exit(VCPKG_LINE_INFO);
Assert::AreEqual(size_t(1), pghs.size());
Assert::AreEqual(size_t(4), pghs[0].size());
Assert::AreEqual("zlib", pghs[0]["Package"].c_str());
@@ -320,7 +322,6 @@ namespace UnitTest1
TEST_METHOD(BinaryParagraph_serialize_max)
{
- std::stringstream ss;
vcpkg::BinaryParagraph pgh({
{ "Package", "zlib" },
{ "Version", "1.2.8" },
@@ -330,8 +331,8 @@ namespace UnitTest1
{ "Depends", "dep" },
{ "Multi-Arch", "same" },
});
- ss << pgh;
- auto pghs = vcpkg::Paragraphs::parse_paragraphs(ss.str()).value_or_exit(VCPKG_LINE_INFO);
+ std::string ss = Strings::serialize(pgh);
+ auto pghs = vcpkg::Paragraphs::parse_paragraphs(ss).value_or_exit(VCPKG_LINE_INFO);
Assert::AreEqual(size_t(1), pghs.size());
Assert::AreEqual(size_t(7), pghs[0].size());
Assert::AreEqual("zlib", pghs[0]["Package"].c_str());
@@ -344,7 +345,6 @@ namespace UnitTest1
TEST_METHOD(BinaryParagraph_serialize_multiple_deps)
{
- std::stringstream ss;
vcpkg::BinaryParagraph pgh({
{ "Package", "zlib" },
{ "Version", "1.2.8" },
@@ -352,8 +352,8 @@ namespace UnitTest1
{ "Multi-Arch", "same" },
{ "Depends", "a, b, c" },
});
- ss << pgh;
- auto pghs = vcpkg::Paragraphs::parse_paragraphs(ss.str()).value_or_exit(VCPKG_LINE_INFO);
+ std::string ss = Strings::serialize(pgh);
+ auto pghs = vcpkg::Paragraphs::parse_paragraphs(ss).value_or_exit(VCPKG_LINE_INFO);
Assert::AreEqual(size_t(1), pghs.size());
Assert::AreEqual("a, b, c", pghs[0]["Depends"].c_str());
}
diff --git a/toolsrc/src/vcpkg.cpp b/toolsrc/src/vcpkg.cpp
index 74e11c3d4..cb7c3f76d 100644
--- a/toolsrc/src/vcpkg.cpp
+++ b/toolsrc/src/vcpkg.cpp
@@ -41,18 +41,18 @@ static void inner(const VcpkgCmdArguments& args)
fs::path vcpkg_root_dir;
if (args.vcpkg_root_dir != nullptr)
{
- vcpkg_root_dir = fs::absolute(Strings::utf8_to_utf16(*args.vcpkg_root_dir));
+ vcpkg_root_dir = fs::stdfs::absolute(Strings::utf8_to_utf16(*args.vcpkg_root_dir));
}
else
{
const Optional<std::wstring> vcpkg_root_dir_env = System::get_environmental_variable(L"VCPKG_ROOT");
if (auto v = vcpkg_root_dir_env.get())
{
- vcpkg_root_dir = fs::absolute(*v);
+ vcpkg_root_dir = fs::stdfs::absolute(*v);
}
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::stdfs::absolute(System::get_exe_path_of_current_process()), ".vcpkg-root");
}
}
@@ -111,7 +111,7 @@ static void loadConfig()
try
{
- auto maybe_pghs = Paragraphs::get_paragraphs(localappdata / "vcpkg" / "config");
+ auto maybe_pghs = Paragraphs::get_paragraphs(Files::get_real_filesystem(), localappdata / "vcpkg" / "config");
if (auto p_pghs = maybe_pghs.get())
{
const auto& pghs = *p_pghs;
@@ -144,10 +144,12 @@ static void loadConfig()
try
{
std::error_code ec;
- fs::create_directory(localappdata / "vcpkg", ec);
- std::ofstream(localappdata / "vcpkg" / "config", std::ios_base::out | std::ios_base::trunc)
- << "User-Id: " << user_id << "\n"
- << "User-Since: " << user_time << "\n";
+ auto& fs = Files::get_real_filesystem();
+ fs.create_directory(localappdata / "vcpkg", ec);
+ fs.write_contents(localappdata / "vcpkg" / "config",
+ Strings::format(
+ "User-Id: %s\n"
+ "User-Since: %s\n", user_id, user_time));
}
catch (...) { }
}
diff --git a/toolsrc/src/vcpkg_Dependencies.cpp b/toolsrc/src/vcpkg_Dependencies.cpp
index d1a2a69c1..9514184ff 100644
--- a/toolsrc/src/vcpkg_Dependencies.cpp
+++ b/toolsrc/src/vcpkg_Dependencies.cpp
@@ -133,7 +133,7 @@ namespace vcpkg::Dependencies
if (auto bpgh = maybe_bpgh.get())
return InstallPlanAction{ spec, { nullopt, *bpgh, nullopt }, request_type };
- Expected<SourceParagraph> maybe_spgh = Paragraphs::try_load_port(paths.port_dir(spec));
+ Expected<SourceParagraph> maybe_spgh = Paragraphs::try_load_port(paths.get_filesystem(), paths.port_dir(spec));
if (auto spgh = maybe_spgh.get())
return InstallPlanAction{ spec, { nullopt, nullopt, *spgh }, request_type };
diff --git a/toolsrc/src/vcpkg_Files.cpp b/toolsrc/src/vcpkg_Files.cpp
index 2669a9333..21896a53d 100644
--- a/toolsrc/src/vcpkg_Files.cpp
+++ b/toolsrc/src/vcpkg_Files.cpp
@@ -6,123 +6,171 @@ namespace vcpkg::Files
{
static const std::regex FILESYSTEM_INVALID_CHARACTERS_REGEX = std::regex(R"([\/:*?"<>|])");
- bool has_invalid_chars_for_filesystem(const std::string& s)
- {
- return std::regex_search(s, FILESYSTEM_INVALID_CHARACTERS_REGEX);
- }
-
- Expected<std::string> read_contents(const fs::path& file_path) noexcept
+ struct RealFilesystem final : Filesystem
{
- std::fstream file_stream(file_path, std::ios_base::in | std::ios_base::binary);
- if (file_stream.fail())
+ virtual Expected<std::string> read_contents(const fs::path& file_path) const override
{
- return std::errc::no_such_file_or_directory;
+ 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;
+ }
+
+ file_stream.seekg(0, file_stream.end);
+ auto length = file_stream.tellg();
+ file_stream.seekg(0, file_stream.beg);
+
+ if (length > SIZE_MAX)
+ {
+ return std::errc::file_too_large;
+ }
+
+ std::string output;
+ output.resize(static_cast<size_t>(length));
+ file_stream.read(&output[0], length);
+ file_stream.close();
+
+ return std::move(output);
}
+ virtual Expected<std::vector<std::string>> read_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;
+ }
- file_stream.seekg(0, file_stream.end);
- auto length = file_stream.tellg();
- file_stream.seekg(0, file_stream.beg);
+ std::vector<std::string> output;
+ std::string line;
+ while (std::getline(file_stream, line))
+ {
+ output.push_back(line);
+ }
+ file_stream.close();
- if (length > SIZE_MAX)
+ 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::file_too_large;
+ fs::path current_dir = starting_dir;
+ for (; !current_dir.empty(); current_dir = current_dir.parent_path())
+ {
+ const fs::path candidate = current_dir / filename;
+ if (exists(candidate))
+ {
+ break;
+ }
+ }
+
+ return current_dir;
}
- std::string output;
- output.resize(static_cast<size_t>(length));
- file_stream.read(&output[0], length);
- file_stream.close();
+ virtual std::vector<fs::path> get_files_recursive(const fs::path & dir) const override
+ {
+ std::vector<fs::path> ret;
- return std::move(output);
- }
+ fs::stdfs::recursive_directory_iterator b(dir), e{};
+ for (; b != e; ++b)
+ {
+ ret.push_back(b->path());
+ }
- 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::errc::no_such_file_or_directory;
+ return ret;
}
- std::vector<std::string> output;
- std::string line;
- while (std::getline(file_stream, line))
+ virtual std::vector<fs::path> get_files_non_recursive(const fs::path & dir) const override
{
- output.push_back(line);
- }
- file_stream.close();
+ std::vector<fs::path> ret;
- return std::move(output);
- }
+ fs::stdfs::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)
- {
- output << line << "\n";
+ 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_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;
- }
+ virtual void rename(const fs::path & oldpath, const fs::path & newpath) override
+ {
+ fs::stdfs::rename(oldpath, newpath);
+ }
+ virtual bool remove(const fs::path & path) override
+ {
+ return fs::stdfs::remove(path);
+ }
+ virtual bool remove(const fs::path & path, std::error_code& ec) override
+ {
+ return fs::stdfs::remove(path, ec);
+ }
+ virtual std::uintmax_t remove_all(const fs::path & path, std::error_code& ec) override
+ {
+ return fs::stdfs::remove_all(path, ec);
+ }
+ virtual bool exists(const fs::path & path) const override
+ {
+ return fs::stdfs::exists(path);
+ }
+ virtual bool is_directory(const fs::path & path) const override
+ {
+ return fs::stdfs::is_directory(path);
+ }
+ virtual bool is_regular_file(const fs::path & path) const override
+ {
+ return fs::stdfs::is_regular_file(path);
+ }
+ virtual bool is_empty(const fs::path & path) const override
+ {
+ return fs::stdfs::is_empty(path);
+ }
+ virtual bool create_directory(const fs::path & path, std::error_code & ec) override
+ {
+ return fs::stdfs::create_directory(path, ec);
+ }
+ virtual void copy(const fs::path & oldpath, const fs::path & newpath, fs::copy_options opts) override
+ {
+ fs::stdfs::copy(oldpath, newpath, opts);
+ }
+ virtual bool copy_file(const fs::path & oldpath, const fs::path & newpath, fs::copy_options opts, std::error_code & ec) override
+ {
+ return fs::stdfs::copy_file(oldpath, newpath, opts, ec);
+ }
- 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);
- }
+ virtual fs::file_status status(const fs::path& path, std::error_code& ec) const override
+ {
+ return fs::stdfs::status(path, ec);
+ }
+ virtual void write_contents(const fs::path& file_path, const std::string& data) override
+ {
+ FILE* f = nullptr;
+ auto ec = _wfopen_s(&f, file_path.native().c_str(), L"wb");
+ Checks::check_exit(VCPKG_LINE_INFO, ec == 0);
+ auto count = fwrite(data.data(), sizeof(data[0]), data.size(), f);
+ fclose(f);
- 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;
- }
+ Checks::check_exit(VCPKG_LINE_INFO, count == data.size());
+ }
+ };
- 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/vcpkg_metrics_uploader.cpp b/toolsrc/src/vcpkg_metrics_uploader.cpp
index 9dbdc1fee..d0fc5179c 100644
--- a/toolsrc/src/vcpkg_metrics_uploader.cpp
+++ b/toolsrc/src/vcpkg_metrics_uploader.cpp
@@ -11,5 +11,5 @@ int WINAPI WinMain(_In_ HINSTANCE, _In_opt_ HINSTANCE, _In_ LPSTR, _In_ int)
LPWSTR * szArgList = CommandLineToArgvW(GetCommandLineW(), &argCount);
Checks::check_exit(VCPKG_LINE_INFO, argCount == 2, "Requires exactly one argument, the path to the payload file");
- Metrics::upload(Files::read_contents(szArgList[1]).value_or_exit(VCPKG_LINE_INFO));
+ Metrics::upload(Files::get_real_filesystem().read_contents(szArgList[1]).value_or_exit(VCPKG_LINE_INFO));
}
diff --git a/toolsrc/src/vcpkglib.cpp b/toolsrc/src/vcpkglib.cpp
index 253c0c7ea..90d3e99b9 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"
#include "vcpkg_Util.h"
@@ -10,20 +11,20 @@ namespace vcpkg
{
bool g_debugging = false;
- static StatusParagraphs load_current_database(const fs::path& vcpkg_dir_status_file, const fs::path& vcpkg_dir_status_file_old)
+ static StatusParagraphs load_current_database(Files::Filesystem& fs, const fs::path& vcpkg_dir_status_file, const fs::path& vcpkg_dir_status_file_old)
{
- if (!fs::exists(vcpkg_dir_status_file))
+ if (!fs.exists(vcpkg_dir_status_file))
{
- if (!fs::exists(vcpkg_dir_status_file_old))
+ if (!fs.exists(vcpkg_dir_status_file_old))
{
// no status file, use empty db
return StatusParagraphs();
}
- fs::rename(vcpkg_dir_status_file_old, vcpkg_dir_status_file);
+ fs.rename(vcpkg_dir_status_file_old, vcpkg_dir_status_file);
}
- auto pghs = Paragraphs::get_paragraphs(vcpkg_dir_status_file).value_or_exit(VCPKG_LINE_INFO);
+ auto pghs = Paragraphs::get_paragraphs(fs, vcpkg_dir_status_file).value_or_exit(VCPKG_LINE_INFO);
std::vector<std::unique_ptr<StatusParagraph>> status_pghs;
for (auto&& p : pghs)
@@ -36,57 +37,52 @@ 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(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.get_files_non_recursive(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(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));
}
}
- std::fstream(status_file_new, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc) << current_status_db;
+ fs.write_contents(status_file_new, Strings::serialize(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;
@@ -95,16 +91,17 @@ namespace vcpkg
void write_update(const VcpkgPaths& paths, const StatusParagraph& p)
{
static int update_id = 0;
+ auto& fs = paths.get_filesystem();
+
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);
+
+ fs.write_contents(tmp_update_filename, Strings::serialize(p));
+ fs.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;
@@ -168,8 +165,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_lines(updated_listfile_path, *lines);
+ fs.rename(updated_listfile_path, listfile_path);
}
std::vector<StatusParagraph*> get_installed_ports(const StatusParagraphs& status_db)
@@ -187,6 +184,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)
@@ -197,9 +196,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_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
Util::erase_remove_if(installed_files_of_current_pgh, [](const std::string& file) { return file.back() == '/'; });