From 4cbbf4ebe67f953f4b4611ec0f7dc34bcc44f43d Mon Sep 17 00:00:00 2001 From: ras0219 Date: Wed, 17 Jun 2020 12:32:05 -0700 Subject: [PATCH] [vcpkg] Fix issue #9781 by exporting from the installed directory (#11015) * [vcpkg] Fix issue #9781 by exporting from the installed directory * [vcpkg] Address code review comments for #11015 * [vcpkg] Remove duplicate triplet in installed path from exports Co-authored-by: Robert Schumacher --- toolsrc/include/vcpkg/base/files.h | 2 ++ toolsrc/include/vcpkg/install.h | 8 ++++++- toolsrc/src/vcpkg/commands.exportifw.cpp | 2 +- toolsrc/src/vcpkg/export.chocolatey.cpp | 2 +- toolsrc/src/vcpkg/export.cpp | 15 +++++++++++-- toolsrc/src/vcpkg/install.cpp | 27 +++++++++++++++--------- 6 files changed, 41 insertions(+), 15 deletions(-) diff --git a/toolsrc/include/vcpkg/base/files.h b/toolsrc/include/vcpkg/base/files.h index 909029b559e..cb041922178 100644 --- a/toolsrc/include/vcpkg/base/files.h +++ b/toolsrc/include/vcpkg/base/files.h @@ -111,6 +111,8 @@ namespace vcpkg::Files { std::string read_contents(const fs::path& file_path, LineInfo linfo) const; virtual Expected read_contents(const fs::path& file_path) const = 0; + /// Read text lines from a file + /// Lines will have up to one trailing carriage-return character stripped (CRLF) virtual Expected> read_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 get_files_recursive(const fs::path& dir) const = 0; diff --git a/toolsrc/include/vcpkg/install.h b/toolsrc/include/vcpkg/install.h index ad91bbb3782..9a438b0392c 100644 --- a/toolsrc/include/vcpkg/install.h +++ b/toolsrc/include/vcpkg/install.h @@ -70,7 +70,13 @@ namespace vcpkg::Install std::vector get_all_port_names(const VcpkgPaths& paths); - void install_files_and_write_listfile(Files::Filesystem& fs, const fs::path& source_dir, const InstallDir& dirs); + void install_package_and_write_listfile(const VcpkgPaths& paths, const PackageSpec& spec, const InstallDir& dirs); + + void install_files_and_write_listfile(Files::Filesystem& fs, + const fs::path& source_dir, + const std::vector& files, + const InstallDir& destination_dir); + InstallResult install_package(const VcpkgPaths& paths, const BinaryControlFile& binary_paragraph, StatusParagraphs* status_db); diff --git a/toolsrc/src/vcpkg/commands.exportifw.cpp b/toolsrc/src/vcpkg/commands.exportifw.cpp index 33b6acf0b76..db0987512d8 100644 --- a/toolsrc/src/vcpkg/commands.exportifw.cpp +++ b/toolsrc/src/vcpkg/commands.exportifw.cpp @@ -476,7 +476,7 @@ namespace vcpkg::Export::IFW ifw_package_dir_path / "vcpkg" / "info" / (binary_paragraph.fullstem() + ".list")); - Install::install_files_and_write_listfile(paths.get_filesystem(), paths.package_dir(action.spec), dirs); + Install::install_package_and_write_listfile(paths, action.spec, dirs); } System::printf("Exporting packages %s... done\n", ifw_packages_dir_path.generic_u8string()); diff --git a/toolsrc/src/vcpkg/export.chocolatey.cpp b/toolsrc/src/vcpkg/export.chocolatey.cpp index 81bdeacd76a..8d98a4d3f78 100644 --- a/toolsrc/src/vcpkg/export.chocolatey.cpp +++ b/toolsrc/src/vcpkg/export.chocolatey.cpp @@ -200,7 +200,7 @@ if (Test-Path $installedDir) action.spec.triplet().to_string(), per_package_dir_path / "installed" / "vcpkg" / "info" / (binary_paragraph.fullstem() + ".list")); - Install::install_files_and_write_listfile(paths.get_filesystem(), paths.package_dir(action.spec), dirs); + Install::install_package_and_write_listfile(paths, action.spec, dirs); const std::string nuspec_file_content = create_nuspec_file_contents( per_package_dir_path.string(), binary_paragraph, packages_version, chocolatey_options); diff --git a/toolsrc/src/vcpkg/export.cpp b/toolsrc/src/vcpkg/export.cpp index 1ecef7f7997..10f320bd827 100644 --- a/toolsrc/src/vcpkg/export.cpp +++ b/toolsrc/src/vcpkg/export.cpp @@ -3,9 +3,9 @@ #include #include #include -#include #include #include +#include #include #include #include @@ -519,7 +519,18 @@ namespace vcpkg::Export action.spec.triplet().to_string(), raw_exported_dir_path / "installed" / "vcpkg" / "info" / (binary_paragraph.fullstem() + ".list")); - Install::install_files_and_write_listfile(paths.get_filesystem(), paths.package_dir(action.spec), dirs); + auto lines = fs.read_lines(paths.listfile_path(binary_paragraph)).value_or_exit(VCPKG_LINE_INFO); + std::vector files; + for (auto&& suffix : lines) + { + if (suffix.empty()) continue; + if (suffix.back() == '/') suffix.pop_back(); + if (suffix == action.spec.triplet().to_string()) continue; + files.push_back(paths.installed / fs::u8path(suffix)); + } + + Install::install_files_and_write_listfile( + fs, paths.installed / action.spec.triplet().to_string(), files, dirs); } // Copy files needed for integration diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp index b8130a0cb75..d00a764fcd7 100644 --- a/toolsrc/src/vcpkg/install.cpp +++ b/toolsrc/src/vcpkg/install.cpp @@ -42,30 +42,37 @@ namespace vcpkg::Install const fs::path& InstallDir::listfile() const { return this->m_listfile; } + void install_package_and_write_listfile(const VcpkgPaths& paths, + const PackageSpec& spec, + const InstallDir& destination_dir) + { + auto& fs = paths.get_filesystem(); + auto source_dir = paths.package_dir(spec); + Checks::check_exit( + VCPKG_LINE_INFO, fs.exists(source_dir), "Source directory %s does not exist", source_dir.u8string()); + auto files = fs.get_files_recursive(source_dir); + install_files_and_write_listfile(fs, source_dir, files, destination_dir); + } void install_files_and_write_listfile(Files::Filesystem& fs, const fs::path& source_dir, + const std::vector& files, const InstallDir& destination_dir) { std::vector output; std::error_code ec; - const size_t prefix_length = source_dir.native().size(); + const size_t prefix_length = source_dir.generic_u8string().size(); const fs::path& destination = destination_dir.destination(); const std::string& destination_subdirectory = destination_dir.destination_subdirectory(); const fs::path& listfile = destination_dir.listfile(); - Checks::check_exit( - VCPKG_LINE_INFO, fs.exists(source_dir), "Source directory %s does not exist", source_dir.generic_string()); fs.create_directories(destination, ec); - Checks::check_exit( - VCPKG_LINE_INFO, !ec, "Could not create destination directory %s", destination.generic_string()); + Checks::check_exit(VCPKG_LINE_INFO, !ec, "Could not create destination directory %s", destination.u8string()); const fs::path listfile_parent = listfile.parent_path(); fs.create_directories(listfile_parent, ec); - Checks::check_exit( - VCPKG_LINE_INFO, !ec, "Could not create directory for listfile %s", listfile.generic_string()); + Checks::check_exit(VCPKG_LINE_INFO, !ec, "Could not create directory for listfile %s", listfile.u8string()); output.push_back(Strings::format(R"(%s/)", destination_subdirectory)); - auto files = fs.get_files_recursive(source_dir); for (auto&& file : files) { const auto status = fs.symlink_status(file, ec); @@ -75,7 +82,7 @@ namespace vcpkg::Install continue; } - const std::string filename = file.filename().u8string(); + const std::string filename = file.filename().generic_u8string(); if (fs::is_regular_file(status) && (Strings::case_insensitive_ascii_equals(filename, "CONTROL") || Strings::case_insensitive_ascii_equals(filename, "BUILD_INFO"))) { @@ -278,7 +285,7 @@ namespace vcpkg::Install const InstallDir install_dir = InstallDir::from_destination_root( paths.installed, triplet.to_string(), paths.listfile_path(bcf.core_paragraph)); - install_files_and_write_listfile(paths.get_filesystem(), package_dir, install_dir); + install_package_and_write_listfile(paths, bcf.core_paragraph.spec, install_dir); source_paragraph.state = InstallState::INSTALLED; write_update(paths, source_paragraph);