From d010c81b132d2d40e6f72adb49bcfe5a4d1ac353 Mon Sep 17 00:00:00 2001 From: Olaf Date: Mon, 8 May 2017 11:45:01 +0200 Subject: List packages for vcpkg install --- toolsrc/src/commands_update.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/commands_update.cpp b/toolsrc/src/commands_update.cpp index e39c7dd35..f87ccfb06 100644 --- a/toolsrc/src/commands_update.cpp +++ b/toolsrc/src/commands_update.cpp @@ -56,15 +56,18 @@ namespace vcpkg::Commands::Update } else { + std::string install_line; System::println("The following packages differ from their port versions:"); for (auto&& package : outdated_packages) { + install_line += package.spec.to_string(); + install_line += " "; System::println(" %-32s %s", package.spec, package.version_diff.to_string()); } System::println("\n" "To update these packages, run\n" " .\\vcpkg remove --outdated\n" - " .\\vcpkg install ..."); + " .\\vcpkg install " + install_line); } auto version_file = paths.get_filesystem().read_contents(paths.root / "toolsrc" / "VERSION.txt"); -- cgit v1.2.3 From c0be6aecc6c817e556e6bfd1251842615023644e Mon Sep 17 00:00:00 2001 From: Jon Erickson Date: Tue, 16 May 2017 21:10:00 -0400 Subject: Added '--full-desc' option to search and list commands to shows full description for packages. --- toolsrc/src/commands_list.cpp | 28 ++++++++++++++++++++-------- toolsrc/src/commands_search.cpp | 28 ++++++++++++++++++++-------- 2 files changed, 40 insertions(+), 16 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/commands_list.cpp b/toolsrc/src/commands_list.cpp index 6451ac5eb..521fc5a9a 100644 --- a/toolsrc/src/commands_list.cpp +++ b/toolsrc/src/commands_list.cpp @@ -7,12 +7,24 @@ namespace vcpkg::Commands::List { - static void do_print(const StatusParagraph& pgh) + static const std::string OPTION_FULLDESC = "--full-desc"; // TODO: This should find a better home, eventually + + static void do_print(const StatusParagraph& pgh, bool FullDesc) { - System::println("%-27s %-16s %s", - pgh.package.displayname(), - pgh.package.version, - details::shorten_description(pgh.package.description)); + if (FullDesc) + { + System::println("%-27s %-16s %s", + pgh.package.displayname(), + pgh.package.version, + pgh.package.description); + } + else + { + System::println("%-27s %-16s %s", + pgh.package.displayname(), + pgh.package.version, + details::shorten_description(pgh.package.description)); + } } void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) @@ -21,7 +33,7 @@ namespace vcpkg::Commands::List "The argument should be a substring to search for, or no argument to display all installed libraries.\n%s", Commands::Help::create_example_string("list png")); args.check_max_arg_count(1, example); - args.check_and_get_optional_command_arguments({}); + const std::unordered_set options = args.check_and_get_optional_command_arguments({OPTION_FULLDESC}); const StatusParagraphs status_paragraphs = database_load_check(paths); std::vector installed_packages = get_installed_ports(status_paragraphs); @@ -42,7 +54,7 @@ namespace vcpkg::Commands::List { for (const StatusParagraph* status_paragraph : installed_packages) { - do_print(*status_paragraph); + do_print(*status_paragraph, options.find(OPTION_FULLDESC) != options.cend()); } } else @@ -56,7 +68,7 @@ namespace vcpkg::Commands::List continue; } - do_print(*status_paragraph); + do_print(*status_paragraph, options.find(OPTION_FULLDESC) != options.cend()); } } diff --git a/toolsrc/src/commands_search.cpp b/toolsrc/src/commands_search.cpp index 0ba7305e9..6ec2a5395 100644 --- a/toolsrc/src/commands_search.cpp +++ b/toolsrc/src/commands_search.cpp @@ -9,6 +9,8 @@ namespace vcpkg::Commands::Search { static const std::string OPTION_GRAPH = "--graph"; // TODO: This should find a better home, eventually + static const std::string OPTION_FULLDESC = "--full-desc"; // TODO: This should find a better home, eventually + static std::string replace_dashes_with_underscore(const std::string& input) { @@ -45,12 +47,22 @@ namespace vcpkg::Commands::Search return s; } - static void do_print(const SourceParagraph& source_paragraph) + static void do_print(const SourceParagraph& source_paragraph, bool FullDesc) { - System::println("%-20s %-16s %s", - source_paragraph.name, - source_paragraph.version, - details::shorten_description(source_paragraph.description)); + if (FullDesc) + { + System::println("%-20s %-16s %s", + source_paragraph.name, + source_paragraph.version, + source_paragraph.description); + } + else + { + System::println("%-20s %-16s %s", + source_paragraph.name, + source_paragraph.version, + details::shorten_description(source_paragraph.description)); + } } void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) @@ -59,7 +71,7 @@ namespace vcpkg::Commands::Search "The argument should be a substring to search for, or no argument to display all libraries.\n%s", Commands::Help::create_example_string("search png")); args.check_max_arg_count(1, example); - const std::unordered_set options = args.check_and_get_optional_command_arguments({OPTION_GRAPH}); + const std::unordered_set options = args.check_and_get_optional_command_arguments({OPTION_GRAPH, OPTION_FULLDESC}); const std::vector source_paragraphs = Paragraphs::load_all_ports(paths.get_filesystem(), paths.ports); @@ -74,7 +86,7 @@ namespace vcpkg::Commands::Search { for (const SourceParagraph& source_paragraph : source_paragraphs) { - do_print(source_paragraph); + do_print(source_paragraph, options.find(OPTION_FULLDESC) != options.cend()); } } else @@ -88,7 +100,7 @@ namespace vcpkg::Commands::Search continue; } - do_print(source_paragraph); + do_print(source_paragraph, options.find(OPTION_FULLDESC) != options.cend()); } } -- cgit v1.2.3 From 621d2f852d43b5766bbf13bd22591524a083e48e Mon Sep 17 00:00:00 2001 From: Daniel Shaw Date: Mon, 22 May 2017 15:41:02 -0700 Subject: [vcpkg-search] added search in description --- toolsrc/src/commands_search.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/commands_search.cpp b/toolsrc/src/commands_search.cpp index 0ba7305e9..739aa0f43 100644 --- a/toolsrc/src/commands_search.cpp +++ b/toolsrc/src/commands_search.cpp @@ -85,7 +85,11 @@ namespace vcpkg::Commands::Search if (Strings::case_insensitive_ascii_find(source_paragraph.name, args.command_arguments[0]) == source_paragraph.name.end()) { - continue; + if (Strings::case_insensitive_ascii_find(source_paragraph.description, args.command_arguments[0]) == + source_paragraph.description.end()) + { + continue; + } } do_print(source_paragraph); -- cgit v1.2.3 From 3dd8bde9bdb46e3c501db5a123cb1431c701f2a1 Mon Sep 17 00:00:00 2001 From: Hartmut Kaiser Date: Mon, 22 May 2017 21:30:50 -0500 Subject: Adding policy ALLOW_OBSOLETE_MSVCRT suppressing dependency check for msvcrt.dll --- toolsrc/include/PostBuildLint_BuildPolicies.h | 8 ++-- toolsrc/src/PostBuildLint.cpp | 60 +++++++++++++++------------ toolsrc/src/PostBuildLint_BuildPolicies.cpp | 9 ++++ 3 files changed, 47 insertions(+), 30 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/PostBuildLint_BuildPolicies.h b/toolsrc/include/PostBuildLint_BuildPolicies.h index 697edbb8d..95e01d71c 100644 --- a/toolsrc/include/PostBuildLint_BuildPolicies.h +++ b/toolsrc/include/PostBuildLint_BuildPolicies.h @@ -13,7 +13,8 @@ namespace vcpkg::PostBuildLint EMPTY_PACKAGE, DLLS_WITHOUT_LIBS, ONLY_RELEASE_CRT, - EMPTY_INCLUDE_FOLDER + EMPTY_INCLUDE_FOLDER, + ALLOW_OBSOLETE_MSVCRT }; static BuildPolicies parse(const std::string& s); @@ -38,8 +39,9 @@ namespace vcpkg::PostBuildLint static constexpr BuildPolicies DLLS_WITHOUT_LIBS(BuildPolicies::BackingEnum::DLLS_WITHOUT_LIBS); static constexpr BuildPolicies ONLY_RELEASE_CRT(BuildPolicies::BackingEnum::ONLY_RELEASE_CRT); static constexpr BuildPolicies EMPTY_INCLUDE_FOLDER(BuildPolicies::BackingEnum::EMPTY_INCLUDE_FOLDER); + static constexpr BuildPolicies ALLOW_OBSOLETE_MSVCRT(BuildPolicies::BackingEnum::ALLOW_OBSOLETE_MSVCRT); - static constexpr std::array VALUES = { - EMPTY_PACKAGE, DLLS_WITHOUT_LIBS, ONLY_RELEASE_CRT, EMPTY_INCLUDE_FOLDER}; + static constexpr std::array VALUES = { + EMPTY_PACKAGE, DLLS_WITHOUT_LIBS, ONLY_RELEASE_CRT, EMPTY_INCLUDE_FOLDER, ALLOW_OBSOLETE_MSVCRT}; } } diff --git a/toolsrc/src/PostBuildLint.cpp b/toolsrc/src/PostBuildLint.cpp index 0d2f556c1..a8365e109 100644 --- a/toolsrc/src/PostBuildLint.cpp +++ b/toolsrc/src/PostBuildLint.cpp @@ -37,30 +37,6 @@ namespace vcpkg::PostBuildLint } }; - const std::vector& get_outdated_dynamic_crts() - { - static const std::vector v = {{"msvcp100.dll", R"(msvcp100\.dll)"}, - {"msvcp100d.dll", R"(msvcp100d\.dll)"}, - {"msvcp110.dll", R"(msvcp110\.dll)"}, - {"msvcp110_win.dll", R"(msvcp110_win\.dll)"}, - {"msvcp120.dll", R"(msvcp120\.dll)"}, - {"msvcp120_clr0400.dll", R"(msvcp120_clr0400\.dll)"}, - {"msvcp60.dll", R"(msvcp60\.dll)"}, - {"msvcp60.dll", R"(msvcp60\.dll)"}, - - {"msvcr100.dll", R"(msvcr100\.dll)"}, - {"msvcr100d.dll", R"(msvcr100d\.dll)"}, - {"msvcr100_clr0400.dll", R"(msvcr100_clr0400\.dll)"}, - {"msvcr110.dll", R"(msvcr110\.dll)"}, - {"msvcr120.dll", R"(msvcr120\.dll)"}, - {"msvcr120_clr0400.dll", R"(msvcr120_clr0400\.dll)"}, - {"msvcrt.dll", R"(msvcrt\.dll)"}, - {"msvcrt20.dll", R"(msvcrt20\.dll)"}, - {"msvcrt40.dll", R"(msvcrt40\.dll)"}}; - - return v; - } - template static bool contains_and_enabled(const std::map map, const T& key) { @@ -70,6 +46,34 @@ namespace vcpkg::PostBuildLint return false; } + const std::vector& get_outdated_dynamic_crts(const std::map& policies) + { + static std::vector v = {{"msvcp100.dll", R"(msvcp100\.dll)"}, + {"msvcp100d.dll", R"(msvcp100d\.dll)"}, + {"msvcp110.dll", R"(msvcp110\.dll)"}, + {"msvcp110_win.dll", R"(msvcp110_win\.dll)"}, + {"msvcp120.dll", R"(msvcp120\.dll)"}, + {"msvcp120_clr0400.dll", R"(msvcp120_clr0400\.dll)"}, + {"msvcp60.dll", R"(msvcp60\.dll)"}, + {"msvcp60.dll", R"(msvcp60\.dll)"}, + + {"msvcr100.dll", R"(msvcr100\.dll)"}, + {"msvcr100d.dll", R"(msvcr100d\.dll)"}, + {"msvcr100_clr0400.dll", R"(msvcr100_clr0400\.dll)"}, + {"msvcr110.dll", R"(msvcr110\.dll)"}, + {"msvcr120.dll", R"(msvcr120\.dll)"}, + {"msvcr120_clr0400.dll", R"(msvcr120_clr0400\.dll)"}, + {"msvcrt20.dll", R"(msvcrt20\.dll)"}, + {"msvcrt40.dll", R"(msvcrt40\.dll)"}}; + + if (contains_and_enabled(policies, BuildPoliciesC::ALLOW_OBSOLETE_MSVCRT)) + { + v.push_back(OutdatedDynamicCrt{"msvcrt.dll", R"(msvcrt\.dll)"}); + } + + return v; + } + static LintStatus check_for_files_in_include_directory(const Files::Filesystem& fs, const std::map& policies, const fs::path& package_dir) @@ -656,9 +660,11 @@ namespace vcpkg::PostBuildLint OutdatedDynamicCrt_and_file() = delete; }; - static LintStatus check_outdated_crt_linkage_of_dlls(const std::vector& dlls, const fs::path dumpbin_exe) + static LintStatus check_outdated_crt_linkage_of_dlls(const std::vector& dlls, + const fs::path dumpbin_exe, + const BuildInfo& build_info) { - const std::vector& outdated_crts = get_outdated_dynamic_crts(); + const std::vector& outdated_crts = get_outdated_dynamic_crts(build_info.policies); std::vector dlls_with_outdated_crt; @@ -798,7 +804,7 @@ namespace vcpkg::PostBuildLint error_count += check_uwp_bit_of_dlls(pre_build_info.cmake_system_name, dlls, toolset.dumpbin); error_count += check_dll_architecture(pre_build_info.target_architecture, dlls); - error_count += check_outdated_crt_linkage_of_dlls(dlls, toolset.dumpbin); + error_count += check_outdated_crt_linkage_of_dlls(dlls, toolset.dumpbin, build_info); break; } case LinkageType::BackingEnum::STATIC: diff --git a/toolsrc/src/PostBuildLint_BuildPolicies.cpp b/toolsrc/src/PostBuildLint_BuildPolicies.cpp index 001ba31e7..d2189e20d 100644 --- a/toolsrc/src/PostBuildLint_BuildPolicies.cpp +++ b/toolsrc/src/PostBuildLint_BuildPolicies.cpp @@ -12,6 +12,7 @@ namespace vcpkg::PostBuildLint static const std::string NAME_DLLS_WITHOUT_LIBS = "PolicyDLLsWithoutLIBs"; static const std::string NAME_ONLY_RELEASE_CRT = "PolicyOnlyReleaseCRT"; static const std::string NAME_EMPTY_INCLUDE_FOLDER = "PolicyEmptyIncludeFolder"; + static const std::string NAME_ALLOW_OBSOLETE_MSVCRT = "PolicyAllowObsoleteMsvcrt"; BuildPolicies BuildPolicies::parse(const std::string& s) { @@ -35,6 +36,11 @@ namespace vcpkg::PostBuildLint return BuildPoliciesC::EMPTY_INCLUDE_FOLDER; } + if (s == NAME_ALLOW_OBSOLETE_MSVCRT) + { + return BuildPoliciesC::ALLOW_OBSOLETE_MSVCRT; + } + return BuildPoliciesC::NULLVALUE; } @@ -46,6 +52,7 @@ namespace vcpkg::PostBuildLint case BuildPoliciesC::DLLS_WITHOUT_LIBS: return NAME_DLLS_WITHOUT_LIBS; case BuildPoliciesC::ONLY_RELEASE_CRT: return NAME_ONLY_RELEASE_CRT; case BuildPoliciesC::EMPTY_INCLUDE_FOLDER: return NAME_EMPTY_INCLUDE_FOLDER; + case BuildPoliciesC::ALLOW_OBSOLETE_MSVCRT: return NAME_ALLOW_OBSOLETE_MSVCRT; case BuildPoliciesC::NULLVALUE: return NULLVALUE_STRING; default: Checks::unreachable(VCPKG_LINE_INFO); } @@ -57,6 +64,7 @@ namespace vcpkg::PostBuildLint static const std::string CMAKE_VARIABLE_DLLS_WITHOUT_LIBS = "VCPKG_POLICY_DLLS_WITHOUT_LIBS"; static const std::string CMAKE_VARIABLE_ONLY_RELEASE_CRT = "VCPKG_POLICY_ONLY_RELEASE_CRT"; static const std::string CMAKE_VARIABLE_EMPTY_INCLUDE_FOLDER = "VCPKG_POLICY_EMPTY_INCLUDE_FOLDER"; + static const std::string CMAKE_VARIABLE_ALLOW_OBSOLETE_MSVCRT = "VCPKG_POLICY_ALLOW_OBSOLETE_MSVCRT"; switch (this->backing_enum) { @@ -64,6 +72,7 @@ namespace vcpkg::PostBuildLint case BuildPoliciesC::DLLS_WITHOUT_LIBS: return CMAKE_VARIABLE_DLLS_WITHOUT_LIBS; case BuildPoliciesC::ONLY_RELEASE_CRT: return CMAKE_VARIABLE_ONLY_RELEASE_CRT; case BuildPoliciesC::EMPTY_INCLUDE_FOLDER: return CMAKE_VARIABLE_EMPTY_INCLUDE_FOLDER; + case BuildPoliciesC::ALLOW_OBSOLETE_MSVCRT: return CMAKE_VARIABLE_ALLOW_OBSOLETE_MSVCRT; case BuildPoliciesC::NULLVALUE: Enums::nullvalue_used(VCPKG_LINE_INFO, BuildPoliciesC::ENUM_NAME); default: Checks::unreachable(VCPKG_LINE_INFO); } -- cgit v1.2.3 From f9d0ee313c815f7d2b322f0c68d20b539465ce38 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Mon, 22 May 2017 20:49:15 -0700 Subject: [vcpkg] Avoid modifying static globals after initialization --- toolsrc/src/PostBuildLint.cpp | 43 +++++++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 18 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/PostBuildLint.cpp b/toolsrc/src/PostBuildLint.cpp index a8365e109..4491f3f2e 100644 --- a/toolsrc/src/PostBuildLint.cpp +++ b/toolsrc/src/PostBuildLint.cpp @@ -48,27 +48,34 @@ namespace vcpkg::PostBuildLint const std::vector& get_outdated_dynamic_crts(const std::map& policies) { - static std::vector v = {{"msvcp100.dll", R"(msvcp100\.dll)"}, - {"msvcp100d.dll", R"(msvcp100d\.dll)"}, - {"msvcp110.dll", R"(msvcp110\.dll)"}, - {"msvcp110_win.dll", R"(msvcp110_win\.dll)"}, - {"msvcp120.dll", R"(msvcp120\.dll)"}, - {"msvcp120_clr0400.dll", R"(msvcp120_clr0400\.dll)"}, - {"msvcp60.dll", R"(msvcp60\.dll)"}, - {"msvcp60.dll", R"(msvcp60\.dll)"}, - - {"msvcr100.dll", R"(msvcr100\.dll)"}, - {"msvcr100d.dll", R"(msvcr100d\.dll)"}, - {"msvcr100_clr0400.dll", R"(msvcr100_clr0400\.dll)"}, - {"msvcr110.dll", R"(msvcr110\.dll)"}, - {"msvcr120.dll", R"(msvcr120\.dll)"}, - {"msvcr120_clr0400.dll", R"(msvcr120_clr0400\.dll)"}, - {"msvcrt20.dll", R"(msvcrt20\.dll)"}, - {"msvcrt40.dll", R"(msvcrt40\.dll)"}}; + static const std::vector v_no_msvcrt = { + {"msvcp100.dll", R"(msvcp100\.dll)"}, + {"msvcp100d.dll", R"(msvcp100d\.dll)"}, + {"msvcp110.dll", R"(msvcp110\.dll)"}, + {"msvcp110_win.dll", R"(msvcp110_win\.dll)"}, + {"msvcp120.dll", R"(msvcp120\.dll)"}, + {"msvcp120_clr0400.dll", R"(msvcp120_clr0400\.dll)"}, + {"msvcp60.dll", R"(msvcp60\.dll)"}, + {"msvcp60.dll", R"(msvcp60\.dll)"}, + + {"msvcr100.dll", R"(msvcr100\.dll)"}, + {"msvcr100d.dll", R"(msvcr100d\.dll)"}, + {"msvcr100_clr0400.dll", R"(msvcr100_clr0400\.dll)"}, + {"msvcr110.dll", R"(msvcr110\.dll)"}, + {"msvcr120.dll", R"(msvcr120\.dll)"}, + {"msvcr120_clr0400.dll", R"(msvcr120_clr0400\.dll)"}, + {"msvcrt20.dll", R"(msvcrt20\.dll)"}, + {"msvcrt40.dll", R"(msvcrt40\.dll)"}}; + + static const std::vector v = [&]() { + auto ret = v_no_msvcrt; + ret.push_back(OutdatedDynamicCrt{"msvcrt.dll", R"(msvcrt\.dll)"}); + return ret; + }(); if (contains_and_enabled(policies, BuildPoliciesC::ALLOW_OBSOLETE_MSVCRT)) { - v.push_back(OutdatedDynamicCrt{"msvcrt.dll", R"(msvcrt\.dll)"}); + return v_no_msvcrt; } return v; -- cgit v1.2.3 From 6be01a12db23788c32ca8cc8e70b8467ae912d1d Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Wed, 24 May 2017 00:44:00 -0700 Subject: [vcpkg] Refactored to simplify BuildPolicies into BuildPolicy. Restrict policy consumers to a simpler interface than std::map. Rename vcpkg::getMachineType -> vcpkg::to_machine_type. --- toolsrc/include/MachineType.h | 2 +- toolsrc/include/PostBuildLint_BuildPolicies.h | 47 ---------------- toolsrc/include/pch.h | 1 + toolsrc/include/vcpkg_Build.h | 39 +++++++++++-- toolsrc/src/MachineType.cpp | 2 +- toolsrc/src/PostBuildLint.cpp | 32 ++++------- toolsrc/src/PostBuildLint_BuildPolicies.cpp | 80 --------------------------- toolsrc/src/coff_file_reader.cpp | 6 +- toolsrc/src/vcpkg_Build.cpp | 37 +++++++++---- toolsrc/src/vcpkg_Build_BuildPolicy.cpp | 51 +++++++++++++++++ toolsrc/vcpkglib/vcpkglib.vcxproj | 5 +- toolsrc/vcpkglib/vcpkglib.vcxproj.filters | 15 ++--- 12 files changed, 135 insertions(+), 182 deletions(-) delete mode 100644 toolsrc/include/PostBuildLint_BuildPolicies.h delete mode 100644 toolsrc/src/PostBuildLint_BuildPolicies.cpp create mode 100644 toolsrc/src/vcpkg_Build_BuildPolicy.cpp (limited to 'toolsrc') diff --git a/toolsrc/include/MachineType.h b/toolsrc/include/MachineType.h index 2318c092b..6f61bbd53 100644 --- a/toolsrc/include/MachineType.h +++ b/toolsrc/include/MachineType.h @@ -32,5 +32,5 @@ namespace vcpkg WCEMIPSV2 = 0x169, // MIPS little-endian WCE v2 }; - MachineType getMachineType(const uint16_t value); + MachineType to_machine_type(const uint16_t value); } diff --git a/toolsrc/include/PostBuildLint_BuildPolicies.h b/toolsrc/include/PostBuildLint_BuildPolicies.h deleted file mode 100644 index 95e01d71c..000000000 --- a/toolsrc/include/PostBuildLint_BuildPolicies.h +++ /dev/null @@ -1,47 +0,0 @@ -#pragma once -#include "CStringView.h" -#include -#include - -namespace vcpkg::PostBuildLint -{ - struct BuildPolicies final - { - enum class BackingEnum - { - NULLVALUE = 0, - EMPTY_PACKAGE, - DLLS_WITHOUT_LIBS, - ONLY_RELEASE_CRT, - EMPTY_INCLUDE_FOLDER, - ALLOW_OBSOLETE_MSVCRT - }; - - static BuildPolicies parse(const std::string& s); - - constexpr BuildPolicies() : backing_enum(BackingEnum::NULLVALUE) {} - constexpr explicit BuildPolicies(BackingEnum backing_enum) : backing_enum(backing_enum) {} - constexpr operator BackingEnum() const { return backing_enum; } - - const std::string& to_string() const; - const std::string& cmake_variable() const; - - private: - BackingEnum backing_enum; - }; - - namespace BuildPoliciesC - { - static constexpr CStringView ENUM_NAME = "vcpkg::PostBuildLint::BuildPolicies"; - - static constexpr BuildPolicies NULLVALUE(BuildPolicies::BackingEnum::NULLVALUE); - static constexpr BuildPolicies EMPTY_PACKAGE(BuildPolicies::BackingEnum::EMPTY_PACKAGE); - static constexpr BuildPolicies DLLS_WITHOUT_LIBS(BuildPolicies::BackingEnum::DLLS_WITHOUT_LIBS); - static constexpr BuildPolicies ONLY_RELEASE_CRT(BuildPolicies::BackingEnum::ONLY_RELEASE_CRT); - static constexpr BuildPolicies EMPTY_INCLUDE_FOLDER(BuildPolicies::BackingEnum::EMPTY_INCLUDE_FOLDER); - static constexpr BuildPolicies ALLOW_OBSOLETE_MSVCRT(BuildPolicies::BackingEnum::ALLOW_OBSOLETE_MSVCRT); - - static constexpr std::array VALUES = { - EMPTY_PACKAGE, DLLS_WITHOUT_LIBS, ONLY_RELEASE_CRT, EMPTY_INCLUDE_FOLDER, ALLOW_OBSOLETE_MSVCRT}; - } -} diff --git a/toolsrc/include/pch.h b/toolsrc/include/pch.h index 2eee658c8..c58c30ea3 100644 --- a/toolsrc/include/pch.h +++ b/toolsrc/include/pch.h @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include diff --git a/toolsrc/include/vcpkg_Build.h b/toolsrc/include/vcpkg_Build.h index 4deb81900..45b3ff1e8 100644 --- a/toolsrc/include/vcpkg_Build.h +++ b/toolsrc/include/vcpkg_Build.h @@ -1,12 +1,13 @@ #pragma once +#include "CStringView.h" #include "PackageSpec.h" -#include "PostBuildLint_BuildPolicies.h" #include "PostBuildLint_LinkageType.h" #include "StatusParagraphs.h" #include "VcpkgPaths.h" #include "vcpkg_Files.h" #include "vcpkg_optional.h" + #include #include #include @@ -69,16 +70,46 @@ namespace vcpkg::Build const BuildPackageConfig& config, const StatusParagraphs& status_db); - struct BuildInfo + enum class BuildPolicy + { + EMPTY_PACKAGE, + DLLS_WITHOUT_LIBS, + ONLY_RELEASE_CRT, + EMPTY_INCLUDE_FOLDER, + ALLOW_OBSOLETE_MSVCRT, + // Must be last + COUNT, + }; + + Optional to_build_policy(const std::string& str); + + const std::string& to_string(BuildPolicy policy); + CStringView to_cmake_variable(BuildPolicy policy); + + struct BuildPolicies { - static BuildInfo create(std::unordered_map pgh); + BuildPolicies() {} + BuildPolicies(std::map&& map) : m_policies(std::move(map)) {} + inline bool is_enabled(BuildPolicy policy) const + { + auto it = m_policies.find(policy); + if (it != m_policies.cend()) return it->second; + return false; + } + + private: + std::map m_policies; + }; + + struct BuildInfo + { PostBuildLint::LinkageType crt_linkage; PostBuildLint::LinkageType library_linkage; Optional version; - std::map policies; + BuildPolicies policies; }; BuildInfo read_build_info(const Files::Filesystem& fs, const fs::path& filepath); diff --git a/toolsrc/src/MachineType.cpp b/toolsrc/src/MachineType.cpp index f288855e6..2f44ce21a 100644 --- a/toolsrc/src/MachineType.cpp +++ b/toolsrc/src/MachineType.cpp @@ -5,7 +5,7 @@ namespace vcpkg { - MachineType getMachineType(const uint16_t value) + MachineType to_machine_type(const uint16_t value) { MachineType t = static_cast(value); switch (t) diff --git a/toolsrc/src/PostBuildLint.cpp b/toolsrc/src/PostBuildLint.cpp index 4491f3f2e..bcad27032 100644 --- a/toolsrc/src/PostBuildLint.cpp +++ b/toolsrc/src/PostBuildLint.cpp @@ -12,6 +12,7 @@ using vcpkg::Build::PreBuildInfo; using vcpkg::Build::BuildInfo; +using vcpkg::Build::BuildPolicy; namespace vcpkg::PostBuildLint { @@ -37,16 +38,7 @@ namespace vcpkg::PostBuildLint } }; - template - static bool contains_and_enabled(const std::map map, const T& key) - { - auto it = map.find(key); - if (it != map.cend()) return it->second; - - return false; - } - - const std::vector& get_outdated_dynamic_crts(const std::map& policies) + const std::vector& get_outdated_dynamic_crts(const Build::BuildPolicies& policies) { static const std::vector v_no_msvcrt = { {"msvcp100.dll", R"(msvcp100\.dll)"}, @@ -73,7 +65,7 @@ namespace vcpkg::PostBuildLint return ret; }(); - if (contains_and_enabled(policies, BuildPoliciesC::ALLOW_OBSOLETE_MSVCRT)) + if (policies.is_enabled(BuildPolicy::ALLOW_OBSOLETE_MSVCRT)) { return v_no_msvcrt; } @@ -82,10 +74,10 @@ namespace vcpkg::PostBuildLint } static LintStatus check_for_files_in_include_directory(const Files::Filesystem& fs, - const std::map& policies, + const Build::BuildPolicies& policies, const fs::path& package_dir) { - if (contains_and_enabled(policies, BuildPoliciesC::EMPTY_INCLUDE_FOLDER)) + if (policies.is_enabled(BuildPolicy::EMPTY_INCLUDE_FOLDER)) { return LintStatus::SUCCESS; } @@ -511,16 +503,12 @@ namespace vcpkg::PostBuildLint return LintStatus::ERROR_DETECTED; } - static LintStatus check_lib_files_are_available_if_dlls_are_available(const std::map& policies, + static LintStatus check_lib_files_are_available_if_dlls_are_available(const Build::BuildPolicies& policies, const size_t lib_count, const size_t dll_count, const fs::path& lib_dir) { - auto it = policies.find(BuildPoliciesC::DLLS_WITHOUT_LIBS); - if (it != policies.cend() && it->second) - { - return LintStatus::SUCCESS; - } + if (policies.is_enabled(BuildPolicy::DLLS_WITHOUT_LIBS)) return LintStatus::SUCCESS; if (lib_count == 0 && dll_count != 0) { @@ -528,7 +516,7 @@ namespace vcpkg::PostBuildLint System::println(System::Color::warning, "If this is intended, add the following line in the portfile:\n" " SET(%s enabled)", - BuildPoliciesC::DLLS_WITHOUT_LIBS.cmake_variable()); + to_cmake_variable(BuildPolicy::DLLS_WITHOUT_LIBS)); return LintStatus::ERROR_DETECTED; } @@ -750,7 +738,7 @@ namespace vcpkg::PostBuildLint size_t error_count = 0; - if (contains_and_enabled(build_info.policies, BuildPoliciesC::EMPTY_PACKAGE)) + if (build_info.policies.is_enabled(BuildPolicy::EMPTY_PACKAGE)) { return error_count; } @@ -822,7 +810,7 @@ namespace vcpkg::PostBuildLint error_count += check_bin_folders_are_not_present_in_static_build(fs, package_dir); - if (!contains_and_enabled(build_info.policies, BuildPoliciesC::ONLY_RELEASE_CRT)) + if (!build_info.policies.is_enabled(BuildPolicy::ONLY_RELEASE_CRT)) { error_count += check_crt_linkage_of_libs( BuildType::value_of(ConfigurationTypeC::DEBUG, build_info.crt_linkage), diff --git a/toolsrc/src/PostBuildLint_BuildPolicies.cpp b/toolsrc/src/PostBuildLint_BuildPolicies.cpp deleted file mode 100644 index d2189e20d..000000000 --- a/toolsrc/src/PostBuildLint_BuildPolicies.cpp +++ /dev/null @@ -1,80 +0,0 @@ -#include "pch.h" - -#include "PostBuildLint_BuildPolicies.h" -#include "vcpkg_Checks.h" -#include "vcpkg_Enums.h" - -namespace vcpkg::PostBuildLint -{ - static const std::string NULLVALUE_STRING = Enums::nullvalue_to_string(BuildPoliciesC::ENUM_NAME); - - static const std::string NAME_EMPTY_PACKAGE = "PolicyEmptyPackage"; - static const std::string NAME_DLLS_WITHOUT_LIBS = "PolicyDLLsWithoutLIBs"; - static const std::string NAME_ONLY_RELEASE_CRT = "PolicyOnlyReleaseCRT"; - static const std::string NAME_EMPTY_INCLUDE_FOLDER = "PolicyEmptyIncludeFolder"; - static const std::string NAME_ALLOW_OBSOLETE_MSVCRT = "PolicyAllowObsoleteMsvcrt"; - - BuildPolicies BuildPolicies::parse(const std::string& s) - { - if (s == NAME_EMPTY_PACKAGE) - { - return BuildPoliciesC::EMPTY_PACKAGE; - } - - if (s == NAME_DLLS_WITHOUT_LIBS) - { - return BuildPoliciesC::DLLS_WITHOUT_LIBS; - } - - if (s == NAME_ONLY_RELEASE_CRT) - { - return BuildPoliciesC::ONLY_RELEASE_CRT; - } - - if (s == NAME_EMPTY_INCLUDE_FOLDER) - { - return BuildPoliciesC::EMPTY_INCLUDE_FOLDER; - } - - if (s == NAME_ALLOW_OBSOLETE_MSVCRT) - { - return BuildPoliciesC::ALLOW_OBSOLETE_MSVCRT; - } - - return BuildPoliciesC::NULLVALUE; - } - - const std::string& BuildPolicies::to_string() const - { - switch (this->backing_enum) - { - case BuildPoliciesC::EMPTY_PACKAGE: return NAME_EMPTY_PACKAGE; - case BuildPoliciesC::DLLS_WITHOUT_LIBS: return NAME_DLLS_WITHOUT_LIBS; - case BuildPoliciesC::ONLY_RELEASE_CRT: return NAME_ONLY_RELEASE_CRT; - case BuildPoliciesC::EMPTY_INCLUDE_FOLDER: return NAME_EMPTY_INCLUDE_FOLDER; - case BuildPoliciesC::ALLOW_OBSOLETE_MSVCRT: return NAME_ALLOW_OBSOLETE_MSVCRT; - case BuildPoliciesC::NULLVALUE: return NULLVALUE_STRING; - default: Checks::unreachable(VCPKG_LINE_INFO); - } - } - - const std::string& BuildPolicies::cmake_variable() const - { - static const std::string CMAKE_VARIABLE_EMPTY_PACKAGE = "VCPKG_POLICY_EMPTY_PACKAGE"; - static const std::string CMAKE_VARIABLE_DLLS_WITHOUT_LIBS = "VCPKG_POLICY_DLLS_WITHOUT_LIBS"; - static const std::string CMAKE_VARIABLE_ONLY_RELEASE_CRT = "VCPKG_POLICY_ONLY_RELEASE_CRT"; - static const std::string CMAKE_VARIABLE_EMPTY_INCLUDE_FOLDER = "VCPKG_POLICY_EMPTY_INCLUDE_FOLDER"; - static const std::string CMAKE_VARIABLE_ALLOW_OBSOLETE_MSVCRT = "VCPKG_POLICY_ALLOW_OBSOLETE_MSVCRT"; - - switch (this->backing_enum) - { - case BuildPoliciesC::EMPTY_PACKAGE: return CMAKE_VARIABLE_EMPTY_PACKAGE; - case BuildPoliciesC::DLLS_WITHOUT_LIBS: return CMAKE_VARIABLE_DLLS_WITHOUT_LIBS; - case BuildPoliciesC::ONLY_RELEASE_CRT: return CMAKE_VARIABLE_ONLY_RELEASE_CRT; - case BuildPoliciesC::EMPTY_INCLUDE_FOLDER: return CMAKE_VARIABLE_EMPTY_INCLUDE_FOLDER; - case BuildPoliciesC::ALLOW_OBSOLETE_MSVCRT: return CMAKE_VARIABLE_ALLOW_OBSOLETE_MSVCRT; - case BuildPoliciesC::NULLVALUE: Enums::nullvalue_used(VCPKG_LINE_INFO, BuildPoliciesC::ENUM_NAME); - default: Checks::unreachable(VCPKG_LINE_INFO); - } - } -} diff --git a/toolsrc/src/coff_file_reader.cpp b/toolsrc/src/coff_file_reader.cpp index 467fc9a64..b06c6d57b 100644 --- a/toolsrc/src/coff_file_reader.cpp +++ b/toolsrc/src/coff_file_reader.cpp @@ -87,7 +87,7 @@ namespace vcpkg::COFFFileReader std::string machine_field_as_string = data.substr(MACHINE_TYPE_OFFSET, MACHINE_TYPE_SIZE); const uint16_t machine = reinterpret_bytes(machine_field_as_string.c_str()); - return getMachineType(machine); + return to_machine_type(machine); } private: @@ -210,7 +210,7 @@ namespace vcpkg::COFFFileReader std::string machine_field_as_string = data.substr(MACHINE_TYPE_OFFSET, MACHINE_TYPE_SIZE); const uint16_t machine = reinterpret_bytes(machine_field_as_string.c_str()); - return getMachineType(machine); + return to_machine_type(machine); } private: @@ -297,7 +297,7 @@ namespace vcpkg::COFFFileReader marker.set_to_offset(offset + ArchiveMemberHeader::HEADER_SIZE); // Skip the header, no need to read it. marker.seek_to_marker(fs); const uint16_t first_two_bytes = peek_value_from_stream(fs); - const bool isImportHeader = getMachineType(first_two_bytes) == MachineType::UNKNOWN; + const bool isImportHeader = to_machine_type(first_two_bytes) == MachineType::UNKNOWN; const MachineType machine = isImportHeader ? ImportHeader::read(fs).machineType() : CoffFileHeader::read(fs).machineType(); machine_types.insert(machine); diff --git a/toolsrc/src/vcpkg_Build.cpp b/toolsrc/src/vcpkg_Build.cpp index 6605fa4fb..d44a673fc 100644 --- a/toolsrc/src/vcpkg_Build.cpp +++ b/toolsrc/src/vcpkg_Build.cpp @@ -13,8 +13,6 @@ #include "vcpkglib.h" #include "vcpkglib_helpers.h" -using vcpkg::PostBuildLint::BuildPolicies; -namespace BuildPoliciesC = vcpkg::PostBuildLint::BuildPoliciesC; using vcpkg::PostBuildLint::LinkageType; namespace LinkageTypeC = vcpkg::PostBuildLint::LinkageTypeC; @@ -214,7 +212,7 @@ namespace vcpkg::Build Commands::Version::version()); } - BuildInfo BuildInfo::create(std::unordered_map pgh) + static BuildInfo inner_create_buildinfo(std::unordered_map pgh) { BuildInfo build_info; const std::string crt_linkage_as_string = @@ -240,20 +238,35 @@ namespace vcpkg::Build pgh.erase(it_version); } + std::map policies; + // The remaining entries are policies for (const std::unordered_map::value_type& p : pgh) { - const BuildPolicies policy = BuildPolicies::parse(p.first); - Checks::check_exit( - VCPKG_LINE_INFO, policy != BuildPoliciesC::NULLVALUE, "Unknown policy found: %s", p.first); - if (p.second == "enabled") - build_info.policies.emplace(policy, true); - else if (p.second == "disabled") - build_info.policies.emplace(policy, false); + auto maybe_policy = to_build_policy(p.first); + if (auto policy = maybe_policy.get()) + { + Checks::check_exit(VCPKG_LINE_INFO, + policies.find(*policy) == policies.end(), + "Policy specified multiple times: %s", + p.first); + + if (p.second == "enabled") + policies.emplace(*policy, true); + else if (p.second == "disabled") + policies.emplace(*policy, false); + else + Checks::exit_with_message( + VCPKG_LINE_INFO, "Unknown setting for policy '%s': %s", p.first, p.second); + } else - Checks::exit_with_message(VCPKG_LINE_INFO, "Unknown setting for policy '%s': %s", p.first, p.second); + { + Checks::exit_with_message(VCPKG_LINE_INFO, "Unknown policy found: %s", p.first); + } } + build_info.policies = BuildPolicies(std::move(policies)); + return build_info; } @@ -262,7 +275,7 @@ namespace vcpkg::Build const Expected> 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()); + return inner_create_buildinfo(*pghs.get()); } PreBuildInfo PreBuildInfo::from_triplet_file(const VcpkgPaths& paths, const Triplet& triplet) diff --git a/toolsrc/src/vcpkg_Build_BuildPolicy.cpp b/toolsrc/src/vcpkg_Build_BuildPolicy.cpp new file mode 100644 index 000000000..e75e176a2 --- /dev/null +++ b/toolsrc/src/vcpkg_Build_BuildPolicy.cpp @@ -0,0 +1,51 @@ +#include "pch.h" + +#include "vcpkg_Build.h" +#include "vcpkg_Checks.h" +#include "vcpkg_Enums.h" + +namespace vcpkg::Build +{ + static const std::string NAME_EMPTY_PACKAGE = "PolicyEmptyPackage"; + static const std::string NAME_DLLS_WITHOUT_LIBS = "PolicyDLLsWithoutLIBs"; + static const std::string NAME_ONLY_RELEASE_CRT = "PolicyOnlyReleaseCRT"; + static const std::string NAME_EMPTY_INCLUDE_FOLDER = "PolicyEmptyIncludeFolder"; + static const std::string NAME_ALLOW_OBSOLETE_MSVCRT = "PolicyAllowObsoleteMsvcrt"; + + Optional to_build_policy(const std::string& s) + { + if (s == NAME_EMPTY_PACKAGE) return BuildPolicy::EMPTY_PACKAGE; + if (s == NAME_DLLS_WITHOUT_LIBS) return BuildPolicy::DLLS_WITHOUT_LIBS; + if (s == NAME_ONLY_RELEASE_CRT) return BuildPolicy::ONLY_RELEASE_CRT; + if (s == NAME_EMPTY_INCLUDE_FOLDER) return BuildPolicy::EMPTY_INCLUDE_FOLDER; + if (s == NAME_ALLOW_OBSOLETE_MSVCRT) return BuildPolicy::ALLOW_OBSOLETE_MSVCRT; + + return nullopt; + } + + const std::string& to_string(BuildPolicy policy) + { + switch (policy) + { + case BuildPolicy::EMPTY_PACKAGE: return NAME_EMPTY_PACKAGE; + case BuildPolicy::DLLS_WITHOUT_LIBS: return NAME_DLLS_WITHOUT_LIBS; + case BuildPolicy::ONLY_RELEASE_CRT: return NAME_ONLY_RELEASE_CRT; + case BuildPolicy::EMPTY_INCLUDE_FOLDER: return NAME_EMPTY_INCLUDE_FOLDER; + case BuildPolicy::ALLOW_OBSOLETE_MSVCRT: return NAME_ALLOW_OBSOLETE_MSVCRT; + default: Checks::unreachable(VCPKG_LINE_INFO); + } + } + + CStringView to_cmake_variable(BuildPolicy policy) + { + switch (policy) + { + case BuildPolicy::EMPTY_PACKAGE: return "VCPKG_POLICY_EMPTY_PACKAGE"; + case BuildPolicy::DLLS_WITHOUT_LIBS: return "VCPKG_POLICY_DLLS_WITHOUT_LIBS"; + case BuildPolicy::ONLY_RELEASE_CRT: return "VCPKG_POLICY_ONLY_RELEASE_CRT"; + case BuildPolicy::EMPTY_INCLUDE_FOLDER: return "VCPKG_POLICY_EMPTY_INCLUDE_FOLDER"; + case BuildPolicy::ALLOW_OBSOLETE_MSVCRT: return "VCPKG_POLICY_ALLOW_OBSOLETE_MSVCRT"; + default: Checks::unreachable(VCPKG_LINE_INFO); + } + } +} diff --git a/toolsrc/vcpkglib/vcpkglib.vcxproj b/toolsrc/vcpkglib/vcpkglib.vcxproj index 472f4d4e9..4ec37a16d 100644 --- a/toolsrc/vcpkglib/vcpkglib.vcxproj +++ b/toolsrc/vcpkglib/vcpkglib.vcxproj @@ -141,8 +141,8 @@ + - @@ -154,7 +154,6 @@ - @@ -189,7 +188,7 @@ - + diff --git a/toolsrc/vcpkglib/vcpkglib.vcxproj.filters b/toolsrc/vcpkglib/vcpkglib.vcxproj.filters index f8958b4a6..895eb2a4a 100644 --- a/toolsrc/vcpkglib/vcpkglib.vcxproj.filters +++ b/toolsrc/vcpkglib/vcpkglib.vcxproj.filters @@ -129,9 +129,6 @@ Source Files - - Source Files - Source Files @@ -183,6 +180,9 @@ Source Files + + Source Files + @@ -257,18 +257,12 @@ Header Files - - Header Files - Header Files Header Files - - Header Files - Header Files @@ -314,5 +308,8 @@ Header Files + + Header Files + \ No newline at end of file -- cgit v1.2.3 From a5eb44f1a62315f673b8f2f48c1d3895dcceabda Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Wed, 24 May 2017 15:51:18 -0700 Subject: [vcpkg] Rename CoffFileHeader::machineType -> machine_type --- toolsrc/src/coff_file_reader.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/coff_file_reader.cpp b/toolsrc/src/coff_file_reader.cpp index b06c6d57b..6c38c452b 100644 --- a/toolsrc/src/coff_file_reader.cpp +++ b/toolsrc/src/coff_file_reader.cpp @@ -80,7 +80,7 @@ namespace vcpkg::COFFFileReader return ret; } - MachineType machineType() const + MachineType machine_type() const { static const size_t MACHINE_TYPE_OFFSET = 0; static const size_t MACHINE_TYPE_SIZE = 2; @@ -203,7 +203,7 @@ namespace vcpkg::COFFFileReader return ret; } - MachineType machineType() const + MachineType machine_type() const { static const size_t MACHINE_TYPE_OFFSET = 6; static const size_t MACHINE_TYPE_SIZE = 2; @@ -236,7 +236,7 @@ namespace vcpkg::COFFFileReader read_and_verify_PE_signature(fs); CoffFileHeader header = CoffFileHeader::read(fs); - MachineType machine = header.machineType(); + MachineType machine = header.machine_type(); return {machine}; } @@ -299,7 +299,7 @@ namespace vcpkg::COFFFileReader const uint16_t first_two_bytes = peek_value_from_stream(fs); const bool isImportHeader = to_machine_type(first_two_bytes) == MachineType::UNKNOWN; const MachineType machine = - isImportHeader ? ImportHeader::read(fs).machineType() : CoffFileHeader::read(fs).machineType(); + isImportHeader ? ImportHeader::read(fs).machine_type() : CoffFileHeader::read(fs).machine_type(); machine_types.insert(machine); } -- cgit v1.2.3 From 81fe73d02061866c2188fc8d9e13f9990a20d64d Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Wed, 24 May 2017 15:54:12 -0700 Subject: [vcpkg] Add comments --- toolsrc/include/BinaryParagraph.h | 3 +++ toolsrc/include/SourceParagraph.h | 3 +++ toolsrc/include/StatusParagraph.h | 3 +++ toolsrc/include/vcpkg_Build.h | 6 ++++++ 4 files changed, 15 insertions(+) (limited to 'toolsrc') diff --git a/toolsrc/include/BinaryParagraph.h b/toolsrc/include/BinaryParagraph.h index 90ca8fe9a..1c2edf790 100644 --- a/toolsrc/include/BinaryParagraph.h +++ b/toolsrc/include/BinaryParagraph.h @@ -6,6 +6,9 @@ namespace vcpkg { + /// + /// Built package metadata + /// struct BinaryParagraph { BinaryParagraph(); diff --git a/toolsrc/include/SourceParagraph.h b/toolsrc/include/SourceParagraph.h index 8d51b45d4..19f558170 100644 --- a/toolsrc/include/SourceParagraph.h +++ b/toolsrc/include/SourceParagraph.h @@ -15,6 +15,9 @@ namespace vcpkg const std::string& to_string(const Dependency& dep); + /// + /// Port metadata (CONTROL file) + /// struct SourceParagraph { SourceParagraph(); diff --git a/toolsrc/include/StatusParagraph.h b/toolsrc/include/StatusParagraph.h index ad913d11b..2d1815dc0 100644 --- a/toolsrc/include/StatusParagraph.h +++ b/toolsrc/include/StatusParagraph.h @@ -23,6 +23,9 @@ namespace vcpkg PURGE }; + /// + /// Installed package metadata + /// struct StatusParagraph { StatusParagraph(); diff --git a/toolsrc/include/vcpkg_Build.h b/toolsrc/include/vcpkg_Build.h index 45b3ff1e8..e0a5ae1ce 100644 --- a/toolsrc/include/vcpkg_Build.h +++ b/toolsrc/include/vcpkg_Build.h @@ -33,8 +33,14 @@ namespace vcpkg::Build std::string create_error_message(const BuildResult build_result, const PackageSpec& spec); std::string create_user_troubleshooting_message(const PackageSpec& spec); + /// + /// Settings from the triplet file which impact the build environment and post-build checks + /// struct PreBuildInfo { + /// + /// Runs the triplet file in a "capture" mode to create a PreBuildInfo + /// static PreBuildInfo from_triplet_file(const VcpkgPaths& paths, const Triplet& triplet); std::string target_architecture; -- cgit v1.2.3 From 1253b875195590e528d8a28e12a798264603ba43 Mon Sep 17 00:00:00 2001 From: Albert Ziegenhagel Date: Fri, 2 Jun 2017 18:13:12 +0200 Subject: Implement support to request a specific toolset version via the variable `VCPKG_PLATFORM_TOOLSET` in the triplet file --- toolsrc/include/VcpkgPaths.h | 7 +++-- toolsrc/src/PostBuildLint.cpp | 2 +- toolsrc/src/VcpkgPaths.cpp | 63 ++++++++++++++++++++++++++++++++++++------- toolsrc/src/commands_env.cpp | 2 +- toolsrc/src/vcpkg_Build.cpp | 2 +- 5 files changed, 61 insertions(+), 15 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/VcpkgPaths.h b/toolsrc/include/VcpkgPaths.h index 25c1728b9..ca03f0e2a 100644 --- a/toolsrc/include/VcpkgPaths.h +++ b/toolsrc/include/VcpkgPaths.h @@ -48,7 +48,10 @@ namespace vcpkg const fs::path& get_cmake_exe() const; const fs::path& get_git_exe() const; const fs::path& get_nuget_exe() const; - const Toolset& get_toolset() const; + const std::vector& get_toolsets() const; + + const Toolset& get_latest_toolset() const; + const Toolset& get_toolset(const std::string& toolset_version) const; Files::Filesystem& get_filesystem() const; @@ -56,6 +59,6 @@ namespace vcpkg Lazy cmake_exe; Lazy git_exe; Lazy nuget_exe; - Lazy toolset; + Lazy> toolsets; }; } diff --git a/toolsrc/src/PostBuildLint.cpp b/toolsrc/src/PostBuildLint.cpp index bcad27032..363346ab6 100644 --- a/toolsrc/src/PostBuildLint.cpp +++ b/toolsrc/src/PostBuildLint.cpp @@ -733,7 +733,7 @@ namespace vcpkg::PostBuildLint const auto& fs = paths.get_filesystem(); // for dumpbin - const Toolset& toolset = paths.get_toolset(); + const Toolset& toolset = paths.get_toolset(pre_build_info.platform_toolset); const fs::path package_dir = paths.package_dir(spec); size_t error_count = 0; diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp index 3dd32de01..acd847b5f 100644 --- a/toolsrc/src/VcpkgPaths.cpp +++ b/toolsrc/src/VcpkgPaths.cpp @@ -269,7 +269,7 @@ namespace vcpkg return nullopt; } - static Toolset find_toolset_instance(const VcpkgPaths& paths) + static std::vector find_toolset_instances(const VcpkgPaths& paths) { const auto& fs = paths.get_filesystem(); @@ -277,7 +277,10 @@ namespace vcpkg // Note: this will contain a mix of vcvarsall.bat locations and dumpbin.exe locations. std::vector paths_examined; + std::vector found_toolsets; + // VS2017 + Optional vs2017_toolset; for (const fs::path& instance : vs2017_installation_instances) { const fs::path vc_dir = instance / "VC"; @@ -303,9 +306,15 @@ namespace vcpkg paths_examined.push_back(dumpbin_path); if (fs.exists(dumpbin_path)) { - return {dumpbin_path, vcvarsall_bat, L"v141"}; + vs2017_toolset = Toolset{dumpbin_path, vcvarsall_bat, L"v141"}; + break; } } + if(vs2017_toolset) break; + } + if(auto value = vs2017_toolset.get()) + { + found_toolsets.push_back(*value); } // VS2015 @@ -321,23 +330,57 @@ namespace vcpkg paths_examined.push_back(vs2015_dumpbin_exe); if (fs.exists(vs2015_dumpbin_exe)) { - return {vs2015_dumpbin_exe, vs2015_vcvarsall_bat, L"v140"}; + found_toolsets.push_back({vs2015_dumpbin_exe, vs2015_vcvarsall_bat, L"v140"}); } } } - System::println(System::Color::error, "Could not locate a complete toolset."); - System::println("The following paths were examined:"); - for (const fs::path& path : paths_examined) + std::sort(found_toolsets.begin(), + found_toolsets.end(), + [](const Toolset& left, const Toolset& right) { return left.version > right.version; }); + + if(found_toolsets.empty()) { - System::println(" %s", path.u8string()); + System::println(System::Color::error, "Could not locate a complete toolset."); + System::println("The following paths were examined:"); + for(const fs::path& path : paths_examined) + { + System::println(" %s", path.u8string()); + } + Checks::exit_fail(VCPKG_LINE_INFO); } - Checks::exit_fail(VCPKG_LINE_INFO); + + return found_toolsets; + } + + const std::vector& VcpkgPaths::get_toolsets() const + { + return this->toolsets.get_lazy([this]() { return find_toolset_instances(*this); }); } - const Toolset& VcpkgPaths::get_toolset() const + const Toolset& VcpkgPaths::get_latest_toolset() const { - return this->toolset.get_lazy([this]() { return find_toolset_instance(*this); }); + // Invariant: toolsets are non-empty and sorted + return get_toolsets().back(); } + const Toolset& VcpkgPaths::get_toolset(const std::string& toolset_version) const + { + if(toolset_version.empty()) + { + return this->get_latest_toolset(); + } + else + { + const auto& vs_toolsets = this->get_toolsets(); + + const auto toolset = Util::find_if(vs_toolsets, [&](const Toolset& toolset) { return toolset_version == Strings::to_utf8(toolset.version); }); + if(toolset == vs_toolsets.end()) + { + Checks::exit_with_message(VCPKG_LINE_INFO, Strings::format("Could not find toolset %s", toolset_version)); + } + return *toolset; + } + } + Files::Filesystem& VcpkgPaths::get_filesystem() const { return Files::get_real_filesystem(); } } diff --git a/toolsrc/src/commands_env.cpp b/toolsrc/src/commands_env.cpp index 5e1ecc5e7..dd7172b89 100644 --- a/toolsrc/src/commands_env.cpp +++ b/toolsrc/src/commands_env.cpp @@ -13,7 +13,7 @@ namespace vcpkg::Commands::Env args.check_and_get_optional_command_arguments({}); auto pre_build_info = Build::PreBuildInfo::from_triplet_file(paths, default_triplet); - System::cmd_execute_clean(Build::make_build_env_cmd(pre_build_info, paths.get_toolset()) + L" && cmd"); + System::cmd_execute_clean(Build::make_build_env_cmd(pre_build_info, paths.get_toolset(pre_build_info.platform_toolset)) + L" && cmd"); Checks::exit_success(VCPKG_LINE_INFO); } diff --git a/toolsrc/src/vcpkg_Build.cpp b/toolsrc/src/vcpkg_Build.cpp index d44a673fc..817febe2f 100644 --- a/toolsrc/src/vcpkg_Build.cpp +++ b/toolsrc/src/vcpkg_Build.cpp @@ -128,8 +128,8 @@ namespace vcpkg::Build const fs::path& git_exe_path = paths.get_git_exe(); const fs::path ports_cmake_script_path = paths.ports_cmake; - const Toolset& toolset = paths.get_toolset(); auto pre_build_info = PreBuildInfo::from_triplet_file(paths, triplet); + const Toolset& toolset = paths.get_toolset(pre_build_info.platform_toolset); const auto cmd_set_environment = make_build_env_cmd(pre_build_info, toolset); const std::wstring cmd_launch_cmake = -- cgit v1.2.3 From 60825eed0e8b8c7646d0e66bc2743b4a1e8e4a96 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Mon, 5 Jun 2017 22:01:41 -0700 Subject: [vcpkg] Formatting and simplification of VcpkgPaths::get_toolset() --- toolsrc/include/VcpkgPaths.h | 6 ++-- toolsrc/src/VcpkgPaths.cpp | 79 ++++++++++++++++++-------------------------- 2 files changed, 37 insertions(+), 48 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/VcpkgPaths.h b/toolsrc/include/VcpkgPaths.h index ca03f0e2a..95cd4bc28 100644 --- a/toolsrc/include/VcpkgPaths.h +++ b/toolsrc/include/VcpkgPaths.h @@ -48,9 +48,11 @@ namespace vcpkg const fs::path& get_cmake_exe() const; const fs::path& get_git_exe() const; const fs::path& get_nuget_exe() const; - const std::vector& get_toolsets() const; - const Toolset& get_latest_toolset() const; + /// Retrieve a toolset matching a VS version + /// + /// Valid version strings are "v140", "v141", and "". Empty string gets the latest. + /// const Toolset& get_toolset(const std::string& toolset_version) const; Files::Filesystem& get_filesystem() const; diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp index acd847b5f..9068e3903 100644 --- a/toolsrc/src/VcpkgPaths.cpp +++ b/toolsrc/src/VcpkgPaths.cpp @@ -279,6 +279,24 @@ namespace vcpkg std::vector found_toolsets; + // VS2015 + const Optional vs_2015_installation_instance = get_VS2015_installation_instance(); + if (auto v = vs_2015_installation_instance.get()) + { + const fs::path vs2015_vcvarsall_bat = *v / "VC" / "vcvarsall.bat"; + + paths_examined.push_back(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)) + { + found_toolsets.push_back({vs2015_dumpbin_exe, vs2015_vcvarsall_bat, L"v140"}); + } + } + } + // VS2017 Optional vs2017_toolset; for (const fs::path& instance : vs2017_installation_instances) @@ -310,40 +328,18 @@ namespace vcpkg break; } } - if(vs2017_toolset) break; - } - if(auto value = vs2017_toolset.get()) - { - found_toolsets.push_back(*value); - } - - // VS2015 - const Optional vs_2015_installation_instance = get_VS2015_installation_instance(); - if (auto v = vs_2015_installation_instance.get()) - { - const fs::path vs2015_vcvarsall_bat = *v / "VC" / "vcvarsall.bat"; - - paths_examined.push_back(vs2015_vcvarsall_bat); - if (fs.exists(vs2015_vcvarsall_bat)) + if (auto value = vs2017_toolset.get()) { - const fs::path vs2015_dumpbin_exe = *v / "VC" / "bin" / "dumpbin.exe"; - paths_examined.push_back(vs2015_dumpbin_exe); - if (fs.exists(vs2015_dumpbin_exe)) - { - found_toolsets.push_back({vs2015_dumpbin_exe, vs2015_vcvarsall_bat, L"v140"}); - } + found_toolsets.push_back(*value); + break; } } - std::sort(found_toolsets.begin(), - found_toolsets.end(), - [](const Toolset& left, const Toolset& right) { return left.version > right.version; }); - - if(found_toolsets.empty()) + if (found_toolsets.empty()) { System::println(System::Color::error, "Could not locate a complete toolset."); System::println("The following paths were examined:"); - for(const fs::path& path : paths_examined) + for (const fs::path& path : paths_examined) { System::println(" %s", path.u8string()); } @@ -353,31 +349,22 @@ namespace vcpkg return found_toolsets; } - const std::vector& VcpkgPaths::get_toolsets() const - { - return this->toolsets.get_lazy([this]() { return find_toolset_instances(*this); }); - } - - const Toolset& VcpkgPaths::get_latest_toolset() const - { - // Invariant: toolsets are non-empty and sorted - return get_toolsets().back(); - } const Toolset& VcpkgPaths::get_toolset(const std::string& toolset_version) const { - if(toolset_version.empty()) + // Invariant: toolsets are non-empty and sorted with newest at back() + const auto& vs_toolsets = this->toolsets.get_lazy([this]() { return find_toolset_instances(*this); }); + + if (toolset_version.empty()) { - return this->get_latest_toolset(); + return vs_toolsets.back(); } else { - const auto& vs_toolsets = this->get_toolsets(); - - const auto toolset = Util::find_if(vs_toolsets, [&](const Toolset& toolset) { return toolset_version == Strings::to_utf8(toolset.version); }); - if(toolset == vs_toolsets.end()) - { - Checks::exit_with_message(VCPKG_LINE_INFO, Strings::format("Could not find toolset %s", toolset_version)); - } + const auto toolset = Util::find_if(vs_toolsets, [&](const Toolset& toolset) { + return toolset_version == Strings::to_utf8(toolset.version); + }); + Checks::check_exit( + VCPKG_LINE_INFO, toolset != vs_toolsets.end(), "Could not find toolset '%s'", toolset_version); return *toolset; } } -- cgit v1.2.3 From 264cd050e6280e5b87ec055e0a9d8985a7ba30b3 Mon Sep 17 00:00:00 2001 From: Daniel Shaw Date: Mon, 5 Jun 2017 15:58:47 -0700 Subject: ExpectedT factory class --- toolsrc/include/LineInfo.h | 2 + toolsrc/include/PackageSpec.h | 6 ++- toolsrc/include/PackageSpecParseResult.h | 31 ++++++------- toolsrc/include/Paragraphs.h | 3 +- toolsrc/include/SourceParagraph.h | 17 ++++++- toolsrc/include/vcpkg_expected.h | 79 ++++++++++++++++++++++++-------- toolsrc/src/PackageSpec.cpp | 10 ++-- toolsrc/src/PackageSpecParseResult.cpp | 24 +--------- toolsrc/src/Paragraphs.cpp | 23 ++++++---- toolsrc/src/SourceParagraph.cpp | 47 ++++++++++++++----- toolsrc/src/commands_build.cpp | 17 ++++--- toolsrc/src/tests_paragraph.cpp | 66 +++++++++++++++----------- toolsrc/src/vcpkg.cpp | 4 +- toolsrc/src/vcpkg_Dependencies.cpp | 10 +++- toolsrc/src/vcpkg_Files.cpp | 6 +-- toolsrc/src/vcpkg_Input.cpp | 4 +- 16 files changed, 221 insertions(+), 128 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/LineInfo.h b/toolsrc/include/LineInfo.h index 66d91c520..62973462a 100644 --- a/toolsrc/include/LineInfo.h +++ b/toolsrc/include/LineInfo.h @@ -1,5 +1,7 @@ #pragma once +#include + namespace vcpkg { struct LineInfo diff --git a/toolsrc/include/PackageSpec.h b/toolsrc/include/PackageSpec.h index 050d9d079..58edb8274 100644 --- a/toolsrc/include/PackageSpec.h +++ b/toolsrc/include/PackageSpec.h @@ -7,9 +7,11 @@ namespace vcpkg { struct PackageSpec { - static Expected from_string(const std::string& spec_as_string, const Triplet& default_triplet); + static ExpectedT from_string(const std::string& spec_as_string, + const Triplet& default_triplet); static std::string to_string(const std::string& name, const Triplet& triplet); - static Expected from_name_and_triplet(const std::string& name, const Triplet& triplet); + static ExpectedT from_name_and_triplet(const std::string& name, + const Triplet& triplet); const std::string& name() const; diff --git a/toolsrc/include/PackageSpecParseResult.h b/toolsrc/include/PackageSpecParseResult.h index b72c534c2..17d151626 100644 --- a/toolsrc/include/PackageSpecParseResult.h +++ b/toolsrc/include/PackageSpecParseResult.h @@ -1,5 +1,6 @@ #pragma once -#include + +#include "vcpkg_expected.h" namespace vcpkg { @@ -10,27 +11,21 @@ namespace vcpkg INVALID_CHARACTERS }; - struct PackageSpecParseResultCategoryImpl final : std::error_category - { - virtual const char* name() const noexcept override; + CStringView to_string(PackageSpecParseResult ev) noexcept; - virtual std::string message(int ev) const noexcept override; - }; - - const std::error_category& package_spec_parse_result_category(); + template<> + struct ErrorHolder + { + ErrorHolder() : m_err(PackageSpecParseResult::SUCCESS) {} + ErrorHolder(PackageSpecParseResult err) : m_err(err) {} - std::error_code make_error_code(PackageSpecParseResult e); + constexpr bool has_error() const { return m_err != PackageSpecParseResult::SUCCESS; } - PackageSpecParseResult to_package_spec_parse_result(int i); + PackageSpecParseResult error() const { return m_err; } - PackageSpecParseResult to_package_spec_parse_result(std::error_code ec); -} + CStringView to_string() const { return vcpkg::to_string(m_err); } -// Enable implicit conversion to std::error_code -namespace std -{ - template<> - struct is_error_code_enum : ::std::true_type - { + private: + PackageSpecParseResult m_err; }; } diff --git a/toolsrc/include/Paragraphs.h b/toolsrc/include/Paragraphs.h index 66f6bd2e4..59f0eefc8 100644 --- a/toolsrc/include/Paragraphs.h +++ b/toolsrc/include/Paragraphs.h @@ -16,7 +16,8 @@ namespace vcpkg::Paragraphs Expected parse_single_paragraph(const std::string& str); Expected> parse_paragraphs(const std::string& str); - Expected try_load_port(const Files::Filesystem& fs, const fs::path& control_path); + ExpectedT try_load_port(const Files::Filesystem& fs, + const fs::path& control_path); Expected try_load_cached_package(const VcpkgPaths& paths, const PackageSpec& spec); diff --git a/toolsrc/include/SourceParagraph.h b/toolsrc/include/SourceParagraph.h index 19f558170..9874eb3a9 100644 --- a/toolsrc/include/SourceParagraph.h +++ b/toolsrc/include/SourceParagraph.h @@ -1,5 +1,6 @@ #pragma once +#include "vcpkg_expected.h" #include #include @@ -15,14 +16,23 @@ namespace vcpkg const std::string& to_string(const Dependency& dep); + struct ParseControlErrorInfo + { + std::string name; + std::string remaining_fields_as_string; + std::string valid_fields_as_string; + std::error_code error; + }; + /// /// Port metadata (CONTROL file) /// struct SourceParagraph { - SourceParagraph(); + static ExpectedT parse_control_file( + std::unordered_map fields); - explicit SourceParagraph(std::unordered_map fields); + SourceParagraph(); std::string name; std::string version; @@ -31,6 +41,9 @@ namespace vcpkg std::vector depends; }; + void print_error_message(const ParseControlErrorInfo& info); + void print_error_message(std::vector error_info_list); + std::vector filter_dependencies(const std::vector& deps, const Triplet& t); std::vector expand_qualified_dependencies(const std::vector& depends); diff --git a/toolsrc/include/vcpkg_expected.h b/toolsrc/include/vcpkg_expected.h index 3a920022b..15dbf5e79 100644 --- a/toolsrc/include/vcpkg_expected.h +++ b/toolsrc/include/vcpkg_expected.h @@ -5,27 +5,63 @@ namespace vcpkg { - template - class Expected + template + struct ErrorHolder { - public: - // Constructors are intentionally implicit - Expected(const std::error_code& ec) : m_error_code(ec), m_t() {} + ErrorHolder() : m_is_error(false) {} + ErrorHolder(const Err& err) : m_is_error(true), m_err(err) {} + ErrorHolder(Err&& err) : m_is_error(true), m_err(std::move(err)) {} + + constexpr bool has_error() const { return m_is_error; } + + const Err& error() const { return m_err; } + Err& error() { return m_err; } + + CStringView to_string() const { return "value was error"; } + + private: + bool m_is_error; + Err m_err; + }; + + template<> + struct ErrorHolder + { + ErrorHolder() = default; + ErrorHolder(const std::error_code& err) : m_err(err) {} + + constexpr bool has_error() const { return bool(m_err); } - Expected(std::errc ec) : Expected(std::make_error_code(ec)) {} + const std::error_code& error() const { return m_err; } + std::error_code& error() { return m_err; } - Expected(const T& t) : m_error_code(), m_t(t) {} + CStringView to_string() const { return "value was error"; } - Expected(T&& t) : m_error_code(), m_t(std::move(t)) {} + private: + std::error_code m_err; + }; + + template + class ExpectedT + { + public: + constexpr ExpectedT() = default; + + // Constructors are intentionally implicit + + ExpectedT(const S& s) : m_s(s) {} + ExpectedT(S&& s) : m_s(std::move(s)) {} - Expected() : Expected(std::error_code(), T()) {} + ExpectedT(const T& t) : m_t(t) {} + ExpectedT(T&& t) : m_t(std::move(t)) {} - Expected(const Expected&) = default; - Expected(Expected&&) = default; - Expected& operator=(const Expected&) = default; - Expected& operator=(Expected&&) = default; + ExpectedT(const ExpectedT&) = default; + ExpectedT(ExpectedT&&) = default; + ExpectedT& operator=(const ExpectedT&) = default; + ExpectedT& operator=(ExpectedT&&) = default; - std::error_code error_code() const { return this->m_error_code; } + explicit constexpr operator bool() const noexcept { return !m_s.has_error(); } + constexpr bool has_value() const noexcept { return !m_s.has_error(); } T&& value_or_exit(const LineInfo& line_info) && { @@ -39,9 +75,13 @@ namespace vcpkg return this->m_t; } + const S& error() const & { return this->m_s.error(); } + + S&& error() && { return std::move(this->m_s.error()); } + const T* get() const { - if (m_error_code) + if (!this->has_value()) { return nullptr; } @@ -50,7 +90,7 @@ namespace vcpkg T* get() { - if (m_error_code) + if (!this->has_value()) { return nullptr; } @@ -60,10 +100,13 @@ namespace vcpkg private: void exit_if_error(const LineInfo& line_info) const { - Checks::check_exit(line_info, !this->m_error_code, this->m_error_code.message()); + Checks::check_exit(line_info, !m_s.has_error(), m_s.to_string()); } - std::error_code m_error_code; + ErrorHolder m_s; T m_t; }; + + template + using Expected = ExpectedT; } diff --git a/toolsrc/src/PackageSpec.cpp b/toolsrc/src/PackageSpec.cpp index 69883a030..ab005f255 100644 --- a/toolsrc/src/PackageSpec.cpp +++ b/toolsrc/src/PackageSpec.cpp @@ -7,7 +7,8 @@ namespace vcpkg { static bool is_valid_package_spec_char(char c) { return (c == '-') || isdigit(c) || (isalpha(c) && islower(c)); } - Expected PackageSpec::from_string(const std::string& spec_as_string, const Triplet& default_triplet) + ExpectedT PackageSpec::from_string(const std::string& spec_as_string, + const Triplet& default_triplet) { auto pos = spec_as_string.find(':'); if (pos == std::string::npos) @@ -18,7 +19,7 @@ namespace vcpkg auto pos2 = spec_as_string.find(':', pos + 1); if (pos2 != std::string::npos) { - return std::error_code(PackageSpecParseResult::TOO_MANY_COLONS); + return PackageSpecParseResult::TOO_MANY_COLONS; } const std::string name = spec_as_string.substr(0, pos); @@ -26,11 +27,12 @@ namespace vcpkg return from_name_and_triplet(name, triplet); } - Expected PackageSpec::from_name_and_triplet(const std::string& name, const Triplet& triplet) + ExpectedT PackageSpec::from_name_and_triplet(const std::string& name, + const Triplet& triplet) { if (Util::find_if_not(name, is_valid_package_spec_char) != name.end()) { - return std::error_code(PackageSpecParseResult::INVALID_CHARACTERS); + return PackageSpecParseResult::INVALID_CHARACTERS; } PackageSpec p; diff --git a/toolsrc/src/PackageSpecParseResult.cpp b/toolsrc/src/PackageSpecParseResult.cpp index 487c3aa1d..838c788ba 100644 --- a/toolsrc/src/PackageSpecParseResult.cpp +++ b/toolsrc/src/PackageSpecParseResult.cpp @@ -5,11 +5,9 @@ namespace vcpkg { - const char* PackageSpecParseResultCategoryImpl::name() const noexcept { return "PackageSpecParseResult"; } - - std::string PackageSpecParseResultCategoryImpl::message(int ev) const noexcept + CStringView to_string(PackageSpecParseResult ev) noexcept { - switch (static_cast(ev)) + switch (ev) { case PackageSpecParseResult::SUCCESS: return "OK"; case PackageSpecParseResult::TOO_MANY_COLONS: return "Too many colons"; @@ -19,22 +17,4 @@ namespace vcpkg default: Checks::unreachable(VCPKG_LINE_INFO); } } - - const std::error_category& package_spec_parse_result_category() - { - static PackageSpecParseResultCategoryImpl instance; - return instance; - } - - std::error_code make_error_code(PackageSpecParseResult e) - { - return std::error_code(static_cast(e), package_spec_parse_result_category()); - } - - PackageSpecParseResult to_package_spec_parse_result(int i) { return static_cast(i); } - - PackageSpecParseResult to_package_spec_parse_result(std::error_code ec) - { - return to_package_spec_parse_result(ec.value()); - } } diff --git a/toolsrc/src/Paragraphs.cpp b/toolsrc/src/Paragraphs.cpp index 70d3db2b3..13103d1f8 100644 --- a/toolsrc/src/Paragraphs.cpp +++ b/toolsrc/src/Paragraphs.cpp @@ -168,7 +168,7 @@ namespace vcpkg::Paragraphs return parse_single_paragraph(*spgh); } - return contents.error_code(); + return contents.error(); } Expected>> get_paragraphs(const Files::Filesystem& fs, @@ -180,7 +180,7 @@ namespace vcpkg::Paragraphs return parse_paragraphs(*spgh); } - return contents.error_code(); + return contents.error(); } Expected> parse_single_paragraph(const std::string& str) @@ -201,15 +201,16 @@ namespace vcpkg::Paragraphs return Parser(str.c_str(), str.c_str() + str.size()).get_paragraphs(); } - Expected try_load_port(const Files::Filesystem& fs, const fs::path& path) + ExpectedT try_load_port(const Files::Filesystem& fs, const fs::path& path) { + ParseControlErrorInfo error_info; Expected> pghs = get_single_paragraph(fs, path / "CONTROL"); if (auto p = pghs.get()) { - return SourceParagraph(*p); + return SourceParagraph::parse_control_file(*p); } - - return pghs.error_code(); + error_info.error = pghs.error(); + return error_info; } Expected try_load_cached_package(const VcpkgPaths& paths, const PackageSpec& spec) @@ -222,20 +223,26 @@ namespace vcpkg::Paragraphs return BinaryParagraph(*p); } - return pghs.error_code(); + return pghs.error(); } std::vector load_all_ports(const Files::Filesystem& fs, const fs::path& ports_dir) { std::vector output; + std::vector port_errors; for (auto&& path : fs.get_files_non_recursive(ports_dir)) { - Expected source_paragraph = try_load_port(fs, path); + ExpectedT source_paragraph = try_load_port(fs, path); if (auto srcpgh = source_paragraph.get()) { output.emplace_back(std::move(*srcpgh)); } + else + { + port_errors.emplace_back(source_paragraph.error()); + } } + print_error_message(port_errors); return output; } diff --git a/toolsrc/src/SourceParagraph.cpp b/toolsrc/src/SourceParagraph.cpp index d140ce72b..9516681c9 100644 --- a/toolsrc/src/SourceParagraph.cpp +++ b/toolsrc/src/SourceParagraph.cpp @@ -5,6 +5,8 @@ #include "vcpkg_Checks.h" #include "vcpkg_Maps.h" #include "vcpkg_System.h" +#include "vcpkg_expected.h" + #include "vcpkglib_helpers.h" namespace vcpkg @@ -37,15 +39,41 @@ namespace vcpkg SourceParagraph::SourceParagraph() = default; - SourceParagraph::SourceParagraph(std::unordered_map fields) + void print_error_message(const ParseControlErrorInfo& info) + { + System::println( + System::Color::error, "Error: There are invalid fields in the Source Paragraph of %s", info.name); + System::println("The following fields were not expected:\n\n %s\n\n", info.remaining_fields_as_string); + System::println("This is the list of valid fields (case-sensitive): \n\n %s\n", info.valid_fields_as_string); + System::println("Different source may be available for vcpkg. Use .\\bootstrap-vcpkg.bat to update.\n"); + } + + void print_error_message(std::vector error_info_list) + { + for (ParseControlErrorInfo error_info : error_info_list) + { + System::println( + System::Color::error, "Error: There are invalid fields in the Source Paragraph of %s", error_info.name); + System::println("The following fields were not expected:\n\n %s\n\n", + error_info.remaining_fields_as_string); + } + + System::println("This is the list of valid fields (case-sensitive): \n\n %s\n", + error_info_list.front().valid_fields_as_string); + System::println("Different source may be available for vcpkg. Use .\\bootstrap-vcpkg.bat to update.\n"); + } + + ExpectedT SourceParagraph::parse_control_file( + std::unordered_map fields) { - this->name = details::remove_required_field(&fields, SourceParagraphRequiredField::SOURCE); - this->version = details::remove_required_field(&fields, SourceParagraphRequiredField::VERSION); - this->description = details::remove_optional_field(&fields, SourceParagraphOptionalField::DESCRIPTION); - this->maintainer = details::remove_optional_field(&fields, SourceParagraphOptionalField::MAINTAINER); + SourceParagraph sparagraph; + sparagraph.name = details::remove_required_field(&fields, SourceParagraphRequiredField::SOURCE); + sparagraph.version = details::remove_required_field(&fields, SourceParagraphRequiredField::VERSION); + sparagraph.description = details::remove_optional_field(&fields, SourceParagraphOptionalField::DESCRIPTION); + sparagraph.maintainer = details::remove_optional_field(&fields, SourceParagraphOptionalField::MAINTAINER); std::string deps = details::remove_optional_field(&fields, SourceParagraphOptionalField::BUILD_DEPENDS); - this->depends = expand_qualified_dependencies(parse_depends(deps)); + sparagraph.depends = expand_qualified_dependencies(parse_depends(deps)); if (!fields.empty()) { @@ -55,12 +83,9 @@ namespace vcpkg const std::string remaining_fields_as_string = Strings::join("\n ", remaining_fields); const std::string valid_fields_as_string = Strings::join("\n ", valid_fields); - System::println( - System::Color::error, "Error: There are invalid fields in the Source Paragraph of %s", this->name); - System::println("The following fields were not expected:\n\n %s\n\n", remaining_fields_as_string); - System::println("This is the list of valid fields (case-sensitive): \n\n %s\n", valid_fields_as_string); - Checks::exit_fail(VCPKG_LINE_INFO); + return ParseControlErrorInfo{sparagraph.name, remaining_fields_as_string, valid_fields_as_string}; } + return sparagraph; } std::vector vcpkg::expand_qualified_dependencies(const std::vector& depends) diff --git a/toolsrc/src/commands_build.cpp b/toolsrc/src/commands_build.cpp index ec6586fa3..4a0cee021 100644 --- a/toolsrc/src/commands_build.cpp +++ b/toolsrc/src/commands_build.cpp @@ -33,13 +33,16 @@ namespace vcpkg::Commands::BuildCommand Checks::exit_success(VCPKG_LINE_INFO); } - const Expected 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 %s: %s", - spec, - maybe_spgh.error_code().message()); - const SourceParagraph& spgh = *maybe_spgh.get(); + const ExpectedT maybe_spgh = + Paragraphs::try_load_port(paths.get_filesystem(), port_dir); + // why do we add a const here + if (!maybe_spgh) + { + print_error_message(maybe_spgh.error()); + Checks::exit_fail(VCPKG_LINE_INFO); + } + + const SourceParagraph& spgh = maybe_spgh.value_or_exit(VCPKG_LINE_INFO); Checks::check_exit(VCPKG_LINE_INFO, spec.name() == spgh.name, "The Name: field inside the CONTROL does not match the port directory: '%s' != '%s'", diff --git a/toolsrc/src/tests_paragraph.cpp b/toolsrc/src/tests_paragraph.cpp index b66adc816..1c77b437b 100644 --- a/toolsrc/src/tests_paragraph.cpp +++ b/toolsrc/src/tests_paragraph.cpp @@ -25,7 +25,10 @@ namespace UnitTest1 { TEST_METHOD(SourceParagraph_Construct_Minimum) { - vcpkg::SourceParagraph pgh({{"Source", "zlib"}, {"Version", "1.2.8"}}); + auto m_pgh = vcpkg::SourceParagraph::parse_control_file({{"Source", "zlib"}, {"Version", "1.2.8"}}); + + Assert::IsTrue(m_pgh.has_value()); + auto& pgh = *m_pgh.get(); Assert::AreEqual("zlib", pgh.name.c_str()); Assert::AreEqual("1.2.8", pgh.version.c_str()); @@ -36,11 +39,12 @@ namespace UnitTest1 TEST_METHOD(SourceParagraph_Construct_Maximum) { - vcpkg::SourceParagraph pgh({{"Source", "s"}, - {"Version", "v"}, - {"Maintainer", "m"}, - {"Description", "d"}, - {"Build-Depends", "bd"}}); + auto m_pgh = vcpkg::SourceParagraph::parse_control_file({ + {"Source", "s"}, {"Version", "v"}, {"Maintainer", "m"}, {"Description", "d"}, {"Build-Depends", "bd"}, + }); + Assert::IsTrue(m_pgh.has_value()); + auto& pgh = *m_pgh.get(); + Assert::AreEqual("s", pgh.name.c_str()); Assert::AreEqual("v", pgh.version.c_str()); Assert::AreEqual("m", pgh.maintainer.c_str()); @@ -51,7 +55,11 @@ namespace UnitTest1 TEST_METHOD(SourceParagraph_Two_Depends) { - vcpkg::SourceParagraph pgh({{"Source", "zlib"}, {"Version", "1.2.8"}, {"Build-Depends", "z, openssl"}}); + auto m_pgh = vcpkg::SourceParagraph::parse_control_file({ + {"Source", "zlib"}, {"Version", "1.2.8"}, {"Build-Depends", "z, openssl"}, + }); + Assert::IsTrue(m_pgh.has_value()); + auto& pgh = *m_pgh.get(); Assert::AreEqual(size_t(2), pgh.depends.size()); Assert::AreEqual("z", pgh.depends[0].name.c_str()); @@ -60,8 +68,11 @@ namespace UnitTest1 TEST_METHOD(SourceParagraph_Three_Depends) { - vcpkg::SourceParagraph pgh( - {{"Source", "zlib"}, {"Version", "1.2.8"}, {"Build-Depends", "z, openssl, xyz"}}); + auto m_pgh = vcpkg::SourceParagraph::parse_control_file({ + {"Source", "zlib"}, {"Version", "1.2.8"}, {"Build-Depends", "z, openssl, xyz"}, + }); + Assert::IsTrue(m_pgh.has_value()); + auto& pgh = *m_pgh.get(); Assert::AreEqual(size_t(3), pgh.depends.size()); Assert::AreEqual("z", pgh.depends[0].name.c_str()); @@ -71,8 +82,11 @@ namespace UnitTest1 TEST_METHOD(SourceParagraph_Construct_Qualified_Depends) { - vcpkg::SourceParagraph pgh( - {{"Source", "zlib"}, {"Version", "1.2.8"}, {"Build-Depends", "libA [windows], libB [uwp]"}}); + auto m_pgh = vcpkg::SourceParagraph::parse_control_file({ + {"Source", "zlib"}, {"Version", "1.2.8"}, {"Build-Depends", "libA [windows], libB [uwp]"}, + }); + Assert::IsTrue(m_pgh.has_value()); + auto& pgh = *m_pgh.get(); Assert::AreEqual("zlib", pgh.name.c_str()); Assert::AreEqual("1.2.8", pgh.version.c_str()); @@ -101,13 +115,15 @@ namespace UnitTest1 TEST_METHOD(BinaryParagraph_Construct_Maximum) { - vcpkg::BinaryParagraph pgh({{"Package", "s"}, - {"Version", "v"}, - {"Architecture", "x86-windows"}, - {"Multi-Arch", "same"}, - {"Maintainer", "m"}, - {"Description", "d"}, - {"Depends", "bd"}}); + vcpkg::BinaryParagraph pgh({ + {"Package", "s"}, + {"Version", "v"}, + {"Architecture", "x86-windows"}, + {"Multi-Arch", "same"}, + {"Maintainer", "m"}, + {"Description", "d"}, + {"Depends", "bd"}, + }); Assert::AreEqual("s", pgh.spec.name().c_str()); Assert::AreEqual("v", pgh.version.c_str()); Assert::AreEqual("m", pgh.maintainer.c_str()); @@ -327,28 +343,26 @@ namespace UnitTest1 TEST_METHOD(package_spec_parse) { - vcpkg::Expected spec = + vcpkg::ExpectedT spec = vcpkg::PackageSpec::from_string("zlib", vcpkg::Triplet::X86_WINDOWS); - Assert::AreEqual(vcpkg::PackageSpecParseResult::SUCCESS, - vcpkg::to_package_spec_parse_result(spec.error_code())); + Assert::AreEqual(vcpkg::PackageSpecParseResult::SUCCESS, spec.error()); Assert::AreEqual("zlib", spec.get()->name().c_str()); Assert::AreEqual(vcpkg::Triplet::X86_WINDOWS.canonical_name(), spec.get()->triplet().canonical_name()); } TEST_METHOD(package_spec_parse_with_arch) { - vcpkg::Expected spec = + vcpkg::ExpectedT spec = vcpkg::PackageSpec::from_string("zlib:x64-uwp", vcpkg::Triplet::X86_WINDOWS); - Assert::AreEqual(vcpkg::PackageSpecParseResult::SUCCESS, - vcpkg::to_package_spec_parse_result(spec.error_code())); + Assert::AreEqual(vcpkg::PackageSpecParseResult::SUCCESS, spec.error()); Assert::AreEqual("zlib", spec.get()->name().c_str()); Assert::AreEqual(vcpkg::Triplet::X64_UWP.canonical_name(), spec.get()->triplet().canonical_name()); } TEST_METHOD(package_spec_parse_with_multiple_colon) { - auto ec = vcpkg::PackageSpec::from_string("zlib:x86-uwp:", vcpkg::Triplet::X86_WINDOWS).error_code(); - Assert::AreEqual(vcpkg::PackageSpecParseResult::TOO_MANY_COLONS, vcpkg::to_package_spec_parse_result(ec)); + auto ec = vcpkg::PackageSpec::from_string("zlib:x86-uwp:", vcpkg::Triplet::X86_WINDOWS).error(); + Assert::AreEqual(vcpkg::PackageSpecParseResult::TOO_MANY_COLONS, ec); } TEST_METHOD(utf8_to_utf16) diff --git a/toolsrc/src/vcpkg.cpp b/toolsrc/src/vcpkg.cpp index 154aefd0a..738b7b284 100644 --- a/toolsrc/src/vcpkg.cpp +++ b/toolsrc/src/vcpkg.cpp @@ -61,10 +61,10 @@ static void inner(const VcpkgCmdArguments& args) const Expected expected_paths = VcpkgPaths::create(vcpkg_root_dir); Checks::check_exit(VCPKG_LINE_INFO, - !expected_paths.error_code(), + !expected_paths.error(), "Error: Invalid vcpkg root directory %s: %s", vcpkg_root_dir.string(), - expected_paths.error_code().message()); + expected_paths.error().message()); const VcpkgPaths paths = expected_paths.value_or_exit(VCPKG_LINE_INFO); int exit_code = _wchdir(paths.root.c_str()); Checks::check_exit(VCPKG_LINE_INFO, exit_code == 0, "Changing the working dir failed"); diff --git a/toolsrc/src/vcpkg_Dependencies.cpp b/toolsrc/src/vcpkg_Dependencies.cpp index acfb55239..ea5832e46 100644 --- a/toolsrc/src/vcpkg_Dependencies.cpp +++ b/toolsrc/src/vcpkg_Dependencies.cpp @@ -174,11 +174,14 @@ namespace vcpkg::Dependencies if (auto bpgh = maybe_bpgh.get()) return InstallPlanAction{spec, {nullopt, *bpgh, nullopt}, request_type}; - Expected maybe_spgh = + ExpectedT 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}; + else + print_error_message(maybe_spgh.error()); + Checks::exit_with_message(VCPKG_LINE_INFO, "Could not find package %s", spec); } }; @@ -283,11 +286,14 @@ namespace vcpkg::Dependencies if (auto bpgh = maybe_bpgh.get()) return ExportPlanAction{spec, {nullopt, *bpgh, nullopt}, request_type}; - Expected maybe_spgh = + ExpectedT maybe_spgh = Paragraphs::try_load_port(paths.get_filesystem(), paths.port_dir(spec)); if (auto spgh = maybe_spgh.get()) return ExportPlanAction{spec, {nullopt, nullopt, *spgh}, request_type}; + else + print_error_message(maybe_spgh.error()); + Checks::exit_with_message(VCPKG_LINE_INFO, "Could not find package %s", spec); } }; diff --git a/toolsrc/src/vcpkg_Files.cpp b/toolsrc/src/vcpkg_Files.cpp index 17aa2997a..7b12ea699 100644 --- a/toolsrc/src/vcpkg_Files.cpp +++ b/toolsrc/src/vcpkg_Files.cpp @@ -15,7 +15,7 @@ namespace vcpkg::Files 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 std::make_error_code(std::errc::no_such_file_or_directory); } file_stream.seekg(0, file_stream.end); @@ -24,7 +24,7 @@ namespace vcpkg::Files if (length > SIZE_MAX) { - return std::errc::file_too_large; + return std::make_error_code(std::errc::file_too_large); } std::string output; @@ -39,7 +39,7 @@ namespace vcpkg::Files 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 std::make_error_code(std::errc::no_such_file_or_directory); } std::vector output; diff --git a/toolsrc/src/vcpkg_Input.cpp b/toolsrc/src/vcpkg_Input.cpp index 7d8e4767e..df738315b 100644 --- a/toolsrc/src/vcpkg_Input.cpp +++ b/toolsrc/src/vcpkg_Input.cpp @@ -12,14 +12,14 @@ namespace vcpkg::Input CStringView example_text) { const std::string as_lowercase = Strings::ascii_to_lowercase(package_spec_as_string); - Expected expected_spec = PackageSpec::from_string(as_lowercase, default_triplet); + auto expected_spec = PackageSpec::from_string(as_lowercase, default_triplet); if (auto spec = expected_spec.get()) { return *spec; } // Intentionally show the lowercased string - System::println(System::Color::error, "Error: %s: %s", expected_spec.error_code().message(), as_lowercase); + System::println(System::Color::error, "Error: %s: %s", vcpkg::to_string(expected_spec.error()), as_lowercase); System::print(example_text); Checks::exit_fail(VCPKG_LINE_INFO); } -- cgit v1.2.3 From fcf0f331c67a39a758d55c5c841cb81b2dd49289 Mon Sep 17 00:00:00 2001 From: Daniel Shaw Date: Mon, 5 Jun 2017 16:25:04 -0700 Subject: error message vector check --- toolsrc/src/SourceParagraph.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'toolsrc') diff --git a/toolsrc/src/SourceParagraph.cpp b/toolsrc/src/SourceParagraph.cpp index 9516681c9..8a131ef6a 100644 --- a/toolsrc/src/SourceParagraph.cpp +++ b/toolsrc/src/SourceParagraph.cpp @@ -50,6 +50,7 @@ namespace vcpkg void print_error_message(std::vector error_info_list) { + if (error_info_list.size() == 0) return; for (ParseControlErrorInfo error_info : error_info_list) { System::println( -- cgit v1.2.3 From 6c09b1dd240cc295c6b123ce3597ae612e872e2d Mon Sep 17 00:00:00 2001 From: Daniel Shaw Date: Mon, 5 Jun 2017 16:57:35 -0700 Subject: PackageSpecParseResult const ref bug --- toolsrc/include/PackageSpecParseResult.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/include/PackageSpecParseResult.h b/toolsrc/include/PackageSpecParseResult.h index 17d151626..1462b8073 100644 --- a/toolsrc/include/PackageSpecParseResult.h +++ b/toolsrc/include/PackageSpecParseResult.h @@ -21,7 +21,8 @@ namespace vcpkg constexpr bool has_error() const { return m_err != PackageSpecParseResult::SUCCESS; } - PackageSpecParseResult error() const { return m_err; } + const PackageSpecParseResult& error() const { return m_err; } + PackageSpecParseResult& error() { return m_err; } CStringView to_string() const { return vcpkg::to_string(m_err); } -- cgit v1.2.3 From cc443d1c6b10735f9e4e5d439432124ffcfb376f Mon Sep 17 00:00:00 2001 From: Daniel Shaw Date: Mon, 5 Jun 2017 17:55:06 -0700 Subject: minor changes --- toolsrc/include/SourceParagraph.h | 2 +- toolsrc/src/SourceParagraph.cpp | 2 -- toolsrc/src/commands_build.cpp | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/SourceParagraph.h b/toolsrc/include/SourceParagraph.h index 9874eb3a9..7b0fa3178 100644 --- a/toolsrc/include/SourceParagraph.h +++ b/toolsrc/include/SourceParagraph.h @@ -32,7 +32,7 @@ namespace vcpkg static ExpectedT parse_control_file( std::unordered_map fields); - SourceParagraph(); + SourceParagraph() = default; std::string name; std::string version; diff --git a/toolsrc/src/SourceParagraph.cpp b/toolsrc/src/SourceParagraph.cpp index 8a131ef6a..c77659176 100644 --- a/toolsrc/src/SourceParagraph.cpp +++ b/toolsrc/src/SourceParagraph.cpp @@ -37,8 +37,6 @@ namespace vcpkg return valid_fields; } - SourceParagraph::SourceParagraph() = default; - void print_error_message(const ParseControlErrorInfo& info) { System::println( diff --git a/toolsrc/src/commands_build.cpp b/toolsrc/src/commands_build.cpp index 4a0cee021..294b70b27 100644 --- a/toolsrc/src/commands_build.cpp +++ b/toolsrc/src/commands_build.cpp @@ -35,7 +35,7 @@ namespace vcpkg::Commands::BuildCommand const ExpectedT maybe_spgh = Paragraphs::try_load_port(paths.get_filesystem(), port_dir); - // why do we add a const here + if (!maybe_spgh) { print_error_message(maybe_spgh.error()); -- cgit v1.2.3 From 69d5f50ce433750c422446b64b0a45b6b4ea738a Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 22 May 2017 20:18:40 -0700 Subject: Install continue --- toolsrc/include/vcpkg_Build.h | 43 ++++++++++-- toolsrc/include/vcpkg_Commands.h | 7 ++ toolsrc/src/commands_build.cpp | 5 +- toolsrc/src/commands_ci.cpp | 55 ++------------- toolsrc/src/commands_install.cpp | 147 ++++++++++++++++++++------------------- toolsrc/src/vcpkg_Build.cpp | 22 +++--- 6 files changed, 141 insertions(+), 138 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg_Build.h b/toolsrc/include/vcpkg_Build.h index e0a5ae1ce..bce1eeb3e 100644 --- a/toolsrc/include/vcpkg_Build.h +++ b/toolsrc/include/vcpkg_Build.h @@ -14,6 +14,38 @@ namespace vcpkg::Build { + enum class UseHeadVersion + { + NO = 0, + YES + }; + + inline UseHeadVersion to_use_head_version(const bool value) + { + return value ? UseHeadVersion::YES : UseHeadVersion::NO; + } + + inline bool to_bool(const UseHeadVersion value) { return value == UseHeadVersion::YES; } + + enum class AllowDownloads + { + NO = 0, + YES + }; + + inline AllowDownloads to_allow_downloads(const bool value) + { + return value ? AllowDownloads::YES : AllowDownloads::NO; + } + + inline bool to_bool(const AllowDownloads value) { return value == AllowDownloads::YES; } + + struct BuildPackageOptions + { + UseHeadVersion use_head_version; + AllowDownloads allow_downloads; + }; + enum class BuildResult { NULLVALUE = 0, @@ -59,17 +91,18 @@ namespace vcpkg::Build struct BuildPackageConfig { - BuildPackageConfig(const SourceParagraph& src, const Triplet& triplet, fs::path&& port_dir) - : src(src), triplet(triplet), port_dir(std::move(port_dir)), use_head_version(false), no_downloads(false) + BuildPackageConfig(const SourceParagraph& src, + const Triplet& triplet, + fs::path&& port_dir, + const BuildPackageOptions& build_package_options) + : src(src), triplet(triplet), port_dir(std::move(port_dir)), build_package_options(build_package_options) { } const SourceParagraph& src; const Triplet& triplet; fs::path port_dir; - - bool use_head_version; - bool no_downloads; + const BuildPackageOptions& build_package_options; }; ExtendedBuildResult build_package(const VcpkgPaths& paths, diff --git a/toolsrc/include/vcpkg_Commands.h b/toolsrc/include/vcpkg_Commands.h index 14d468352..006971e47 100644 --- a/toolsrc/include/vcpkg_Commands.h +++ b/toolsrc/include/vcpkg_Commands.h @@ -4,6 +4,8 @@ #include "VcpkgCmdArguments.h" #include "VcpkgPaths.h" #include "VersionT.h" +#include "vcpkg_Build.h" +#include "vcpkg_Dependencies.h" #include namespace vcpkg::Commands @@ -48,6 +50,11 @@ namespace vcpkg::Commands const fs::path& listfile() const; }; + Build::BuildResult perform_install_plan_action(const VcpkgPaths& paths, + const Dependencies::InstallPlanAction& action, + const Build::BuildPackageOptions& install_plan_options, + StatusParagraphs& status_db); + void install_files_and_write_listfile(Files::Filesystem& fs, const fs::path& source_dir, const InstallDir& dirs); diff --git a/toolsrc/src/commands_build.cpp b/toolsrc/src/commands_build.cpp index 294b70b27..5a5cd462e 100644 --- a/toolsrc/src/commands_build.cpp +++ b/toolsrc/src/commands_build.cpp @@ -50,9 +50,8 @@ namespace vcpkg::Commands::BuildCommand spec.name()); StatusParagraphs status_db = database_load_check(paths); - const Build::BuildPackageConfig build_config{ - spgh, spec.triplet(), paths.port_dir(spec), - }; + Build::BuildPackageOptions build_package_options{Build::UseHeadVersion::NO, Build::AllowDownloads::YES}; + const Build::BuildPackageConfig build_config{spgh, spec.triplet(), paths.port_dir(spec), build_package_options}; const auto result = Build::build_package(paths, build_config, status_db); if (result.code == BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES) { diff --git a/toolsrc/src/commands_ci.cpp b/toolsrc/src/commands_ci.cpp index e9755335c..bad1286f0 100644 --- a/toolsrc/src/commands_ci.cpp +++ b/toolsrc/src/commands_ci.cpp @@ -50,6 +50,8 @@ namespace vcpkg::Commands::CI const ElapsedTime timer = ElapsedTime::create_started(); size_t counter = 0; const size_t package_count = install_plan.size(); + const Build::BuildPackageOptions install_plan_options = {Build::UseHeadVersion::NO, Build::AllowDownloads::YES}; + for (const InstallPlanAction& action : install_plan) { const ElapsedTime build_timer = ElapsedTime::create_started(); @@ -60,55 +62,10 @@ namespace vcpkg::Commands::CI timing.push_back("0"); results.push_back(BuildResult::NULLVALUE); - try - { - switch (action.plan_type) - { - case InstallPlanType::ALREADY_INSTALLED: - results.back() = BuildResult::SUCCEEDED; - System::println(System::Color::success, "Package %s is already installed", display_name); - break; - case InstallPlanType::BUILD_AND_INSTALL: - { - System::println("Building package %s... ", display_name); - auto&& source_paragraph = action.any_paragraph.source_paragraph.value_or_exit(VCPKG_LINE_INFO); - const Build::BuildPackageConfig build_config{ - source_paragraph, action.spec.triplet(), paths.port_dir(action.spec), - }; - const auto result_ex = Build::build_package(paths, build_config, status_db); - const auto result = result_ex.code; - - timing.back() = build_timer.to_string(); - results.back() = result; - if (result != BuildResult::SUCCEEDED) - { - System::println(System::Color::error, Build::create_error_message(result, action.spec)); - continue; - } - System::println(System::Color::success, "Building package %s... done", display_name); - - const BinaryParagraph bpgh = - Paragraphs::try_load_cached_package(paths, action.spec).value_or_exit(VCPKG_LINE_INFO); - System::println("Installing package %s... ", display_name); - Install::install_package(paths, bpgh, &status_db); - System::println(System::Color::success, "Installing package %s... done", display_name); - break; - } - case InstallPlanType::INSTALL: - results.back() = BuildResult::SUCCEEDED; - System::println("Installing package %s... ", display_name); - Install::install_package( - paths, action.any_paragraph.binary_paragraph.value_or_exit(VCPKG_LINE_INFO), &status_db); - System::println(System::Color::success, "Installing package %s... done", display_name); - break; - default: Checks::unreachable(VCPKG_LINE_INFO); - } - } - catch (const std::exception& e) - { - System::println(System::Color::error, "Error: Could not install package %s: %s", action.spec, e.what()); - results.back() = BuildResult::NULLVALUE; - } + const BuildResult result = + Install::perform_install_plan_action(paths, action, install_plan_options, status_db); + timing.back() = build_timer.to_string(); + results.back() = result; System::println("Elapsed time for package %s: %s", action.spec, build_timer.to_string()); } diff --git a/toolsrc/src/commands_install.cpp b/toolsrc/src/commands_install.cpp index bebe6a3a2..73b3e9eab 100644 --- a/toolsrc/src/commands_install.cpp +++ b/toolsrc/src/commands_install.cpp @@ -263,6 +263,77 @@ namespace vcpkg::Commands::Install status_db->insert(std::make_unique(source_paragraph)); } + using Build::BuildResult; + + BuildResult perform_install_plan_action(const VcpkgPaths& paths, + const InstallPlanAction& action, + const Build::BuildPackageOptions& build_package_options, + StatusParagraphs& status_db) + { + const InstallPlanType& plan_type = action.plan_type; + const std::string display_name = action.spec.to_string(); + + const bool is_user_requested = action.request_type == RequestType::USER_REQUESTED; + const bool use_head_version = to_bool(build_package_options.use_head_version); + + if (plan_type == InstallPlanType::ALREADY_INSTALLED) + { + if (use_head_version && is_user_requested) + { + System::println( + System::Color::warning, "Package %s is already installed -- not building from HEAD", display_name); + } + else + { + System::println(System::Color::success, "Package %s is already installed", display_name); + } + return BuildResult::SUCCEEDED; + } + + if (plan_type == InstallPlanType::BUILD_AND_INSTALL) + { + if (use_head_version) + System::println("Building package %s from HEAD... ", display_name); + else + System::println("Building package %s... ", display_name); + + const Build::BuildPackageConfig build_config{ + action.any_paragraph.source_paragraph.value_or_exit(VCPKG_LINE_INFO), + action.spec.triplet(), + paths.port_dir(action.spec), + build_package_options}; + const auto result = Build::build_package(paths, build_config, status_db); + if (result.code != Build::BuildResult::SUCCEEDED) + { + System::println(System::Color::error, Build::create_error_message(result.code, action.spec)); + return result.code; + } + System::println("Building package %s... done", display_name); + + const BinaryParagraph bpgh = + Paragraphs::try_load_cached_package(paths, action.spec).value_or_exit(VCPKG_LINE_INFO); + System::println("Installing package %s... ", display_name); + install_package(paths, bpgh, &status_db); + System::println(System::Color::success, "Installing package %s... done", display_name); + return BuildResult::SUCCEEDED; + } + + if (plan_type == InstallPlanType::INSTALL) + { + if (use_head_version && is_user_requested) + { + System::println( + System::Color::warning, "Package %s is already built -- not building from HEAD", display_name); + } + System::println("Installing package %s... ", display_name); + install_package(paths, action.any_paragraph.binary_paragraph.value_or_exit(VCPKG_LINE_INFO), &status_db); + System::println(System::Color::success, "Installing package %s... done", display_name); + return BuildResult::SUCCEEDED; + } + + Checks::unreachable(VCPKG_LINE_INFO); + } + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) { static const std::string OPTION_DRY_RUN = "--dry-run"; @@ -315,80 +386,16 @@ namespace vcpkg::Commands::Install Checks::exit_success(VCPKG_LINE_INFO); } + const Build::BuildPackageOptions install_plan_options = {Build::to_use_head_version(use_head_version), + Build::to_allow_downloads(!no_downloads)}; + // execute the plan for (const InstallPlanAction& action : install_plan) { - const std::string display_name = action.spec.to_string(); - - try - { - switch (action.plan_type) - { - case InstallPlanType::ALREADY_INSTALLED: - if (use_head_version && action.request_type == RequestType::USER_REQUESTED) - { - System::println(System::Color::warning, - "Package %s is already installed -- not building from HEAD", - display_name); - } - else - { - System::println(System::Color::success, "Package %s is already installed", display_name); - } - break; - case InstallPlanType::BUILD_AND_INSTALL: - { - Build::BuildPackageConfig build_config{ - action.any_paragraph.source_paragraph.value_or_exit(VCPKG_LINE_INFO), - action.spec.triplet(), - paths.port_dir(action.spec), - }; - - build_config.use_head_version = - use_head_version && action.request_type == RequestType::USER_REQUESTED; - build_config.no_downloads = no_downloads; - - if (build_config.use_head_version) - System::println("Building package %s from HEAD... ", display_name); - else - System::println("Building package %s... ", display_name); - - const auto result = Build::build_package(paths, build_config, status_db); - if (result.code != Build::BuildResult::SUCCEEDED) - { - System::println(System::Color::error, - Build::create_error_message(result.code, action.spec)); - System::println(Build::create_user_troubleshooting_message(action.spec)); - Checks::exit_fail(VCPKG_LINE_INFO); - } - System::println("Building package %s... done", display_name); - - const BinaryParagraph bpgh = - Paragraphs::try_load_cached_package(paths, action.spec).value_or_exit(VCPKG_LINE_INFO); - System::println("Installing package %s... ", display_name); - install_package(paths, bpgh, &status_db); - System::println(System::Color::success, "Installing package %s... done", display_name); - break; - } - case InstallPlanType::INSTALL: - if (use_head_version && action.request_type == RequestType::USER_REQUESTED) - { - System::println(System::Color::warning, - "Package %s is already built -- not building from HEAD", - display_name); - } - System::println("Installing package %s... ", display_name); - install_package( - paths, action.any_paragraph.binary_paragraph.value_or_exit(VCPKG_LINE_INFO), &status_db); - System::println(System::Color::success, "Installing package %s... done", display_name); - break; - case InstallPlanType::UNKNOWN: - default: Checks::unreachable(VCPKG_LINE_INFO); - } - } - catch (const std::exception& e) + const BuildResult result = perform_install_plan_action(paths, action, install_plan_options, status_db); + if (result != BuildResult::SUCCEEDED) { - System::println(System::Color::error, "Error: Could not install package %s: %s", action.spec, e.what()); + System::println(Build::create_user_troubleshooting_message(action.spec)); Checks::exit_fail(VCPKG_LINE_INFO); } } diff --git a/toolsrc/src/vcpkg_Build.cpp b/toolsrc/src/vcpkg_Build.cpp index 817febe2f..91e4552ec 100644 --- a/toolsrc/src/vcpkg_Build.cpp +++ b/toolsrc/src/vcpkg_Build.cpp @@ -132,17 +132,17 @@ namespace vcpkg::Build const Toolset& toolset = paths.get_toolset(pre_build_info.platform_toolset); const auto cmd_set_environment = make_build_env_cmd(pre_build_info, toolset); - const std::wstring cmd_launch_cmake = - make_cmake_cmd(cmake_exe_path, - ports_cmake_script_path, - {{L"CMD", L"BUILD"}, - {L"PORT", config.src.name}, - {L"CURRENT_PORT_DIR", config.port_dir / "/."}, - {L"TARGET_TRIPLET", triplet.canonical_name()}, - {L"VCPKG_PLATFORM_TOOLSET", toolset.version}, - {L"VCPKG_USE_HEAD_VERSION", config.use_head_version ? L"1" : L"0"}, - {L"_VCPKG_NO_DOWNLOADS", config.no_downloads ? L"1" : L"0"}, - {L"GIT", git_exe_path}}); + const std::wstring cmd_launch_cmake = make_cmake_cmd( + cmake_exe_path, + ports_cmake_script_path, + {{L"CMD", L"BUILD"}, + {L"PORT", config.src.name}, + {L"CURRENT_PORT_DIR", config.port_dir / "/."}, + {L"TARGET_TRIPLET", triplet.canonical_name()}, + {L"VCPKG_PLATFORM_TOOLSET", toolset.version}, + {L"VCPKG_USE_HEAD_VERSION", to_bool(config.build_package_options.use_head_version) ? L"1" : L"0"}, + {L"_VCPKG_NO_DOWNLOADS", !to_bool(config.build_package_options.allow_downloads) ? L"1" : L"0"}, + {L"GIT", git_exe_path}}); const std::wstring command = Strings::wformat(LR"(%s && %s)", cmd_set_environment, cmd_launch_cmake); -- cgit v1.2.3 From a8edf0710cd8a52abd8b88ff0ebe159621c3b206 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 6 Jun 2017 15:50:44 -0700 Subject: Add missing #include --- toolsrc/include/PostBuildLint_LinkageType.h | 1 + 1 file changed, 1 insertion(+) (limited to 'toolsrc') diff --git a/toolsrc/include/PostBuildLint_LinkageType.h b/toolsrc/include/PostBuildLint_LinkageType.h index 8d19dc5a4..383cd0ffb 100644 --- a/toolsrc/include/PostBuildLint_LinkageType.h +++ b/toolsrc/include/PostBuildLint_LinkageType.h @@ -1,6 +1,7 @@ #pragma once #include "CStringView.h" #include +#include namespace vcpkg::PostBuildLint { -- cgit v1.2.3 From 831f0631f7eea7aebad5fcce95c0bbf0e0cdff68 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Tue, 6 Jun 2017 16:08:36 -0700 Subject: [vcpkg] Added parser support for 'Supports' field --- toolsrc/include/SourceParagraph.h | 37 +++++++++++++++++- toolsrc/include/vcpkg_Util.h | 6 +++ toolsrc/src/BinaryParagraph.cpp | 2 +- toolsrc/src/SourceParagraph.cpp | 80 +++++++++++++++++++++++++++++--------- toolsrc/src/tests_dependencies.cpp | 65 ++++++++++++++++++++++++++++++- toolsrc/src/tests_paragraph.cpp | 23 ++++++++++- 6 files changed, 189 insertions(+), 24 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/SourceParagraph.h b/toolsrc/include/SourceParagraph.h index 7b0fa3178..a53158f3f 100644 --- a/toolsrc/include/SourceParagraph.h +++ b/toolsrc/include/SourceParagraph.h @@ -1,6 +1,9 @@ #pragma once +#include "vcpkg_System.h" #include "vcpkg_expected.h" + +#include #include #include @@ -38,6 +41,7 @@ namespace vcpkg std::string version; std::string description; std::string maintainer; + std::vector supports; std::vector depends; }; @@ -47,5 +51,36 @@ namespace vcpkg std::vector filter_dependencies(const std::vector& deps, const Triplet& t); std::vector expand_qualified_dependencies(const std::vector& depends); - std::vector parse_depends(const std::string& depends_string); + std::vector parse_comma_list(const std::string& str); + + struct Supports + { + static ExpectedT> parse(const std::vector& strs); + + using Architecture = System::CPUArchitecture; + + enum class Platform + { + WINDOWS, + UWP, + }; + enum class Linkage + { + DYNAMIC, + STATIC, + }; + enum class ToolsetVersion + { + V140, + V141, + }; + + bool supports(Architecture arch, Platform plat, Linkage crt, ToolsetVersion tools); + + private: + std::vector architectures; + std::vector platforms; + std::vector crt_linkages; + std::vector toolsets; + }; } diff --git a/toolsrc/include/vcpkg_Util.h b/toolsrc/include/vcpkg_Util.h index 6648302ac..1bd1bcc4a 100644 --- a/toolsrc/include/vcpkg_Util.h +++ b/toolsrc/include/vcpkg_Util.h @@ -34,6 +34,12 @@ namespace vcpkg::Util cont.erase(std::remove_if(cont.begin(), cont.end(), pred), cont.end()); } + template + auto find(const Container& cont, V&& v) + { + return std::find(cont.cbegin(), cont.cend(), v); + } + template auto find_if(const Container& cont, Pred pred) { diff --git a/toolsrc/src/BinaryParagraph.cpp b/toolsrc/src/BinaryParagraph.cpp index d545eee2a..21980cd7d 100644 --- a/toolsrc/src/BinaryParagraph.cpp +++ b/toolsrc/src/BinaryParagraph.cpp @@ -42,7 +42,7 @@ namespace vcpkg Checks::check_exit(VCPKG_LINE_INFO, multi_arch == "same", "Multi-Arch must be 'same' but was %s", multi_arch); std::string deps = details::remove_optional_field(&fields, BinaryParagraphOptionalField::DEPENDS); - this->depends = parse_depends(deps); + this->depends = parse_comma_list(deps); } BinaryParagraph::BinaryParagraph(const SourceParagraph& spgh, const Triplet& triplet) diff --git a/toolsrc/src/SourceParagraph.cpp b/toolsrc/src/SourceParagraph.cpp index c77659176..2508af1e8 100644 --- a/toolsrc/src/SourceParagraph.cpp +++ b/toolsrc/src/SourceParagraph.cpp @@ -5,6 +5,7 @@ #include "vcpkg_Checks.h" #include "vcpkg_Maps.h" #include "vcpkg_System.h" +#include "vcpkg_Util.h" #include "vcpkg_expected.h" #include "vcpkglib_helpers.h" @@ -23,6 +24,7 @@ namespace vcpkg static const std::string DESCRIPTION = "Description"; static const std::string MAINTAINER = "Maintainer"; static const std::string BUILD_DEPENDS = "Build-Depends"; + static const std::string SUPPORTS = "Supports"; } static const std::vector& get_list_of_valid_fields() @@ -32,7 +34,8 @@ namespace vcpkg SourceParagraphOptionalField::DESCRIPTION, SourceParagraphOptionalField::MAINTAINER, - SourceParagraphOptionalField::BUILD_DEPENDS}; + SourceParagraphOptionalField::BUILD_DEPENDS, + SourceParagraphOptionalField::SUPPORTS}; return valid_fields; } @@ -72,7 +75,10 @@ namespace vcpkg sparagraph.maintainer = details::remove_optional_field(&fields, SourceParagraphOptionalField::MAINTAINER); std::string deps = details::remove_optional_field(&fields, SourceParagraphOptionalField::BUILD_DEPENDS); - sparagraph.depends = expand_qualified_dependencies(parse_depends(deps)); + sparagraph.depends = expand_qualified_dependencies(parse_comma_list(deps)); + + std::string sups = details::remove_optional_field(&fields, SourceParagraphOptionalField::SUPPORTS); + sparagraph.supports = parse_comma_list(sups); if (!fields.empty()) { @@ -89,7 +95,7 @@ namespace vcpkg std::vector vcpkg::expand_qualified_dependencies(const std::vector& depends) { - auto convert = [&](const std::string& depend_string) -> Dependency { + return Util::fmap(depends, [&](const std::string& depend_string) -> Dependency { auto pos = depend_string.find(' '); if (pos == std::string::npos) return {depend_string, ""}; // expect of the form "\w+ \[\w+\]" @@ -102,21 +108,12 @@ namespace vcpkg } dep.qualifier = depend_string.substr(pos + 2, depend_string.size() - pos - 3); return dep; - }; - - std::vector ret; - - for (auto&& depend_string : depends) - { - ret.push_back(convert(depend_string)); - } - - return ret; + }); } - std::vector parse_depends(const std::string& depends_string) + std::vector parse_comma_list(const std::string& str) { - if (depends_string.empty()) + if (str.empty()) { return {}; } @@ -126,17 +123,17 @@ namespace vcpkg size_t cur = 0; do { - auto pos = depends_string.find(',', cur); + auto pos = str.find(',', cur); if (pos == std::string::npos) { - out.push_back(depends_string.substr(cur)); + out.push_back(str.substr(cur)); break; } - out.push_back(depends_string.substr(cur, pos - cur)); + out.push_back(str.substr(cur, pos - cur)); // skip comma and space ++pos; - if (depends_string[pos] == ' ') + if (str[pos] == ' ') { ++pos; } @@ -161,4 +158,49 @@ namespace vcpkg } const std::string& to_string(const Dependency& dep) { return dep.name; } + + ExpectedT> Supports::parse(const std::vector& strs) + { + Supports ret; + std::vector unrecognized; + + for (auto&& str : strs) + { + if (str == "x64") + ret.architectures.push_back(Architecture::X64); + else if (str == "x86") + ret.architectures.push_back(Architecture::X86); + else if (str == "arm") + ret.architectures.push_back(Architecture::ARM); + else if (str == "windows") + ret.platforms.push_back(Platform::WINDOWS); + else if (str == "uwp") + ret.platforms.push_back(Platform::UWP); + else if (str == "v140") + ret.toolsets.push_back(ToolsetVersion::V140); + else if (str == "v141") + ret.toolsets.push_back(ToolsetVersion::V141); + else if (str == "crt-static") + ret.crt_linkages.push_back(Linkage::STATIC); + else if (str == "crt-dynamic") + ret.crt_linkages.push_back(Linkage::DYNAMIC); + else + unrecognized.push_back(str); + } + + if (unrecognized.empty()) + return std::move(ret); + else + return std::move(unrecognized); + } + + bool Supports::supports(Architecture arch, Platform plat, Linkage crt, ToolsetVersion tools) + { + auto is_in_or_empty = [](auto v, auto&& c) -> bool { return c.empty() || c.end() != Util::find(c, v); }; + if (!is_in_or_empty(arch, architectures)) return false; + if (!is_in_or_empty(plat, platforms)) return false; + if (!is_in_or_empty(crt, crt_linkages)) return false; + if (!is_in_or_empty(tools, toolsets)) return false; + return true; + } } diff --git a/toolsrc/src/tests_dependencies.cpp b/toolsrc/src/tests_dependencies.cpp index 3aabed80e..fdf2afea8 100644 --- a/toolsrc/src/tests_dependencies.cpp +++ b/toolsrc/src/tests_dependencies.cpp @@ -15,7 +15,7 @@ namespace UnitTest1 { TEST_METHOD(parse_depends_one) { - auto v = expand_qualified_dependencies(parse_depends("libA [windows]")); + auto v = expand_qualified_dependencies(parse_comma_list("libA [windows]")); Assert::AreEqual(size_t(1), v.size()); Assert::AreEqual("libA", v[0].name.c_str()); Assert::AreEqual("windows", v[0].qualifier.c_str()); @@ -23,7 +23,7 @@ namespace UnitTest1 TEST_METHOD(filter_depends) { - auto deps = expand_qualified_dependencies(parse_depends("libA [windows], libB, libC [uwp]")); + auto deps = expand_qualified_dependencies(parse_comma_list("libA [windows], libB, libC [uwp]")); auto v = filter_dependencies(deps, Triplet::X64_WINDOWS); Assert::AreEqual(size_t(2), v.size()); Assert::AreEqual("libA", v[0].c_str()); @@ -35,4 +35,65 @@ namespace UnitTest1 Assert::AreEqual("libC", v2[1].c_str()); } }; + + class SupportsTests : public TestClass + { + TEST_METHOD(parse_supports_all) + { + auto v = Supports::parse({ + "x64", "x86", "arm", "windows", "uwp", "v140", "v141", "crt-static", "crt-dynamic", + }); + Assert::AreNotEqual(uintptr_t(0), uintptr_t(v.get())); + + Assert::IsTrue(v.get()->supports(System::CPUArchitecture::X64, + Supports::Platform::UWP, + Supports::Linkage::DYNAMIC, + Supports::ToolsetVersion::V140)); + Assert::IsTrue(v.get()->supports(System::CPUArchitecture::ARM, + Supports::Platform::WINDOWS, + Supports::Linkage::STATIC, + Supports::ToolsetVersion::V141)); + } + + TEST_METHOD(parse_supports_invalid) + { + auto v = Supports::parse({"arm64"}); + Assert::AreEqual(uintptr_t(0), uintptr_t(v.get())); + Assert::AreEqual(size_t(1), v.error().size()); + Assert::AreEqual("arm64", v.error()[0].c_str()); + } + + TEST_METHOD(parse_supports_case_sensitive) + { + auto v = Supports::parse({"Windows"}); + Assert::AreEqual(uintptr_t(0), uintptr_t(v.get())); + Assert::AreEqual(size_t(1), v.error().size()); + Assert::AreEqual("Windows", v.error()[0].c_str()); + } + + TEST_METHOD(parse_supports_some) + { + auto v = Supports::parse({ + "x64", "x86", "windows", + }); + Assert::AreNotEqual(uintptr_t(0), uintptr_t(v.get())); + + Assert::IsTrue(v.get()->supports(System::CPUArchitecture::X64, + Supports::Platform::WINDOWS, + Supports::Linkage::DYNAMIC, + Supports::ToolsetVersion::V140)); + Assert::IsFalse(v.get()->supports(System::CPUArchitecture::ARM, + Supports::Platform::WINDOWS, + Supports::Linkage::DYNAMIC, + Supports::ToolsetVersion::V140)); + Assert::IsFalse(v.get()->supports(System::CPUArchitecture::X64, + Supports::Platform::UWP, + Supports::Linkage::DYNAMIC, + Supports::ToolsetVersion::V140)); + Assert::IsTrue(v.get()->supports(System::CPUArchitecture::X64, + Supports::Platform::WINDOWS, + Supports::Linkage::STATIC, + Supports::ToolsetVersion::V141)); + } + }; } diff --git a/toolsrc/src/tests_paragraph.cpp b/toolsrc/src/tests_paragraph.cpp index 1c77b437b..374e4ddd1 100644 --- a/toolsrc/src/tests_paragraph.cpp +++ b/toolsrc/src/tests_paragraph.cpp @@ -40,7 +40,12 @@ namespace UnitTest1 TEST_METHOD(SourceParagraph_Construct_Maximum) { auto m_pgh = vcpkg::SourceParagraph::parse_control_file({ - {"Source", "s"}, {"Version", "v"}, {"Maintainer", "m"}, {"Description", "d"}, {"Build-Depends", "bd"}, + {"Source", "s"}, + {"Version", "v"}, + {"Maintainer", "m"}, + {"Description", "d"}, + {"Build-Depends", "bd"}, + {"Supports", "x64"}, }); Assert::IsTrue(m_pgh.has_value()); auto& pgh = *m_pgh.get(); @@ -51,6 +56,8 @@ namespace UnitTest1 Assert::AreEqual("d", pgh.description.c_str()); Assert::AreEqual(size_t(1), pgh.depends.size()); Assert::AreEqual("bd", pgh.depends[0].name.c_str()); + Assert::AreEqual(size_t(1), pgh.supports.size()); + Assert::AreEqual("x64", pgh.supports[0].c_str()); } TEST_METHOD(SourceParagraph_Two_Depends) @@ -80,6 +87,20 @@ namespace UnitTest1 Assert::AreEqual("xyz", pgh.depends[2].name.c_str()); } + TEST_METHOD(SourceParagraph_Three_Supports) + { + auto m_pgh = vcpkg::SourceParagraph::parse_control_file({ + {"Source", "zlib"}, {"Version", "1.2.8"}, {"Supports", "x64, windows, uwp"}, + }); + Assert::IsTrue(m_pgh.has_value()); + auto& pgh = *m_pgh.get(); + + Assert::AreEqual(size_t(3), pgh.supports.size()); + Assert::AreEqual("x64", pgh.supports[0].c_str()); + Assert::AreEqual("windows", pgh.supports[1].c_str()); + Assert::AreEqual("uwp", pgh.supports[2].c_str()); + } + TEST_METHOD(SourceParagraph_Construct_Qualified_Depends) { auto m_pgh = vcpkg::SourceParagraph::parse_control_file({ -- cgit v1.2.3 From 9a698d7088beb3fa32b1b9d0321781c0ba07e18e Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 6 Jun 2017 16:30:01 -0700 Subject: Convert BuildType/Configuration Type into simple enum classes --- toolsrc/include/PostBuildLint_BuildType.h | 32 ++++++++++++------- toolsrc/include/PostBuildLint_ConfigurationType.h | 36 --------------------- toolsrc/include/PostBuildLint_LinkageType.h | 39 ----------------------- toolsrc/include/vcpkg_Build.h | 14 ++++++-- toolsrc/src/PostBuildLint.cpp | 15 ++++----- toolsrc/src/PostBuildLint_BuildType.cpp | 12 +++---- toolsrc/src/PostBuildLint_ConfigurationType.cpp | 24 -------------- toolsrc/src/PostBuildLint_LinkageType.cpp | 39 ----------------------- toolsrc/src/vcpkg_Build.cpp | 31 ++++++++++-------- toolsrc/vcpkglib/vcpkglib.vcxproj | 4 --- toolsrc/vcpkglib/vcpkglib.vcxproj.filters | 12 ------- 11 files changed, 62 insertions(+), 196 deletions(-) delete mode 100644 toolsrc/include/PostBuildLint_ConfigurationType.h delete mode 100644 toolsrc/include/PostBuildLint_LinkageType.h delete mode 100644 toolsrc/src/PostBuildLint_ConfigurationType.cpp delete mode 100644 toolsrc/src/PostBuildLint_LinkageType.cpp (limited to 'toolsrc') diff --git a/toolsrc/include/PostBuildLint_BuildType.h b/toolsrc/include/PostBuildLint_BuildType.h index 58bb20766..38ad3084e 100644 --- a/toolsrc/include/PostBuildLint_BuildType.h +++ b/toolsrc/include/PostBuildLint_BuildType.h @@ -1,12 +1,17 @@ #pragma once #include "CStringView.h" -#include "PostBuildLint_ConfigurationType.h" -#include "PostBuildLint_LinkageType.h" +#include "vcpkg_Build.h" #include #include namespace vcpkg::PostBuildLint { + enum class ConfigurationType + { + DEBUG, + RELEASE, + }; + struct BuildType { enum class BackingEnum @@ -17,11 +22,13 @@ namespace vcpkg::PostBuildLint RELEASE_DYNAMIC }; - static BuildType value_of(const ConfigurationType& config, const LinkageType& linkage); + static BuildType value_of(const ConfigurationType& config, const Build::LinkageType& linkage); BuildType() = delete; - constexpr BuildType(const BackingEnum backing_enum, const ConfigurationType config, const LinkageType linkage) + constexpr BuildType(const BackingEnum backing_enum, + const ConfigurationType config, + const Build::LinkageType linkage) : backing_enum(backing_enum), m_config(config), m_linkage(linkage) { } @@ -29,28 +36,29 @@ namespace vcpkg::PostBuildLint constexpr operator BackingEnum() const { return backing_enum; } const ConfigurationType& config() const; - const LinkageType& linkage() const; + const Build::LinkageType& linkage() const; const std::regex& crt_regex() const; const std::string& to_string() const; private: BackingEnum backing_enum; ConfigurationType m_config; - LinkageType m_linkage; + Build::LinkageType m_linkage; }; namespace BuildTypeC { - namespace CC = ConfigurationTypeC; - namespace LC = LinkageTypeC; + using Build::LinkageType; using BE = BuildType::BackingEnum; static constexpr CStringView ENUM_NAME = "vcpkg::PostBuildLint::BuildType"; - static constexpr BuildType DEBUG_STATIC = {BE::DEBUG_STATIC, CC::DEBUG, LC::STATIC}; - static constexpr BuildType DEBUG_DYNAMIC = {BE::DEBUG_DYNAMIC, CC::DEBUG, LC::DYNAMIC}; - static constexpr BuildType RELEASE_STATIC = {BE::RELEASE_STATIC, CC::RELEASE, LC::STATIC}; - static constexpr BuildType RELEASE_DYNAMIC = {BE::RELEASE_DYNAMIC, CC::RELEASE, LC::DYNAMIC}; + static constexpr BuildType DEBUG_STATIC = {BE::DEBUG_STATIC, ConfigurationType::DEBUG, LinkageType::STATIC}; + static constexpr BuildType DEBUG_DYNAMIC = {BE::DEBUG_DYNAMIC, ConfigurationType::DEBUG, LinkageType::DYNAMIC}; + static constexpr BuildType RELEASE_STATIC = { + BE::RELEASE_STATIC, ConfigurationType::RELEASE, LinkageType::STATIC}; + static constexpr BuildType RELEASE_DYNAMIC = { + BE::RELEASE_DYNAMIC, ConfigurationType::RELEASE, LinkageType::DYNAMIC}; static constexpr std::array VALUES = { DEBUG_STATIC, DEBUG_DYNAMIC, RELEASE_STATIC, RELEASE_DYNAMIC}; diff --git a/toolsrc/include/PostBuildLint_ConfigurationType.h b/toolsrc/include/PostBuildLint_ConfigurationType.h deleted file mode 100644 index 8157415b0..000000000 --- a/toolsrc/include/PostBuildLint_ConfigurationType.h +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once -#include "CStringView.h" -#include - -namespace vcpkg::PostBuildLint -{ - struct ConfigurationType - { - enum class BackingEnum - { - NULLVALUE = 0, - DEBUG = 1, - RELEASE = 2 - }; - - constexpr ConfigurationType() : backing_enum(BackingEnum::NULLVALUE) {} - constexpr explicit ConfigurationType(BackingEnum backing_enum) : backing_enum(backing_enum) {} - constexpr operator BackingEnum() const { return backing_enum; } - - const std::string& to_string() const; - - private: - BackingEnum backing_enum; - }; - - namespace ConfigurationTypeC - { - static constexpr CStringView ENUM_NAME = "vcpkg::PostBuildLint::ConfigurationType"; - - static constexpr ConfigurationType NULLVALUE(ConfigurationType::BackingEnum::NULLVALUE); - static constexpr ConfigurationType DEBUG(ConfigurationType::BackingEnum::DEBUG); - static constexpr ConfigurationType RELEASE(ConfigurationType::BackingEnum::RELEASE); - - static constexpr std::array VALUES = {DEBUG, RELEASE}; - } -} diff --git a/toolsrc/include/PostBuildLint_LinkageType.h b/toolsrc/include/PostBuildLint_LinkageType.h deleted file mode 100644 index 383cd0ffb..000000000 --- a/toolsrc/include/PostBuildLint_LinkageType.h +++ /dev/null @@ -1,39 +0,0 @@ -#pragma once -#include "CStringView.h" -#include -#include - -namespace vcpkg::PostBuildLint -{ - struct LinkageType final - { - enum class BackingEnum - { - NULLVALUE = 0, - DYNAMIC, - STATIC - }; - - static LinkageType value_of(const std::string& as_string); - - constexpr LinkageType() : backing_enum(BackingEnum::NULLVALUE) {} - constexpr explicit LinkageType(BackingEnum backing_enum) : backing_enum(backing_enum) {} - constexpr operator BackingEnum() const { return backing_enum; } - - const std::string& to_string() const; - - private: - BackingEnum backing_enum; - }; - - namespace LinkageTypeC - { - static constexpr CStringView ENUM_NAME = "vcpkg::PostBuildLint::LinkageType"; - - static constexpr LinkageType NULLVALUE(LinkageType::BackingEnum::NULLVALUE); - static constexpr LinkageType DYNAMIC(LinkageType::BackingEnum::DYNAMIC); - static constexpr LinkageType STATIC(LinkageType::BackingEnum::STATIC); - - static constexpr std::array VALUES = {DYNAMIC, STATIC}; - } -} diff --git a/toolsrc/include/vcpkg_Build.h b/toolsrc/include/vcpkg_Build.h index bce1eeb3e..e13f66029 100644 --- a/toolsrc/include/vcpkg_Build.h +++ b/toolsrc/include/vcpkg_Build.h @@ -2,12 +2,12 @@ #include "CStringView.h" #include "PackageSpec.h" -#include "PostBuildLint_LinkageType.h" #include "StatusParagraphs.h" #include "VcpkgPaths.h" #include "vcpkg_Files.h" #include "vcpkg_optional.h" +#include #include #include #include @@ -141,10 +141,18 @@ namespace vcpkg::Build std::map m_policies; }; + enum class LinkageType : char + { + DYNAMIC, + STATIC, + }; + + Optional to_linkage_type(const std::string& str); + struct BuildInfo { - PostBuildLint::LinkageType crt_linkage; - PostBuildLint::LinkageType library_linkage; + LinkageType crt_linkage; + LinkageType library_linkage; Optional version; diff --git a/toolsrc/src/PostBuildLint.cpp b/toolsrc/src/PostBuildLint.cpp index 363346ab6..82d50a68f 100644 --- a/toolsrc/src/PostBuildLint.cpp +++ b/toolsrc/src/PostBuildLint.cpp @@ -777,7 +777,7 @@ namespace vcpkg::PostBuildLint switch (build_info.library_linkage) { - case LinkageType::BackingEnum::DYNAMIC: + case Build::LinkageType::DYNAMIC: { std::vector debug_dlls = fs.get_files_recursive(debug_bin_dir); Util::unstable_keep_if(debug_dlls, has_extension_pred(fs, ".dll")); @@ -802,7 +802,7 @@ namespace vcpkg::PostBuildLint error_count += check_outdated_crt_linkage_of_dlls(dlls, toolset.dumpbin, build_info); break; } - case LinkageType::BackingEnum::STATIC: + case Build::LinkageType::STATIC: { std::vector dlls = fs.get_files_recursive(package_dir); Util::unstable_keep_if(dlls, has_extension_pred(fs, ".dll")); @@ -812,18 +812,17 @@ namespace vcpkg::PostBuildLint if (!build_info.policies.is_enabled(BuildPolicy::ONLY_RELEASE_CRT)) { - error_count += check_crt_linkage_of_libs( - BuildType::value_of(ConfigurationTypeC::DEBUG, build_info.crt_linkage), - debug_libs, - toolset.dumpbin); + error_count += + check_crt_linkage_of_libs(BuildType::value_of(ConfigurationType::DEBUG, build_info.crt_linkage), + debug_libs, + toolset.dumpbin); } error_count += - check_crt_linkage_of_libs(BuildType::value_of(ConfigurationTypeC::RELEASE, build_info.crt_linkage), + check_crt_linkage_of_libs(BuildType::value_of(ConfigurationType::RELEASE, build_info.crt_linkage), release_libs, toolset.dumpbin); break; } - case LinkageType::BackingEnum::NULLVALUE: default: Checks::unreachable(VCPKG_LINE_INFO); } diff --git a/toolsrc/src/PostBuildLint_BuildType.cpp b/toolsrc/src/PostBuildLint_BuildType.cpp index e690036d2..649f0ccca 100644 --- a/toolsrc/src/PostBuildLint_BuildType.cpp +++ b/toolsrc/src/PostBuildLint_BuildType.cpp @@ -5,24 +5,24 @@ namespace vcpkg::PostBuildLint { - BuildType BuildType::value_of(const ConfigurationType& config, const LinkageType& linkage) + BuildType BuildType::value_of(const ConfigurationType& config, const Build::LinkageType& linkage) { - if (config == ConfigurationTypeC::DEBUG && linkage == LinkageTypeC::STATIC) + if (config == ConfigurationType::DEBUG && linkage == Build::LinkageType::STATIC) { return BuildTypeC::DEBUG_STATIC; } - if (config == ConfigurationTypeC::DEBUG && linkage == LinkageTypeC::DYNAMIC) + if (config == ConfigurationType::DEBUG && linkage == Build::LinkageType::DYNAMIC) { return BuildTypeC::DEBUG_DYNAMIC; } - if (config == ConfigurationTypeC::RELEASE && linkage == LinkageTypeC::STATIC) + if (config == ConfigurationType::RELEASE && linkage == Build::LinkageType::STATIC) { return BuildTypeC::RELEASE_STATIC; } - if (config == ConfigurationTypeC::RELEASE && linkage == LinkageTypeC::DYNAMIC) + if (config == ConfigurationType::RELEASE && linkage == Build::LinkageType::DYNAMIC) { return BuildTypeC::RELEASE_DYNAMIC; } @@ -32,7 +32,7 @@ namespace vcpkg::PostBuildLint const ConfigurationType& BuildType::config() const { return this->m_config; } - const LinkageType& BuildType::linkage() const { return this->m_linkage; } + const Build::LinkageType& BuildType::linkage() const { return this->m_linkage; } const std::regex& BuildType::crt_regex() const { diff --git a/toolsrc/src/PostBuildLint_ConfigurationType.cpp b/toolsrc/src/PostBuildLint_ConfigurationType.cpp deleted file mode 100644 index eeccb1804..000000000 --- a/toolsrc/src/PostBuildLint_ConfigurationType.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include "pch.h" - -#include "PackageSpec.h" -#include "PostBuildLint_ConfigurationType.h" -#include "vcpkg_Enums.h" - -namespace vcpkg::PostBuildLint -{ - static const std::string NULLVALUE_STRING = Enums::nullvalue_to_string(ConfigurationTypeC::ENUM_NAME); - - static const std::string NAME_DEBUG = "Debug"; - static const std::string NAME_RELEASE = "Release"; - - const std::string& ConfigurationType::to_string() const - { - switch (this->backing_enum) - { - case ConfigurationTypeC::DEBUG: return NAME_DEBUG; - case ConfigurationTypeC::RELEASE: return NAME_RELEASE; - case ConfigurationTypeC::NULLVALUE: return NULLVALUE_STRING; - default: Checks::unreachable(VCPKG_LINE_INFO); - } - } -} diff --git a/toolsrc/src/PostBuildLint_LinkageType.cpp b/toolsrc/src/PostBuildLint_LinkageType.cpp deleted file mode 100644 index 43bdbed7b..000000000 --- a/toolsrc/src/PostBuildLint_LinkageType.cpp +++ /dev/null @@ -1,39 +0,0 @@ -#include "pch.h" - -#include "PostBuildLint_LinkageType.h" -#include "vcpkg_Checks.h" -#include "vcpkg_Enums.h" - -namespace vcpkg::PostBuildLint -{ - static const std::string NULLVALUE_STRING = Enums::nullvalue_to_string(LinkageTypeC::ENUM_NAME); - - static const std::string NAME_DYNAMIC = "dynamic"; - static const std::string NAME_STATIC = "static"; - - LinkageType LinkageType::value_of(const std::string& as_string) - { - if (as_string == NAME_DYNAMIC) - { - return LinkageTypeC::DYNAMIC; - } - - if (as_string == NAME_STATIC) - { - return LinkageTypeC::STATIC; - } - - return LinkageTypeC::NULLVALUE; - } - - const std::string& LinkageType::to_string() const - { - switch (this->backing_enum) - { - case LinkageTypeC::DYNAMIC: return NAME_DYNAMIC; - case LinkageTypeC::STATIC: return NAME_STATIC; - case LinkageTypeC::NULLVALUE: return NULLVALUE_STRING; - default: Checks::unreachable(VCPKG_LINE_INFO); - } - } -} diff --git a/toolsrc/src/vcpkg_Build.cpp b/toolsrc/src/vcpkg_Build.cpp index 91e4552ec..0ca6dc243 100644 --- a/toolsrc/src/vcpkg_Build.cpp +++ b/toolsrc/src/vcpkg_Build.cpp @@ -13,11 +13,15 @@ #include "vcpkglib.h" #include "vcpkglib_helpers.h" -using vcpkg::PostBuildLint::LinkageType; -namespace LinkageTypeC = vcpkg::PostBuildLint::LinkageTypeC; - namespace vcpkg::Build { + Optional to_linkage_type(const std::string& str) + { + if (str == "dynamic") return LinkageType::DYNAMIC; + if (str == "static") return LinkageType::STATIC; + return nullopt; + } + namespace BuildInfoRequiredField { static const std::string CRT_LINKAGE = "CRTLinkage"; @@ -217,19 +221,20 @@ namespace vcpkg::Build BuildInfo build_info; const std::string crt_linkage_as_string = details::remove_required_field(&pgh, BuildInfoRequiredField::CRT_LINKAGE); - build_info.crt_linkage = LinkageType::value_of(crt_linkage_as_string); - Checks::check_exit(VCPKG_LINE_INFO, - build_info.crt_linkage != LinkageTypeC::NULLVALUE, - "Invalid crt linkage type: [%s]", - crt_linkage_as_string); + + auto crtlinkage = to_linkage_type(crt_linkage_as_string); + if (auto p = crtlinkage.get()) + build_info.crt_linkage = *p; + else + Checks::exit_with_message(VCPKG_LINE_INFO, "Invalid crt linkage type: [%s]", crt_linkage_as_string); const std::string library_linkage_as_string = details::remove_required_field(&pgh, BuildInfoRequiredField::LIBRARY_LINKAGE); - build_info.library_linkage = LinkageType::value_of(library_linkage_as_string); - Checks::check_exit(VCPKG_LINE_INFO, - build_info.library_linkage != LinkageTypeC::NULLVALUE, - "Invalid library linkage type: [%s]", - library_linkage_as_string); + auto liblinkage = to_linkage_type(library_linkage_as_string); + if (auto p = liblinkage.get()) + build_info.library_linkage = *p; + else + Checks::exit_with_message(VCPKG_LINE_INFO, "Invalid library linkage type: [%s]", library_linkage_as_string); auto it_version = pgh.find("Version"); if (it_version != pgh.end()) diff --git a/toolsrc/vcpkglib/vcpkglib.vcxproj b/toolsrc/vcpkglib/vcpkglib.vcxproj index 4ec37a16d..abc2e4a4e 100644 --- a/toolsrc/vcpkglib/vcpkglib.vcxproj +++ b/toolsrc/vcpkglib/vcpkglib.vcxproj @@ -154,8 +154,6 @@ - - @@ -218,8 +216,6 @@ Create - - diff --git a/toolsrc/vcpkglib/vcpkglib.vcxproj.filters b/toolsrc/vcpkglib/vcpkglib.vcxproj.filters index 895eb2a4a..599bfeafb 100644 --- a/toolsrc/vcpkglib/vcpkglib.vcxproj.filters +++ b/toolsrc/vcpkglib/vcpkglib.vcxproj.filters @@ -129,12 +129,6 @@ Source Files - - Source Files - - - Source Files - Source Files @@ -257,12 +251,6 @@ Header Files - - Header Files - - - Header Files - Header Files -- cgit v1.2.3 From 247a6cec90004b8666d155eacc0f27d3a6c8fcf9 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Thu, 8 Jun 2017 00:36:17 -0700 Subject: [vcpkg] Improve diagnostics upon port load failure --- toolsrc/include/Paragraphs.h | 8 ++++ toolsrc/include/SourceParagraph.h | 9 +++-- toolsrc/include/Span.h | 38 ++++++++++++++++++ toolsrc/include/pch.h | 1 + toolsrc/include/vcpkg_Strings.h | 15 ++++---- toolsrc/src/Paragraphs.cpp | 23 +++++++---- toolsrc/src/SourceParagraph.cpp | 64 +++++++++++++++++-------------- toolsrc/src/commands_ci.cpp | 5 ++- toolsrc/src/commands_depends.cpp | 5 +-- toolsrc/src/commands_search.cpp | 25 +++++++++++- toolsrc/src/vcpkg_Dependencies.cpp | 6 +-- toolsrc/vcpkglib/vcpkglib.vcxproj | 1 + toolsrc/vcpkglib/vcpkglib.vcxproj.filters | 3 ++ 13 files changed, 147 insertions(+), 56 deletions(-) create mode 100644 toolsrc/include/Span.h (limited to 'toolsrc') diff --git a/toolsrc/include/Paragraphs.h b/toolsrc/include/Paragraphs.h index 59f0eefc8..04f9fb879 100644 --- a/toolsrc/include/Paragraphs.h +++ b/toolsrc/include/Paragraphs.h @@ -21,6 +21,14 @@ namespace vcpkg::Paragraphs Expected try_load_cached_package(const VcpkgPaths& paths, const PackageSpec& spec); + struct LoadResults + { + std::vector paragraphs; + std::vector errors; + }; + + LoadResults try_load_all_ports(const Files::Filesystem& fs, const fs::path& ports_dir); + std::vector load_all_ports(const Files::Filesystem& fs, const fs::path& ports_dir); std::map extract_port_names_and_versions( diff --git a/toolsrc/include/SourceParagraph.h b/toolsrc/include/SourceParagraph.h index a53158f3f..47ad5b830 100644 --- a/toolsrc/include/SourceParagraph.h +++ b/toolsrc/include/SourceParagraph.h @@ -1,5 +1,6 @@ #pragma once +#include "Span.h" #include "vcpkg_System.h" #include "vcpkg_expected.h" @@ -23,7 +24,6 @@ namespace vcpkg { std::string name; std::string remaining_fields_as_string; - std::string valid_fields_as_string; std::error_code error; }; @@ -45,8 +45,11 @@ namespace vcpkg std::vector depends; }; - void print_error_message(const ParseControlErrorInfo& info); - void print_error_message(std::vector error_info_list); + void print_error_message(span error_info_list); + inline void print_error_message(const ParseControlErrorInfo& error_info_list) + { + return print_error_message({&error_info_list, 1}); + } std::vector filter_dependencies(const std::vector& deps, const Triplet& t); diff --git a/toolsrc/include/Span.h b/toolsrc/include/Span.h new file mode 100644 index 000000000..b16af2cef --- /dev/null +++ b/toolsrc/include/Span.h @@ -0,0 +1,38 @@ +#pragma once + +#include +#include +#include + +template +struct span +{ +public: + using element_type = T; + using pointer = T*; + using reference = T&; + using iterator = T*; + + constexpr span() noexcept : m_ptr(nullptr), m_count(0) {} + constexpr span(std::nullptr_t) noexcept : span() {} + constexpr span(T* ptr, size_t count) noexcept : m_ptr(ptr), m_count(count) {} + constexpr span(T* ptr_begin, T* ptr_end) noexcept : m_ptr(ptr_begin), m_count(ptr_end - ptr_begin) {} + + template + constexpr span(T (&arr)[N]) noexcept : span(arr, N) + { + } + + span(std::vector& v) noexcept : span(v.data(), v.size()) {} + span(const std::vector>& v) noexcept : span(v.data(), v.size()) {} + + constexpr iterator begin() const { return m_ptr; } + constexpr iterator end() const { return m_ptr + m_count; } + + constexpr reference operator[](size_t i) const { return m_ptr[i]; } + constexpr size_t size() const { return m_count; } + +private: + pointer m_ptr; + size_t m_count; +}; diff --git a/toolsrc/include/pch.h b/toolsrc/include/pch.h index c58c30ea3..406d0741e 100644 --- a/toolsrc/include/pch.h +++ b/toolsrc/include/pch.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include diff --git a/toolsrc/include/vcpkg_Strings.h b/toolsrc/include/vcpkg_Strings.h index 3f8f4562e..cab8071aa 100644 --- a/toolsrc/include/vcpkg_Strings.h +++ b/toolsrc/include/vcpkg_Strings.h @@ -58,8 +58,8 @@ namespace vcpkg::Strings std::string ascii_to_lowercase(const std::string& input); - template - std::basic_string join(const CharType* delimiter, const std::vector& v, Transformer transformer) + template + std::basic_string join(const CharType* delimiter, const Container& v, Transformer transformer) { if (v.empty()) { @@ -69,20 +69,21 @@ namespace vcpkg::Strings std::basic_string output; size_t size = v.size(); - output.append(transformer(v.at(0))); + output.append(transformer(v[0])); for (size_t i = 1; i < size; ++i) { output.append(delimiter); - output.append(transformer(v.at(i))); + output.append(transformer(v[i])); } return output; } - template - std::basic_string join(const CharType* delimiter, const std::vector& v) + template + std::basic_string join(const CharType* delimiter, const Container& v) { - return join(delimiter, v, [](const T& x) -> const T& { return x; }); + using Element = decltype(v[0]); + return join(delimiter, v, [](const Element& x) -> const Element& { return x; }); } void trim(std::string* s); diff --git a/toolsrc/src/Paragraphs.cpp b/toolsrc/src/Paragraphs.cpp index 13103d1f8..31e8f1da3 100644 --- a/toolsrc/src/Paragraphs.cpp +++ b/toolsrc/src/Paragraphs.cpp @@ -209,6 +209,7 @@ namespace vcpkg::Paragraphs { return SourceParagraph::parse_control_file(*p); } + error_info.name = path.filename().generic_u8string(); error_info.error = pghs.error(); return error_info; } @@ -226,25 +227,33 @@ namespace vcpkg::Paragraphs return pghs.error(); } - std::vector load_all_ports(const Files::Filesystem& fs, const fs::path& ports_dir) + LoadResults try_load_all_ports(const Files::Filesystem& fs, const fs::path& ports_dir) { - std::vector output; - std::vector port_errors; + LoadResults ret; for (auto&& path : fs.get_files_non_recursive(ports_dir)) { ExpectedT source_paragraph = try_load_port(fs, path); if (auto srcpgh = source_paragraph.get()) { - output.emplace_back(std::move(*srcpgh)); + ret.paragraphs.emplace_back(std::move(*srcpgh)); } else { - port_errors.emplace_back(source_paragraph.error()); + ret.errors.emplace_back(source_paragraph.error()); } } - print_error_message(port_errors); + return ret; + } - return output; + std::vector load_all_ports(const Files::Filesystem& fs, const fs::path& ports_dir) + { + auto results = try_load_all_ports(fs, ports_dir); + if (!results.errors.empty()) + { + print_error_message(results.errors); + Checks::exit_fail(VCPKG_LINE_INFO); + } + return std::move(results.paragraphs); } std::map extract_port_names_and_versions( diff --git a/toolsrc/src/SourceParagraph.cpp b/toolsrc/src/SourceParagraph.cpp index 2508af1e8..4001e891f 100644 --- a/toolsrc/src/SourceParagraph.cpp +++ b/toolsrc/src/SourceParagraph.cpp @@ -27,42 +27,52 @@ namespace vcpkg static const std::string SUPPORTS = "Supports"; } - static const std::vector& get_list_of_valid_fields() + static span get_list_of_valid_fields() { - static const std::vector valid_fields = {SourceParagraphRequiredField::SOURCE, - SourceParagraphRequiredField::VERSION, + static const std::string valid_fields[] = {SourceParagraphRequiredField::SOURCE, + SourceParagraphRequiredField::VERSION, - SourceParagraphOptionalField::DESCRIPTION, - SourceParagraphOptionalField::MAINTAINER, - SourceParagraphOptionalField::BUILD_DEPENDS, - SourceParagraphOptionalField::SUPPORTS}; + SourceParagraphOptionalField::DESCRIPTION, + SourceParagraphOptionalField::MAINTAINER, + SourceParagraphOptionalField::BUILD_DEPENDS, + SourceParagraphOptionalField::SUPPORTS}; return valid_fields; } - void print_error_message(const ParseControlErrorInfo& info) + void print_error_message(span error_info_list) { - System::println( - System::Color::error, "Error: There are invalid fields in the Source Paragraph of %s", info.name); - System::println("The following fields were not expected:\n\n %s\n\n", info.remaining_fields_as_string); - System::println("This is the list of valid fields (case-sensitive): \n\n %s\n", info.valid_fields_as_string); - System::println("Different source may be available for vcpkg. Use .\\bootstrap-vcpkg.bat to update.\n"); - } + Checks::check_exit(VCPKG_LINE_INFO, error_info_list.size() > 0); - void print_error_message(std::vector error_info_list) - { - if (error_info_list.size() == 0) return; - for (ParseControlErrorInfo error_info : error_info_list) + for (auto&& error_info : error_info_list) { - System::println( - System::Color::error, "Error: There are invalid fields in the Source Paragraph of %s", error_info.name); - System::println("The following fields were not expected:\n\n %s\n\n", - error_info.remaining_fields_as_string); + if (error_info.error) + { + System::println( + System::Color::error, "Error: while loading %s: %s", error_info.name, error_info.error.message()); + } } - System::println("This is the list of valid fields (case-sensitive): \n\n %s\n", - error_info_list.front().valid_fields_as_string); - System::println("Different source may be available for vcpkg. Use .\\bootstrap-vcpkg.bat to update.\n"); + bool have_remaining_fields = false; + for (auto&& error_info : error_info_list) + { + if (!error_info.remaining_fields_as_string.empty()) + { + System::println(System::Color::error, + "Error: There are invalid fields in the Source Paragraph of %s", + error_info.name); + System::println("The following fields were not expected:\n\n %s\n\n", + error_info.remaining_fields_as_string); + have_remaining_fields = true; + } + } + + if (have_remaining_fields) + { + System::println("This is the list of valid fields (case-sensitive): \n\n %s\n", + Strings::join("\n ", get_list_of_valid_fields())); + System::println("Different source may be available for vcpkg. Use .\\bootstrap-vcpkg.bat to update.\n"); + } } ExpectedT SourceParagraph::parse_control_file( @@ -83,12 +93,10 @@ namespace vcpkg if (!fields.empty()) { const std::vector remaining_fields = Maps::extract_keys(fields); - const std::vector& valid_fields = get_list_of_valid_fields(); const std::string remaining_fields_as_string = Strings::join("\n ", remaining_fields); - const std::string valid_fields_as_string = Strings::join("\n ", valid_fields); - return ParseControlErrorInfo{sparagraph.name, remaining_fields_as_string, valid_fields_as_string}; + return ParseControlErrorInfo{sparagraph.name, remaining_fields_as_string}; } return sparagraph; } diff --git a/toolsrc/src/commands_ci.cpp b/toolsrc/src/commands_ci.cpp index bad1286f0..7e724f3ee 100644 --- a/toolsrc/src/commands_ci.cpp +++ b/toolsrc/src/commands_ci.cpp @@ -20,9 +20,10 @@ namespace vcpkg::Commands::CI const fs::path& ports_directory, const Triplet& triplet) { - std::vector ports = Paragraphs::load_all_ports(fs, ports_directory); + auto sources = Paragraphs::load_all_ports(fs, ports_directory); + std::vector specs; - for (const SourceParagraph& p : ports) + for (const SourceParagraph& p : sources) { specs.push_back(PackageSpec::from_name_and_triplet(p.name, triplet).value_or_exit(VCPKG_LINE_INFO)); } diff --git a/toolsrc/src/commands_depends.cpp b/toolsrc/src/commands_depends.cpp index ad33bbad4..9db4b7bb1 100644 --- a/toolsrc/src/commands_depends.cpp +++ b/toolsrc/src/commands_depends.cpp @@ -13,10 +13,9 @@ namespace vcpkg::Commands::DependInfo args.check_exact_arg_count(0, example); args.check_and_get_optional_command_arguments({}); - const std::vector source_paragraphs = - Paragraphs::load_all_ports(paths.get_filesystem(), paths.ports); + auto sources = Paragraphs::load_all_ports(paths.get_filesystem(), paths.ports); - for (const SourceParagraph& source_paragraph : source_paragraphs) + for (const SourceParagraph& source_paragraph : sources) { auto s = Strings::join(", ", source_paragraph.depends, [](const Dependency& d) { return d.name; }); System::println("%s: %s", source_paragraph.name, s); diff --git a/toolsrc/src/commands_search.cpp b/toolsrc/src/commands_search.cpp index 739aa0f43..4b7f49ba8 100644 --- a/toolsrc/src/commands_search.cpp +++ b/toolsrc/src/commands_search.cpp @@ -4,6 +4,7 @@ #include "SourceParagraph.h" #include "vcpkg_Commands.h" #include "vcpkg_System.h" +#include "vcpkglib.h" #include "vcpkglib_helpers.h" namespace vcpkg::Commands::Search @@ -61,8 +62,28 @@ namespace vcpkg::Commands::Search args.check_max_arg_count(1, example); const std::unordered_set options = args.check_and_get_optional_command_arguments({OPTION_GRAPH}); - const std::vector source_paragraphs = - Paragraphs::load_all_ports(paths.get_filesystem(), paths.ports); + auto sources_and_errors = Paragraphs::try_load_all_ports(paths.get_filesystem(), paths.ports); + + if (!sources_and_errors.errors.empty()) + { + if (vcpkg::g_debugging) + { + print_error_message(sources_and_errors.errors); + } + else + { + for (auto&& error : sources_and_errors.errors) + { + System::println( + System::Color::warning, "Warning: an error occurred while parsing '%s'\n", error.name); + } + System::println(System::Color::warning, + "Use '--debug' to get more information about the parse failures.\n"); + } + } + + auto& source_paragraphs = sources_and_errors.paragraphs; + if (options.find(OPTION_GRAPH) != options.cend()) { const std::string graph_as_string = create_graph_as_string(source_paragraphs); diff --git a/toolsrc/src/vcpkg_Dependencies.cpp b/toolsrc/src/vcpkg_Dependencies.cpp index ea5832e46..f32d92f4c 100644 --- a/toolsrc/src/vcpkg_Dependencies.cpp +++ b/toolsrc/src/vcpkg_Dependencies.cpp @@ -179,10 +179,8 @@ namespace vcpkg::Dependencies if (auto spgh = maybe_spgh.get()) return InstallPlanAction{spec, {nullopt, nullopt, *spgh}, request_type}; - else - print_error_message(maybe_spgh.error()); - - Checks::exit_with_message(VCPKG_LINE_INFO, "Could not find package %s", spec); + print_error_message(maybe_spgh.error()); + Checks::exit_fail(VCPKG_LINE_INFO); } }; diff --git a/toolsrc/vcpkglib/vcpkglib.vcxproj b/toolsrc/vcpkglib/vcpkglib.vcxproj index abc2e4a4e..487609cca 100644 --- a/toolsrc/vcpkglib/vcpkglib.vcxproj +++ b/toolsrc/vcpkglib/vcpkglib.vcxproj @@ -142,6 +142,7 @@ + diff --git a/toolsrc/vcpkglib/vcpkglib.vcxproj.filters b/toolsrc/vcpkglib/vcpkglib.vcxproj.filters index 599bfeafb..a901cebe7 100644 --- a/toolsrc/vcpkglib/vcpkglib.vcxproj.filters +++ b/toolsrc/vcpkglib/vcpkglib.vcxproj.filters @@ -299,5 +299,8 @@ Header Files + + Header Files + \ No newline at end of file -- cgit v1.2.3 From 44a995d4461c54f0ff838af2649b618c533e60b7 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Thu, 8 Jun 2017 04:36:11 -0700 Subject: [vcpkg] Hotfix previous commit. --- toolsrc/include/SourceParagraph.h | 2 +- toolsrc/include/vcpkg_Strings.h | 2 +- toolsrc/src/SourceParagraph.cpp | 2 +- toolsrc/src/tests_dependencies.cpp | 48 +++++++++++++++++++------------------- 4 files changed, 27 insertions(+), 27 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/SourceParagraph.h b/toolsrc/include/SourceParagraph.h index 47ad5b830..2f30e338e 100644 --- a/toolsrc/include/SourceParagraph.h +++ b/toolsrc/include/SourceParagraph.h @@ -78,7 +78,7 @@ namespace vcpkg V141, }; - bool supports(Architecture arch, Platform plat, Linkage crt, ToolsetVersion tools); + bool is_supported(Architecture arch, Platform plat, Linkage crt, ToolsetVersion tools); private: std::vector architectures; diff --git a/toolsrc/include/vcpkg_Strings.h b/toolsrc/include/vcpkg_Strings.h index cab8071aa..e95a0601a 100644 --- a/toolsrc/include/vcpkg_Strings.h +++ b/toolsrc/include/vcpkg_Strings.h @@ -61,7 +61,7 @@ namespace vcpkg::Strings template std::basic_string join(const CharType* delimiter, const Container& v, Transformer transformer) { - if (v.empty()) + if (v.size() == 0) { return std::basic_string(); } diff --git a/toolsrc/src/SourceParagraph.cpp b/toolsrc/src/SourceParagraph.cpp index 4001e891f..3b770a4b4 100644 --- a/toolsrc/src/SourceParagraph.cpp +++ b/toolsrc/src/SourceParagraph.cpp @@ -202,7 +202,7 @@ namespace vcpkg return std::move(unrecognized); } - bool Supports::supports(Architecture arch, Platform plat, Linkage crt, ToolsetVersion tools) + bool Supports::is_supported(Architecture arch, Platform plat, Linkage crt, ToolsetVersion tools) { auto is_in_or_empty = [](auto v, auto&& c) -> bool { return c.empty() || c.end() != Util::find(c, v); }; if (!is_in_or_empty(arch, architectures)) return false; diff --git a/toolsrc/src/tests_dependencies.cpp b/toolsrc/src/tests_dependencies.cpp index fdf2afea8..995d46873 100644 --- a/toolsrc/src/tests_dependencies.cpp +++ b/toolsrc/src/tests_dependencies.cpp @@ -45,14 +45,14 @@ namespace UnitTest1 }); Assert::AreNotEqual(uintptr_t(0), uintptr_t(v.get())); - Assert::IsTrue(v.get()->supports(System::CPUArchitecture::X64, - Supports::Platform::UWP, - Supports::Linkage::DYNAMIC, - Supports::ToolsetVersion::V140)); - Assert::IsTrue(v.get()->supports(System::CPUArchitecture::ARM, - Supports::Platform::WINDOWS, - Supports::Linkage::STATIC, - Supports::ToolsetVersion::V141)); + Assert::IsTrue(v.get()->is_supported(System::CPUArchitecture::X64, + Supports::Platform::UWP, + Supports::Linkage::DYNAMIC, + Supports::ToolsetVersion::V140)); + Assert::IsTrue(v.get()->is_supported(System::CPUArchitecture::ARM, + Supports::Platform::WINDOWS, + Supports::Linkage::STATIC, + Supports::ToolsetVersion::V141)); } TEST_METHOD(parse_supports_invalid) @@ -78,22 +78,22 @@ namespace UnitTest1 }); Assert::AreNotEqual(uintptr_t(0), uintptr_t(v.get())); - Assert::IsTrue(v.get()->supports(System::CPUArchitecture::X64, - Supports::Platform::WINDOWS, - Supports::Linkage::DYNAMIC, - Supports::ToolsetVersion::V140)); - Assert::IsFalse(v.get()->supports(System::CPUArchitecture::ARM, - Supports::Platform::WINDOWS, - Supports::Linkage::DYNAMIC, - Supports::ToolsetVersion::V140)); - Assert::IsFalse(v.get()->supports(System::CPUArchitecture::X64, - Supports::Platform::UWP, - Supports::Linkage::DYNAMIC, - Supports::ToolsetVersion::V140)); - Assert::IsTrue(v.get()->supports(System::CPUArchitecture::X64, - Supports::Platform::WINDOWS, - Supports::Linkage::STATIC, - Supports::ToolsetVersion::V141)); + Assert::IsTrue(v.get()->is_supported(System::CPUArchitecture::X64, + Supports::Platform::WINDOWS, + Supports::Linkage::DYNAMIC, + Supports::ToolsetVersion::V140)); + Assert::IsFalse(v.get()->is_supported(System::CPUArchitecture::ARM, + Supports::Platform::WINDOWS, + Supports::Linkage::DYNAMIC, + Supports::ToolsetVersion::V140)); + Assert::IsFalse(v.get()->is_supported(System::CPUArchitecture::X64, + Supports::Platform::UWP, + Supports::Linkage::DYNAMIC, + Supports::ToolsetVersion::V140)); + Assert::IsTrue(v.get()->is_supported(System::CPUArchitecture::X64, + Supports::Platform::WINDOWS, + Supports::Linkage::STATIC, + Supports::ToolsetVersion::V141)); } }; } -- cgit v1.2.3 From e5dc2f9c8ff5dfe3266a0c144a1e21b96fa62e25 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Fri, 9 Jun 2017 23:45:52 -0700 Subject: [vcpkg] Rename --full-desc to --x-full-desc --- toolsrc/src/commands_list.cpp | 10 ++++------ toolsrc/src/commands_search.cpp | 20 +++++++++----------- 2 files changed, 13 insertions(+), 17 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/commands_list.cpp b/toolsrc/src/commands_list.cpp index 521fc5a9a..d21883fc2 100644 --- a/toolsrc/src/commands_list.cpp +++ b/toolsrc/src/commands_list.cpp @@ -7,16 +7,13 @@ namespace vcpkg::Commands::List { - static const std::string OPTION_FULLDESC = "--full-desc"; // TODO: This should find a better home, eventually + static const std::string OPTION_FULLDESC = "--x-full-desc"; // TODO: This should find a better home, eventually static void do_print(const StatusParagraph& pgh, bool FullDesc) { if (FullDesc) { - System::println("%-27s %-16s %s", - pgh.package.displayname(), - pgh.package.version, - pgh.package.description); + System::println("%-27s %-16s %s", pgh.package.displayname(), pgh.package.version, pgh.package.description); } else { @@ -33,7 +30,8 @@ namespace vcpkg::Commands::List "The argument should be a substring to search for, or no argument to display all installed libraries.\n%s", Commands::Help::create_example_string("list png")); args.check_max_arg_count(1, example); - const std::unordered_set options = args.check_and_get_optional_command_arguments({OPTION_FULLDESC}); + const std::unordered_set options = + args.check_and_get_optional_command_arguments({OPTION_FULLDESC}); const StatusParagraphs status_paragraphs = database_load_check(paths); std::vector installed_packages = get_installed_ports(status_paragraphs); diff --git a/toolsrc/src/commands_search.cpp b/toolsrc/src/commands_search.cpp index 6ec2a5395..bdb1e5d77 100644 --- a/toolsrc/src/commands_search.cpp +++ b/toolsrc/src/commands_search.cpp @@ -8,9 +8,8 @@ namespace vcpkg::Commands::Search { - static const std::string OPTION_GRAPH = "--graph"; // TODO: This should find a better home, eventually - static const std::string OPTION_FULLDESC = "--full-desc"; // TODO: This should find a better home, eventually - + static const std::string OPTION_GRAPH = "--graph"; // TODO: This should find a better home, eventually + static const std::string OPTION_FULLDESC = "--x-full-desc"; // TODO: This should find a better home, eventually static std::string replace_dashes_with_underscore(const std::string& input) { @@ -51,17 +50,15 @@ namespace vcpkg::Commands::Search { if (FullDesc) { - System::println("%-20s %-16s %s", - source_paragraph.name, - source_paragraph.version, - source_paragraph.description); + System::println( + "%-20s %-16s %s", source_paragraph.name, source_paragraph.version, source_paragraph.description); } else { System::println("%-20s %-16s %s", - source_paragraph.name, - source_paragraph.version, - details::shorten_description(source_paragraph.description)); + source_paragraph.name, + source_paragraph.version, + details::shorten_description(source_paragraph.description)); } } @@ -71,7 +68,8 @@ namespace vcpkg::Commands::Search "The argument should be a substring to search for, or no argument to display all libraries.\n%s", Commands::Help::create_example_string("search png")); args.check_max_arg_count(1, example); - const std::unordered_set options = args.check_and_get_optional_command_arguments({OPTION_GRAPH, OPTION_FULLDESC}); + const std::unordered_set options = + args.check_and_get_optional_command_arguments({OPTION_GRAPH, OPTION_FULLDESC}); const std::vector source_paragraphs = Paragraphs::load_all_ports(paths.get_filesystem(), paths.ports); -- cgit v1.2.3 From 687440f9760f3b9492de9a3105cdd6b99f9a3634 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Wed, 14 Jun 2017 22:06:52 -0700 Subject: [vcpkg] Add additional debug messages --- toolsrc/src/vcpkg_System.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg_System.cpp b/toolsrc/src/vcpkg_System.cpp index 21329e003..c91c6be78 100644 --- a/toolsrc/src/vcpkg_System.cpp +++ b/toolsrc/src/vcpkg_System.cpp @@ -142,6 +142,7 @@ namespace vcpkg::System const std::wstring& actual_cmd_line = Strings::wformat(LR"###("%s 2>&1")###", cmd_line); + Debug::println("_wpopen(%s)", Strings::to_utf8(actual_cmd_line)); std::string output; char buf[1024]; auto pipe = _wpopen(actual_cmd_line.c_str(), L"r"); @@ -158,6 +159,7 @@ namespace vcpkg::System return {1, output}; } auto ec = _pclose(pipe); + Debug::println("_wpopen() returned %d", ec); return {ec, output}; } -- cgit v1.2.3 From 8d955c83b53d42983ebd9a046a0a0a5ade08537f Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 19 Jun 2017 13:25:41 -0700 Subject: Use std::experimental::filesystem instead of std::tr2::sys --- toolsrc/include/filesystem_fs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/include/filesystem_fs.h b/toolsrc/include/filesystem_fs.h index 8e223511d..0651ebf25 100644 --- a/toolsrc/include/filesystem_fs.h +++ b/toolsrc/include/filesystem_fs.h @@ -4,7 +4,7 @@ namespace fs { - namespace stdfs = std::tr2::sys; + namespace stdfs = std::experimental::filesystem; using stdfs::path; using stdfs::copy_options; -- cgit v1.2.3 From bca0988023a8c7bfc896d0f5787eb02e74c6fb59 Mon Sep 17 00:00:00 2001 From: Daniel Shaw Date: Mon, 19 Jun 2017 15:06:15 -0700 Subject: [vcpkg] feature packages initial parsing --- toolsrc/include/PackageSpec.h | 6 ++ toolsrc/include/Paragraphs.h | 8 +-- toolsrc/include/SourceParagraph.h | 27 ++++++-- toolsrc/include/vcpkg_Commands.h | 2 +- toolsrc/include/vcpkg_Input.h | 3 + toolsrc/include/vcpkg_Strings.h | 2 + toolsrc/src/Paragraphs.cpp | 21 ++++-- toolsrc/src/SourceParagraph.cpp | 62 +++++++++++++++-- toolsrc/src/VcpkgCmdArguments.cpp | 5 ++ toolsrc/src/commands_build.cpp | 32 +++++---- toolsrc/src/commands_build_external.cpp | 6 +- toolsrc/src/commands_ci.cpp | 6 +- toolsrc/src/commands_depends.cpp | 5 +- toolsrc/src/commands_portsdiff.cpp | 4 +- toolsrc/src/commands_search.cpp | 61 ++++++++++++----- toolsrc/src/commands_update.cpp | 4 +- toolsrc/src/tests_paragraph.cpp | 116 +++++++++++++++++--------------- toolsrc/src/vcpkg_Dependencies.cpp | 16 ++--- toolsrc/src/vcpkg_Input.cpp | 34 +++++++++- toolsrc/src/vcpkg_Strings.cpp | 5 ++ 20 files changed, 300 insertions(+), 125 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/PackageSpec.h b/toolsrc/include/PackageSpec.h index 58edb8274..62b6fc9de 100644 --- a/toolsrc/include/PackageSpec.h +++ b/toolsrc/include/PackageSpec.h @@ -26,6 +26,12 @@ namespace vcpkg Triplet m_triplet; }; + struct FullPackageSpec + { + PackageSpec package_spec; + std::vector features; + }; + bool operator==(const PackageSpec& left, const PackageSpec& right); bool operator!=(const PackageSpec& left, const PackageSpec& right); } diff --git a/toolsrc/include/Paragraphs.h b/toolsrc/include/Paragraphs.h index 04f9fb879..83a32b2af 100644 --- a/toolsrc/include/Paragraphs.h +++ b/toolsrc/include/Paragraphs.h @@ -16,20 +16,20 @@ namespace vcpkg::Paragraphs Expected parse_single_paragraph(const std::string& str); Expected> parse_paragraphs(const std::string& str); - ExpectedT try_load_port(const Files::Filesystem& fs, - const fs::path& control_path); + ExpectedT try_load_port(const Files::Filesystem& fs, + const fs::path& control_path); Expected try_load_cached_package(const VcpkgPaths& paths, const PackageSpec& spec); struct LoadResults { - std::vector paragraphs; + std::vector paragraphs; std::vector errors; }; LoadResults try_load_all_ports(const Files::Filesystem& fs, const fs::path& ports_dir); - std::vector load_all_ports(const Files::Filesystem& fs, const fs::path& ports_dir); + std::vector load_all_ports(const Files::Filesystem& fs, const fs::path& ports_dir); std::map extract_port_names_and_versions( const std::vector& source_paragraphs); diff --git a/toolsrc/include/SourceParagraph.h b/toolsrc/include/SourceParagraph.h index 2f30e338e..31c9560cc 100644 --- a/toolsrc/include/SourceParagraph.h +++ b/toolsrc/include/SourceParagraph.h @@ -10,6 +10,8 @@ namespace vcpkg { + extern bool g_feature_packages; + struct Triplet; struct Dependency @@ -27,23 +29,38 @@ namespace vcpkg std::error_code error; }; + struct FeatureParagraph + { + std::string name; + std::string description; + std::vector depends; + }; + /// /// Port metadata (CONTROL file) /// struct SourceParagraph { - static ExpectedT parse_control_file( - std::unordered_map fields); - - SourceParagraph() = default; - std::string name; std::string version; std::string description; std::string maintainer; std::vector supports; std::vector depends; + std::string default_features; }; + struct SourceControlFile + { + static ExpectedT parse_control_file( + std::vector>&& control_paragraphs); + + SourceParagraph core_paragraph; + std::vector> feature_paragraphs; + + std::vector errors; + }; + + std::vector getSourceParagraphs(const std::vector& control_files); void print_error_message(span error_info_list); inline void print_error_message(const ParseControlErrorInfo& error_info_list) diff --git a/toolsrc/include/vcpkg_Commands.h b/toolsrc/include/vcpkg_Commands.h index 006971e47..67319f240 100644 --- a/toolsrc/include/vcpkg_Commands.h +++ b/toolsrc/include/vcpkg_Commands.h @@ -18,7 +18,7 @@ namespace vcpkg::Commands namespace BuildCommand { - void perform_and_exit(const PackageSpec& spec, + void perform_and_exit(const FullPackageSpec& full_spec, const fs::path& port_dir, const std::unordered_set& options, const VcpkgPaths& paths); diff --git a/toolsrc/include/vcpkg_Input.h b/toolsrc/include/vcpkg_Input.h index 77f7ecfb5..fa568207a 100644 --- a/toolsrc/include/vcpkg_Input.h +++ b/toolsrc/include/vcpkg_Input.h @@ -6,6 +6,9 @@ namespace vcpkg::Input PackageSpec check_and_get_package_spec(const std::string& package_spec_as_string, const Triplet& default_triplet, CStringView example_text); + FullPackageSpec check_and_get_full_package_spec(const std::string& full_package_spec_as_string, + const Triplet& default_triplet, + CStringView example_text); void check_triplet(const Triplet& t, const VcpkgPaths& paths); } diff --git a/toolsrc/include/vcpkg_Strings.h b/toolsrc/include/vcpkg_Strings.h index e95a0601a..325a2cb4c 100644 --- a/toolsrc/include/vcpkg_Strings.h +++ b/toolsrc/include/vcpkg_Strings.h @@ -54,6 +54,8 @@ namespace vcpkg::Strings std::string::const_iterator case_insensitive_ascii_find(const std::string& s, const std::string& pattern); + bool case_insensitive_ascii_contains(const std::string& s, const std::string& pattern); + int case_insensitive_ascii_compare(const CStringView left, const CStringView right); std::string ascii_to_lowercase(const std::string& input); diff --git a/toolsrc/src/Paragraphs.cpp b/toolsrc/src/Paragraphs.cpp index 31e8f1da3..440d04ce4 100644 --- a/toolsrc/src/Paragraphs.cpp +++ b/toolsrc/src/Paragraphs.cpp @@ -201,13 +201,22 @@ namespace vcpkg::Paragraphs return Parser(str.c_str(), str.c_str() + str.size()).get_paragraphs(); } - ExpectedT try_load_port(const Files::Filesystem& fs, const fs::path& path) + ExpectedT try_load_port(const Files::Filesystem& fs, const fs::path& path) { ParseControlErrorInfo error_info; - Expected> pghs = get_single_paragraph(fs, path / "CONTROL"); - if (auto p = pghs.get()) + Expected>> pghs = get_paragraphs(fs, path / "CONTROL"); + if (auto vector_pghs = pghs.get()) { - return SourceParagraph::parse_control_file(*p); + auto csf = SourceControlFile::parse_control_file(std::move(*vector_pghs)); + if (!g_feature_packages) + { + if (auto ptr = csf.get()) + { + ptr->core_paragraph.default_features.clear(); + ptr->feature_paragraphs.clear(); + } + } + return csf; } error_info.name = path.filename().generic_u8string(); error_info.error = pghs.error(); @@ -232,7 +241,7 @@ namespace vcpkg::Paragraphs LoadResults ret; for (auto&& path : fs.get_files_non_recursive(ports_dir)) { - ExpectedT source_paragraph = try_load_port(fs, path); + ExpectedT source_paragraph = try_load_port(fs, path); if (auto srcpgh = source_paragraph.get()) { ret.paragraphs.emplace_back(std::move(*srcpgh)); @@ -245,7 +254,7 @@ namespace vcpkg::Paragraphs return ret; } - std::vector load_all_ports(const Files::Filesystem& fs, const fs::path& ports_dir) + std::vector load_all_ports(const Files::Filesystem& fs, const fs::path& ports_dir) { auto results = try_load_all_ports(fs, ports_dir); if (!results.errors.empty()) diff --git a/toolsrc/src/SourceParagraph.cpp b/toolsrc/src/SourceParagraph.cpp index 3b770a4b4..a938feb99 100644 --- a/toolsrc/src/SourceParagraph.cpp +++ b/toolsrc/src/SourceParagraph.cpp @@ -12,7 +12,7 @@ namespace vcpkg { - // + bool g_feature_packages = false; namespace SourceParagraphRequiredField { static const std::string SOURCE = "Source"; @@ -25,6 +25,7 @@ namespace vcpkg static const std::string MAINTAINER = "Maintainer"; static const std::string BUILD_DEPENDS = "Build-Depends"; static const std::string SUPPORTS = "Supports"; + static const std::string DEFAULTFEATURES = "Default-Features"; } static span get_list_of_valid_fields() @@ -40,6 +41,17 @@ namespace vcpkg return valid_fields; } + namespace FeatureParagraphRequiredField + { + static const std::string FEATURE = "Feature"; + } + + namespace FeatureParagraphOptionalField + { + static const std::string DESCRIPTION = "Description"; + static const std::string BUILD_DEPENDS = "Build-Depends"; + } + void print_error_message(span error_info_list) { Checks::check_exit(VCPKG_LINE_INFO, error_info_list.size() > 0); @@ -74,11 +86,22 @@ namespace vcpkg System::println("Different source may be available for vcpkg. Use .\\bootstrap-vcpkg.bat to update.\n"); } } + std::vector getSourceParagraphs(const std::vector& control_files) + { + return Util::fmap(control_files, [](const SourceControlFile& x) { return x.core_paragraph; }); + } - ExpectedT SourceParagraph::parse_control_file( - std::unordered_map fields) + ExpectedT SourceControlFile::parse_control_file( + std::vector>&& control_paragraphs) { - SourceParagraph sparagraph; + if (control_paragraphs.size() == 0) + { + return ExpectedT(); + } + auto&& fields = control_paragraphs.front(); + + SourceControlFile control_file; + SourceParagraph& sparagraph = control_file.core_paragraph; sparagraph.name = details::remove_required_field(&fields, SourceParagraphRequiredField::SOURCE); sparagraph.version = details::remove_required_field(&fields, SourceParagraphRequiredField::VERSION); sparagraph.description = details::remove_optional_field(&fields, SourceParagraphOptionalField::DESCRIPTION); @@ -90,6 +113,9 @@ namespace vcpkg std::string sups = details::remove_optional_field(&fields, SourceParagraphOptionalField::SUPPORTS); sparagraph.supports = parse_comma_list(sups); + sparagraph.default_features = + details::remove_optional_field(&fields, SourceParagraphOptionalField::DEFAULTFEATURES); + if (!fields.empty()) { const std::vector remaining_fields = Maps::extract_keys(fields); @@ -98,7 +124,33 @@ namespace vcpkg return ParseControlErrorInfo{sparagraph.name, remaining_fields_as_string}; } - return sparagraph; + + control_paragraphs.erase(control_paragraphs.begin()); + + for (auto&& feature_pgh : control_paragraphs) + { + control_file.feature_paragraphs.emplace_back(std::make_unique()); + + FeatureParagraph& fparagraph = *control_file.feature_paragraphs.back(); + + fparagraph.name = details::remove_required_field(&feature_pgh, FeatureParagraphRequiredField::FEATURE); + fparagraph.description = + details::remove_required_field(&feature_pgh, FeatureParagraphOptionalField::DESCRIPTION); + std::string feature_deps = + details::remove_optional_field(&feature_pgh, FeatureParagraphOptionalField::BUILD_DEPENDS); + fparagraph.depends = expand_qualified_dependencies(parse_comma_list(feature_deps)); + + if (!feature_pgh.empty()) + { + const std::vector remaining_fields = Maps::extract_keys(feature_pgh); + + const std::string remaining_fields_as_string = Strings::join("\n ", remaining_fields); + + return ParseControlErrorInfo{sparagraph.name, remaining_fields_as_string}; + } + } + + return control_file; } std::vector vcpkg::expand_qualified_dependencies(const std::vector& depends) diff --git a/toolsrc/src/VcpkgCmdArguments.cpp b/toolsrc/src/VcpkgCmdArguments.cpp index 733308cb0..62e0b114c 100644 --- a/toolsrc/src/VcpkgCmdArguments.cpp +++ b/toolsrc/src/VcpkgCmdArguments.cpp @@ -117,6 +117,11 @@ namespace vcpkg parse_switch(false, "printmetrics", args.printmetrics); continue; } + if (arg == "--featurepackages") + { + g_feature_packages = true; + continue; + } args.optional_command_arguments.insert(arg); continue; diff --git a/toolsrc/src/commands_build.cpp b/toolsrc/src/commands_build.cpp index 5a5cd462e..a9e4f574e 100644 --- a/toolsrc/src/commands_build.cpp +++ b/toolsrc/src/commands_build.cpp @@ -19,11 +19,12 @@ namespace vcpkg::Commands::BuildCommand static const std::string OPTION_CHECKS_ONLY = "--checks-only"; - void perform_and_exit(const PackageSpec& spec, + void perform_and_exit(const FullPackageSpec& full_spec, const fs::path& port_dir, const std::unordered_set& options, const VcpkgPaths& paths) { + const PackageSpec& spec = full_spec.package_spec; if (options.find(OPTION_CHECKS_ONLY) != options.end()) { auto pre_build_info = Build::PreBuildInfo::from_triplet_file(paths, spec.triplet()); @@ -33,25 +34,32 @@ namespace vcpkg::Commands::BuildCommand Checks::exit_success(VCPKG_LINE_INFO); } - const ExpectedT maybe_spgh = + const ExpectedT source_control_file = Paragraphs::try_load_port(paths.get_filesystem(), port_dir); - if (!maybe_spgh) + if (!source_control_file.has_value()) { - print_error_message(maybe_spgh.error()); + print_error_message(source_control_file.error()); Checks::exit_fail(VCPKG_LINE_INFO); } - const SourceParagraph& spgh = maybe_spgh.value_or_exit(VCPKG_LINE_INFO); + for (std::string str : full_spec.features) + { + System::println("%s \n", str); + } + const SourceControlFile& scf = source_control_file.value_or_exit(VCPKG_LINE_INFO); Checks::check_exit(VCPKG_LINE_INFO, - spec.name() == spgh.name, + spec.name() == scf.core_paragraph.name, "The Name: field inside the CONTROL does not match the port directory: '%s' != '%s'", - spgh.name, + scf.core_paragraph.name, spec.name()); StatusParagraphs status_db = database_load_check(paths); Build::BuildPackageOptions build_package_options{Build::UseHeadVersion::NO, Build::AllowDownloads::YES}; - const Build::BuildPackageConfig build_config{spgh, spec.triplet(), paths.port_dir(spec), build_package_options}; + + const Build::BuildPackageConfig build_config{ + scf.core_paragraph, spec.triplet(), paths.port_dir(spec), build_package_options}; + const auto result = Build::build_package(paths, build_config, status_db); if (result.code == BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES) { @@ -82,11 +90,11 @@ namespace vcpkg::Commands::BuildCommand static const std::string example = Commands::Help::create_example_string("build zlib:x64-windows"); args.check_exact_arg_count( 1, example); // Build only takes a single package and all dependencies must already be installed - const PackageSpec spec = - Input::check_and_get_package_spec(args.command_arguments.at(0), default_triplet, example); - Input::check_triplet(spec.triplet(), paths); + std::string command_argument = args.command_arguments.at(0); + const FullPackageSpec spec = Input::check_and_get_full_package_spec(command_argument, default_triplet, example); + Input::check_triplet(spec.package_spec.triplet(), paths); const std::unordered_set options = args.check_and_get_optional_command_arguments({OPTION_CHECKS_ONLY}); - perform_and_exit(spec, paths.port_dir(spec), options, paths); + perform_and_exit(spec, paths.port_dir(spec.package_spec), options, paths); } } diff --git a/toolsrc/src/commands_build_external.cpp b/toolsrc/src/commands_build_external.cpp index 2712ba0cf..ff70e9cf2 100644 --- a/toolsrc/src/commands_build_external.cpp +++ b/toolsrc/src/commands_build_external.cpp @@ -11,9 +11,9 @@ namespace vcpkg::Commands::BuildExternal static const std::string example = Commands::Help::create_example_string(R"(build_external zlib2 C:\path\to\dir\with\controlfile\)"); args.check_exact_arg_count(2, example); - const PackageSpec spec = - Input::check_and_get_package_spec(args.command_arguments.at(0), default_triplet, example); - Input::check_triplet(spec.triplet(), paths); + const FullPackageSpec spec = + Input::check_and_get_full_package_spec(args.command_arguments.at(0), default_triplet, example); + Input::check_triplet(spec.package_spec.triplet(), paths); const std::unordered_set options = args.check_and_get_optional_command_arguments({}); const fs::path port_dir = args.command_arguments.at(1); diff --git a/toolsrc/src/commands_ci.cpp b/toolsrc/src/commands_ci.cpp index 7e724f3ee..65e44e847 100644 --- a/toolsrc/src/commands_ci.cpp +++ b/toolsrc/src/commands_ci.cpp @@ -20,11 +20,11 @@ namespace vcpkg::Commands::CI const fs::path& ports_directory, const Triplet& triplet) { - auto sources = Paragraphs::load_all_ports(fs, ports_directory); - + auto ports = Paragraphs::load_all_ports(fs, ports_directory); std::vector specs; - for (const SourceParagraph& p : sources) + for (const SourceControlFile& control_file : ports) { + const SourceParagraph& p = control_file.core_paragraph; specs.push_back(PackageSpec::from_name_and_triplet(p.name, triplet).value_or_exit(VCPKG_LINE_INFO)); } diff --git a/toolsrc/src/commands_depends.cpp b/toolsrc/src/commands_depends.cpp index 9db4b7bb1..468bf5d72 100644 --- a/toolsrc/src/commands_depends.cpp +++ b/toolsrc/src/commands_depends.cpp @@ -13,10 +13,11 @@ namespace vcpkg::Commands::DependInfo args.check_exact_arg_count(0, example); args.check_and_get_optional_command_arguments({}); - auto sources = Paragraphs::load_all_ports(paths.get_filesystem(), paths.ports); + const auto source_control_files = Paragraphs::load_all_ports(paths.get_filesystem(), paths.ports); - for (const SourceParagraph& source_paragraph : sources) + for (const SourceControlFile& source_control_file : source_control_files) { + const SourceParagraph& source_paragraph = source_control_file.core_paragraph; auto s = Strings::join(", ", source_paragraph.depends, [](const Dependency& d) { return d.name; }); System::println("%s: %s", source_paragraph.name, s); } diff --git a/toolsrc/src/commands_portsdiff.cpp b/toolsrc/src/commands_portsdiff.cpp index a614d654e..e872c394d 100644 --- a/toolsrc/src/commands_portsdiff.cpp +++ b/toolsrc/src/commands_portsdiff.cpp @@ -97,10 +97,10 @@ namespace vcpkg::Commands::PortsDiff L".vcpkg-root", git_exe.native()); System::cmd_execute_clean(cmd); - const std::vector source_paragraphs = + const std::vector source_control_files = Paragraphs::load_all_ports(paths.get_filesystem(), temp_checkout_path / ports_dir_name_as_string); const std::map names_and_versions = - Paragraphs::extract_port_names_and_versions(source_paragraphs); + Paragraphs::extract_port_names_and_versions(getSourceParagraphs(source_control_files)); fs.remove_all(temp_checkout_path, ec); return names_and_versions; } diff --git a/toolsrc/src/commands_search.cpp b/toolsrc/src/commands_search.cpp index 0f8ebbb3b..b39d21887 100644 --- a/toolsrc/src/commands_search.cpp +++ b/toolsrc/src/commands_search.cpp @@ -19,15 +19,16 @@ namespace vcpkg::Commands::Search return output; } - static std::string create_graph_as_string(const std::vector& source_paragraphs) + static std::string create_graph_as_string(const std::vector& source_control_files) { int empty_node_count = 0; std::string s; s.append("digraph G{ rankdir=LR; edge [minlen=3]; overlap=false;"); - for (const SourceParagraph& source_paragraph : source_paragraphs) + for (const SourceControlFile& source_control_file : source_control_files) { + const SourceParagraph& source_paragraph = source_control_file.core_paragraph; if (source_paragraph.depends.empty()) { empty_node_count++; @@ -46,10 +47,9 @@ namespace vcpkg::Commands::Search s.append(Strings::format("empty [label=\"%d singletons...\"]; }", empty_node_count)); return s; } - - static void do_print(const SourceParagraph& source_paragraph, bool FullDesc) + static void do_print(const SourceParagraph& source_paragraph, bool full_desc) { - if (FullDesc) + if (full_desc) { System::println( "%-20s %-16s %s", source_paragraph.name, source_paragraph.version, source_paragraph.description); @@ -63,6 +63,20 @@ namespace vcpkg::Commands::Search } } + static void do_print(const std::string& name, const FeatureParagraph& feature_paragraph, bool full_desc) + { + if (full_desc) + { + System::println("%-37s %s", name + "[" + feature_paragraph.name + "]", feature_paragraph.description); + } + else + { + System::println("%-37s %s", + name + "[" + feature_paragraph.name + "]", + details::shorten_description(feature_paragraph.description)); + } + } + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { static const std::string example = Strings::format( @@ -85,7 +99,7 @@ namespace vcpkg::Commands::Search for (auto&& error : sources_and_errors.errors) { System::println( - System::Color::warning, "Warning: an error occurred while parsing '%s'\n", error.name); + System::Color::warning, "Warning: an error occurred while parsing '%s'", error.name); } System::println(System::Color::warning, "Use '--debug' to get more information about the parse failures.\n"); @@ -93,7 +107,6 @@ namespace vcpkg::Commands::Search } auto& source_paragraphs = sources_and_errors.paragraphs; - if (options.find(OPTION_GRAPH) != options.cend()) { const std::string graph_as_string = create_graph_as_string(source_paragraphs); @@ -103,27 +116,41 @@ namespace vcpkg::Commands::Search if (args.command_arguments.empty()) { - for (const SourceParagraph& source_paragraph : source_paragraphs) + for (const SourceControlFile& source_control_file : source_paragraphs) { - do_print(source_paragraph, options.find(OPTION_FULLDESC) != options.cend()); + do_print(source_control_file.core_paragraph, options.find(OPTION_FULLDESC) != options.cend()); + for (auto&& feature_paragraph : source_control_file.feature_paragraphs) + { + do_print(source_control_file.core_paragraph.name, + *feature_paragraph, + options.find(OPTION_FULLDESC) != options.cend()); + } } } else { + const auto& icontains = Strings::case_insensitive_ascii_contains; + // At this point there is 1 argument - for (const SourceParagraph& source_paragraph : source_paragraphs) + auto&& args_zero = args.command_arguments[0]; + for (const SourceControlFile& source_control_file : source_paragraphs) { - if (Strings::case_insensitive_ascii_find(source_paragraph.name, args.command_arguments[0]) == - source_paragraph.name.end()) + auto&& sp = source_control_file.core_paragraph; + + bool contains_name = icontains(sp.name, args_zero); + if (contains_name || icontains(sp.description, args_zero)) { - if (Strings::case_insensitive_ascii_find(source_paragraph.description, args.command_arguments[0]) == - source_paragraph.description.end()) + do_print(sp, options.find(OPTION_FULLDESC) != options.cend()); + } + + for (auto&& feature_paragraph : source_control_file.feature_paragraphs) + { + if (contains_name || icontains(feature_paragraph->name, args_zero) || + icontains(feature_paragraph->description, args_zero)) { - continue; + do_print(sp.name, *feature_paragraph, options.find(OPTION_FULLDESC) != options.cend()); } } - - do_print(source_paragraph, options.find(OPTION_FULLDESC) != options.cend()); } } diff --git a/toolsrc/src/commands_update.cpp b/toolsrc/src/commands_update.cpp index f87ccfb06..f00a89da4 100644 --- a/toolsrc/src/commands_update.cpp +++ b/toolsrc/src/commands_update.cpp @@ -15,8 +15,8 @@ namespace vcpkg::Commands::Update std::vector find_outdated_packages(const VcpkgPaths& paths, const StatusParagraphs& status_db) { - const std::vector source_paragraphs = - Paragraphs::load_all_ports(paths.get_filesystem(), paths.ports); + auto source_control_files = Paragraphs::load_all_ports(paths.get_filesystem(), paths.ports); + const std::vector source_paragraphs = getSourceParagraphs(source_control_files); const std::map src_names_to_versions = Paragraphs::extract_port_names_and_versions(source_paragraphs); const std::vector installed_packages = get_installed_ports(status_db); diff --git a/toolsrc/src/tests_paragraph.cpp b/toolsrc/src/tests_paragraph.cpp index 374e4ddd1..8dff520fb 100644 --- a/toolsrc/src/tests_paragraph.cpp +++ b/toolsrc/src/tests_paragraph.cpp @@ -25,99 +25,107 @@ namespace UnitTest1 { TEST_METHOD(SourceParagraph_Construct_Minimum) { - auto m_pgh = vcpkg::SourceParagraph::parse_control_file({{"Source", "zlib"}, {"Version", "1.2.8"}}); + auto m_pgh = + vcpkg::SourceControlFile::parse_control_file(std::vector>{{ + {"Source", "zlib"}, {"Version", "1.2.8"}, + }}); Assert::IsTrue(m_pgh.has_value()); auto& pgh = *m_pgh.get(); - Assert::AreEqual("zlib", pgh.name.c_str()); - Assert::AreEqual("1.2.8", pgh.version.c_str()); - Assert::AreEqual("", pgh.maintainer.c_str()); - Assert::AreEqual("", pgh.description.c_str()); - Assert::AreEqual(size_t(0), pgh.depends.size()); + Assert::AreEqual("zlib", pgh.core_paragraph.name.c_str()); + Assert::AreEqual("1.2.8", pgh.core_paragraph.version.c_str()); + Assert::AreEqual("", pgh.core_paragraph.maintainer.c_str()); + Assert::AreEqual("", pgh.core_paragraph.description.c_str()); + Assert::AreEqual(size_t(0), pgh.core_paragraph.depends.size()); } TEST_METHOD(SourceParagraph_Construct_Maximum) { - auto m_pgh = vcpkg::SourceParagraph::parse_control_file({ - {"Source", "s"}, - {"Version", "v"}, - {"Maintainer", "m"}, - {"Description", "d"}, - {"Build-Depends", "bd"}, - {"Supports", "x64"}, - }); + auto m_pgh = + vcpkg::SourceControlFile::parse_control_file(std::vector>{{ + {"Source", "s"}, + {"Version", "v"}, + {"Maintainer", "m"}, + {"Description", "d"}, + {"Build-Depends", "bd"}, + {"Supports", "x64"}, + }}); Assert::IsTrue(m_pgh.has_value()); auto& pgh = *m_pgh.get(); - Assert::AreEqual("s", pgh.name.c_str()); - Assert::AreEqual("v", pgh.version.c_str()); - Assert::AreEqual("m", pgh.maintainer.c_str()); - Assert::AreEqual("d", pgh.description.c_str()); - Assert::AreEqual(size_t(1), pgh.depends.size()); - Assert::AreEqual("bd", pgh.depends[0].name.c_str()); - Assert::AreEqual(size_t(1), pgh.supports.size()); - Assert::AreEqual("x64", pgh.supports[0].c_str()); + Assert::AreEqual("s", pgh.core_paragraph.name.c_str()); + Assert::AreEqual("v", pgh.core_paragraph.version.c_str()); + Assert::AreEqual("m", pgh.core_paragraph.maintainer.c_str()); + Assert::AreEqual("d", pgh.core_paragraph.description.c_str()); + Assert::AreEqual(size_t(1), pgh.core_paragraph.depends.size()); + Assert::AreEqual("bd", pgh.core_paragraph.depends[0].name.c_str()); + Assert::AreEqual(size_t(1), pgh.core_paragraph.supports.size()); + Assert::AreEqual("x64", pgh.core_paragraph.supports[0].c_str()); } TEST_METHOD(SourceParagraph_Two_Depends) { - auto m_pgh = vcpkg::SourceParagraph::parse_control_file({ - {"Source", "zlib"}, {"Version", "1.2.8"}, {"Build-Depends", "z, openssl"}, - }); + auto m_pgh = + vcpkg::SourceControlFile::parse_control_file(std::vector>{{ + {"Source", "zlib"}, {"Version", "1.2.8"}, {"Build-Depends", "z, openssl"}, + }}); Assert::IsTrue(m_pgh.has_value()); auto& pgh = *m_pgh.get(); - Assert::AreEqual(size_t(2), pgh.depends.size()); - Assert::AreEqual("z", pgh.depends[0].name.c_str()); - Assert::AreEqual("openssl", pgh.depends[1].name.c_str()); + Assert::AreEqual(size_t(2), pgh.core_paragraph.depends.size()); + Assert::AreEqual("z", pgh.core_paragraph.depends[0].name.c_str()); + Assert::AreEqual("openssl", pgh.core_paragraph.depends[1].name.c_str()); } TEST_METHOD(SourceParagraph_Three_Depends) { - auto m_pgh = vcpkg::SourceParagraph::parse_control_file({ - {"Source", "zlib"}, {"Version", "1.2.8"}, {"Build-Depends", "z, openssl, xyz"}, - }); + auto m_pgh = + vcpkg::SourceControlFile::parse_control_file(std::vector>{{ + {"Source", "zlib"}, {"Version", "1.2.8"}, {"Build-Depends", "z, openssl, xyz"}, + }}); Assert::IsTrue(m_pgh.has_value()); auto& pgh = *m_pgh.get(); - Assert::AreEqual(size_t(3), pgh.depends.size()); - Assert::AreEqual("z", pgh.depends[0].name.c_str()); - Assert::AreEqual("openssl", pgh.depends[1].name.c_str()); - Assert::AreEqual("xyz", pgh.depends[2].name.c_str()); + Assert::AreEqual(size_t(3), pgh.core_paragraph.depends.size()); + Assert::AreEqual("z", pgh.core_paragraph.depends[0].name.c_str()); + Assert::AreEqual("openssl", pgh.core_paragraph.depends[1].name.c_str()); + Assert::AreEqual("xyz", pgh.core_paragraph.depends[2].name.c_str()); } TEST_METHOD(SourceParagraph_Three_Supports) { - auto m_pgh = vcpkg::SourceParagraph::parse_control_file({ - {"Source", "zlib"}, {"Version", "1.2.8"}, {"Supports", "x64, windows, uwp"}, - }); + auto m_pgh = + vcpkg::SourceControlFile::parse_control_file(std::vector>{{ + {"Source", "zlib"}, {"Version", "1.2.8"}, {"Supports", "x64, windows, uwp"}, + }}); Assert::IsTrue(m_pgh.has_value()); auto& pgh = *m_pgh.get(); - Assert::AreEqual(size_t(3), pgh.supports.size()); - Assert::AreEqual("x64", pgh.supports[0].c_str()); - Assert::AreEqual("windows", pgh.supports[1].c_str()); - Assert::AreEqual("uwp", pgh.supports[2].c_str()); + Assert::AreEqual(size_t(3), pgh.core_paragraph.supports.size()); + Assert::AreEqual("x64", pgh.core_paragraph.supports[0].c_str()); + Assert::AreEqual("windows", pgh.core_paragraph.supports[1].c_str()); + Assert::AreEqual("uwp", pgh.core_paragraph.supports[2].c_str()); } TEST_METHOD(SourceParagraph_Construct_Qualified_Depends) { - auto m_pgh = vcpkg::SourceParagraph::parse_control_file({ - {"Source", "zlib"}, {"Version", "1.2.8"}, {"Build-Depends", "libA [windows], libB [uwp]"}, - }); + auto m_pgh = + vcpkg::SourceControlFile::parse_control_file(std::vector>{{ + {"Source", "zlib"}, {"Version", "1.2.8"}, {"Build-Depends", "libA [windows], libB [uwp]"}, + }}); Assert::IsTrue(m_pgh.has_value()); auto& pgh = *m_pgh.get(); - Assert::AreEqual("zlib", pgh.name.c_str()); - Assert::AreEqual("1.2.8", pgh.version.c_str()); - Assert::AreEqual("", pgh.maintainer.c_str()); - Assert::AreEqual("", pgh.description.c_str()); - Assert::AreEqual(size_t(2), pgh.depends.size()); - Assert::AreEqual("libA", pgh.depends[0].name.c_str()); - Assert::AreEqual("windows", pgh.depends[0].qualifier.c_str()); - Assert::AreEqual("libB", pgh.depends[1].name.c_str()); - Assert::AreEqual("uwp", pgh.depends[1].qualifier.c_str()); + Assert::AreEqual("zlib", pgh.core_paragraph.name.c_str()); + Assert::AreEqual("1.2.8", pgh.core_paragraph.version.c_str()); + Assert::AreEqual("", pgh.core_paragraph.maintainer.c_str()); + Assert::AreEqual("", pgh.core_paragraph.description.c_str()); + Assert::AreEqual(size_t(2), pgh.core_paragraph.depends.size()); + Assert::AreEqual("libA", pgh.core_paragraph.depends[0].name.c_str()); + Assert::AreEqual("windows", pgh.core_paragraph.depends[0].qualifier.c_str()); + Assert::AreEqual("libB", pgh.core_paragraph.depends[1].name.c_str()); + Assert::AreEqual("uwp", pgh.core_paragraph.depends[1].qualifier.c_str()); } TEST_METHOD(BinaryParagraph_Construct_Minimum) diff --git a/toolsrc/src/vcpkg_Dependencies.cpp b/toolsrc/src/vcpkg_Dependencies.cpp index f32d92f4c..add8acb4d 100644 --- a/toolsrc/src/vcpkg_Dependencies.cpp +++ b/toolsrc/src/vcpkg_Dependencies.cpp @@ -174,12 +174,12 @@ namespace vcpkg::Dependencies if (auto bpgh = maybe_bpgh.get()) return InstallPlanAction{spec, {nullopt, *bpgh, nullopt}, request_type}; - ExpectedT maybe_spgh = + ExpectedT source_control_file = 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}; + if (auto scf = source_control_file.get()) + return InstallPlanAction{spec, {nullopt, nullopt, (*scf).core_paragraph}, request_type}; - print_error_message(maybe_spgh.error()); + print_error_message(source_control_file.error()); Checks::exit_fail(VCPKG_LINE_INFO); } }; @@ -284,13 +284,13 @@ namespace vcpkg::Dependencies if (auto bpgh = maybe_bpgh.get()) return ExportPlanAction{spec, {nullopt, *bpgh, nullopt}, request_type}; - ExpectedT maybe_spgh = + ExpectedT source_control_file = Paragraphs::try_load_port(paths.get_filesystem(), paths.port_dir(spec)); - if (auto spgh = maybe_spgh.get()) - return ExportPlanAction{spec, {nullopt, nullopt, *spgh}, request_type}; + if (auto scf = source_control_file.get()) + return ExportPlanAction{spec, {nullopt, nullopt, (*scf).core_paragraph}, request_type}; else - print_error_message(maybe_spgh.error()); + print_error_message(source_control_file.error()); Checks::exit_with_message(VCPKG_LINE_INFO, "Could not find package %s", spec); } diff --git a/toolsrc/src/vcpkg_Input.cpp b/toolsrc/src/vcpkg_Input.cpp index df738315b..fdedd5507 100644 --- a/toolsrc/src/vcpkg_Input.cpp +++ b/toolsrc/src/vcpkg_Input.cpp @@ -15,7 +15,7 @@ namespace vcpkg::Input auto expected_spec = PackageSpec::from_string(as_lowercase, default_triplet); if (auto spec = expected_spec.get()) { - return *spec; + return PackageSpec{*spec}; } // Intentionally show the lowercased string @@ -34,4 +34,36 @@ namespace vcpkg::Input Checks::exit_fail(VCPKG_LINE_INFO); } } + + FullPackageSpec check_and_get_full_package_spec(const std::string& full_package_spec_as_string, + const Triplet& default_triplet, + CStringView example_text) + { + int left_pos = (int)full_package_spec_as_string.find('['); + if (left_pos == std::string::npos) + { + return FullPackageSpec{ + check_and_get_package_spec(full_package_spec_as_string, default_triplet, example_text)}; + } + int right_pos = (int)full_package_spec_as_string.find(']'); + if (left_pos >= right_pos) + { + System::println(System::Color::error, "Error: Argument is not formatted correctly \"%s\""); + Checks::exit_fail(VCPKG_LINE_INFO); + } + + std::string package_spec_as_string = full_package_spec_as_string.substr(0, left_pos); + const std::string as_lowercase = Strings::ascii_to_lowercase(package_spec_as_string); + auto expected_spec = PackageSpec::from_string(as_lowercase, default_triplet); + if (auto&& spec = expected_spec.get()) + { + return {*spec, + parse_comma_list(full_package_spec_as_string.substr(left_pos + 1, right_pos - left_pos - 1))}; + } + + // Intentionally show the lowercased string + System::println(System::Color::error, "Error: %s: %s", vcpkg::to_string(expected_spec.error()), as_lowercase); + System::print(example_text); + Checks::exit_fail(VCPKG_LINE_INFO); + } } diff --git a/toolsrc/src/vcpkg_Strings.cpp b/toolsrc/src/vcpkg_Strings.cpp index 9ba9eb700..aafed5fd3 100644 --- a/toolsrc/src/vcpkg_Strings.cpp +++ b/toolsrc/src/vcpkg_Strings.cpp @@ -68,6 +68,11 @@ namespace vcpkg::Strings [](const char a, const char b) { return details::tolower_char(a) == b; }); } + bool case_insensitive_ascii_contains(const std::string& s, const std::string& pattern) + { + return case_insensitive_ascii_find(s, pattern) != s.end(); + } + int case_insensitive_ascii_compare(const CStringView left, const CStringView right) { return _stricmp(left, right); -- cgit v1.2.3 From 8741214bf69d1209a1e6d405ed8561d27f04436a Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Sat, 17 Jun 2017 02:39:14 -0700 Subject: [vcpkg] Use unique_ptr<> for paragraphs. Post-parser phase rework. --- toolsrc/include/Paragraphs.h | 28 +++--- toolsrc/include/SourceParagraph.h | 24 ++--- toolsrc/include/StatusParagraph.h | 2 +- toolsrc/include/vcpkg_Build.h | 10 +- toolsrc/include/vcpkg_Parse.h | 36 ++++++++ toolsrc/include/vcpkg_expected.h | 6 +- toolsrc/include/vcpkglib.h | 1 + toolsrc/include/vcpkglib_helpers.h | 18 ---- toolsrc/src/BinaryParagraph.cpp | 46 +++++---- toolsrc/src/Paragraphs.cpp | 38 ++++---- toolsrc/src/SourceParagraph.cpp | 149 ++++++++++++++---------------- toolsrc/src/StatusParagraph.cpp | 12 ++- toolsrc/src/commands_build.cpp | 12 ++- toolsrc/src/commands_ci.cpp | 13 +-- toolsrc/src/commands_depends.cpp | 4 +- toolsrc/src/commands_list.cpp | 3 +- toolsrc/src/commands_portsdiff.cpp | 6 +- toolsrc/src/commands_search.cpp | 28 +++--- toolsrc/src/commands_update.cpp | 7 +- toolsrc/src/tests_paragraph.cpp | 66 ++++++------- toolsrc/src/vcpkg_Build.cpp | 83 ++++++++--------- toolsrc/src/vcpkg_Build_BuildPolicy.cpp | 11 --- toolsrc/src/vcpkg_Dependencies.cpp | 19 ++-- toolsrc/src/vcpkg_Parse.cpp | 59 ++++++++++++ toolsrc/src/vcpkglib.cpp | 10 +- toolsrc/src/vcpkglib_helpers.cpp | 56 ----------- toolsrc/vcpkglib/vcpkglib.vcxproj | 4 +- toolsrc/vcpkglib/vcpkglib.vcxproj.filters | 12 +-- 28 files changed, 387 insertions(+), 376 deletions(-) create mode 100644 toolsrc/include/vcpkg_Parse.h delete mode 100644 toolsrc/include/vcpkglib_helpers.h create mode 100644 toolsrc/src/vcpkg_Parse.cpp delete mode 100644 toolsrc/src/vcpkglib_helpers.cpp (limited to 'toolsrc') diff --git a/toolsrc/include/Paragraphs.h b/toolsrc/include/Paragraphs.h index 83a32b2af..60f509266 100644 --- a/toolsrc/include/Paragraphs.h +++ b/toolsrc/include/Paragraphs.h @@ -1,36 +1,38 @@ #pragma once +#include + #include "BinaryParagraph.h" #include "VcpkgPaths.h" #include "VersionT.h" #include "filesystem_fs.h" +#include "vcpkg_Parse.h" #include "vcpkg_expected.h" -#include namespace vcpkg::Paragraphs { - using ParagraphDataMap = std::unordered_map; + using RawParagraph = Parse::RawParagraph; - Expected get_single_paragraph(const Files::Filesystem& fs, const fs::path& control_path); - Expected> get_paragraphs(const Files::Filesystem& fs, const fs::path& control_path); - Expected parse_single_paragraph(const std::string& str); - Expected> parse_paragraphs(const std::string& str); + Expected get_single_paragraph(const Files::Filesystem& fs, const fs::path& control_path); + Expected> get_paragraphs(const Files::Filesystem& fs, const fs::path& control_path); + Expected parse_single_paragraph(const std::string& str); + Expected> parse_paragraphs(const std::string& str); - ExpectedT try_load_port(const Files::Filesystem& fs, - const fs::path& control_path); + Parse::ParseExpected try_load_port(const Files::Filesystem& fs, const fs::path& control_path); Expected try_load_cached_package(const VcpkgPaths& paths, const PackageSpec& spec); struct LoadResults { - std::vector paragraphs; - std::vector errors; + std::vector> paragraphs; + std::vector> errors; }; LoadResults try_load_all_ports(const Files::Filesystem& fs, const fs::path& ports_dir); - std::vector load_all_ports(const Files::Filesystem& fs, const fs::path& ports_dir); + std::vector> load_all_ports(const Files::Filesystem& fs, + const fs::path& ports_dir); - std::map extract_port_names_and_versions( - const std::vector& source_paragraphs); + std::map load_all_port_names_and_versions(const Files::Filesystem& fs, + const fs::path& ports_dir); } diff --git a/toolsrc/include/SourceParagraph.h b/toolsrc/include/SourceParagraph.h index 31c9560cc..e85884b51 100644 --- a/toolsrc/include/SourceParagraph.h +++ b/toolsrc/include/SourceParagraph.h @@ -1,6 +1,7 @@ #pragma once #include "Span.h" +#include "vcpkg_Parse.h" #include "vcpkg_System.h" #include "vcpkg_expected.h" @@ -22,13 +23,6 @@ namespace vcpkg const std::string& to_string(const Dependency& dep); - struct ParseControlErrorInfo - { - std::string name; - std::string remaining_fields_as_string; - std::error_code error; - }; - struct FeatureParagraph { std::string name; @@ -47,23 +41,19 @@ namespace vcpkg std::string maintainer; std::vector supports; std::vector depends; - std::string default_features; + std::vector default_features; }; struct SourceControlFile { - static ExpectedT parse_control_file( - std::vector>&& control_paragraphs); + static Parse::ParseExpected parse_control_file( + std::vector&& control_paragraphs); - SourceParagraph core_paragraph; + std::unique_ptr core_paragraph; std::vector> feature_paragraphs; - - std::vector errors; }; - std::vector getSourceParagraphs(const std::vector& control_files); - - void print_error_message(span error_info_list); - inline void print_error_message(const ParseControlErrorInfo& error_info_list) + void print_error_message(span> error_info_list); + inline void print_error_message(const std::unique_ptr& error_info_list) { return print_error_message({&error_info_list, 1}); } diff --git a/toolsrc/include/StatusParagraph.h b/toolsrc/include/StatusParagraph.h index 2d1815dc0..b56533d65 100644 --- a/toolsrc/include/StatusParagraph.h +++ b/toolsrc/include/StatusParagraph.h @@ -29,7 +29,7 @@ namespace vcpkg struct StatusParagraph { StatusParagraph(); - explicit StatusParagraph(const std::unordered_map& fields); + explicit StatusParagraph(std::unordered_map&& fields); BinaryParagraph package; Want want; diff --git a/toolsrc/include/vcpkg_Build.h b/toolsrc/include/vcpkg_Build.h index e13f66029..9a4e2baeb 100644 --- a/toolsrc/include/vcpkg_Build.h +++ b/toolsrc/include/vcpkg_Build.h @@ -120,14 +120,20 @@ namespace vcpkg::Build COUNT, }; - Optional to_build_policy(const std::string& str); + constexpr std::array g_all_policies = { + BuildPolicy::EMPTY_PACKAGE, + BuildPolicy::DLLS_WITHOUT_LIBS, + BuildPolicy::ONLY_RELEASE_CRT, + BuildPolicy::EMPTY_INCLUDE_FOLDER, + BuildPolicy::ALLOW_OBSOLETE_MSVCRT, + }; const std::string& to_string(BuildPolicy policy); CStringView to_cmake_variable(BuildPolicy policy); struct BuildPolicies { - BuildPolicies() {} + BuildPolicies() = default; BuildPolicies(std::map&& map) : m_policies(std::move(map)) {} inline bool is_enabled(BuildPolicy policy) const diff --git a/toolsrc/include/vcpkg_Parse.h b/toolsrc/include/vcpkg_Parse.h new file mode 100644 index 000000000..a2eb152dc --- /dev/null +++ b/toolsrc/include/vcpkg_Parse.h @@ -0,0 +1,36 @@ +#pragma once + +#include +#include + +#include "vcpkg_expected.h" +#include "vcpkg_optional.h" + +namespace vcpkg::Parse +{ + struct ParseControlErrorInfo + { + std::string name; + std::vector missing_fields; + std::vector extra_fields; + std::error_code error; + }; + + template + using ParseExpected = ExpectedT, std::unique_ptr>; + + using RawParagraph = std::unordered_map; + + struct ParagraphParser + { + ParagraphParser(RawParagraph&& fields) : fields(std::move(fields)) {} + + void required_field(const std::string& fieldname, std::string& out); + std::string optional_field(const std::string& fieldname); + std::unique_ptr error_info(const std::string& name) const; + + private: + RawParagraph&& fields; + std::vector missing_fields; + }; +} diff --git a/toolsrc/include/vcpkg_expected.h b/toolsrc/include/vcpkg_expected.h index 15dbf5e79..9637ec087 100644 --- a/toolsrc/include/vcpkg_expected.h +++ b/toolsrc/include/vcpkg_expected.h @@ -9,8 +9,10 @@ namespace vcpkg struct ErrorHolder { ErrorHolder() : m_is_error(false) {} - ErrorHolder(const Err& err) : m_is_error(true), m_err(err) {} - ErrorHolder(Err&& err) : m_is_error(true), m_err(std::move(err)) {} + template + ErrorHolder(U&& err) : m_is_error(true), m_err(std::forward(err)) + { + } constexpr bool has_error() const { return m_is_error; } diff --git a/toolsrc/include/vcpkglib.h b/toolsrc/include/vcpkglib.h index df64e5463..bd2400b77 100644 --- a/toolsrc/include/vcpkglib.h +++ b/toolsrc/include/vcpkglib.h @@ -36,4 +36,5 @@ namespace vcpkg const fs::path& cmake_script, const std::vector& pass_variables); + std::string shorten_description(const std::string& desc); } // namespace vcpkg diff --git a/toolsrc/include/vcpkglib_helpers.h b/toolsrc/include/vcpkglib_helpers.h deleted file mode 100644 index a8ddcde4d..000000000 --- a/toolsrc/include/vcpkglib_helpers.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include - -namespace vcpkg::details -{ - std::string optional_field(const std::unordered_map& fields, - const std::string& fieldname); - std::string remove_optional_field(std::unordered_map* fields, - const std::string& fieldname); - - std::string required_field(const std::unordered_map& fields, - const std::string& fieldname); - std::string remove_required_field(std::unordered_map* fields, - const std::string& fieldname); - - std::string shorten_description(const std::string& desc); -} diff --git a/toolsrc/src/BinaryParagraph.cpp b/toolsrc/src/BinaryParagraph.cpp index 21980cd7d..af76c6b29 100644 --- a/toolsrc/src/BinaryParagraph.cpp +++ b/toolsrc/src/BinaryParagraph.cpp @@ -2,13 +2,11 @@ #include "BinaryParagraph.h" #include "vcpkg_Checks.h" -#include "vcpkglib_helpers.h" - -using namespace vcpkg::details; +#include "vcpkg_Parse.h" namespace vcpkg { - namespace BinaryParagraphRequiredField + namespace Fields { static const std::string PACKAGE = "Package"; static const std::string VERSION = "Version"; @@ -16,7 +14,7 @@ namespace vcpkg static const std::string MULTI_ARCH = "Multi-Arch"; } - namespace BinaryParagraphOptionalField + namespace Fields { static const std::string DESCRIPTION = "Description"; static const std::string MAINTAINER = "Maintainer"; @@ -27,22 +25,36 @@ namespace vcpkg BinaryParagraph::BinaryParagraph(std::unordered_map fields) { - const std::string name = details::remove_required_field(&fields, BinaryParagraphRequiredField::PACKAGE); - const std::string architecture = - details::remove_required_field(&fields, BinaryParagraphRequiredField::ARCHITECTURE); - const Triplet triplet = Triplet::from_canonical_name(architecture); + using namespace vcpkg::Parse; - this->spec = PackageSpec::from_name_and_triplet(name, triplet).value_or_exit(VCPKG_LINE_INFO); - this->version = details::remove_required_field(&fields, BinaryParagraphRequiredField::VERSION); + ParagraphParser parser(std::move(fields)); - this->description = details::remove_optional_field(&fields, BinaryParagraphOptionalField::DESCRIPTION); - this->maintainer = details::remove_optional_field(&fields, BinaryParagraphOptionalField::MAINTAINER); + { + std::string name; + parser.required_field(Fields::PACKAGE, name); + std::string architecture; + parser.required_field(Fields::ARCHITECTURE, architecture); + this->spec = PackageSpec::from_name_and_triplet(name, Triplet::from_canonical_name(architecture)) + .value_or_exit(VCPKG_LINE_INFO); + } - std::string multi_arch = details::remove_required_field(&fields, BinaryParagraphRequiredField::MULTI_ARCH); - Checks::check_exit(VCPKG_LINE_INFO, multi_arch == "same", "Multi-Arch must be 'same' but was %s", multi_arch); + parser.required_field(Fields::VERSION, this->version); + this->description = parser.optional_field(Fields::DESCRIPTION); + this->maintainer = parser.optional_field(Fields::MAINTAINER); + + std::string multi_arch; + parser.required_field(Fields::MULTI_ARCH, multi_arch); - std::string deps = details::remove_optional_field(&fields, BinaryParagraphOptionalField::DEPENDS); - this->depends = parse_comma_list(deps); + this->depends = parse_comma_list(parser.optional_field(Fields::DEPENDS)); + + if (auto err = parser.error_info(this->spec.name())) + { + print_error_message(err); + Checks::exit_fail(VCPKG_LINE_INFO); + } + + // prefer failing above when possible because it gives better information + Checks::check_exit(VCPKG_LINE_INFO, multi_arch == "same", "Multi-Arch must be 'same' but was %s", multi_arch); } BinaryParagraph::BinaryParagraph(const SourceParagraph& spgh, const Triplet& triplet) diff --git a/toolsrc/src/Paragraphs.cpp b/toolsrc/src/Paragraphs.cpp index 440d04ce4..3749e919e 100644 --- a/toolsrc/src/Paragraphs.cpp +++ b/toolsrc/src/Paragraphs.cpp @@ -4,6 +4,8 @@ #include "Paragraphs.h" #include "vcpkg_Files.h" +using namespace vcpkg::Parse; + namespace vcpkg::Paragraphs { struct Parser @@ -201,9 +203,8 @@ namespace vcpkg::Paragraphs return Parser(str.c_str(), str.c_str() + str.size()).get_paragraphs(); } - ExpectedT try_load_port(const Files::Filesystem& fs, const fs::path& path) + ParseExpected try_load_port(const Files::Filesystem& fs, const fs::path& path) { - ParseControlErrorInfo error_info; Expected>> pghs = get_paragraphs(fs, path / "CONTROL"); if (auto vector_pghs = pghs.get()) { @@ -212,14 +213,16 @@ namespace vcpkg::Paragraphs { if (auto ptr = csf.get()) { - ptr->core_paragraph.default_features.clear(); - ptr->feature_paragraphs.clear(); + Checks::check_exit(VCPKG_LINE_INFO, ptr->get() != nullptr); + ptr->get()->core_paragraph->default_features.clear(); + ptr->get()->feature_paragraphs.clear(); } } return csf; } - error_info.name = path.filename().generic_u8string(); - error_info.error = pghs.error(); + auto error_info = std::make_unique(); + error_info->name = path.filename().generic_u8string(); + error_info->error = pghs.error(); return error_info; } @@ -241,20 +244,21 @@ namespace vcpkg::Paragraphs LoadResults ret; for (auto&& path : fs.get_files_non_recursive(ports_dir)) { - ExpectedT source_paragraph = try_load_port(fs, path); - if (auto srcpgh = source_paragraph.get()) + auto maybe_spgh = try_load_port(fs, path); + if (auto spgh = maybe_spgh.get()) { - ret.paragraphs.emplace_back(std::move(*srcpgh)); + ret.paragraphs.emplace_back(std::move(*spgh)); } else { - ret.errors.emplace_back(source_paragraph.error()); + ret.errors.emplace_back(std::move(maybe_spgh).error()); } } return ret; } - std::vector load_all_ports(const Files::Filesystem& fs, const fs::path& ports_dir) + std::vector> load_all_ports(const Files::Filesystem& fs, + const fs::path& ports_dir) { auto results = try_load_all_ports(fs, ports_dir); if (!results.errors.empty()) @@ -265,14 +269,14 @@ namespace vcpkg::Paragraphs return std::move(results.paragraphs); } - std::map extract_port_names_and_versions( - const std::vector& source_paragraphs) + std::map load_all_port_names_and_versions(const Files::Filesystem& fs, + const fs::path& ports_dir) { + auto all_ports = load_all_ports(fs, ports_dir); + std::map names_and_versions; - for (const SourceParagraph& port : source_paragraphs) - { - names_and_versions.emplace(port.name, port.version); - } + for (auto&& port : all_ports) + names_and_versions.emplace(port->core_paragraph->name, port->core_paragraph->version); return names_and_versions; } diff --git a/toolsrc/src/SourceParagraph.cpp b/toolsrc/src/SourceParagraph.cpp index a938feb99..83b8e2e2d 100644 --- a/toolsrc/src/SourceParagraph.cpp +++ b/toolsrc/src/SourceParagraph.cpp @@ -8,73 +8,56 @@ #include "vcpkg_Util.h" #include "vcpkg_expected.h" -#include "vcpkglib_helpers.h" - namespace vcpkg { - bool g_feature_packages = false; - namespace SourceParagraphRequiredField - { - static const std::string SOURCE = "Source"; - static const std::string VERSION = "Version"; - } + using namespace vcpkg::Parse; - namespace SourceParagraphOptionalField + bool g_feature_packages = false; + namespace Fields { + static const std::string BUILD_DEPENDS = "Build-Depends"; + static const std::string DEFAULTFEATURES = "Default-Features"; static const std::string DESCRIPTION = "Description"; + static const std::string FEATURE = "Feature"; static const std::string MAINTAINER = "Maintainer"; - static const std::string BUILD_DEPENDS = "Build-Depends"; + static const std::string SOURCE = "Source"; static const std::string SUPPORTS = "Supports"; - static const std::string DEFAULTFEATURES = "Default-Features"; + static const std::string VERSION = "Version"; } static span get_list_of_valid_fields() { - static const std::string valid_fields[] = {SourceParagraphRequiredField::SOURCE, - SourceParagraphRequiredField::VERSION, - - SourceParagraphOptionalField::DESCRIPTION, - SourceParagraphOptionalField::MAINTAINER, - SourceParagraphOptionalField::BUILD_DEPENDS, - SourceParagraphOptionalField::SUPPORTS}; + static const std::string valid_fields[] = { + Fields::SOURCE, Fields::VERSION, Fields::DESCRIPTION, Fields::MAINTAINER, Fields::BUILD_DEPENDS, + }; return valid_fields; } - namespace FeatureParagraphRequiredField - { - static const std::string FEATURE = "Feature"; - } - - namespace FeatureParagraphOptionalField - { - static const std::string DESCRIPTION = "Description"; - static const std::string BUILD_DEPENDS = "Build-Depends"; - } - - void print_error_message(span error_info_list) + void print_error_message(span> error_info_list) { Checks::check_exit(VCPKG_LINE_INFO, error_info_list.size() > 0); for (auto&& error_info : error_info_list) { - if (error_info.error) + Checks::check_exit(VCPKG_LINE_INFO, error_info != nullptr); + if (error_info->error) { System::println( - System::Color::error, "Error: while loading %s: %s", error_info.name, error_info.error.message()); + System::Color::error, "Error: while loading %s: %s", error_info->name, error_info->error.message()); } } bool have_remaining_fields = false; for (auto&& error_info : error_info_list) { - if (!error_info.remaining_fields_as_string.empty()) + if (!error_info->extra_fields.empty()) { System::println(System::Color::error, "Error: There are invalid fields in the Source Paragraph of %s", - error_info.name); + error_info->name); System::println("The following fields were not expected:\n\n %s\n\n", - error_info.remaining_fields_as_string); + Strings::join("\n ", error_info->extra_fields)); have_remaining_fields = true; } } @@ -86,71 +69,75 @@ namespace vcpkg System::println("Different source may be available for vcpkg. Use .\\bootstrap-vcpkg.bat to update.\n"); } } - std::vector getSourceParagraphs(const std::vector& control_files) + + static ParseExpected parse_source_paragraph(RawParagraph&& fields) { - return Util::fmap(control_files, [](const SourceControlFile& x) { return x.core_paragraph; }); + ParagraphParser parser(std::move(fields)); + + auto spgh = std::make_unique(); + + parser.required_field(Fields::SOURCE, spgh->name); + parser.required_field(Fields::VERSION, spgh->version); + + spgh->description = parser.optional_field(Fields::DESCRIPTION); + spgh->maintainer = parser.optional_field(Fields::MAINTAINER); + spgh->depends = expand_qualified_dependencies(parse_comma_list(parser.optional_field(Fields::BUILD_DEPENDS))); + spgh->supports = parse_comma_list(parser.optional_field(Fields::SUPPORTS)); + spgh->default_features = parse_comma_list(parser.optional_field(Fields::DEFAULTFEATURES)); + + auto err = parser.error_info(spgh->name); + if (err) + return std::move(err); + else + return std::move(spgh); } - ExpectedT SourceControlFile::parse_control_file( - std::vector>&& control_paragraphs) + static ParseExpected parse_feature_paragraph(RawParagraph&& fields) { - if (control_paragraphs.size() == 0) - { - return ExpectedT(); - } - auto&& fields = control_paragraphs.front(); + ParagraphParser parser(std::move(fields)); - SourceControlFile control_file; - SourceParagraph& sparagraph = control_file.core_paragraph; - sparagraph.name = details::remove_required_field(&fields, SourceParagraphRequiredField::SOURCE); - sparagraph.version = details::remove_required_field(&fields, SourceParagraphRequiredField::VERSION); - sparagraph.description = details::remove_optional_field(&fields, SourceParagraphOptionalField::DESCRIPTION); - sparagraph.maintainer = details::remove_optional_field(&fields, SourceParagraphOptionalField::MAINTAINER); + auto fpgh = std::make_unique(); - std::string deps = details::remove_optional_field(&fields, SourceParagraphOptionalField::BUILD_DEPENDS); - sparagraph.depends = expand_qualified_dependencies(parse_comma_list(deps)); + parser.required_field(Fields::FEATURE, fpgh->name); + parser.required_field(Fields::DESCRIPTION, fpgh->description); - std::string sups = details::remove_optional_field(&fields, SourceParagraphOptionalField::SUPPORTS); - sparagraph.supports = parse_comma_list(sups); + fpgh->depends = expand_qualified_dependencies(parse_comma_list(parser.optional_field(Fields::BUILD_DEPENDS))); - sparagraph.default_features = - details::remove_optional_field(&fields, SourceParagraphOptionalField::DEFAULTFEATURES); + auto err = parser.error_info(fpgh->name); + if (err) + return std::move(err); + else + return std::move(fpgh); + } - if (!fields.empty()) + ParseExpected SourceControlFile::parse_control_file( + std::vector>&& control_paragraphs) + { + if (control_paragraphs.size() == 0) { - const std::vector remaining_fields = Maps::extract_keys(fields); + return std::make_unique(); + } - const std::string remaining_fields_as_string = Strings::join("\n ", remaining_fields); + auto control_file = std::make_unique(); - return ParseControlErrorInfo{sparagraph.name, remaining_fields_as_string}; - } + auto maybe_source = parse_source_paragraph(std::move(control_paragraphs.front())); + if (auto source = maybe_source.get()) + control_file->core_paragraph = std::move(*source); + else + return std::move(maybe_source).error(); control_paragraphs.erase(control_paragraphs.begin()); for (auto&& feature_pgh : control_paragraphs) { - control_file.feature_paragraphs.emplace_back(std::make_unique()); - - FeatureParagraph& fparagraph = *control_file.feature_paragraphs.back(); - - fparagraph.name = details::remove_required_field(&feature_pgh, FeatureParagraphRequiredField::FEATURE); - fparagraph.description = - details::remove_required_field(&feature_pgh, FeatureParagraphOptionalField::DESCRIPTION); - std::string feature_deps = - details::remove_optional_field(&feature_pgh, FeatureParagraphOptionalField::BUILD_DEPENDS); - fparagraph.depends = expand_qualified_dependencies(parse_comma_list(feature_deps)); - - if (!feature_pgh.empty()) - { - const std::vector remaining_fields = Maps::extract_keys(feature_pgh); - - const std::string remaining_fields_as_string = Strings::join("\n ", remaining_fields); - - return ParseControlErrorInfo{sparagraph.name, remaining_fields_as_string}; - } + auto maybe_feature = parse_feature_paragraph(std::move(feature_pgh)); + if (auto feature = maybe_feature.get()) + control_file->feature_paragraphs.emplace_back(std::move(*feature)); + else + return std::move(maybe_feature).error(); } - return control_file; + return std::move(control_file); } std::vector vcpkg::expand_qualified_dependencies(const std::vector& depends) diff --git a/toolsrc/src/StatusParagraph.cpp b/toolsrc/src/StatusParagraph.cpp index b9ceed278..5b5c3978f 100644 --- a/toolsrc/src/StatusParagraph.cpp +++ b/toolsrc/src/StatusParagraph.cpp @@ -1,9 +1,8 @@ #include "pch.h" #include "StatusParagraph.h" -#include "vcpkglib_helpers.h" -using namespace vcpkg::details; +using namespace vcpkg::Parse; namespace vcpkg { @@ -24,9 +23,14 @@ namespace vcpkg .push_back('\n'); } - StatusParagraph::StatusParagraph(const std::unordered_map& fields) : package(fields) + StatusParagraph::StatusParagraph(std::unordered_map&& fields) { - std::string status_field = required_field(fields, BinaryParagraphRequiredField::STATUS); + auto status_it = fields.find(BinaryParagraphRequiredField::STATUS); + Checks::check_exit(VCPKG_LINE_INFO, status_it != fields.end(), "Expected 'Status' field in status paragraph"); + std::string status_field = std::move(status_it->second); + fields.erase(status_it); + + this->package = BinaryParagraph(std::move(fields)); auto b = status_field.begin(); auto mark = b; diff --git a/toolsrc/src/commands_build.cpp b/toolsrc/src/commands_build.cpp index a9e4f574e..4da9cede2 100644 --- a/toolsrc/src/commands_build.cpp +++ b/toolsrc/src/commands_build.cpp @@ -11,6 +11,8 @@ #include "vcpkglib.h" using vcpkg::Build::BuildResult; +using vcpkg::Parse::ParseControlErrorInfo; +using vcpkg::Parse::ParseExpected; namespace vcpkg::Commands::BuildCommand { @@ -34,7 +36,7 @@ namespace vcpkg::Commands::BuildCommand Checks::exit_success(VCPKG_LINE_INFO); } - const ExpectedT source_control_file = + const ParseExpected source_control_file = Paragraphs::try_load_port(paths.get_filesystem(), port_dir); if (!source_control_file.has_value()) @@ -47,18 +49,18 @@ namespace vcpkg::Commands::BuildCommand { System::println("%s \n", str); } - const SourceControlFile& scf = source_control_file.value_or_exit(VCPKG_LINE_INFO); + const auto& scf = source_control_file.value_or_exit(VCPKG_LINE_INFO); Checks::check_exit(VCPKG_LINE_INFO, - spec.name() == scf.core_paragraph.name, + spec.name() == scf->core_paragraph->name, "The Name: field inside the CONTROL does not match the port directory: '%s' != '%s'", - scf.core_paragraph.name, + scf->core_paragraph->name, spec.name()); StatusParagraphs status_db = database_load_check(paths); Build::BuildPackageOptions build_package_options{Build::UseHeadVersion::NO, Build::AllowDownloads::YES}; const Build::BuildPackageConfig build_config{ - scf.core_paragraph, spec.triplet(), paths.port_dir(spec), build_package_options}; + *scf->core_paragraph, spec.triplet(), paths.port_dir(spec), build_package_options}; const auto result = Build::build_package(paths, build_config, status_db); if (result.code == BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES) diff --git a/toolsrc/src/commands_ci.cpp b/toolsrc/src/commands_ci.cpp index 65e44e847..7ffc7577a 100644 --- a/toolsrc/src/commands_ci.cpp +++ b/toolsrc/src/commands_ci.cpp @@ -8,6 +8,7 @@ #include "vcpkg_Files.h" #include "vcpkg_Input.h" #include "vcpkg_System.h" +#include "vcpkg_Util.h" #include "vcpkglib.h" namespace vcpkg::Commands::CI @@ -21,14 +22,10 @@ namespace vcpkg::Commands::CI const Triplet& triplet) { auto ports = Paragraphs::load_all_ports(fs, ports_directory); - std::vector specs; - for (const SourceControlFile& control_file : ports) - { - const SourceParagraph& p = control_file.core_paragraph; - specs.push_back(PackageSpec::from_name_and_triplet(p.name, triplet).value_or_exit(VCPKG_LINE_INFO)); - } - - return specs; + return Util::fmap(ports, [&](auto&& control_file) -> PackageSpec { + return PackageSpec::from_name_and_triplet(control_file->core_paragraph->name, triplet) + .value_or_exit(VCPKG_LINE_INFO); + }); } void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) diff --git a/toolsrc/src/commands_depends.cpp b/toolsrc/src/commands_depends.cpp index 468bf5d72..ccfe58e4e 100644 --- a/toolsrc/src/commands_depends.cpp +++ b/toolsrc/src/commands_depends.cpp @@ -15,9 +15,9 @@ namespace vcpkg::Commands::DependInfo const auto source_control_files = Paragraphs::load_all_ports(paths.get_filesystem(), paths.ports); - for (const SourceControlFile& source_control_file : source_control_files) + for (auto&& source_control_file : source_control_files) { - const SourceParagraph& source_paragraph = source_control_file.core_paragraph; + const SourceParagraph& source_paragraph = *source_control_file->core_paragraph; auto s = Strings::join(", ", source_paragraph.depends, [](const Dependency& d) { return d.name; }); System::println("%s: %s", source_paragraph.name, s); } diff --git a/toolsrc/src/commands_list.cpp b/toolsrc/src/commands_list.cpp index d21883fc2..9bc9bcc08 100644 --- a/toolsrc/src/commands_list.cpp +++ b/toolsrc/src/commands_list.cpp @@ -3,7 +3,6 @@ #include "vcpkg_Commands.h" #include "vcpkg_System.h" #include "vcpkglib.h" -#include "vcpkglib_helpers.h" namespace vcpkg::Commands::List { @@ -20,7 +19,7 @@ namespace vcpkg::Commands::List System::println("%-27s %-16s %s", pgh.package.displayname(), pgh.package.version, - details::shorten_description(pgh.package.description)); + vcpkg::shorten_description(pgh.package.description)); } } diff --git a/toolsrc/src/commands_portsdiff.cpp b/toolsrc/src/commands_portsdiff.cpp index e872c394d..83d62896f 100644 --- a/toolsrc/src/commands_portsdiff.cpp +++ b/toolsrc/src/commands_portsdiff.cpp @@ -97,10 +97,8 @@ namespace vcpkg::Commands::PortsDiff L".vcpkg-root", git_exe.native()); System::cmd_execute_clean(cmd); - const std::vector source_control_files = - Paragraphs::load_all_ports(paths.get_filesystem(), temp_checkout_path / ports_dir_name_as_string); - const std::map names_and_versions = - Paragraphs::extract_port_names_and_versions(getSourceParagraphs(source_control_files)); + const std::map names_and_versions = Paragraphs::load_all_port_names_and_versions( + paths.get_filesystem(), temp_checkout_path / ports_dir_name_as_string); fs.remove_all(temp_checkout_path, ec); return names_and_versions; } diff --git a/toolsrc/src/commands_search.cpp b/toolsrc/src/commands_search.cpp index b39d21887..fee99a5db 100644 --- a/toolsrc/src/commands_search.cpp +++ b/toolsrc/src/commands_search.cpp @@ -5,7 +5,6 @@ #include "vcpkg_Commands.h" #include "vcpkg_System.h" #include "vcpkglib.h" -#include "vcpkglib_helpers.h" namespace vcpkg::Commands::Search { @@ -19,16 +18,17 @@ namespace vcpkg::Commands::Search return output; } - static std::string create_graph_as_string(const std::vector& source_control_files) + static std::string create_graph_as_string( + const std::vector>& source_control_files) { int empty_node_count = 0; std::string s; s.append("digraph G{ rankdir=LR; edge [minlen=3]; overlap=false;"); - for (const SourceControlFile& source_control_file : source_control_files) + for (const auto& source_control_file : source_control_files) { - const SourceParagraph& source_paragraph = source_control_file.core_paragraph; + const SourceParagraph& source_paragraph = *source_control_file->core_paragraph; if (source_paragraph.depends.empty()) { empty_node_count++; @@ -59,7 +59,7 @@ namespace vcpkg::Commands::Search System::println("%-20s %-16s %s", source_paragraph.name, source_paragraph.version, - details::shorten_description(source_paragraph.description)); + vcpkg::shorten_description(source_paragraph.description)); } } @@ -73,7 +73,7 @@ namespace vcpkg::Commands::Search { System::println("%-37s %s", name + "[" + feature_paragraph.name + "]", - details::shorten_description(feature_paragraph.description)); + vcpkg::shorten_description(feature_paragraph.description)); } } @@ -99,7 +99,7 @@ namespace vcpkg::Commands::Search for (auto&& error : sources_and_errors.errors) { System::println( - System::Color::warning, "Warning: an error occurred while parsing '%s'", error.name); + System::Color::warning, "Warning: an error occurred while parsing '%s'", error->name); } System::println(System::Color::warning, "Use '--debug' to get more information about the parse failures.\n"); @@ -116,12 +116,12 @@ namespace vcpkg::Commands::Search if (args.command_arguments.empty()) { - for (const SourceControlFile& source_control_file : source_paragraphs) + for (const auto& source_control_file : source_paragraphs) { - do_print(source_control_file.core_paragraph, options.find(OPTION_FULLDESC) != options.cend()); - for (auto&& feature_paragraph : source_control_file.feature_paragraphs) + do_print(*source_control_file->core_paragraph, options.find(OPTION_FULLDESC) != options.cend()); + for (auto&& feature_paragraph : source_control_file->feature_paragraphs) { - do_print(source_control_file.core_paragraph.name, + do_print(source_control_file->core_paragraph->name, *feature_paragraph, options.find(OPTION_FULLDESC) != options.cend()); } @@ -133,9 +133,9 @@ namespace vcpkg::Commands::Search // At this point there is 1 argument auto&& args_zero = args.command_arguments[0]; - for (const SourceControlFile& source_control_file : source_paragraphs) + for (const auto& source_control_file : source_paragraphs) { - auto&& sp = source_control_file.core_paragraph; + auto&& sp = *source_control_file->core_paragraph; bool contains_name = icontains(sp.name, args_zero); if (contains_name || icontains(sp.description, args_zero)) @@ -143,7 +143,7 @@ namespace vcpkg::Commands::Search do_print(sp, options.find(OPTION_FULLDESC) != options.cend()); } - for (auto&& feature_paragraph : source_control_file.feature_paragraphs) + for (auto&& feature_paragraph : source_control_file->feature_paragraphs) { if (contains_name || icontains(feature_paragraph->name, args_zero) || icontains(feature_paragraph->description, args_zero)) diff --git a/toolsrc/src/commands_update.cpp b/toolsrc/src/commands_update.cpp index f00a89da4..35f24af12 100644 --- a/toolsrc/src/commands_update.cpp +++ b/toolsrc/src/commands_update.cpp @@ -15,10 +15,8 @@ namespace vcpkg::Commands::Update std::vector find_outdated_packages(const VcpkgPaths& paths, const StatusParagraphs& status_db) { - auto source_control_files = Paragraphs::load_all_ports(paths.get_filesystem(), paths.ports); - const std::vector source_paragraphs = getSourceParagraphs(source_control_files); const std::map src_names_to_versions = - Paragraphs::extract_port_names_and_versions(source_paragraphs); + Paragraphs::load_all_port_names_and_versions(paths.get_filesystem(), paths.ports); const std::vector installed_packages = get_installed_ports(status_db); std::vector output; @@ -67,7 +65,8 @@ namespace vcpkg::Commands::Update System::println("\n" "To update these packages, run\n" " .\\vcpkg remove --outdated\n" - " .\\vcpkg install " + install_line); + " .\\vcpkg install " + + install_line); } auto version_file = paths.get_filesystem().read_contents(paths.root / "toolsrc" / "VERSION.txt"); diff --git a/toolsrc/src/tests_paragraph.cpp b/toolsrc/src/tests_paragraph.cpp index 8dff520fb..2a53cc8b4 100644 --- a/toolsrc/src/tests_paragraph.cpp +++ b/toolsrc/src/tests_paragraph.cpp @@ -33,11 +33,11 @@ namespace UnitTest1 Assert::IsTrue(m_pgh.has_value()); auto& pgh = *m_pgh.get(); - Assert::AreEqual("zlib", pgh.core_paragraph.name.c_str()); - Assert::AreEqual("1.2.8", pgh.core_paragraph.version.c_str()); - Assert::AreEqual("", pgh.core_paragraph.maintainer.c_str()); - Assert::AreEqual("", pgh.core_paragraph.description.c_str()); - Assert::AreEqual(size_t(0), pgh.core_paragraph.depends.size()); + Assert::AreEqual("zlib", pgh->core_paragraph->name.c_str()); + Assert::AreEqual("1.2.8", pgh->core_paragraph->version.c_str()); + Assert::AreEqual("", pgh->core_paragraph->maintainer.c_str()); + Assert::AreEqual("", pgh->core_paragraph->description.c_str()); + Assert::AreEqual(size_t(0), pgh->core_paragraph->depends.size()); } TEST_METHOD(SourceParagraph_Construct_Maximum) @@ -54,14 +54,14 @@ namespace UnitTest1 Assert::IsTrue(m_pgh.has_value()); auto& pgh = *m_pgh.get(); - Assert::AreEqual("s", pgh.core_paragraph.name.c_str()); - Assert::AreEqual("v", pgh.core_paragraph.version.c_str()); - Assert::AreEqual("m", pgh.core_paragraph.maintainer.c_str()); - Assert::AreEqual("d", pgh.core_paragraph.description.c_str()); - Assert::AreEqual(size_t(1), pgh.core_paragraph.depends.size()); - Assert::AreEqual("bd", pgh.core_paragraph.depends[0].name.c_str()); - Assert::AreEqual(size_t(1), pgh.core_paragraph.supports.size()); - Assert::AreEqual("x64", pgh.core_paragraph.supports[0].c_str()); + Assert::AreEqual("s", pgh->core_paragraph->name.c_str()); + Assert::AreEqual("v", pgh->core_paragraph->version.c_str()); + Assert::AreEqual("m", pgh->core_paragraph->maintainer.c_str()); + Assert::AreEqual("d", pgh->core_paragraph->description.c_str()); + Assert::AreEqual(size_t(1), pgh->core_paragraph->depends.size()); + Assert::AreEqual("bd", pgh->core_paragraph->depends[0].name.c_str()); + Assert::AreEqual(size_t(1), pgh->core_paragraph->supports.size()); + Assert::AreEqual("x64", pgh->core_paragraph->supports[0].c_str()); } TEST_METHOD(SourceParagraph_Two_Depends) @@ -73,9 +73,9 @@ namespace UnitTest1 Assert::IsTrue(m_pgh.has_value()); auto& pgh = *m_pgh.get(); - Assert::AreEqual(size_t(2), pgh.core_paragraph.depends.size()); - Assert::AreEqual("z", pgh.core_paragraph.depends[0].name.c_str()); - Assert::AreEqual("openssl", pgh.core_paragraph.depends[1].name.c_str()); + Assert::AreEqual(size_t(2), pgh->core_paragraph->depends.size()); + Assert::AreEqual("z", pgh->core_paragraph->depends[0].name.c_str()); + Assert::AreEqual("openssl", pgh->core_paragraph->depends[1].name.c_str()); } TEST_METHOD(SourceParagraph_Three_Depends) @@ -87,10 +87,10 @@ namespace UnitTest1 Assert::IsTrue(m_pgh.has_value()); auto& pgh = *m_pgh.get(); - Assert::AreEqual(size_t(3), pgh.core_paragraph.depends.size()); - Assert::AreEqual("z", pgh.core_paragraph.depends[0].name.c_str()); - Assert::AreEqual("openssl", pgh.core_paragraph.depends[1].name.c_str()); - Assert::AreEqual("xyz", pgh.core_paragraph.depends[2].name.c_str()); + Assert::AreEqual(size_t(3), pgh->core_paragraph->depends.size()); + Assert::AreEqual("z", pgh->core_paragraph->depends[0].name.c_str()); + Assert::AreEqual("openssl", pgh->core_paragraph->depends[1].name.c_str()); + Assert::AreEqual("xyz", pgh->core_paragraph->depends[2].name.c_str()); } TEST_METHOD(SourceParagraph_Three_Supports) @@ -102,10 +102,10 @@ namespace UnitTest1 Assert::IsTrue(m_pgh.has_value()); auto& pgh = *m_pgh.get(); - Assert::AreEqual(size_t(3), pgh.core_paragraph.supports.size()); - Assert::AreEqual("x64", pgh.core_paragraph.supports[0].c_str()); - Assert::AreEqual("windows", pgh.core_paragraph.supports[1].c_str()); - Assert::AreEqual("uwp", pgh.core_paragraph.supports[2].c_str()); + Assert::AreEqual(size_t(3), pgh->core_paragraph->supports.size()); + Assert::AreEqual("x64", pgh->core_paragraph->supports[0].c_str()); + Assert::AreEqual("windows", pgh->core_paragraph->supports[1].c_str()); + Assert::AreEqual("uwp", pgh->core_paragraph->supports[2].c_str()); } TEST_METHOD(SourceParagraph_Construct_Qualified_Depends) @@ -117,15 +117,15 @@ namespace UnitTest1 Assert::IsTrue(m_pgh.has_value()); auto& pgh = *m_pgh.get(); - Assert::AreEqual("zlib", pgh.core_paragraph.name.c_str()); - Assert::AreEqual("1.2.8", pgh.core_paragraph.version.c_str()); - Assert::AreEqual("", pgh.core_paragraph.maintainer.c_str()); - Assert::AreEqual("", pgh.core_paragraph.description.c_str()); - Assert::AreEqual(size_t(2), pgh.core_paragraph.depends.size()); - Assert::AreEqual("libA", pgh.core_paragraph.depends[0].name.c_str()); - Assert::AreEqual("windows", pgh.core_paragraph.depends[0].qualifier.c_str()); - Assert::AreEqual("libB", pgh.core_paragraph.depends[1].name.c_str()); - Assert::AreEqual("uwp", pgh.core_paragraph.depends[1].qualifier.c_str()); + Assert::AreEqual("zlib", pgh->core_paragraph->name.c_str()); + Assert::AreEqual("1.2.8", pgh->core_paragraph->version.c_str()); + Assert::AreEqual("", pgh->core_paragraph->maintainer.c_str()); + Assert::AreEqual("", pgh->core_paragraph->description.c_str()); + Assert::AreEqual(size_t(2), pgh->core_paragraph->depends.size()); + Assert::AreEqual("libA", pgh->core_paragraph->depends[0].name.c_str()); + Assert::AreEqual("windows", pgh->core_paragraph->depends[0].qualifier.c_str()); + Assert::AreEqual("libB", pgh->core_paragraph->depends[1].name.c_str()); + Assert::AreEqual("uwp", pgh->core_paragraph->depends[1].qualifier.c_str()); } TEST_METHOD(BinaryParagraph_Construct_Minimum) diff --git a/toolsrc/src/vcpkg_Build.cpp b/toolsrc/src/vcpkg_Build.cpp index 0ca6dc243..a73d59910 100644 --- a/toolsrc/src/vcpkg_Build.cpp +++ b/toolsrc/src/vcpkg_Build.cpp @@ -11,7 +11,6 @@ #include "vcpkg_System.h" #include "vcpkg_optional.h" #include "vcpkglib.h" -#include "vcpkglib_helpers.h" namespace vcpkg::Build { @@ -218,56 +217,52 @@ namespace vcpkg::Build static BuildInfo inner_create_buildinfo(std::unordered_map pgh) { + Parse::ParagraphParser parser(std::move(pgh)); + BuildInfo build_info; - const std::string crt_linkage_as_string = - details::remove_required_field(&pgh, BuildInfoRequiredField::CRT_LINKAGE); - - auto crtlinkage = to_linkage_type(crt_linkage_as_string); - if (auto p = crtlinkage.get()) - build_info.crt_linkage = *p; - else - Checks::exit_with_message(VCPKG_LINE_INFO, "Invalid crt linkage type: [%s]", crt_linkage_as_string); - - const std::string library_linkage_as_string = - details::remove_required_field(&pgh, BuildInfoRequiredField::LIBRARY_LINKAGE); - auto liblinkage = to_linkage_type(library_linkage_as_string); - if (auto p = liblinkage.get()) - build_info.library_linkage = *p; - else - Checks::exit_with_message(VCPKG_LINE_INFO, "Invalid library linkage type: [%s]", library_linkage_as_string); - - auto it_version = pgh.find("Version"); - if (it_version != pgh.end()) + { - build_info.version = it_version->second; - pgh.erase(it_version); + std::string crt_linkage_as_string; + parser.required_field(BuildInfoRequiredField::CRT_LINKAGE, crt_linkage_as_string); + + auto crtlinkage = to_linkage_type(crt_linkage_as_string); + if (auto p = crtlinkage.get()) + build_info.crt_linkage = *p; + else + Checks::exit_with_message(VCPKG_LINE_INFO, "Invalid crt linkage type: [%s]", crt_linkage_as_string); } - std::map policies; + { + std::string library_linkage_as_string; + parser.required_field(BuildInfoRequiredField::LIBRARY_LINKAGE, library_linkage_as_string); + auto liblinkage = to_linkage_type(library_linkage_as_string); + if (auto p = liblinkage.get()) + build_info.library_linkage = *p; + else + Checks::exit_with_message( + VCPKG_LINE_INFO, "Invalid library linkage type: [%s]", library_linkage_as_string); + } + build_info.version = parser.optional_field("Version"); - // The remaining entries are policies - for (const std::unordered_map::value_type& p : pgh) + std::map policies; + for (auto policy : g_all_policies) { - auto maybe_policy = to_build_policy(p.first); - if (auto policy = maybe_policy.get()) - { - Checks::check_exit(VCPKG_LINE_INFO, - policies.find(*policy) == policies.end(), - "Policy specified multiple times: %s", - p.first); - - if (p.second == "enabled") - policies.emplace(*policy, true); - else if (p.second == "disabled") - policies.emplace(*policy, false); - else - Checks::exit_with_message( - VCPKG_LINE_INFO, "Unknown setting for policy '%s': %s", p.first, p.second); - } + const auto setting = parser.optional_field(to_string(policy)); + if (setting.empty()) + continue; + else if (setting == "enabled") + policies.emplace(policy, true); + else if (setting == "disabled") + policies.emplace(policy, false); else - { - Checks::exit_with_message(VCPKG_LINE_INFO, "Unknown policy found: %s", p.first); - } + Checks::exit_with_message( + VCPKG_LINE_INFO, "Unknown setting for policy '%s': %s", to_string(policy), setting); + } + + if (auto err = parser.error_info("PostBuildInformation")) + { + print_error_message(err); + Checks::exit_fail(VCPKG_LINE_INFO); } build_info.policies = BuildPolicies(std::move(policies)); diff --git a/toolsrc/src/vcpkg_Build_BuildPolicy.cpp b/toolsrc/src/vcpkg_Build_BuildPolicy.cpp index e75e176a2..b3bb778dc 100644 --- a/toolsrc/src/vcpkg_Build_BuildPolicy.cpp +++ b/toolsrc/src/vcpkg_Build_BuildPolicy.cpp @@ -12,17 +12,6 @@ namespace vcpkg::Build static const std::string NAME_EMPTY_INCLUDE_FOLDER = "PolicyEmptyIncludeFolder"; static const std::string NAME_ALLOW_OBSOLETE_MSVCRT = "PolicyAllowObsoleteMsvcrt"; - Optional to_build_policy(const std::string& s) - { - if (s == NAME_EMPTY_PACKAGE) return BuildPolicy::EMPTY_PACKAGE; - if (s == NAME_DLLS_WITHOUT_LIBS) return BuildPolicy::DLLS_WITHOUT_LIBS; - if (s == NAME_ONLY_RELEASE_CRT) return BuildPolicy::ONLY_RELEASE_CRT; - if (s == NAME_EMPTY_INCLUDE_FOLDER) return BuildPolicy::EMPTY_INCLUDE_FOLDER; - if (s == NAME_ALLOW_OBSOLETE_MSVCRT) return BuildPolicy::ALLOW_OBSOLETE_MSVCRT; - - return nullopt; - } - const std::string& to_string(BuildPolicy policy) { switch (policy) diff --git a/toolsrc/src/vcpkg_Dependencies.cpp b/toolsrc/src/vcpkg_Dependencies.cpp index add8acb4d..bbf807c95 100644 --- a/toolsrc/src/vcpkg_Dependencies.cpp +++ b/toolsrc/src/vcpkg_Dependencies.cpp @@ -174,12 +174,11 @@ namespace vcpkg::Dependencies if (auto bpgh = maybe_bpgh.get()) return InstallPlanAction{spec, {nullopt, *bpgh, nullopt}, request_type}; - ExpectedT source_control_file = - Paragraphs::try_load_port(paths.get_filesystem(), paths.port_dir(spec)); - if (auto scf = source_control_file.get()) - return InstallPlanAction{spec, {nullopt, nullopt, (*scf).core_paragraph}, request_type}; + auto maybe_scf = Paragraphs::try_load_port(paths.get_filesystem(), paths.port_dir(spec)); + if (auto scf = maybe_scf.get()) + return InstallPlanAction{spec, {nullopt, nullopt, *scf->get()->core_paragraph}, request_type}; - print_error_message(source_control_file.error()); + print_error_message(maybe_scf.error()); Checks::exit_fail(VCPKG_LINE_INFO); } }; @@ -284,13 +283,11 @@ namespace vcpkg::Dependencies if (auto bpgh = maybe_bpgh.get()) return ExportPlanAction{spec, {nullopt, *bpgh, nullopt}, request_type}; - ExpectedT source_control_file = - Paragraphs::try_load_port(paths.get_filesystem(), paths.port_dir(spec)); - if (auto scf = source_control_file.get()) - return ExportPlanAction{spec, {nullopt, nullopt, (*scf).core_paragraph}, request_type}; - + auto maybe_scf = Paragraphs::try_load_port(paths.get_filesystem(), paths.port_dir(spec)); + if (auto scf = maybe_scf.get()) + return ExportPlanAction{spec, {nullopt, nullopt, *scf->get()->core_paragraph}, request_type}; else - print_error_message(source_control_file.error()); + print_error_message(maybe_scf.error()); Checks::exit_with_message(VCPKG_LINE_INFO, "Could not find package %s", spec); } diff --git a/toolsrc/src/vcpkg_Parse.cpp b/toolsrc/src/vcpkg_Parse.cpp new file mode 100644 index 000000000..b63ce41a9 --- /dev/null +++ b/toolsrc/src/vcpkg_Parse.cpp @@ -0,0 +1,59 @@ +#include "pch.h" + +#include "vcpkg_Checks.h" +#include "vcpkg_Maps.h" +#include "vcpkg_Parse.h" + +namespace vcpkg::Parse +{ + static Optional get_field(const std::unordered_map& fields, + const std::string& fieldname) + { + auto it = fields.find(fieldname); + if (it == fields.end()) + { + return nullopt; + } + + return it->second; + } + + static Optional remove_field(std::unordered_map* fields, + const std::string& fieldname) + { + auto it = fields->find(fieldname); + if (it == fields->end()) + { + return nullopt; + } + + const std::string value = std::move(it->second); + fields->erase(it); + return value; + } + + void ParagraphParser::required_field(const std::string& fieldname, std::string& out) + { + auto maybe_field = remove_field(&fields, fieldname); + if (auto field = maybe_field.get()) + out = std::move(*field); + else + missing_fields.push_back(fieldname); + } + std::string ParagraphParser::optional_field(const std::string& fieldname) + { + return remove_field(&fields, fieldname).value_or(""); + } + std::unique_ptr ParagraphParser::error_info(const std::string& name) const + { + if (!fields.empty() || !missing_fields.empty()) + { + auto err = std::make_unique(); + err->name = name; + err->extra_fields = Maps::extract_keys(fields); + err->missing_fields = std::move(missing_fields); + return err; + } + return nullptr; + } +} diff --git a/toolsrc/src/vcpkglib.cpp b/toolsrc/src/vcpkglib.cpp index 15130f77e..6b180b532 100644 --- a/toolsrc/src/vcpkglib.cpp +++ b/toolsrc/src/vcpkglib.cpp @@ -31,7 +31,7 @@ namespace vcpkg std::vector> status_pghs; for (auto&& p : pghs) { - status_pghs.push_back(std::make_unique(p)); + status_pghs.push_back(std::make_unique(std::move(p))); } return StatusParagraphs(std::move(status_pghs)); @@ -69,7 +69,7 @@ namespace vcpkg auto pghs = Paragraphs::get_paragraphs(fs, file).value_or_exit(VCPKG_LINE_INFO); for (auto&& p : pghs) { - current_status_db.insert(std::make_unique(p)); + current_status_db.insert(std::make_unique(std::move(p))); } } @@ -239,4 +239,10 @@ namespace vcpkg return Strings::wformat( LR"("%s" %s -P "%s")", cmake_exe.native(), cmd_cmake_pass_variables, cmake_script.generic_wstring()); } + + std::string shorten_description(const std::string& desc) + { + auto simple_desc = std::regex_replace(desc, std::regex("\\s+"), " "); + return simple_desc.size() <= 52 ? simple_desc : simple_desc.substr(0, 49) + "..."; + } } diff --git a/toolsrc/src/vcpkglib_helpers.cpp b/toolsrc/src/vcpkglib_helpers.cpp deleted file mode 100644 index 9f992d320..000000000 --- a/toolsrc/src/vcpkglib_helpers.cpp +++ /dev/null @@ -1,56 +0,0 @@ -#include "pch.h" - -#include "vcpkg_Checks.h" -#include "vcpkglib_helpers.h" - -namespace vcpkg::details -{ - std::string optional_field(const std::unordered_map& fields, const std::string& fieldname) - { - auto it = fields.find(fieldname); - if (it == fields.end()) - { - return std::string(); - } - - return it->second; - } - - std::string remove_optional_field(std::unordered_map* fields, - const std::string& fieldname) - { - auto it = fields->find(fieldname); - if (it == fields->end()) - { - return std::string(); - } - - const std::string value = std::move(it->second); - fields->erase(it); - return value; - } - - std::string required_field(const std::unordered_map& fields, const std::string& fieldname) - { - auto it = fields.find(fieldname); - Checks::check_exit(VCPKG_LINE_INFO, it != fields.end(), "Required field not present: %s", fieldname); - return it->second; - } - - std::string remove_required_field(std::unordered_map* fields, - const std::string& fieldname) - { - auto it = fields->find(fieldname); - Checks::check_exit(VCPKG_LINE_INFO, it != fields->end(), "Required field not present: %s", fieldname); - - const std::string value = std::move(it->second); - fields->erase(it); - return value; - } - - std::string shorten_description(const std::string& desc) - { - auto simple_desc = std::regex_replace(desc, std::regex("\\s+"), " "); - return simple_desc.size() <= 52 ? simple_desc : simple_desc.substr(0, 49) + "..."; - } -} diff --git a/toolsrc/vcpkglib/vcpkglib.vcxproj b/toolsrc/vcpkglib/vcpkglib.vcxproj index 487609cca..200f91d1c 100644 --- a/toolsrc/vcpkglib/vcpkglib.vcxproj +++ b/toolsrc/vcpkglib/vcpkglib.vcxproj @@ -161,7 +161,7 @@ - + @@ -227,7 +227,7 @@ - + diff --git a/toolsrc/vcpkglib/vcpkglib.vcxproj.filters b/toolsrc/vcpkglib/vcpkglib.vcxproj.filters index a901cebe7..4f51dfa9a 100644 --- a/toolsrc/vcpkglib/vcpkglib.vcxproj.filters +++ b/toolsrc/vcpkglib/vcpkglib.vcxproj.filters @@ -30,9 +30,6 @@ Source Files - - Source Files - Source Files @@ -177,14 +174,14 @@ Source Files + + Source Files + Header Files - - Header Files - Header Files @@ -302,5 +299,8 @@ Header Files + + Header Files + \ No newline at end of file -- cgit v1.2.3 From befe2531f620471e1b2c5562c9994420e03c008a Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Tue, 20 Jun 2017 09:53:22 -0700 Subject: [vcpkg] Handle missing fields in print_error_message() --- toolsrc/src/SourceParagraph.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/SourceParagraph.cpp b/toolsrc/src/SourceParagraph.cpp index 83b8e2e2d..9289edb38 100644 --- a/toolsrc/src/SourceParagraph.cpp +++ b/toolsrc/src/SourceParagraph.cpp @@ -56,7 +56,7 @@ namespace vcpkg System::println(System::Color::error, "Error: There are invalid fields in the Source Paragraph of %s", error_info->name); - System::println("The following fields were not expected:\n\n %s\n\n", + System::println("The following fields were not expected:\n\n %s\n", Strings::join("\n ", error_info->extra_fields)); have_remaining_fields = true; } @@ -68,6 +68,18 @@ namespace vcpkg Strings::join("\n ", get_list_of_valid_fields())); System::println("Different source may be available for vcpkg. Use .\\bootstrap-vcpkg.bat to update.\n"); } + + for (auto&& error_info : error_info_list) + { + if (!error_info->missing_fields.empty()) + { + System::println(System::Color::error, + "Error: There are missing fields in the Source Paragraphs of %s", + error_info->name); + System::println("The following fields were missing:\n\n %s\n", + Strings::join("\n ", error_info->missing_fields)); + } + } } static ParseExpected parse_source_paragraph(RawParagraph&& fields) -- cgit v1.2.3 From e72b0ec9a2ac23300c39d7bc8217dfd5cfa6ab63 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Tue, 20 Jun 2017 16:26:25 -0700 Subject: [vcpkg] Hotfix regression in 8741214. Fixes #1325. --- toolsrc/src/vcpkg_Build.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg_Build.cpp b/toolsrc/src/vcpkg_Build.cpp index a73d59910..c794b5ede 100644 --- a/toolsrc/src/vcpkg_Build.cpp +++ b/toolsrc/src/vcpkg_Build.cpp @@ -242,7 +242,8 @@ namespace vcpkg::Build Checks::exit_with_message( VCPKG_LINE_INFO, "Invalid library linkage type: [%s]", library_linkage_as_string); } - build_info.version = parser.optional_field("Version"); + std::string version = parser.optional_field("Version"); + if (!version.empty()) build_info.version = std::move(version); std::map policies; for (auto policy : g_all_policies) -- cgit v1.2.3 From b188fefecaf03c1f30ee4752c2235975058553e2 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 21 Jun 2017 15:27:34 -0700 Subject: [triplet] Use pointer to instance-controlled strings and cache hashcode --- toolsrc/include/triplet.h | 34 +++++++++++++++++----------------- toolsrc/src/triplet.cpp | 39 +++++++++++++++++++++++++++++---------- 2 files changed, 46 insertions(+), 27 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/triplet.h b/toolsrc/include/triplet.h index e634afd3f..be3bcf5b3 100644 --- a/toolsrc/include/triplet.h +++ b/toolsrc/include/triplet.h @@ -4,8 +4,13 @@ namespace vcpkg { + struct TripletInstance; + struct Triplet { + public: + constexpr Triplet() : m_instance(&default_instance) {} + static Triplet from_canonical_name(const std::string& triplet_as_string); static const Triplet X86_WINDOWS; @@ -16,28 +21,23 @@ namespace vcpkg const std::string& canonical_name() const; const std::string& to_string() const; + size_t hash_code() const; + + bool operator==(const Triplet& other) const; private: - std::string m_canonical_name; - }; + static const TripletInstance default_instance; - bool operator==(const Triplet& left, const Triplet& right); + constexpr Triplet(const TripletInstance* ptr) : m_instance(ptr) {} + + const TripletInstance* m_instance; + }; bool operator!=(const Triplet& left, const Triplet& right); } -namespace std +template<> +struct std::hash { - template<> - struct hash - { - size_t operator()(const vcpkg::Triplet& t) const - { - std::hash hasher; - size_t hash = 17; - hash = hash * 31 + hasher(t.canonical_name()); - return hash; - } - }; - -} // namespace std + size_t operator()(const vcpkg::Triplet& t) const { return t.hash_code(); } +}; diff --git a/toolsrc/src/triplet.cpp b/toolsrc/src/triplet.cpp index ff41ce77d..451deb040 100644 --- a/toolsrc/src/triplet.cpp +++ b/toolsrc/src/triplet.cpp @@ -6,31 +6,50 @@ namespace vcpkg { + struct TripletInstance + { + TripletInstance(std::string&& s) : value(std::move(s)), hash(std::hash()(value)) {} + + const std::string value; + const size_t hash = 0; + + bool operator==(const TripletInstance& o) const { return o.value == value; } + }; + const TripletInstance Triplet::default_instance({}); +} + +template<> +struct std::hash +{ + size_t operator()(const vcpkg::TripletInstance& t) const { return t.hash; } +}; + +namespace vcpkg +{ + static std::unordered_set g_triplet_instances; + const Triplet Triplet::X86_WINDOWS = from_canonical_name("x86-windows"); const Triplet Triplet::X64_WINDOWS = from_canonical_name("x64-windows"); const Triplet Triplet::X86_UWP = from_canonical_name("x86-uwp"); const Triplet Triplet::X64_UWP = from_canonical_name("x64-uwp"); const Triplet Triplet::ARM_UWP = from_canonical_name("arm-uwp"); - bool operator==(const Triplet& left, const Triplet& right) - { - return left.canonical_name() == right.canonical_name(); - } + bool Triplet::operator==(const Triplet& other) const { return this->m_instance == other.m_instance; } bool operator!=(const Triplet& left, const Triplet& right) { return !(left == right); } Triplet Triplet::from_canonical_name(const std::string& triplet_as_string) { - const std::string s(Strings::ascii_to_lowercase(triplet_as_string)); + std::string s(Strings::ascii_to_lowercase(triplet_as_string)); auto it = std::find(s.cbegin(), s.cend(), '-'); Checks::check_exit(VCPKG_LINE_INFO, it != s.cend(), "Invalid triplet: %s", triplet_as_string); - Triplet t; - t.m_canonical_name = s; - return t; + auto p = g_triplet_instances.emplace(std::move(s)); + return &*p.first; } - const std::string& Triplet::canonical_name() const { return this->m_canonical_name; } + const std::string& Triplet::canonical_name() const { return this->m_instance->value; } - const std::string& Triplet::to_string() const { return this->m_canonical_name; } + const std::string& Triplet::to_string() const { return this->canonical_name(); } + size_t Triplet::hash_code() const { return m_instance->hash; } } -- cgit v1.2.3 From 8461bc1913df1a7db287999c33876291cd25be61 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Wed, 21 Jun 2017 17:41:31 -0700 Subject: [vcpkg-export] Fix nuget export. Fixes #1223. --- toolsrc/src/commands_export.cpp | 4 ++++ toolsrc/src/vcpkg_Files.cpp | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/commands_export.cpp b/toolsrc/src/commands_export.cpp index e46001b06..cbb3a7733 100644 --- a/toolsrc/src/commands_export.cpp +++ b/toolsrc/src/commands_export.cpp @@ -122,6 +122,10 @@ namespace vcpkg::Commands::Export const std::string targets_redirect_content = create_targets_redirect("../../scripts/buildsystems/msbuild/vcpkg.targets"); const fs::path targets_redirect = paths.buildsystems / "tmp" / "vcpkg.export.nuget.targets"; + + std::error_code ec; + fs.create_directories(paths.buildsystems / "tmp", ec); + fs.write_contents(targets_redirect, targets_redirect_content); const std::string nuspec_file_content = diff --git a/toolsrc/src/vcpkg_Files.cpp b/toolsrc/src/vcpkg_Files.cpp index 7b12ea699..29da7e684 100644 --- a/toolsrc/src/vcpkg_Files.cpp +++ b/toolsrc/src/vcpkg_Files.cpp @@ -164,7 +164,8 @@ namespace vcpkg::Files { FILE* f = nullptr; auto ec = _wfopen_s(&f, file_path.native().c_str(), L"wb"); - Checks::check_exit(VCPKG_LINE_INFO, ec == 0); + Checks::check_exit( + VCPKG_LINE_INFO, ec == 0, "Error: Could not open file for writing: %s", file_path.u8string().c_str()); auto count = fwrite(data.data(), sizeof(data[0]), data.size(), f); fclose(f); -- cgit v1.2.3 From 838e8783d659456037c0e8e89dcc689e626b6816 Mon Sep 17 00:00:00 2001 From: Daniel Shaw Date: Mon, 26 Jun 2017 13:48:04 -0700 Subject: adding tests for install plans --- toolsrc/include/vcpkg_Dependencies.h | 19 +++- toolsrc/src/commands_ci.cpp | 3 +- toolsrc/src/commands_install.cpp | 3 +- toolsrc/src/test_install_plan.cpp | 155 ++++++++++++++++++++++++++++ toolsrc/src/vcpkg_Dependencies.cpp | 79 +++++++++++++- toolsrc/vcpkgtest/vcpkgtest.vcxproj | 1 + toolsrc/vcpkgtest/vcpkgtest.vcxproj.filters | 3 + 7 files changed, 259 insertions(+), 4 deletions(-) create mode 100644 toolsrc/src/test_install_plan.cpp (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg_Dependencies.h b/toolsrc/include/vcpkg_Dependencies.h index 018c4f5cf..da31aa4bf 100644 --- a/toolsrc/include/vcpkg_Dependencies.h +++ b/toolsrc/include/vcpkg_Dependencies.h @@ -97,7 +97,24 @@ namespace vcpkg::Dependencies RequestType request_type; }; - std::vector create_install_plan(const VcpkgPaths& paths, + __interface PortFileProvider { virtual const SourceControlFile* get_control_file(const PackageSpec& spec) const; }; + + struct MapPortFile : PortFileProvider + { + const std::unordered_map& ports; + explicit MapPortFile(const std::unordered_map& map); + const SourceControlFile* get_control_file(const PackageSpec& spec) const override; + }; + + struct PathsPortFile : PortFileProvider + { + const VcpkgPaths& ports; + mutable std::unordered_map cache; + explicit PathsPortFile(const VcpkgPaths& paths); + const SourceControlFile* get_control_file(const PackageSpec& spec) const override; + }; + + std::vector create_install_plan(const PortFileProvider& port_file_provider, const std::vector& specs, const StatusParagraphs& status_db); diff --git a/toolsrc/src/commands_ci.cpp b/toolsrc/src/commands_ci.cpp index 7ffc7577a..85febd580 100644 --- a/toolsrc/src/commands_ci.cpp +++ b/toolsrc/src/commands_ci.cpp @@ -40,7 +40,8 @@ namespace vcpkg::Commands::CI const std::vector specs = load_all_package_specs(paths.get_filesystem(), paths.ports, triplet); StatusParagraphs status_db = database_load_check(paths); - const std::vector install_plan = Dependencies::create_install_plan(paths, specs, status_db); + const std::vector install_plan /* = + Dependencies::create_install_plan(Dependencies::PathsPortFile(paths), specs, status_db)*/; Checks::check_exit(VCPKG_LINE_INFO, !install_plan.empty(), "Install plan cannot be empty"); std::vector results; diff --git a/toolsrc/src/commands_install.cpp b/toolsrc/src/commands_install.cpp index 73b3e9eab..a58432eef 100644 --- a/toolsrc/src/commands_install.cpp +++ b/toolsrc/src/commands_install.cpp @@ -359,7 +359,8 @@ namespace vcpkg::Commands::Install // create the plan StatusParagraphs status_db = database_load_check(paths); - std::vector install_plan = Dependencies::create_install_plan(paths, specs, status_db); + std::vector install_plan = + Dependencies::create_install_plan(Dependencies::PathsPortFile(paths), specs, status_db); Checks::check_exit(VCPKG_LINE_INFO, !install_plan.empty(), "Install plan cannot be empty"); // log the plan diff --git a/toolsrc/src/test_install_plan.cpp b/toolsrc/src/test_install_plan.cpp new file mode 100644 index 000000000..90aaa532f --- /dev/null +++ b/toolsrc/src/test_install_plan.cpp @@ -0,0 +1,155 @@ +#include "CppUnitTest.h" +#include "vcpkg_Dependencies.h" + +using namespace Microsoft::VisualStudio::CppUnitTestFramework; + +using namespace vcpkg; + +namespace UnitTest1 +{ + class InstallPlanTests : public TestClass + { + TEST_METHOD(basic_install_scheme) + { + std::vector> status_paragraphs; + + std::unordered_map map; + auto add_scf = [&](std::vector>&& fields) -> PackageSpec { + auto m_pgh = vcpkg::SourceControlFile::parse_control_file(std::move(fields)); + Assert::IsTrue(m_pgh.has_value()); + auto& scf = *m_pgh.get(); + + auto spec = PackageSpec::from_name_and_triplet(scf.core_paragraph.name, Triplet::X86_WINDOWS); + Assert::IsTrue(spec.has_value()); + map.emplace(*spec.get(), std::move(*m_pgh.get())); + return PackageSpec{*spec.get()}; + }; + + auto spec_a = add_scf({{{"Source", "a"}, {"Version", "1.2.8"}, {"Build-Depends", "b"}}}); + auto spec_b = add_scf({{{"Source", "b"}, {"Version", "1.3"}, {"Build-Depends", "c"}}}); + auto spec_c = add_scf({{{"Source", "c"}, {"Version", "2.5.3"}, {"Build-Depends", ""}}}); + + auto map_port = Dependencies::MapPortFile(map); + auto install_plan = + Dependencies::create_install_plan(map_port, {spec_a}, StatusParagraphs(std::move(status_paragraphs))); + + Assert::AreEqual(size_t(3), install_plan.size()); + Assert::AreEqual("c", install_plan[0].spec.name().c_str()); + Assert::AreEqual("b", install_plan[1].spec.name().c_str()); + Assert::AreEqual("a", install_plan[2].spec.name().c_str()); + } + + TEST_METHOD(multiple_install_scheme) + { + std::vector> status_paragraphs; + + std::unordered_map map; + auto add_scf = [&](std::vector>&& fields) -> PackageSpec { + auto m_pgh = vcpkg::SourceControlFile::parse_control_file(std::move(fields)); + Assert::IsTrue(m_pgh.has_value()); + auto& scf = *m_pgh.get(); + + auto spec = PackageSpec::from_name_and_triplet(scf.core_paragraph.name, Triplet::X86_WINDOWS); + Assert::IsTrue(spec.has_value()); + map.emplace(*spec.get(), std::move(*m_pgh.get())); + return PackageSpec{*spec.get()}; + }; + + auto spec_a = add_scf({{{"Source", "a"}, {"Version", "1.2.8"}, {"Build-Depends", "d"}}}); + auto spec_b = add_scf({{{"Source", "b"}, {"Version", "1.3"}, {"Build-Depends", "d, e"}}}); + auto spec_c = add_scf({{{"Source", "c"}, {"Version", "2.5.3"}, {"Build-Depends", "e, h"}}}); + auto spec_d = add_scf({{{"Source", "d"}, {"Version", "4.0"}, {"Build-Depends", "f, g, h"}}}); + auto spec_e = add_scf({{{"Source", "e"}, {"Version", "1.0"}, {"Build-Depends", "g"}}}); + auto spec_f = add_scf({{{"Source", "f"}, {"Version", "1.0"}, {"Build-Depends", ""}}}); + auto spec_g = add_scf({{{"Source", "g"}, {"Version", "1.0"}, {"Build-Depends", ""}}}); + auto spec_h = add_scf({{{"Source", "h"}, {"Version", "1.0"}, {"Build-Depends", ""}}}); + + auto map_port = Dependencies::MapPortFile(map); + auto install_plan = Dependencies::create_install_plan( + map_port, {spec_a, spec_b, spec_c}, StatusParagraphs(std::move(status_paragraphs))); + + auto iterator_pos = [&](const PackageSpec& spec) -> int { + int counter = 0; + for (auto&& install_p : install_plan) + { + if (install_p.spec == spec) + { + return counter; + } + counter++; + } + return -1; + }; + int a_pos = iterator_pos(spec_a), b_pos = iterator_pos(spec_b), c_pos = iterator_pos(spec_c), + d_pos = iterator_pos(spec_d), e_pos = iterator_pos(spec_e), f_pos = iterator_pos(spec_f), + g_pos = iterator_pos(spec_g), h_pos = iterator_pos(spec_h); + + Assert::IsTrue(a_pos > d_pos); + Assert::IsTrue(b_pos > e_pos); + Assert::IsTrue(b_pos > d_pos); + Assert::IsTrue(c_pos > e_pos); + Assert::IsTrue(c_pos > h_pos); + Assert::IsTrue(d_pos > f_pos); + Assert::IsTrue(d_pos > g_pos); + Assert::IsTrue(d_pos > h_pos); + Assert::IsTrue(e_pos > g_pos); + } + + TEST_METHOD(long_install_scheme) + { + using Pgh = std::unordered_map; + std::vector> status_paragraphs; + status_paragraphs.push_back(std::make_unique(Pgh{{"Package", "j"}, + {"Version", "1.2.8"}, + {"Architecture", "x86-windows"}, + {"Multi-Arch", "same"}, + {"Build-Depends", "k"}, + {"Status", "install ok installed"}})); + status_paragraphs.push_back(std::make_unique(Pgh{{"Package", "k"}, + {"Version", "1.2.8"}, + {"Architecture", "x86-windows"}, + {"Multi-Arch", "same"}, + {"Build-Depends", ""}, + {"Status", "install ok installed"}})); + + std::unordered_map map; + auto add_scf = [&](std::vector>&& fields) -> PackageSpec { + auto m_pgh = vcpkg::SourceControlFile::parse_control_file(std::move(fields)); + Assert::IsTrue(m_pgh.has_value()); + auto& scf = *m_pgh.get(); + + auto spec = PackageSpec::from_name_and_triplet(scf.core_paragraph.name, Triplet::X86_WINDOWS); + Assert::IsTrue(spec.has_value()); + map.emplace(*spec.get(), std::move(*m_pgh.get())); + return PackageSpec{*spec.get()}; + }; + + auto spec_h = add_scf({{{"Source", "h"}, {"Version", "1.2.8"}, {"Build-Depends", "j, k"}}}); + auto spec_c = add_scf({{{"Source", "c"}, {"Version", "1.2.8"}, {"Build-Depends", "d, e, f, g, h, j, k"}}}); + auto spec_k = add_scf({{{"Source", "k"}, {"Version", "1.2.8"}, {"Build-Depends", ""}}}); + auto spec_b = + add_scf({{{"Source", "b"}, {"Version", "1.2.8"}, {"Build-Depends", "c, d, e, f, g, h, j, k"}}}); + auto spec_d = add_scf({{{"Source", "d"}, {"Version", "1.2.8"}, {"Build-Depends", "e, f, g, h, j, k"}}}); + auto spec_j = add_scf({{{"Source", "j"}, {"Version", "1.2.8"}, {"Build-Depends", "k"}}}); + auto spec_f = add_scf({{{"Source", "f"}, {"Version", "1.2.8"}, {"Build-Depends", "g, h, j, k"}}}); + auto spec_e = add_scf({{{"Source", "e"}, {"Version", "1.2.8"}, {"Build-Depends", "f, g, h, j, k"}}}); + auto spec_a = + add_scf({{{"Source", "a"}, {"Version", "1.2.8"}, {"Build-Depends", "b, c, d, e, f, g, h, j, k"}}}); + auto spec_g = add_scf({{{"Source", "g"}, {"Version", "1.2.8"}, {"Build-Depends", "h, j, k"}}}); + + auto map_port = Dependencies::MapPortFile(map); + auto install_plan = + Dependencies::create_install_plan(map_port, {spec_a}, StatusParagraphs(std::move(status_paragraphs))); + + Assert::AreEqual(size_t(8), install_plan.size()); + Assert::AreEqual("h", install_plan[0].spec.name().c_str()); + Assert::AreEqual("g", install_plan[1].spec.name().c_str()); + Assert::AreEqual("f", install_plan[2].spec.name().c_str()); + Assert::AreEqual("e", install_plan[3].spec.name().c_str()); + Assert::AreEqual("d", install_plan[4].spec.name().c_str()); + Assert::AreEqual("c", install_plan[5].spec.name().c_str()); + Assert::AreEqual("b", install_plan[6].spec.name().c_str()); + Assert::AreEqual("a", install_plan[7].spec.name().c_str()); + } + }; +} \ No newline at end of file diff --git a/toolsrc/src/vcpkg_Dependencies.cpp b/toolsrc/src/vcpkg_Dependencies.cpp index bbf807c95..79f572496 100644 --- a/toolsrc/src/vcpkg_Dependencies.cpp +++ b/toolsrc/src/vcpkg_Dependencies.cpp @@ -139,9 +139,86 @@ namespace vcpkg::Dependencies return left->spec.name() < right->spec.name(); } - std::vector create_install_plan(const VcpkgPaths& paths, + MapPortFile::MapPortFile(const std::unordered_map& map) : ports(map){}; + const SourceControlFile* MapPortFile::get_control_file(const PackageSpec& spec) const + { + auto scf = ports.find(spec); + if (scf == ports.end()) + { + Checks::exit_fail(VCPKG_LINE_INFO); + } + return &scf->second; + } + + PathsPortFile::PathsPortFile(const VcpkgPaths& paths) : ports(paths){}; + const SourceControlFile* PathsPortFile::get_control_file(const PackageSpec& spec) const + { + std::unordered_map::iterator cache_it = cache.find(spec); + if (cache_it != cache.end()) + { + return &cache_it->second; + } + ExpectedT source_control_file = + Paragraphs::try_load_port(ports.get_filesystem(), ports.port_dir(spec)); + + if (auto scf = source_control_file.get()) + { + auto it = cache.emplace(spec, std::move(*scf)); + return &it.first->second; + } + + Checks::exit_fail(VCPKG_LINE_INFO); + } + + std::vector create_install_plan(const PortFileProvider& port_file_provider, const std::vector& specs, const StatusParagraphs& status_db) + { + struct InstallAdjacencyProvider final : Graphs::AdjacencyProvider + { + const PortFileProvider& port_file_provider; + const StatusParagraphs& status_db; + const std::unordered_set& specs_as_set; + + InstallAdjacencyProvider(const PortFileProvider& port_file_provider, + const StatusParagraphs& s, + const std::unordered_set& specs_as_set) + : port_file_provider(port_file_provider), status_db(s), specs_as_set(specs_as_set) + { + } + + std::vector adjacency_list(const InstallPlanAction& plan) const override + { + if (plan.any_paragraph.status_paragraph.get()) return std::vector{}; + return plan.any_paragraph.dependencies(plan.spec.triplet()); + } + + InstallPlanAction load_vertex_data(const PackageSpec& spec) const override + { + const RequestType request_type = specs_as_set.find(spec) != specs_as_set.end() + ? RequestType::USER_REQUESTED + : RequestType::AUTO_SELECTED; + auto it = status_db.find_installed(spec); + if (it != status_db.end()) return InstallPlanAction{spec, {*it->get(), nullopt, nullopt}, request_type}; + return InstallPlanAction{ + spec, {nullopt, nullopt, port_file_provider.get_control_file(spec)->core_paragraph}, request_type}; + } + }; + + const std::unordered_set specs_as_set(specs.cbegin(), specs.cend()); + std::vector toposort = + Graphs::topological_sort(specs, InstallAdjacencyProvider{port_file_provider, status_db, specs_as_set}); + Util::erase_remove_if(toposort, [](const InstallPlanAction& plan) { + return plan.request_type == RequestType::AUTO_SELECTED && + plan.plan_type == InstallPlanType::ALREADY_INSTALLED; + }); + + return toposort; + } + + std::vector create_full_install_plan(const VcpkgPaths& paths, + const std::vector& specs, + const StatusParagraphs& status_db) { struct InstallAdjacencyProvider final : Graphs::AdjacencyProvider { diff --git a/toolsrc/vcpkgtest/vcpkgtest.vcxproj b/toolsrc/vcpkgtest/vcpkgtest.vcxproj index 26d5c98eb..ca66260d4 100644 --- a/toolsrc/vcpkgtest/vcpkgtest.vcxproj +++ b/toolsrc/vcpkgtest/vcpkgtest.vcxproj @@ -22,6 +22,7 @@ + diff --git a/toolsrc/vcpkgtest/vcpkgtest.vcxproj.filters b/toolsrc/vcpkgtest/vcpkgtest.vcxproj.filters index f1230cfce..e376e59f4 100644 --- a/toolsrc/vcpkgtest/vcpkgtest.vcxproj.filters +++ b/toolsrc/vcpkgtest/vcpkgtest.vcxproj.filters @@ -24,5 +24,8 @@ Source Files + + Source Files + \ No newline at end of file -- cgit v1.2.3 From cc06f978914917622904a0326094c1d5fba4118e Mon Sep 17 00:00:00 2001 From: Daniel Shaw Date: Mon, 26 Jun 2017 15:45:31 -0700 Subject: Merge branch 'master' into create_install_tests --- toolsrc/src/commands_ci.cpp | 4 +-- toolsrc/src/test_install_plan.cpp | 16 +++++----- toolsrc/src/vcpkg_Dependencies.cpp | 61 ++------------------------------------ 3 files changed, 13 insertions(+), 68 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/commands_ci.cpp b/toolsrc/src/commands_ci.cpp index 85febd580..5f6fc95b5 100644 --- a/toolsrc/src/commands_ci.cpp +++ b/toolsrc/src/commands_ci.cpp @@ -40,8 +40,8 @@ namespace vcpkg::Commands::CI const std::vector specs = load_all_package_specs(paths.get_filesystem(), paths.ports, triplet); StatusParagraphs status_db = database_load_check(paths); - const std::vector install_plan /* = - Dependencies::create_install_plan(Dependencies::PathsPortFile(paths), specs, status_db)*/; + const std::vector install_plan = + Dependencies::create_install_plan(Dependencies::PathsPortFile(paths), specs, status_db); Checks::check_exit(VCPKG_LINE_INFO, !install_plan.empty(), "Install plan cannot be empty"); std::vector results; diff --git a/toolsrc/src/test_install_plan.cpp b/toolsrc/src/test_install_plan.cpp index 90aaa532f..2404e30f7 100644 --- a/toolsrc/src/test_install_plan.cpp +++ b/toolsrc/src/test_install_plan.cpp @@ -19,9 +19,9 @@ namespace UnitTest1 Assert::IsTrue(m_pgh.has_value()); auto& scf = *m_pgh.get(); - auto spec = PackageSpec::from_name_and_triplet(scf.core_paragraph.name, Triplet::X86_WINDOWS); + auto spec = PackageSpec::from_name_and_triplet(scf->core_paragraph->name, Triplet::X86_WINDOWS); Assert::IsTrue(spec.has_value()); - map.emplace(*spec.get(), std::move(*m_pgh.get())); + map.emplace(*spec.get(), std::move(*scf.get())); return PackageSpec{*spec.get()}; }; @@ -49,9 +49,9 @@ namespace UnitTest1 Assert::IsTrue(m_pgh.has_value()); auto& scf = *m_pgh.get(); - auto spec = PackageSpec::from_name_and_triplet(scf.core_paragraph.name, Triplet::X86_WINDOWS); + auto spec = PackageSpec::from_name_and_triplet(scf->core_paragraph->name, Triplet::X86_WINDOWS); Assert::IsTrue(spec.has_value()); - map.emplace(*spec.get(), std::move(*m_pgh.get())); + map.emplace(*spec.get(), std::move(*scf.get())); return PackageSpec{*spec.get()}; }; @@ -103,13 +103,13 @@ namespace UnitTest1 {"Version", "1.2.8"}, {"Architecture", "x86-windows"}, {"Multi-Arch", "same"}, - {"Build-Depends", "k"}, + {"Depends", "k"}, {"Status", "install ok installed"}})); status_paragraphs.push_back(std::make_unique(Pgh{{"Package", "k"}, {"Version", "1.2.8"}, {"Architecture", "x86-windows"}, {"Multi-Arch", "same"}, - {"Build-Depends", ""}, + {"Depends", ""}, {"Status", "install ok installed"}})); std::unordered_map map; @@ -118,9 +118,9 @@ namespace UnitTest1 Assert::IsTrue(m_pgh.has_value()); auto& scf = *m_pgh.get(); - auto spec = PackageSpec::from_name_and_triplet(scf.core_paragraph.name, Triplet::X86_WINDOWS); + auto spec = PackageSpec::from_name_and_triplet(scf->core_paragraph->name, Triplet::X86_WINDOWS); Assert::IsTrue(spec.has_value()); - map.emplace(*spec.get(), std::move(*m_pgh.get())); + map.emplace(*spec.get(), std::move(*scf.get())); return PackageSpec{*spec.get()}; }; diff --git a/toolsrc/src/vcpkg_Dependencies.cpp b/toolsrc/src/vcpkg_Dependencies.cpp index 79f572496..726c147fd 100644 --- a/toolsrc/src/vcpkg_Dependencies.cpp +++ b/toolsrc/src/vcpkg_Dependencies.cpp @@ -158,12 +158,12 @@ namespace vcpkg::Dependencies { return &cache_it->second; } - ExpectedT source_control_file = + Parse::ParseExpected source_control_file = Paragraphs::try_load_port(ports.get_filesystem(), ports.port_dir(spec)); if (auto scf = source_control_file.get()) { - auto it = cache.emplace(spec, std::move(*scf)); + auto it = cache.emplace(spec, std::move(*scf->get())); return &it.first->second; } @@ -201,7 +201,7 @@ namespace vcpkg::Dependencies auto it = status_db.find_installed(spec); if (it != status_db.end()) return InstallPlanAction{spec, {*it->get(), nullopt, nullopt}, request_type}; return InstallPlanAction{ - spec, {nullopt, nullopt, port_file_provider.get_control_file(spec)->core_paragraph}, request_type}; + spec, {nullopt, nullopt, *port_file_provider.get_control_file(spec)->core_paragraph}, request_type}; } }; @@ -216,61 +216,6 @@ namespace vcpkg::Dependencies return toposort; } - std::vector create_full_install_plan(const VcpkgPaths& paths, - const std::vector& specs, - const StatusParagraphs& status_db) - { - struct InstallAdjacencyProvider final : Graphs::AdjacencyProvider - { - const VcpkgPaths& paths; - const StatusParagraphs& status_db; - const std::unordered_set& specs_as_set; - - InstallAdjacencyProvider(const VcpkgPaths& p, - const StatusParagraphs& s, - const std::unordered_set& specs_as_set) - : paths(p), status_db(s), specs_as_set(specs_as_set) - { - } - - std::vector adjacency_list(const InstallPlanAction& plan) const override - { - if (plan.any_paragraph.status_paragraph.get()) return std::vector{}; - return plan.any_paragraph.dependencies(plan.spec.triplet()); - } - - InstallPlanAction load_vertex_data(const PackageSpec& spec) const override - { - const RequestType request_type = specs_as_set.find(spec) != specs_as_set.end() - ? RequestType::USER_REQUESTED - : RequestType::AUTO_SELECTED; - auto it = status_db.find_installed(spec); - if (it != status_db.end()) return InstallPlanAction{spec, {*it->get(), nullopt, nullopt}, request_type}; - - Expected maybe_bpgh = Paragraphs::try_load_cached_package(paths, spec); - if (auto bpgh = maybe_bpgh.get()) - return InstallPlanAction{spec, {nullopt, *bpgh, nullopt}, request_type}; - - auto maybe_scf = Paragraphs::try_load_port(paths.get_filesystem(), paths.port_dir(spec)); - if (auto scf = maybe_scf.get()) - return InstallPlanAction{spec, {nullopt, nullopt, *scf->get()->core_paragraph}, request_type}; - - print_error_message(maybe_scf.error()); - Checks::exit_fail(VCPKG_LINE_INFO); - } - }; - - const std::unordered_set specs_as_set(specs.cbegin(), specs.cend()); - std::vector toposort = - Graphs::topological_sort(specs, InstallAdjacencyProvider{paths, status_db, specs_as_set}); - Util::erase_remove_if(toposort, [](const InstallPlanAction& plan) { - return plan.request_type == RequestType::AUTO_SELECTED && - plan.plan_type == InstallPlanType::ALREADY_INSTALLED; - }); - - return toposort; - } - std::vector create_remove_plan(const std::vector& specs, const StatusParagraphs& status_db) { -- cgit v1.2.3 From 7944f9f7779ebbc0923efd27cff268ac23b1c312 Mon Sep 17 00:00:00 2001 From: Daniel Shaw Date: Tue, 27 Jun 2017 14:52:26 -0700 Subject: refactor create_install_plan tests --- toolsrc/include/vcpkg_Dependencies.h | 6 +- toolsrc/src/commands_ci.cpp | 3 +- toolsrc/src/commands_install.cpp | 3 +- toolsrc/src/test_install_plan.cpp | 118 ++++++++++++++++------------------- toolsrc/src/vcpkg_Dependencies.cpp | 14 ++--- 5 files changed, 67 insertions(+), 77 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg_Dependencies.h b/toolsrc/include/vcpkg_Dependencies.h index da31aa4bf..c8e15de27 100644 --- a/toolsrc/include/vcpkg_Dependencies.h +++ b/toolsrc/include/vcpkg_Dependencies.h @@ -97,13 +97,13 @@ namespace vcpkg::Dependencies RequestType request_type; }; - __interface PortFileProvider { virtual const SourceControlFile* get_control_file(const PackageSpec& spec) const; }; + __interface PortFileProvider { virtual const SourceControlFile& get_control_file(const PackageSpec& spec) const; }; struct MapPortFile : PortFileProvider { const std::unordered_map& ports; explicit MapPortFile(const std::unordered_map& map); - const SourceControlFile* get_control_file(const PackageSpec& spec) const override; + const SourceControlFile& get_control_file(const PackageSpec& spec) const override; }; struct PathsPortFile : PortFileProvider @@ -111,7 +111,7 @@ namespace vcpkg::Dependencies const VcpkgPaths& ports; mutable std::unordered_map cache; explicit PathsPortFile(const VcpkgPaths& paths); - const SourceControlFile* get_control_file(const PackageSpec& spec) const override; + const SourceControlFile& get_control_file(const PackageSpec& spec) const override; }; std::vector create_install_plan(const PortFileProvider& port_file_provider, diff --git a/toolsrc/src/commands_ci.cpp b/toolsrc/src/commands_ci.cpp index 5f6fc95b5..95d722302 100644 --- a/toolsrc/src/commands_ci.cpp +++ b/toolsrc/src/commands_ci.cpp @@ -40,8 +40,9 @@ namespace vcpkg::Commands::CI const std::vector specs = load_all_package_specs(paths.get_filesystem(), paths.ports, triplet); StatusParagraphs status_db = database_load_check(paths); + auto paths_port_file = Dependencies::PathsPortFile(paths); const std::vector install_plan = - Dependencies::create_install_plan(Dependencies::PathsPortFile(paths), specs, status_db); + Dependencies::create_install_plan(paths_port_file, specs, status_db); Checks::check_exit(VCPKG_LINE_INFO, !install_plan.empty(), "Install plan cannot be empty"); std::vector results; diff --git a/toolsrc/src/commands_install.cpp b/toolsrc/src/commands_install.cpp index a58432eef..d340a9cf8 100644 --- a/toolsrc/src/commands_install.cpp +++ b/toolsrc/src/commands_install.cpp @@ -359,8 +359,9 @@ namespace vcpkg::Commands::Install // create the plan StatusParagraphs status_db = database_load_check(paths); + auto paths_port_file = Dependencies::PathsPortFile(paths); std::vector install_plan = - Dependencies::create_install_plan(Dependencies::PathsPortFile(paths), specs, status_db); + Dependencies::create_install_plan(paths_port_file, specs, status_db); Checks::check_exit(VCPKG_LINE_INFO, !install_plan.empty(), "Install plan cannot be empty"); // log the plan diff --git a/toolsrc/src/test_install_plan.cpp b/toolsrc/src/test_install_plan.cpp index 2404e30f7..93a1436d8 100644 --- a/toolsrc/src/test_install_plan.cpp +++ b/toolsrc/src/test_install_plan.cpp @@ -9,12 +9,11 @@ namespace UnitTest1 { class InstallPlanTests : public TestClass { - TEST_METHOD(basic_install_scheme) + struct PackageSpecMap { - std::vector> status_paragraphs; - std::unordered_map map; - auto add_scf = [&](std::vector>&& fields) -> PackageSpec { + PackageSpec get_package_spec(std::vector>&& fields) + { auto m_pgh = vcpkg::SourceControlFile::parse_control_file(std::move(fields)); Assert::IsTrue(m_pgh.has_value()); auto& scf = *m_pgh.get(); @@ -23,13 +22,19 @@ namespace UnitTest1 Assert::IsTrue(spec.has_value()); map.emplace(*spec.get(), std::move(*scf.get())); return PackageSpec{*spec.get()}; - }; + } + }; + TEST_METHOD(basic_install_scheme) + { + std::vector> status_paragraphs; + + PackageSpecMap spec_map; - auto spec_a = add_scf({{{"Source", "a"}, {"Version", "1.2.8"}, {"Build-Depends", "b"}}}); - auto spec_b = add_scf({{{"Source", "b"}, {"Version", "1.3"}, {"Build-Depends", "c"}}}); - auto spec_c = add_scf({{{"Source", "c"}, {"Version", "2.5.3"}, {"Build-Depends", ""}}}); + auto spec_a = spec_map.get_package_spec({{{"Source", "a"}, {"Version", "1.2.8"}, {"Build-Depends", "b"}}}); + auto spec_b = spec_map.get_package_spec({{{"Source", "b"}, {"Version", "1.3"}, {"Build-Depends", "c"}}}); + auto spec_c = spec_map.get_package_spec({{{"Source", "c"}, {"Version", "2.5.3"}, {"Build-Depends", ""}}}); - auto map_port = Dependencies::MapPortFile(map); + auto map_port = Dependencies::MapPortFile(spec_map.map); auto install_plan = Dependencies::create_install_plan(map_port, {spec_a}, StatusParagraphs(std::move(status_paragraphs))); @@ -43,43 +48,30 @@ namespace UnitTest1 { std::vector> status_paragraphs; - std::unordered_map map; - auto add_scf = [&](std::vector>&& fields) -> PackageSpec { - auto m_pgh = vcpkg::SourceControlFile::parse_control_file(std::move(fields)); - Assert::IsTrue(m_pgh.has_value()); - auto& scf = *m_pgh.get(); - - auto spec = PackageSpec::from_name_and_triplet(scf->core_paragraph->name, Triplet::X86_WINDOWS); - Assert::IsTrue(spec.has_value()); - map.emplace(*spec.get(), std::move(*scf.get())); - return PackageSpec{*spec.get()}; - }; + PackageSpecMap spec_map; - auto spec_a = add_scf({{{"Source", "a"}, {"Version", "1.2.8"}, {"Build-Depends", "d"}}}); - auto spec_b = add_scf({{{"Source", "b"}, {"Version", "1.3"}, {"Build-Depends", "d, e"}}}); - auto spec_c = add_scf({{{"Source", "c"}, {"Version", "2.5.3"}, {"Build-Depends", "e, h"}}}); - auto spec_d = add_scf({{{"Source", "d"}, {"Version", "4.0"}, {"Build-Depends", "f, g, h"}}}); - auto spec_e = add_scf({{{"Source", "e"}, {"Version", "1.0"}, {"Build-Depends", "g"}}}); - auto spec_f = add_scf({{{"Source", "f"}, {"Version", "1.0"}, {"Build-Depends", ""}}}); - auto spec_g = add_scf({{{"Source", "g"}, {"Version", "1.0"}, {"Build-Depends", ""}}}); - auto spec_h = add_scf({{{"Source", "h"}, {"Version", "1.0"}, {"Build-Depends", ""}}}); + auto spec_a = spec_map.get_package_spec({{{"Source", "a"}, {"Version", "1.2.8"}, {"Build-Depends", "d"}}}); + auto spec_b = spec_map.get_package_spec({{{"Source", "b"}, {"Version", "1.3"}, {"Build-Depends", "d, e"}}}); + auto spec_c = + spec_map.get_package_spec({{{"Source", "c"}, {"Version", "2.5.3"}, {"Build-Depends", "e, h"}}}); + auto spec_d = + spec_map.get_package_spec({{{"Source", "d"}, {"Version", "4.0"}, {"Build-Depends", "f, g, h"}}}); + auto spec_e = spec_map.get_package_spec({{{"Source", "e"}, {"Version", "1.0"}, {"Build-Depends", "g"}}}); + auto spec_f = spec_map.get_package_spec({{{"Source", "f"}, {"Version", "1.0"}, {"Build-Depends", ""}}}); + auto spec_g = spec_map.get_package_spec({{{"Source", "g"}, {"Version", "1.0"}, {"Build-Depends", ""}}}); + auto spec_h = spec_map.get_package_spec({{{"Source", "h"}, {"Version", "1.0"}, {"Build-Depends", ""}}}); - auto map_port = Dependencies::MapPortFile(map); + auto map_port = Dependencies::MapPortFile(spec_map.map); auto install_plan = Dependencies::create_install_plan( map_port, {spec_a, spec_b, spec_c}, StatusParagraphs(std::move(status_paragraphs))); auto iterator_pos = [&](const PackageSpec& spec) -> int { - int counter = 0; - for (auto&& install_p : install_plan) - { - if (install_p.spec == spec) - { - return counter; - } - counter++; - } - return -1; + auto it = std::find_if( + install_plan.begin(), install_plan.end(), [&](auto& action) { return action.spec == spec; }); + Assert::IsTrue(it != install_plan.end()); + return (int)(it - install_plan.begin()); }; + int a_pos = iterator_pos(spec_a), b_pos = iterator_pos(spec_b), c_pos = iterator_pos(spec_c), d_pos = iterator_pos(spec_d), e_pos = iterator_pos(spec_e), f_pos = iterator_pos(spec_f), g_pos = iterator_pos(spec_g), h_pos = iterator_pos(spec_h); @@ -112,32 +104,28 @@ namespace UnitTest1 {"Depends", ""}, {"Status", "install ok installed"}})); - std::unordered_map map; - auto add_scf = [&](std::vector>&& fields) -> PackageSpec { - auto m_pgh = vcpkg::SourceControlFile::parse_control_file(std::move(fields)); - Assert::IsTrue(m_pgh.has_value()); - auto& scf = *m_pgh.get(); - - auto spec = PackageSpec::from_name_and_triplet(scf->core_paragraph->name, Triplet::X86_WINDOWS); - Assert::IsTrue(spec.has_value()); - map.emplace(*spec.get(), std::move(*scf.get())); - return PackageSpec{*spec.get()}; - }; - - auto spec_h = add_scf({{{"Source", "h"}, {"Version", "1.2.8"}, {"Build-Depends", "j, k"}}}); - auto spec_c = add_scf({{{"Source", "c"}, {"Version", "1.2.8"}, {"Build-Depends", "d, e, f, g, h, j, k"}}}); - auto spec_k = add_scf({{{"Source", "k"}, {"Version", "1.2.8"}, {"Build-Depends", ""}}}); - auto spec_b = - add_scf({{{"Source", "b"}, {"Version", "1.2.8"}, {"Build-Depends", "c, d, e, f, g, h, j, k"}}}); - auto spec_d = add_scf({{{"Source", "d"}, {"Version", "1.2.8"}, {"Build-Depends", "e, f, g, h, j, k"}}}); - auto spec_j = add_scf({{{"Source", "j"}, {"Version", "1.2.8"}, {"Build-Depends", "k"}}}); - auto spec_f = add_scf({{{"Source", "f"}, {"Version", "1.2.8"}, {"Build-Depends", "g, h, j, k"}}}); - auto spec_e = add_scf({{{"Source", "e"}, {"Version", "1.2.8"}, {"Build-Depends", "f, g, h, j, k"}}}); - auto spec_a = - add_scf({{{"Source", "a"}, {"Version", "1.2.8"}, {"Build-Depends", "b, c, d, e, f, g, h, j, k"}}}); - auto spec_g = add_scf({{{"Source", "g"}, {"Version", "1.2.8"}, {"Build-Depends", "h, j, k"}}}); - - auto map_port = Dependencies::MapPortFile(map); + PackageSpecMap spec_map; + + auto spec_h = + spec_map.get_package_spec({{{"Source", "h"}, {"Version", "1.2.8"}, {"Build-Depends", "j, k"}}}); + auto spec_c = spec_map.get_package_spec( + {{{"Source", "c"}, {"Version", "1.2.8"}, {"Build-Depends", "d, e, f, g, h, j, k"}}}); + auto spec_k = spec_map.get_package_spec({{{"Source", "k"}, {"Version", "1.2.8"}, {"Build-Depends", ""}}}); + auto spec_b = spec_map.get_package_spec( + {{{"Source", "b"}, {"Version", "1.2.8"}, {"Build-Depends", "c, d, e, f, g, h, j, k"}}}); + auto spec_d = spec_map.get_package_spec( + {{{"Source", "d"}, {"Version", "1.2.8"}, {"Build-Depends", "e, f, g, h, j, k"}}}); + auto spec_j = spec_map.get_package_spec({{{"Source", "j"}, {"Version", "1.2.8"}, {"Build-Depends", "k"}}}); + auto spec_f = + spec_map.get_package_spec({{{"Source", "f"}, {"Version", "1.2.8"}, {"Build-Depends", "g, h, j, k"}}}); + auto spec_e = spec_map.get_package_spec( + {{{"Source", "e"}, {"Version", "1.2.8"}, {"Build-Depends", "f, g, h, j, k"}}}); + auto spec_a = spec_map.get_package_spec( + {{{"Source", "a"}, {"Version", "1.2.8"}, {"Build-Depends", "b, c, d, e, f, g, h, j, k"}}}); + auto spec_g = + spec_map.get_package_spec({{{"Source", "g"}, {"Version", "1.2.8"}, {"Build-Depends", "h, j, k"}}}); + + auto map_port = Dependencies::MapPortFile(spec_map.map); auto install_plan = Dependencies::create_install_plan(map_port, {spec_a}, StatusParagraphs(std::move(status_paragraphs))); diff --git a/toolsrc/src/vcpkg_Dependencies.cpp b/toolsrc/src/vcpkg_Dependencies.cpp index 726c147fd..984d0ab4c 100644 --- a/toolsrc/src/vcpkg_Dependencies.cpp +++ b/toolsrc/src/vcpkg_Dependencies.cpp @@ -140,23 +140,23 @@ namespace vcpkg::Dependencies } MapPortFile::MapPortFile(const std::unordered_map& map) : ports(map){}; - const SourceControlFile* MapPortFile::get_control_file(const PackageSpec& spec) const + const SourceControlFile& MapPortFile::get_control_file(const PackageSpec& spec) const { auto scf = ports.find(spec); if (scf == ports.end()) { Checks::exit_fail(VCPKG_LINE_INFO); } - return &scf->second; + return scf->second; } PathsPortFile::PathsPortFile(const VcpkgPaths& paths) : ports(paths){}; - const SourceControlFile* PathsPortFile::get_control_file(const PackageSpec& spec) const + const SourceControlFile& PathsPortFile::get_control_file(const PackageSpec& spec) const { std::unordered_map::iterator cache_it = cache.find(spec); if (cache_it != cache.end()) { - return &cache_it->second; + return cache_it->second; } Parse::ParseExpected source_control_file = Paragraphs::try_load_port(ports.get_filesystem(), ports.port_dir(spec)); @@ -164,9 +164,9 @@ namespace vcpkg::Dependencies if (auto scf = source_control_file.get()) { auto it = cache.emplace(spec, std::move(*scf->get())); - return &it.first->second; + return it.first->second; } - + print_error_message(source_control_file.error()); Checks::exit_fail(VCPKG_LINE_INFO); } @@ -201,7 +201,7 @@ namespace vcpkg::Dependencies auto it = status_db.find_installed(spec); if (it != status_db.end()) return InstallPlanAction{spec, {*it->get(), nullopt, nullopt}, request_type}; return InstallPlanAction{ - spec, {nullopt, nullopt, *port_file_provider.get_control_file(spec)->core_paragraph}, request_type}; + spec, {nullopt, nullopt, *port_file_provider.get_control_file(spec).core_paragraph}, request_type}; } }; -- cgit v1.2.3 From 4267c86b1f7cfe20e88fe7a1eaaa4caaca8c5d77 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Fri, 7 Jul 2017 17:19:19 -0700 Subject: [grpc] Use vcpkg_copy_tool_dependencies --- toolsrc/src/PostBuildLint.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/PostBuildLint.cpp b/toolsrc/src/PostBuildLint.cpp index 82d50a68f..8e11ae5b1 100644 --- a/toolsrc/src/PostBuildLint.cpp +++ b/toolsrc/src/PostBuildLint.cpp @@ -775,15 +775,15 @@ namespace vcpkg::PostBuildLint error_count += check_lib_architecture(pre_build_info.target_architecture, libs); } + std::vector debug_dlls = fs.get_files_recursive(debug_bin_dir); + Util::unstable_keep_if(debug_dlls, has_extension_pred(fs, ".dll")); + std::vector release_dlls = fs.get_files_recursive(release_bin_dir); + Util::unstable_keep_if(release_dlls, has_extension_pred(fs, ".dll")); + switch (build_info.library_linkage) { case Build::LinkageType::DYNAMIC: { - std::vector debug_dlls = fs.get_files_recursive(debug_bin_dir); - Util::unstable_keep_if(debug_dlls, has_extension_pred(fs, ".dll")); - std::vector 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); error_count += check_lib_files_are_available_if_dlls_are_available( @@ -804,8 +804,8 @@ namespace vcpkg::PostBuildLint } case Build::LinkageType::STATIC: { - std::vector dlls = fs.get_files_recursive(package_dir); - Util::unstable_keep_if(dlls, has_extension_pred(fs, ".dll")); + auto dlls = release_dlls; + dlls.insert(dlls.end(), debug_dlls.begin(), debug_dlls.end()); error_count += check_no_dlls_present(dlls); error_count += check_bin_folders_are_not_present_in_static_build(fs, package_dir); -- cgit v1.2.3 From 6f31f2d1b92f19cf8972dff67a5ef79905942a8d Mon Sep 17 00:00:00 2001 From: Maktm Date: Sun, 9 Jul 2017 01:28:51 -0500 Subject: Adds a missing new line statement --- toolsrc/src/commands_help.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/commands_help.cpp b/toolsrc/src/commands_help.cpp index a9f9956fe..e4be11a77 100644 --- a/toolsrc/src/commands_help.cpp +++ b/toolsrc/src/commands_help.cpp @@ -56,7 +56,7 @@ namespace vcpkg::Commands::Help std::string create_example_string(const std::string& command_and_arguments) { std::string cs = Strings::format("Example:\n" - " vcpkg %s", + " vcpkg %s\n", command_and_arguments); return cs; } -- cgit v1.2.3 From fe602fc3581e3e9d99a64d759a45fc63d49f7f59 Mon Sep 17 00:00:00 2001 From: atkawa7 Date: Tue, 11 Jul 2017 08:58:15 -0700 Subject: [vcpkg] remove flushall --- toolsrc/src/vcpkg_System.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg_System.cpp b/toolsrc/src/vcpkg_System.cpp index c91c6be78..883fe6612 100644 --- a/toolsrc/src/vcpkg_System.cpp +++ b/toolsrc/src/vcpkg_System.cpp @@ -94,7 +94,7 @@ namespace vcpkg::System }; // Flush stdout before launching external process - _flushall(); + fflush(nullptr); std::vector env_cstr; env_cstr.reserve(env_wstrings.size() + 2); @@ -125,7 +125,7 @@ namespace vcpkg::System int cmd_execute(const CWStringView cmd_line) { // Flush stdout before launching external process - _flushall(); + fflush(nullptr); // Basically we are wrapping it in quotes const std::wstring& actual_cmd_line = Strings::wformat(LR"###("%s")###", cmd_line); -- cgit v1.2.3 From e9ba08be3aeaaea3cfc5a8455fac41384e2d7f93 Mon Sep 17 00:00:00 2001 From: atkawa7 Date: Wed, 12 Jul 2017 20:28:14 -0700 Subject: [vcpkg] remove platform dependency of string format --- toolsrc/src/vcpkg_Strings.cpp | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg_Strings.cpp b/toolsrc/src/vcpkg_Strings.cpp index aafed5fd3..77ff1a106 100644 --- a/toolsrc/src/vcpkg_Strings.cpp +++ b/toolsrc/src/vcpkg_Strings.cpp @@ -19,26 +19,36 @@ namespace vcpkg::Strings::details std::string format_internal(const char* fmtstr, ...) { - va_list lst; - va_start(lst, fmtstr); + va_list args; + va_start(args, fmtstr); - const int sz = _vscprintf_l(fmtstr, c_locale(), lst); - std::string output(sz, '\0'); - _vsnprintf_s_l(&output[0], output.size() + 1, output.size() + 1, fmtstr, c_locale(), lst); - va_end(lst); + int sz = vsnprintf(nullptr, 0, fmtstr, args) + 1; + + char* buffer = new char[sz]; + + vsnprintf(buffer, sz, fmtstr, args); + va_end(args); + + std::string output(buffer); + delete[] buffer; return output; } std::wstring wformat_internal(const wchar_t* fmtstr, ...) { - va_list lst; - va_start(lst, fmtstr); + va_list args; + va_start(args, fmtstr); + + int sz = vswprintf(nullptr, 0, fmtstr, args) + 1; + + wchar_t* buffer = new wchar_t[sz]; + + vswprintf(buffer, sz, fmtstr, args); + va_end(args); - const int sz = _vscwprintf_l(fmtstr, c_locale(), lst); - std::wstring output(sz, '\0'); - _vsnwprintf_s_l(&output[0], output.size() + 1, output.size() + 1, fmtstr, c_locale(), lst); - va_end(lst); + std::wstring output(buffer); + delete[] buffer; return output; } -- cgit v1.2.3 From 336e25218a73f9b54120e3c35b3d28e6426deeb1 Mon Sep 17 00:00:00 2001 From: Daniel Shaw Date: Wed, 12 Jul 2017 17:40:41 -0700 Subject: feature packages graph traversal --- toolsrc/include/BinaryParagraph.h | 4 +- toolsrc/include/vcpkg_Dependencies.h | 89 ++++++++++ toolsrc/include/vcpkg_Graphs.h | 93 +++++++++++ toolsrc/include/vcpkg_Util.h | 1 + toolsrc/src/BinaryParagraph.cpp | 11 +- toolsrc/src/PackageSpec.cpp | 5 +- toolsrc/src/test_install_plan.cpp | 308 +++++++++++++++++++++++++++++++++++ toolsrc/src/vcpkg_Dependencies.cpp | 244 +++++++++++++++++++++++++++ 8 files changed, 752 insertions(+), 3 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/BinaryParagraph.h b/toolsrc/include/BinaryParagraph.h index 1c2edf790..4adde5e36 100644 --- a/toolsrc/include/BinaryParagraph.h +++ b/toolsrc/include/BinaryParagraph.h @@ -25,8 +25,10 @@ namespace vcpkg std::string version; std::string description; std::string maintainer; + std::string feature; + std::vector default_features; std::vector depends; }; void serialize(const BinaryParagraph& pgh, std::string& out_str); -} +} \ No newline at end of file diff --git a/toolsrc/include/vcpkg_Dependencies.h b/toolsrc/include/vcpkg_Dependencies.h index c8e15de27..92523a654 100644 --- a/toolsrc/include/vcpkg_Dependencies.h +++ b/toolsrc/include/vcpkg_Dependencies.h @@ -2,6 +2,7 @@ #include "PackageSpec.h" #include "StatusParagraphs.h" #include "VcpkgPaths.h" +#include "vcpkg_Graphs.h" #include "vcpkg_optional.h" #include @@ -23,6 +24,45 @@ namespace vcpkg::Dependencies Optional status_paragraph; Optional binary_paragraph; Optional source_paragraph; + Optional source_control_file; + }; + + struct ClusterNode + { + std::vector status_paragraphs; + Optional source_paragraph; + }; +} + +namespace vcpkg::Dependencies +{ + struct FeatureSpec + { + PackageSpec spec; + std::string feature_name; + }; + + struct FeatureNodeEdges + { + std::vector dotted; + std::vector dashed; + bool plus = false; + }; + std::vector to_feature_specs(const std::vector depends, + const std::unordered_map str_to_spec); + struct Cluster + { + ClusterNode cluster_node; + std::unordered_map edges; + std::unordered_set tracked_nodes; + std::unordered_set original_nodes; + bool minus = false; + bool zero = true; + Cluster() = default; + + private: + Cluster(const Cluster&) = delete; + Cluster& operator=(const Cluster&) = delete; }; enum class InstallPlanType @@ -39,6 +79,10 @@ namespace vcpkg::Dependencies InstallPlanAction(); InstallPlanAction(const PackageSpec& spec, const AnyParagraph& any_paragraph, const RequestType& request_type); + InstallPlanAction(const PackageSpec& spec, + const SourceControlFile& any_paragraph, + std::unordered_set features, + const RequestType& request_type); InstallPlanAction(const InstallPlanAction&) = delete; InstallPlanAction(InstallPlanAction&&) = default; InstallPlanAction& operator=(const InstallPlanAction&) = delete; @@ -48,6 +92,7 @@ namespace vcpkg::Dependencies AnyParagraph any_paragraph; InstallPlanType plan_type; RequestType request_type; + std::unordered_set feature_list; }; enum class RemovePlanType @@ -73,6 +118,12 @@ namespace vcpkg::Dependencies RequestType request_type; }; + struct AnyAction + { + Optional install_plan; + Optional remove_plan; + }; + enum class ExportPlanType { UNKNOWN, @@ -125,3 +176,41 @@ namespace vcpkg::Dependencies const std::vector& specs, const StatusParagraphs& status_db); } + +template<> +struct std::hash +{ + size_t operator()(const vcpkg::Dependencies::Cluster& value) const + { + size_t hash = 17; + if (auto source = value.cluster_node.source_paragraph.get()) + { + hash = hash * 31 + std::hash()((*source)->core_paragraph->name); + } + else if (!value.cluster_node.status_paragraphs.empty()) + { + auto start = *value.cluster_node.status_paragraphs.begin(); + hash = hash * 31 + std::hash()(start.package.displayname()); + } + + return hash; + } +}; + +namespace vcpkg::Dependencies +{ + struct GraphPlan + { + Graphs::Graph remove_graph; + Graphs::Graph install_graph; + }; + bool mark_plus(const std::string& feature, + Cluster& cluster, + std::unordered_map& pkg_to_cluster, + GraphPlan& graph_plan); + void mark_minus(Cluster& cluster, std::unordered_map& pkg_to_cluster, GraphPlan& graph_plan); + + std::vector create_feature_install_plan(const std::unordered_map& map, + const std::vector& specs, + const StatusParagraphs& status_db); +} diff --git a/toolsrc/include/vcpkg_Graphs.h b/toolsrc/include/vcpkg_Graphs.h index 3c8c024c2..13c0a7136 100644 --- a/toolsrc/include/vcpkg_Graphs.h +++ b/toolsrc/include/vcpkg_Graphs.h @@ -1,6 +1,7 @@ #pragma once #include +#include namespace vcpkg::Graphs { @@ -63,4 +64,96 @@ namespace vcpkg::Graphs return sorted; } + + template + struct GraphAdjacencyProvider final : AdjacencyProvider + { + const std::unordered_map>& vertices; + + GraphAdjacencyProvider(const std::unordered_map>& vertices) : vertices(vertices) {} + + std::vector adjacency_list(const V& vertex) const override + { + const std::unordered_set& as_set = this->vertices.at(vertex); + return std::vector(as_set.cbegin(), as_set.cend()); // TODO: Avoid redundant copy + } + + V load_vertex_data(const V& vertex) const override { return vertex; } + }; + + template + struct Graph + { + public: + void add_vertex(V v) { this->vertices[v]; } + + // TODO: Change with iterators + void add_vertices(const std::vector& vs) + { + for (const V& v : vs) + { + this->vertices[v]; + } + } + + void add_edge(V u, V v) + { + this->vertices[v]; + this->vertices[u].insert(v); + } + + std::vector topological_sort() const + { + GraphAdjacencyProvider adjacency_provider{this->vertices}; + std::unordered_map indegrees = count_indegrees(); + + std::vector sorted; + sorted.reserve(indegrees.size()); + + std::unordered_map exploration_status; + exploration_status.reserve(indegrees.size()); + + for (auto& pair : indegrees) + { + if (pair.second == 0) // Starting from vertices with indegree == 0. Not required. + { + V vertex = pair.first; + topological_sort_internal(vertex, adjacency_provider, exploration_status, sorted); + } + } + + return sorted; + } + + std::unordered_map count_indegrees() const + { + std::unordered_map indegrees; + + for (auto& pair : this->vertices) + { + indegrees[pair.first]; + for (V neighbour : pair.second) + { + ++indegrees[neighbour]; + } + } + + return indegrees; + } + + const std::unordered_map>& adjacency_list() const { return this->vertices; } + std::vector vertex_list() const + { + // why no &? it returns 0 + std::vector vertex_list; + for (const auto& vertex : this->vertices) + { + vertex_list.emplace_back(vertex.first); + } + return vertex_list; + } + + private: + std::unordered_map> vertices; + }; } diff --git a/toolsrc/include/vcpkg_Util.h b/toolsrc/include/vcpkg_Util.h index 1bd1bcc4a..671997e7e 100644 --- a/toolsrc/include/vcpkg_Util.h +++ b/toolsrc/include/vcpkg_Util.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include diff --git a/toolsrc/src/BinaryParagraph.cpp b/toolsrc/src/BinaryParagraph.cpp index af76c6b29..e126054a8 100644 --- a/toolsrc/src/BinaryParagraph.cpp +++ b/toolsrc/src/BinaryParagraph.cpp @@ -16,9 +16,11 @@ namespace vcpkg namespace Fields { + static const std::string FEATURE = "Feature"; static const std::string DESCRIPTION = "Description"; static const std::string MAINTAINER = "Maintainer"; static const std::string DEPENDS = "Depends"; + static const std::string DEFAULTFEATURES = "Default-Features"; } BinaryParagraph::BinaryParagraph() = default; @@ -38,7 +40,10 @@ namespace vcpkg .value_or_exit(VCPKG_LINE_INFO); } - parser.required_field(Fields::VERSION, this->version); + // one or the other + this->version = parser.optional_field(Fields::VERSION); + this->feature = parser.optional_field(Fields::FEATURE); + this->description = parser.optional_field(Fields::DESCRIPTION); this->maintainer = parser.optional_field(Fields::MAINTAINER); @@ -46,6 +51,10 @@ namespace vcpkg parser.required_field(Fields::MULTI_ARCH, multi_arch); this->depends = parse_comma_list(parser.optional_field(Fields::DEPENDS)); + if (this->feature.empty()) + { + this->default_features = parse_comma_list(parser.optional_field(Fields::DEFAULTFEATURES)); + } if (auto err = parser.error_info(this->spec.name())) { diff --git a/toolsrc/src/PackageSpec.cpp b/toolsrc/src/PackageSpec.cpp index ab005f255..12217ac98 100644 --- a/toolsrc/src/PackageSpec.cpp +++ b/toolsrc/src/PackageSpec.cpp @@ -5,7 +5,10 @@ namespace vcpkg { - static bool is_valid_package_spec_char(char c) { return (c == '-') || isdigit(c) || (isalpha(c) && islower(c)); } + static bool is_valid_package_spec_char(char c) + { + return (c == '-') || isdigit(c) || (isalpha(c) && islower(c)) || (c == '[') || (c == ']'); + } ExpectedT PackageSpec::from_string(const std::string& spec_as_string, const Triplet& default_triplet) diff --git a/toolsrc/src/test_install_plan.cpp b/toolsrc/src/test_install_plan.cpp index 93a1436d8..d90e1e523 100644 --- a/toolsrc/src/test_install_plan.cpp +++ b/toolsrc/src/test_install_plan.cpp @@ -1,5 +1,6 @@ #include "CppUnitTest.h" #include "vcpkg_Dependencies.h" +#include "vcpkg_Util.h" using namespace Microsoft::VisualStudio::CppUnitTestFramework; @@ -24,6 +25,35 @@ namespace UnitTest1 return PackageSpec{*spec.get()}; } }; + + static void features_check(Dependencies::AnyAction* install_action, + std::string pkg_name, + std::vector vec) + { + const auto& plan = *install_action->install_plan.get(); + const auto& feature_list = plan.feature_list; + + Assert::AreEqual(pkg_name.c_str(), + (*plan.any_paragraph.source_control_file.get())->core_paragraph->name.c_str()); + Assert::AreEqual(size_t(vec.size()), feature_list.size()); + + for (auto&& feature_name : vec) + { + if (feature_name == "core" || feature_name == "") + { + Assert::IsTrue(Util::find(feature_list, "core") != feature_list.end() || + Util::find(feature_list, "") != feature_list.end()); + continue; + } + Assert::IsTrue(Util::find(feature_list, feature_name) != feature_list.end()); + } + } + + static void remove_plan_check(Dependencies::AnyAction* install_action, std::string pkg_name) + { + Assert::AreEqual(pkg_name.c_str(), install_action->remove_plan.get()->spec.name().c_str()); + } + TEST_METHOD(basic_install_scheme) { std::vector> status_paragraphs; @@ -139,5 +169,283 @@ namespace UnitTest1 Assert::AreEqual("b", install_plan[6].spec.name().c_str()); Assert::AreEqual("a", install_plan[7].spec.name().c_str()); } + + TEST_METHOD(basic_feature_test_1) + { + using Pgh = std::unordered_map; + + std::vector> status_paragraphs; + status_paragraphs.push_back(std::make_unique(Pgh{{"Package", "a"}, + {"Default-Features", ""}, + {"Version", "1.3.8"}, + {"Architecture", "x86-windows"}, + {"Multi-Arch", "same"}, + {"Depends", "b, b[beefeatureone]"}, + {"Status", "install ok installed"}})); + status_paragraphs.push_back(std::make_unique(Pgh{{"Package", "b"}, + {"Feature", "beefeatureone"}, + {"Architecture", "x86-windows"}, + {"Multi-Arch", "same"}, + {"Depends", ""}, + {"Status", "install ok installed"}})); + status_paragraphs.push_back(std::make_unique(Pgh{{"Package", "b"}, + {"Default-Features", "beefeatureone"}, + {"Version", "1.3"}, + {"Architecture", "x86-windows"}, + {"Multi-Arch", "same"}, + {"Depends", ""}, + {"Status", "install ok installed"}})); + + PackageSpecMap spec_map; + + auto spec_a = + FullPackageSpec{spec_map.get_package_spec( + {{{"Source", "a"}, {"Version", "1.3.8"}, {"Build-Depends", "b, b[beefeatureone]"}}, + {{"Feature", "featureone"}, + {"Description", "the first feature for a"}, + {"Build-Depends", "b[beefeaturetwo]"}} + + }), + {"featureone"}}; + auto spec_b = FullPackageSpec{spec_map.get_package_spec( + {{{"Source", "b"}, {"Version", "1.3"}, {"Build-Depends", ""}}, + {{"Feature", "beefeatureone"}, {"Description", "the first feature for b"}, {"Build-Depends", ""}}, + {{"Feature", "beefeaturetwo"}, {"Description", "the second feature for b"}, {"Build-Depends", ""}}, + {{"Feature", "beefeaturethree"}, {"Description", "the third feature for b"}, {"Build-Depends", ""}} + + })}; + + auto install_plan = Dependencies::create_feature_install_plan( + spec_map.map, {spec_a}, StatusParagraphs(std::move(status_paragraphs))); + + Assert::AreEqual(size_t(4), install_plan.size()); + remove_plan_check(&install_plan[0], "a"); + remove_plan_check(&install_plan[1], "b"); + features_check(&install_plan[2], "b", {"beefeatureone", "core", "beefeatureone"}); + features_check(&install_plan[3], "a", {"featureone", "core"}); + } + + TEST_METHOD(basic_feature_test_2) + { + using Pgh = std::unordered_map; + + std::vector> status_paragraphs; + + PackageSpecMap spec_map; + + auto spec_a = + FullPackageSpec{spec_map.get_package_spec( + {{{"Source", "a"}, {"Version", "1.3.8"}, {"Build-Depends", "b[beefeatureone]"}}, + {{"Feature", "featureone"}, + {"Description", "the first feature for a"}, + {"Build-Depends", "b[beefeaturetwo]"}} + + }), + {"featureone"}}; + auto spec_b = FullPackageSpec{spec_map.get_package_spec( + {{{"Source", "b"}, {"Version", "1.3"}, {"Build-Depends", ""}}, + {{"Feature", "beefeatureone"}, {"Description", "the first feature for b"}, {"Build-Depends", ""}}, + {{"Feature", "beefeaturetwo"}, {"Description", "the second feature for b"}, {"Build-Depends", ""}}, + {{"Feature", "beefeaturethree"}, {"Description", "the third feature for b"}, {"Build-Depends", ""}} + + })}; + + auto install_plan = Dependencies::create_feature_install_plan( + spec_map.map, {spec_a}, StatusParagraphs(std::move(status_paragraphs))); + + Assert::AreEqual(size_t(2), install_plan.size()); + features_check(&install_plan[0], "b", {"beefeatureone", "beefeaturetwo", "core"}); + features_check(&install_plan[1], "a", {"featureone", "core"}); + } + + TEST_METHOD(basic_feature_test_3) + { + using Pgh = std::unordered_map; + + std::vector> status_paragraphs; + status_paragraphs.push_back(std::make_unique(Pgh{{"Package", "a"}, + {"Default-Features", ""}, + {"Version", "1.3"}, + {"Architecture", "x86-windows"}, + {"Multi-Arch", "same"}, + {"Depends", ""}, + {"Status", "install ok installed"}})); + + PackageSpecMap spec_map; + + auto spec_a = FullPackageSpec{ + spec_map.get_package_spec( + {{{"Source", "a"}, {"Version", "1.3"}, {"Build-Depends", "b"}}, + {{"Feature", "one"}, {"Description", "the first feature for a"}, {"Build-Depends", ""}}}), + {"core"}}; + auto spec_b = FullPackageSpec{spec_map.get_package_spec({ + {{"Source", "b"}, {"Version", "1.3"}, {"Build-Depends", ""}}, + })}; + auto spec_c = FullPackageSpec{spec_map.get_package_spec({ + {{"Source", "c"}, {"Version", "1.3"}, {"Build-Depends", "a[one]"}}, + }), + {"core"}}; + + auto install_plan = Dependencies::create_feature_install_plan( + spec_map.map, {spec_c, spec_a}, StatusParagraphs(std::move(status_paragraphs))); + + Assert::AreEqual(size_t(4), install_plan.size()); + remove_plan_check(&install_plan[0], "a"); + features_check(&install_plan[1], "b", {"core"}); + features_check(&install_plan[2], "a", {"one", "core"}); + features_check(&install_plan[3], "c", {"core"}); + } + + TEST_METHOD(basic_feature_test_4) + { + using Pgh = std::unordered_map; + + std::vector> status_paragraphs; + status_paragraphs.push_back(std::make_unique(Pgh{{"Package", "a"}, + {"Default-Features", ""}, + {"Version", "1.3"}, + {"Architecture", "x86-windows"}, + {"Multi-Arch", "same"}, + {"Depends", ""}, + {"Status", "install ok installed"}})); + status_paragraphs.push_back(std::make_unique(Pgh{{"Package", "a"}, + {"Feature", "one"}, + {"Architecture", "x86-windows"}, + {"Multi-Arch", "same"}, + {"Depends", ""}, + {"Status", "install ok installed"}})); + + PackageSpecMap spec_map; + + auto spec_a = FullPackageSpec{ + spec_map.get_package_spec( + {{{"Source", "a"}, {"Version", "1.3"}, {"Build-Depends", "b"}}, + {{"Feature", "one"}, {"Description", "the first feature for a"}, {"Build-Depends", ""}}}), + }; + auto spec_b = FullPackageSpec{spec_map.get_package_spec({ + {{"Source", "b"}, {"Version", "1.3"}, {"Build-Depends", ""}}, + })}; + auto spec_c = FullPackageSpec{spec_map.get_package_spec({ + {{"Source", "c"}, {"Version", "1.3"}, {"Build-Depends", "a[one]"}}, + }), + {"core"}}; + + auto install_plan = Dependencies::create_feature_install_plan( + spec_map.map, {spec_c}, StatusParagraphs(std::move(status_paragraphs))); + + Assert::AreEqual(size_t(1), install_plan.size()); + features_check(&install_plan[0], "c", {"core"}); + } + + TEST_METHOD(basic_feature_test_5) + { + using Pgh = std::unordered_map; + + std::vector> status_paragraphs; + + PackageSpecMap spec_map; + + auto spec_a = FullPackageSpec{ + spec_map.get_package_spec( + {{{"Source", "a"}, {"Version", "1.3"}, {"Build-Depends", ""}}, + {{"Feature", "1"}, {"Description", "the first feature for a"}, {"Build-Depends", "b[1]"}}, + {{"Feature", "2"}, {"Description", "the first feature for a"}, {"Build-Depends", "b[2]"}}, + {{"Feature", "3"}, {"Description", "the first feature for a"}, {"Build-Depends", "a[2]"}}}), + {"3"}}; + auto spec_b = FullPackageSpec{spec_map.get_package_spec({ + {{"Source", "b"}, {"Version", "1.3"}, {"Build-Depends", ""}}, + {{"Feature", "1"}, {"Description", "the first feature for a"}, {"Build-Depends", ""}}, + {{"Feature", "2"}, {"Description", "the first feature for a"}, {"Build-Depends", ""}}, + })}; + + auto install_plan = Dependencies::create_feature_install_plan( + spec_map.map, {spec_a}, StatusParagraphs(std::move(status_paragraphs))); + + Assert::AreEqual(size_t(2), install_plan.size()); + features_check(&install_plan[0], "b", {"core", "2"}); + features_check(&install_plan[1], "a", {"core", "3", "2"}); + } + + TEST_METHOD(basic_feature_test_6) + { + using Pgh = std::unordered_map; + + std::vector> status_paragraphs; + status_paragraphs.push_back(std::make_unique(Pgh{{"Package", "b"}, + {"Default-Features", ""}, + {"Version", "1.3"}, + {"Architecture", "x86-windows"}, + {"Multi-Arch", "same"}, + {"Depends", ""}, + {"Status", "install ok installed"}})); + PackageSpecMap spec_map; + + auto spec_a = FullPackageSpec{spec_map.get_package_spec({ + {{"Source", "a"}, {"Version", "1.3"}, {"Build-Depends", "b[core]"}}, + }), + {"core"}}; + auto spec_b = FullPackageSpec{ + spec_map.get_package_spec({ + {{"Source", "b"}, {"Version", "1.3"}, {"Build-Depends", ""}}, + {{"Feature", "1"}, {"Description", "the first feature for a"}, {"Build-Depends", ""}}, + }), + {"1"}}; + + auto install_plan = Dependencies::create_feature_install_plan( + spec_map.map, {spec_a, spec_b}, StatusParagraphs(std::move(status_paragraphs))); + + Assert::AreEqual(size_t(3), install_plan.size()); + remove_plan_check(&install_plan[0], "b"); + features_check(&install_plan[1], "b", {"core", "1"}); + features_check(&install_plan[2], "a", {"core"}); + } + + TEST_METHOD(basic_feature_test_7) + { + using Pgh = std::unordered_map; + + std::vector> status_paragraphs; + status_paragraphs.push_back(std::make_unique(Pgh{{"Package", "x"}, + {"Default-Features", ""}, + {"Version", "1.3"}, + {"Architecture", "x86-windows"}, + {"Multi-Arch", "same"}, + {"Depends", "b"}, + {"Status", "install ok installed"}})); + status_paragraphs.push_back(std::make_unique(Pgh{{"Package", "b"}, + {"Default-Features", ""}, + {"Version", "1.3"}, + {"Architecture", "x86-windows"}, + {"Multi-Arch", "same"}, + {"Depends", ""}, + {"Status", "install ok installed"}})); + PackageSpecMap spec_map; + + auto spec_a = FullPackageSpec{spec_map.get_package_spec({ + {{"Source", "a"}, {"Version", "1.3"}, {"Build-Depends", ""}}, + })}; + auto spec_x = FullPackageSpec{spec_map.get_package_spec({ + {{"Source", "x"}, {"Version", "1.3"}, {"Build-Depends", "a"}}, + }), + {"core"}}; + auto spec_b = FullPackageSpec{ + spec_map.get_package_spec({ + {{"Source", "b"}, {"Version", "1.3"}, {"Build-Depends", ""}, {"Default-Features", ""}}, + {{"Feature", "1"}, {"Description", "the first feature for a"}, {"Build-Depends", ""}}, + }), + {"1"}}; + + auto install_plan = Dependencies::create_feature_install_plan( + spec_map.map, {spec_b, spec_x}, StatusParagraphs(std::move(status_paragraphs))); + + Assert::AreEqual(size_t(5), install_plan.size()); + remove_plan_check(&install_plan[0], "x"); + remove_plan_check(&install_plan[1], "b"); + + // order here may change but A < X, and B anywhere + features_check(&install_plan[2], "a", {"core"}); + features_check(&install_plan[3], "x", {"core"}); + features_check(&install_plan[4], "b", {"core", "1"}); + } }; } \ No newline at end of file diff --git a/toolsrc/src/vcpkg_Dependencies.cpp b/toolsrc/src/vcpkg_Dependencies.cpp index 984d0ab4c..824de15e1 100644 --- a/toolsrc/src/vcpkg_Dependencies.cpp +++ b/toolsrc/src/vcpkg_Dependencies.cpp @@ -54,6 +54,20 @@ namespace vcpkg::Dependencies { } + InstallPlanAction::InstallPlanAction(const PackageSpec& spec, + const SourceControlFile& any_paragraph, + std::unordered_set features, + const RequestType& request_type) + : InstallPlanAction() + { + this->spec = spec; + this->request_type = request_type; + + this->plan_type = InstallPlanType::BUILD_AND_INSTALL; + this->any_paragraph.source_control_file = &any_paragraph; + this->feature_list = features; + } + InstallPlanAction::InstallPlanAction(const PackageSpec& spec, const AnyParagraph& any_paragraph, const RequestType& request_type) @@ -320,4 +334,234 @@ namespace vcpkg::Dependencies Graphs::topological_sort(specs, ExportAdjacencyProvider{paths, status_db, specs_as_set}); return toposort; } + + std::vector to_feature_specs(const std::vector depends, + const std::unordered_map str_to_spec) + { + std::vector f_specs; + for (auto&& depend : depends) + { + int end = (int)depend.find(']'); + if (end != std::string::npos) + { + int start = (int)depend.find('['); + + auto feature_name = depend.substr(start + 1, end - start - 1); + auto package_name = depend.substr(0, start); + auto p_spec = str_to_spec.find(package_name); + if (p_spec != str_to_spec.end()) + { + auto feature_spec = FeatureSpec{p_spec->second, feature_name}; + f_specs.emplace_back(std::move(feature_spec)); + } + } + else + { + auto p_spec = str_to_spec.find(depend); + if (p_spec != str_to_spec.end()) + { + auto feature_spec = FeatureSpec{p_spec->second, ""}; + f_specs.emplace_back(std::move(feature_spec)); + } + } + } + return f_specs; + } + + bool mark_plus(const std::string& feature, + Cluster& cluster, + std::unordered_map& pkg_to_cluster, + GraphPlan& graph_plan) + { + auto it = cluster.edges.find(feature); + std::string updated_feature = feature; + if (updated_feature == "") + { + updated_feature = "core"; + it = cluster.edges.find("core"); + } + if (it == cluster.edges.end()) + { + Checks::exit_fail(VCPKG_LINE_INFO); + } + + if (cluster.edges[updated_feature].plus) return true; + + if (cluster.original_nodes.find(updated_feature) == cluster.original_nodes.end()) + { + cluster.zero = true; + } + + if (!cluster.zero) + { + return false; + } + cluster.edges[updated_feature].plus = true; + + if (!cluster.original_nodes.empty()) + { + mark_minus(cluster, pkg_to_cluster, graph_plan); + } + + graph_plan.install_graph.add_vertex(&cluster); + auto& tracked = cluster.tracked_nodes; + tracked.insert(updated_feature); + if (tracked.find("core") == tracked.end() && tracked.find("") == tracked.end()) + { + cluster.tracked_nodes.insert("core"); + for (auto&& depend : cluster.edges["core"].dashed) + { + auto& depend_cluster = pkg_to_cluster[depend.spec]; + mark_plus(depend.feature_name, depend_cluster, pkg_to_cluster, graph_plan); + graph_plan.install_graph.add_edge(&cluster, &depend_cluster); + } + } + + for (auto&& depend : cluster.edges[updated_feature].dashed) + { + auto& depend_cluster = pkg_to_cluster[depend.spec]; + mark_plus(depend.feature_name, depend_cluster, pkg_to_cluster, graph_plan); + if (&depend_cluster == &cluster) continue; + graph_plan.install_graph.add_edge(&cluster, &depend_cluster); + } + return true; + } + + void mark_minus(Cluster& cluster, std::unordered_map& pkg_to_cluster, GraphPlan& graph_plan) + { + if (cluster.minus) return; + cluster.minus = true; + + graph_plan.remove_graph.add_vertex(&cluster); + for (auto&& pair : cluster.edges) + { + auto& dotted_edges = pair.second.dotted; + for (auto&& depend : dotted_edges) + { + auto& depend_cluster = pkg_to_cluster[depend.spec]; + graph_plan.remove_graph.add_edge(&cluster, &depend_cluster); + depend_cluster.zero = true; + mark_minus(depend_cluster, pkg_to_cluster, graph_plan); + } + } + for (auto&& original_feature : cluster.original_nodes) + { + cluster.zero = true; + mark_plus(original_feature, cluster, pkg_to_cluster, graph_plan); + } + } + + std::vector create_feature_install_plan(const std::unordered_map& map, + const std::vector& specs, + const StatusParagraphs& status_db) + { + const auto triplet = Triplet::X86_WINDOWS; + std::unordered_map pkg_spec_to_package_node; + std::unordered_map str_to_spec; + + for (const auto& it : map) + { + str_to_spec.emplace(it.first.name(), it.first); + } + + for (const auto& it : map) + { + Cluster& node = pkg_spec_to_package_node[it.first]; + FeatureNodeEdges core_dependencies; + core_dependencies.dashed = + to_feature_specs(filter_dependencies(it.second.core_paragraph->depends, triplet), str_to_spec); + node.edges["core"] = std::move(core_dependencies); + + for (const auto& feature : it.second.feature_paragraphs) + { + FeatureNodeEdges added_edges; + added_edges.dashed = to_feature_specs(filter_dependencies(feature->depends, triplet), str_to_spec); + node.edges.emplace(feature->name, std::move(added_edges)); + } + node.cluster_node.source_paragraph = &it.second; + } + + for (auto&& status_paragraph : status_db) + { + auto& spec = status_paragraph->package.spec; + auto& status_paragraph_feature = status_paragraph->package.feature; + Cluster& cluster = pkg_spec_to_package_node[spec]; + + cluster.zero = false; + auto reverse_edges = to_feature_specs(status_paragraph->package.depends, str_to_spec); + + for (auto&& dependency : reverse_edges) + { + auto pkg_node = pkg_spec_to_package_node.find(dependency.spec); + auto depends_name = dependency.feature_name; + if (depends_name == "") + { + for (auto&& default_feature : status_paragraph->package.default_features) + { + auto& target_node = pkg_node->second.edges[default_feature]; + target_node.dotted.emplace_back(FeatureSpec{spec, status_paragraph_feature}); + } + depends_name = "core"; + } + auto& target_node = pkg_node->second.edges[depends_name]; + target_node.dotted.emplace_back(FeatureSpec{spec, status_paragraph_feature}); + } + cluster.cluster_node.status_paragraphs.emplace_back(*status_paragraph); + if (status_paragraph_feature == "") + { + cluster.original_nodes.insert("core"); + } + else + { + cluster.original_nodes.insert(status_paragraph_feature); + } + } + + GraphPlan graph_plan; + for (auto&& spec : specs) + { + Cluster& spec_cluster = pkg_spec_to_package_node[spec.package_spec]; + for (auto&& feature : spec.features) + { + mark_plus(feature, spec_cluster, pkg_spec_to_package_node, graph_plan); + } + } + + Graphs::GraphAdjacencyProvider adjacency_remove_graph(graph_plan.remove_graph.adjacency_list()); + auto remove_vertex_list = graph_plan.remove_graph.vertex_list(); + auto remove_toposort = Graphs::topological_sort(remove_vertex_list, adjacency_remove_graph); + + Graphs::GraphAdjacencyProvider adjacency_install_graph(graph_plan.install_graph.adjacency_list()); + auto insert_vertex_list = graph_plan.install_graph.vertex_list(); + auto insert_toposort = Graphs::topological_sort(insert_vertex_list, adjacency_install_graph); + + std::vector install_plan; + + for (auto&& cluster : remove_toposort) + { + auto scf = *cluster->cluster_node.source_paragraph.get(); + + AnyAction any_plan; + any_plan.remove_plan = RemovePlanAction{ + str_to_spec[scf->core_paragraph->name], RemovePlanType::REMOVE, RequestType::AUTO_SELECTED}; + + install_plan.emplace_back(std::move(any_plan)); + } + + for (auto&& cluster : insert_toposort) + { + if (!cluster->zero) continue; + + auto scf = *cluster->cluster_node.source_paragraph.get(); + auto& pkg_spec = str_to_spec[scf->core_paragraph->name]; + auto action = InstallPlanAction{ + pkg_spec, map.find(pkg_spec)->second, cluster->tracked_nodes, RequestType::AUTO_SELECTED}; + + AnyAction any_plan; + any_plan.install_plan = std::move(action); + install_plan.emplace_back(std::move(any_plan)); + } + + return install_plan; + } } -- cgit v1.2.3 From 7cca4a2d59124070661d69912288d73758ed4f94 Mon Sep 17 00:00:00 2001 From: Daniel Shaw Date: Mon, 17 Jul 2017 13:36:33 -0700 Subject: clean tests --- toolsrc/src/test_install_plan.cpp | 98 +++++++++++++++++---------------------- 1 file changed, 43 insertions(+), 55 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/test_install_plan.cpp b/toolsrc/src/test_install_plan.cpp index d90e1e523..19cede6df 100644 --- a/toolsrc/src/test_install_plan.cpp +++ b/toolsrc/src/test_install_plan.cpp @@ -24,6 +24,10 @@ namespace UnitTest1 map.emplace(*spec.get(), std::move(*scf.get())); return PackageSpec{*spec.get()}; } + PackageSpec set_package_map(std::string source, std::string version, std::string build_depends) + { + return get_package_spec({{{"Source", source}, {"Version", version}, {"Build-Depends", build_depends}}}); + } }; static void features_check(Dependencies::AnyAction* install_action, @@ -59,10 +63,9 @@ namespace UnitTest1 std::vector> status_paragraphs; PackageSpecMap spec_map; - - auto spec_a = spec_map.get_package_spec({{{"Source", "a"}, {"Version", "1.2.8"}, {"Build-Depends", "b"}}}); - auto spec_b = spec_map.get_package_spec({{{"Source", "b"}, {"Version", "1.3"}, {"Build-Depends", "c"}}}); - auto spec_c = spec_map.get_package_spec({{{"Source", "c"}, {"Version", "2.5.3"}, {"Build-Depends", ""}}}); + auto spec_a = spec_map.set_package_map("a", "1.2.8", "b"); + auto spec_b = spec_map.set_package_map("b", "1.3", "c"); + auto spec_c = spec_map.set_package_map("c", "2.5.3", ""); auto map_port = Dependencies::MapPortFile(spec_map.map); auto install_plan = @@ -79,17 +82,14 @@ namespace UnitTest1 std::vector> status_paragraphs; PackageSpecMap spec_map; - - auto spec_a = spec_map.get_package_spec({{{"Source", "a"}, {"Version", "1.2.8"}, {"Build-Depends", "d"}}}); - auto spec_b = spec_map.get_package_spec({{{"Source", "b"}, {"Version", "1.3"}, {"Build-Depends", "d, e"}}}); - auto spec_c = - spec_map.get_package_spec({{{"Source", "c"}, {"Version", "2.5.3"}, {"Build-Depends", "e, h"}}}); - auto spec_d = - spec_map.get_package_spec({{{"Source", "d"}, {"Version", "4.0"}, {"Build-Depends", "f, g, h"}}}); - auto spec_e = spec_map.get_package_spec({{{"Source", "e"}, {"Version", "1.0"}, {"Build-Depends", "g"}}}); - auto spec_f = spec_map.get_package_spec({{{"Source", "f"}, {"Version", "1.0"}, {"Build-Depends", ""}}}); - auto spec_g = spec_map.get_package_spec({{{"Source", "g"}, {"Version", "1.0"}, {"Build-Depends", ""}}}); - auto spec_h = spec_map.get_package_spec({{{"Source", "h"}, {"Version", "1.0"}, {"Build-Depends", ""}}}); + auto spec_a = spec_map.set_package_map("a", "1.2.8", "d"); + auto spec_b = spec_map.set_package_map("b", "1.3", "d, e"); + auto spec_c = spec_map.set_package_map("c", "2.5.3", "e, h"); + auto spec_d = spec_map.set_package_map("d", "4.0", "f, g, h"); + auto spec_e = spec_map.set_package_map("e", "1.0", "g"); + auto spec_f = spec_map.set_package_map("f", "1.0", ""); + auto spec_g = spec_map.set_package_map("g", "1.0", ""); + auto spec_h = spec_map.set_package_map("h", "1.0", ""); auto map_port = Dependencies::MapPortFile(spec_map.map); auto install_plan = Dependencies::create_install_plan( @@ -136,24 +136,16 @@ namespace UnitTest1 PackageSpecMap spec_map; - auto spec_h = - spec_map.get_package_spec({{{"Source", "h"}, {"Version", "1.2.8"}, {"Build-Depends", "j, k"}}}); - auto spec_c = spec_map.get_package_spec( - {{{"Source", "c"}, {"Version", "1.2.8"}, {"Build-Depends", "d, e, f, g, h, j, k"}}}); - auto spec_k = spec_map.get_package_spec({{{"Source", "k"}, {"Version", "1.2.8"}, {"Build-Depends", ""}}}); - auto spec_b = spec_map.get_package_spec( - {{{"Source", "b"}, {"Version", "1.2.8"}, {"Build-Depends", "c, d, e, f, g, h, j, k"}}}); - auto spec_d = spec_map.get_package_spec( - {{{"Source", "d"}, {"Version", "1.2.8"}, {"Build-Depends", "e, f, g, h, j, k"}}}); - auto spec_j = spec_map.get_package_spec({{{"Source", "j"}, {"Version", "1.2.8"}, {"Build-Depends", "k"}}}); - auto spec_f = - spec_map.get_package_spec({{{"Source", "f"}, {"Version", "1.2.8"}, {"Build-Depends", "g, h, j, k"}}}); - auto spec_e = spec_map.get_package_spec( - {{{"Source", "e"}, {"Version", "1.2.8"}, {"Build-Depends", "f, g, h, j, k"}}}); - auto spec_a = spec_map.get_package_spec( - {{{"Source", "a"}, {"Version", "1.2.8"}, {"Build-Depends", "b, c, d, e, f, g, h, j, k"}}}); - auto spec_g = - spec_map.get_package_spec({{{"Source", "g"}, {"Version", "1.2.8"}, {"Build-Depends", "h, j, k"}}}); + auto spec_a = spec_map.set_package_map("a", "1.2.8", "b, c, d, e, f, g, h, j, k"); + auto spec_b = spec_map.set_package_map("b", "1.2.8", "c, d, e, f, g, h, j, k"); + auto spec_c = spec_map.set_package_map("c", "1.2.8", "d, e, f, g, h, j, k"); + auto spec_d = spec_map.set_package_map("d", "1.2.8", "e, f, g, h, j, k"); + auto spec_e = spec_map.set_package_map("e", "1.2.8", "f, g, h, j, k"); + auto spec_f = spec_map.set_package_map("f", "1.2.8", "g, h, j, k"); + auto spec_g = spec_map.set_package_map("g", "1.2.8", "h, j, k"); + auto spec_h = spec_map.set_package_map("h", "1.2.8", "j, k"); + auto spec_j = spec_map.set_package_map("j", "1.2.8", "k"); + auto spec_k = spec_map.set_package_map("k", "1.2.8", ""); auto map_port = Dependencies::MapPortFile(spec_map.map); auto install_plan = @@ -197,23 +189,20 @@ namespace UnitTest1 {"Status", "install ok installed"}})); PackageSpecMap spec_map; - auto spec_a = - FullPackageSpec{spec_map.get_package_spec( - {{{"Source", "a"}, {"Version", "1.3.8"}, {"Build-Depends", "b, b[beefeatureone]"}}, - {{"Feature", "featureone"}, - {"Description", "the first feature for a"}, - {"Build-Depends", "b[beefeaturetwo]"}} - - }), + FullPackageSpec{spec_map.get_package_spec({ + {{"Source", "a"}, {"Version", "1.3.8"}, {"Build-Depends", "b, b[beefeatureone]"}}, + {{"Feature", "featureone"}, + {"Description", "the first feature for a"}, + {"Build-Depends", "b[beefeaturetwo]"}}, + }), {"featureone"}}; - auto spec_b = FullPackageSpec{spec_map.get_package_spec( - {{{"Source", "b"}, {"Version", "1.3"}, {"Build-Depends", ""}}, - {{"Feature", "beefeatureone"}, {"Description", "the first feature for b"}, {"Build-Depends", ""}}, - {{"Feature", "beefeaturetwo"}, {"Description", "the second feature for b"}, {"Build-Depends", ""}}, - {{"Feature", "beefeaturethree"}, {"Description", "the third feature for b"}, {"Build-Depends", ""}} - - })}; + auto spec_b = FullPackageSpec{spec_map.get_package_spec({ + {{"Source", "b"}, {"Version", "1.3"}, {"Build-Depends", ""}}, + {{"Feature", "beefeatureone"}, {"Description", "the first feature for b"}, {"Build-Depends", ""}}, + {{"Feature", "beefeaturetwo"}, {"Description", "the second feature for b"}, {"Build-Depends", ""}}, + {{"Feature", "beefeaturethree"}, {"Description", "the third feature for b"}, {"Build-Depends", ""}}, + })}; auto install_plan = Dependencies::create_feature_install_plan( spec_map.map, {spec_a}, StatusParagraphs(std::move(status_paragraphs))); @@ -242,13 +231,12 @@ namespace UnitTest1 }), {"featureone"}}; - auto spec_b = FullPackageSpec{spec_map.get_package_spec( - {{{"Source", "b"}, {"Version", "1.3"}, {"Build-Depends", ""}}, - {{"Feature", "beefeatureone"}, {"Description", "the first feature for b"}, {"Build-Depends", ""}}, - {{"Feature", "beefeaturetwo"}, {"Description", "the second feature for b"}, {"Build-Depends", ""}}, - {{"Feature", "beefeaturethree"}, {"Description", "the third feature for b"}, {"Build-Depends", ""}} - - })}; + auto spec_b = FullPackageSpec{spec_map.get_package_spec({ + {{"Source", "b"}, {"Version", "1.3"}, {"Build-Depends", ""}}, + {{"Feature", "beefeatureone"}, {"Description", "the first feature for b"}, {"Build-Depends", ""}}, + {{"Feature", "beefeaturetwo"}, {"Description", "the second feature for b"}, {"Build-Depends", ""}}, + {{"Feature", "beefeaturethree"}, {"Description", "the third feature for b"}, {"Build-Depends", ""}}, + })}; auto install_plan = Dependencies::create_feature_install_plan( spec_map.map, {spec_a}, StatusParagraphs(std::move(status_paragraphs))); -- cgit v1.2.3 From 1445115906139f5c6d14bcbbacdcc0cfb543fd80 Mon Sep 17 00:00:00 2001 From: Daniel Shaw Date: Wed, 19 Jul 2017 14:19:11 -0700 Subject: refactor feature packages --- toolsrc/include/vcpkg_Dependencies.h | 40 +++++++-------------- toolsrc/src/commands_ci.cpp | 2 +- toolsrc/src/test_install_plan.cpp | 2 +- toolsrc/src/vcpkg_Dependencies.cpp | 67 ++++++++++++++++++------------------ 4 files changed, 48 insertions(+), 63 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg_Dependencies.h b/toolsrc/include/vcpkg_Dependencies.h index 92523a654..ff559c0f1 100644 --- a/toolsrc/include/vcpkg_Dependencies.h +++ b/toolsrc/include/vcpkg_Dependencies.h @@ -44,20 +44,20 @@ namespace vcpkg::Dependencies struct FeatureNodeEdges { - std::vector dotted; - std::vector dashed; + std::vector remove_edges; + std::vector build_edges; bool plus = false; }; std::vector to_feature_specs(const std::vector depends, const std::unordered_map str_to_spec); struct Cluster { - ClusterNode cluster_node; + ClusterNode cluster_data; std::unordered_map edges; - std::unordered_set tracked_nodes; - std::unordered_set original_nodes; - bool minus = false; - bool zero = true; + std::unordered_set to_install_features; + std::unordered_set original_features; + bool will_remove = false; + bool transient_uninstalled = true; Cluster() = default; private: @@ -81,7 +81,7 @@ namespace vcpkg::Dependencies InstallPlanAction(const PackageSpec& spec, const AnyParagraph& any_paragraph, const RequestType& request_type); InstallPlanAction(const PackageSpec& spec, const SourceControlFile& any_paragraph, - std::unordered_set features, + const std::unordered_set& features, const RequestType& request_type); InstallPlanAction(const InstallPlanAction&) = delete; InstallPlanAction(InstallPlanAction&&) = default; @@ -163,6 +163,10 @@ namespace vcpkg::Dependencies mutable std::unordered_map cache; explicit PathsPortFile(const VcpkgPaths& paths); const SourceControlFile& get_control_file(const PackageSpec& spec) const override; + + private: + PathsPortFile(const PathsPortFile&) = delete; + PathsPortFile& operator=(const PathsPortFile&) = delete; }; std::vector create_install_plan(const PortFileProvider& port_file_provider, @@ -177,26 +181,6 @@ namespace vcpkg::Dependencies const StatusParagraphs& status_db); } -template<> -struct std::hash -{ - size_t operator()(const vcpkg::Dependencies::Cluster& value) const - { - size_t hash = 17; - if (auto source = value.cluster_node.source_paragraph.get()) - { - hash = hash * 31 + std::hash()((*source)->core_paragraph->name); - } - else if (!value.cluster_node.status_paragraphs.empty()) - { - auto start = *value.cluster_node.status_paragraphs.begin(); - hash = hash * 31 + std::hash()(start.package.displayname()); - } - - return hash; - } -}; - namespace vcpkg::Dependencies { struct GraphPlan diff --git a/toolsrc/src/commands_ci.cpp b/toolsrc/src/commands_ci.cpp index 95d722302..f781adf69 100644 --- a/toolsrc/src/commands_ci.cpp +++ b/toolsrc/src/commands_ci.cpp @@ -40,7 +40,7 @@ namespace vcpkg::Commands::CI const std::vector specs = load_all_package_specs(paths.get_filesystem(), paths.ports, triplet); StatusParagraphs status_db = database_load_check(paths); - auto paths_port_file = Dependencies::PathsPortFile(paths); + const auto& paths_port_file = Dependencies::PathsPortFile(paths); const std::vector install_plan = Dependencies::create_install_plan(paths_port_file, specs, status_db); Checks::check_exit(VCPKG_LINE_INFO, !install_plan.empty(), "Install plan cannot be empty"); diff --git a/toolsrc/src/test_install_plan.cpp b/toolsrc/src/test_install_plan.cpp index 19cede6df..671b6ed67 100644 --- a/toolsrc/src/test_install_plan.cpp +++ b/toolsrc/src/test_install_plan.cpp @@ -430,7 +430,7 @@ namespace UnitTest1 remove_plan_check(&install_plan[0], "x"); remove_plan_check(&install_plan[1], "b"); - // order here may change but A < X, and B anywhere + // TODO: order here may change but A < X, and B anywhere features_check(&install_plan[2], "a", {"core"}); features_check(&install_plan[3], "x", {"core"}); features_check(&install_plan[4], "b", {"core", "1"}); diff --git a/toolsrc/src/vcpkg_Dependencies.cpp b/toolsrc/src/vcpkg_Dependencies.cpp index 824de15e1..90168813e 100644 --- a/toolsrc/src/vcpkg_Dependencies.cpp +++ b/toolsrc/src/vcpkg_Dependencies.cpp @@ -56,7 +56,7 @@ namespace vcpkg::Dependencies InstallPlanAction::InstallPlanAction(const PackageSpec& spec, const SourceControlFile& any_paragraph, - std::unordered_set features, + const std::unordered_set& features, const RequestType& request_type) : InstallPlanAction() { @@ -153,7 +153,8 @@ namespace vcpkg::Dependencies return left->spec.name() < right->spec.name(); } - MapPortFile::MapPortFile(const std::unordered_map& map) : ports(map){}; + MapPortFile::MapPortFile(const std::unordered_map& map) : ports(map) {} + const SourceControlFile& MapPortFile::get_control_file(const PackageSpec& spec) const { auto scf = ports.find(spec); @@ -164,7 +165,8 @@ namespace vcpkg::Dependencies return scf->second; } - PathsPortFile::PathsPortFile(const VcpkgPaths& paths) : ports(paths){}; + PathsPortFile::PathsPortFile(const VcpkgPaths& paths) : ports(paths) {} + const SourceControlFile& PathsPortFile::get_control_file(const PackageSpec& spec) const { std::unordered_map::iterator cache_it = cache.find(spec); @@ -382,34 +384,34 @@ namespace vcpkg::Dependencies } if (it == cluster.edges.end()) { - Checks::exit_fail(VCPKG_LINE_INFO); + Checks::unreachable(VCPKG_LINE_INFO); } if (cluster.edges[updated_feature].plus) return true; - if (cluster.original_nodes.find(updated_feature) == cluster.original_nodes.end()) + if (cluster.original_features.find(updated_feature) == cluster.original_features.end()) { - cluster.zero = true; + cluster.transient_uninstalled = true; } - if (!cluster.zero) + if (!cluster.transient_uninstalled) { return false; } cluster.edges[updated_feature].plus = true; - if (!cluster.original_nodes.empty()) + if (!cluster.original_features.empty()) { mark_minus(cluster, pkg_to_cluster, graph_plan); } graph_plan.install_graph.add_vertex(&cluster); - auto& tracked = cluster.tracked_nodes; + auto& tracked = cluster.to_install_features; tracked.insert(updated_feature); if (tracked.find("core") == tracked.end() && tracked.find("") == tracked.end()) { - cluster.tracked_nodes.insert("core"); - for (auto&& depend : cluster.edges["core"].dashed) + cluster.to_install_features.insert("core"); + for (auto&& depend : cluster.edges["core"].build_edges) { auto& depend_cluster = pkg_to_cluster[depend.spec]; mark_plus(depend.feature_name, depend_cluster, pkg_to_cluster, graph_plan); @@ -417,7 +419,7 @@ namespace vcpkg::Dependencies } } - for (auto&& depend : cluster.edges[updated_feature].dashed) + for (auto&& depend : cluster.edges[updated_feature].build_edges) { auto& depend_cluster = pkg_to_cluster[depend.spec]; mark_plus(depend.feature_name, depend_cluster, pkg_to_cluster, graph_plan); @@ -429,28 +431,27 @@ namespace vcpkg::Dependencies void mark_minus(Cluster& cluster, std::unordered_map& pkg_to_cluster, GraphPlan& graph_plan) { - if (cluster.minus) return; - cluster.minus = true; + if (cluster.will_remove) return; + cluster.will_remove = true; graph_plan.remove_graph.add_vertex(&cluster); for (auto&& pair : cluster.edges) { - auto& dotted_edges = pair.second.dotted; - for (auto&& depend : dotted_edges) + auto& remove_edges_edges = pair.second.remove_edges; + for (auto&& depend : remove_edges_edges) { auto& depend_cluster = pkg_to_cluster[depend.spec]; graph_plan.remove_graph.add_edge(&cluster, &depend_cluster); - depend_cluster.zero = true; + depend_cluster.transient_uninstalled = true; mark_minus(depend_cluster, pkg_to_cluster, graph_plan); } } - for (auto&& original_feature : cluster.original_nodes) + for (auto&& original_feature : cluster.original_features) { - cluster.zero = true; + cluster.transient_uninstalled = true; mark_plus(original_feature, cluster, pkg_to_cluster, graph_plan); } } - std::vector create_feature_install_plan(const std::unordered_map& map, const std::vector& specs, const StatusParagraphs& status_db) @@ -468,17 +469,17 @@ namespace vcpkg::Dependencies { Cluster& node = pkg_spec_to_package_node[it.first]; FeatureNodeEdges core_dependencies; - core_dependencies.dashed = + core_dependencies.build_edges = to_feature_specs(filter_dependencies(it.second.core_paragraph->depends, triplet), str_to_spec); node.edges["core"] = std::move(core_dependencies); for (const auto& feature : it.second.feature_paragraphs) { FeatureNodeEdges added_edges; - added_edges.dashed = to_feature_specs(filter_dependencies(feature->depends, triplet), str_to_spec); + added_edges.build_edges = to_feature_specs(filter_dependencies(feature->depends, triplet), str_to_spec); node.edges.emplace(feature->name, std::move(added_edges)); } - node.cluster_node.source_paragraph = &it.second; + node.cluster_data.source_paragraph = &it.second; } for (auto&& status_paragraph : status_db) @@ -487,7 +488,7 @@ namespace vcpkg::Dependencies auto& status_paragraph_feature = status_paragraph->package.feature; Cluster& cluster = pkg_spec_to_package_node[spec]; - cluster.zero = false; + cluster.transient_uninstalled = false; auto reverse_edges = to_feature_specs(status_paragraph->package.depends, str_to_spec); for (auto&& dependency : reverse_edges) @@ -499,21 +500,21 @@ namespace vcpkg::Dependencies for (auto&& default_feature : status_paragraph->package.default_features) { auto& target_node = pkg_node->second.edges[default_feature]; - target_node.dotted.emplace_back(FeatureSpec{spec, status_paragraph_feature}); + target_node.remove_edges.emplace_back(FeatureSpec{spec, status_paragraph_feature}); } depends_name = "core"; } auto& target_node = pkg_node->second.edges[depends_name]; - target_node.dotted.emplace_back(FeatureSpec{spec, status_paragraph_feature}); + target_node.remove_edges.emplace_back(FeatureSpec{spec, status_paragraph_feature}); } - cluster.cluster_node.status_paragraphs.emplace_back(*status_paragraph); + cluster.cluster_data.status_paragraphs.emplace_back(*status_paragraph); if (status_paragraph_feature == "") { - cluster.original_nodes.insert("core"); + cluster.original_features.insert("core"); } else { - cluster.original_nodes.insert(status_paragraph_feature); + cluster.original_features.insert(status_paragraph_feature); } } @@ -539,7 +540,7 @@ namespace vcpkg::Dependencies for (auto&& cluster : remove_toposort) { - auto scf = *cluster->cluster_node.source_paragraph.get(); + auto scf = *cluster->cluster_data.source_paragraph.get(); AnyAction any_plan; any_plan.remove_plan = RemovePlanAction{ @@ -550,12 +551,12 @@ namespace vcpkg::Dependencies for (auto&& cluster : insert_toposort) { - if (!cluster->zero) continue; + if (!cluster->transient_uninstalled) continue; - auto scf = *cluster->cluster_node.source_paragraph.get(); + auto scf = *cluster->cluster_data.source_paragraph.get(); auto& pkg_spec = str_to_spec[scf->core_paragraph->name]; auto action = InstallPlanAction{ - pkg_spec, map.find(pkg_spec)->second, cluster->tracked_nodes, RequestType::AUTO_SELECTED}; + pkg_spec, map.find(pkg_spec)->second, cluster->to_install_features, RequestType::AUTO_SELECTED}; AnyAction any_plan; any_plan.install_plan = std::move(action); -- cgit v1.2.3 From 8097e2f3c29eb05f707ad86c712e8523cca9421f Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Mon, 24 Jul 2017 09:03:03 -0700 Subject: [vcpkg] ALLOW_OBSOLETE_MSVCRT policy should enable use of all CRTs. --- toolsrc/src/PostBuildLint.cpp | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/PostBuildLint.cpp b/toolsrc/src/PostBuildLint.cpp index 8e11ae5b1..a5d923ad2 100644 --- a/toolsrc/src/PostBuildLint.cpp +++ b/toolsrc/src/PostBuildLint.cpp @@ -38,7 +38,7 @@ namespace vcpkg::PostBuildLint } }; - const std::vector& get_outdated_dynamic_crts(const Build::BuildPolicies& policies) + const std::vector& get_outdated_dynamic_crts() { static const std::vector v_no_msvcrt = { {"msvcp100.dll", R"(msvcp100\.dll)"}, @@ -59,18 +59,7 @@ namespace vcpkg::PostBuildLint {"msvcrt20.dll", R"(msvcrt20\.dll)"}, {"msvcrt40.dll", R"(msvcrt40\.dll)"}}; - static const std::vector v = [&]() { - auto ret = v_no_msvcrt; - ret.push_back(OutdatedDynamicCrt{"msvcrt.dll", R"(msvcrt\.dll)"}); - return ret; - }(); - - if (policies.is_enabled(BuildPolicy::ALLOW_OBSOLETE_MSVCRT)) - { - return v_no_msvcrt; - } - - return v; + return v_no_msvcrt; } static LintStatus check_for_files_in_include_directory(const Files::Filesystem& fs, @@ -659,7 +648,7 @@ namespace vcpkg::PostBuildLint const fs::path dumpbin_exe, const BuildInfo& build_info) { - const std::vector& outdated_crts = get_outdated_dynamic_crts(build_info.policies); + if (build_info.policies.is_enabled(BuildPolicy::ALLOW_OBSOLETE_MSVCRT)) return LintStatus::SUCCESS; std::vector dlls_with_outdated_crt; @@ -673,7 +662,7 @@ namespace vcpkg::PostBuildLint "Running command:\n %s\n failed", Strings::to_utf8(cmd_line)); - for (const OutdatedDynamicCrt& outdated_crt : outdated_crts) + for (const OutdatedDynamicCrt& outdated_crt : get_outdated_dynamic_crts()) { if (std::regex_search(ec_data.output.cbegin(), ec_data.output.cend(), outdated_crt.regex)) { -- cgit v1.2.3 From 11f540d7e9a3f43614196f45ab7e82ab3fbed03e Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Mon, 24 Jul 2017 13:26:45 -0700 Subject: [vcpkg] Use _vsnprintf_s_l on Windows for locale-insensitivity. Avoid manual buffer management. --- toolsrc/src/vcpkg_Strings.cpp | 43 +++++++++++++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 12 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg_Strings.cpp b/toolsrc/src/vcpkg_Strings.cpp index 77ff1a106..36d017f54 100644 --- a/toolsrc/src/vcpkg_Strings.cpp +++ b/toolsrc/src/vcpkg_Strings.cpp @@ -11,27 +11,49 @@ namespace vcpkg::Strings::details // Avoids C4244 warnings because of char<->int conversion that occur when using std::tolower() static char tolower_char(const char c) { return static_cast(std::tolower(c)); } +#if defined(_WIN32) static _locale_t& c_locale() { static _locale_t c_locale_impl = _create_locale(LC_ALL, "C"); return c_locale_impl; } + static int plat_vsnprintf(_Out_writes_z_(bufsz) char* const buffer, + _In_ size_t const bufsz, + _In_z_ _Printf_format_string_params_(1) char const* const fmtstr, + va_list args) + { + return _vsnprintf_s_l(buffer, bufsz, bufsz, fmtstr, c_locale(), args); + } + static int plat_vswprintf(_Out_writes_z_(bufsz) wchar_t* const buffer, + _In_ size_t const bufsz, + _In_z_ _Printf_format_string_params_(1) wchar_t const* const fmtstr, + va_list args) + { + return _vsnwprintf_s_l(buffer, bufsz, bufsz, fmtstr, c_locale(), args); + } +#else + static int plat_vsnprintf(char* buffer, size_t bufsz, const char* fmtstr, va_list args) + { + return vsnprintf(buffer, bufsz, fmtstr, args); + } + static int plat_vswprintf(char* buffer, size_t bufsz, const char* fmtstr, va_list args) + { + return vswprintf(buffer, bufsz, fmtstr, args); + } +#endif std::string format_internal(const char* fmtstr, ...) { va_list args; va_start(args, fmtstr); - int sz = vsnprintf(nullptr, 0, fmtstr, args) + 1; + int sz = plat_vsnprintf(nullptr, 0, fmtstr, args); - char* buffer = new char[sz]; + std::string output(sz, '\0'); - vsnprintf(buffer, sz, fmtstr, args); + plat_vsnprintf(&output.at(0), output.size() + 1, fmtstr, args); va_end(args); - std::string output(buffer); - delete[] buffer; - return output; } @@ -40,16 +62,13 @@ namespace vcpkg::Strings::details va_list args; va_start(args, fmtstr); - int sz = vswprintf(nullptr, 0, fmtstr, args) + 1; + int sz = plat_vswprintf(nullptr, 0, fmtstr, args); - wchar_t* buffer = new wchar_t[sz]; + std::wstring output(sz, L'\0'); - vswprintf(buffer, sz, fmtstr, args); + plat_vswprintf(&output.at(0), output.size() + 1, fmtstr, args); va_end(args); - std::wstring output(buffer); - delete[] buffer; - return output; } } -- cgit v1.2.3 From c0af06a69141b251f84f75588c18013889a99f76 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Mon, 24 Jul 2017 13:34:18 -0700 Subject: [vcpkg] Revert #1450, pending bugfix. --- toolsrc/src/vcpkg_Strings.cpp | 51 ++++++++++--------------------------------- 1 file changed, 11 insertions(+), 40 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg_Strings.cpp b/toolsrc/src/vcpkg_Strings.cpp index 36d017f54..aafed5fd3 100644 --- a/toolsrc/src/vcpkg_Strings.cpp +++ b/toolsrc/src/vcpkg_Strings.cpp @@ -11,63 +11,34 @@ namespace vcpkg::Strings::details // Avoids C4244 warnings because of char<->int conversion that occur when using std::tolower() static char tolower_char(const char c) { return static_cast(std::tolower(c)); } -#if defined(_WIN32) static _locale_t& c_locale() { static _locale_t c_locale_impl = _create_locale(LC_ALL, "C"); return c_locale_impl; } - static int plat_vsnprintf(_Out_writes_z_(bufsz) char* const buffer, - _In_ size_t const bufsz, - _In_z_ _Printf_format_string_params_(1) char const* const fmtstr, - va_list args) - { - return _vsnprintf_s_l(buffer, bufsz, bufsz, fmtstr, c_locale(), args); - } - static int plat_vswprintf(_Out_writes_z_(bufsz) wchar_t* const buffer, - _In_ size_t const bufsz, - _In_z_ _Printf_format_string_params_(1) wchar_t const* const fmtstr, - va_list args) - { - return _vsnwprintf_s_l(buffer, bufsz, bufsz, fmtstr, c_locale(), args); - } -#else - static int plat_vsnprintf(char* buffer, size_t bufsz, const char* fmtstr, va_list args) - { - return vsnprintf(buffer, bufsz, fmtstr, args); - } - static int plat_vswprintf(char* buffer, size_t bufsz, const char* fmtstr, va_list args) - { - return vswprintf(buffer, bufsz, fmtstr, args); - } -#endif std::string format_internal(const char* fmtstr, ...) { - va_list args; - va_start(args, fmtstr); - - int sz = plat_vsnprintf(nullptr, 0, fmtstr, args); + va_list lst; + va_start(lst, fmtstr); + const int sz = _vscprintf_l(fmtstr, c_locale(), lst); std::string output(sz, '\0'); - - plat_vsnprintf(&output.at(0), output.size() + 1, fmtstr, args); - va_end(args); + _vsnprintf_s_l(&output[0], output.size() + 1, output.size() + 1, fmtstr, c_locale(), lst); + va_end(lst); return output; } std::wstring wformat_internal(const wchar_t* fmtstr, ...) { - va_list args; - va_start(args, fmtstr); - - int sz = plat_vswprintf(nullptr, 0, fmtstr, args); - - std::wstring output(sz, L'\0'); + va_list lst; + va_start(lst, fmtstr); - plat_vswprintf(&output.at(0), output.size() + 1, fmtstr, args); - va_end(args); + const int sz = _vscwprintf_l(fmtstr, c_locale(), lst); + std::wstring output(sz, '\0'); + _vsnwprintf_s_l(&output[0], output.size() + 1, output.size() + 1, fmtstr, c_locale(), lst); + va_end(lst); return output; } -- cgit v1.2.3 From 3c841c6128ebfe8e99a372f2907bd985b533a799 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Mon, 24 Jul 2017 13:59:53 -0700 Subject: [vcpkg] Revert revert. Bug fixed. --- toolsrc/src/vcpkg_Strings.cpp | 49 ++++++++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 12 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg_Strings.cpp b/toolsrc/src/vcpkg_Strings.cpp index aafed5fd3..0c1c1f9f9 100644 --- a/toolsrc/src/vcpkg_Strings.cpp +++ b/toolsrc/src/vcpkg_Strings.cpp @@ -1,5 +1,6 @@ #include "pch.h" +#include "vcpkg_Checks.h" #include "vcpkg_Strings.h" #include "vcpkg_Util.h" @@ -11,34 +12,58 @@ namespace vcpkg::Strings::details // Avoids C4244 warnings because of char<->int conversion that occur when using std::tolower() static char tolower_char(const char c) { return static_cast(std::tolower(c)); } +#if defined(_WIN32) static _locale_t& c_locale() { static _locale_t c_locale_impl = _create_locale(LC_ALL, "C"); return c_locale_impl; } +#endif std::string format_internal(const char* fmtstr, ...) { - va_list lst; - va_start(lst, fmtstr); + va_list args; + va_start(args, fmtstr); + +#if defined(_WIN32) + const int sz = _vscprintf_l(fmtstr, c_locale(), args); +#else + const int sz = vsnprintf(nullptr, 0, fmtstr, args); +#endif + Checks::check_exit(VCPKG_LINE_INFO, sz > 0); - const int sz = _vscprintf_l(fmtstr, c_locale(), lst); std::string output(sz, '\0'); - _vsnprintf_s_l(&output[0], output.size() + 1, output.size() + 1, fmtstr, c_locale(), lst); - va_end(lst); + +#if defined(_WIN32) + _vsnprintf_s_l(&output.at(0), output.size() + 1, output.size(), fmtstr, c_locale(), args); +#else + vsnprintf(&output.at(0), output.size() + 1, fmtstr, args); +#endif + va_end(args); return output; } std::wstring wformat_internal(const wchar_t* fmtstr, ...) { - va_list lst; - va_start(lst, fmtstr); - - const int sz = _vscwprintf_l(fmtstr, c_locale(), lst); - std::wstring output(sz, '\0'); - _vsnwprintf_s_l(&output[0], output.size() + 1, output.size() + 1, fmtstr, c_locale(), lst); - va_end(lst); + va_list args; + va_start(args, fmtstr); + +#if defined(_WIN32) + const int sz = _vscwprintf_l(fmtstr, c_locale(), args); +#else + const int sz = vswprintf(nullptr, 0, fmtstr, args); +#endif + Checks::check_exit(VCPKG_LINE_INFO, sz > 0); + + std::wstring output(sz, L'\0'); + +#if defined(_WIN32) + _vsnwprintf_s_l(&output.at(0), output.size() + 1, output.size(), fmtstr, c_locale(), args); +#else + vswprintf(&output.at(0), output.size() + 1, fmtstr, args); +#endif + va_end(args); return output; } -- cgit v1.2.3 From 59389ca236b005922cf1101f66c957d2396f6371 Mon Sep 17 00:00:00 2001 From: Daniel Shaw Date: Wed, 19 Jul 2017 14:29:28 -0700 Subject: end to end feature pkg draft --- toolsrc/include/BinaryParagraph.h | 3 + toolsrc/include/PackageSpec.h | 6 +- toolsrc/include/SourceParagraph.h | 1 + toolsrc/include/vcpkg_Build.h | 23 ++++++- toolsrc/include/vcpkg_Commands.h | 1 + toolsrc/include/vcpkg_Dependencies.h | 34 ++++++---- toolsrc/src/BinaryParagraph.cpp | 15 ++++- toolsrc/src/PackageSpec.cpp | 47 +++++++++++--- toolsrc/src/commands_install.cpp | 38 ++++++++++- toolsrc/src/commands_remove.cpp | 2 +- toolsrc/src/test_install_plan.cpp | 118 ++++++++++++++++++++++++++++++----- toolsrc/src/tests_paragraph.cpp | 20 +++--- toolsrc/src/vcpkg_Build.cpp | 62 +++++++++++++++--- toolsrc/src/vcpkg_Dependencies.cpp | 88 +++++++++++++------------- toolsrc/src/vcpkg_Input.cpp | 27 ++------ toolsrc/src/vcpkg_Parse.cpp | 12 ---- 16 files changed, 359 insertions(+), 138 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/BinaryParagraph.h b/toolsrc/include/BinaryParagraph.h index 4adde5e36..f411b3c39 100644 --- a/toolsrc/include/BinaryParagraph.h +++ b/toolsrc/include/BinaryParagraph.h @@ -14,6 +14,9 @@ namespace vcpkg BinaryParagraph(); explicit BinaryParagraph(std::unordered_map fields); BinaryParagraph(const SourceParagraph& spgh, const Triplet& triplet); + BinaryParagraph::BinaryParagraph(const SourceParagraph& spgh, + const FeatureParagraph& fpgh, + const Triplet& triplet); std::string displayname() const; diff --git a/toolsrc/include/PackageSpec.h b/toolsrc/include/PackageSpec.h index 62b6fc9de..15b5e5b9b 100644 --- a/toolsrc/include/PackageSpec.h +++ b/toolsrc/include/PackageSpec.h @@ -1,5 +1,6 @@ #pragma once #include "PackageSpecParseResult.h" +#include "SourceParagraph.h" #include "Triplet.h" #include "vcpkg_expected.h" @@ -7,8 +8,6 @@ namespace vcpkg { struct PackageSpec { - static ExpectedT from_string(const std::string& spec_as_string, - const Triplet& default_triplet); static std::string to_string(const std::string& name, const Triplet& triplet); static ExpectedT from_name_and_triplet(const std::string& name, const Triplet& triplet); @@ -30,6 +29,9 @@ namespace vcpkg { PackageSpec package_spec; std::vector features; + + static ExpectedT from_string(const std::string& spec_as_string, + const Triplet& default_triplet); }; bool operator==(const PackageSpec& left, const PackageSpec& right); diff --git a/toolsrc/include/SourceParagraph.h b/toolsrc/include/SourceParagraph.h index e85884b51..7ddf999cc 100644 --- a/toolsrc/include/SourceParagraph.h +++ b/toolsrc/include/SourceParagraph.h @@ -60,6 +60,7 @@ namespace vcpkg std::vector filter_dependencies(const std::vector& deps, const Triplet& t); + // zlib[uwp] becomes Dependency{"zlib", "uwp"} std::vector expand_qualified_dependencies(const std::vector& depends); std::vector parse_comma_list(const std::string& str); diff --git a/toolsrc/include/vcpkg_Build.h b/toolsrc/include/vcpkg_Build.h index 9a4e2baeb..c4f3e6746 100644 --- a/toolsrc/include/vcpkg_Build.h +++ b/toolsrc/include/vcpkg_Build.h @@ -95,14 +95,35 @@ namespace vcpkg::Build const Triplet& triplet, fs::path&& port_dir, const BuildPackageOptions& build_package_options) - : src(src), triplet(triplet), port_dir(std::move(port_dir)), build_package_options(build_package_options) + : src(src) + , scf(nullptr) + , triplet(triplet) + , port_dir(std::move(port_dir)) + , build_package_options(build_package_options) + , feature_list(nullptr) + { + } + + BuildPackageConfig(const SourceControlFile& src, + const Triplet& triplet, + fs::path&& port_dir, + const BuildPackageOptions& build_package_options, + const std::unordered_set& feature_list) + : src(*src.core_paragraph) + , scf(&src) + , triplet(triplet) + , port_dir(std::move(port_dir)) + , build_package_options(build_package_options) + , feature_list(&feature_list) { } const SourceParagraph& src; + const SourceControlFile* scf; const Triplet& triplet; fs::path port_dir; const BuildPackageOptions& build_package_options; + const std::unordered_set* feature_list; }; ExtendedBuildResult build_package(const VcpkgPaths& paths, diff --git a/toolsrc/include/vcpkg_Commands.h b/toolsrc/include/vcpkg_Commands.h index 67319f240..8348a64e4 100644 --- a/toolsrc/include/vcpkg_Commands.h +++ b/toolsrc/include/vcpkg_Commands.h @@ -77,6 +77,7 @@ namespace vcpkg::Commands namespace Remove { void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet); + void remove_package(const VcpkgPaths& paths, const PackageSpec& spec, StatusParagraphs* status_db); } namespace Update diff --git a/toolsrc/include/vcpkg_Dependencies.h b/toolsrc/include/vcpkg_Dependencies.h index ff559c0f1..e3af0fd28 100644 --- a/toolsrc/include/vcpkg_Dependencies.h +++ b/toolsrc/include/vcpkg_Dependencies.h @@ -26,12 +26,6 @@ namespace vcpkg::Dependencies Optional source_paragraph; Optional source_control_file; }; - - struct ClusterNode - { - std::vector status_paragraphs; - Optional source_paragraph; - }; } namespace vcpkg::Dependencies @@ -48,11 +42,13 @@ namespace vcpkg::Dependencies std::vector build_edges; bool plus = false; }; - std::vector to_feature_specs(const std::vector depends, - const std::unordered_map str_to_spec); + std::vector to_feature_specs(const std::vector& depends, const Triplet& t); + struct Cluster { - ClusterNode cluster_data; + std::vector status_paragraphs; + Optional source_control_file; + PackageSpec spec; std::unordered_map edges; std::unordered_set to_install_features; std::unordered_set original_features; @@ -65,6 +61,13 @@ namespace vcpkg::Dependencies Cluster& operator=(const Cluster&) = delete; }; + struct ClusterPtr + { + Cluster* ptr; + }; + + bool operator==(const ClusterPtr& l, const ClusterPtr& r); + enum class InstallPlanType { UNKNOWN, @@ -181,12 +184,21 @@ namespace vcpkg::Dependencies const StatusParagraphs& status_db); } +template<> +struct std::hash +{ + size_t operator()(const vcpkg::Dependencies::ClusterPtr& value) const + { + return std::hash()(value.ptr->spec); + } +}; + namespace vcpkg::Dependencies { struct GraphPlan { - Graphs::Graph remove_graph; - Graphs::Graph install_graph; + Graphs::Graph remove_graph; + Graphs::Graph install_graph; }; bool mark_plus(const std::string& feature, Cluster& cluster, diff --git a/toolsrc/src/BinaryParagraph.cpp b/toolsrc/src/BinaryParagraph.cpp index e126054a8..b6f3e8a87 100644 --- a/toolsrc/src/BinaryParagraph.cpp +++ b/toolsrc/src/BinaryParagraph.cpp @@ -75,6 +75,16 @@ namespace vcpkg this->depends = filter_dependencies(spgh.depends, triplet); } + BinaryParagraph::BinaryParagraph(const SourceParagraph& spgh, const FeatureParagraph& fpgh, const Triplet& triplet) + { + this->spec = PackageSpec::from_name_and_triplet(spgh.name, triplet).value_or_exit(VCPKG_LINE_INFO); + this->version = ""; + this->feature = fpgh.name; + this->description = fpgh.description; + this->maintainer = ""; + this->depends = filter_dependencies(fpgh.depends, triplet); + } + std::string BinaryParagraph::displayname() const { return this->spec.to_string(); } std::string BinaryParagraph::dir() const { return this->spec.dir(); } @@ -87,7 +97,10 @@ namespace vcpkg void serialize(const BinaryParagraph& pgh, std::string& out_str) { out_str.append("Package: ").append(pgh.spec.name()).push_back('\n'); - out_str.append("Version: ").append(pgh.version).push_back('\n'); + if (!pgh.version.empty()) + out_str.append("Version: ").append(pgh.version).push_back('\n'); + else if (!pgh.feature.empty()) + out_str.append("Feature: ").append(pgh.feature).push_back('\n'); if (!pgh.depends.empty()) { out_str.append("Depends: "); diff --git a/toolsrc/src/PackageSpec.cpp b/toolsrc/src/PackageSpec.cpp index 12217ac98..a7e5648cd 100644 --- a/toolsrc/src/PackageSpec.cpp +++ b/toolsrc/src/PackageSpec.cpp @@ -10,13 +10,47 @@ namespace vcpkg return (c == '-') || isdigit(c) || (isalpha(c) && islower(c)) || (c == '[') || (c == ']'); } - ExpectedT PackageSpec::from_string(const std::string& spec_as_string, - const Triplet& default_triplet) + ExpectedT FullPackageSpec::from_string(const std::string& spec_as_string, + const Triplet& default_triplet) { auto pos = spec_as_string.find(':'); - if (pos == std::string::npos) + auto pos_l_bracket = spec_as_string.find('['); + auto pos_r_bracket = spec_as_string.find(']'); + + FullPackageSpec f; + if (pos == std::string::npos && pos_l_bracket == std::string::npos) + { + f.package_spec = + PackageSpec::from_name_and_triplet(spec_as_string, default_triplet).value_or_exit(VCPKG_LINE_INFO); + return f; + } + else if (pos == std::string::npos) + { + if (pos_r_bracket == std::string::npos || pos_l_bracket >= pos_r_bracket) + { + return PackageSpecParseResult::INVALID_CHARACTERS; + } + const std::string name = spec_as_string.substr(0, pos_l_bracket); + f.package_spec = PackageSpec::from_name_and_triplet(name, default_triplet).value_or_exit(VCPKG_LINE_INFO); + f.features = parse_comma_list(spec_as_string.substr(pos_l_bracket + 1, pos_r_bracket - pos_l_bracket - 1)); + return f; + } + else if (pos_l_bracket == std::string::npos && pos_r_bracket == std::string::npos) + { + const std::string name = spec_as_string.substr(0, pos); + const Triplet triplet = Triplet::from_canonical_name(spec_as_string.substr(pos + 1)); + f.package_spec = PackageSpec::from_name_and_triplet(name, triplet).value_or_exit(VCPKG_LINE_INFO); + } + else { - return from_name_and_triplet(spec_as_string, default_triplet); + if (pos_r_bracket == std::string::npos || pos_l_bracket >= pos_r_bracket) + { + return PackageSpecParseResult::INVALID_CHARACTERS; + } + const std::string name = spec_as_string.substr(0, pos_l_bracket); + f.features = parse_comma_list(spec_as_string.substr(pos_l_bracket + 1, pos_r_bracket - pos_l_bracket - 1)); + const Triplet triplet = Triplet::from_canonical_name(spec_as_string.substr(pos + 1)); + f.package_spec = PackageSpec::from_name_and_triplet(name, triplet).value_or_exit(VCPKG_LINE_INFO); } auto pos2 = spec_as_string.find(':', pos + 1); @@ -24,10 +58,7 @@ namespace vcpkg { return PackageSpecParseResult::TOO_MANY_COLONS; } - - const std::string name = spec_as_string.substr(0, pos); - const Triplet triplet = Triplet::from_canonical_name(spec_as_string.substr(pos + 1)); - return from_name_and_triplet(name, triplet); + return f; } ExpectedT PackageSpec::from_name_and_triplet(const std::string& name, diff --git a/toolsrc/src/commands_install.cpp b/toolsrc/src/commands_install.cpp index d340a9cf8..2ce5b6c62 100644 --- a/toolsrc/src/commands_install.cpp +++ b/toolsrc/src/commands_install.cpp @@ -16,6 +16,8 @@ namespace vcpkg::Commands::Install using Dependencies::InstallPlanAction; using Dependencies::RequestType; using Dependencies::InstallPlanType; + using Dependencies::RemovePlanAction; + using Dependencies::RemovePlanType; InstallDir InstallDir::from_destination_root(const fs::path& destination_root, const std::string& destination_subdirectory, @@ -290,7 +292,7 @@ namespace vcpkg::Commands::Install return BuildResult::SUCCEEDED; } - if (plan_type == InstallPlanType::BUILD_AND_INSTALL) + if (plan_type == InstallPlanType::BUILD_AND_INSTALL && !g_feature_packages) { if (use_head_version) System::println("Building package %s from HEAD... ", display_name); @@ -318,7 +320,36 @@ namespace vcpkg::Commands::Install return BuildResult::SUCCEEDED; } - if (plan_type == InstallPlanType::INSTALL) + if (plan_type == InstallPlanType::BUILD_AND_INSTALL && g_feature_packages) + { + if (use_head_version) + System::println("Building package %s from HEAD... ", display_name); + else + System::println("Building package %s... ", display_name); + + const Build::BuildPackageConfig build_config{ + *action.any_paragraph.source_control_file.value_or_exit(VCPKG_LINE_INFO), + action.spec.triplet(), + paths.port_dir(action.spec), + build_package_options, + action.feature_list}; + const auto result = Build::build_package(paths, build_config, status_db); + if (result.code != Build::BuildResult::SUCCEEDED) + { + System::println(System::Color::error, Build::create_error_message(result.code, action.spec)); + return result.code; + } + System::println("Building package %s... done", display_name); + + const BinaryParagraph bpgh = + Paragraphs::try_load_cached_package(paths, action.spec).value_or_exit(VCPKG_LINE_INFO); + System::println("Installing package %s... ", display_name); + install_package(paths, bpgh, &status_db); + System::println(System::Color::success, "Installing package %s... done", display_name); + return BuildResult::SUCCEEDED; + } + + if (plan_type == InstallPlanType::INSTALL && !g_feature_packages) { if (use_head_version && is_user_requested) { @@ -359,7 +390,8 @@ namespace vcpkg::Commands::Install // create the plan StatusParagraphs status_db = database_load_check(paths); - auto paths_port_file = Dependencies::PathsPortFile(paths); + + Dependencies::PathsPortFile paths_port_file(paths); std::vector install_plan = Dependencies::create_install_plan(paths_port_file, specs, status_db); Checks::check_exit(VCPKG_LINE_INFO, !install_plan.empty(), "Install plan cannot be empty"); diff --git a/toolsrc/src/commands_remove.cpp b/toolsrc/src/commands_remove.cpp index e2b5d12a1..eabf2b9ae 100644 --- a/toolsrc/src/commands_remove.cpp +++ b/toolsrc/src/commands_remove.cpp @@ -14,7 +14,7 @@ namespace vcpkg::Commands::Remove using Dependencies::RequestType; using Update::OutdatedPackage; - static void remove_package(const VcpkgPaths& paths, const PackageSpec& spec, StatusParagraphs* status_db) + 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()); diff --git a/toolsrc/src/test_install_plan.cpp b/toolsrc/src/test_install_plan.cpp index 671b6ed67..d02af5662 100644 --- a/toolsrc/src/test_install_plan.cpp +++ b/toolsrc/src/test_install_plan.cpp @@ -13,13 +13,16 @@ namespace UnitTest1 struct PackageSpecMap { std::unordered_map map; + Triplet triplet; + PackageSpecMap(const Triplet& t) { triplet = t; } + PackageSpec get_package_spec(std::vector>&& fields) { auto m_pgh = vcpkg::SourceControlFile::parse_control_file(std::move(fields)); Assert::IsTrue(m_pgh.has_value()); auto& scf = *m_pgh.get(); - auto spec = PackageSpec::from_name_and_triplet(scf->core_paragraph->name, Triplet::X86_WINDOWS); + auto spec = PackageSpec::from_name_and_triplet(scf->core_paragraph->name, triplet); Assert::IsTrue(spec.has_value()); map.emplace(*spec.get(), std::move(*scf.get())); return PackageSpec{*spec.get()}; @@ -32,11 +35,14 @@ namespace UnitTest1 static void features_check(Dependencies::AnyAction* install_action, std::string pkg_name, - std::vector vec) + std::vector vec, + const Triplet& triplet = Triplet::X86_WINDOWS) { - const auto& plan = *install_action->install_plan.get(); + const auto& plan = install_action->install_plan.value_or_exit(VCPKG_LINE_INFO); const auto& feature_list = plan.feature_list; + Assert::AreEqual(plan.spec.triplet().to_string().c_str(), triplet.to_string().c_str()); + Assert::AreEqual(pkg_name.c_str(), (*plan.any_paragraph.source_control_file.get())->core_paragraph->name.c_str()); Assert::AreEqual(size_t(vec.size()), feature_list.size()); @@ -53,16 +59,20 @@ namespace UnitTest1 } } - static void remove_plan_check(Dependencies::AnyAction* install_action, std::string pkg_name) + static void remove_plan_check(Dependencies::AnyAction* remove_action, + std::string pkg_name, + const Triplet& triplet = Triplet::X86_WINDOWS) { - Assert::AreEqual(pkg_name.c_str(), install_action->remove_plan.get()->spec.name().c_str()); + const auto& plan = remove_action->remove_plan.value_or_exit(VCPKG_LINE_INFO); + Assert::AreEqual(plan.spec.triplet().to_string().c_str(), triplet.to_string().c_str()); + Assert::AreEqual(pkg_name.c_str(), plan.spec.name().c_str()); } TEST_METHOD(basic_install_scheme) { std::vector> status_paragraphs; - PackageSpecMap spec_map; + PackageSpecMap spec_map(Triplet::X86_WINDOWS); auto spec_a = spec_map.set_package_map("a", "1.2.8", "b"); auto spec_b = spec_map.set_package_map("b", "1.3", "c"); auto spec_c = spec_map.set_package_map("c", "2.5.3", ""); @@ -81,7 +91,7 @@ namespace UnitTest1 { std::vector> status_paragraphs; - PackageSpecMap spec_map; + PackageSpecMap spec_map(Triplet::X86_WINDOWS); auto spec_a = spec_map.set_package_map("a", "1.2.8", "d"); auto spec_b = spec_map.set_package_map("b", "1.3", "d, e"); auto spec_c = spec_map.set_package_map("c", "2.5.3", "e, h"); @@ -134,7 +144,7 @@ namespace UnitTest1 {"Depends", ""}, {"Status", "install ok installed"}})); - PackageSpecMap spec_map; + PackageSpecMap spec_map(Triplet::X86_WINDOWS); auto spec_a = spec_map.set_package_map("a", "1.2.8", "b, c, d, e, f, g, h, j, k"); auto spec_b = spec_map.set_package_map("b", "1.2.8", "c, d, e, f, g, h, j, k"); @@ -188,7 +198,7 @@ namespace UnitTest1 {"Depends", ""}, {"Status", "install ok installed"}})); - PackageSpecMap spec_map; + PackageSpecMap spec_map(Triplet::X86_WINDOWS); auto spec_a = FullPackageSpec{spec_map.get_package_spec({ {{"Source", "a"}, {"Version", "1.3.8"}, {"Build-Depends", "b, b[beefeatureone]"}}, @@ -220,7 +230,7 @@ namespace UnitTest1 std::vector> status_paragraphs; - PackageSpecMap spec_map; + PackageSpecMap spec_map(Triplet::X86_WINDOWS); auto spec_a = FullPackageSpec{spec_map.get_package_spec( @@ -259,7 +269,7 @@ namespace UnitTest1 {"Depends", ""}, {"Status", "install ok installed"}})); - PackageSpecMap spec_map; + PackageSpecMap spec_map(Triplet::X86_WINDOWS); auto spec_a = FullPackageSpec{ spec_map.get_package_spec( @@ -303,7 +313,7 @@ namespace UnitTest1 {"Depends", ""}, {"Status", "install ok installed"}})); - PackageSpecMap spec_map; + PackageSpecMap spec_map(Triplet::X86_WINDOWS); auto spec_a = FullPackageSpec{ spec_map.get_package_spec( @@ -331,7 +341,7 @@ namespace UnitTest1 std::vector> status_paragraphs; - PackageSpecMap spec_map; + PackageSpecMap spec_map(Triplet::X86_WINDOWS); auto spec_a = FullPackageSpec{ spec_map.get_package_spec( @@ -366,7 +376,7 @@ namespace UnitTest1 {"Multi-Arch", "same"}, {"Depends", ""}, {"Status", "install ok installed"}})); - PackageSpecMap spec_map; + PackageSpecMap spec_map(Triplet::X86_WINDOWS); auto spec_a = FullPackageSpec{spec_map.get_package_spec({ {{"Source", "a"}, {"Version", "1.3"}, {"Build-Depends", "b[core]"}}, @@ -407,7 +417,7 @@ namespace UnitTest1 {"Multi-Arch", "same"}, {"Depends", ""}, {"Status", "install ok installed"}})); - PackageSpecMap spec_map; + PackageSpecMap spec_map(Triplet::X86_WINDOWS); auto spec_a = FullPackageSpec{spec_map.get_package_spec({ {{"Source", "a"}, {"Version", "1.3"}, {"Build-Depends", ""}}, @@ -435,5 +445,83 @@ namespace UnitTest1 features_check(&install_plan[3], "x", {"core"}); features_check(&install_plan[4], "b", {"core", "1"}); } + + TEST_METHOD(basic_feature_test_8) + { + using Pgh = std::unordered_map; + + std::vector> status_paragraphs; + status_paragraphs.push_back(std::make_unique(Pgh{{"Package", "a"}, + {"Default-Features", ""}, + {"Version", "1.3"}, + {"Architecture", "x64-windows"}, + {"Multi-Arch", "same"}, + {"Depends", ""}, + {"Status", "install ok installed"}})); + status_paragraphs.push_back(std::make_unique(Pgh{{"Package", "a"}, + {"Default-Features", ""}, + {"Version", "1.3"}, + {"Architecture", "x86-windows"}, + {"Multi-Arch", "same"}, + {"Depends", ""}, + {"Status", "install ok installed"}})); + + PackageSpecMap spec_map(Triplet::X64_WINDOWS); + + auto spec_a_64 = FullPackageSpec{ + spec_map.get_package_spec( + {{{"Source", "a"}, {"Version", "1.3"}, {"Build-Depends", "b"}}, + {{"Feature", "one"}, {"Description", "the first feature for a"}, {"Build-Depends", ""}}}), + {"core"}}; + auto spec_b_64 = FullPackageSpec{spec_map.get_package_spec({ + {{"Source", "b"}, {"Version", "1.3"}, {"Build-Depends", ""}}, + })}; + auto spec_c_64 = FullPackageSpec{spec_map.get_package_spec({ + {{"Source", "c"}, {"Version", "1.3"}, {"Build-Depends", "a[one]"}}, + }), + {"core"}}; + + spec_map.triplet = Triplet::X86_WINDOWS; + auto spec_a_86 = FullPackageSpec{ + spec_map.get_package_spec( + {{{"Source", "a"}, {"Version", "1.3"}, {"Build-Depends", "b"}}, + {{"Feature", "one"}, {"Description", "the first feature for a"}, {"Build-Depends", ""}}}), + {"core"}}; + auto spec_b_86 = FullPackageSpec{spec_map.get_package_spec({ + {{"Source", "b"}, {"Version", "1.3"}, {"Build-Depends", ""}}, + })}; + auto spec_c_86 = FullPackageSpec{spec_map.get_package_spec({ + {{"Source", "c"}, {"Version", "1.3"}, {"Build-Depends", "a[one]"}}, + }), + {"core"}}; + + auto install_plan = + Dependencies::create_feature_install_plan(spec_map.map, + {spec_c_64, spec_a_86, spec_a_64, spec_c_86}, + StatusParagraphs(std::move(status_paragraphs))); + + /*Assert::AreEqual(size_t(8), install_plan.size()); + auto iterator_pos = [&](const PackageSpec& spec, size_t start) -> int { + auto it = std::find_if(install_plan.begin() + start, install_plan.end(), [&](auto& action) { + return action.spec == spec; + }); + Assert::IsTrue(it != install_plan.end()); + return (int)(it - install_plan.begin()); + }; + int a_64_1 = iterator_pos(spec_a_64.package_spec, 0), a_86_1 = iterator_pos(spec_a_86.package_spec, 0), + b_64 = iterator_pos(spec_b_64.package_spec, 0), b_86 = iterator_pos(spec_b_86.package_spec, 0), + c_64 = iterator_pos(spec_c_64.package_spec, 0), c_86 = iterator_pos(spec_c_86.package_spec, 0), + a_64_2 = iterator_pos(spec_a_64.package_spec, a_64_1 + 1), + a_86_2 = iterator_pos(spec_a_86.package_spec, a_86_1 + 1);*/ + + remove_plan_check(&install_plan[0], "a", Triplet::X64_WINDOWS); + remove_plan_check(&install_plan[1], "a"); + features_check(&install_plan[2], "b", {"core"}, Triplet::X64_WINDOWS); + features_check(&install_plan[3], "a", {"one", "core"}, Triplet::X64_WINDOWS); + features_check(&install_plan[4], "c", {"core"}, Triplet::X64_WINDOWS); + features_check(&install_plan[5], "b", {"core"}); + features_check(&install_plan[6], "a", {"one", "core"}); + features_check(&install_plan[7], "c", {"core"}); + } }; } \ No newline at end of file diff --git a/toolsrc/src/tests_paragraph.cpp b/toolsrc/src/tests_paragraph.cpp index 2a53cc8b4..dd9a40160 100644 --- a/toolsrc/src/tests_paragraph.cpp +++ b/toolsrc/src/tests_paragraph.cpp @@ -372,25 +372,27 @@ namespace UnitTest1 TEST_METHOD(package_spec_parse) { - vcpkg::ExpectedT spec = - vcpkg::PackageSpec::from_string("zlib", vcpkg::Triplet::X86_WINDOWS); + vcpkg::ExpectedT spec = + vcpkg::FullPackageSpec::from_string("zlib", vcpkg::Triplet::X86_WINDOWS); Assert::AreEqual(vcpkg::PackageSpecParseResult::SUCCESS, spec.error()); - Assert::AreEqual("zlib", spec.get()->name().c_str()); - Assert::AreEqual(vcpkg::Triplet::X86_WINDOWS.canonical_name(), spec.get()->triplet().canonical_name()); + Assert::AreEqual("zlib", spec.get()->package_spec.name().c_str()); + Assert::AreEqual(vcpkg::Triplet::X86_WINDOWS.canonical_name(), + spec.get()->package_spec.triplet().canonical_name()); } TEST_METHOD(package_spec_parse_with_arch) { - vcpkg::ExpectedT spec = - vcpkg::PackageSpec::from_string("zlib:x64-uwp", vcpkg::Triplet::X86_WINDOWS); + vcpkg::ExpectedT spec = + vcpkg::FullPackageSpec::from_string("zlib:x64-uwp", vcpkg::Triplet::X86_WINDOWS); Assert::AreEqual(vcpkg::PackageSpecParseResult::SUCCESS, spec.error()); - Assert::AreEqual("zlib", spec.get()->name().c_str()); - Assert::AreEqual(vcpkg::Triplet::X64_UWP.canonical_name(), spec.get()->triplet().canonical_name()); + Assert::AreEqual("zlib", spec.get()->package_spec.name().c_str()); + Assert::AreEqual(vcpkg::Triplet::X64_UWP.canonical_name(), + spec.get()->package_spec.triplet().canonical_name()); } TEST_METHOD(package_spec_parse_with_multiple_colon) { - auto ec = vcpkg::PackageSpec::from_string("zlib:x86-uwp:", vcpkg::Triplet::X86_WINDOWS).error(); + auto ec = vcpkg::FullPackageSpec::from_string("zlib:x86-uwp:", vcpkg::Triplet::X86_WINDOWS).error(); Assert::AreEqual(vcpkg::PackageSpecParseResult::TOO_MANY_COLONS, ec); } diff --git a/toolsrc/src/vcpkg_Build.cpp b/toolsrc/src/vcpkg_Build.cpp index c794b5ede..a0d690f37 100644 --- a/toolsrc/src/vcpkg_Build.cpp +++ b/toolsrc/src/vcpkg_Build.cpp @@ -102,6 +102,17 @@ namespace vcpkg::Build paths.get_filesystem().write_contents(binary_control_file, Strings::serialize(bpgh)); } + static void create_binary_feature_control_file(const VcpkgPaths& paths, + const SourceParagraph& source_paragraph, + const FeatureParagraph& feature_paragraph, + const Triplet& triplet, + const BuildInfo& build_info) + { + BinaryParagraph bpgh = BinaryParagraph(source_paragraph, feature_paragraph, triplet); + const fs::path binary_control_file = paths.packages / bpgh.dir() / "CONTROL"; + paths.get_filesystem().write_contents(binary_control_file, Strings::serialize(bpgh)); + } + ExtendedBuildResult build_package(const VcpkgPaths& paths, const BuildPackageConfig& config, const StatusParagraphs& status_db) @@ -135,17 +146,36 @@ namespace vcpkg::Build const Toolset& toolset = paths.get_toolset(pre_build_info.platform_toolset); const auto cmd_set_environment = make_build_env_cmd(pre_build_info, toolset); + std::string features; + if (g_feature_packages) + { + if (config.feature_list) + { + for (auto&& feature : *config.feature_list) + { + features.append(feature + ";"); + } + if (features.size() > 0) + { + features.pop_back(); + } + } + } + const std::wstring cmd_launch_cmake = make_cmake_cmd( cmake_exe_path, ports_cmake_script_path, - {{L"CMD", L"BUILD"}, - {L"PORT", config.src.name}, - {L"CURRENT_PORT_DIR", config.port_dir / "/."}, - {L"TARGET_TRIPLET", triplet.canonical_name()}, - {L"VCPKG_PLATFORM_TOOLSET", toolset.version}, - {L"VCPKG_USE_HEAD_VERSION", to_bool(config.build_package_options.use_head_version) ? L"1" : L"0"}, - {L"_VCPKG_NO_DOWNLOADS", !to_bool(config.build_package_options.allow_downloads) ? L"1" : L"0"}, - {L"GIT", git_exe_path}}); + { + {L"CMD", L"BUILD"}, + {L"PORT", config.src.name}, + {L"CURRENT_PORT_DIR", config.port_dir / "/."}, + {L"TARGET_TRIPLET", triplet.canonical_name()}, + {L"VCPKG_PLATFORM_TOOLSET", toolset.version}, + {L"VCPKG_USE_HEAD_VERSION", to_bool(config.build_package_options.use_head_version) ? L"1" : L"0"}, + {L"_VCPKG_NO_DOWNLOADS", !to_bool(config.build_package_options.allow_downloads) ? L"1" : L"0"}, + {L"GIT", git_exe_path}, + {L"FEATURES", features}, + }); const std::wstring command = Strings::wformat(LR"(%s && %s)", cmd_set_environment, cmd_launch_cmake); @@ -170,7 +200,21 @@ namespace vcpkg::Build { return {BuildResult::POST_BUILD_CHECKS_FAILED, {}}; } - + if (g_feature_packages) + { + if (config.feature_list) + { + for (auto&& feature : *config.feature_list) + { + for (auto&& f_pgh : config.scf->feature_paragraphs) + { + if (f_pgh->name == feature) + create_binary_feature_control_file( + paths, *config.scf->core_paragraph, *f_pgh, triplet, build_info); + } + } + } + } create_binary_control_file(paths, config.src, triplet, build_info); // const fs::path port_buildtrees_dir = paths.buildtrees / spec.name; diff --git a/toolsrc/src/vcpkg_Dependencies.cpp b/toolsrc/src/vcpkg_Dependencies.cpp index 90168813e..820e51b33 100644 --- a/toolsrc/src/vcpkg_Dependencies.cpp +++ b/toolsrc/src/vcpkg_Dependencies.cpp @@ -12,6 +12,8 @@ namespace vcpkg::Dependencies { + bool operator==(const ClusterPtr& l, const ClusterPtr& r) { return l.ptr == r.ptr; } + std::vector AnyParagraph::dependencies(const Triplet& triplet) const { auto to_package_specs = [&](const std::vector& dependencies_as_string) { @@ -337,8 +339,7 @@ namespace vcpkg::Dependencies return toposort; } - std::vector to_feature_specs(const std::vector depends, - const std::unordered_map str_to_spec) + std::vector to_feature_specs(const std::vector& depends, const Triplet& triplet) { std::vector f_specs; for (auto&& depend : depends) @@ -350,21 +351,16 @@ namespace vcpkg::Dependencies auto feature_name = depend.substr(start + 1, end - start - 1); auto package_name = depend.substr(0, start); - auto p_spec = str_to_spec.find(package_name); - if (p_spec != str_to_spec.end()) - { - auto feature_spec = FeatureSpec{p_spec->second, feature_name}; - f_specs.emplace_back(std::move(feature_spec)); - } + auto p_spec = PackageSpec::from_name_and_triplet(package_name, triplet).value_or_exit(VCPKG_LINE_INFO); + auto feature_spec = FeatureSpec{p_spec, feature_name}; + f_specs.emplace_back(std::move(feature_spec)); } else { - auto p_spec = str_to_spec.find(depend); - if (p_spec != str_to_spec.end()) - { - auto feature_spec = FeatureSpec{p_spec->second, ""}; - f_specs.emplace_back(std::move(feature_spec)); - } + auto p_spec = PackageSpec::from_name_and_triplet(depend, triplet).value_or_exit(VCPKG_LINE_INFO); + + auto feature_spec = FeatureSpec{p_spec, ""}; + f_specs.emplace_back(std::move(feature_spec)); } } return f_specs; @@ -405,7 +401,7 @@ namespace vcpkg::Dependencies mark_minus(cluster, pkg_to_cluster, graph_plan); } - graph_plan.install_graph.add_vertex(&cluster); + graph_plan.install_graph.add_vertex({&cluster}); auto& tracked = cluster.to_install_features; tracked.insert(updated_feature); if (tracked.find("core") == tracked.end() && tracked.find("") == tracked.end()) @@ -415,7 +411,7 @@ namespace vcpkg::Dependencies { auto& depend_cluster = pkg_to_cluster[depend.spec]; mark_plus(depend.feature_name, depend_cluster, pkg_to_cluster, graph_plan); - graph_plan.install_graph.add_edge(&cluster, &depend_cluster); + graph_plan.install_graph.add_edge({&cluster}, {&depend_cluster}); } } @@ -424,7 +420,7 @@ namespace vcpkg::Dependencies auto& depend_cluster = pkg_to_cluster[depend.spec]; mark_plus(depend.feature_name, depend_cluster, pkg_to_cluster, graph_plan); if (&depend_cluster == &cluster) continue; - graph_plan.install_graph.add_edge(&cluster, &depend_cluster); + graph_plan.install_graph.add_edge({&cluster}, {&depend_cluster}); } return true; } @@ -434,14 +430,14 @@ namespace vcpkg::Dependencies if (cluster.will_remove) return; cluster.will_remove = true; - graph_plan.remove_graph.add_vertex(&cluster); + graph_plan.remove_graph.add_vertex({&cluster}); for (auto&& pair : cluster.edges) { auto& remove_edges_edges = pair.second.remove_edges; for (auto&& depend : remove_edges_edges) { auto& depend_cluster = pkg_to_cluster[depend.spec]; - graph_plan.remove_graph.add_edge(&cluster, &depend_cluster); + graph_plan.remove_graph.add_edge({&cluster}, {&depend_cluster}); depend_cluster.transient_uninstalled = true; mark_minus(depend_cluster, pkg_to_cluster, graph_plan); } @@ -456,40 +452,37 @@ namespace vcpkg::Dependencies const std::vector& specs, const StatusParagraphs& status_db) { - const auto triplet = Triplet::X86_WINDOWS; std::unordered_map pkg_spec_to_package_node; - std::unordered_map str_to_spec; - - for (const auto& it : map) - { - str_to_spec.emplace(it.first.name(), it.first); - } for (const auto& it : map) { Cluster& node = pkg_spec_to_package_node[it.first]; + + node.spec = it.first; FeatureNodeEdges core_dependencies; - core_dependencies.build_edges = - to_feature_specs(filter_dependencies(it.second.core_paragraph->depends, triplet), str_to_spec); + auto core_depends = filter_dependencies(it.second.core_paragraph->depends, node.spec.triplet()); + core_dependencies.build_edges = to_feature_specs(core_depends, node.spec.triplet()); node.edges["core"] = std::move(core_dependencies); for (const auto& feature : it.second.feature_paragraphs) { FeatureNodeEdges added_edges; - added_edges.build_edges = to_feature_specs(filter_dependencies(feature->depends, triplet), str_to_spec); + auto depends = filter_dependencies(feature->depends, node.spec.triplet()); + added_edges.build_edges = to_feature_specs(depends, node.spec.triplet()); node.edges.emplace(feature->name, std::move(added_edges)); } - node.cluster_data.source_paragraph = &it.second; + node.source_control_file = &it.second; } - for (auto&& status_paragraph : status_db) + for (auto&& status_paragraph : get_installed_ports(status_db)) { auto& spec = status_paragraph->package.spec; auto& status_paragraph_feature = status_paragraph->package.feature; Cluster& cluster = pkg_spec_to_package_node[spec]; cluster.transient_uninstalled = false; - auto reverse_edges = to_feature_specs(status_paragraph->package.depends, str_to_spec); + auto reverse_edges = + to_feature_specs(status_paragraph->package.depends, status_paragraph->package.spec.triplet()); for (auto&& dependency : reverse_edges) { @@ -507,7 +500,7 @@ namespace vcpkg::Dependencies auto& target_node = pkg_node->second.edges[depends_name]; target_node.remove_edges.emplace_back(FeatureSpec{spec, status_paragraph_feature}); } - cluster.cluster_data.status_paragraphs.emplace_back(*status_paragraph); + cluster.status_paragraphs.emplace_back(*status_paragraph); if (status_paragraph_feature == "") { cluster.original_features.insert("core"); @@ -528,35 +521,40 @@ namespace vcpkg::Dependencies } } - Graphs::GraphAdjacencyProvider adjacency_remove_graph(graph_plan.remove_graph.adjacency_list()); + Graphs::GraphAdjacencyProvider adjacency_remove_graph(graph_plan.remove_graph.adjacency_list()); auto remove_vertex_list = graph_plan.remove_graph.vertex_list(); auto remove_toposort = Graphs::topological_sort(remove_vertex_list, adjacency_remove_graph); - Graphs::GraphAdjacencyProvider adjacency_install_graph(graph_plan.install_graph.adjacency_list()); + Graphs::GraphAdjacencyProvider adjacency_install_graph(graph_plan.install_graph.adjacency_list()); auto insert_vertex_list = graph_plan.install_graph.vertex_list(); auto insert_toposort = Graphs::topological_sort(insert_vertex_list, adjacency_install_graph); std::vector install_plan; - for (auto&& cluster : remove_toposort) + for (auto&& like_cluster : remove_toposort) { - auto scf = *cluster->cluster_data.source_paragraph.get(); + auto scf = *like_cluster.ptr->source_control_file.get(); AnyAction any_plan; any_plan.remove_plan = RemovePlanAction{ - str_to_spec[scf->core_paragraph->name], RemovePlanType::REMOVE, RequestType::AUTO_SELECTED}; + PackageSpec::from_name_and_triplet(scf->core_paragraph->name, like_cluster.ptr->spec.triplet()) + .value_or_exit(VCPKG_LINE_INFO), + RemovePlanType::REMOVE, + RequestType::AUTO_SELECTED}; install_plan.emplace_back(std::move(any_plan)); } - for (auto&& cluster : insert_toposort) + for (auto&& like_cluster : insert_toposort) { - if (!cluster->transient_uninstalled) continue; - - auto scf = *cluster->cluster_data.source_paragraph.get(); - auto& pkg_spec = str_to_spec[scf->core_paragraph->name]; - auto action = InstallPlanAction{ - pkg_spec, map.find(pkg_spec)->second, cluster->to_install_features, RequestType::AUTO_SELECTED}; + if (!like_cluster.ptr->transient_uninstalled) continue; + + auto scf = *like_cluster.ptr->source_control_file.get(); + auto pkg_spec = + PackageSpec::from_name_and_triplet(scf->core_paragraph->name, like_cluster.ptr->spec.triplet()) + .value_or_exit(VCPKG_LINE_INFO); + auto action = + InstallPlanAction{pkg_spec, *scf, like_cluster.ptr->to_install_features, RequestType::AUTO_SELECTED}; AnyAction any_plan; any_plan.install_plan = std::move(action); diff --git a/toolsrc/src/vcpkg_Input.cpp b/toolsrc/src/vcpkg_Input.cpp index fdedd5507..f4e9a07c2 100644 --- a/toolsrc/src/vcpkg_Input.cpp +++ b/toolsrc/src/vcpkg_Input.cpp @@ -12,10 +12,10 @@ namespace vcpkg::Input CStringView example_text) { const std::string as_lowercase = Strings::ascii_to_lowercase(package_spec_as_string); - auto expected_spec = PackageSpec::from_string(as_lowercase, default_triplet); + auto expected_spec = FullPackageSpec::from_string(as_lowercase, default_triplet); if (auto spec = expected_spec.get()) { - return PackageSpec{*spec}; + return PackageSpec{spec->package_spec}; } // Intentionally show the lowercased string @@ -39,26 +39,11 @@ namespace vcpkg::Input const Triplet& default_triplet, CStringView example_text) { - int left_pos = (int)full_package_spec_as_string.find('['); - if (left_pos == std::string::npos) - { - return FullPackageSpec{ - check_and_get_package_spec(full_package_spec_as_string, default_triplet, example_text)}; - } - int right_pos = (int)full_package_spec_as_string.find(']'); - if (left_pos >= right_pos) - { - System::println(System::Color::error, "Error: Argument is not formatted correctly \"%s\""); - Checks::exit_fail(VCPKG_LINE_INFO); - } - - std::string package_spec_as_string = full_package_spec_as_string.substr(0, left_pos); - const std::string as_lowercase = Strings::ascii_to_lowercase(package_spec_as_string); - auto expected_spec = PackageSpec::from_string(as_lowercase, default_triplet); - if (auto&& spec = expected_spec.get()) + const std::string as_lowercase = Strings::ascii_to_lowercase(full_package_spec_as_string); + auto expected_spec = FullPackageSpec::from_string(as_lowercase, default_triplet); + if (auto spec = expected_spec.get()) { - return {*spec, - parse_comma_list(full_package_spec_as_string.substr(left_pos + 1, right_pos - left_pos - 1))}; + return *spec; } // Intentionally show the lowercased string diff --git a/toolsrc/src/vcpkg_Parse.cpp b/toolsrc/src/vcpkg_Parse.cpp index b63ce41a9..659af2939 100644 --- a/toolsrc/src/vcpkg_Parse.cpp +++ b/toolsrc/src/vcpkg_Parse.cpp @@ -6,18 +6,6 @@ namespace vcpkg::Parse { - static Optional get_field(const std::unordered_map& fields, - const std::string& fieldname) - { - auto it = fields.find(fieldname); - if (it == fields.end()) - { - return nullopt; - } - - return it->second; - } - static Optional remove_field(std::unordered_map* fields, const std::string& fieldname) { -- cgit v1.2.3 From 5d86005aa7a25f192d6a3023423e2977bcef7367 Mon Sep 17 00:00:00 2001 From: Mikhail Paulyshka Date: Tue, 25 Jul 2017 04:07:08 +0300 Subject: cmake: update to 3.9 --- toolsrc/src/VcpkgPaths.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp index 9068e3903..bc1152b9d 100644 --- a/toolsrc/src/VcpkgPaths.cpp +++ b/toolsrc/src/VcpkgPaths.cpp @@ -98,10 +98,10 @@ namespace vcpkg static fs::path get_cmake_path(const fs::path& downloads_folder, const fs::path scripts_folder) { - static constexpr std::array expected_version = {3, 8, 0}; + static constexpr std::array expected_version = {3, 9, 0}; static const std::wstring version_check_arguments = L"--version"; - const fs::path downloaded_copy = downloads_folder / "cmake-3.8.0-win32-x86" / "bin" / "cmake.exe"; + const fs::path downloaded_copy = downloads_folder / "cmake-3.9.0-win32-x86" / "bin" / "cmake.exe"; const std::vector from_path = find_from_PATH(L"cmake"); std::vector candidate_paths; -- cgit v1.2.3 From 60296cf16189d4cb048482a1c4476a41d9b18918 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Wed, 26 Jul 2017 13:54:28 -0700 Subject: [vcpkg] Add support for single-option arguments. --- toolsrc/include/VcpkgCmdArguments.h | 17 +++++++-- toolsrc/src/VcpkgCmdArguments.cpp | 69 ++++++++++++++++++++++++++++++++----- toolsrc/src/tests_arguments.cpp | 23 +++++++++++++ 3 files changed, 98 insertions(+), 11 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/VcpkgCmdArguments.h b/toolsrc/include/VcpkgCmdArguments.h index 316987100..0de5747b1 100644 --- a/toolsrc/include/VcpkgCmdArguments.h +++ b/toolsrc/include/VcpkgCmdArguments.h @@ -2,11 +2,18 @@ #include "vcpkg_optional.h" #include +#include #include #include namespace vcpkg { + struct ParsedArguments + { + std::unordered_set switches; + std::unordered_map settings; + }; + struct VcpkgCmdArguments { static VcpkgCmdArguments create_from_command_line(const int argc, const wchar_t* const* const argv); @@ -21,7 +28,13 @@ namespace vcpkg std::string command; std::vector command_arguments; std::unordered_set check_and_get_optional_command_arguments( - const std::vector& valid_options) const; + const std::vector& valid_options) const + { + return std::move(check_and_get_optional_command_arguments(valid_options, {}).switches); + } + + ParsedArguments check_and_get_optional_command_arguments(const std::vector& valid_switches, + const std::vector& valid_settings) const; void check_max_arg_count(const size_t expected_arg_count) const; void check_max_arg_count(const size_t expected_arg_count, const std::string& example_text) const; @@ -31,6 +44,6 @@ namespace vcpkg void check_exact_arg_count(const size_t expected_arg_count, const std::string& example_text) const; private: - std::unordered_set optional_command_arguments; + std::unordered_map> optional_command_arguments; }; } diff --git a/toolsrc/src/VcpkgCmdArguments.cpp b/toolsrc/src/VcpkgCmdArguments.cpp index 62e0b114c..ebf4c5fc5 100644 --- a/toolsrc/src/VcpkgCmdArguments.cpp +++ b/toolsrc/src/VcpkgCmdArguments.cpp @@ -123,7 +123,15 @@ namespace vcpkg continue; } - args.optional_command_arguments.insert(arg); + auto eq_pos = arg.find('='); + if (eq_pos != std::string::npos) + { + args.optional_command_arguments.emplace(arg.substr(0, eq_pos), arg.substr(eq_pos + 1)); + } + else + { + args.optional_command_arguments.emplace(arg, nullopt); + } continue; } @@ -140,30 +148,73 @@ namespace vcpkg return args; } - std::unordered_set VcpkgCmdArguments::check_and_get_optional_command_arguments( - const std::vector& valid_options) const + ParsedArguments VcpkgCmdArguments::check_and_get_optional_command_arguments( + const std::vector& valid_switches, const std::vector& valid_settings) const { - std::unordered_set output; + bool failed = false; + ParsedArguments output; + auto options_copy = this->optional_command_arguments; - for (const std::string& option : valid_options) + for (const std::string& option : valid_switches) { auto it = options_copy.find(option); if (it != options_copy.end()) { - output.insert(option); - options_copy.erase(it); + if (it->second.has_value()) + { + // Having a string value indicates it was passed like '--a=xyz' + System::println(System::Color::error, "The option '%s' does not accept an argument.", option); + failed = true; + } + else + { + output.switches.insert(option); + options_copy.erase(it); + } + } + } + + for (const std::string& option : valid_settings) + { + auto it = options_copy.find(option); + if (it != options_copy.end()) + { + if (!it->second.has_value()) + { + // Not having a string value indicates it was passed like '--a' + System::println(System::Color::error, "The option '%s' must be passed an argument.", option); + failed = true; + } + else + { + output.settings.emplace(option, it->second.value_or_exit(VCPKG_LINE_INFO)); + options_copy.erase(it); + } } } if (!options_copy.empty()) { System::println(System::Color::error, "Unknown option(s) for command '%s':", this->command); - for (const std::string& option : options_copy) + for (auto&& option : options_copy) + { + System::println(" %s", option.first); + } + System::println("\nValid options are:", this->command); + for (auto&& option : valid_switches) { - System::println(option); + System::println(" %s", option); } + for (auto&& option : valid_settings) + { + System::println(" %s=...", option); + } + System::println(" --triplet "); + System::println(" --vcpkg-root "); + Checks::exit_fail(VCPKG_LINE_INFO); } + if (failed) Checks::exit_fail(VCPKG_LINE_INFO); return output; } diff --git a/toolsrc/src/tests_arguments.cpp b/toolsrc/src/tests_arguments.cpp index 624fbb910..14b3c3d4f 100644 --- a/toolsrc/src/tests_arguments.cpp +++ b/toolsrc/src/tests_arguments.cpp @@ -31,5 +31,28 @@ namespace UnitTest1 Assert::IsTrue(v.sendmetrics && v.sendmetrics.get()); Assert::IsTrue(v.printmetrics && *v.printmetrics.get()); } + + TEST_METHOD(create_from_arg_sequence_valued_options) + { + std::vector t = {"--a=b", "command", "argument"}; + auto v = VcpkgCmdArguments::create_from_arg_sequence(t.data(), t.data() + t.size()); + auto opts = v.check_and_get_optional_command_arguments({}, {"--a"}); + Assert::AreEqual("b", opts.settings["--a"].c_str()); + Assert::AreEqual(size_t{1}, v.command_arguments.size()); + Assert::AreEqual("argument", v.command_arguments[0].c_str()); + Assert::AreEqual("command", v.command.c_str()); + } + + TEST_METHOD(create_from_arg_sequence_valued_options2) + { + std::vector t = {"--a", "--b=c"}; + auto v = VcpkgCmdArguments::create_from_arg_sequence(t.data(), t.data() + t.size()); + auto opts = v.check_and_get_optional_command_arguments({"--a", "--c"}, {"--b", "--d"}); + Assert::AreEqual("c", opts.settings["--b"].c_str()); + Assert::IsTrue(opts.settings.find("--d") == opts.settings.end()); + Assert::IsTrue(opts.switches.find("--a") != opts.switches.end()); + Assert::IsTrue(opts.settings.find("--c") == opts.settings.end()); + Assert::AreEqual(size_t{0}, v.command_arguments.size()); + } }; } \ No newline at end of file -- cgit v1.2.3 From 06597edfb7e47ff16c60c6dbbecf7883294d8ecb Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Wed, 26 Jul 2017 16:25:24 -0700 Subject: [vcpkg-export] Add NuGet id and NuGet version options to export command. --- toolsrc/include/vcpkg_optional.h | 6 +++++ toolsrc/src/commands_export.cpp | 49 ++++++++++++++++++++++++++++++---------- 2 files changed, 43 insertions(+), 12 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg_optional.h b/toolsrc/include/vcpkg_optional.h index 03fa50678..31a2d3e88 100644 --- a/toolsrc/include/vcpkg_optional.h +++ b/toolsrc/include/vcpkg_optional.h @@ -65,6 +65,12 @@ namespace vcpkg T m_t; }; + template + Optional> make_optional(U&& u) + { + return Optional>(std::forward(u)); + } + template bool operator==(const Optional& o, const T& t) { diff --git a/toolsrc/src/commands_export.cpp b/toolsrc/src/commands_export.cpp index cbb3a7733..5e1cc2052 100644 --- a/toolsrc/src/commands_export.cpp +++ b/toolsrc/src/commands_export.cpp @@ -110,11 +110,10 @@ namespace vcpkg::Commands::Export static fs::path do_nuget_export(const VcpkgPaths& paths, const std::string& nuget_id, + const std::string& nuget_version, const fs::path& raw_exported_dir, const fs::path& output_dir) { - static const std::string NUPKG_VERSION = "1.0.0"; - Files::Filesystem& fs = paths.get_filesystem(); const fs::path& nuget_exe = paths.get_nuget_exe(); @@ -129,7 +128,7 @@ namespace vcpkg::Commands::Export fs.write_contents(targets_redirect, targets_redirect_content); const std::string nuspec_file_content = - create_nuspec_file_contents(raw_exported_dir.string(), targets_redirect.string(), nuget_id, NUPKG_VERSION); + create_nuspec_file_contents(raw_exported_dir.string(), targets_redirect.string(), nuget_id, nuget_version); const fs::path nuspec_file_path = paths.buildsystems / "tmp" / "vcpkg.export.nuspec"; fs.write_contents(nuspec_file_path, nuspec_file_content); @@ -203,6 +202,16 @@ namespace vcpkg::Commands::Export return exported_archive_path; } + static Optional maybe_lookup(std::unordered_map const& m, + std::string const& key) + { + auto it = m.find(key); + if (it != m.end()) + return it->second; + else + return nullopt; + } + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) { static const std::string OPTION_DRY_RUN = "--dry-run"; @@ -210,6 +219,8 @@ namespace vcpkg::Commands::Export static const std::string OPTION_NUGET = "--nuget"; static const std::string OPTION_ZIP = "--zip"; static const std::string OPTION_7ZIP = "--7zip"; + static const std::string OPTION_NUGET_ID = "--nuget-id"; + static const std::string OPTION_NUGET_VERSION = "--nuget-version"; // input sanitization static const std::string example = @@ -222,18 +233,30 @@ namespace vcpkg::Commands::Export for (auto&& spec : specs) Input::check_triplet(spec.triplet(), paths); - const std::unordered_set options = args.check_and_get_optional_command_arguments( - {OPTION_DRY_RUN, OPTION_RAW, OPTION_NUGET, OPTION_ZIP, OPTION_7ZIP}); - const bool dryRun = options.find(OPTION_DRY_RUN) != options.cend(); - const bool raw = options.find(OPTION_RAW) != options.cend(); - const bool nuget = options.find(OPTION_NUGET) != options.cend(); - const bool zip = options.find(OPTION_ZIP) != options.cend(); - const bool _7zip = options.find(OPTION_7ZIP) != options.cend(); + const auto options = args.check_and_get_optional_command_arguments( + { + OPTION_DRY_RUN, OPTION_RAW, OPTION_NUGET, OPTION_ZIP, OPTION_7ZIP, + }, + { + OPTION_NUGET_ID, OPTION_NUGET_VERSION, + }); + const bool dryRun = options.switches.find(OPTION_DRY_RUN) != options.switches.cend(); + const bool raw = options.switches.find(OPTION_RAW) != options.switches.cend(); + const bool nuget = options.switches.find(OPTION_NUGET) != options.switches.cend(); + const bool zip = options.switches.find(OPTION_ZIP) != options.switches.cend(); + const bool _7zip = options.switches.find(OPTION_7ZIP) != options.switches.cend(); Checks::check_exit(VCPKG_LINE_INFO, raw || nuget || zip || _7zip, "Must provide at least one of the following options: --raw --nuget --zip --7zip"); + auto maybe_nuget_id = maybe_lookup(options.settings, OPTION_NUGET_ID); + auto maybe_nuget_version = maybe_lookup(options.settings, OPTION_NUGET_VERSION); + + Checks::check_exit(VCPKG_LINE_INFO, !maybe_nuget_id || nuget, "--nuget-id is only valid with --nuget"); + Checks::check_exit( + VCPKG_LINE_INFO, !maybe_nuget_version || nuget, "--nuget-version is only valid with --nuget"); + // create the plan StatusParagraphs status_db = database_load_check(paths); std::vector export_plan = Dependencies::create_export_plan(paths, specs, status_db); @@ -352,8 +375,10 @@ namespace vcpkg::Commands::Export { System::println("Creating nuget package... "); - const std::string nuget_id = raw_exported_dir_path.filename().string(); - const fs::path output_path = do_nuget_export(paths, nuget_id, raw_exported_dir_path, export_to_path); + const std::string nuget_id = maybe_nuget_id.value_or(raw_exported_dir_path.filename().string()); + const std::string nuget_version = maybe_nuget_version.value_or("1.0.0"); + const fs::path output_path = + do_nuget_export(paths, nuget_id, nuget_version, raw_exported_dir_path, export_to_path); System::println(System::Color::success, "Creating nuget package... done"); System::println(System::Color::success, "NuGet package exported at: %s", output_path.generic_string()); -- cgit v1.2.3 From 800af576df9c632053f1e71f8c16a1c3d37caec2 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Wed, 26 Jul 2017 16:46:22 -0700 Subject: [vcpkg-help] Improve help, including a list of topics. --- toolsrc/src/commands_help.cpp | 43 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/commands_help.cpp b/toolsrc/src/commands_help.cpp index e4be11a77..a12f9003d 100644 --- a/toolsrc/src/commands_help.cpp +++ b/toolsrc/src/commands_help.cpp @@ -5,6 +5,14 @@ namespace vcpkg::Commands::Help { + void help_topics() + { + System::println("Available help topics:\n" + " triplet\n" + " integrate\n" + " export"); + } + void help_topic_valid_triplet(const VcpkgPaths& paths) { System::println("Available architecture triplets:"); @@ -14,6 +22,21 @@ namespace vcpkg::Commands::Help } } + void help_topic_export() + { + System::println("Summary:\n" + " vcpkg export [options] ...\n" + "\n" + "Options:\n" + " --7zip Export to a 7zip (.7z) file\n" + " --dry-run Do not actually export\n" + " --nuget Export a NuGet package\n" + " --nuget-id= Specify the id for the exported NuGet package\n" + " --nuget-version= Specify the version for the exported NuGet package\n" + " --raw Export to an uncompressed directory\n" + " --zip Export to a zip file"); + } + void print_usage() { System::println( @@ -25,6 +48,8 @@ namespace vcpkg::Commands::Help " vcpkg list List installed packages\n" " vcpkg update Display list of packages for updating\n" " vcpkg hash [alg] Hash a file by specific algorithm, default SHA512\n" + " vcpkg help topics Display the list of help topics\n" + " vcpkg help Display help for a specific topic\n" "\n" "%s" // Integration help "\n" @@ -77,14 +102,28 @@ namespace vcpkg::Commands::Help Checks::exit_success(VCPKG_LINE_INFO); } const auto& topic = args.command_arguments[0]; - if (topic == "triplet") + if (topic == "triplet" || topic == "triplets" || topic == "triple") { help_topic_valid_triplet(paths); } + else if (topic == "export") + { + help_topic_export(); + } + else if (topic == "integrate") + { + System::print("Commands:\n" + "%s", + Integrate::INTEGRATE_COMMAND_HELPSTRING); + } + else if (topic == "topics") + { + help_topics(); + } else { System::println(System::Color::error, "Error: unknown topic %s", topic); - print_usage(); + help_topics(); Checks::exit_fail(VCPKG_LINE_INFO); } Checks::exit_success(VCPKG_LINE_INFO); -- cgit v1.2.3 From 17b6d75d0d16d8b620e6680c0364208aa8a52651 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Wed, 26 Jul 2017 16:51:28 -0700 Subject: [vcpkg-export] Tweak error formatting --- toolsrc/src/commands_export.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/commands_export.cpp b/toolsrc/src/commands_export.cpp index 5e1cc2052..4adfbc0f6 100644 --- a/toolsrc/src/commands_export.cpp +++ b/toolsrc/src/commands_export.cpp @@ -246,9 +246,12 @@ namespace vcpkg::Commands::Export const bool zip = options.switches.find(OPTION_ZIP) != options.switches.cend(); const bool _7zip = options.switches.find(OPTION_7ZIP) != options.switches.cend(); - Checks::check_exit(VCPKG_LINE_INFO, - raw || nuget || zip || _7zip, - "Must provide at least one of the following options: --raw --nuget --zip --7zip"); + if (!raw && !nuget && !zip && !_7zip && !dryRun) + { + System::println(System::Color::error, "Must provide at least one export type: --raw --nuget --zip --7zip"); + System::print(example); + Checks::exit_fail(VCPKG_LINE_INFO); + } auto maybe_nuget_id = maybe_lookup(options.settings, OPTION_NUGET_ID); auto maybe_nuget_version = maybe_lookup(options.settings, OPTION_NUGET_VERSION); -- cgit v1.2.3 From 8b49289b77472ba078dfa0d08dcd77a903e2c1ca Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 31 Jul 2017 03:18:00 -0700 Subject: [BinaryParagraph] Remove extra qualification (permissive-) --- toolsrc/include/BinaryParagraph.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/BinaryParagraph.h b/toolsrc/include/BinaryParagraph.h index f411b3c39..1e12dd8a6 100644 --- a/toolsrc/include/BinaryParagraph.h +++ b/toolsrc/include/BinaryParagraph.h @@ -14,9 +14,7 @@ namespace vcpkg BinaryParagraph(); explicit BinaryParagraph(std::unordered_map fields); BinaryParagraph(const SourceParagraph& spgh, const Triplet& triplet); - BinaryParagraph::BinaryParagraph(const SourceParagraph& spgh, - const FeatureParagraph& fpgh, - const Triplet& triplet); + BinaryParagraph(const SourceParagraph& spgh, const FeatureParagraph& fpgh, const Triplet& triplet); std::string displayname() const; -- cgit v1.2.3 From 957cb214e92f45069f142d8b6ccf2a6425df9c51 Mon Sep 17 00:00:00 2001 From: Daniel Shaw Date: Tue, 1 Aug 2017 15:17:42 -0700 Subject: change qualifier bracket to parens --- toolsrc/src/SourceParagraph.cpp | 2 +- toolsrc/src/tests_dependencies.cpp | 4 ++-- toolsrc/src/tests_paragraph.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/SourceParagraph.cpp b/toolsrc/src/SourceParagraph.cpp index 9289edb38..cb7aeb33e 100644 --- a/toolsrc/src/SourceParagraph.cpp +++ b/toolsrc/src/SourceParagraph.cpp @@ -160,7 +160,7 @@ namespace vcpkg // expect of the form "\w+ \[\w+\]" Dependency dep; dep.name = depend_string.substr(0, pos); - if (depend_string.c_str()[pos + 1] != '[' || depend_string[depend_string.size() - 1] != ']') + if (depend_string.c_str()[pos + 1] != '(' || depend_string[depend_string.size() - 1] != ')') { // Error, but for now just slurp the entire string. return {depend_string, ""}; diff --git a/toolsrc/src/tests_dependencies.cpp b/toolsrc/src/tests_dependencies.cpp index 995d46873..7a49bdbd0 100644 --- a/toolsrc/src/tests_dependencies.cpp +++ b/toolsrc/src/tests_dependencies.cpp @@ -15,7 +15,7 @@ namespace UnitTest1 { TEST_METHOD(parse_depends_one) { - auto v = expand_qualified_dependencies(parse_comma_list("libA [windows]")); + auto v = expand_qualified_dependencies(parse_comma_list("libA (windows)")); Assert::AreEqual(size_t(1), v.size()); Assert::AreEqual("libA", v[0].name.c_str()); Assert::AreEqual("windows", v[0].qualifier.c_str()); @@ -23,7 +23,7 @@ namespace UnitTest1 TEST_METHOD(filter_depends) { - auto deps = expand_qualified_dependencies(parse_comma_list("libA [windows], libB, libC [uwp]")); + auto deps = expand_qualified_dependencies(parse_comma_list("libA (windows), libB, libC (uwp)")); auto v = filter_dependencies(deps, Triplet::X64_WINDOWS); Assert::AreEqual(size_t(2), v.size()); Assert::AreEqual("libA", v[0].c_str()); diff --git a/toolsrc/src/tests_paragraph.cpp b/toolsrc/src/tests_paragraph.cpp index dd9a40160..920e58c02 100644 --- a/toolsrc/src/tests_paragraph.cpp +++ b/toolsrc/src/tests_paragraph.cpp @@ -112,7 +112,7 @@ namespace UnitTest1 { auto m_pgh = vcpkg::SourceControlFile::parse_control_file(std::vector>{{ - {"Source", "zlib"}, {"Version", "1.2.8"}, {"Build-Depends", "libA [windows], libB [uwp]"}, + {"Source", "zlib"}, {"Version", "1.2.8"}, {"Build-Depends", "libA (windows), libB (uwp)"}, }}); Assert::IsTrue(m_pgh.has_value()); auto& pgh = *m_pgh.get(); -- cgit v1.2.3 From cebc7acf025e888f70e84f56941d267b2fbda70a Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 7 Aug 2017 12:26:30 -0700 Subject: Updated version of nuget to 4.1.0 --- toolsrc/src/VcpkgPaths.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp index bc1152b9d..f3501e162 100644 --- a/toolsrc/src/VcpkgPaths.cpp +++ b/toolsrc/src/VcpkgPaths.cpp @@ -122,10 +122,10 @@ namespace vcpkg fs::path get_nuget_path(const fs::path& downloads_folder, const fs::path scripts_folder) { - static constexpr std::array expected_version = {3, 3, 0}; + static constexpr std::array expected_version = {4, 1, 0}; static const std::wstring version_check_arguments = L""; - const fs::path downloaded_copy = downloads_folder / "nuget-3.5.0" / "nuget.exe"; + const fs::path downloaded_copy = downloads_folder / "nuget-4.1.0" / "nuget.exe"; const std::vector from_path = find_from_PATH(L"nuget"); std::vector candidate_paths; -- cgit v1.2.3 From 5ef872a604cd9c1f067b4b5773ca2fef55c038e4 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 7 Aug 2017 16:11:39 -0700 Subject: Update CHANGELOG and bump version to v0.0.82 --- toolsrc/VERSION.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/VERSION.txt b/toolsrc/VERSION.txt index acd7a53e1..ab282ee07 100644 --- a/toolsrc/VERSION.txt +++ b/toolsrc/VERSION.txt @@ -1 +1 @@ -"0.0.81" \ No newline at end of file +"0.0.82" \ No newline at end of file -- cgit v1.2.3 From d5659ea88d6bfa656f82d22f2cd186fe2ebb3b27 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Tue, 8 Aug 2017 14:00:03 -0700 Subject: [vcpkg] Improve error messages during Binary Paragraph parsing --- toolsrc/src/BinaryParagraph.cpp | 4 +++- toolsrc/src/SourceParagraph.cpp | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/BinaryParagraph.cpp b/toolsrc/src/BinaryParagraph.cpp index b6f3e8a87..49e9d58e5 100644 --- a/toolsrc/src/BinaryParagraph.cpp +++ b/toolsrc/src/BinaryParagraph.cpp @@ -56,8 +56,10 @@ namespace vcpkg this->default_features = parse_comma_list(parser.optional_field(Fields::DEFAULTFEATURES)); } - if (auto err = parser.error_info(this->spec.name())) + if (auto err = parser.error_info(this->spec.to_string())) { + System::println( + System::Color::error, "Error: while parsing the Binary Paragraph for %s", this->spec.to_string()); print_error_message(err); Checks::exit_fail(VCPKG_LINE_INFO); } diff --git a/toolsrc/src/SourceParagraph.cpp b/toolsrc/src/SourceParagraph.cpp index 9289edb38..a34167db7 100644 --- a/toolsrc/src/SourceParagraph.cpp +++ b/toolsrc/src/SourceParagraph.cpp @@ -54,7 +54,7 @@ namespace vcpkg if (!error_info->extra_fields.empty()) { System::println(System::Color::error, - "Error: There are invalid fields in the Source Paragraph of %s", + "Error: There are invalid fields in the control file of %s", error_info->name); System::println("The following fields were not expected:\n\n %s\n", Strings::join("\n ", error_info->extra_fields)); @@ -74,7 +74,7 @@ namespace vcpkg if (!error_info->missing_fields.empty()) { System::println(System::Color::error, - "Error: There are missing fields in the Source Paragraphs of %s", + "Error: There are missing fields in the control file of %s", error_info->name); System::println("The following fields were missing:\n\n %s\n", Strings::join("\n ", error_info->missing_fields)); -- cgit v1.2.3 From 052b34d4c5df0ade113514552621798ad0e32173 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 9 Aug 2017 13:16:09 -0700 Subject: Add text filtering in `vcpkg depend-info` --- toolsrc/src/commands_depends.cpp | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/commands_depends.cpp b/toolsrc/src/commands_depends.cpp index ccfe58e4e..2d1fb658b 100644 --- a/toolsrc/src/commands_depends.cpp +++ b/toolsrc/src/commands_depends.cpp @@ -4,16 +4,44 @@ #include "vcpkg_Commands.h" #include "vcpkg_Strings.h" #include "vcpkg_System.h" +#include "vcpkg_Util.h" namespace vcpkg::Commands::DependInfo { void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { - static const std::string example = Commands::Help::create_example_string(R"###(depend-info)###"); - args.check_exact_arg_count(0, example); + static const std::string example = Commands::Help::create_example_string(R"###(depend-info [pat])###"); + args.check_max_arg_count(1, example); args.check_and_get_optional_command_arguments({}); - const auto source_control_files = Paragraphs::load_all_ports(paths.get_filesystem(), paths.ports); + std::vector> source_control_files = + Paragraphs::load_all_ports(paths.get_filesystem(), paths.ports); + + if (args.command_arguments.size() == 1) + { + const std::string filter = args.command_arguments.at(0); + + Util::erase_remove_if(source_control_files, + [&](const std::unique_ptr& source_control_file) { + + const SourceParagraph& source_paragraph = *source_control_file->core_paragraph; + + if (Strings::case_insensitive_ascii_contains(source_paragraph.name, filter)) + { + return false; + } + + for (const Dependency& dependency : source_paragraph.depends) + { + if (Strings::case_insensitive_ascii_contains(dependency.name, filter)) + { + return false; + } + } + + return true; + }); + } for (auto&& source_control_file : source_control_files) { -- cgit v1.2.3 From 6e5ec2ff08ebb2b1e746a7f950562c50d94b01c5 Mon Sep 17 00:00:00 2001 From: atkawa7 Date: Fri, 11 Aug 2017 09:10:37 -0700 Subject: [cmake] Fix cmake path --- toolsrc/src/VcpkgPaths.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp index f3501e162..38b11584a 100644 --- a/toolsrc/src/VcpkgPaths.cpp +++ b/toolsrc/src/VcpkgPaths.cpp @@ -98,10 +98,10 @@ namespace vcpkg static fs::path get_cmake_path(const fs::path& downloads_folder, const fs::path scripts_folder) { - static constexpr std::array expected_version = {3, 9, 0}; + static constexpr std::array expected_version = {3, 9, 1}; static const std::wstring version_check_arguments = L"--version"; - const fs::path downloaded_copy = downloads_folder / "cmake-3.9.0-win32-x86" / "bin" / "cmake.exe"; + const fs::path downloaded_copy = downloads_folder / "cmake-3.9.1-win32-x86" / "bin" / "cmake.exe"; const std::vector from_path = find_from_PATH(L"cmake"); std::vector candidate_paths; -- cgit v1.2.3 From 2cdabbf028d6b18c6dd14a84408957f87a925b67 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 11 Aug 2017 12:00:04 -0700 Subject: Update CHANGELOG and bump version to v0.0.83 --- toolsrc/VERSION.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/VERSION.txt b/toolsrc/VERSION.txt index ab282ee07..6320e715f 100644 --- a/toolsrc/VERSION.txt +++ b/toolsrc/VERSION.txt @@ -1 +1 @@ -"0.0.82" \ No newline at end of file +"0.0.83" \ No newline at end of file -- cgit v1.2.3 From 8a0a99b62a61b8efffd8a5e375900c4b572f5d3f Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 11 Aug 2017 15:40:06 -0700 Subject: Update required/downloaded git to 2.14.1 --- toolsrc/src/VcpkgPaths.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp index 38b11584a..f3513a3f3 100644 --- a/toolsrc/src/VcpkgPaths.cpp +++ b/toolsrc/src/VcpkgPaths.cpp @@ -143,10 +143,10 @@ namespace vcpkg fs::path get_git_path(const fs::path& downloads_folder, const fs::path scripts_folder) { - static constexpr std::array expected_version = {2, 0, 0}; + static constexpr std::array expected_version = {2, 14, 1}; static const std::wstring version_check_arguments = L"--version"; - const fs::path downloaded_copy = downloads_folder / "MinGit-2.11.1-32-bit" / "cmd" / "git.exe"; + const fs::path downloaded_copy = downloads_folder / "MinGit-2.14.1-32-bit" / "cmd" / "git.exe"; const std::vector from_path = find_from_PATH(L"git"); std::vector candidate_paths; -- cgit v1.2.3 From 3a0ae04ee662fe2819bc7aa1e7686671d2acf4d4 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 11 Aug 2017 16:09:45 -0700 Subject: Print more info when fetchDependency fails --- toolsrc/src/VcpkgPaths.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp index f3513a3f3..91f5ddb0e 100644 --- a/toolsrc/src/VcpkgPaths.cpp +++ b/toolsrc/src/VcpkgPaths.cpp @@ -72,14 +72,21 @@ namespace vcpkg static fs::path fetch_dependency(const fs::path scripts_folder, const std::wstring& tool_name, - const fs::path& expected_downloaded_path) + const fs::path& expected_downloaded_path, + const std::array& version) { const fs::path script = scripts_folder / "fetchDependency.ps1"; auto install_cmd = System::create_powershell_script_cmd(script, Strings::wformat(L"-Dependency %s", tool_name)); System::ExitCodeAndOutput rc = System::cmd_execute_and_capture_output(install_cmd); if (rc.exit_code) { - System::println(System::Color::error, "Launching powershell failed or was denied"); + const std::string version_as_string = Strings::format("%d.%d.%d", version[0], version[1], version[2]); + + System::println(System::Color::error, + "Launching powershell failed or was denied when trying to fetch %s version %s.\n" + "(No sufficient installed version was found)", + Strings::to_utf8(tool_name), + version_as_string); Metrics::track_property("error", "powershell install failed"); Metrics::track_property("installcmd", install_cmd); Checks::exit_with_code(VCPKG_LINE_INFO, rc.exit_code); @@ -117,7 +124,7 @@ namespace vcpkg return *p; } - return fetch_dependency(scripts_folder, L"cmake", downloaded_copy); + return fetch_dependency(scripts_folder, L"cmake", downloaded_copy, expected_version); } fs::path get_nuget_path(const fs::path& downloads_folder, const fs::path scripts_folder) @@ -138,7 +145,7 @@ namespace vcpkg return *p; } - return fetch_dependency(scripts_folder, L"nuget", downloaded_copy); + return fetch_dependency(scripts_folder, L"nuget", downloaded_copy, expected_version); } fs::path get_git_path(const fs::path& downloads_folder, const fs::path scripts_folder) @@ -162,7 +169,7 @@ namespace vcpkg return *p; } - return fetch_dependency(scripts_folder, L"git", downloaded_copy); + return fetch_dependency(scripts_folder, L"git", downloaded_copy, expected_version); } Expected VcpkgPaths::create(const fs::path& vcpkg_root_dir) -- cgit v1.2.3 From 011368ef9e1754715873eb0a298f0d069210ea6c Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 11 Aug 2017 16:11:00 -0700 Subject: Take path by const& --- toolsrc/src/VcpkgPaths.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp index 91f5ddb0e..60204bcdd 100644 --- a/toolsrc/src/VcpkgPaths.cpp +++ b/toolsrc/src/VcpkgPaths.cpp @@ -70,7 +70,7 @@ namespace vcpkg return Util::fmap(Strings::split(out.output, "\n"), [](auto&& s) { return fs::path(s); }); } - static fs::path fetch_dependency(const fs::path scripts_folder, + static fs::path fetch_dependency(const fs::path& scripts_folder, const std::wstring& tool_name, const fs::path& expected_downloaded_path, const std::array& version) @@ -103,7 +103,7 @@ namespace vcpkg return actual_downloaded_path; } - static fs::path get_cmake_path(const fs::path& downloads_folder, const fs::path scripts_folder) + static fs::path get_cmake_path(const fs::path& downloads_folder, const fs::path& scripts_folder) { static constexpr std::array expected_version = {3, 9, 1}; static const std::wstring version_check_arguments = L"--version"; @@ -127,7 +127,7 @@ namespace vcpkg return fetch_dependency(scripts_folder, L"cmake", downloaded_copy, expected_version); } - fs::path get_nuget_path(const fs::path& downloads_folder, const fs::path scripts_folder) + fs::path get_nuget_path(const fs::path& downloads_folder, const fs::path& scripts_folder) { static constexpr std::array expected_version = {4, 1, 0}; static const std::wstring version_check_arguments = L""; @@ -148,7 +148,7 @@ namespace vcpkg return fetch_dependency(scripts_folder, L"nuget", downloaded_copy, expected_version); } - fs::path get_git_path(const fs::path& downloads_folder, const fs::path scripts_folder) + fs::path get_git_path(const fs::path& downloads_folder, const fs::path& scripts_folder) { static constexpr std::array expected_version = {2, 14, 1}; static const std::wstring version_check_arguments = L"--version"; -- cgit v1.2.3 From 561e1dd69b8f53c1a87f2e68ff347b4a60c950e1 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Tue, 15 Aug 2017 13:58:04 -0700 Subject: [vcpkg-tests] Reformat --- toolsrc/src/tests_paragraph.cpp | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/tests_paragraph.cpp b/toolsrc/src/tests_paragraph.cpp index 920e58c02..af4b55498 100644 --- a/toolsrc/src/tests_paragraph.cpp +++ b/toolsrc/src/tests_paragraph.cpp @@ -27,7 +27,8 @@ namespace UnitTest1 { auto m_pgh = vcpkg::SourceControlFile::parse_control_file(std::vector>{{ - {"Source", "zlib"}, {"Version", "1.2.8"}, + {"Source", "zlib"}, + {"Version", "1.2.8"}, }}); Assert::IsTrue(m_pgh.has_value()); @@ -68,7 +69,9 @@ namespace UnitTest1 { auto m_pgh = vcpkg::SourceControlFile::parse_control_file(std::vector>{{ - {"Source", "zlib"}, {"Version", "1.2.8"}, {"Build-Depends", "z, openssl"}, + {"Source", "zlib"}, + {"Version", "1.2.8"}, + {"Build-Depends", "z, openssl"}, }}); Assert::IsTrue(m_pgh.has_value()); auto& pgh = *m_pgh.get(); @@ -82,7 +85,9 @@ namespace UnitTest1 { auto m_pgh = vcpkg::SourceControlFile::parse_control_file(std::vector>{{ - {"Source", "zlib"}, {"Version", "1.2.8"}, {"Build-Depends", "z, openssl, xyz"}, + {"Source", "zlib"}, + {"Version", "1.2.8"}, + {"Build-Depends", "z, openssl, xyz"}, }}); Assert::IsTrue(m_pgh.has_value()); auto& pgh = *m_pgh.get(); @@ -97,7 +102,9 @@ namespace UnitTest1 { auto m_pgh = vcpkg::SourceControlFile::parse_control_file(std::vector>{{ - {"Source", "zlib"}, {"Version", "1.2.8"}, {"Supports", "x64, windows, uwp"}, + {"Source", "zlib"}, + {"Version", "1.2.8"}, + {"Supports", "x64, windows, uwp"}, }}); Assert::IsTrue(m_pgh.has_value()); auto& pgh = *m_pgh.get(); @@ -112,7 +119,9 @@ namespace UnitTest1 { auto m_pgh = vcpkg::SourceControlFile::parse_control_file(std::vector>{{ - {"Source", "zlib"}, {"Version", "1.2.8"}, {"Build-Depends", "libA (windows), libB (uwp)"}, + {"Source", "zlib"}, + {"Version", "1.2.8"}, + {"Build-Depends", "libA (windows), libB (uwp)"}, }}); Assert::IsTrue(m_pgh.has_value()); auto& pgh = *m_pgh.get(); @@ -131,7 +140,10 @@ namespace UnitTest1 TEST_METHOD(BinaryParagraph_Construct_Minimum) { vcpkg::BinaryParagraph pgh({ - {"Package", "zlib"}, {"Version", "1.2.8"}, {"Architecture", "x86-windows"}, {"Multi-Arch", "same"}, + {"Package", "zlib"}, + {"Version", "1.2.8"}, + {"Architecture", "x86-windows"}, + {"Multi-Arch", "same"}, }); Assert::AreEqual("zlib", pgh.spec.name().c_str()); @@ -320,7 +332,10 @@ namespace UnitTest1 TEST_METHOD(BinaryParagraph_serialize_min) { vcpkg::BinaryParagraph pgh({ - {"Package", "zlib"}, {"Version", "1.2.8"}, {"Architecture", "x86-windows"}, {"Multi-Arch", "same"}, + {"Package", "zlib"}, + {"Version", "1.2.8"}, + {"Architecture", "x86-windows"}, + {"Multi-Arch", "same"}, }); std::string ss = Strings::serialize(pgh); auto pghs = vcpkg::Paragraphs::parse_paragraphs(ss).value_or_exit(VCPKG_LINE_INFO); -- cgit v1.2.3 From 307b761df4197bf9cf1b69652808530e6219a868 Mon Sep 17 00:00:00 2001 From: Daniel Shaw Date: Tue, 25 Jul 2017 21:29:31 -0700 Subject: partial end to end feature packages hdf5 added vcpkg feature package support to other commands remove comments change qualifier bracket to parens added features to qualified dependencies --- toolsrc/include/BinaryParagraph.h | 6 ++ toolsrc/include/Paragraphs.h | 2 +- toolsrc/include/SourceParagraph.h | 15 ++- toolsrc/include/StatusParagraphs.h | 3 + toolsrc/include/vcpkg_Commands.h | 2 +- toolsrc/include/vcpkg_Dependencies.h | 5 +- toolsrc/src/BinaryParagraph.cpp | 12 ++- toolsrc/src/Paragraphs.cpp | 16 ++- toolsrc/src/SourceParagraph.cpp | 57 +++++++++- toolsrc/src/StatusParagraphs.cpp | 26 ++++- toolsrc/src/commands_depends.cpp | 2 +- toolsrc/src/commands_install.cpp | 200 ++++++++++++++++++++++++++++++----- toolsrc/src/commands_remove.cpp | 27 +++-- toolsrc/src/commands_search.cpp | 2 +- toolsrc/src/test_install_plan.cpp | 50 ++++++++- toolsrc/src/tests_dependencies.cpp | 2 +- toolsrc/src/tests_paragraph.cpp | 28 +++-- toolsrc/src/vcpkg_Build.cpp | 46 +++++--- toolsrc/src/vcpkg_Dependencies.cpp | 52 ++++++--- toolsrc/src/vcpkglib.cpp | 2 +- 20 files changed, 459 insertions(+), 96 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/BinaryParagraph.h b/toolsrc/include/BinaryParagraph.h index 1e12dd8a6..61e03343a 100644 --- a/toolsrc/include/BinaryParagraph.h +++ b/toolsrc/include/BinaryParagraph.h @@ -31,5 +31,11 @@ namespace vcpkg std::vector depends; }; + struct BinaryControlFile + { + BinaryParagraph core_paragraph; + std::vector features; + }; + void serialize(const BinaryParagraph& pgh, std::string& out_str); } \ No newline at end of file diff --git a/toolsrc/include/Paragraphs.h b/toolsrc/include/Paragraphs.h index 60f509266..aae46f7da 100644 --- a/toolsrc/include/Paragraphs.h +++ b/toolsrc/include/Paragraphs.h @@ -20,7 +20,7 @@ namespace vcpkg::Paragraphs Parse::ParseExpected try_load_port(const Files::Filesystem& fs, const fs::path& control_path); - Expected try_load_cached_package(const VcpkgPaths& paths, const PackageSpec& spec); + Expected try_load_cached_control_package(const VcpkgPaths& paths, const PackageSpec& spec); struct LoadResults { diff --git a/toolsrc/include/SourceParagraph.h b/toolsrc/include/SourceParagraph.h index 7ddf999cc..fee61c3e8 100644 --- a/toolsrc/include/SourceParagraph.h +++ b/toolsrc/include/SourceParagraph.h @@ -15,13 +15,24 @@ namespace vcpkg struct Triplet; - struct Dependency + struct Features { std::string name; + std::vector features; + }; + + Features parse_feature_list(const std::string& name); + + struct Dependency + { + Features depend; std::string qualifier; + + std::string name() const; + static Dependency parse_dependency(std::string name, std::string qualifier); }; - const std::string& to_string(const Dependency& dep); + const std::string to_string(const Dependency& dep); struct FeatureParagraph { diff --git a/toolsrc/include/StatusParagraphs.h b/toolsrc/include/StatusParagraphs.h index 2af177219..bf2ef2f3e 100644 --- a/toolsrc/include/StatusParagraphs.h +++ b/toolsrc/include/StatusParagraphs.h @@ -17,6 +17,9 @@ namespace vcpkg const_iterator find(const PackageSpec& spec) const { return find(spec.name(), spec.triplet()); } const_iterator find(const std::string& name, const Triplet& triplet) const; iterator find(const std::string& name, const Triplet& triplet); + std::vector*> StatusParagraphs::find_all(const std::string& name, + const Triplet& triplet); + iterator find(const std::string& name, const Triplet& triplet, const std::string& feature); const_iterator find_installed(const PackageSpec& spec) const { diff --git a/toolsrc/include/vcpkg_Commands.h b/toolsrc/include/vcpkg_Commands.h index 8348a64e4..d5f316d69 100644 --- a/toolsrc/include/vcpkg_Commands.h +++ b/toolsrc/include/vcpkg_Commands.h @@ -59,7 +59,7 @@ namespace vcpkg::Commands const fs::path& source_dir, const InstallDir& dirs); void install_package(const VcpkgPaths& paths, - const BinaryParagraph& binary_paragraph, + const BinaryControlFile& binary_paragraph, StatusParagraphs* status_db); void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet); } diff --git a/toolsrc/include/vcpkg_Dependencies.h b/toolsrc/include/vcpkg_Dependencies.h index e3af0fd28..3fee8ef33 100644 --- a/toolsrc/include/vcpkg_Dependencies.h +++ b/toolsrc/include/vcpkg_Dependencies.h @@ -90,6 +90,7 @@ namespace vcpkg::Dependencies InstallPlanAction(InstallPlanAction&&) = default; InstallPlanAction& operator=(const InstallPlanAction&) = delete; InstallPlanAction& operator=(InstallPlanAction&&) = default; + std::string displayname() const; PackageSpec spec; AnyParagraph any_paragraph; @@ -205,7 +206,9 @@ namespace vcpkg::Dependencies std::unordered_map& pkg_to_cluster, GraphPlan& graph_plan); void mark_minus(Cluster& cluster, std::unordered_map& pkg_to_cluster, GraphPlan& graph_plan); - + void mark_plus_default(Cluster& cluster, + std::unordered_map& pkg_to_cluster, + GraphPlan& graph_plan); std::vector create_feature_install_plan(const std::unordered_map& map, const std::vector& specs, const StatusParagraphs& status_db); diff --git a/toolsrc/src/BinaryParagraph.cpp b/toolsrc/src/BinaryParagraph.cpp index 49e9d58e5..9abd388b9 100644 --- a/toolsrc/src/BinaryParagraph.cpp +++ b/toolsrc/src/BinaryParagraph.cpp @@ -87,7 +87,17 @@ namespace vcpkg this->depends = filter_dependencies(fpgh.depends, triplet); } - std::string BinaryParagraph::displayname() const { return this->spec.to_string(); } + std::string BinaryParagraph::displayname() const + { + if (this->feature == "") + { + return this->spec.name() + "[core]:" + this->spec.triplet().to_string(); + } + else + { + return this->spec.name() + "[" + this->feature + "]:" + this->spec.triplet().to_string(); + } + } std::string BinaryParagraph::dir() const { return this->spec.dir(); } diff --git a/toolsrc/src/Paragraphs.cpp b/toolsrc/src/Paragraphs.cpp index 3749e919e..3a30f66a3 100644 --- a/toolsrc/src/Paragraphs.cpp +++ b/toolsrc/src/Paragraphs.cpp @@ -3,6 +3,7 @@ #include "ParagraphParseResult.h" #include "Paragraphs.h" #include "vcpkg_Files.h" +#include "vcpkg_Util.h" using namespace vcpkg::Parse; @@ -226,14 +227,21 @@ namespace vcpkg::Paragraphs return error_info; } - Expected try_load_cached_package(const VcpkgPaths& paths, const PackageSpec& spec) + Expected try_load_cached_control_package(const VcpkgPaths& paths, const PackageSpec& spec) { - Expected> pghs = - get_single_paragraph(paths.get_filesystem(), paths.package_dir(spec) / "CONTROL"); + Expected>> pghs = + get_paragraphs(paths.get_filesystem(), paths.package_dir(spec) / "CONTROL"); if (auto p = pghs.get()) { - return BinaryParagraph(*p); + BinaryControlFile bcf; + bcf.core_paragraph = BinaryParagraph(p->front()); + p->erase(p->begin()); + + bcf.features = + Util::fmap(*p, [&](auto&& raw_feature) -> BinaryParagraph { return BinaryParagraph(raw_feature); }); + + return bcf; } return pghs.error(); diff --git a/toolsrc/src/SourceParagraph.cpp b/toolsrc/src/SourceParagraph.cpp index a37567f3a..2aab7c572 100644 --- a/toolsrc/src/SourceParagraph.cpp +++ b/toolsrc/src/SourceParagraph.cpp @@ -152,18 +152,61 @@ namespace vcpkg return std::move(control_file); } + Features parse_feature_list(const std::string& name) + { + Features f; + int end = (int)name.find(']'); + if (end != std::string::npos) + { + int start = (int)name.find('['); + + auto feature_name_list = name.substr(start + 1, end - start - 1); + f.name = name.substr(0, start); + f.features = parse_comma_list(feature_name_list); + } + else + { + f.name = name; + } + return f; + } + + Dependency Dependency::parse_dependency(std::string name, std::string qualifier) + { + Dependency dep; + dep.qualifier = qualifier; + dep.depend = parse_feature_list(name); + return dep; + } + + std::string Dependency::name() const + { + std::string str = this->depend.name; + if (this->depend.features.empty()) return str; + + str += "["; + for (auto&& s : this->depend.features) + { + str += s + ","; + } + str.pop_back(); + str += "]"; + return str; + } + std::vector vcpkg::expand_qualified_dependencies(const std::vector& depends) { return Util::fmap(depends, [&](const std::string& depend_string) -> Dependency { auto pos = depend_string.find(' '); - if (pos == std::string::npos) return {depend_string, ""}; + if (pos == std::string::npos) return Dependency::parse_dependency(depend_string, ""); // expect of the form "\w+ \[\w+\]" Dependency dep; - dep.name = depend_string.substr(0, pos); + + dep.depend.name = depend_string.substr(0, pos); if (depend_string.c_str()[pos + 1] != '(' || depend_string[depend_string.size() - 1] != ')') { // Error, but for now just slurp the entire string. - return {depend_string, ""}; + return Dependency::parse_dependency(depend_string, ""); } dep.qualifier = depend_string.substr(pos + 2, depend_string.size() - pos - 3); return dep; @@ -210,13 +253,17 @@ namespace vcpkg { if (dep.qualifier.empty() || t.canonical_name().find(dep.qualifier) != std::string::npos) { - ret.push_back(dep.name); + ret.emplace_back(dep.name()); } } return ret; } - const std::string& to_string(const Dependency& dep) { return dep.name; } + const std::string to_string(const Dependency& dep) + { + std::string name = dep.name(); + return name; + } ExpectedT> Supports::parse(const std::vector& strs) { diff --git a/toolsrc/src/StatusParagraphs.cpp b/toolsrc/src/StatusParagraphs.cpp index 27f3c30a2..02ee61f75 100644 --- a/toolsrc/src/StatusParagraphs.cpp +++ b/toolsrc/src/StatusParagraphs.cpp @@ -27,6 +27,30 @@ namespace vcpkg }); } + std::vector*> StatusParagraphs::find_all(const std::string& name, + const Triplet& triplet) + { + std::vector*> spghs; + for (auto&& p : *this) + { + if (p->package.spec.name() == name && p->package.spec.triplet() == triplet) + { + spghs.emplace_back(&p); + } + } + return spghs; + } + + StatusParagraphs::iterator StatusParagraphs::find(const std::string& name, + const Triplet& triplet, + const std::string& feature) + { + return std::find_if(begin(), end(), [&](const std::unique_ptr& pgh) { + const PackageSpec& spec = pgh->package.spec; + return spec.name() == name && spec.triplet() == triplet && pgh->package.feature == feature; + }); + } + StatusParagraphs::const_iterator StatusParagraphs::find_installed(const std::string& name, const Triplet& triplet) const { @@ -43,7 +67,7 @@ namespace vcpkg { Checks::check_exit(VCPKG_LINE_INFO, pgh != nullptr, "Inserted null paragraph"); const PackageSpec& spec = pgh->package.spec; - auto ptr = find(spec.name(), spec.triplet()); + auto ptr = find(spec.name(), spec.triplet(), pgh->package.feature); if (ptr == end()) { paragraphs.push_back(std::move(pgh)); diff --git a/toolsrc/src/commands_depends.cpp b/toolsrc/src/commands_depends.cpp index 2d1fb658b..b04af5282 100644 --- a/toolsrc/src/commands_depends.cpp +++ b/toolsrc/src/commands_depends.cpp @@ -46,7 +46,7 @@ namespace vcpkg::Commands::DependInfo for (auto&& source_control_file : source_control_files) { const SourceParagraph& source_paragraph = *source_control_file->core_paragraph; - auto s = Strings::join(", ", source_paragraph.depends, [](const Dependency& d) { return d.name; }); + auto s = Strings::join(", ", source_paragraph.depends, [](const Dependency& d) { return d.name(); }); System::println("%s: %s", source_paragraph.name, s); } diff --git a/toolsrc/src/commands_install.cpp b/toolsrc/src/commands_install.cpp index 2ce5b6c62..2965d9025 100644 --- a/toolsrc/src/commands_install.cpp +++ b/toolsrc/src/commands_install.cpp @@ -211,10 +211,10 @@ namespace vcpkg::Commands::Install } } - void install_package(const VcpkgPaths& paths, const BinaryParagraph& binary_paragraph, StatusParagraphs* status_db) + void install_package(const VcpkgPaths& paths, const BinaryControlFile& bcf, StatusParagraphs* status_db) { - const fs::path package_dir = paths.package_dir(binary_paragraph.spec); - const Triplet& triplet = binary_paragraph.spec.triplet(); + const fs::path package_dir = paths.package_dir(bcf.core_paragraph.spec); + const Triplet& triplet = bcf.core_paragraph.spec.triplet(); const std::vector pgh_and_files = get_installed_files(paths, *status_db); const SortedVector package_files = @@ -234,7 +234,7 @@ namespace vcpkg::Commands::Install System::println(System::Color::error, "The following files are already installed in %s and are in conflict with %s", triplet_install_path.generic_string(), - binary_paragraph.spec); + bcf.core_paragraph.spec); System::print("\n "); System::println(Strings::join("\n ", intersection)); System::println(""); @@ -242,27 +242,42 @@ namespace vcpkg::Commands::Install } StatusParagraph source_paragraph; - source_paragraph.package = binary_paragraph; + source_paragraph.package = bcf.core_paragraph; source_paragraph.want = Want::INSTALL; source_paragraph.state = InstallState::HALF_INSTALLED; - for (auto&& dep : source_paragraph.package.depends) - { - if (status_db->find_installed(dep, source_paragraph.package.spec.triplet()) == status_db->end()) - { - Checks::unreachable(VCPKG_LINE_INFO); - } - } + write_update(paths, source_paragraph); status_db->insert(std::make_unique(source_paragraph)); + std::vector features_spghs; + for (auto&& feature : bcf.features) + { + features_spghs.emplace_back(); + + StatusParagraph& feature_paragraph = features_spghs.back(); + feature_paragraph.package = feature; + feature_paragraph.want = Want::INSTALL; + feature_paragraph.state = InstallState::HALF_INSTALLED; + + write_update(paths, feature_paragraph); + status_db->insert(std::make_unique(feature_paragraph)); + } + const InstallDir install_dir = InstallDir::from_destination_root( - paths.installed, triplet.to_string(), paths.listfile_path(binary_paragraph)); + paths.installed, triplet.to_string(), paths.listfile_path(bcf.core_paragraph)); install_files_and_write_listfile(paths.get_filesystem(), package_dir, install_dir); source_paragraph.state = InstallState::INSTALLED; write_update(paths, source_paragraph); status_db->insert(std::make_unique(source_paragraph)); + + for (auto&& feature_paragraph : features_spghs) + { + feature_paragraph.state = InstallState::INSTALLED; + write_update(paths, feature_paragraph); + status_db->insert(std::make_unique(feature_paragraph)); + } } using Build::BuildResult; @@ -312,8 +327,8 @@ namespace vcpkg::Commands::Install } System::println("Building package %s... done", display_name); - const BinaryParagraph bpgh = - Paragraphs::try_load_cached_package(paths, action.spec).value_or_exit(VCPKG_LINE_INFO); + const BinaryControlFile bpgh = + Paragraphs::try_load_cached_control_package(paths, action.spec).value_or_exit(VCPKG_LINE_INFO); System::println("Installing package %s... ", display_name); install_package(paths, bpgh, &status_db); System::println(System::Color::success, "Installing package %s... done", display_name); @@ -322,10 +337,11 @@ namespace vcpkg::Commands::Install if (plan_type == InstallPlanType::BUILD_AND_INSTALL && g_feature_packages) { + const std::string display_name_feature = action.displayname(); if (use_head_version) - System::println("Building package %s from HEAD... ", display_name); + System::println("Building package %s from HEAD... ", display_name_feature); else - System::println("Building package %s... ", display_name); + System::println("Building package %s... ", display_name_feature); const Build::BuildPackageConfig build_config{ *action.any_paragraph.source_control_file.value_or_exit(VCPKG_LINE_INFO), @@ -339,13 +355,13 @@ namespace vcpkg::Commands::Install System::println(System::Color::error, Build::create_error_message(result.code, action.spec)); return result.code; } - System::println("Building package %s... done", display_name); + System::println("Building package %s... done", display_name_feature); - const BinaryParagraph bpgh = - Paragraphs::try_load_cached_package(paths, action.spec).value_or_exit(VCPKG_LINE_INFO); - System::println("Installing package %s... ", display_name); - install_package(paths, bpgh, &status_db); - System::println(System::Color::success, "Installing package %s... done", display_name); + const BinaryControlFile bcf = + Paragraphs::try_load_cached_control_package(paths, action.spec).value_or_exit(VCPKG_LINE_INFO); + System::println("Installing package %s... ", display_name_feature); + install_package(paths, bcf, &status_db); + System::println(System::Color::success, "Installing package %s... done", display_name_feature); return BuildResult::SUCCEEDED; } @@ -357,7 +373,9 @@ namespace vcpkg::Commands::Install System::Color::warning, "Package %s is already built -- not building from HEAD", display_name); } System::println("Installing package %s... ", display_name); - install_package(paths, action.any_paragraph.binary_paragraph.value_or_exit(VCPKG_LINE_INFO), &status_db); + install_package(paths, + BinaryControlFile{action.any_paragraph.binary_paragraph.value_or_exit(VCPKG_LINE_INFO)}, + &status_db); System::println(System::Color::success, "Installing package %s... done", display_name); return BuildResult::SUCCEEDED; } @@ -365,11 +383,27 @@ namespace vcpkg::Commands::Install Checks::unreachable(VCPKG_LINE_INFO); } + static void print_plan(const std::vector rebuilt_plans, + const std::vector new_plans) + { + const std::string rebuilt_string = Strings::join("\n", rebuilt_plans, [](const InstallPlanAction* p) { + return Dependencies::to_output_string(p->request_type, p->displayname()); + }); + + const std::string new_string = Strings::join("\n", new_plans, [](const InstallPlanAction* p) { + return Dependencies::to_output_string(p->request_type, p->displayname()); + }); + + if (rebuilt_plans.size() > 0) System::println("The following packages will be rebuilt:\n%s", rebuilt_string); + if (new_plans.size() > 0) System::println("The following packages will be installed:\n%s", new_string); + } + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) { static const std::string OPTION_DRY_RUN = "--dry-run"; static const std::string OPTION_USE_HEAD_VERSION = "--head"; static const std::string OPTION_NO_DOWNLOADS = "--no-downloads"; + static const std::string OPTION_RECURSE = "--recurse"; // input sanitization static const std::string example = @@ -383,14 +417,130 @@ namespace vcpkg::Commands::Install Input::check_triplet(spec.triplet(), paths); const std::unordered_set options = args.check_and_get_optional_command_arguments( - {OPTION_DRY_RUN, OPTION_USE_HEAD_VERSION, OPTION_NO_DOWNLOADS}); + {OPTION_DRY_RUN, OPTION_USE_HEAD_VERSION, OPTION_NO_DOWNLOADS, OPTION_RECURSE}); const bool dryRun = options.find(OPTION_DRY_RUN) != options.cend(); const bool use_head_version = options.find(OPTION_USE_HEAD_VERSION) != options.cend(); const bool no_downloads = options.find(OPTION_NO_DOWNLOADS) != options.cend(); + const bool isRecursive = options.find(OPTION_RECURSE) != options.cend(); // create the plan StatusParagraphs status_db = database_load_check(paths); + if (g_feature_packages) + { + const std::vector full_specs = Util::fmap(args.command_arguments, [&](auto&& arg) { + return Input::check_and_get_full_package_spec(arg, default_triplet, example); + }); + + std::unordered_map scf_map; + auto all_ports = Paragraphs::try_load_all_ports(paths.get_filesystem(), paths.ports); + for (auto&& port : all_ports.paragraphs) + { + auto pkg_spec = PackageSpec::from_name_and_triplet(port->core_paragraph->name, default_triplet) + .value_or_exit(VCPKG_LINE_INFO); + scf_map[pkg_spec] = std::move(*port); + } + std::vector action_plan = + Dependencies::create_feature_install_plan(scf_map, full_specs, status_db); + // install plan will be empty if it is already installed - need to change this at status paragraph part + Checks::check_exit( + VCPKG_LINE_INFO, !action_plan.empty(), "Install plan cannot be empty for feature packages"); + + const Build::BuildPackageOptions install_plan_options = {Build::to_use_head_version(use_head_version), + Build::to_allow_downloads(!no_downloads)}; + + std::vector remove_plans; + + std::vector rebuilt_plans; + std::vector new_plans; + + // removal will happen before install + for (auto&& action : action_plan) + { + if (auto install_action = action.install_plan.get()) + { + auto it = Util::find_if( + remove_plans, [&](const RemovePlanAction* plan) { return plan->spec == install_action->spec; }); + if (it != remove_plans.end()) + { + rebuilt_plans.emplace_back(install_action); + } + else + { + new_plans.emplace_back(install_action); + } + } + else if (auto remove_action = action.remove_plan.get()) + { + remove_plans.emplace_back(remove_action); + } + } + + print_plan(rebuilt_plans, new_plans); + + if (remove_plans.size() > 0 && !isRecursive) + { + System::println(System::Color::warning, + "If you are sure you want to rebuild the above packages, run the command with the " + "--recurse option"); + Checks::exit_fail(VCPKG_LINE_INFO); + } + + // execute the plan + for (const Dependencies::AnyAction& any_action : action_plan) + { + if (auto install_action = any_action.install_plan.get()) + { + const BuildResult result = + perform_install_plan_action(paths, *install_action, install_plan_options, status_db); + if (result != BuildResult::SUCCEEDED) + { + System::println(Build::create_user_troubleshooting_message(install_action->spec)); + Checks::exit_fail(VCPKG_LINE_INFO); + } + } + else if (auto remove_action = any_action.remove_plan.get()) + { + static const std::string OPTION_PURGE = "--purge"; + static const std::string OPTION_NO_PURGE = "--no-purge"; + + const bool alsoRemoveFolderFromPackages = options.find(OPTION_NO_PURGE) == options.end(); + if (options.find(OPTION_PURGE) != options.end() && !alsoRemoveFolderFromPackages) + { + // User specified --purge and --no-purge + System::println(System::Color::error, "Error: cannot specify both --no-purge and --purge."); + System::print(example); + Checks::exit_fail(VCPKG_LINE_INFO); + } + const std::string display_name = remove_action->spec.to_string(); + switch (remove_action->plan_type) + { + case RemovePlanType::NOT_INSTALLED: + System::println(System::Color::success, "Package %s is not installed", display_name); + break; + case RemovePlanType::REMOVE: + System::println("Removing package %s... ", display_name); + Commands::Remove::remove_package(paths, remove_action->spec, &status_db); + System::println(System::Color::success, "Removing package %s... done", display_name); + break; + case RemovePlanType::UNKNOWN: + default: Checks::unreachable(VCPKG_LINE_INFO); + } + + if (alsoRemoveFolderFromPackages) + { + System::println("Purging package %s... ", display_name); + Files::Filesystem& fs = paths.get_filesystem(); + std::error_code ec; + fs.remove_all(paths.packages / remove_action->spec.dir(), ec); + System::println(System::Color::success, "Purging package %s... done", display_name); + } + } + } + + Checks::exit_success(VCPKG_LINE_INFO); + } + Dependencies::PathsPortFile paths_port_file(paths); std::vector install_plan = Dependencies::create_install_plan(paths_port_file, specs, status_db); diff --git a/toolsrc/src/commands_remove.cpp b/toolsrc/src/commands_remove.cpp index eabf2b9ae..e480f02dd 100644 --- a/toolsrc/src/commands_remove.cpp +++ b/toolsrc/src/commands_remove.cpp @@ -17,13 +17,19 @@ namespace vcpkg::Commands::Remove 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()); + auto spghs = status_db->find_all(spec.name(), spec.triplet()); + auto core_pkg = **status_db->find(spec.name(), spec.triplet(), ""); - pkg.want = Want::PURGE; - pkg.state = InstallState::HALF_INSTALLED; - write_update(paths, pkg); + for (auto&& spgh : spghs) + { + StatusParagraph& pkg = **spgh; + if (pkg.state != InstallState::INSTALLED) continue; + pkg.want = Want::PURGE; + pkg.state = InstallState::HALF_INSTALLED; + write_update(paths, pkg); + } - auto maybe_lines = fs.read_lines(paths.listfile_path(pkg.package)); + auto maybe_lines = fs.read_lines(paths.listfile_path(core_pkg.package)); if (auto lines = maybe_lines.get()) { @@ -80,11 +86,16 @@ namespace vcpkg::Commands::Remove } } - fs.remove(paths.listfile_path(pkg.package)); + fs.remove(paths.listfile_path(core_pkg.package)); } - pkg.state = InstallState::NOT_INSTALLED; - write_update(paths, pkg); + for (auto&& spgh : spghs) + { + StatusParagraph& pkg = **spgh; + if (pkg.state != InstallState::HALF_INSTALLED) continue; + pkg.state = InstallState::NOT_INSTALLED; + write_update(paths, pkg); + } } static void print_plan(const std::map>& group_by_plan_type) diff --git a/toolsrc/src/commands_search.cpp b/toolsrc/src/commands_search.cpp index fee99a5db..f12c25fb6 100644 --- a/toolsrc/src/commands_search.cpp +++ b/toolsrc/src/commands_search.cpp @@ -39,7 +39,7 @@ namespace vcpkg::Commands::Search s.append(Strings::format("%s;", name)); for (const Dependency& d : source_paragraph.depends) { - const std::string dependency_name = replace_dashes_with_underscore(d.name); + const std::string dependency_name = replace_dashes_with_underscore(d.name()); s.append(Strings::format("%s -> %s;", name, dependency_name)); } } diff --git a/toolsrc/src/test_install_plan.cpp b/toolsrc/src/test_install_plan.cpp index d02af5662..347998723 100644 --- a/toolsrc/src/test_install_plan.cpp +++ b/toolsrc/src/test_install_plan.cpp @@ -347,13 +347,13 @@ namespace UnitTest1 spec_map.get_package_spec( {{{"Source", "a"}, {"Version", "1.3"}, {"Build-Depends", ""}}, {{"Feature", "1"}, {"Description", "the first feature for a"}, {"Build-Depends", "b[1]"}}, - {{"Feature", "2"}, {"Description", "the first feature for a"}, {"Build-Depends", "b[2]"}}, - {{"Feature", "3"}, {"Description", "the first feature for a"}, {"Build-Depends", "a[2]"}}}), + {{"Feature", "2"}, {"Description", "the second feature for a"}, {"Build-Depends", "b[2]"}}, + {{"Feature", "3"}, {"Description", "the third feature for a"}, {"Build-Depends", "a[2]"}}}), {"3"}}; auto spec_b = FullPackageSpec{spec_map.get_package_spec({ {{"Source", "b"}, {"Version", "1.3"}, {"Build-Depends", ""}}, - {{"Feature", "1"}, {"Description", "the first feature for a"}, {"Build-Depends", ""}}, - {{"Feature", "2"}, {"Description", "the first feature for a"}, {"Build-Depends", ""}}, + {{"Feature", "1"}, {"Description", "the first feature for b"}, {"Build-Depends", ""}}, + {{"Feature", "2"}, {"Description", "the second feature for b"}, {"Build-Depends", ""}}, })}; auto install_plan = Dependencies::create_feature_install_plan( @@ -434,7 +434,7 @@ namespace UnitTest1 {"1"}}; auto install_plan = Dependencies::create_feature_install_plan( - spec_map.map, {spec_b, spec_x}, StatusParagraphs(std::move(status_paragraphs))); + spec_map.map, {spec_b}, StatusParagraphs(std::move(status_paragraphs))); Assert::AreEqual(size_t(5), install_plan.size()); remove_plan_check(&install_plan[0], "x"); @@ -523,5 +523,45 @@ namespace UnitTest1 features_check(&install_plan[6], "a", {"one", "core"}); features_check(&install_plan[7], "c", {"core"}); } + + TEST_METHOD(default_features_test) + { + using Pgh = std::unordered_map; + + std::vector> status_paragraphs; + + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + + auto spec_a = FullPackageSpec{ + spec_map.get_package_spec( + {{{"Source", "a"}, {"Version", "1.3"}, {"Default-Features", "1, 2"}, {"Build-Depends", ""}}, + {{"Feature", "1"}, {"Description", "the first feature for a"}, {"Build-Depends", "b[2]"}}, + {{"Feature", "2"}, {"Description", "the second feature for a"}, {"Build-Depends", ""}}, + {{"Feature", "3"}, {"Description", "the third feature for a"}, {"Build-Depends", ""}}}), + {""}}; + auto spec_b = FullPackageSpec{ + spec_map.get_package_spec({ + {{"Source", "b"}, {"Version", "1.3"}, {"Default-Features", "1, 2"}, {"Build-Depends", ""}}, + {{"Feature", "1"}, {"Description", "the first feature for b"}, {"Build-Depends", "c[1]"}}, + {{"Feature", "2"}, {"Description", "the second feature for b"}, {"Build-Depends", ""}}, + }), + {""}}; + + auto spec_c = FullPackageSpec{ + spec_map.get_package_spec({ + {{"Source", "c"}, {"Version", "1.3"}, {"Default-Features", "2"}, {"Build-Depends", ""}}, + {{"Feature", "1"}, {"Description", "the first feature for c"}, {"Build-Depends", ""}}, + {{"Feature", "2"}, {"Description", "the second feature for c"}, {"Build-Depends", ""}}, + }), + {""}}; + + auto install_plan = Dependencies::create_feature_install_plan( + spec_map.map, {spec_a}, StatusParagraphs(std::move(status_paragraphs))); + + Assert::AreEqual(size_t(3), install_plan.size()); + features_check(&install_plan[0], "c", {"core", "1", "2"}); + features_check(&install_plan[1], "b", {"core", "1", "2"}); + features_check(&install_plan[2], "a", {"core", "1", "2"}); + } }; } \ No newline at end of file diff --git a/toolsrc/src/tests_dependencies.cpp b/toolsrc/src/tests_dependencies.cpp index 7a49bdbd0..26cc1e22c 100644 --- a/toolsrc/src/tests_dependencies.cpp +++ b/toolsrc/src/tests_dependencies.cpp @@ -17,7 +17,7 @@ namespace UnitTest1 { auto v = expand_qualified_dependencies(parse_comma_list("libA (windows)")); Assert::AreEqual(size_t(1), v.size()); - Assert::AreEqual("libA", v[0].name.c_str()); + Assert::AreEqual("libA", v[0].depend.name.c_str()); Assert::AreEqual("windows", v[0].qualifier.c_str()); } diff --git a/toolsrc/src/tests_paragraph.cpp b/toolsrc/src/tests_paragraph.cpp index af4b55498..3f2760c22 100644 --- a/toolsrc/src/tests_paragraph.cpp +++ b/toolsrc/src/tests_paragraph.cpp @@ -60,7 +60,7 @@ namespace UnitTest1 Assert::AreEqual("m", pgh->core_paragraph->maintainer.c_str()); Assert::AreEqual("d", pgh->core_paragraph->description.c_str()); Assert::AreEqual(size_t(1), pgh->core_paragraph->depends.size()); - Assert::AreEqual("bd", pgh->core_paragraph->depends[0].name.c_str()); + Assert::AreEqual("bd", pgh->core_paragraph->depends[0].name().c_str()); Assert::AreEqual(size_t(1), pgh->core_paragraph->supports.size()); Assert::AreEqual("x64", pgh->core_paragraph->supports[0].c_str()); } @@ -77,8 +77,8 @@ namespace UnitTest1 auto& pgh = *m_pgh.get(); Assert::AreEqual(size_t(2), pgh->core_paragraph->depends.size()); - Assert::AreEqual("z", pgh->core_paragraph->depends[0].name.c_str()); - Assert::AreEqual("openssl", pgh->core_paragraph->depends[1].name.c_str()); + Assert::AreEqual("z", pgh->core_paragraph->depends[0].name().c_str()); + Assert::AreEqual("openssl", pgh->core_paragraph->depends[1].name().c_str()); } TEST_METHOD(SourceParagraph_Three_Depends) @@ -93,9 +93,9 @@ namespace UnitTest1 auto& pgh = *m_pgh.get(); Assert::AreEqual(size_t(3), pgh->core_paragraph->depends.size()); - Assert::AreEqual("z", pgh->core_paragraph->depends[0].name.c_str()); - Assert::AreEqual("openssl", pgh->core_paragraph->depends[1].name.c_str()); - Assert::AreEqual("xyz", pgh->core_paragraph->depends[2].name.c_str()); + Assert::AreEqual("z", pgh->core_paragraph->depends[0].name().c_str()); + Assert::AreEqual("openssl", pgh->core_paragraph->depends[1].name().c_str()); + Assert::AreEqual("xyz", pgh->core_paragraph->depends[2].name().c_str()); } TEST_METHOD(SourceParagraph_Three_Supports) @@ -131,9 +131,9 @@ namespace UnitTest1 Assert::AreEqual("", pgh->core_paragraph->maintainer.c_str()); Assert::AreEqual("", pgh->core_paragraph->description.c_str()); Assert::AreEqual(size_t(2), pgh->core_paragraph->depends.size()); - Assert::AreEqual("libA", pgh->core_paragraph->depends[0].name.c_str()); + Assert::AreEqual("libA", pgh->core_paragraph->depends[0].name().c_str()); Assert::AreEqual("windows", pgh->core_paragraph->depends[0].qualifier.c_str()); - Assert::AreEqual("libB", pgh->core_paragraph->depends[1].name.c_str()); + Assert::AreEqual("libB", pgh->core_paragraph->depends[1].name().c_str()); Assert::AreEqual("uwp", pgh->core_paragraph->depends[1].qualifier.c_str()); } @@ -411,6 +411,18 @@ namespace UnitTest1 Assert::AreEqual(vcpkg::PackageSpecParseResult::TOO_MANY_COLONS, ec); } + TEST_METHOD(package_spec_feature_parse_with_arch) + { + vcpkg::ExpectedT spec = + vcpkg::FullPackageSpec::from_string("zlib[feature]:x64-uwp", vcpkg::Triplet::X86_WINDOWS); + Assert::AreEqual(vcpkg::PackageSpecParseResult::SUCCESS, spec.error()); + Assert::AreEqual("zlib", spec.get()->package_spec.name().c_str()); + Assert::IsTrue(spec.get()->features.size() == 1); + Assert::AreEqual("feature", spec.get()->features.front().c_str()); + Assert::AreEqual(vcpkg::Triplet::X64_UWP.canonical_name(), + spec.get()->package_spec.triplet().canonical_name()); + } + TEST_METHOD(utf8_to_utf16) { auto str = vcpkg::Strings::to_utf16("abc"); diff --git a/toolsrc/src/vcpkg_Build.cpp b/toolsrc/src/vcpkg_Build.cpp index a0d690f37..124efb7f2 100644 --- a/toolsrc/src/vcpkg_Build.cpp +++ b/toolsrc/src/vcpkg_Build.cpp @@ -88,29 +88,37 @@ namespace vcpkg::Build return Strings::wformat(LR"("%s" %s %s %s 2>&1)", toolset.vcvarsall.native(), arch, target, tonull); } - static void create_binary_control_file(const VcpkgPaths& paths, - const SourceParagraph& source_paragraph, + static void create_binary_feature_control_file(const SourceParagraph& source_paragraph, + const FeatureParagraph& feature_paragraph, + const Triplet& triplet, + BinaryControlFile& bcf) + { + BinaryParagraph bpgh(source_paragraph, feature_paragraph, triplet); + bcf.features.emplace_back(std::move(bpgh)); + } + + static void create_binary_control_file(const SourceParagraph& source_paragraph, const Triplet& triplet, - const BuildInfo& build_info) + const BuildInfo& build_info, + BinaryControlFile& bcf) { - BinaryParagraph bpgh = BinaryParagraph(source_paragraph, triplet); + BinaryParagraph bpgh(source_paragraph, triplet); if (auto p_ver = build_info.version.get()) { bpgh.version = *p_ver; } - const fs::path binary_control_file = paths.packages / bpgh.dir() / "CONTROL"; - paths.get_filesystem().write_contents(binary_control_file, Strings::serialize(bpgh)); + bcf.core_paragraph = std::move(bpgh); } - static void create_binary_feature_control_file(const VcpkgPaths& paths, - const SourceParagraph& source_paragraph, - const FeatureParagraph& feature_paragraph, - const Triplet& triplet, - const BuildInfo& build_info) + static void write_binary_control_file(const VcpkgPaths& paths, BinaryControlFile bcf) { - BinaryParagraph bpgh = BinaryParagraph(source_paragraph, feature_paragraph, triplet); - const fs::path binary_control_file = paths.packages / bpgh.dir() / "CONTROL"; - paths.get_filesystem().write_contents(binary_control_file, Strings::serialize(bpgh)); + std::string start = Strings::serialize(bcf.core_paragraph); + for (auto&& feature : bcf.features) + { + start += "\n" + Strings::serialize(feature); + } + const fs::path binary_control_file = paths.packages / bcf.core_paragraph.dir() / "CONTROL"; + paths.get_filesystem().write_contents(binary_control_file, start); } ExtendedBuildResult build_package(const VcpkgPaths& paths, @@ -196,6 +204,10 @@ namespace vcpkg::Build auto build_info = read_build_info(paths.get_filesystem(), paths.build_info_file_path(spec)); const size_t error_count = PostBuildLint::perform_all_checks(spec, paths, pre_build_info, build_info); + BinaryControlFile bcf; + + create_binary_control_file(config.src, triplet, build_info, bcf); + if (error_count != 0) { return {BuildResult::POST_BUILD_CHECKS_FAILED, {}}; @@ -209,13 +221,13 @@ namespace vcpkg::Build for (auto&& f_pgh : config.scf->feature_paragraphs) { if (f_pgh->name == feature) - create_binary_feature_control_file( - paths, *config.scf->core_paragraph, *f_pgh, triplet, build_info); + create_binary_feature_control_file(*config.scf->core_paragraph, *f_pgh, triplet, bcf); } } } } - create_binary_control_file(paths, config.src, triplet, build_info); + + write_binary_control_file(paths, bcf); // const fs::path port_buildtrees_dir = paths.buildtrees / spec.name; // delete_directory(port_buildtrees_dir); diff --git a/toolsrc/src/vcpkg_Dependencies.cpp b/toolsrc/src/vcpkg_Dependencies.cpp index 820e51b33..c84ca73f3 100644 --- a/toolsrc/src/vcpkg_Dependencies.cpp +++ b/toolsrc/src/vcpkg_Dependencies.cpp @@ -101,6 +101,25 @@ namespace vcpkg::Dependencies this->plan_type = InstallPlanType::UNKNOWN; } + std::string InstallPlanAction::displayname() const + { + if (this->feature_list.empty()) + { + return this->spec.to_string(); + } + else + { + std::string features; + for (auto&& feature : this->feature_list) + { + features += feature + ","; + } + features.pop_back(); + + return this->spec.name() + "[" + features + "]:" + this->spec.triplet().to_string(); + } + } + bool InstallPlanAction::compare_by_name(const InstallPlanAction* left, const InstallPlanAction* right) { return left->spec.name() < right->spec.name(); @@ -319,9 +338,9 @@ namespace vcpkg::Dependencies ? RequestType::USER_REQUESTED : RequestType::AUTO_SELECTED; - Expected maybe_bpgh = Paragraphs::try_load_cached_package(paths, spec); - if (auto bpgh = maybe_bpgh.get()) - return ExportPlanAction{spec, {nullopt, *bpgh, nullopt}, request_type}; + Expected maybe_bpgh = Paragraphs::try_load_cached_control_package(paths, spec); + if (auto bcf = maybe_bpgh.get()) + return ExportPlanAction{spec, {nullopt, bcf->core_paragraph, nullopt}, request_type}; auto maybe_scf = Paragraphs::try_load_port(paths.get_filesystem(), paths.port_dir(spec)); if (auto scf = maybe_scf.get()) @@ -366,6 +385,20 @@ namespace vcpkg::Dependencies return f_specs; } + void mark_plus_default(Cluster& cluster, + std::unordered_map& pkg_to_cluster, + GraphPlan& graph_plan) + { + mark_plus("core", cluster, pkg_to_cluster, graph_plan); + if (auto scf = cluster.source_control_file.get()) + { + for (auto&& default_feature : (*scf)->core_paragraph->default_features) + { + mark_plus(default_feature, cluster, pkg_to_cluster, graph_plan); + } + } + } + bool mark_plus(const std::string& feature, Cluster& cluster, std::unordered_map& pkg_to_cluster, @@ -404,21 +437,12 @@ namespace vcpkg::Dependencies graph_plan.install_graph.add_vertex({&cluster}); auto& tracked = cluster.to_install_features; tracked.insert(updated_feature); - if (tracked.find("core") == tracked.end() && tracked.find("") == tracked.end()) - { - cluster.to_install_features.insert("core"); - for (auto&& depend : cluster.edges["core"].build_edges) - { - auto& depend_cluster = pkg_to_cluster[depend.spec]; - mark_plus(depend.feature_name, depend_cluster, pkg_to_cluster, graph_plan); - graph_plan.install_graph.add_edge({&cluster}, {&depend_cluster}); - } - } for (auto&& depend : cluster.edges[updated_feature].build_edges) { auto& depend_cluster = pkg_to_cluster[depend.spec]; mark_plus(depend.feature_name, depend_cluster, pkg_to_cluster, graph_plan); + mark_plus_default(depend_cluster, pkg_to_cluster, graph_plan); if (&depend_cluster == &cluster) continue; graph_plan.install_graph.add_edge({&cluster}, {&depend_cluster}); } @@ -448,6 +472,7 @@ namespace vcpkg::Dependencies mark_plus(original_feature, cluster, pkg_to_cluster, graph_plan); } } + std::vector create_feature_install_plan(const std::unordered_map& map, const std::vector& specs, const StatusParagraphs& status_db) @@ -515,6 +540,7 @@ namespace vcpkg::Dependencies for (auto&& spec : specs) { Cluster& spec_cluster = pkg_spec_to_package_node[spec.package_spec]; + mark_plus_default(spec_cluster, pkg_spec_to_package_node, graph_plan); for (auto&& feature : spec.features) { mark_plus(feature, spec_cluster, pkg_spec_to_package_node, graph_plan); diff --git a/toolsrc/src/vcpkglib.cpp b/toolsrc/src/vcpkglib.cpp index 6b180b532..428ae090d 100644 --- a/toolsrc/src/vcpkglib.cpp +++ b/toolsrc/src/vcpkglib.cpp @@ -191,7 +191,7 @@ namespace vcpkg for (const std::unique_ptr& pgh : status_db) { - if (pgh->state != InstallState::INSTALLED) + if (pgh->state != InstallState::INSTALLED || pgh->package.feature != "") { continue; } -- cgit v1.2.3 From aab0173509c89746f8988b000854d2ed8c9115e7 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Fri, 18 Aug 2017 16:22:52 -0700 Subject: [vcpkg] Fix rebase build. --- toolsrc/src/commands_depends.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/commands_depends.cpp b/toolsrc/src/commands_depends.cpp index b04af5282..49e1c6c01 100644 --- a/toolsrc/src/commands_depends.cpp +++ b/toolsrc/src/commands_depends.cpp @@ -33,7 +33,7 @@ namespace vcpkg::Commands::DependInfo for (const Dependency& dependency : source_paragraph.depends) { - if (Strings::case_insensitive_ascii_contains(dependency.name, filter)) + if (Strings::case_insensitive_ascii_contains(dependency.name(), filter)) { return false; } -- cgit v1.2.3 From 4d34488649fe5d71b8a553706d960a3784c56bb1 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Fri, 18 Aug 2017 20:32:35 -0700 Subject: [vcpkg] Consolidate specifier parsing --- toolsrc/include/PackageSpec.h | 9 ++++ toolsrc/include/vcpkg_Checks.h | 7 ++- toolsrc/src/PackageSpec.cpp | 101 +++++++++++++++++++++---------------- toolsrc/src/SourceParagraph.cpp | 30 ++++++----- toolsrc/src/tests_paragraph.cpp | 61 +++++++++++++--------- toolsrc/src/vcpkg_Dependencies.cpp | 26 +++++----- 6 files changed, 139 insertions(+), 95 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/PackageSpec.h b/toolsrc/include/PackageSpec.h index 15b5e5b9b..77a14e90e 100644 --- a/toolsrc/include/PackageSpec.h +++ b/toolsrc/include/PackageSpec.h @@ -6,6 +6,15 @@ namespace vcpkg { + struct ParsedSpecifier + { + std::string name; + std::vector features; + std::string triplet; + + static ExpectedT from_string(const std::string& input); + }; + struct PackageSpec { static std::string to_string(const std::string& name, const Triplet& triplet); diff --git a/toolsrc/include/vcpkg_Checks.h b/toolsrc/include/vcpkg_Checks.h index 6d8ff5711..754b44f75 100644 --- a/toolsrc/include/vcpkg_Checks.h +++ b/toolsrc/include/vcpkg_Checks.h @@ -5,18 +5,23 @@ namespace vcpkg::Checks { + // Indicate that an internal error has occurred and exit the tool. This should be used when invariants have been + // broken. [[noreturn]] void unreachable(const LineInfo& line_info); [[noreturn]] void exit_with_code(const LineInfo& line_info, const int exit_code); + // Exit the tool without an error message. [[noreturn]] inline void exit_fail(const LineInfo& line_info) { exit_with_code(line_info, EXIT_FAILURE); } + // Exit the tool successfully. [[noreturn]] inline void exit_success(const LineInfo& line_info) { exit_with_code(line_info, EXIT_SUCCESS); } - // Part of the reason these exist is to not include extra headers in this one to avoid circular #includes. + // Display an error message to the user and exit the tool. [[noreturn]] void exit_with_message(const LineInfo& line_info, const CStringView errorMessage); template + // Display an error message to the user and exit the tool. [[noreturn]] void exit_with_message(const LineInfo& line_info, const char* errorMessageTemplate, const Arg1 errorMessageArg1, diff --git a/toolsrc/src/PackageSpec.cpp b/toolsrc/src/PackageSpec.cpp index a7e5648cd..e243f4d89 100644 --- a/toolsrc/src/PackageSpec.cpp +++ b/toolsrc/src/PackageSpec.cpp @@ -13,52 +13,16 @@ namespace vcpkg ExpectedT FullPackageSpec::from_string(const std::string& spec_as_string, const Triplet& default_triplet) { - auto pos = spec_as_string.find(':'); - auto pos_l_bracket = spec_as_string.find('['); - auto pos_r_bracket = spec_as_string.find(']'); - - FullPackageSpec f; - if (pos == std::string::npos && pos_l_bracket == std::string::npos) - { - f.package_spec = - PackageSpec::from_name_and_triplet(spec_as_string, default_triplet).value_or_exit(VCPKG_LINE_INFO); - return f; - } - else if (pos == std::string::npos) - { - if (pos_r_bracket == std::string::npos || pos_l_bracket >= pos_r_bracket) - { - return PackageSpecParseResult::INVALID_CHARACTERS; - } - const std::string name = spec_as_string.substr(0, pos_l_bracket); - f.package_spec = PackageSpec::from_name_and_triplet(name, default_triplet).value_or_exit(VCPKG_LINE_INFO); - f.features = parse_comma_list(spec_as_string.substr(pos_l_bracket + 1, pos_r_bracket - pos_l_bracket - 1)); - return f; - } - else if (pos_l_bracket == std::string::npos && pos_r_bracket == std::string::npos) - { - const std::string name = spec_as_string.substr(0, pos); - const Triplet triplet = Triplet::from_canonical_name(spec_as_string.substr(pos + 1)); - f.package_spec = PackageSpec::from_name_and_triplet(name, triplet).value_or_exit(VCPKG_LINE_INFO); - } - else + auto res = ParsedSpecifier::from_string(spec_as_string); + if (auto p = res.get()) { - if (pos_r_bracket == std::string::npos || pos_l_bracket >= pos_r_bracket) - { - return PackageSpecParseResult::INVALID_CHARACTERS; - } - const std::string name = spec_as_string.substr(0, pos_l_bracket); - f.features = parse_comma_list(spec_as_string.substr(pos_l_bracket + 1, pos_r_bracket - pos_l_bracket - 1)); - const Triplet triplet = Triplet::from_canonical_name(spec_as_string.substr(pos + 1)); - f.package_spec = PackageSpec::from_name_and_triplet(name, triplet).value_or_exit(VCPKG_LINE_INFO); + FullPackageSpec fspec; + Triplet t = p->triplet.empty() ? default_triplet : Triplet::from_canonical_name(p->triplet); + fspec.package_spec = PackageSpec::from_name_and_triplet(p->name, t).value_or_exit(VCPKG_LINE_INFO); + fspec.features = std::move(p->features); + return fspec; } - - auto pos2 = spec_as_string.find(':', pos + 1); - if (pos2 != std::string::npos) - { - return PackageSpecParseResult::TOO_MANY_COLONS; - } - return f; + return res.error(); } ExpectedT PackageSpec::from_name_and_triplet(const std::string& name, @@ -93,4 +57,53 @@ namespace vcpkg } bool operator!=(const PackageSpec& left, const PackageSpec& right) { return !(left == right); } + + ExpectedT ParsedSpecifier::from_string(const std::string& input) + { + auto pos = input.find(':'); + auto pos_l_bracket = input.find('['); + auto pos_r_bracket = input.find(']'); + + ParsedSpecifier f; + if (pos == std::string::npos && pos_l_bracket == std::string::npos) + { + f.name = input; + return f; + } + else if (pos == std::string::npos) + { + if (pos_r_bracket == std::string::npos || pos_l_bracket >= pos_r_bracket) + { + return PackageSpecParseResult::INVALID_CHARACTERS; + } + const std::string name = input.substr(0, pos_l_bracket); + f.name = name; + f.features = parse_comma_list(input.substr(pos_l_bracket + 1, pos_r_bracket - pos_l_bracket - 1)); + return f; + } + else if (pos_l_bracket == std::string::npos && pos_r_bracket == std::string::npos) + { + const std::string name = input.substr(0, pos); + f.triplet = input.substr(pos + 1); + f.name = name; + } + else + { + if (pos_r_bracket == std::string::npos || pos_l_bracket >= pos_r_bracket) + { + return PackageSpecParseResult::INVALID_CHARACTERS; + } + const std::string name = input.substr(0, pos_l_bracket); + f.features = parse_comma_list(input.substr(pos_l_bracket + 1, pos_r_bracket - pos_l_bracket - 1)); + f.triplet = input.substr(pos + 1); + f.name = name; + } + + auto pos2 = input.find(':', pos + 1); + if (pos2 != std::string::npos) + { + return PackageSpecParseResult::TOO_MANY_COLONS; + } + return f; + } } diff --git a/toolsrc/src/SourceParagraph.cpp b/toolsrc/src/SourceParagraph.cpp index 2aab7c572..f9ae6854a 100644 --- a/toolsrc/src/SourceParagraph.cpp +++ b/toolsrc/src/SourceParagraph.cpp @@ -1,5 +1,6 @@ #include "pch.h" +#include "PackageSpec.h" #include "SourceParagraph.h" #include "Triplet.h" #include "vcpkg_Checks.h" @@ -28,7 +29,11 @@ namespace vcpkg static span get_list_of_valid_fields() { static const std::string valid_fields[] = { - Fields::SOURCE, Fields::VERSION, Fields::DESCRIPTION, Fields::MAINTAINER, Fields::BUILD_DEPENDS, + Fields::SOURCE, + Fields::VERSION, + Fields::DESCRIPTION, + Fields::MAINTAINER, + Fields::BUILD_DEPENDS, }; return valid_fields; @@ -154,21 +159,20 @@ namespace vcpkg Features parse_feature_list(const std::string& name) { - Features f; - int end = (int)name.find(']'); - if (end != std::string::npos) + auto maybe_spec = ParsedSpecifier::from_string(name); + if (auto spec = maybe_spec.get()) { - int start = (int)name.find('['); + Checks::check_exit( + VCPKG_LINE_INFO, spec->triplet.empty(), "error: triplet not allowed in specifier: %s", name); - auto feature_name_list = name.substr(start + 1, end - start - 1); - f.name = name.substr(0, start); - f.features = parse_comma_list(feature_name_list); + Features f; + f.name = spec->name; + f.features = spec->features; + return f; } - else - { - f.name = name; - } - return f; + + Checks::exit_with_message( + VCPKG_LINE_INFO, "error while parsing feature list: %s: %s", to_string(maybe_spec.error()), name); } Dependency Dependency::parse_dependency(std::string name, std::string qualifier) diff --git a/toolsrc/src/tests_paragraph.cpp b/toolsrc/src/tests_paragraph.cpp index 3f2760c22..1fd950e19 100644 --- a/toolsrc/src/tests_paragraph.cpp +++ b/toolsrc/src/tests_paragraph.cpp @@ -385,42 +385,53 @@ namespace UnitTest1 Assert::AreEqual("a, b, c", pghs[0]["Depends"].c_str()); } - TEST_METHOD(package_spec_parse) + TEST_METHOD(parsed_specifier_from_string) { - vcpkg::ExpectedT spec = - vcpkg::FullPackageSpec::from_string("zlib", vcpkg::Triplet::X86_WINDOWS); - Assert::AreEqual(vcpkg::PackageSpecParseResult::SUCCESS, spec.error()); - Assert::AreEqual("zlib", spec.get()->package_spec.name().c_str()); - Assert::AreEqual(vcpkg::Triplet::X86_WINDOWS.canonical_name(), - spec.get()->package_spec.triplet().canonical_name()); + auto maybe_spec = vcpkg::ParsedSpecifier::from_string("zlib"); + Assert::AreEqual(vcpkg::PackageSpecParseResult::SUCCESS, maybe_spec.error()); + auto spec = maybe_spec.get(); + Assert::AreEqual("zlib", spec->name.c_str()); + Assert::AreEqual(size_t(0), spec->features.size()); + Assert::AreEqual("", spec->triplet.c_str()); } - TEST_METHOD(package_spec_parse_with_arch) + TEST_METHOD(parsed_specifier_from_string_with_triplet) { - vcpkg::ExpectedT spec = - vcpkg::FullPackageSpec::from_string("zlib:x64-uwp", vcpkg::Triplet::X86_WINDOWS); - Assert::AreEqual(vcpkg::PackageSpecParseResult::SUCCESS, spec.error()); - Assert::AreEqual("zlib", spec.get()->package_spec.name().c_str()); - Assert::AreEqual(vcpkg::Triplet::X64_UWP.canonical_name(), - spec.get()->package_spec.triplet().canonical_name()); + auto maybe_spec = vcpkg::ParsedSpecifier::from_string("zlib:x64-uwp"); + Assert::AreEqual(vcpkg::PackageSpecParseResult::SUCCESS, maybe_spec.error()); + auto spec = maybe_spec.get(); + Assert::AreEqual("zlib", spec->name.c_str()); + Assert::AreEqual("x64-uwp", spec->triplet.c_str()); } - TEST_METHOD(package_spec_parse_with_multiple_colon) + TEST_METHOD(parsed_specifier_from_string_with_colons) { - auto ec = vcpkg::FullPackageSpec::from_string("zlib:x86-uwp:", vcpkg::Triplet::X86_WINDOWS).error(); + auto ec = vcpkg::ParsedSpecifier::from_string("zlib:x86-uwp:").error(); Assert::AreEqual(vcpkg::PackageSpecParseResult::TOO_MANY_COLONS, ec); } - TEST_METHOD(package_spec_feature_parse_with_arch) + TEST_METHOD(parsed_specifier_from_string_with_feature) { - vcpkg::ExpectedT spec = - vcpkg::FullPackageSpec::from_string("zlib[feature]:x64-uwp", vcpkg::Triplet::X86_WINDOWS); - Assert::AreEqual(vcpkg::PackageSpecParseResult::SUCCESS, spec.error()); - Assert::AreEqual("zlib", spec.get()->package_spec.name().c_str()); - Assert::IsTrue(spec.get()->features.size() == 1); - Assert::AreEqual("feature", spec.get()->features.front().c_str()); - Assert::AreEqual(vcpkg::Triplet::X64_UWP.canonical_name(), - spec.get()->package_spec.triplet().canonical_name()); + auto maybe_spec = vcpkg::ParsedSpecifier::from_string("zlib[feature]:x64-uwp"); + Assert::AreEqual(vcpkg::PackageSpecParseResult::SUCCESS, maybe_spec.error()); + auto spec = maybe_spec.get(); + Assert::AreEqual("zlib", spec->name.c_str()); + Assert::IsTrue(spec->features.size() == 1); + Assert::AreEqual("feature", spec->features.front().c_str()); + Assert::AreEqual("x64-uwp", spec->triplet.c_str()); + } + + TEST_METHOD(parsed_specifier_from_string_with_many_features) + { + auto maybe_spec = vcpkg::ParsedSpecifier::from_string("zlib[0, 1,2]"); + Assert::AreEqual(vcpkg::PackageSpecParseResult::SUCCESS, maybe_spec.error()); + auto spec = maybe_spec.get(); + Assert::AreEqual("zlib", spec->name.c_str()); + Assert::IsTrue(spec->features.size() == 3); + Assert::AreEqual("0", spec->features[0].c_str()); + Assert::AreEqual("1", spec->features[1].c_str()); + Assert::AreEqual("2", spec->features[2].c_str()); + Assert::AreEqual("", spec->triplet.c_str()); } TEST_METHOD(utf8_to_utf16) diff --git a/toolsrc/src/vcpkg_Dependencies.cpp b/toolsrc/src/vcpkg_Dependencies.cpp index c84ca73f3..799bca439 100644 --- a/toolsrc/src/vcpkg_Dependencies.cpp +++ b/toolsrc/src/vcpkg_Dependencies.cpp @@ -363,23 +363,25 @@ namespace vcpkg::Dependencies std::vector f_specs; for (auto&& depend : depends) { - int end = (int)depend.find(']'); - if (end != std::string::npos) + auto maybe_spec = ParsedSpecifier::from_string(depend); + if (auto spec = maybe_spec.get()) { - int start = (int)depend.find('['); + Checks::check_exit(VCPKG_LINE_INFO, + spec->triplet.empty(), + "error: triplets cannot currently be specified in this context: %s", + depend); + PackageSpec pspec = + PackageSpec::from_name_and_triplet(spec->name, triplet).value_or_exit(VCPKG_LINE_INFO); - auto feature_name = depend.substr(start + 1, end - start - 1); - auto package_name = depend.substr(0, start); - auto p_spec = PackageSpec::from_name_and_triplet(package_name, triplet).value_or_exit(VCPKG_LINE_INFO); - auto feature_spec = FeatureSpec{p_spec, feature_name}; - f_specs.emplace_back(std::move(feature_spec)); + for (auto&& feature : spec->features) + f_specs.push_back(FeatureSpec{pspec, feature}); + + if (spec->features.empty()) f_specs.push_back(FeatureSpec{pspec, ""}); } else { - auto p_spec = PackageSpec::from_name_and_triplet(depend, triplet).value_or_exit(VCPKG_LINE_INFO); - - auto feature_spec = FeatureSpec{p_spec, ""}; - f_specs.emplace_back(std::move(feature_spec)); + Checks::exit_with_message( + VCPKG_LINE_INFO, "error while parsing feature list: %s: %s", to_string(maybe_spec.error()), depend); } } return f_specs; -- cgit v1.2.3 From f219ce0b8c3e84e5fc1df21ad2f2c8b13f0fe413 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Sat, 19 Aug 2017 19:27:34 -0700 Subject: [vcpkg] Reorganize some parsing functions. --- toolsrc/include/PackageSpec.h | 11 ++++++-- toolsrc/include/SourceParagraph.h | 12 +------- toolsrc/include/vcpkg_Parse.h | 2 ++ toolsrc/src/PackageSpec.cpp | 26 +++++++++++++---- toolsrc/src/SourceParagraph.cpp | 57 ++++---------------------------------- toolsrc/src/tests_dependencies.cpp | 15 ++++++++-- toolsrc/src/vcpkg_Parse.cpp | 33 ++++++++++++++++++++++ 7 files changed, 84 insertions(+), 72 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/PackageSpec.h b/toolsrc/include/PackageSpec.h index 77a14e90e..8e986b4d6 100644 --- a/toolsrc/include/PackageSpec.h +++ b/toolsrc/include/PackageSpec.h @@ -1,6 +1,6 @@ #pragma once + #include "PackageSpecParseResult.h" -#include "SourceParagraph.h" #include "Triplet.h" #include "vcpkg_expected.h" @@ -17,7 +17,6 @@ namespace vcpkg struct PackageSpec { - static std::string to_string(const std::string& name, const Triplet& triplet); static ExpectedT from_name_and_triplet(const std::string& name, const Triplet& triplet); @@ -43,6 +42,14 @@ namespace vcpkg const Triplet& default_triplet); }; + struct Features + { + std::string name; + std::vector features; + + static ExpectedT from_string(const std::string& input); + }; + bool operator==(const PackageSpec& left, const PackageSpec& right); bool operator!=(const PackageSpec& left, const PackageSpec& right); } diff --git a/toolsrc/include/SourceParagraph.h b/toolsrc/include/SourceParagraph.h index fee61c3e8..d938e2e3b 100644 --- a/toolsrc/include/SourceParagraph.h +++ b/toolsrc/include/SourceParagraph.h @@ -1,5 +1,6 @@ #pragma once +#include "PackageSpec.h" #include "Span.h" #include "vcpkg_Parse.h" #include "vcpkg_System.h" @@ -13,16 +14,6 @@ namespace vcpkg { extern bool g_feature_packages; - struct Triplet; - - struct Features - { - std::string name; - std::vector features; - }; - - Features parse_feature_list(const std::string& name); - struct Dependency { Features depend; @@ -73,7 +64,6 @@ namespace vcpkg // zlib[uwp] becomes Dependency{"zlib", "uwp"} std::vector expand_qualified_dependencies(const std::vector& depends); - std::vector parse_comma_list(const std::string& str); struct Supports { diff --git a/toolsrc/include/vcpkg_Parse.h b/toolsrc/include/vcpkg_Parse.h index a2eb152dc..e663448b9 100644 --- a/toolsrc/include/vcpkg_Parse.h +++ b/toolsrc/include/vcpkg_Parse.h @@ -33,4 +33,6 @@ namespace vcpkg::Parse RawParagraph&& fields; std::vector missing_fields; }; + + std::vector parse_comma_list(const std::string& str); } diff --git a/toolsrc/src/PackageSpec.cpp b/toolsrc/src/PackageSpec.cpp index e243f4d89..475b3e3f6 100644 --- a/toolsrc/src/PackageSpec.cpp +++ b/toolsrc/src/PackageSpec.cpp @@ -1,8 +1,11 @@ #include "pch.h" #include "PackageSpec.h" +#include "vcpkg_Parse.h" #include "vcpkg_Util.h" +using vcpkg::Parse::parse_comma_list; + namespace vcpkg { static bool is_valid_package_spec_char(char c) @@ -45,11 +48,7 @@ namespace vcpkg std::string PackageSpec::dir() const { return Strings::format("%s_%s", this->m_name, this->m_triplet); } - std::string PackageSpec::to_string(const std::string& name, const Triplet& triplet) - { - return Strings::format("%s:%s", name, triplet); - } - std::string PackageSpec::to_string() const { return to_string(this->name(), this->triplet()); } + std::string PackageSpec::to_string() const { return Strings::format("%s:%s", this->name(), this->triplet()); } bool operator==(const PackageSpec& left, const PackageSpec& right) { @@ -106,4 +105,21 @@ namespace vcpkg } return f; } + + ExpectedT Features::from_string(const std::string& name) + { + auto maybe_spec = ParsedSpecifier::from_string(name); + if (auto spec = maybe_spec.get()) + { + Checks::check_exit( + VCPKG_LINE_INFO, spec->triplet.empty(), "error: triplet not allowed in specifier: %s", name); + + Features f; + f.name = spec->name; + f.features = spec->features; + return f; + } + + return maybe_spec.error(); + } } diff --git a/toolsrc/src/SourceParagraph.cpp b/toolsrc/src/SourceParagraph.cpp index f9ae6854a..76c5a2004 100644 --- a/toolsrc/src/SourceParagraph.cpp +++ b/toolsrc/src/SourceParagraph.cpp @@ -157,29 +157,15 @@ namespace vcpkg return std::move(control_file); } - Features parse_feature_list(const std::string& name) - { - auto maybe_spec = ParsedSpecifier::from_string(name); - if (auto spec = maybe_spec.get()) - { - Checks::check_exit( - VCPKG_LINE_INFO, spec->triplet.empty(), "error: triplet not allowed in specifier: %s", name); - - Features f; - f.name = spec->name; - f.features = spec->features; - return f; - } - - Checks::exit_with_message( - VCPKG_LINE_INFO, "error while parsing feature list: %s: %s", to_string(maybe_spec.error()), name); - } - Dependency Dependency::parse_dependency(std::string name, std::string qualifier) { Dependency dep; dep.qualifier = qualifier; - dep.depend = parse_feature_list(name); + if (auto maybe_features = Features::from_string(name)) + dep.depend = *maybe_features.get(); + else + Checks::exit_with_message( + VCPKG_LINE_INFO, "error while parsing dependency: %s: %s", to_string(maybe_features.error()), name); return dep; } @@ -217,39 +203,6 @@ namespace vcpkg }); } - std::vector parse_comma_list(const std::string& str) - { - if (str.empty()) - { - return {}; - } - - std::vector out; - - size_t cur = 0; - do - { - auto pos = str.find(',', cur); - if (pos == std::string::npos) - { - out.push_back(str.substr(cur)); - break; - } - out.push_back(str.substr(cur, pos - cur)); - - // skip comma and space - ++pos; - if (str[pos] == ' ') - { - ++pos; - } - - cur = pos; - } while (cur != std::string::npos); - - return out; - } - std::vector filter_dependencies(const std::vector& deps, const Triplet& t) { std::vector ret; diff --git a/toolsrc/src/tests_dependencies.cpp b/toolsrc/src/tests_dependencies.cpp index 26cc1e22c..6a6981d73 100644 --- a/toolsrc/src/tests_dependencies.cpp +++ b/toolsrc/src/tests_dependencies.cpp @@ -8,6 +8,7 @@ using namespace Microsoft::VisualStudio::CppUnitTestFramework; using namespace vcpkg; +using Parse::parse_comma_list; namespace UnitTest1 { @@ -41,7 +42,15 @@ namespace UnitTest1 TEST_METHOD(parse_supports_all) { auto v = Supports::parse({ - "x64", "x86", "arm", "windows", "uwp", "v140", "v141", "crt-static", "crt-dynamic", + "x64", + "x86", + "arm", + "windows", + "uwp", + "v140", + "v141", + "crt-static", + "crt-dynamic", }); Assert::AreNotEqual(uintptr_t(0), uintptr_t(v.get())); @@ -74,7 +83,9 @@ namespace UnitTest1 TEST_METHOD(parse_supports_some) { auto v = Supports::parse({ - "x64", "x86", "windows", + "x64", + "x86", + "windows", }); Assert::AreNotEqual(uintptr_t(0), uintptr_t(v.get())); diff --git a/toolsrc/src/vcpkg_Parse.cpp b/toolsrc/src/vcpkg_Parse.cpp index 659af2939..118cde900 100644 --- a/toolsrc/src/vcpkg_Parse.cpp +++ b/toolsrc/src/vcpkg_Parse.cpp @@ -44,4 +44,37 @@ namespace vcpkg::Parse } return nullptr; } + + std::vector parse_comma_list(const std::string& str) + { + if (str.empty()) + { + return {}; + } + + std::vector out; + + size_t cur = 0; + do + { + auto pos = str.find(',', cur); + if (pos == std::string::npos) + { + out.push_back(str.substr(cur)); + break; + } + out.push_back(str.substr(cur, pos - cur)); + + // skip comma and space + ++pos; + if (str[pos] == ' ') + { + ++pos; + } + + cur = pos; + } while (cur != std::string::npos); + + return out; + } } -- cgit v1.2.3 From bd222504abea410d77487e176649ae9b6989c4e0 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Sun, 20 Aug 2017 19:09:39 -0700 Subject: [vcpkg] Refactor parsing together and flatten featurespec usages --- toolsrc/include/PackageSpec.h | 20 +++++ toolsrc/include/vcpkg_Dependencies.h | 9 +-- toolsrc/src/PackageSpec.cpp | 42 ++++++++++ toolsrc/src/commands_install.cpp | 6 +- toolsrc/src/test_install_plan.cpp | 56 ++++++++----- toolsrc/src/tests_package_spec.cpp | 119 ++++++++++++++++++++++++++++ toolsrc/src/tests_paragraph.cpp | 63 --------------- toolsrc/src/vcpkg_Dependencies.cpp | 56 +++---------- toolsrc/vcpkgtest/vcpkgtest.vcxproj | 1 + toolsrc/vcpkgtest/vcpkgtest.vcxproj.filters | 3 + 10 files changed, 237 insertions(+), 138 deletions(-) create mode 100644 toolsrc/src/tests_package_spec.cpp (limited to 'toolsrc') diff --git a/toolsrc/include/PackageSpec.h b/toolsrc/include/PackageSpec.h index 8e986b4d6..8b485316f 100644 --- a/toolsrc/include/PackageSpec.h +++ b/toolsrc/include/PackageSpec.h @@ -33,11 +33,31 @@ namespace vcpkg Triplet m_triplet; }; + struct FeatureSpec + { + FeatureSpec(const PackageSpec& spec, const std::string& feature) : m_spec(spec), m_feature(feature) {} + + const std::string& name() const { return m_spec.name(); } + const std::string& feature() const { return m_feature; } + const Triplet& triplet() const { return m_spec.triplet(); } + + const PackageSpec& spec() const { return m_spec; } + + static std::vector from_strings_and_triplet(const std::vector& depends, + const Triplet& t); + + private: + PackageSpec m_spec; + std::string m_feature; + }; + struct FullPackageSpec { PackageSpec package_spec; std::vector features; + static std::vector to_feature_specs(const std::vector& specs); + static ExpectedT from_string(const std::string& spec_as_string, const Triplet& default_triplet); }; diff --git a/toolsrc/include/vcpkg_Dependencies.h b/toolsrc/include/vcpkg_Dependencies.h index 3fee8ef33..37d3a59e5 100644 --- a/toolsrc/include/vcpkg_Dependencies.h +++ b/toolsrc/include/vcpkg_Dependencies.h @@ -30,19 +30,12 @@ namespace vcpkg::Dependencies namespace vcpkg::Dependencies { - struct FeatureSpec - { - PackageSpec spec; - std::string feature_name; - }; - struct FeatureNodeEdges { std::vector remove_edges; std::vector build_edges; bool plus = false; }; - std::vector to_feature_specs(const std::vector& depends, const Triplet& t); struct Cluster { @@ -210,6 +203,6 @@ namespace vcpkg::Dependencies std::unordered_map& pkg_to_cluster, GraphPlan& graph_plan); std::vector create_feature_install_plan(const std::unordered_map& map, - const std::vector& specs, + const std::vector& specs, const StatusParagraphs& status_db); } diff --git a/toolsrc/src/PackageSpec.cpp b/toolsrc/src/PackageSpec.cpp index 475b3e3f6..a5d40e998 100644 --- a/toolsrc/src/PackageSpec.cpp +++ b/toolsrc/src/PackageSpec.cpp @@ -13,6 +13,48 @@ namespace vcpkg return (c == '-') || isdigit(c) || (isalpha(c) && islower(c)) || (c == '[') || (c == ']'); } + std::vector FeatureSpec::from_strings_and_triplet(const std::vector& depends, + const Triplet& triplet) + { + std::vector f_specs; + for (auto&& depend : depends) + { + auto maybe_spec = ParsedSpecifier::from_string(depend); + if (auto spec = maybe_spec.get()) + { + Checks::check_exit(VCPKG_LINE_INFO, + spec->triplet.empty(), + "error: triplets cannot currently be specified in this context: %s", + depend); + PackageSpec pspec = + PackageSpec::from_name_and_triplet(spec->name, triplet).value_or_exit(VCPKG_LINE_INFO); + + for (auto&& feature : spec->features) + f_specs.push_back(FeatureSpec{pspec, feature}); + + if (spec->features.empty()) f_specs.push_back(FeatureSpec{pspec, ""}); + } + else + { + Checks::exit_with_message( + VCPKG_LINE_INFO, "error while parsing feature list: %s: %s", to_string(maybe_spec.error()), depend); + } + } + return f_specs; + } + + std::vector FullPackageSpec::to_feature_specs(const std::vector& specs) + { + std::vector ret; + for (auto&& spec : specs) + { + ret.emplace_back(spec.package_spec, ""); + for (auto&& feature : spec.features) + ret.emplace_back(spec.package_spec, feature); + } + return ret; + } + ExpectedT FullPackageSpec::from_string(const std::string& spec_as_string, const Triplet& default_triplet) { diff --git a/toolsrc/src/commands_install.cpp b/toolsrc/src/commands_install.cpp index 2965d9025..3fc0e2563 100644 --- a/toolsrc/src/commands_install.cpp +++ b/toolsrc/src/commands_install.cpp @@ -14,10 +14,10 @@ namespace vcpkg::Commands::Install { using Dependencies::InstallPlanAction; - using Dependencies::RequestType; using Dependencies::InstallPlanType; using Dependencies::RemovePlanAction; using Dependencies::RemovePlanType; + using Dependencies::RequestType; InstallDir InstallDir::from_destination_root(const fs::path& destination_root, const std::string& destination_subdirectory, @@ -440,8 +440,8 @@ namespace vcpkg::Commands::Install .value_or_exit(VCPKG_LINE_INFO); scf_map[pkg_spec] = std::move(*port); } - std::vector action_plan = - Dependencies::create_feature_install_plan(scf_map, full_specs, status_db); + std::vector action_plan = Dependencies::create_feature_install_plan( + scf_map, FullPackageSpec::to_feature_specs(full_specs), status_db); // install plan will be empty if it is already installed - need to change this at status paragraph part Checks::check_exit( VCPKG_LINE_INFO, !action_plan.empty(), "Install plan cannot be empty for feature packages"); diff --git a/toolsrc/src/test_install_plan.cpp b/toolsrc/src/test_install_plan.cpp index 347998723..e7c62813e 100644 --- a/toolsrc/src/test_install_plan.cpp +++ b/toolsrc/src/test_install_plan.cpp @@ -214,8 +214,10 @@ namespace UnitTest1 {{"Feature", "beefeaturethree"}, {"Description", "the third feature for b"}, {"Build-Depends", ""}}, })}; - auto install_plan = Dependencies::create_feature_install_plan( - spec_map.map, {spec_a}, StatusParagraphs(std::move(status_paragraphs))); + auto install_plan = + Dependencies::create_feature_install_plan(spec_map.map, + FullPackageSpec::to_feature_specs({spec_a}), + StatusParagraphs(std::move(status_paragraphs))); Assert::AreEqual(size_t(4), install_plan.size()); remove_plan_check(&install_plan[0], "a"); @@ -248,8 +250,10 @@ namespace UnitTest1 {{"Feature", "beefeaturethree"}, {"Description", "the third feature for b"}, {"Build-Depends", ""}}, })}; - auto install_plan = Dependencies::create_feature_install_plan( - spec_map.map, {spec_a}, StatusParagraphs(std::move(status_paragraphs))); + auto install_plan = + Dependencies::create_feature_install_plan(spec_map.map, + FullPackageSpec::to_feature_specs({spec_a}), + StatusParagraphs(std::move(status_paragraphs))); Assert::AreEqual(size_t(2), install_plan.size()); features_check(&install_plan[0], "b", {"beefeatureone", "beefeaturetwo", "core"}); @@ -284,8 +288,10 @@ namespace UnitTest1 }), {"core"}}; - auto install_plan = Dependencies::create_feature_install_plan( - spec_map.map, {spec_c, spec_a}, StatusParagraphs(std::move(status_paragraphs))); + auto install_plan = + Dependencies::create_feature_install_plan(spec_map.map, + FullPackageSpec::to_feature_specs({spec_c, spec_a}), + StatusParagraphs(std::move(status_paragraphs))); Assert::AreEqual(size_t(4), install_plan.size()); remove_plan_check(&install_plan[0], "a"); @@ -328,8 +334,10 @@ namespace UnitTest1 }), {"core"}}; - auto install_plan = Dependencies::create_feature_install_plan( - spec_map.map, {spec_c}, StatusParagraphs(std::move(status_paragraphs))); + auto install_plan = + Dependencies::create_feature_install_plan(spec_map.map, + FullPackageSpec::to_feature_specs({spec_c}), + StatusParagraphs(std::move(status_paragraphs))); Assert::AreEqual(size_t(1), install_plan.size()); features_check(&install_plan[0], "c", {"core"}); @@ -356,8 +364,10 @@ namespace UnitTest1 {{"Feature", "2"}, {"Description", "the second feature for b"}, {"Build-Depends", ""}}, })}; - auto install_plan = Dependencies::create_feature_install_plan( - spec_map.map, {spec_a}, StatusParagraphs(std::move(status_paragraphs))); + auto install_plan = + Dependencies::create_feature_install_plan(spec_map.map, + FullPackageSpec::to_feature_specs({spec_a}), + StatusParagraphs(std::move(status_paragraphs))); Assert::AreEqual(size_t(2), install_plan.size()); features_check(&install_plan[0], "b", {"core", "2"}); @@ -389,8 +399,10 @@ namespace UnitTest1 }), {"1"}}; - auto install_plan = Dependencies::create_feature_install_plan( - spec_map.map, {spec_a, spec_b}, StatusParagraphs(std::move(status_paragraphs))); + auto install_plan = + Dependencies::create_feature_install_plan(spec_map.map, + FullPackageSpec::to_feature_specs({spec_a, spec_b}), + StatusParagraphs(std::move(status_paragraphs))); Assert::AreEqual(size_t(3), install_plan.size()); remove_plan_check(&install_plan[0], "b"); @@ -433,8 +445,10 @@ namespace UnitTest1 }), {"1"}}; - auto install_plan = Dependencies::create_feature_install_plan( - spec_map.map, {spec_b}, StatusParagraphs(std::move(status_paragraphs))); + auto install_plan = + Dependencies::create_feature_install_plan(spec_map.map, + FullPackageSpec::to_feature_specs({spec_b}), + StatusParagraphs(std::move(status_paragraphs))); Assert::AreEqual(size_t(5), install_plan.size()); remove_plan_check(&install_plan[0], "x"); @@ -495,10 +509,10 @@ namespace UnitTest1 }), {"core"}}; - auto install_plan = - Dependencies::create_feature_install_plan(spec_map.map, - {spec_c_64, spec_a_86, spec_a_64, spec_c_86}, - StatusParagraphs(std::move(status_paragraphs))); + auto install_plan = Dependencies::create_feature_install_plan( + spec_map.map, + FullPackageSpec::to_feature_specs({spec_c_64, spec_a_86, spec_a_64, spec_c_86}), + StatusParagraphs(std::move(status_paragraphs))); /*Assert::AreEqual(size_t(8), install_plan.size()); auto iterator_pos = [&](const PackageSpec& spec, size_t start) -> int { @@ -555,8 +569,10 @@ namespace UnitTest1 }), {""}}; - auto install_plan = Dependencies::create_feature_install_plan( - spec_map.map, {spec_a}, StatusParagraphs(std::move(status_paragraphs))); + auto install_plan = + Dependencies::create_feature_install_plan(spec_map.map, + FullPackageSpec::to_feature_specs({spec_a}), + StatusParagraphs(std::move(status_paragraphs))); Assert::AreEqual(size_t(3), install_plan.size()); features_check(&install_plan[0], "c", {"core", "1", "2"}); diff --git a/toolsrc/src/tests_package_spec.cpp b/toolsrc/src/tests_package_spec.cpp new file mode 100644 index 000000000..fa201b372 --- /dev/null +++ b/toolsrc/src/tests_package_spec.cpp @@ -0,0 +1,119 @@ +#include "BinaryParagraph.h" +#include "CppUnitTest.h" +#include "Paragraphs.h" +#include "vcpkg_Strings.h" + +#pragma comment(lib, "version") +#pragma comment(lib, "winhttp") + +using namespace Microsoft::VisualStudio::CppUnitTestFramework; + +namespace Microsoft::VisualStudio::CppUnitTestFramework +{ + template<> + inline std::wstring ToString(const vcpkg::PackageSpecParseResult& t) + { + return ToString(static_cast(t)); + } + + template<> + inline std::wstring ToString(const vcpkg::PackageSpec& t) + { + return ToString(t.to_string()); + } +} + +namespace Strings = vcpkg::Strings; + +namespace UnitTest1 +{ + using namespace vcpkg; + + class SpecifierConversion : public TestClass + { + TEST_METHOD(full_package_spec_to_feature_specs) + { + auto a_spec = PackageSpec::from_name_and_triplet("a", Triplet::X64_WINDOWS).value_or_exit(VCPKG_LINE_INFO); + auto b_spec = PackageSpec::from_name_and_triplet("b", Triplet::X64_WINDOWS).value_or_exit(VCPKG_LINE_INFO); + + auto fspecs = FullPackageSpec::to_feature_specs({{a_spec, {"0", "1"}}, {b_spec, {"2", "3"}}}); + + Assert::AreEqual(size_t(6), fspecs.size()); + + std::array features = {"", "0", "1", "", "2", "3"}; + std::array specs = {&a_spec, &a_spec, &a_spec, &b_spec, &b_spec, &b_spec}; + + for (int i = 0; i < features.size(); ++i) + { + Assert::AreEqual(features[i], fspecs[i].feature().c_str()); + Assert::AreEqual(*specs[i], fspecs[i].spec()); + } + } + }; + + class SpecifierParsing : public TestClass + { + TEST_METHOD(parsed_specifier_from_string) + { + auto maybe_spec = vcpkg::ParsedSpecifier::from_string("zlib"); + Assert::AreEqual(vcpkg::PackageSpecParseResult::SUCCESS, maybe_spec.error()); + auto spec = maybe_spec.get(); + Assert::AreEqual("zlib", spec->name.c_str()); + Assert::AreEqual(size_t(0), spec->features.size()); + Assert::AreEqual("", spec->triplet.c_str()); + } + + TEST_METHOD(parsed_specifier_from_string_with_triplet) + { + auto maybe_spec = vcpkg::ParsedSpecifier::from_string("zlib:x64-uwp"); + Assert::AreEqual(vcpkg::PackageSpecParseResult::SUCCESS, maybe_spec.error()); + auto spec = maybe_spec.get(); + Assert::AreEqual("zlib", spec->name.c_str()); + Assert::AreEqual("x64-uwp", spec->triplet.c_str()); + } + + TEST_METHOD(parsed_specifier_from_string_with_colons) + { + auto ec = vcpkg::ParsedSpecifier::from_string("zlib:x86-uwp:").error(); + Assert::AreEqual(vcpkg::PackageSpecParseResult::TOO_MANY_COLONS, ec); + } + + TEST_METHOD(parsed_specifier_from_string_with_feature) + { + auto maybe_spec = vcpkg::ParsedSpecifier::from_string("zlib[feature]:x64-uwp"); + Assert::AreEqual(vcpkg::PackageSpecParseResult::SUCCESS, maybe_spec.error()); + auto spec = maybe_spec.get(); + Assert::AreEqual("zlib", spec->name.c_str()); + Assert::IsTrue(spec->features.size() == 1); + Assert::AreEqual("feature", spec->features.front().c_str()); + Assert::AreEqual("x64-uwp", spec->triplet.c_str()); + } + + TEST_METHOD(parsed_specifier_from_string_with_many_features) + { + auto maybe_spec = vcpkg::ParsedSpecifier::from_string("zlib[0, 1,2]"); + Assert::AreEqual(vcpkg::PackageSpecParseResult::SUCCESS, maybe_spec.error()); + auto spec = maybe_spec.get(); + Assert::AreEqual("zlib", spec->name.c_str()); + Assert::IsTrue(spec->features.size() == 3); + Assert::AreEqual("0", spec->features[0].c_str()); + Assert::AreEqual("1", spec->features[1].c_str()); + Assert::AreEqual("2", spec->features[2].c_str()); + Assert::AreEqual("", spec->triplet.c_str()); + } + + TEST_METHOD(utf8_to_utf16) + { + auto str = vcpkg::Strings::to_utf16("abc"); + Assert::AreEqual(L"abc", str.c_str()); + } + + TEST_METHOD(utf8_to_utf16_with_whitespace) + { + auto str = vcpkg::Strings::to_utf16("abc -x86-windows"); + Assert::AreEqual(L"abc -x86-windows", str.c_str()); + } + }; + + TEST_CLASS(Metrics){}; +} diff --git a/toolsrc/src/tests_paragraph.cpp b/toolsrc/src/tests_paragraph.cpp index 1fd950e19..47a07e12d 100644 --- a/toolsrc/src/tests_paragraph.cpp +++ b/toolsrc/src/tests_paragraph.cpp @@ -384,68 +384,5 @@ namespace UnitTest1 Assert::AreEqual(size_t(1), pghs.size()); Assert::AreEqual("a, b, c", pghs[0]["Depends"].c_str()); } - - TEST_METHOD(parsed_specifier_from_string) - { - auto maybe_spec = vcpkg::ParsedSpecifier::from_string("zlib"); - Assert::AreEqual(vcpkg::PackageSpecParseResult::SUCCESS, maybe_spec.error()); - auto spec = maybe_spec.get(); - Assert::AreEqual("zlib", spec->name.c_str()); - Assert::AreEqual(size_t(0), spec->features.size()); - Assert::AreEqual("", spec->triplet.c_str()); - } - - TEST_METHOD(parsed_specifier_from_string_with_triplet) - { - auto maybe_spec = vcpkg::ParsedSpecifier::from_string("zlib:x64-uwp"); - Assert::AreEqual(vcpkg::PackageSpecParseResult::SUCCESS, maybe_spec.error()); - auto spec = maybe_spec.get(); - Assert::AreEqual("zlib", spec->name.c_str()); - Assert::AreEqual("x64-uwp", spec->triplet.c_str()); - } - - TEST_METHOD(parsed_specifier_from_string_with_colons) - { - auto ec = vcpkg::ParsedSpecifier::from_string("zlib:x86-uwp:").error(); - Assert::AreEqual(vcpkg::PackageSpecParseResult::TOO_MANY_COLONS, ec); - } - - TEST_METHOD(parsed_specifier_from_string_with_feature) - { - auto maybe_spec = vcpkg::ParsedSpecifier::from_string("zlib[feature]:x64-uwp"); - Assert::AreEqual(vcpkg::PackageSpecParseResult::SUCCESS, maybe_spec.error()); - auto spec = maybe_spec.get(); - Assert::AreEqual("zlib", spec->name.c_str()); - Assert::IsTrue(spec->features.size() == 1); - Assert::AreEqual("feature", spec->features.front().c_str()); - Assert::AreEqual("x64-uwp", spec->triplet.c_str()); - } - - TEST_METHOD(parsed_specifier_from_string_with_many_features) - { - auto maybe_spec = vcpkg::ParsedSpecifier::from_string("zlib[0, 1,2]"); - Assert::AreEqual(vcpkg::PackageSpecParseResult::SUCCESS, maybe_spec.error()); - auto spec = maybe_spec.get(); - Assert::AreEqual("zlib", spec->name.c_str()); - Assert::IsTrue(spec->features.size() == 3); - Assert::AreEqual("0", spec->features[0].c_str()); - Assert::AreEqual("1", spec->features[1].c_str()); - Assert::AreEqual("2", spec->features[2].c_str()); - Assert::AreEqual("", spec->triplet.c_str()); - } - - TEST_METHOD(utf8_to_utf16) - { - auto str = vcpkg::Strings::to_utf16("abc"); - Assert::AreEqual(L"abc", str.c_str()); - } - - TEST_METHOD(utf8_to_utf16_with_whitespace) - { - auto str = vcpkg::Strings::to_utf16("abc -x86-windows"); - Assert::AreEqual(L"abc -x86-windows", str.c_str()); - } }; - - TEST_CLASS(Metrics){}; } diff --git a/toolsrc/src/vcpkg_Dependencies.cpp b/toolsrc/src/vcpkg_Dependencies.cpp index 799bca439..5226fac24 100644 --- a/toolsrc/src/vcpkg_Dependencies.cpp +++ b/toolsrc/src/vcpkg_Dependencies.cpp @@ -358,35 +358,6 @@ namespace vcpkg::Dependencies return toposort; } - std::vector to_feature_specs(const std::vector& depends, const Triplet& triplet) - { - std::vector f_specs; - for (auto&& depend : depends) - { - auto maybe_spec = ParsedSpecifier::from_string(depend); - if (auto spec = maybe_spec.get()) - { - Checks::check_exit(VCPKG_LINE_INFO, - spec->triplet.empty(), - "error: triplets cannot currently be specified in this context: %s", - depend); - PackageSpec pspec = - PackageSpec::from_name_and_triplet(spec->name, triplet).value_or_exit(VCPKG_LINE_INFO); - - for (auto&& feature : spec->features) - f_specs.push_back(FeatureSpec{pspec, feature}); - - if (spec->features.empty()) f_specs.push_back(FeatureSpec{pspec, ""}); - } - else - { - Checks::exit_with_message( - VCPKG_LINE_INFO, "error while parsing feature list: %s: %s", to_string(maybe_spec.error()), depend); - } - } - return f_specs; - } - void mark_plus_default(Cluster& cluster, std::unordered_map& pkg_to_cluster, GraphPlan& graph_plan) @@ -442,8 +413,8 @@ namespace vcpkg::Dependencies for (auto&& depend : cluster.edges[updated_feature].build_edges) { - auto& depend_cluster = pkg_to_cluster[depend.spec]; - mark_plus(depend.feature_name, depend_cluster, pkg_to_cluster, graph_plan); + auto& depend_cluster = pkg_to_cluster[depend.spec()]; + mark_plus(depend.feature(), depend_cluster, pkg_to_cluster, graph_plan); mark_plus_default(depend_cluster, pkg_to_cluster, graph_plan); if (&depend_cluster == &cluster) continue; graph_plan.install_graph.add_edge({&cluster}, {&depend_cluster}); @@ -462,7 +433,7 @@ namespace vcpkg::Dependencies auto& remove_edges_edges = pair.second.remove_edges; for (auto&& depend : remove_edges_edges) { - auto& depend_cluster = pkg_to_cluster[depend.spec]; + auto& depend_cluster = pkg_to_cluster[depend.spec()]; graph_plan.remove_graph.add_edge({&cluster}, {&depend_cluster}); depend_cluster.transient_uninstalled = true; mark_minus(depend_cluster, pkg_to_cluster, graph_plan); @@ -476,7 +447,7 @@ namespace vcpkg::Dependencies } std::vector create_feature_install_plan(const std::unordered_map& map, - const std::vector& specs, + const std::vector& specs, const StatusParagraphs& status_db) { std::unordered_map pkg_spec_to_package_node; @@ -488,14 +459,14 @@ namespace vcpkg::Dependencies node.spec = it.first; FeatureNodeEdges core_dependencies; auto core_depends = filter_dependencies(it.second.core_paragraph->depends, node.spec.triplet()); - core_dependencies.build_edges = to_feature_specs(core_depends, node.spec.triplet()); + core_dependencies.build_edges = FeatureSpec::from_strings_and_triplet(core_depends, node.spec.triplet()); node.edges["core"] = std::move(core_dependencies); for (const auto& feature : it.second.feature_paragraphs) { FeatureNodeEdges added_edges; auto depends = filter_dependencies(feature->depends, node.spec.triplet()); - added_edges.build_edges = to_feature_specs(depends, node.spec.triplet()); + added_edges.build_edges = FeatureSpec::from_strings_and_triplet(depends, node.spec.triplet()); node.edges.emplace(feature->name, std::move(added_edges)); } node.source_control_file = &it.second; @@ -508,13 +479,13 @@ namespace vcpkg::Dependencies Cluster& cluster = pkg_spec_to_package_node[spec]; cluster.transient_uninstalled = false; - auto reverse_edges = - to_feature_specs(status_paragraph->package.depends, status_paragraph->package.spec.triplet()); + auto reverse_edges = FeatureSpec::from_strings_and_triplet(status_paragraph->package.depends, + status_paragraph->package.spec.triplet()); for (auto&& dependency : reverse_edges) { - auto pkg_node = pkg_spec_to_package_node.find(dependency.spec); - auto depends_name = dependency.feature_name; + auto pkg_node = pkg_spec_to_package_node.find(dependency.spec()); + auto depends_name = dependency.feature(); if (depends_name == "") { for (auto&& default_feature : status_paragraph->package.default_features) @@ -541,12 +512,9 @@ namespace vcpkg::Dependencies GraphPlan graph_plan; for (auto&& spec : specs) { - Cluster& spec_cluster = pkg_spec_to_package_node[spec.package_spec]; + Cluster& spec_cluster = pkg_spec_to_package_node[spec.spec()]; mark_plus_default(spec_cluster, pkg_spec_to_package_node, graph_plan); - for (auto&& feature : spec.features) - { - mark_plus(feature, spec_cluster, pkg_spec_to_package_node, graph_plan); - } + mark_plus(spec.feature(), spec_cluster, pkg_spec_to_package_node, graph_plan); } Graphs::GraphAdjacencyProvider adjacency_remove_graph(graph_plan.remove_graph.adjacency_list()); diff --git a/toolsrc/vcpkgtest/vcpkgtest.vcxproj b/toolsrc/vcpkgtest/vcpkgtest.vcxproj index ca66260d4..041e74d31 100644 --- a/toolsrc/vcpkgtest/vcpkgtest.vcxproj +++ b/toolsrc/vcpkgtest/vcpkgtest.vcxproj @@ -21,6 +21,7 @@ + diff --git a/toolsrc/vcpkgtest/vcpkgtest.vcxproj.filters b/toolsrc/vcpkgtest/vcpkgtest.vcxproj.filters index e376e59f4..b31dbd951 100644 --- a/toolsrc/vcpkgtest/vcpkgtest.vcxproj.filters +++ b/toolsrc/vcpkgtest/vcpkgtest.vcxproj.filters @@ -27,5 +27,8 @@ Source Files + + Source Files + \ No newline at end of file -- cgit v1.2.3 From 1ba7cef1f07e8fd8c0053694b306dcc3960f720e Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Sun, 20 Aug 2017 19:36:43 -0700 Subject: [vcpkg] Remove incomplete default features implementation --- toolsrc/include/SourceParagraph.h | 11 ++-- toolsrc/include/vcpkg_Dependencies.h | 8 --- toolsrc/src/SourceParagraph.cpp | 5 ++ toolsrc/src/test_install_plan.cpp | 42 ------------- toolsrc/src/vcpkg_Dependencies.cpp | 114 +++++++++++++++++++---------------- 5 files changed, 74 insertions(+), 106 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/SourceParagraph.h b/toolsrc/include/SourceParagraph.h index d938e2e3b..05f18f940 100644 --- a/toolsrc/include/SourceParagraph.h +++ b/toolsrc/include/SourceParagraph.h @@ -23,6 +23,12 @@ namespace vcpkg static Dependency parse_dependency(std::string name, std::string qualifier); }; + std::vector filter_dependencies(const std::vector& deps, const Triplet& t); + std::vector filter_dependencies_to_specs(const std::vector& deps, const Triplet& t); + + // zlib[uwp] becomes Dependency{"zlib", "uwp"} + std::vector expand_qualified_dependencies(const std::vector& depends); + const std::string to_string(const Dependency& dep); struct FeatureParagraph @@ -60,11 +66,6 @@ namespace vcpkg return print_error_message({&error_info_list, 1}); } - std::vector filter_dependencies(const std::vector& deps, const Triplet& t); - - // zlib[uwp] becomes Dependency{"zlib", "uwp"} - std::vector expand_qualified_dependencies(const std::vector& depends); - struct Supports { static ExpectedT> parse(const std::vector& strs); diff --git a/toolsrc/include/vcpkg_Dependencies.h b/toolsrc/include/vcpkg_Dependencies.h index 37d3a59e5..3a81cf27b 100644 --- a/toolsrc/include/vcpkg_Dependencies.h +++ b/toolsrc/include/vcpkg_Dependencies.h @@ -194,14 +194,6 @@ namespace vcpkg::Dependencies Graphs::Graph remove_graph; Graphs::Graph install_graph; }; - bool mark_plus(const std::string& feature, - Cluster& cluster, - std::unordered_map& pkg_to_cluster, - GraphPlan& graph_plan); - void mark_minus(Cluster& cluster, std::unordered_map& pkg_to_cluster, GraphPlan& graph_plan); - void mark_plus_default(Cluster& cluster, - std::unordered_map& pkg_to_cluster, - GraphPlan& graph_plan); std::vector create_feature_install_plan(const std::unordered_map& map, const std::vector& specs, const StatusParagraphs& status_db); diff --git a/toolsrc/src/SourceParagraph.cpp b/toolsrc/src/SourceParagraph.cpp index 76c5a2004..54f34cbd3 100644 --- a/toolsrc/src/SourceParagraph.cpp +++ b/toolsrc/src/SourceParagraph.cpp @@ -216,6 +216,11 @@ namespace vcpkg return ret; } + std::vector filter_dependencies_to_specs(const std::vector& deps, const Triplet& t) + { + return FeatureSpec::from_strings_and_triplet(filter_dependencies(deps, t), t); + } + const std::string to_string(const Dependency& dep) { std::string name = dep.name(); diff --git a/toolsrc/src/test_install_plan.cpp b/toolsrc/src/test_install_plan.cpp index e7c62813e..f0884c063 100644 --- a/toolsrc/src/test_install_plan.cpp +++ b/toolsrc/src/test_install_plan.cpp @@ -537,47 +537,5 @@ namespace UnitTest1 features_check(&install_plan[6], "a", {"one", "core"}); features_check(&install_plan[7], "c", {"core"}); } - - TEST_METHOD(default_features_test) - { - using Pgh = std::unordered_map; - - std::vector> status_paragraphs; - - PackageSpecMap spec_map(Triplet::X86_WINDOWS); - - auto spec_a = FullPackageSpec{ - spec_map.get_package_spec( - {{{"Source", "a"}, {"Version", "1.3"}, {"Default-Features", "1, 2"}, {"Build-Depends", ""}}, - {{"Feature", "1"}, {"Description", "the first feature for a"}, {"Build-Depends", "b[2]"}}, - {{"Feature", "2"}, {"Description", "the second feature for a"}, {"Build-Depends", ""}}, - {{"Feature", "3"}, {"Description", "the third feature for a"}, {"Build-Depends", ""}}}), - {""}}; - auto spec_b = FullPackageSpec{ - spec_map.get_package_spec({ - {{"Source", "b"}, {"Version", "1.3"}, {"Default-Features", "1, 2"}, {"Build-Depends", ""}}, - {{"Feature", "1"}, {"Description", "the first feature for b"}, {"Build-Depends", "c[1]"}}, - {{"Feature", "2"}, {"Description", "the second feature for b"}, {"Build-Depends", ""}}, - }), - {""}}; - - auto spec_c = FullPackageSpec{ - spec_map.get_package_spec({ - {{"Source", "c"}, {"Version", "1.3"}, {"Default-Features", "2"}, {"Build-Depends", ""}}, - {{"Feature", "1"}, {"Description", "the first feature for c"}, {"Build-Depends", ""}}, - {{"Feature", "2"}, {"Description", "the second feature for c"}, {"Build-Depends", ""}}, - }), - {""}}; - - auto install_plan = - Dependencies::create_feature_install_plan(spec_map.map, - FullPackageSpec::to_feature_specs({spec_a}), - StatusParagraphs(std::move(status_paragraphs))); - - Assert::AreEqual(size_t(3), install_plan.size()); - features_check(&install_plan[0], "c", {"core", "1", "2"}); - features_check(&install_plan[1], "b", {"core", "1", "2"}); - features_check(&install_plan[2], "a", {"core", "1", "2"}); - } }; } \ No newline at end of file diff --git a/toolsrc/src/vcpkg_Dependencies.cpp b/toolsrc/src/vcpkg_Dependencies.cpp index 5226fac24..fa4876bd7 100644 --- a/toolsrc/src/vcpkg_Dependencies.cpp +++ b/toolsrc/src/vcpkg_Dependencies.cpp @@ -12,6 +12,10 @@ namespace vcpkg::Dependencies { + struct ClusterGraph; + void mark_plus(const std::string& feature, Cluster& cluster, ClusterGraph& pkg_to_cluster, GraphPlan& graph_plan); + void mark_minus(Cluster& cluster, ClusterGraph& pkg_to_cluster, GraphPlan& graph_plan); + bool operator==(const ClusterPtr& l, const ClusterPtr& r) { return l.ptr == r.ptr; } std::vector AnyParagraph::dependencies(const Triplet& triplet) const @@ -358,71 +362,74 @@ namespace vcpkg::Dependencies return toposort; } - void mark_plus_default(Cluster& cluster, - std::unordered_map& pkg_to_cluster, - GraphPlan& graph_plan) + struct ClusterGraph { - mark_plus("core", cluster, pkg_to_cluster, graph_plan); - if (auto scf = cluster.source_control_file.get()) + explicit ClusterGraph(std::unordered_map&& graph) : m_graph(std::move(graph)) {} + ClusterGraph(ClusterGraph&&) = default; + + Cluster& get(const PackageSpec& spec) { - for (auto&& default_feature : (*scf)->core_paragraph->default_features) - { - mark_plus(default_feature, cluster, pkg_to_cluster, graph_plan); - } + auto it = m_graph.find(spec); + if (it == m_graph.end()) Checks::unreachable(VCPKG_LINE_INFO); + return it->second; } - } - bool mark_plus(const std::string& feature, - Cluster& cluster, - std::unordered_map& pkg_to_cluster, - GraphPlan& graph_plan) + private: + ClusterGraph(const ClusterGraph&) = delete; + std::unordered_map m_graph; + }; + + void mark_plus(const std::string& feature, Cluster& cluster, ClusterGraph& graph, GraphPlan& graph_plan) { - auto it = cluster.edges.find(feature); - std::string updated_feature = feature; - if (updated_feature == "") + if (feature == "") { - updated_feature = "core"; - it = cluster.edges.find("core"); + // Indicates that core was not specified in the reference + return mark_plus("core", cluster, graph, graph_plan); } + auto it = cluster.edges.find(feature); if (it == cluster.edges.end()) { Checks::unreachable(VCPKG_LINE_INFO); } - if (cluster.edges[updated_feature].plus) return true; + if (cluster.edges[feature].plus) return; - if (cluster.original_features.find(updated_feature) == cluster.original_features.end()) + if (cluster.original_features.find(feature) == cluster.original_features.end()) { cluster.transient_uninstalled = true; } if (!cluster.transient_uninstalled) { - return false; + return; } - cluster.edges[updated_feature].plus = true; + cluster.edges[feature].plus = true; if (!cluster.original_features.empty()) { - mark_minus(cluster, pkg_to_cluster, graph_plan); + mark_minus(cluster, graph, graph_plan); } graph_plan.install_graph.add_vertex({&cluster}); auto& tracked = cluster.to_install_features; - tracked.insert(updated_feature); + tracked.insert(feature); + + if (feature != "core") + { + // All features implicitly depend on core + mark_plus("core", cluster, graph, graph_plan); + } - for (auto&& depend : cluster.edges[updated_feature].build_edges) + for (auto&& depend : cluster.edges[feature].build_edges) { - auto& depend_cluster = pkg_to_cluster[depend.spec()]; - mark_plus(depend.feature(), depend_cluster, pkg_to_cluster, graph_plan); - mark_plus_default(depend_cluster, pkg_to_cluster, graph_plan); + auto& depend_cluster = graph.get(depend.spec()); + mark_plus(depend.feature(), depend_cluster, graph, graph_plan); if (&depend_cluster == &cluster) continue; graph_plan.install_graph.add_edge({&cluster}, {&depend_cluster}); } - return true; } - void mark_minus(Cluster& cluster, std::unordered_map& pkg_to_cluster, GraphPlan& graph_plan) + void mark_minus(Cluster& cluster, ClusterGraph& graph, GraphPlan& graph_plan) { if (cluster.will_remove) return; cluster.will_remove = true; @@ -433,40 +440,38 @@ namespace vcpkg::Dependencies auto& remove_edges_edges = pair.second.remove_edges; for (auto&& depend : remove_edges_edges) { - auto& depend_cluster = pkg_to_cluster[depend.spec()]; + auto& depend_cluster = graph.get(depend.spec()); graph_plan.remove_graph.add_edge({&cluster}, {&depend_cluster}); - depend_cluster.transient_uninstalled = true; - mark_minus(depend_cluster, pkg_to_cluster, graph_plan); + mark_minus(depend_cluster, graph, graph_plan); } } + + cluster.transient_uninstalled = true; for (auto&& original_feature : cluster.original_features) { - cluster.transient_uninstalled = true; - mark_plus(original_feature, cluster, pkg_to_cluster, graph_plan); + mark_plus(original_feature, cluster, graph, graph_plan); } } - std::vector create_feature_install_plan(const std::unordered_map& map, - const std::vector& specs, - const StatusParagraphs& status_db) + static ClusterGraph create_feature_install_graph(const std::unordered_map& map, + const StatusParagraphs& status_db) { - std::unordered_map pkg_spec_to_package_node; + std::unordered_map graph; for (const auto& it : map) { - Cluster& node = pkg_spec_to_package_node[it.first]; + Cluster& node = graph[it.first]; node.spec = it.first; FeatureNodeEdges core_dependencies; - auto core_depends = filter_dependencies(it.second.core_paragraph->depends, node.spec.triplet()); - core_dependencies.build_edges = FeatureSpec::from_strings_and_triplet(core_depends, node.spec.triplet()); - node.edges["core"] = std::move(core_dependencies); + core_dependencies.build_edges = + filter_dependencies_to_specs(it.second.core_paragraph->depends, node.spec.triplet()); + node.edges.emplace("core", std::move(core_dependencies)); for (const auto& feature : it.second.feature_paragraphs) { FeatureNodeEdges added_edges; - auto depends = filter_dependencies(feature->depends, node.spec.triplet()); - added_edges.build_edges = FeatureSpec::from_strings_and_triplet(depends, node.spec.triplet()); + added_edges.build_edges = filter_dependencies_to_specs(feature->depends, node.spec.triplet()); node.edges.emplace(feature->name, std::move(added_edges)); } node.source_control_file = &it.second; @@ -476,7 +481,7 @@ namespace vcpkg::Dependencies { auto& spec = status_paragraph->package.spec; auto& status_paragraph_feature = status_paragraph->package.feature; - Cluster& cluster = pkg_spec_to_package_node[spec]; + Cluster& cluster = graph[spec]; cluster.transient_uninstalled = false; auto reverse_edges = FeatureSpec::from_strings_and_triplet(status_paragraph->package.depends, @@ -484,7 +489,7 @@ namespace vcpkg::Dependencies for (auto&& dependency : reverse_edges) { - auto pkg_node = pkg_spec_to_package_node.find(dependency.spec()); + auto pkg_node = graph.find(dependency.spec()); auto depends_name = dependency.feature(); if (depends_name == "") { @@ -508,13 +513,20 @@ namespace vcpkg::Dependencies cluster.original_features.insert(status_paragraph_feature); } } + return ClusterGraph(std::move(graph)); + } + + std::vector create_feature_install_plan(const std::unordered_map& map, + const std::vector& specs, + const StatusParagraphs& status_db) + { + ClusterGraph graph = create_feature_install_graph(map, status_db); GraphPlan graph_plan; for (auto&& spec : specs) { - Cluster& spec_cluster = pkg_spec_to_package_node[spec.spec()]; - mark_plus_default(spec_cluster, pkg_spec_to_package_node, graph_plan); - mark_plus(spec.feature(), spec_cluster, pkg_spec_to_package_node, graph_plan); + Cluster& spec_cluster = graph.get(spec.spec()); + mark_plus(spec.feature(), spec_cluster, graph, graph_plan); } Graphs::GraphAdjacencyProvider adjacency_remove_graph(graph_plan.remove_graph.adjacency_list()); -- cgit v1.2.3 From c7de717cbc2b6ab89dc8056984c0a4685e9cf56e Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Sun, 20 Aug 2017 20:06:21 -0700 Subject: [vcpkg] Refactor features implementation. Improve error handling. --- toolsrc/include/vcpkg_Dependencies.h | 48 ------------ toolsrc/src/vcpkg_Dependencies.cpp | 140 ++++++++++++++++++++++++----------- 2 files changed, 98 insertions(+), 90 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg_Dependencies.h b/toolsrc/include/vcpkg_Dependencies.h index 3a81cf27b..9ac52490e 100644 --- a/toolsrc/include/vcpkg_Dependencies.h +++ b/toolsrc/include/vcpkg_Dependencies.h @@ -30,37 +30,6 @@ namespace vcpkg::Dependencies namespace vcpkg::Dependencies { - struct FeatureNodeEdges - { - std::vector remove_edges; - std::vector build_edges; - bool plus = false; - }; - - struct Cluster - { - std::vector status_paragraphs; - Optional source_control_file; - PackageSpec spec; - std::unordered_map edges; - std::unordered_set to_install_features; - std::unordered_set original_features; - bool will_remove = false; - bool transient_uninstalled = true; - Cluster() = default; - - private: - Cluster(const Cluster&) = delete; - Cluster& operator=(const Cluster&) = delete; - }; - - struct ClusterPtr - { - Cluster* ptr; - }; - - bool operator==(const ClusterPtr& l, const ClusterPtr& r); - enum class InstallPlanType { UNKNOWN, @@ -176,24 +145,7 @@ namespace vcpkg::Dependencies std::vector create_export_plan(const VcpkgPaths& paths, const std::vector& specs, const StatusParagraphs& status_db); -} -template<> -struct std::hash -{ - size_t operator()(const vcpkg::Dependencies::ClusterPtr& value) const - { - return std::hash()(value.ptr->spec); - } -}; - -namespace vcpkg::Dependencies -{ - struct GraphPlan - { - Graphs::Graph remove_graph; - Graphs::Graph install_graph; - }; std::vector create_feature_install_plan(const std::unordered_map& map, const std::vector& specs, const StatusParagraphs& status_db); diff --git a/toolsrc/src/vcpkg_Dependencies.cpp b/toolsrc/src/vcpkg_Dependencies.cpp index fa4876bd7..8f92179b5 100644 --- a/toolsrc/src/vcpkg_Dependencies.cpp +++ b/toolsrc/src/vcpkg_Dependencies.cpp @@ -12,11 +12,76 @@ namespace vcpkg::Dependencies { - struct ClusterGraph; - void mark_plus(const std::string& feature, Cluster& cluster, ClusterGraph& pkg_to_cluster, GraphPlan& graph_plan); - void mark_minus(Cluster& cluster, ClusterGraph& pkg_to_cluster, GraphPlan& graph_plan); + struct FeatureNodeEdges + { + std::vector remove_edges; + std::vector build_edges; + bool plus = false; + }; + + struct Cluster + { + std::vector status_paragraphs; + Optional source_control_file; + PackageSpec spec; + std::unordered_map edges; + std::unordered_set to_install_features; + std::unordered_set original_features; + bool will_remove = false; + bool transient_uninstalled = true; + Cluster() = default; + + private: + Cluster(const Cluster&) = delete; + Cluster& operator=(const Cluster&) = delete; + }; + + struct ClusterPtr + { + Cluster* ptr; + }; bool operator==(const ClusterPtr& l, const ClusterPtr& r) { return l.ptr == r.ptr; } +} + +template<> +struct std::hash +{ + size_t operator()(const vcpkg::Dependencies::ClusterPtr& value) const + { + return std::hash()(value.ptr->spec); + } +}; + +namespace vcpkg::Dependencies +{ + struct GraphPlan + { + Graphs::Graph remove_graph; + Graphs::Graph install_graph; + }; + + struct ClusterGraph + { + explicit ClusterGraph(std::unordered_map&& graph) : m_graph(std::move(graph)) {} + ClusterGraph(ClusterGraph&&) = default; + + Cluster& get(const PackageSpec& spec) + { + if (auto p = try_get(spec)) return *p; + Checks::exit_with_message(VCPKG_LINE_INFO, "error: reference to missing package: %s", spec); + } + Cluster* try_get(const PackageSpec& spec) + { + auto it = m_graph.find(spec); + if (it == m_graph.end()) return nullptr; + return &it->second; + } + + private: + ClusterGraph(const ClusterGraph&) = delete; + std::unordered_map m_graph; + }; std::vector AnyParagraph::dependencies(const Triplet& triplet) const { @@ -362,22 +427,8 @@ namespace vcpkg::Dependencies return toposort; } - struct ClusterGraph - { - explicit ClusterGraph(std::unordered_map&& graph) : m_graph(std::move(graph)) {} - ClusterGraph(ClusterGraph&&) = default; - - Cluster& get(const PackageSpec& spec) - { - auto it = m_graph.find(spec); - if (it == m_graph.end()) Checks::unreachable(VCPKG_LINE_INFO); - return it->second; - } - - private: - ClusterGraph(const ClusterGraph&) = delete; - std::unordered_map m_graph; - }; + void mark_plus(const std::string& feature, Cluster& cluster, ClusterGraph& pkg_to_cluster, GraphPlan& graph_plan); + void mark_minus(Cluster& cluster, ClusterGraph& pkg_to_cluster, GraphPlan& graph_plan); void mark_plus(const std::string& feature, Cluster& cluster, ClusterGraph& graph, GraphPlan& graph_plan) { @@ -477,33 +528,18 @@ namespace vcpkg::Dependencies node.source_control_file = &it.second; } - for (auto&& status_paragraph : get_installed_ports(status_db)) + auto installed_ports = get_installed_ports(status_db); + + for (auto&& status_paragraph : installed_ports) { - auto& spec = status_paragraph->package.spec; - auto& status_paragraph_feature = status_paragraph->package.feature; - Cluster& cluster = graph[spec]; + Cluster& cluster = graph[status_paragraph->package.spec]; cluster.transient_uninstalled = false; - auto reverse_edges = FeatureSpec::from_strings_and_triplet(status_paragraph->package.depends, - status_paragraph->package.spec.triplet()); - for (auto&& dependency : reverse_edges) - { - auto pkg_node = graph.find(dependency.spec()); - auto depends_name = dependency.feature(); - if (depends_name == "") - { - for (auto&& default_feature : status_paragraph->package.default_features) - { - auto& target_node = pkg_node->second.edges[default_feature]; - target_node.remove_edges.emplace_back(FeatureSpec{spec, status_paragraph_feature}); - } - depends_name = "core"; - } - auto& target_node = pkg_node->second.edges[depends_name]; - target_node.remove_edges.emplace_back(FeatureSpec{spec, status_paragraph_feature}); - } - cluster.status_paragraphs.emplace_back(*status_paragraph); + cluster.status_paragraphs.emplace_back(status_paragraph); + + auto& status_paragraph_feature = status_paragraph->package.feature; + // In this case, empty string indicates the "core" paragraph for a package. if (status_paragraph_feature == "") { cluster.original_features.insert("core"); @@ -513,6 +549,26 @@ namespace vcpkg::Dependencies cluster.original_features.insert(status_paragraph_feature); } } + + for (auto&& status_paragraph : installed_ports) + { + auto& spec = status_paragraph->package.spec; + auto& status_paragraph_feature = status_paragraph->package.feature; + auto reverse_edges = FeatureSpec::from_strings_and_triplet(status_paragraph->package.depends, + status_paragraph->package.spec.triplet()); + + for (auto&& dependency : reverse_edges) + { + auto dep_cluster = graph.find(dependency.spec()); + if (dep_cluster == graph.end()) Checks::unreachable(VCPKG_LINE_INFO); + + auto depends_name = dependency.feature(); + if (depends_name == "") depends_name = "core"; + + auto& target_node = dep_cluster->second.edges[depends_name]; + target_node.remove_edges.emplace_back(FeatureSpec{spec, status_paragraph_feature}); + } + } return ClusterGraph(std::move(graph)); } -- cgit v1.2.3 From 27be8b5c7489ea52156669f8e556ad3db1fd11d1 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Mon, 21 Aug 2017 17:16:14 -0700 Subject: [vcpkg] Fix feature packages for non-default triplets. Reduce duplication between normal installs and feature installs. --- toolsrc/include/VcpkgPaths.h | 1 + toolsrc/include/vcpkg_Dependencies.h | 17 ++- toolsrc/include/vcpkg_Util.h | 6 +- toolsrc/src/VcpkgPaths.cpp | 1 + toolsrc/src/commands_install.cpp | 269 ++++++++++++++++------------------- toolsrc/src/test_install_plan.cpp | 4 +- toolsrc/src/vcpkg_Dependencies.cpp | 118 ++++++++------- 7 files changed, 207 insertions(+), 209 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/VcpkgPaths.h b/toolsrc/include/VcpkgPaths.h index 95cd4bc28..e4e7ba83d 100644 --- a/toolsrc/include/VcpkgPaths.h +++ b/toolsrc/include/VcpkgPaths.h @@ -21,6 +21,7 @@ namespace vcpkg fs::path package_dir(const PackageSpec& spec) const; fs::path port_dir(const PackageSpec& spec) const; + fs::path port_dir(const std::string& name) const; fs::path build_info_file_path(const PackageSpec& spec) const; fs::path listfile_path(const BinaryParagraph& pgh) const; diff --git a/toolsrc/include/vcpkg_Dependencies.h b/toolsrc/include/vcpkg_Dependencies.h index 9ac52490e..e6c3c55c9 100644 --- a/toolsrc/include/vcpkg_Dependencies.h +++ b/toolsrc/include/vcpkg_Dependencies.h @@ -86,6 +86,9 @@ namespace vcpkg::Dependencies struct AnyAction { + AnyAction(InstallPlanAction&& iplan) : install_plan(std::move(iplan)) {} + AnyAction(RemovePlanAction&& rplan) : remove_plan(std::move(rplan)) {} + Optional install_plan; Optional remove_plan; }; @@ -114,21 +117,21 @@ namespace vcpkg::Dependencies RequestType request_type; }; - __interface PortFileProvider { virtual const SourceControlFile& get_control_file(const PackageSpec& spec) const; }; + __interface PortFileProvider { virtual const SourceControlFile& get_control_file(const std::string& spec) const; }; struct MapPortFile : PortFileProvider { - const std::unordered_map& ports; - explicit MapPortFile(const std::unordered_map& map); - const SourceControlFile& get_control_file(const PackageSpec& spec) const override; + const std::unordered_map& ports; + explicit MapPortFile(const std::unordered_map& map); + const SourceControlFile& get_control_file(const std::string& spec) const override; }; struct PathsPortFile : PortFileProvider { const VcpkgPaths& ports; - mutable std::unordered_map cache; + mutable std::unordered_map cache; explicit PathsPortFile(const VcpkgPaths& paths); - const SourceControlFile& get_control_file(const PackageSpec& spec) const override; + const SourceControlFile& get_control_file(const std::string& spec) const override; private: PathsPortFile(const PathsPortFile&) = delete; @@ -146,7 +149,7 @@ namespace vcpkg::Dependencies const std::vector& specs, const StatusParagraphs& status_db); - std::vector create_feature_install_plan(const std::unordered_map& map, + std::vector create_feature_install_plan(const std::unordered_map& map, const std::vector& specs, const StatusParagraphs& status_db); } diff --git a/toolsrc/include/vcpkg_Util.h b/toolsrc/include/vcpkg_Util.h index 671997e7e..a62b48d54 100644 --- a/toolsrc/include/vcpkg_Util.h +++ b/toolsrc/include/vcpkg_Util.h @@ -7,12 +7,12 @@ namespace vcpkg::Util { template - using FmapOut = decltype(std::declval()(std::declval()[0])); + using FmapOut = decltype(std::declval()(*begin(std::declval()))); template> - std::vector fmap(const Cont& xs, Func&& f) + std::vector fmap(Cont&& xs, Func&& f) { - using O = decltype(f(xs[0])); + using O = decltype(f(*begin(xs))); std::vector ret; ret.reserve(xs.size()); diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp index 60204bcdd..4be636650 100644 --- a/toolsrc/src/VcpkgPaths.cpp +++ b/toolsrc/src/VcpkgPaths.cpp @@ -214,6 +214,7 @@ namespace vcpkg fs::path VcpkgPaths::package_dir(const PackageSpec& spec) const { return this->packages / spec.dir(); } fs::path VcpkgPaths::port_dir(const PackageSpec& spec) const { return this->ports / spec.name(); } + fs::path VcpkgPaths::port_dir(const std::string& name) const { return this->ports / name; } fs::path VcpkgPaths::build_info_file_path(const PackageSpec& spec) const { diff --git a/toolsrc/src/commands_install.cpp b/toolsrc/src/commands_install.cpp index 3fc0e2563..9e37dc057 100644 --- a/toolsrc/src/commands_install.cpp +++ b/toolsrc/src/commands_install.cpp @@ -13,11 +13,7 @@ namespace vcpkg::Commands::Install { - using Dependencies::InstallPlanAction; - using Dependencies::InstallPlanType; - using Dependencies::RemovePlanAction; - using Dependencies::RemovePlanType; - using Dependencies::RequestType; + using namespace Dependencies; InstallDir InstallDir::from_destination_root(const fs::path& destination_root, const std::string& destination_subdirectory, @@ -176,41 +172,6 @@ namespace vcpkg::Commands::Install return SortedVector(std::move(installed_files)); } - static void print_plan(const std::map>& group_by_plan_type) - { - static constexpr std::array order = { - InstallPlanType::ALREADY_INSTALLED, InstallPlanType::BUILD_AND_INSTALL, InstallPlanType::INSTALL}; - - for (const InstallPlanType plan_type : order) - { - auto it = group_by_plan_type.find(plan_type); - if (it == group_by_plan_type.cend()) - { - continue; - } - - std::vector cont = it->second; - std::sort(cont.begin(), cont.end(), &InstallPlanAction::compare_by_name); - const std::string as_string = Strings::join("\n", cont, [](const InstallPlanAction* p) { - return Dependencies::to_output_string(p->request_type, p->spec.to_string()); - }); - - switch (plan_type) - { - case InstallPlanType::ALREADY_INSTALLED: - System::println("The following packages are already installed:\n%s", as_string); - continue; - case InstallPlanType::BUILD_AND_INSTALL: - System::println("The following packages will be built and installed:\n%s", as_string); - continue; - case InstallPlanType::INSTALL: - System::println("The following packages will be installed:\n%s", as_string); - continue; - default: Checks::unreachable(VCPKG_LINE_INFO); - } - } - } - void install_package(const VcpkgPaths& paths, const BinaryControlFile& bcf, StatusParagraphs* status_db) { const fs::path package_dir = paths.package_dir(bcf.core_paragraph.spec); @@ -383,19 +344,78 @@ namespace vcpkg::Commands::Install Checks::unreachable(VCPKG_LINE_INFO); } - static void print_plan(const std::vector rebuilt_plans, - const std::vector new_plans) + static void print_plan(const std::vector& action_plan, bool is_recursive) { + std::vector remove_plans; + std::vector rebuilt_plans; + std::vector only_install_plans; + std::vector new_plans; + + const bool has_non_user_requested_packages = Util::find_if(action_plan, [](const AnyAction& package) -> bool { + if (auto iplan = package.install_plan.get()) + return iplan->request_type != RequestType::USER_REQUESTED; + else + return false; + }) != action_plan.cend(); + + for (auto&& action : action_plan) + { + if (auto install_action = action.install_plan.get()) + { + // remove plans are guaranteed to come before install plans, so we know the plan will be contained if at + // all. + auto it = Util::find_if( + remove_plans, [&](const RemovePlanAction* plan) { return plan->spec == install_action->spec; }); + if (it != remove_plans.end()) + { + rebuilt_plans.emplace_back(install_action); + } + else + { + if (install_action->plan_type == InstallPlanType::INSTALL) + only_install_plans.emplace_back(install_action); + else + new_plans.emplace_back(install_action); + } + } + else if (auto remove_action = action.remove_plan.get()) + { + remove_plans.emplace_back(remove_action); + } + } + + std::sort(remove_plans.begin(), remove_plans.end(), &RemovePlanAction::compare_by_name); + std::sort(rebuilt_plans.begin(), rebuilt_plans.end(), &InstallPlanAction::compare_by_name); + std::sort(only_install_plans.begin(), only_install_plans.end(), &InstallPlanAction::compare_by_name); + std::sort(new_plans.begin(), new_plans.end(), &InstallPlanAction::compare_by_name); + const std::string rebuilt_string = Strings::join("\n", rebuilt_plans, [](const InstallPlanAction* p) { - return Dependencies::to_output_string(p->request_type, p->displayname()); + return to_output_string(p->request_type, p->displayname()); }); + if (rebuilt_plans.size() > 0) System::println("The following packages will be rebuilt:\n%s", rebuilt_string); const std::string new_string = Strings::join("\n", new_plans, [](const InstallPlanAction* p) { - return Dependencies::to_output_string(p->request_type, p->displayname()); + return to_output_string(p->request_type, p->displayname()); }); + if (new_plans.size() > 0) + System::println("The following packages will be built and installed:\n%s", new_string); - if (rebuilt_plans.size() > 0) System::println("The following packages will be rebuilt:\n%s", rebuilt_string); - if (new_plans.size() > 0) System::println("The following packages will be installed:\n%s", new_string); + const std::string only_install_string = Strings::join("\n", only_install_plans, [](const InstallPlanAction* p) { + return to_output_string(p->request_type, p->displayname()); + }); + if (only_install_plans.size() > 0) + System::println("The following packages will be directly installed:\n%s", only_install_string); + + if (has_non_user_requested_packages) + System::println("Additional packages (*) will be installed to complete this operation."); + + if (remove_plans.size() > 0 && !is_recursive) + { + System::println(System::Color::warning, + "If you are sure you want to rebuild the above packages, run the command with the " + "--recurse option"); + Checks::exit_fail(VCPKG_LINE_INFO); + } } void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) @@ -410,86 +430,81 @@ namespace vcpkg::Commands::Install Commands::Help::create_example_string("install zlib zlib:x64-windows curl boost"); args.check_min_arg_count(1, example); - const std::vector specs = Util::fmap(args.command_arguments, [&](auto&& arg) { - return Input::check_and_get_package_spec(arg, default_triplet, example); + const std::vector specs = Util::fmap(args.command_arguments, [&](auto&& arg) { + return Input::check_and_get_full_package_spec(arg, default_triplet, example); }); + for (auto&& spec : specs) - Input::check_triplet(spec.triplet(), paths); + { + Input::check_triplet(spec.package_spec.triplet(), paths); + if (!spec.features.empty() && !g_feature_packages) + { + Checks::exit_with_message( + VCPKG_LINE_INFO, "Feature packages are experimentally available under the --featurepackages flag."); + } + } const std::unordered_set options = args.check_and_get_optional_command_arguments( {OPTION_DRY_RUN, OPTION_USE_HEAD_VERSION, OPTION_NO_DOWNLOADS, OPTION_RECURSE}); const bool dryRun = options.find(OPTION_DRY_RUN) != options.cend(); const bool use_head_version = options.find(OPTION_USE_HEAD_VERSION) != options.cend(); const bool no_downloads = options.find(OPTION_NO_DOWNLOADS) != options.cend(); - const bool isRecursive = options.find(OPTION_RECURSE) != options.cend(); + const bool is_recursive = options.find(OPTION_RECURSE) != options.cend(); // create the plan StatusParagraphs status_db = database_load_check(paths); + const Build::BuildPackageOptions install_plan_options = {Build::to_use_head_version(use_head_version), + Build::to_allow_downloads(!no_downloads)}; + + std::vector action_plan; + if (g_feature_packages) { - const std::vector full_specs = Util::fmap(args.command_arguments, [&](auto&& arg) { - return Input::check_and_get_full_package_spec(arg, default_triplet, example); - }); - - std::unordered_map scf_map; + std::unordered_map scf_map; auto all_ports = Paragraphs::try_load_all_ports(paths.get_filesystem(), paths.ports); for (auto&& port : all_ports.paragraphs) { - auto pkg_spec = PackageSpec::from_name_and_triplet(port->core_paragraph->name, default_triplet) - .value_or_exit(VCPKG_LINE_INFO); - scf_map[pkg_spec] = std::move(*port); + scf_map[port->core_paragraph->name] = std::move(*port); } - std::vector action_plan = Dependencies::create_feature_install_plan( - scf_map, FullPackageSpec::to_feature_specs(full_specs), status_db); - // install plan will be empty if it is already installed - need to change this at status paragraph part - Checks::check_exit( - VCPKG_LINE_INFO, !action_plan.empty(), "Install plan cannot be empty for feature packages"); - - const Build::BuildPackageOptions install_plan_options = {Build::to_use_head_version(use_head_version), - Build::to_allow_downloads(!no_downloads)}; + action_plan = create_feature_install_plan(scf_map, FullPackageSpec::to_feature_specs(specs), status_db); + } + else + { + Dependencies::PathsPortFile paths_port_file(paths); + auto install_plan = Dependencies::create_install_plan( + paths_port_file, Util::fmap(specs, [](auto&& spec) { return spec.package_spec; }), status_db); - std::vector remove_plans; + action_plan = Util::fmap( + install_plan, [](InstallPlanAction& install_action) { return AnyAction(std::move(install_action)); }); + } - std::vector rebuilt_plans; - std::vector new_plans; + // install plan will be empty if it is already installed - need to change this at status paragraph part + Checks::check_exit(VCPKG_LINE_INFO, !action_plan.empty(), "Install plan cannot be empty"); - // removal will happen before install - for (auto&& action : action_plan) - { - if (auto install_action = action.install_plan.get()) - { - auto it = Util::find_if( - remove_plans, [&](const RemovePlanAction* plan) { return plan->spec == install_action->spec; }); - if (it != remove_plans.end()) - { - rebuilt_plans.emplace_back(install_action); - } - else - { - new_plans.emplace_back(install_action); - } - } - else if (auto remove_action = action.remove_plan.get()) - { - remove_plans.emplace_back(remove_action); - } - } + // log the plan + const std::string specs_string = Strings::join(",", action_plan, [](const AnyAction& action) { + if (auto iaction = action.install_plan.get()) + return iaction->spec.to_string(); + else if (auto raction = action.remove_plan.get()) + return "R$" + raction->spec.to_string(); + Checks::unreachable(VCPKG_LINE_INFO); + }); + Metrics::track_property("installplan", specs_string); - print_plan(rebuilt_plans, new_plans); + print_plan(action_plan, is_recursive); - if (remove_plans.size() > 0 && !isRecursive) - { - System::println(System::Color::warning, - "If you are sure you want to rebuild the above packages, run the command with the " - "--recurse option"); - Checks::exit_fail(VCPKG_LINE_INFO); - } + if (dryRun) + { + Checks::exit_success(VCPKG_LINE_INFO); + } - // execute the plan - for (const Dependencies::AnyAction& any_action : action_plan) + // execute the plan + if (g_feature_packages) + { + for (const auto& action : action_plan) { - if (auto install_action = any_action.install_plan.get()) + if (auto install_action = action.install_plan.get()) { const BuildResult result = perform_install_plan_action(paths, *install_action, install_plan_options, status_db); @@ -499,7 +514,7 @@ namespace vcpkg::Commands::Install Checks::exit_fail(VCPKG_LINE_INFO); } } - else if (auto remove_action = any_action.remove_plan.get()) + else if (auto remove_action = action.remove_plan.get()) { static const std::string OPTION_PURGE = "--purge"; static const std::string OPTION_NO_PURGE = "--no-purge"; @@ -537,50 +552,18 @@ namespace vcpkg::Commands::Install } } } - - Checks::exit_success(VCPKG_LINE_INFO); - } - - Dependencies::PathsPortFile paths_port_file(paths); - std::vector install_plan = - Dependencies::create_install_plan(paths_port_file, specs, status_db); - Checks::check_exit(VCPKG_LINE_INFO, !install_plan.empty(), "Install plan cannot be empty"); - - // log the plan - const std::string specs_string = - Strings::join(",", install_plan, [](const InstallPlanAction& plan) { return plan.spec.to_string(); }); - Metrics::track_property("installplan", specs_string); - - std::map> group_by_plan_type; - Util::group_by(install_plan, &group_by_plan_type, [](const InstallPlanAction& p) { return p.plan_type; }); - print_plan(group_by_plan_type); - - const bool has_non_user_requested_packages = - Util::find_if(install_plan, [](const InstallPlanAction& package) -> bool { - return package.request_type != RequestType::USER_REQUESTED; - }) != install_plan.cend(); - - if (has_non_user_requested_packages) - { - System::println("Additional packages (*) will be installed to complete this operation."); } - - if (dryRun) + else { - Checks::exit_success(VCPKG_LINE_INFO); - } - - const Build::BuildPackageOptions install_plan_options = {Build::to_use_head_version(use_head_version), - Build::to_allow_downloads(!no_downloads)}; - - // execute the plan - for (const InstallPlanAction& action : install_plan) - { - const BuildResult result = perform_install_plan_action(paths, action, install_plan_options, status_db); - if (result != BuildResult::SUCCEEDED) + for (const auto& action : action_plan) { - System::println(Build::create_user_troubleshooting_message(action.spec)); - Checks::exit_fail(VCPKG_LINE_INFO); + const auto& iaction = action.install_plan.value_or_exit(VCPKG_LINE_INFO); + const BuildResult result = perform_install_plan_action(paths, iaction, install_plan_options, status_db); + if (result != BuildResult::SUCCEEDED) + { + System::println(Build::create_user_troubleshooting_message(iaction.spec)); + Checks::exit_fail(VCPKG_LINE_INFO); + } } } diff --git a/toolsrc/src/test_install_plan.cpp b/toolsrc/src/test_install_plan.cpp index f0884c063..939351872 100644 --- a/toolsrc/src/test_install_plan.cpp +++ b/toolsrc/src/test_install_plan.cpp @@ -12,7 +12,7 @@ namespace UnitTest1 { struct PackageSpecMap { - std::unordered_map map; + std::unordered_map map; Triplet triplet; PackageSpecMap(const Triplet& t) { triplet = t; } @@ -24,7 +24,7 @@ namespace UnitTest1 auto spec = PackageSpec::from_name_and_triplet(scf->core_paragraph->name, triplet); Assert::IsTrue(spec.has_value()); - map.emplace(*spec.get(), std::move(*scf.get())); + map.emplace(scf->core_paragraph->name, std::move(*scf.get())); return PackageSpec{*spec.get()}; } PackageSpec set_package_map(std::string source, std::string version, std::string build_depends) diff --git a/toolsrc/src/vcpkg_Dependencies.cpp b/toolsrc/src/vcpkg_Dependencies.cpp index 8f92179b5..abab359bb 100644 --- a/toolsrc/src/vcpkg_Dependencies.cpp +++ b/toolsrc/src/vcpkg_Dependencies.cpp @@ -63,24 +63,51 @@ namespace vcpkg::Dependencies struct ClusterGraph { - explicit ClusterGraph(std::unordered_map&& graph) : m_graph(std::move(graph)) {} + explicit ClusterGraph(std::unordered_map&& ports) + : m_ports(std::move(ports)) + { + } ClusterGraph(ClusterGraph&&) = default; Cluster& get(const PackageSpec& spec) - { - if (auto p = try_get(spec)) return *p; - Checks::exit_with_message(VCPKG_LINE_INFO, "error: reference to missing package: %s", spec); - } - Cluster* try_get(const PackageSpec& spec) { auto it = m_graph.find(spec); - if (it == m_graph.end()) return nullptr; - return &it->second; + if (it == m_graph.end()) + { + // Load on-demand from m_ports + auto it_ports = m_ports.find(spec.name()); + if (it_ports != m_ports.end()) + { + auto& clust = m_graph[spec]; + clust.spec = spec; + cluster_from_scf(*it_ports->second, clust); + return clust; + } + return m_graph[spec]; + } + return it->second; } private: + void cluster_from_scf(const SourceControlFile& scf, Cluster& out_cluster) + { + FeatureNodeEdges core_dependencies; + core_dependencies.build_edges = + filter_dependencies_to_specs(scf.core_paragraph->depends, out_cluster.spec.triplet()); + out_cluster.edges.emplace("core", std::move(core_dependencies)); + + for (const auto& feature : scf.feature_paragraphs) + { + FeatureNodeEdges added_edges; + added_edges.build_edges = filter_dependencies_to_specs(feature->depends, out_cluster.spec.triplet()); + out_cluster.edges.emplace(feature->name, std::move(added_edges)); + } + out_cluster.source_control_file = &scf; + } + ClusterGraph(const ClusterGraph&) = delete; std::unordered_map m_graph; + std::unordered_map m_ports; }; std::vector AnyParagraph::dependencies(const Triplet& triplet) const @@ -243,9 +270,9 @@ namespace vcpkg::Dependencies return left->spec.name() < right->spec.name(); } - MapPortFile::MapPortFile(const std::unordered_map& map) : ports(map) {} + MapPortFile::MapPortFile(const std::unordered_map& map) : ports(map) {} - const SourceControlFile& MapPortFile::get_control_file(const PackageSpec& spec) const + const SourceControlFile& MapPortFile::get_control_file(const std::string& spec) const { auto scf = ports.find(spec); if (scf == ports.end()) @@ -257,9 +284,9 @@ namespace vcpkg::Dependencies PathsPortFile::PathsPortFile(const VcpkgPaths& paths) : ports(paths) {} - const SourceControlFile& PathsPortFile::get_control_file(const PackageSpec& spec) const + const SourceControlFile& PathsPortFile::get_control_file(const std::string& spec) const { - std::unordered_map::iterator cache_it = cache.find(spec); + auto cache_it = cache.find(spec); if (cache_it != cache.end()) { return cache_it->second; @@ -307,7 +334,9 @@ namespace vcpkg::Dependencies auto it = status_db.find_installed(spec); if (it != status_db.end()) return InstallPlanAction{spec, {*it->get(), nullopt, nullopt}, request_type}; return InstallPlanAction{ - spec, {nullopt, nullopt, *port_file_provider.get_control_file(spec).core_paragraph}, request_type}; + spec, + {nullopt, nullopt, *port_file_provider.get_control_file(spec.name()).core_paragraph}, + request_type}; } }; @@ -504,35 +533,19 @@ namespace vcpkg::Dependencies } } - static ClusterGraph create_feature_install_graph(const std::unordered_map& map, + static ClusterGraph create_feature_install_graph(const std::unordered_map& map, const StatusParagraphs& status_db) { - std::unordered_map graph; - - for (const auto& it : map) - { - Cluster& node = graph[it.first]; - - node.spec = it.first; - FeatureNodeEdges core_dependencies; - core_dependencies.build_edges = - filter_dependencies_to_specs(it.second.core_paragraph->depends, node.spec.triplet()); - node.edges.emplace("core", std::move(core_dependencies)); - - for (const auto& feature : it.second.feature_paragraphs) - { - FeatureNodeEdges added_edges; - added_edges.build_edges = filter_dependencies_to_specs(feature->depends, node.spec.triplet()); - node.edges.emplace(feature->name, std::move(added_edges)); - } - node.source_control_file = &it.second; - } + std::unordered_map ptr_map; + for (auto&& p : map) + ptr_map.emplace(p.first, &p.second); + ClusterGraph graph(std::move(ptr_map)); auto installed_ports = get_installed_ports(status_db); for (auto&& status_paragraph : installed_ports) { - Cluster& cluster = graph[status_paragraph->package.spec]; + Cluster& cluster = graph.get(status_paragraph->package.spec); cluster.transient_uninstalled = false; @@ -559,20 +572,19 @@ namespace vcpkg::Dependencies for (auto&& dependency : reverse_edges) { - auto dep_cluster = graph.find(dependency.spec()); - if (dep_cluster == graph.end()) Checks::unreachable(VCPKG_LINE_INFO); + auto& dep_cluster = graph.get(dependency.spec()); auto depends_name = dependency.feature(); if (depends_name == "") depends_name = "core"; - auto& target_node = dep_cluster->second.edges[depends_name]; + auto& target_node = dep_cluster.edges[depends_name]; target_node.remove_edges.emplace_back(FeatureSpec{spec, status_paragraph_feature}); } } - return ClusterGraph(std::move(graph)); + return graph; } - std::vector create_feature_install_plan(const std::unordered_map& map, + std::vector create_feature_install_plan(const std::unordered_map& map, const std::vector& specs, const StatusParagraphs& status_db) { @@ -598,15 +610,13 @@ namespace vcpkg::Dependencies for (auto&& like_cluster : remove_toposort) { auto scf = *like_cluster.ptr->source_control_file.get(); - - AnyAction any_plan; - any_plan.remove_plan = RemovePlanAction{ - PackageSpec::from_name_and_triplet(scf->core_paragraph->name, like_cluster.ptr->spec.triplet()) - .value_or_exit(VCPKG_LINE_INFO), + auto spec = PackageSpec::from_name_and_triplet(scf->core_paragraph->name, like_cluster.ptr->spec.triplet()) + .value_or_exit(VCPKG_LINE_INFO); + install_plan.emplace_back(RemovePlanAction{ + std::move(spec), RemovePlanType::REMOVE, - RequestType::AUTO_SELECTED}; - - install_plan.emplace_back(std::move(any_plan)); + RequestType::AUTO_SELECTED, + }); } for (auto&& like_cluster : insert_toposort) @@ -617,12 +627,12 @@ namespace vcpkg::Dependencies auto pkg_spec = PackageSpec::from_name_and_triplet(scf->core_paragraph->name, like_cluster.ptr->spec.triplet()) .value_or_exit(VCPKG_LINE_INFO); - auto action = - InstallPlanAction{pkg_spec, *scf, like_cluster.ptr->to_install_features, RequestType::AUTO_SELECTED}; - - AnyAction any_plan; - any_plan.install_plan = std::move(action); - install_plan.emplace_back(std::move(any_plan)); + install_plan.emplace_back(InstallPlanAction{ + pkg_spec, + *scf, + like_cluster.ptr->to_install_features, + RequestType::AUTO_SELECTED, + }); } return install_plan; -- cgit v1.2.3 From c0fdbfb2e813a9decd18b5f8373f09c85756d1c0 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 21 Aug 2017 17:19:40 -0700 Subject: Fix detection of 64-bit VSCode --- toolsrc/src/commands_edit.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'toolsrc') diff --git a/toolsrc/src/commands_edit.cpp b/toolsrc/src/commands_edit.cpp index 4e83fcca8..12ddaad77 100644 --- a/toolsrc/src/commands_edit.cpp +++ b/toolsrc/src/commands_edit.cpp @@ -30,6 +30,15 @@ namespace vcpkg::Commands::Edit } } + if (env_EDITOR.empty()) + { + const fs::path CODE_EXE_PATH = System::get_ProgramFiles_platform_bitness() / "Microsoft VS Code/Code.exe"; + if (fs.exists(CODE_EXE_PATH)) + { + env_EDITOR = CODE_EXE_PATH; + } + } + if (env_EDITOR.empty()) { const fs::path CODE_EXE_PATH = System::get_ProgramFiles_32_bit() / "Microsoft VS Code/Code.exe"; -- cgit v1.2.3 From d708484077ef891c5a69e4d9211613dbcfacb91e Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Mon, 21 Aug 2017 20:06:47 -0700 Subject: [vcpkg] Feature packages now include user requested packages even if they are already installed. --- toolsrc/include/vcpkg_Dependencies.h | 12 +++--- toolsrc/include/vcpkg_Util.h | 10 +++++ toolsrc/src/test_install_plan.cpp | 82 ++++++++++++++++++++++++++++++++++++ toolsrc/src/vcpkg_Dependencies.cpp | 81 +++++++++++++++++++---------------- 4 files changed, 144 insertions(+), 41 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg_Dependencies.h b/toolsrc/include/vcpkg_Dependencies.h index e6c3c55c9..bfb452596 100644 --- a/toolsrc/include/vcpkg_Dependencies.h +++ b/toolsrc/include/vcpkg_Dependencies.h @@ -3,6 +3,7 @@ #include "StatusParagraphs.h" #include "VcpkgPaths.h" #include "vcpkg_Graphs.h" +#include "vcpkg_Util.h" #include "vcpkg_optional.h" #include @@ -38,20 +39,21 @@ namespace vcpkg::Dependencies ALREADY_INSTALLED }; - struct InstallPlanAction + struct InstallPlanAction : Util::MoveOnlyBase { static bool compare_by_name(const InstallPlanAction* left, const InstallPlanAction* right); InstallPlanAction(); + + InstallPlanAction::InstallPlanAction(const PackageSpec& spec, + const std::unordered_set& features, + const RequestType& request_type); InstallPlanAction(const PackageSpec& spec, const AnyParagraph& any_paragraph, const RequestType& request_type); InstallPlanAction(const PackageSpec& spec, const SourceControlFile& any_paragraph, const std::unordered_set& features, const RequestType& request_type); - InstallPlanAction(const InstallPlanAction&) = delete; - InstallPlanAction(InstallPlanAction&&) = default; - InstallPlanAction& operator=(const InstallPlanAction&) = delete; - InstallPlanAction& operator=(InstallPlanAction&&) = default; + std::string displayname() const; PackageSpec spec; diff --git a/toolsrc/include/vcpkg_Util.h b/toolsrc/include/vcpkg_Util.h index a62b48d54..da2f8eb69 100644 --- a/toolsrc/include/vcpkg_Util.h +++ b/toolsrc/include/vcpkg_Util.h @@ -62,4 +62,14 @@ namespace vcpkg::Util (*output)[key].push_back(&element); } } + + struct MoveOnlyBase + { + MoveOnlyBase() = default; + MoveOnlyBase(const MoveOnlyBase&) = delete; + MoveOnlyBase(MoveOnlyBase&&) = default; + + MoveOnlyBase& operator=(const MoveOnlyBase&) = delete; + MoveOnlyBase& operator=(MoveOnlyBase&&) = default; + }; } \ No newline at end of file diff --git a/toolsrc/src/test_install_plan.cpp b/toolsrc/src/test_install_plan.cpp index 939351872..d7a5014a9 100644 --- a/toolsrc/src/test_install_plan.cpp +++ b/toolsrc/src/test_install_plan.cpp @@ -6,6 +6,34 @@ using namespace Microsoft::VisualStudio::CppUnitTestFramework; using namespace vcpkg; +namespace Microsoft::VisualStudio::CppUnitTestFramework +{ + template<> + inline std::wstring ToString(const vcpkg::Dependencies::InstallPlanType& t) + { + switch (t) + { + case Dependencies::InstallPlanType::ALREADY_INSTALLED: return L"ALREADY_INSTALLED"; + case Dependencies::InstallPlanType::BUILD_AND_INSTALL: return L"BUILD_AND_INSTALL"; + case Dependencies::InstallPlanType::INSTALL: return L"INSTALL"; + case Dependencies::InstallPlanType::UNKNOWN: return L"UNKNOWN"; + default: return ToString((int)t); + } + } + + template<> + inline std::wstring ToString(const vcpkg::Dependencies::RequestType& t) + { + switch (t) + { + case Dependencies::RequestType::AUTO_SELECTED: return L"AUTO_SELECTED"; + case Dependencies::RequestType::USER_REQUESTED: return L"USER_REQUESTED"; + case Dependencies::RequestType::UNKNOWN: return L"UNKNOWN"; + default: return ToString((int)t); + } + } +} + namespace UnitTest1 { class InstallPlanTests : public TestClass @@ -127,6 +155,60 @@ namespace UnitTest1 Assert::IsTrue(e_pos > g_pos); } + TEST_METHOD(existing_package_scheme) + { + using Pgh = std::unordered_map; + std::vector> status_paragraphs; + status_paragraphs.push_back(std::make_unique(Pgh{{"Package", "a"}, + {"Version", "1"}, + {"Architecture", "x86-windows"}, + {"Multi-Arch", "same"}, + {"Status", "install ok installed"}})); + + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + auto spec_a = FullPackageSpec{spec_map.set_package_map("a", "1", ""), {""}}; + + auto install_plan = + Dependencies::create_feature_install_plan(spec_map.map, + FullPackageSpec::to_feature_specs({spec_a}), + StatusParagraphs(std::move(status_paragraphs))); + + Assert::AreEqual(size_t(1), install_plan.size()); + auto p = install_plan[0].install_plan.get(); + Assert::IsNotNull(p); + Assert::AreEqual("a", p->spec.name().c_str()); + Assert::AreEqual(Dependencies::InstallPlanType::ALREADY_INSTALLED, p->plan_type); + Assert::AreEqual(Dependencies::RequestType::USER_REQUESTED, p->request_type); + } + + TEST_METHOD(user_requested_package_scheme) + { + using Pgh = std::unordered_map; + std::vector> status_paragraphs; + + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + auto spec_a = FullPackageSpec{spec_map.set_package_map("a", "1", "b"), {""}}; + auto spec_b = FullPackageSpec{spec_map.set_package_map("b", "1", ""), {""}}; + + auto install_plan = + Dependencies::create_feature_install_plan(spec_map.map, + FullPackageSpec::to_feature_specs({spec_a}), + StatusParagraphs(std::move(status_paragraphs))); + + Assert::AreEqual(size_t(2), install_plan.size()); + auto p = install_plan[0].install_plan.get(); + Assert::IsNotNull(p); + Assert::AreEqual("b", p->spec.name().c_str()); + Assert::AreEqual(Dependencies::InstallPlanType::BUILD_AND_INSTALL, p->plan_type); + Assert::AreEqual(Dependencies::RequestType::AUTO_SELECTED, p->request_type); + + auto p2 = install_plan[1].install_plan.get(); + Assert::IsNotNull(p2); + Assert::AreEqual("a", p2->spec.name().c_str()); + Assert::AreEqual(Dependencies::InstallPlanType::BUILD_AND_INSTALL, p2->plan_type); + Assert::AreEqual(Dependencies::RequestType::USER_REQUESTED, p2->request_type); + } + TEST_METHOD(long_install_scheme) { using Pgh = std::unordered_map; diff --git a/toolsrc/src/vcpkg_Dependencies.cpp b/toolsrc/src/vcpkg_Dependencies.cpp index abab359bb..8741e520f 100644 --- a/toolsrc/src/vcpkg_Dependencies.cpp +++ b/toolsrc/src/vcpkg_Dependencies.cpp @@ -29,6 +29,7 @@ namespace vcpkg::Dependencies std::unordered_set original_features; bool will_remove = false; bool transient_uninstalled = true; + RequestType request_type = RequestType::AUTO_SELECTED; Cluster() = default; private: @@ -39,6 +40,8 @@ namespace vcpkg::Dependencies struct ClusterPtr { Cluster* ptr; + + Cluster* operator->() { return ptr; } }; bool operator==(const ClusterPtr& l, const ClusterPtr& r) { return l.ptr == r.ptr; } @@ -147,50 +150,44 @@ namespace vcpkg::Dependencies } } - InstallPlanAction::InstallPlanAction() - : spec(), any_paragraph(), plan_type(InstallPlanType::UNKNOWN), request_type(RequestType::UNKNOWN) - { - } + InstallPlanAction::InstallPlanAction() : plan_type(InstallPlanType::UNKNOWN), request_type(RequestType::UNKNOWN) {} InstallPlanAction::InstallPlanAction(const PackageSpec& spec, const SourceControlFile& any_paragraph, const std::unordered_set& features, const RequestType& request_type) - : InstallPlanAction() + : spec(spec), plan_type(InstallPlanType::BUILD_AND_INSTALL), request_type(request_type), feature_list(features) { - this->spec = spec; - this->request_type = request_type; - - this->plan_type = InstallPlanType::BUILD_AND_INSTALL; this->any_paragraph.source_control_file = &any_paragraph; - this->feature_list = features; + } + + InstallPlanAction::InstallPlanAction(const PackageSpec& spec, + const std::unordered_set& features, + const RequestType& request_type) + : spec(spec), plan_type(InstallPlanType::ALREADY_INSTALLED), request_type(request_type), feature_list(features) + { } InstallPlanAction::InstallPlanAction(const PackageSpec& spec, const AnyParagraph& any_paragraph, const RequestType& request_type) - : InstallPlanAction() + : spec(spec), request_type(request_type), any_paragraph(any_paragraph) { - this->spec = spec; - this->request_type = request_type; if (auto p = any_paragraph.status_paragraph.get()) { this->plan_type = InstallPlanType::ALREADY_INSTALLED; - this->any_paragraph.status_paragraph = *p; return; } if (auto p = any_paragraph.binary_paragraph.get()) { this->plan_type = InstallPlanType::INSTALL; - this->any_paragraph.binary_paragraph = *p; return; } if (auto p = any_paragraph.source_paragraph.get()) { this->plan_type = InstallPlanType::BUILD_AND_INSTALL; - this->any_paragraph.source_paragraph = *p; return; } @@ -594,7 +591,9 @@ namespace vcpkg::Dependencies for (auto&& spec : specs) { Cluster& spec_cluster = graph.get(spec.spec()); + spec_cluster.request_type = RequestType::USER_REQUESTED; mark_plus(spec.feature(), spec_cluster, graph, graph_plan); + graph_plan.install_graph.add_vertex(ClusterPtr{&spec_cluster}); } Graphs::GraphAdjacencyProvider adjacency_remove_graph(graph_plan.remove_graph.adjacency_list()); @@ -605,36 +604,46 @@ namespace vcpkg::Dependencies auto insert_vertex_list = graph_plan.install_graph.vertex_list(); auto insert_toposort = Graphs::topological_sort(insert_vertex_list, adjacency_install_graph); - std::vector install_plan; + std::vector plan; - for (auto&& like_cluster : remove_toposort) + for (auto&& p_cluster : remove_toposort) { - auto scf = *like_cluster.ptr->source_control_file.get(); - auto spec = PackageSpec::from_name_and_triplet(scf->core_paragraph->name, like_cluster.ptr->spec.triplet()) + auto scf = *p_cluster->source_control_file.get(); + auto spec = PackageSpec::from_name_and_triplet(scf->core_paragraph->name, p_cluster->spec.triplet()) .value_or_exit(VCPKG_LINE_INFO); - install_plan.emplace_back(RemovePlanAction{ + plan.emplace_back(RemovePlanAction{ std::move(spec), RemovePlanType::REMOVE, - RequestType::AUTO_SELECTED, + p_cluster->request_type, }); } - for (auto&& like_cluster : insert_toposort) + for (auto&& p_cluster : insert_toposort) { - if (!like_cluster.ptr->transient_uninstalled) continue; - - auto scf = *like_cluster.ptr->source_control_file.get(); - auto pkg_spec = - PackageSpec::from_name_and_triplet(scf->core_paragraph->name, like_cluster.ptr->spec.triplet()) - .value_or_exit(VCPKG_LINE_INFO); - install_plan.emplace_back(InstallPlanAction{ - pkg_spec, - *scf, - like_cluster.ptr->to_install_features, - RequestType::AUTO_SELECTED, - }); + if (p_cluster->transient_uninstalled) + { + // If it will be transiently uninstalled, we need to issue a full installation command + auto pscf = p_cluster->source_control_file.value_or_exit(VCPKG_LINE_INFO); + Checks::check_exit(VCPKG_LINE_INFO, pscf != nullptr); + plan.emplace_back(InstallPlanAction{ + p_cluster->spec, + *pscf, + p_cluster->to_install_features, + p_cluster->request_type, + }); + } + else + { + // If the package isn't transitively installed, still include it if the user explicitly requested it + if (p_cluster->request_type != RequestType::USER_REQUESTED) continue; + plan.emplace_back(InstallPlanAction{ + p_cluster->spec, + p_cluster->original_features, + p_cluster->request_type, + }); + } } - return install_plan; + return plan; } } -- cgit v1.2.3 From 6784704638f46d89d01458b1004e588f535958aa Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Mon, 21 Aug 2017 21:08:43 -0700 Subject: [vcpkg] Improve error messages when a feature is requested that doesn't exist. --- toolsrc/include/PackageSpec.h | 2 ++ toolsrc/src/PackageSpec.cpp | 12 +++++++-- toolsrc/src/test_install_plan.cpp | 6 ++--- toolsrc/src/vcpkg_Dependencies.cpp | 53 +++++++++++++++++++++++++++++--------- 4 files changed, 56 insertions(+), 17 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/PackageSpec.h b/toolsrc/include/PackageSpec.h index 8b485316f..c5ce767f9 100644 --- a/toolsrc/include/PackageSpec.h +++ b/toolsrc/include/PackageSpec.h @@ -43,6 +43,8 @@ namespace vcpkg const PackageSpec& spec() const { return m_spec; } + std::string to_string() const; + static std::vector from_strings_and_triplet(const std::vector& depends, const Triplet& t); diff --git a/toolsrc/src/PackageSpec.cpp b/toolsrc/src/PackageSpec.cpp index a5d40e998..a43bc5ff5 100644 --- a/toolsrc/src/PackageSpec.cpp +++ b/toolsrc/src/PackageSpec.cpp @@ -13,6 +13,12 @@ namespace vcpkg return (c == '-') || isdigit(c) || (isalpha(c) && islower(c)) || (c == '[') || (c == ']'); } + std::string FeatureSpec::to_string() const + { + if (feature().empty()) return spec().to_string(); + return Strings::format("%s[%s]:%s", name(), feature(), triplet()); + } + std::vector FeatureSpec::from_strings_and_triplet(const std::vector& depends, const Triplet& triplet) { @@ -36,8 +42,10 @@ namespace vcpkg } else { - Checks::exit_with_message( - VCPKG_LINE_INFO, "error while parsing feature list: %s: %s", to_string(maybe_spec.error()), depend); + Checks::exit_with_message(VCPKG_LINE_INFO, + "error while parsing feature list: %s: %s", + vcpkg::to_string(maybe_spec.error()), + depend); } } return f_specs; diff --git a/toolsrc/src/test_install_plan.cpp b/toolsrc/src/test_install_plan.cpp index d7a5014a9..1c415f273 100644 --- a/toolsrc/src/test_install_plan.cpp +++ b/toolsrc/src/test_install_plan.cpp @@ -537,9 +537,9 @@ namespace UnitTest1 remove_plan_check(&install_plan[1], "b"); // TODO: order here may change but A < X, and B anywhere - features_check(&install_plan[2], "a", {"core"}); - features_check(&install_plan[3], "x", {"core"}); - features_check(&install_plan[4], "b", {"core", "1"}); + features_check(&install_plan[2], "b", {"core", "1"}); + features_check(&install_plan[3], "a", {"core"}); + features_check(&install_plan[4], "x", {"core"}); } TEST_METHOD(basic_feature_test_8) diff --git a/toolsrc/src/vcpkg_Dependencies.cpp b/toolsrc/src/vcpkg_Dependencies.cpp index 8741e520f..512e65e28 100644 --- a/toolsrc/src/vcpkg_Dependencies.cpp +++ b/toolsrc/src/vcpkg_Dependencies.cpp @@ -453,23 +453,30 @@ namespace vcpkg::Dependencies return toposort; } - void mark_plus(const std::string& feature, Cluster& cluster, ClusterGraph& pkg_to_cluster, GraphPlan& graph_plan); + enum class MarkPlusResult + { + FEATURE_NOT_FOUND, + SUCCESS, + }; + + MarkPlusResult mark_plus(const std::string& feature, + Cluster& cluster, + ClusterGraph& pkg_to_cluster, + GraphPlan& graph_plan); void mark_minus(Cluster& cluster, ClusterGraph& pkg_to_cluster, GraphPlan& graph_plan); - void mark_plus(const std::string& feature, Cluster& cluster, ClusterGraph& graph, GraphPlan& graph_plan) + MarkPlusResult mark_plus(const std::string& feature, Cluster& cluster, ClusterGraph& graph, GraphPlan& graph_plan) { if (feature == "") { // Indicates that core was not specified in the reference return mark_plus("core", cluster, graph, graph_plan); } + auto it = cluster.edges.find(feature); - if (it == cluster.edges.end()) - { - Checks::unreachable(VCPKG_LINE_INFO); - } + if (it == cluster.edges.end()) return MarkPlusResult::FEATURE_NOT_FOUND; - if (cluster.edges[feature].plus) return; + if (cluster.edges[feature].plus) return MarkPlusResult::SUCCESS; if (cluster.original_features.find(feature) == cluster.original_features.end()) { @@ -478,7 +485,7 @@ namespace vcpkg::Dependencies if (!cluster.transient_uninstalled) { - return; + return MarkPlusResult::SUCCESS; } cluster.edges[feature].plus = true; @@ -494,16 +501,28 @@ namespace vcpkg::Dependencies if (feature != "core") { // All features implicitly depend on core - mark_plus("core", cluster, graph, graph_plan); + auto res = mark_plus("core", cluster, graph, graph_plan); + + // Should be impossible for "core" to not exist + Checks::check_exit(VCPKG_LINE_INFO, res == MarkPlusResult::SUCCESS); } for (auto&& depend : cluster.edges[feature].build_edges) { auto& depend_cluster = graph.get(depend.spec()); - mark_plus(depend.feature(), depend_cluster, graph, graph_plan); + auto res = mark_plus(depend.feature(), depend_cluster, graph, graph_plan); + + Checks::check_exit(VCPKG_LINE_INFO, + res == MarkPlusResult::SUCCESS, + "Error: Unable to satisfy dependency %s of %s", + depend, + FeatureSpec(cluster.spec, feature)); + if (&depend_cluster == &cluster) continue; graph_plan.install_graph.add_edge({&cluster}, {&depend_cluster}); } + + return MarkPlusResult::SUCCESS; } void mark_minus(Cluster& cluster, ClusterGraph& graph, GraphPlan& graph_plan) @@ -526,7 +545,13 @@ namespace vcpkg::Dependencies cluster.transient_uninstalled = true; for (auto&& original_feature : cluster.original_features) { - mark_plus(original_feature, cluster, graph, graph_plan); + auto res = mark_plus(original_feature, cluster, graph, graph_plan); + if (res != MarkPlusResult::SUCCESS) + { + System::println(System::Color::warning, + "Warning: could not reinstall feature %s", + FeatureSpec{cluster.spec, original_feature}); + } } } @@ -592,7 +617,11 @@ namespace vcpkg::Dependencies { Cluster& spec_cluster = graph.get(spec.spec()); spec_cluster.request_type = RequestType::USER_REQUESTED; - mark_plus(spec.feature(), spec_cluster, graph, graph_plan); + auto res = mark_plus(spec.feature(), spec_cluster, graph, graph_plan); + + Checks::check_exit( + VCPKG_LINE_INFO, res == MarkPlusResult::SUCCESS, "Error: Unable to locate feature %s", spec); + graph_plan.install_graph.add_vertex(ClusterPtr{&spec_cluster}); } -- cgit v1.2.3 From ca5c3899b4bd4cbd480103c889363227e23ad2f7 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 22 Aug 2017 12:42:43 -0700 Subject: Update CHANGELOG and bump version to v0.0.84 --- toolsrc/VERSION.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/VERSION.txt b/toolsrc/VERSION.txt index 6320e715f..fef58cb81 100644 --- a/toolsrc/VERSION.txt +++ b/toolsrc/VERSION.txt @@ -1 +1 @@ -"0.0.83" \ No newline at end of file +"0.0.84" \ No newline at end of file -- cgit v1.2.3 From bee29497f9e210c2b8d33edccba0d1d95188d852 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Tue, 22 Aug 2017 15:03:42 -0700 Subject: [vcpkg] Compact tests for improved maintainability. --- toolsrc/src/test_install_plan.cpp | 421 +++++++++++++------------------------- 1 file changed, 142 insertions(+), 279 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/test_install_plan.cpp b/toolsrc/src/test_install_plan.cpp index 1c415f273..836ff09ae 100644 --- a/toolsrc/src/test_install_plan.cpp +++ b/toolsrc/src/test_install_plan.cpp @@ -38,28 +38,30 @@ namespace UnitTest1 { class InstallPlanTests : public TestClass { - struct PackageSpecMap + static std::unique_ptr make_control_file( + const char* name, + const char* depends, + const std::vector>& features = {}) { - std::unordered_map map; - Triplet triplet; - PackageSpecMap(const Triplet& t) { triplet = t; } - - PackageSpec get_package_spec(std::vector>&& fields) - { - auto m_pgh = vcpkg::SourceControlFile::parse_control_file(std::move(fields)); - Assert::IsTrue(m_pgh.has_value()); - auto& scf = *m_pgh.get(); - - auto spec = PackageSpec::from_name_and_triplet(scf->core_paragraph->name, triplet); - Assert::IsTrue(spec.has_value()); - map.emplace(scf->core_paragraph->name, std::move(*scf.get())); - return PackageSpec{*spec.get()}; - } - PackageSpec set_package_map(std::string source, std::string version, std::string build_depends) + using Pgh = std::unordered_map; + std::vector scf_pghs; + scf_pghs.push_back(Pgh{ + {"Source", name}, + {"Version", "0"}, + {"Build-Depends", depends}, + }); + for (auto&& feature : features) { - return get_package_spec({{{"Source", source}, {"Version", version}, {"Build-Depends", build_depends}}}); + scf_pghs.push_back(Pgh{ + {"Feature", feature.first}, + {"Description", "feature"}, + {"Build-Depends", feature.second}, + }); } - }; + auto m_pgh = vcpkg::SourceControlFile::parse_control_file(std::move(scf_pghs)); + Assert::IsTrue(m_pgh.has_value()); + return std::move(*m_pgh.get()); + } static void features_check(Dependencies::AnyAction* install_action, std::string pkg_name, @@ -96,14 +98,58 @@ namespace UnitTest1 Assert::AreEqual(pkg_name.c_str(), plan.spec.name().c_str()); } + static std::unique_ptr make_status_pgh(const char* name, const char* depends = "") + { + using Pgh = std::unordered_map; + return std::make_unique(Pgh{{"Package", name}, + {"Version", "1"}, + {"Architecture", "x86-windows"}, + {"Multi-Arch", "same"}, + {"Depends", depends}, + {"Status", "install ok installed"}}); + } + static std::unique_ptr make_status_feature_pgh(const char* name, + const char* feature, + const char* depends = "") + { + using Pgh = std::unordered_map; + return std::make_unique(Pgh{{"Package", name}, + {"Version", "1"}, + {"Feature", feature}, + {"Architecture", "x86-windows"}, + {"Multi-Arch", "same"}, + {"Depends", depends}, + {"Status", "install ok installed"}}); + } + struct PackageSpecMap + { + std::unordered_map map; + Triplet triplet; + PackageSpecMap(const Triplet& t) { triplet = t; } + + PackageSpec emplace(const char* name, + const char* depends = "", + const std::vector>& features = {}) + { + return emplace(std::move(*make_control_file(name, depends, features))); + } + PackageSpec emplace(vcpkg::SourceControlFile&& scf) + { + auto spec = PackageSpec::from_name_and_triplet(scf.core_paragraph->name, triplet); + Assert::IsTrue(spec.has_value()); + map.emplace(scf.core_paragraph->name, std::move(scf)); + return PackageSpec{*spec.get()}; + } + }; + TEST_METHOD(basic_install_scheme) { std::vector> status_paragraphs; PackageSpecMap spec_map(Triplet::X86_WINDOWS); - auto spec_a = spec_map.set_package_map("a", "1.2.8", "b"); - auto spec_b = spec_map.set_package_map("b", "1.3", "c"); - auto spec_c = spec_map.set_package_map("c", "2.5.3", ""); + auto spec_a = spec_map.emplace("a", "b"); + auto spec_b = spec_map.emplace("b", "c"); + auto spec_c = spec_map.emplace("c"); auto map_port = Dependencies::MapPortFile(spec_map.map); auto install_plan = @@ -120,14 +166,14 @@ namespace UnitTest1 std::vector> status_paragraphs; PackageSpecMap spec_map(Triplet::X86_WINDOWS); - auto spec_a = spec_map.set_package_map("a", "1.2.8", "d"); - auto spec_b = spec_map.set_package_map("b", "1.3", "d, e"); - auto spec_c = spec_map.set_package_map("c", "2.5.3", "e, h"); - auto spec_d = spec_map.set_package_map("d", "4.0", "f, g, h"); - auto spec_e = spec_map.set_package_map("e", "1.0", "g"); - auto spec_f = spec_map.set_package_map("f", "1.0", ""); - auto spec_g = spec_map.set_package_map("g", "1.0", ""); - auto spec_h = spec_map.set_package_map("h", "1.0", ""); + auto spec_a = spec_map.emplace("a", "d"); + auto spec_b = spec_map.emplace("b", "d, e"); + auto spec_c = spec_map.emplace("c", "e, h"); + auto spec_d = spec_map.emplace("d", "f, g, h"); + auto spec_e = spec_map.emplace("e", "g"); + auto spec_f = spec_map.emplace("f"); + auto spec_g = spec_map.emplace("g"); + auto spec_h = spec_map.emplace("h"); auto map_port = Dependencies::MapPortFile(spec_map.map); auto install_plan = Dependencies::create_install_plan( @@ -157,16 +203,11 @@ namespace UnitTest1 TEST_METHOD(existing_package_scheme) { - using Pgh = std::unordered_map; std::vector> status_paragraphs; - status_paragraphs.push_back(std::make_unique(Pgh{{"Package", "a"}, - {"Version", "1"}, - {"Architecture", "x86-windows"}, - {"Multi-Arch", "same"}, - {"Status", "install ok installed"}})); + status_paragraphs.push_back(make_status_pgh("a")); PackageSpecMap spec_map(Triplet::X86_WINDOWS); - auto spec_a = FullPackageSpec{spec_map.set_package_map("a", "1", ""), {""}}; + auto spec_a = FullPackageSpec{spec_map.emplace("a")}; auto install_plan = Dependencies::create_feature_install_plan(spec_map.map, @@ -183,12 +224,11 @@ namespace UnitTest1 TEST_METHOD(user_requested_package_scheme) { - using Pgh = std::unordered_map; std::vector> status_paragraphs; PackageSpecMap spec_map(Triplet::X86_WINDOWS); - auto spec_a = FullPackageSpec{spec_map.set_package_map("a", "1", "b"), {""}}; - auto spec_b = FullPackageSpec{spec_map.set_package_map("b", "1", ""), {""}}; + auto spec_a = FullPackageSpec{spec_map.emplace("a", "b")}; + auto spec_b = FullPackageSpec{spec_map.emplace("b")}; auto install_plan = Dependencies::create_feature_install_plan(spec_map.map, @@ -211,33 +251,22 @@ namespace UnitTest1 TEST_METHOD(long_install_scheme) { - using Pgh = std::unordered_map; std::vector> status_paragraphs; - status_paragraphs.push_back(std::make_unique(Pgh{{"Package", "j"}, - {"Version", "1.2.8"}, - {"Architecture", "x86-windows"}, - {"Multi-Arch", "same"}, - {"Depends", "k"}, - {"Status", "install ok installed"}})); - status_paragraphs.push_back(std::make_unique(Pgh{{"Package", "k"}, - {"Version", "1.2.8"}, - {"Architecture", "x86-windows"}, - {"Multi-Arch", "same"}, - {"Depends", ""}, - {"Status", "install ok installed"}})); + status_paragraphs.push_back(make_status_pgh("j", "k")); + status_paragraphs.push_back(make_status_pgh("k")); PackageSpecMap spec_map(Triplet::X86_WINDOWS); - auto spec_a = spec_map.set_package_map("a", "1.2.8", "b, c, d, e, f, g, h, j, k"); - auto spec_b = spec_map.set_package_map("b", "1.2.8", "c, d, e, f, g, h, j, k"); - auto spec_c = spec_map.set_package_map("c", "1.2.8", "d, e, f, g, h, j, k"); - auto spec_d = spec_map.set_package_map("d", "1.2.8", "e, f, g, h, j, k"); - auto spec_e = spec_map.set_package_map("e", "1.2.8", "f, g, h, j, k"); - auto spec_f = spec_map.set_package_map("f", "1.2.8", "g, h, j, k"); - auto spec_g = spec_map.set_package_map("g", "1.2.8", "h, j, k"); - auto spec_h = spec_map.set_package_map("h", "1.2.8", "j, k"); - auto spec_j = spec_map.set_package_map("j", "1.2.8", "k"); - auto spec_k = spec_map.set_package_map("k", "1.2.8", ""); + auto spec_a = spec_map.emplace("a", "b, c, d, e, f, g, h, j, k"); + auto spec_b = spec_map.emplace("b", "c, d, e, f, g, h, j, k"); + auto spec_c = spec_map.emplace("c", "d, e, f, g, h, j, k"); + auto spec_d = spec_map.emplace("d", "e, f, g, h, j, k"); + auto spec_e = spec_map.emplace("e", "f, g, h, j, k"); + auto spec_f = spec_map.emplace("f", "g, h, j, k"); + auto spec_g = spec_map.emplace("g", "h, j, k"); + auto spec_h = spec_map.emplace("h", "j, k"); + auto spec_j = spec_map.emplace("j", "k"); + auto spec_k = spec_map.emplace("k"); auto map_port = Dependencies::MapPortFile(spec_map.map); auto install_plan = @@ -256,45 +285,14 @@ namespace UnitTest1 TEST_METHOD(basic_feature_test_1) { - using Pgh = std::unordered_map; - std::vector> status_paragraphs; - status_paragraphs.push_back(std::make_unique(Pgh{{"Package", "a"}, - {"Default-Features", ""}, - {"Version", "1.3.8"}, - {"Architecture", "x86-windows"}, - {"Multi-Arch", "same"}, - {"Depends", "b, b[beefeatureone]"}, - {"Status", "install ok installed"}})); - status_paragraphs.push_back(std::make_unique(Pgh{{"Package", "b"}, - {"Feature", "beefeatureone"}, - {"Architecture", "x86-windows"}, - {"Multi-Arch", "same"}, - {"Depends", ""}, - {"Status", "install ok installed"}})); - status_paragraphs.push_back(std::make_unique(Pgh{{"Package", "b"}, - {"Default-Features", "beefeatureone"}, - {"Version", "1.3"}, - {"Architecture", "x86-windows"}, - {"Multi-Arch", "same"}, - {"Depends", ""}, - {"Status", "install ok installed"}})); + status_paragraphs.push_back(make_status_pgh("a", "b, b[b1]")); + status_paragraphs.push_back(make_status_pgh("b")); + status_paragraphs.push_back(make_status_feature_pgh("b", "b1")); PackageSpecMap spec_map(Triplet::X86_WINDOWS); - auto spec_a = - FullPackageSpec{spec_map.get_package_spec({ - {{"Source", "a"}, {"Version", "1.3.8"}, {"Build-Depends", "b, b[beefeatureone]"}}, - {{"Feature", "featureone"}, - {"Description", "the first feature for a"}, - {"Build-Depends", "b[beefeaturetwo]"}}, - }), - {"featureone"}}; - auto spec_b = FullPackageSpec{spec_map.get_package_spec({ - {{"Source", "b"}, {"Version", "1.3"}, {"Build-Depends", ""}}, - {{"Feature", "beefeatureone"}, {"Description", "the first feature for b"}, {"Build-Depends", ""}}, - {{"Feature", "beefeaturetwo"}, {"Description", "the second feature for b"}, {"Build-Depends", ""}}, - {{"Feature", "beefeaturethree"}, {"Description", "the third feature for b"}, {"Build-Depends", ""}}, - })}; + auto spec_a = FullPackageSpec{spec_map.emplace("a", "b, b[b1]", {{"a1", "b[b2]"}}), {"a1"}}; + auto spec_b = FullPackageSpec{spec_map.emplace("b", "", {{"b1", ""}, {"b2", ""}, {"b3", ""}})}; auto install_plan = Dependencies::create_feature_install_plan(spec_map.map, @@ -304,33 +302,18 @@ namespace UnitTest1 Assert::AreEqual(size_t(4), install_plan.size()); remove_plan_check(&install_plan[0], "a"); remove_plan_check(&install_plan[1], "b"); - features_check(&install_plan[2], "b", {"beefeatureone", "core", "beefeatureone"}); - features_check(&install_plan[3], "a", {"featureone", "core"}); + features_check(&install_plan[2], "b", {"b1", "core", "b1"}); + features_check(&install_plan[3], "a", {"a1", "core"}); } TEST_METHOD(basic_feature_test_2) { - using Pgh = std::unordered_map; - std::vector> status_paragraphs; PackageSpecMap spec_map(Triplet::X86_WINDOWS); - auto spec_a = - FullPackageSpec{spec_map.get_package_spec( - {{{"Source", "a"}, {"Version", "1.3.8"}, {"Build-Depends", "b[beefeatureone]"}}, - {{"Feature", "featureone"}, - {"Description", "the first feature for a"}, - {"Build-Depends", "b[beefeaturetwo]"}} - - }), - {"featureone"}}; - auto spec_b = FullPackageSpec{spec_map.get_package_spec({ - {{"Source", "b"}, {"Version", "1.3"}, {"Build-Depends", ""}}, - {{"Feature", "beefeatureone"}, {"Description", "the first feature for b"}, {"Build-Depends", ""}}, - {{"Feature", "beefeaturetwo"}, {"Description", "the second feature for b"}, {"Build-Depends", ""}}, - {{"Feature", "beefeaturethree"}, {"Description", "the third feature for b"}, {"Build-Depends", ""}}, - })}; + auto spec_a = FullPackageSpec{spec_map.emplace("a", "b[b1]", {{"a1", "b[b2]"}}), {"a1"}}; + auto spec_b = FullPackageSpec{spec_map.emplace("b", "", {{"b1", ""}, {"b2", ""}, {"b3", ""}})}; auto install_plan = Dependencies::create_feature_install_plan(spec_map.map, @@ -338,37 +321,20 @@ namespace UnitTest1 StatusParagraphs(std::move(status_paragraphs))); Assert::AreEqual(size_t(2), install_plan.size()); - features_check(&install_plan[0], "b", {"beefeatureone", "beefeaturetwo", "core"}); - features_check(&install_plan[1], "a", {"featureone", "core"}); + features_check(&install_plan[0], "b", {"b1", "b2", "core"}); + features_check(&install_plan[1], "a", {"a1", "core"}); } TEST_METHOD(basic_feature_test_3) { - using Pgh = std::unordered_map; - std::vector> status_paragraphs; - status_paragraphs.push_back(std::make_unique(Pgh{{"Package", "a"}, - {"Default-Features", ""}, - {"Version", "1.3"}, - {"Architecture", "x86-windows"}, - {"Multi-Arch", "same"}, - {"Depends", ""}, - {"Status", "install ok installed"}})); + status_paragraphs.push_back(make_status_pgh("a")); PackageSpecMap spec_map(Triplet::X86_WINDOWS); - auto spec_a = FullPackageSpec{ - spec_map.get_package_spec( - {{{"Source", "a"}, {"Version", "1.3"}, {"Build-Depends", "b"}}, - {{"Feature", "one"}, {"Description", "the first feature for a"}, {"Build-Depends", ""}}}), - {"core"}}; - auto spec_b = FullPackageSpec{spec_map.get_package_spec({ - {{"Source", "b"}, {"Version", "1.3"}, {"Build-Depends", ""}}, - })}; - auto spec_c = FullPackageSpec{spec_map.get_package_spec({ - {{"Source", "c"}, {"Version", "1.3"}, {"Build-Depends", "a[one]"}}, - }), - {"core"}}; + auto spec_a = FullPackageSpec{spec_map.emplace("a", "b", {{"a1", ""}}), {"core"}}; + auto spec_b = FullPackageSpec{spec_map.emplace("b")}; + auto spec_c = FullPackageSpec{spec_map.emplace("c", "a[a1]"), {"core"}}; auto install_plan = Dependencies::create_feature_install_plan(spec_map.map, @@ -378,43 +344,21 @@ namespace UnitTest1 Assert::AreEqual(size_t(4), install_plan.size()); remove_plan_check(&install_plan[0], "a"); features_check(&install_plan[1], "b", {"core"}); - features_check(&install_plan[2], "a", {"one", "core"}); + features_check(&install_plan[2], "a", {"a1", "core"}); features_check(&install_plan[3], "c", {"core"}); } TEST_METHOD(basic_feature_test_4) { - using Pgh = std::unordered_map; - std::vector> status_paragraphs; - status_paragraphs.push_back(std::make_unique(Pgh{{"Package", "a"}, - {"Default-Features", ""}, - {"Version", "1.3"}, - {"Architecture", "x86-windows"}, - {"Multi-Arch", "same"}, - {"Depends", ""}, - {"Status", "install ok installed"}})); - status_paragraphs.push_back(std::make_unique(Pgh{{"Package", "a"}, - {"Feature", "one"}, - {"Architecture", "x86-windows"}, - {"Multi-Arch", "same"}, - {"Depends", ""}, - {"Status", "install ok installed"}})); + status_paragraphs.push_back(make_status_pgh("a")); + status_paragraphs.push_back(make_status_feature_pgh("a", "a1", "")); PackageSpecMap spec_map(Triplet::X86_WINDOWS); - auto spec_a = FullPackageSpec{ - spec_map.get_package_spec( - {{{"Source", "a"}, {"Version", "1.3"}, {"Build-Depends", "b"}}, - {{"Feature", "one"}, {"Description", "the first feature for a"}, {"Build-Depends", ""}}}), - }; - auto spec_b = FullPackageSpec{spec_map.get_package_spec({ - {{"Source", "b"}, {"Version", "1.3"}, {"Build-Depends", ""}}, - })}; - auto spec_c = FullPackageSpec{spec_map.get_package_spec({ - {{"Source", "c"}, {"Version", "1.3"}, {"Build-Depends", "a[one]"}}, - }), - {"core"}}; + auto spec_a = FullPackageSpec{spec_map.emplace("a", "b", {{"a1", ""}})}; + auto spec_b = FullPackageSpec{spec_map.emplace("b")}; + auto spec_c = FullPackageSpec{spec_map.emplace("c", "a[a1]"), {"core"}}; auto install_plan = Dependencies::create_feature_install_plan(spec_map.map, @@ -427,24 +371,13 @@ namespace UnitTest1 TEST_METHOD(basic_feature_test_5) { - using Pgh = std::unordered_map; - std::vector> status_paragraphs; PackageSpecMap spec_map(Triplet::X86_WINDOWS); - auto spec_a = FullPackageSpec{ - spec_map.get_package_spec( - {{{"Source", "a"}, {"Version", "1.3"}, {"Build-Depends", ""}}, - {{"Feature", "1"}, {"Description", "the first feature for a"}, {"Build-Depends", "b[1]"}}, - {{"Feature", "2"}, {"Description", "the second feature for a"}, {"Build-Depends", "b[2]"}}, - {{"Feature", "3"}, {"Description", "the third feature for a"}, {"Build-Depends", "a[2]"}}}), - {"3"}}; - auto spec_b = FullPackageSpec{spec_map.get_package_spec({ - {{"Source", "b"}, {"Version", "1.3"}, {"Build-Depends", ""}}, - {{"Feature", "1"}, {"Description", "the first feature for b"}, {"Build-Depends", ""}}, - {{"Feature", "2"}, {"Description", "the second feature for b"}, {"Build-Depends", ""}}, - })}; + auto spec_a = + FullPackageSpec{spec_map.emplace("a", "", {{"a1", "b[b1]"}, {"a2", "b[b2]"}, {"a3", "a[a2]"}}), {"a3"}}; + auto spec_b = FullPackageSpec{spec_map.emplace("b", "", {{"b1", ""}, {"b2", ""}})}; auto install_plan = Dependencies::create_feature_install_plan(spec_map.map, @@ -452,34 +385,18 @@ namespace UnitTest1 StatusParagraphs(std::move(status_paragraphs))); Assert::AreEqual(size_t(2), install_plan.size()); - features_check(&install_plan[0], "b", {"core", "2"}); - features_check(&install_plan[1], "a", {"core", "3", "2"}); + features_check(&install_plan[0], "b", {"core", "b2"}); + features_check(&install_plan[1], "a", {"core", "a3", "a2"}); } TEST_METHOD(basic_feature_test_6) { - using Pgh = std::unordered_map; - std::vector> status_paragraphs; - status_paragraphs.push_back(std::make_unique(Pgh{{"Package", "b"}, - {"Default-Features", ""}, - {"Version", "1.3"}, - {"Architecture", "x86-windows"}, - {"Multi-Arch", "same"}, - {"Depends", ""}, - {"Status", "install ok installed"}})); - PackageSpecMap spec_map(Triplet::X86_WINDOWS); + status_paragraphs.push_back(make_status_pgh("b")); - auto spec_a = FullPackageSpec{spec_map.get_package_spec({ - {{"Source", "a"}, {"Version", "1.3"}, {"Build-Depends", "b[core]"}}, - }), - {"core"}}; - auto spec_b = FullPackageSpec{ - spec_map.get_package_spec({ - {{"Source", "b"}, {"Version", "1.3"}, {"Build-Depends", ""}}, - {{"Feature", "1"}, {"Description", "the first feature for a"}, {"Build-Depends", ""}}, - }), - {"1"}}; + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + auto spec_a = FullPackageSpec{spec_map.emplace("a", "b[core]"), {"core"}}; + auto spec_b = FullPackageSpec{spec_map.emplace("b", "", {{"b1", ""}}), {"b1"}}; auto install_plan = Dependencies::create_feature_install_plan(spec_map.map, @@ -488,44 +405,21 @@ namespace UnitTest1 Assert::AreEqual(size_t(3), install_plan.size()); remove_plan_check(&install_plan[0], "b"); - features_check(&install_plan[1], "b", {"core", "1"}); + features_check(&install_plan[1], "b", {"core", "b1"}); features_check(&install_plan[2], "a", {"core"}); } TEST_METHOD(basic_feature_test_7) { - using Pgh = std::unordered_map; - std::vector> status_paragraphs; - status_paragraphs.push_back(std::make_unique(Pgh{{"Package", "x"}, - {"Default-Features", ""}, - {"Version", "1.3"}, - {"Architecture", "x86-windows"}, - {"Multi-Arch", "same"}, - {"Depends", "b"}, - {"Status", "install ok installed"}})); - status_paragraphs.push_back(std::make_unique(Pgh{{"Package", "b"}, - {"Default-Features", ""}, - {"Version", "1.3"}, - {"Architecture", "x86-windows"}, - {"Multi-Arch", "same"}, - {"Depends", ""}, - {"Status", "install ok installed"}})); + status_paragraphs.push_back(make_status_pgh("x", "b")); + status_paragraphs.push_back(make_status_pgh("b")); + PackageSpecMap spec_map(Triplet::X86_WINDOWS); - auto spec_a = FullPackageSpec{spec_map.get_package_spec({ - {{"Source", "a"}, {"Version", "1.3"}, {"Build-Depends", ""}}, - })}; - auto spec_x = FullPackageSpec{spec_map.get_package_spec({ - {{"Source", "x"}, {"Version", "1.3"}, {"Build-Depends", "a"}}, - }), - {"core"}}; - auto spec_b = FullPackageSpec{ - spec_map.get_package_spec({ - {{"Source", "b"}, {"Version", "1.3"}, {"Build-Depends", ""}, {"Default-Features", ""}}, - {{"Feature", "1"}, {"Description", "the first feature for a"}, {"Build-Depends", ""}}, - }), - {"1"}}; + auto spec_a = FullPackageSpec{spec_map.emplace("a")}; + auto spec_x = FullPackageSpec{spec_map.emplace("x", "a"), {"core"}}; + auto spec_b = FullPackageSpec{spec_map.emplace("b", "", {{"b1", ""}}), {"b1"}}; auto install_plan = Dependencies::create_feature_install_plan(spec_map.map, @@ -537,59 +431,28 @@ namespace UnitTest1 remove_plan_check(&install_plan[1], "b"); // TODO: order here may change but A < X, and B anywhere - features_check(&install_plan[2], "b", {"core", "1"}); + features_check(&install_plan[2], "b", {"core", "b1"}); features_check(&install_plan[3], "a", {"core"}); features_check(&install_plan[4], "x", {"core"}); } TEST_METHOD(basic_feature_test_8) { - using Pgh = std::unordered_map; - std::vector> status_paragraphs; - status_paragraphs.push_back(std::make_unique(Pgh{{"Package", "a"}, - {"Default-Features", ""}, - {"Version", "1.3"}, - {"Architecture", "x64-windows"}, - {"Multi-Arch", "same"}, - {"Depends", ""}, - {"Status", "install ok installed"}})); - status_paragraphs.push_back(std::make_unique(Pgh{{"Package", "a"}, - {"Default-Features", ""}, - {"Version", "1.3"}, - {"Architecture", "x86-windows"}, - {"Multi-Arch", "same"}, - {"Depends", ""}, - {"Status", "install ok installed"}})); + status_paragraphs.push_back(make_status_pgh("a")); + status_paragraphs.push_back(make_status_pgh("a")); + status_paragraphs.back()->package.spec = + PackageSpec::from_name_and_triplet("a", Triplet::X64_WINDOWS).value_or_exit(VCPKG_LINE_INFO); PackageSpecMap spec_map(Triplet::X64_WINDOWS); - - auto spec_a_64 = FullPackageSpec{ - spec_map.get_package_spec( - {{{"Source", "a"}, {"Version", "1.3"}, {"Build-Depends", "b"}}, - {{"Feature", "one"}, {"Description", "the first feature for a"}, {"Build-Depends", ""}}}), - {"core"}}; - auto spec_b_64 = FullPackageSpec{spec_map.get_package_spec({ - {{"Source", "b"}, {"Version", "1.3"}, {"Build-Depends", ""}}, - })}; - auto spec_c_64 = FullPackageSpec{spec_map.get_package_spec({ - {{"Source", "c"}, {"Version", "1.3"}, {"Build-Depends", "a[one]"}}, - }), - {"core"}}; + auto spec_a_64 = FullPackageSpec{spec_map.emplace("a", "b", {{"a1", ""}}), {"core"}}; + auto spec_b_64 = FullPackageSpec{spec_map.emplace("b")}; + auto spec_c_64 = FullPackageSpec{spec_map.emplace("c", "a[a1]"), {"core"}}; spec_map.triplet = Triplet::X86_WINDOWS; - auto spec_a_86 = FullPackageSpec{ - spec_map.get_package_spec( - {{{"Source", "a"}, {"Version", "1.3"}, {"Build-Depends", "b"}}, - {{"Feature", "one"}, {"Description", "the first feature for a"}, {"Build-Depends", ""}}}), - {"core"}}; - auto spec_b_86 = FullPackageSpec{spec_map.get_package_spec({ - {{"Source", "b"}, {"Version", "1.3"}, {"Build-Depends", ""}}, - })}; - auto spec_c_86 = FullPackageSpec{spec_map.get_package_spec({ - {{"Source", "c"}, {"Version", "1.3"}, {"Build-Depends", "a[one]"}}, - }), - {"core"}}; + auto spec_a_86 = FullPackageSpec{spec_map.emplace("a", "b", {{"a1", ""}}), {"core"}}; + auto spec_b_86 = FullPackageSpec{spec_map.emplace("b")}; + auto spec_c_86 = FullPackageSpec{spec_map.emplace("c", "a[a1]"), {"core"}}; auto install_plan = Dependencies::create_feature_install_plan( spec_map.map, @@ -613,10 +476,10 @@ namespace UnitTest1 remove_plan_check(&install_plan[0], "a", Triplet::X64_WINDOWS); remove_plan_check(&install_plan[1], "a"); features_check(&install_plan[2], "b", {"core"}, Triplet::X64_WINDOWS); - features_check(&install_plan[3], "a", {"one", "core"}, Triplet::X64_WINDOWS); + features_check(&install_plan[3], "a", {"a1", "core"}, Triplet::X64_WINDOWS); features_check(&install_plan[4], "c", {"core"}, Triplet::X64_WINDOWS); features_check(&install_plan[5], "b", {"core"}); - features_check(&install_plan[6], "a", {"one", "core"}); + features_check(&install_plan[6], "a", {"a1", "core"}); features_check(&install_plan[7], "c", {"core"}); } }; -- cgit v1.2.3 From 92dd1b77ed043da376c86874aacc1233270fedae Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Tue, 22 Aug 2017 15:14:15 -0700 Subject: [vcpkg] Add Util::ResourceBase, use MoveOnlyBase --- toolsrc/include/vcpkg_Dependencies.h | 20 ++++---------------- toolsrc/include/vcpkg_Util.h | 10 ++++++++++ toolsrc/src/test_install_plan.cpp | 6 +++--- toolsrc/src/vcpkg_Dependencies.cpp | 11 ++--------- 4 files changed, 19 insertions(+), 28 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg_Dependencies.h b/toolsrc/include/vcpkg_Dependencies.h index bfb452596..93719efe9 100644 --- a/toolsrc/include/vcpkg_Dependencies.h +++ b/toolsrc/include/vcpkg_Dependencies.h @@ -70,16 +70,12 @@ namespace vcpkg::Dependencies REMOVE }; - struct RemovePlanAction + struct RemovePlanAction : Util::MoveOnlyBase { static bool compare_by_name(const RemovePlanAction* left, const RemovePlanAction* right); RemovePlanAction(); RemovePlanAction(const PackageSpec& spec, const RemovePlanType& plan_type, const RequestType& request_type); - RemovePlanAction(const RemovePlanAction&) = delete; - RemovePlanAction(RemovePlanAction&&) = default; - RemovePlanAction& operator=(const RemovePlanAction&) = delete; - RemovePlanAction& operator=(RemovePlanAction&&) = default; PackageSpec spec; RemovePlanType plan_type; @@ -102,16 +98,12 @@ namespace vcpkg::Dependencies ALREADY_BUILT }; - struct ExportPlanAction + struct ExportPlanAction : Util::MoveOnlyBase { static bool compare_by_name(const ExportPlanAction* left, const ExportPlanAction* right); ExportPlanAction(); ExportPlanAction(const PackageSpec& spec, const AnyParagraph& any_paragraph, const RequestType& request_type); - ExportPlanAction(const ExportPlanAction&) = delete; - ExportPlanAction(ExportPlanAction&&) = default; - ExportPlanAction& operator=(const ExportPlanAction&) = delete; - ExportPlanAction& operator=(ExportPlanAction&&) = default; PackageSpec spec; AnyParagraph any_paragraph; @@ -121,23 +113,19 @@ namespace vcpkg::Dependencies __interface PortFileProvider { virtual const SourceControlFile& get_control_file(const std::string& spec) const; }; - struct MapPortFile : PortFileProvider + struct MapPortFile : Util::ResourceBase, PortFileProvider { const std::unordered_map& ports; explicit MapPortFile(const std::unordered_map& map); const SourceControlFile& get_control_file(const std::string& spec) const override; }; - struct PathsPortFile : PortFileProvider + struct PathsPortFile : Util::ResourceBase, PortFileProvider { const VcpkgPaths& ports; mutable std::unordered_map cache; explicit PathsPortFile(const VcpkgPaths& paths); const SourceControlFile& get_control_file(const std::string& spec) const override; - - private: - PathsPortFile(const PathsPortFile&) = delete; - PathsPortFile& operator=(const PathsPortFile&) = delete; }; std::vector create_install_plan(const PortFileProvider& port_file_provider, diff --git a/toolsrc/include/vcpkg_Util.h b/toolsrc/include/vcpkg_Util.h index da2f8eb69..4f45cd2c7 100644 --- a/toolsrc/include/vcpkg_Util.h +++ b/toolsrc/include/vcpkg_Util.h @@ -72,4 +72,14 @@ namespace vcpkg::Util MoveOnlyBase& operator=(const MoveOnlyBase&) = delete; MoveOnlyBase& operator=(MoveOnlyBase&&) = default; }; + + struct ResourceBase + { + ResourceBase() = default; + ResourceBase(const ResourceBase&) = delete; + ResourceBase(ResourceBase&&) = delete; + + ResourceBase& operator=(const ResourceBase&) = delete; + ResourceBase& operator=(ResourceBase&&) = delete; + }; } \ No newline at end of file diff --git a/toolsrc/src/test_install_plan.cpp b/toolsrc/src/test_install_plan.cpp index 836ff09ae..6c9311264 100644 --- a/toolsrc/src/test_install_plan.cpp +++ b/toolsrc/src/test_install_plan.cpp @@ -151,7 +151,7 @@ namespace UnitTest1 auto spec_b = spec_map.emplace("b", "c"); auto spec_c = spec_map.emplace("c"); - auto map_port = Dependencies::MapPortFile(spec_map.map); + Dependencies::MapPortFile map_port(spec_map.map); auto install_plan = Dependencies::create_install_plan(map_port, {spec_a}, StatusParagraphs(std::move(status_paragraphs))); @@ -175,7 +175,7 @@ namespace UnitTest1 auto spec_g = spec_map.emplace("g"); auto spec_h = spec_map.emplace("h"); - auto map_port = Dependencies::MapPortFile(spec_map.map); + Dependencies::MapPortFile map_port(spec_map.map); auto install_plan = Dependencies::create_install_plan( map_port, {spec_a, spec_b, spec_c}, StatusParagraphs(std::move(status_paragraphs))); @@ -268,7 +268,7 @@ namespace UnitTest1 auto spec_j = spec_map.emplace("j", "k"); auto spec_k = spec_map.emplace("k"); - auto map_port = Dependencies::MapPortFile(spec_map.map); + Dependencies::MapPortFile map_port(spec_map.map); auto install_plan = Dependencies::create_install_plan(map_port, {spec_a}, StatusParagraphs(std::move(status_paragraphs))); diff --git a/toolsrc/src/vcpkg_Dependencies.cpp b/toolsrc/src/vcpkg_Dependencies.cpp index 512e65e28..188b0f444 100644 --- a/toolsrc/src/vcpkg_Dependencies.cpp +++ b/toolsrc/src/vcpkg_Dependencies.cpp @@ -19,7 +19,7 @@ namespace vcpkg::Dependencies bool plus = false; }; - struct Cluster + struct Cluster : Util::MoveOnlyBase { std::vector status_paragraphs; Optional source_control_file; @@ -30,11 +30,6 @@ namespace vcpkg::Dependencies bool will_remove = false; bool transient_uninstalled = true; RequestType request_type = RequestType::AUTO_SELECTED; - Cluster() = default; - - private: - Cluster(const Cluster&) = delete; - Cluster& operator=(const Cluster&) = delete; }; struct ClusterPtr @@ -64,13 +59,12 @@ namespace vcpkg::Dependencies Graphs::Graph install_graph; }; - struct ClusterGraph + struct ClusterGraph : Util::MoveOnlyBase { explicit ClusterGraph(std::unordered_map&& ports) : m_ports(std::move(ports)) { } - ClusterGraph(ClusterGraph&&) = default; Cluster& get(const PackageSpec& spec) { @@ -108,7 +102,6 @@ namespace vcpkg::Dependencies out_cluster.source_control_file = &scf; } - ClusterGraph(const ClusterGraph&) = delete; std::unordered_map m_graph; std::unordered_map m_ports; }; -- cgit v1.2.3 From 687ea82f89504520e2a4c60feeb5c0bf6260a4de Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Tue, 22 Aug 2017 15:59:27 -0700 Subject: [vcpkg] Improve formatting of search and list. Fix gl2ps version. --- toolsrc/include/vcpkglib.h | 2 +- toolsrc/src/commands_list.cpp | 10 +++++----- toolsrc/src/commands_search.cpp | 10 +++++----- toolsrc/src/vcpkglib.cpp | 5 +++-- 4 files changed, 14 insertions(+), 13 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkglib.h b/toolsrc/include/vcpkglib.h index bd2400b77..63b358d74 100644 --- a/toolsrc/include/vcpkglib.h +++ b/toolsrc/include/vcpkglib.h @@ -36,5 +36,5 @@ namespace vcpkg const fs::path& cmake_script, const std::vector& pass_variables); - std::string shorten_description(const std::string& desc); + std::string shorten_text(const std::string& desc, size_t length); } // namespace vcpkg diff --git a/toolsrc/src/commands_list.cpp b/toolsrc/src/commands_list.cpp index 9bc9bcc08..3cfa7e184 100644 --- a/toolsrc/src/commands_list.cpp +++ b/toolsrc/src/commands_list.cpp @@ -12,14 +12,14 @@ namespace vcpkg::Commands::List { if (FullDesc) { - System::println("%-27s %-16s %s", pgh.package.displayname(), pgh.package.version, pgh.package.description); + System::println("%-30s %-16s %s", pgh.package.displayname(), pgh.package.version, pgh.package.description); } else { - System::println("%-27s %-16s %s", - pgh.package.displayname(), - pgh.package.version, - vcpkg::shorten_description(pgh.package.description)); + System::println("%-30s %-16s %s", + vcpkg::shorten_text(pgh.package.displayname(), 30), + vcpkg::shorten_text(pgh.package.version, 16), + vcpkg::shorten_text(pgh.package.description, 71)); } } diff --git a/toolsrc/src/commands_search.cpp b/toolsrc/src/commands_search.cpp index f12c25fb6..b1bd7ea6f 100644 --- a/toolsrc/src/commands_search.cpp +++ b/toolsrc/src/commands_search.cpp @@ -57,9 +57,9 @@ namespace vcpkg::Commands::Search else { System::println("%-20s %-16s %s", - source_paragraph.name, - source_paragraph.version, - vcpkg::shorten_description(source_paragraph.description)); + vcpkg::shorten_text(source_paragraph.name, 20), + vcpkg::shorten_text(source_paragraph.version, 16), + vcpkg::shorten_text(source_paragraph.description, 81)); } } @@ -72,8 +72,8 @@ namespace vcpkg::Commands::Search else { System::println("%-37s %s", - name + "[" + feature_paragraph.name + "]", - vcpkg::shorten_description(feature_paragraph.description)); + vcpkg::shorten_text(name + "[" + feature_paragraph.name + "]", 37), + vcpkg::shorten_text(feature_paragraph.description, 81)); } } diff --git a/toolsrc/src/vcpkglib.cpp b/toolsrc/src/vcpkglib.cpp index 428ae090d..6e90695de 100644 --- a/toolsrc/src/vcpkglib.cpp +++ b/toolsrc/src/vcpkglib.cpp @@ -240,9 +240,10 @@ namespace vcpkg LR"("%s" %s -P "%s")", cmake_exe.native(), cmd_cmake_pass_variables, cmake_script.generic_wstring()); } - std::string shorten_description(const std::string& desc) + std::string shorten_text(const std::string& desc, size_t length) { + Checks::check_exit(VCPKG_LINE_INFO, length >= 3); auto simple_desc = std::regex_replace(desc, std::regex("\\s+"), " "); - return simple_desc.size() <= 52 ? simple_desc : simple_desc.substr(0, 49) + "..."; + return simple_desc.size() <= length ? simple_desc : simple_desc.substr(0, length - 3) + "..."; } } -- cgit v1.2.3 From 57d078e8d1c5f5284d88e79600aa61fa06530ac4 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 22 Aug 2017 18:25:35 -0700 Subject: [vcpkg edit] Add option --buildtrees --- toolsrc/src/commands_edit.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/commands_edit.cpp b/toolsrc/src/commands_edit.cpp index 12ddaad77..72005a461 100644 --- a/toolsrc/src/commands_edit.cpp +++ b/toolsrc/src/commands_edit.cpp @@ -8,11 +8,14 @@ namespace vcpkg::Commands::Edit { void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { + static const std::string OPTION_BUILDTREES = "--buildtrees"; + 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::unordered_set options = + args.check_and_get_optional_command_arguments({OPTION_BUILDTREES}); const std::string port_name = args.command_arguments.at(0); const fs::path portpath = paths.ports / port_name; @@ -84,6 +87,14 @@ namespace vcpkg::Commands::Edit VCPKG_LINE_INFO, "Visual Studio Code was not found and the environment variable EDITOR is not set"); } + if (options.find(OPTION_BUILDTREES) != options.cend()) + { + const auto buildtrees_current_dir = paths.buildtrees / port_name; + + std::wstring cmdLine = Strings::wformat(LR"("%s" "%s" -n)", env_EDITOR, buildtrees_current_dir.native()); + Checks::exit_with_code(VCPKG_LINE_INFO, System::cmd_execute(cmdLine)); + } + std::wstring cmdLine = Strings::wformat( LR"("%s" "%s" "%s" -n)", env_EDITOR, portpath.native(), (portpath / "portfile.cmake").native()); Checks::exit_with_code(VCPKG_LINE_INFO, System::cmd_execute(cmdLine)); -- cgit v1.2.3 From 14a99b073059d4fcae149a9085254fcb2e78e443 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Wed, 23 Aug 2017 15:47:42 -0700 Subject: [vcpkg] Deduplicate code from feature packages --- toolsrc/include/vcpkg_Build.h | 1 + toolsrc/include/vcpkg_Commands.h | 12 +++- toolsrc/include/vcpkg_Dependencies.h | 2 +- toolsrc/include/vcpkg_Util.h | 19 ++++++- toolsrc/src/commands_export.cpp | 15 +++-- toolsrc/src/commands_install.cpp | 107 +++++++++++++++++------------------ toolsrc/src/vcpkg_Dependencies.cpp | 30 ++++------ 7 files changed, 99 insertions(+), 87 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg_Build.h b/toolsrc/include/vcpkg_Build.h index c4f3e6746..32909f4e1 100644 --- a/toolsrc/include/vcpkg_Build.h +++ b/toolsrc/include/vcpkg_Build.h @@ -52,6 +52,7 @@ namespace vcpkg::Build SUCCEEDED, BUILD_FAILED, POST_BUILD_CHECKS_FAILED, + FILE_CONFLICTS, CASCADED_DUE_TO_MISSING_DEPENDENCIES }; diff --git a/toolsrc/include/vcpkg_Commands.h b/toolsrc/include/vcpkg_Commands.h index d5f316d69..756a12f01 100644 --- a/toolsrc/include/vcpkg_Commands.h +++ b/toolsrc/include/vcpkg_Commands.h @@ -55,12 +55,18 @@ namespace vcpkg::Commands const Build::BuildPackageOptions& install_plan_options, StatusParagraphs& status_db); + enum class InstallResult + { + FILE_CONFLICTS, + SUCCESS, + }; + void install_files_and_write_listfile(Files::Filesystem& fs, const fs::path& source_dir, const InstallDir& dirs); - void install_package(const VcpkgPaths& paths, - const BinaryControlFile& binary_paragraph, - StatusParagraphs* status_db); + InstallResult install_package(const VcpkgPaths& paths, + const BinaryControlFile& binary_paragraph, + StatusParagraphs* status_db); void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet); } diff --git a/toolsrc/include/vcpkg_Dependencies.h b/toolsrc/include/vcpkg_Dependencies.h index 93719efe9..c1f6ad9a5 100644 --- a/toolsrc/include/vcpkg_Dependencies.h +++ b/toolsrc/include/vcpkg_Dependencies.h @@ -23,7 +23,7 @@ namespace vcpkg::Dependencies std::vector dependencies(const Triplet& triplet) const; Optional status_paragraph; - Optional binary_paragraph; + Optional binary_control_file; Optional source_paragraph; Optional source_control_file; }; diff --git a/toolsrc/include/vcpkg_Util.h b/toolsrc/include/vcpkg_Util.h index 4f45cd2c7..cfbd23020 100644 --- a/toolsrc/include/vcpkg_Util.h +++ b/toolsrc/include/vcpkg_Util.h @@ -12,9 +12,7 @@ namespace vcpkg::Util template> std::vector fmap(Cont&& xs, Func&& f) { - using O = decltype(f(*begin(xs))); - - std::vector ret; + std::vector ret; ret.reserve(xs.size()); for (auto&& x : xs) @@ -23,6 +21,21 @@ namespace vcpkg::Util return ret; } + template + using FmapFlattenOut = std::decay_t()(*begin(std::declval()))))>; + + template> + std::vector fmap_flatten(Cont&& xs, Func&& f) + { + std::vector ret; + + for (auto&& x : xs) + for (auto&& y : f(x)) + ret.push_back(std::move(y)); + + return ret; + } + template void unstable_keep_if(Container& cont, Pred pred) { diff --git a/toolsrc/src/commands_export.cpp b/toolsrc/src/commands_export.cpp index 4adfbc0f6..cbcb219b6 100644 --- a/toolsrc/src/commands_export.cpp +++ b/toolsrc/src/commands_export.cpp @@ -11,10 +11,10 @@ namespace vcpkg::Commands::Export { - using Install::InstallDir; using Dependencies::ExportPlanAction; - using Dependencies::RequestType; using Dependencies::ExportPlanType; + using Dependencies::RequestType; + using Install::InstallDir; static std::string create_nuspec_file_contents(const std::string& raw_exported_dir, const std::string& targets_redirect_path, @@ -235,10 +235,15 @@ namespace vcpkg::Commands::Export const auto options = args.check_and_get_optional_command_arguments( { - OPTION_DRY_RUN, OPTION_RAW, OPTION_NUGET, OPTION_ZIP, OPTION_7ZIP, + OPTION_DRY_RUN, + OPTION_RAW, + OPTION_NUGET, + OPTION_ZIP, + OPTION_7ZIP, }, { - OPTION_NUGET_ID, OPTION_NUGET_VERSION, + OPTION_NUGET_ID, + OPTION_NUGET_VERSION, }); const bool dryRun = options.switches.find(OPTION_DRY_RUN) != options.switches.cend(); const bool raw = options.switches.find(OPTION_RAW) != options.switches.cend(); @@ -323,7 +328,7 @@ namespace vcpkg::Commands::Export System::println("Exporting package %s... ", display_name); const BinaryParagraph& binary_paragraph = - action.any_paragraph.binary_paragraph.value_or_exit(VCPKG_LINE_INFO); + action.any_paragraph.binary_control_file.value_or_exit(VCPKG_LINE_INFO).core_paragraph; const InstallDir dirs = InstallDir::from_destination_root( raw_exported_dir_path / "installed", action.spec.triplet().to_string(), diff --git a/toolsrc/src/commands_install.cpp b/toolsrc/src/commands_install.cpp index 9e37dc057..43d41bdf8 100644 --- a/toolsrc/src/commands_install.cpp +++ b/toolsrc/src/commands_install.cpp @@ -172,7 +172,7 @@ namespace vcpkg::Commands::Install return SortedVector(std::move(installed_files)); } - void install_package(const VcpkgPaths& paths, const BinaryControlFile& bcf, StatusParagraphs* status_db) + InstallResult install_package(const VcpkgPaths& paths, const BinaryControlFile& bcf, StatusParagraphs* status_db) { const fs::path package_dir = paths.package_dir(bcf.core_paragraph.spec); const Triplet& triplet = bcf.core_paragraph.spec.triplet(); @@ -199,7 +199,7 @@ namespace vcpkg::Commands::Install System::print("\n "); System::println(Strings::join("\n ", intersection)); System::println(""); - Checks::exit_fail(VCPKG_LINE_INFO); + return InstallResult::FILE_CONFLICTS; } StatusParagraph source_paragraph; @@ -239,6 +239,8 @@ namespace vcpkg::Commands::Install write_update(paths, feature_paragraph); status_db->insert(std::make_unique(feature_paragraph)); } + + return InstallResult::SUCCESS; } using Build::BuildResult; @@ -250,6 +252,7 @@ namespace vcpkg::Commands::Install { const InstallPlanType& plan_type = action.plan_type; const std::string display_name = action.spec.to_string(); + const std::string display_name_with_features = g_feature_packages ? action.displayname() : display_name; const bool is_user_requested = action.request_type == RequestType::USER_REQUESTED; const bool use_head_version = to_bool(build_package_options.use_head_version); @@ -257,76 +260,65 @@ namespace vcpkg::Commands::Install if (plan_type == InstallPlanType::ALREADY_INSTALLED) { if (use_head_version && is_user_requested) - { System::println( System::Color::warning, "Package %s is already installed -- not building from HEAD", display_name); - } else - { System::println(System::Color::success, "Package %s is already installed", display_name); - } return BuildResult::SUCCEEDED; } - if (plan_type == InstallPlanType::BUILD_AND_INSTALL && !g_feature_packages) + if (plan_type == InstallPlanType::BUILD_AND_INSTALL) { if (use_head_version) - System::println("Building package %s from HEAD... ", display_name); + System::println("Building package %s from HEAD... ", display_name_with_features); else - System::println("Building package %s... ", display_name); - - const Build::BuildPackageConfig build_config{ - action.any_paragraph.source_paragraph.value_or_exit(VCPKG_LINE_INFO), - action.spec.triplet(), - paths.port_dir(action.spec), - build_package_options}; - const auto result = Build::build_package(paths, build_config, status_db); - if (result.code != Build::BuildResult::SUCCEEDED) - { - System::println(System::Color::error, Build::create_error_message(result.code, action.spec)); - return result.code; - } - System::println("Building package %s... done", display_name); + System::println("Building package %s... ", display_name_with_features); - const BinaryControlFile bpgh = - Paragraphs::try_load_cached_control_package(paths, action.spec).value_or_exit(VCPKG_LINE_INFO); - System::println("Installing package %s... ", display_name); - install_package(paths, bpgh, &status_db); - System::println(System::Color::success, "Installing package %s... done", display_name); - return BuildResult::SUCCEEDED; - } + const auto result = [&]() -> Build::ExtendedBuildResult { + if (g_feature_packages) + { + const Build::BuildPackageConfig build_config{ + *action.any_paragraph.source_control_file.value_or_exit(VCPKG_LINE_INFO), + action.spec.triplet(), + paths.port_dir(action.spec), + build_package_options, + action.feature_list}; + return Build::build_package(paths, build_config, status_db); + } + else + { + const Build::BuildPackageConfig build_config{ + action.any_paragraph.source_paragraph.value_or_exit(VCPKG_LINE_INFO), + action.spec.triplet(), + paths.port_dir(action.spec), + build_package_options}; + return Build::build_package(paths, build_config, status_db); + } + }(); - if (plan_type == InstallPlanType::BUILD_AND_INSTALL && g_feature_packages) - { - const std::string display_name_feature = action.displayname(); - if (use_head_version) - System::println("Building package %s from HEAD... ", display_name_feature); - else - System::println("Building package %s... ", display_name_feature); - - const Build::BuildPackageConfig build_config{ - *action.any_paragraph.source_control_file.value_or_exit(VCPKG_LINE_INFO), - action.spec.triplet(), - paths.port_dir(action.spec), - build_package_options, - action.feature_list}; - const auto result = Build::build_package(paths, build_config, status_db); if (result.code != Build::BuildResult::SUCCEEDED) { System::println(System::Color::error, Build::create_error_message(result.code, action.spec)); return result.code; } - System::println("Building package %s... done", display_name_feature); + + System::println("Building package %s... done", display_name_with_features); const BinaryControlFile bcf = Paragraphs::try_load_cached_control_package(paths, action.spec).value_or_exit(VCPKG_LINE_INFO); - System::println("Installing package %s... ", display_name_feature); - install_package(paths, bcf, &status_db); - System::println(System::Color::success, "Installing package %s... done", display_name_feature); - return BuildResult::SUCCEEDED; + System::println("Installing package %s... ", display_name_with_features); + auto install_result = install_package(paths, bcf, &status_db); + switch (install_result) + { + case InstallResult::SUCCESS: + System::println(System::Color::success, "Installing package %s... done", display_name); + return BuildResult::SUCCEEDED; + case InstallResult::FILE_CONFLICTS: return BuildResult::FILE_CONFLICTS; + default: Checks::unreachable(VCPKG_LINE_INFO); + } } - if (plan_type == InstallPlanType::INSTALL && !g_feature_packages) + if (plan_type == InstallPlanType::INSTALL) { if (use_head_version && is_user_requested) { @@ -334,11 +326,16 @@ namespace vcpkg::Commands::Install System::Color::warning, "Package %s is already built -- not building from HEAD", display_name); } System::println("Installing package %s... ", display_name); - install_package(paths, - BinaryControlFile{action.any_paragraph.binary_paragraph.value_or_exit(VCPKG_LINE_INFO)}, - &status_db); - System::println(System::Color::success, "Installing package %s... done", display_name); - return BuildResult::SUCCEEDED; + auto install_result = install_package( + paths, action.any_paragraph.binary_control_file.value_or_exit(VCPKG_LINE_INFO), &status_db); + switch (install_result) + { + case InstallResult::SUCCESS: + System::println(System::Color::success, "Installing package %s... done", display_name); + return BuildResult::SUCCEEDED; + case InstallResult::FILE_CONFLICTS: return BuildResult::FILE_CONFLICTS; + default: Checks::unreachable(VCPKG_LINE_INFO); + } } Checks::unreachable(VCPKG_LINE_INFO); diff --git a/toolsrc/src/vcpkg_Dependencies.cpp b/toolsrc/src/vcpkg_Dependencies.cpp index 188b0f444..4525fa02a 100644 --- a/toolsrc/src/vcpkg_Dependencies.cpp +++ b/toolsrc/src/vcpkg_Dependencies.cpp @@ -119,9 +119,11 @@ namespace vcpkg::Dependencies return to_package_specs(p->package.depends); } - if (auto p = this->binary_paragraph.get()) + if (auto p = this->binary_control_file.get()) { - return to_package_specs(p->depends); + auto deps = Util::fmap_flatten(p->features, [](const BinaryParagraph& pgh) { return pgh.depends; }); + deps.insert(deps.end(), p->core_paragraph.depends.begin(), p->core_paragraph.depends.end()); + return to_package_specs(deps); } if (auto p = this->source_paragraph.get()) @@ -164,7 +166,7 @@ namespace vcpkg::Dependencies InstallPlanAction::InstallPlanAction(const PackageSpec& spec, const AnyParagraph& any_paragraph, const RequestType& request_type) - : spec(spec), request_type(request_type), any_paragraph(any_paragraph) + : spec(spec), request_type(request_type), plan_type(InstallPlanType::UNKNOWN), any_paragraph(any_paragraph) { if (auto p = any_paragraph.status_paragraph.get()) { @@ -172,7 +174,7 @@ namespace vcpkg::Dependencies return; } - if (auto p = any_paragraph.binary_paragraph.get()) + if (auto p = any_paragraph.binary_control_file.get()) { this->plan_type = InstallPlanType::INSTALL; return; @@ -183,8 +185,6 @@ namespace vcpkg::Dependencies this->plan_type = InstallPlanType::BUILD_AND_INSTALL; return; } - - this->plan_type = InstallPlanType::UNKNOWN; } std::string InstallPlanAction::displayname() const @@ -225,34 +225,24 @@ namespace vcpkg::Dependencies return left->spec.name() < right->spec.name(); } - ExportPlanAction::ExportPlanAction() - : spec(), any_paragraph(), plan_type(ExportPlanType::UNKNOWN), request_type(RequestType::UNKNOWN) - { - } + ExportPlanAction::ExportPlanAction() : plan_type(ExportPlanType::UNKNOWN), request_type(RequestType::UNKNOWN) {} ExportPlanAction::ExportPlanAction(const PackageSpec& spec, const AnyParagraph& any_paragraph, const RequestType& request_type) - : ExportPlanAction() + : spec(spec), any_paragraph(any_paragraph), plan_type(ExportPlanType::UNKNOWN), request_type(request_type) { - this->spec = spec; - this->request_type = request_type; - - if (auto p = any_paragraph.binary_paragraph.get()) + if (auto p = any_paragraph.binary_control_file.get()) { this->plan_type = ExportPlanType::ALREADY_BUILT; - this->any_paragraph.binary_paragraph = *p; return; } if (auto p = any_paragraph.source_paragraph.get()) { this->plan_type = ExportPlanType::PORT_AVAILABLE_BUT_NOT_BUILT; - this->any_paragraph.source_paragraph = *p; return; } - - this->plan_type = ExportPlanType::UNKNOWN; } bool RemovePlanAction::compare_by_name(const RemovePlanAction* left, const RemovePlanAction* right) @@ -428,7 +418,7 @@ namespace vcpkg::Dependencies Expected maybe_bpgh = Paragraphs::try_load_cached_control_package(paths, spec); if (auto bcf = maybe_bpgh.get()) - return ExportPlanAction{spec, {nullopt, bcf->core_paragraph, nullopt}, request_type}; + return ExportPlanAction{spec, AnyParagraph{nullopt, std::move(*bcf), nullopt}, request_type}; auto maybe_scf = Paragraphs::try_load_port(paths.get_filesystem(), paths.port_dir(spec)); if (auto scf = maybe_scf.get()) -- cgit v1.2.3 From 30d2cb9debccf0bcaa1d61cedefae400fdf07951 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Wed, 23 Aug 2017 15:58:05 -0700 Subject: [vcpkg] Install should not list already installed packages as "to be built" --- toolsrc/src/commands_install.cpp | 53 +++++++++++++++++++++++++++++----------- 1 file changed, 39 insertions(+), 14 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/commands_install.cpp b/toolsrc/src/commands_install.cpp index 43d41bdf8..bd14bf7e3 100644 --- a/toolsrc/src/commands_install.cpp +++ b/toolsrc/src/commands_install.cpp @@ -347,6 +347,7 @@ namespace vcpkg::Commands::Install std::vector rebuilt_plans; std::vector only_install_plans; std::vector new_plans; + std::vector already_installed_plans; const bool has_non_user_requested_packages = Util::find_if(action_plan, [](const AnyAction& package) -> bool { if (auto iplan = package.install_plan.get()) @@ -369,10 +370,16 @@ namespace vcpkg::Commands::Install } else { - if (install_action->plan_type == InstallPlanType::INSTALL) - only_install_plans.emplace_back(install_action); - else - new_plans.emplace_back(install_action); + switch (install_action->plan_type) + { + case InstallPlanType::INSTALL: only_install_plans.emplace_back(install_action); break; + case InstallPlanType::ALREADY_INSTALLED: + if (install_action->request_type == RequestType::USER_REQUESTED) + already_installed_plans.emplace_back(install_action); + break; + case InstallPlanType::BUILD_AND_INSTALL: new_plans.emplace_back(install_action); break; + default: Checks::unreachable(VCPKG_LINE_INFO); + } } } else if (auto remove_action = action.remove_plan.get()) @@ -385,23 +392,41 @@ namespace vcpkg::Commands::Install std::sort(rebuilt_plans.begin(), rebuilt_plans.end(), &InstallPlanAction::compare_by_name); std::sort(only_install_plans.begin(), only_install_plans.end(), &InstallPlanAction::compare_by_name); std::sort(new_plans.begin(), new_plans.end(), &InstallPlanAction::compare_by_name); + std::sort(already_installed_plans.begin(), already_installed_plans.end(), &InstallPlanAction::compare_by_name); - const std::string rebuilt_string = Strings::join("\n", rebuilt_plans, [](const InstallPlanAction* p) { - return to_output_string(p->request_type, p->displayname()); - }); - if (rebuilt_plans.size() > 0) System::println("The following packages will be rebuilt:\n%s", rebuilt_string); + if (already_installed_plans.size() > 0) + { + const std::string already_string = + Strings::join("\n", already_installed_plans, [](const InstallPlanAction* p) { + return to_output_string(p->request_type, p->displayname()); + }); + System::println("The following packages are already installed:\n%s", already_string); + } + + if (rebuilt_plans.size() > 0) + { + const std::string rebuilt_string = Strings::join("\n", rebuilt_plans, [](const InstallPlanAction* p) { + return to_output_string(p->request_type, p->displayname()); + }); + System::println("The following packages will be rebuilt:\n%s", rebuilt_string); + } - const std::string new_string = Strings::join("\n", new_plans, [](const InstallPlanAction* p) { - return to_output_string(p->request_type, p->displayname()); - }); if (new_plans.size() > 0) + { + const std::string new_string = Strings::join("\n", new_plans, [](const InstallPlanAction* p) { + return to_output_string(p->request_type, p->displayname()); + }); System::println("The following packages will be built and installed:\n%s", new_string); + } - const std::string only_install_string = Strings::join("\n", only_install_plans, [](const InstallPlanAction* p) { - return to_output_string(p->request_type, p->displayname()); - }); if (only_install_plans.size() > 0) + { + const std::string only_install_string = + Strings::join("\n", only_install_plans, [](const InstallPlanAction* p) { + return to_output_string(p->request_type, p->displayname()); + }); System::println("The following packages will be directly installed:\n%s", only_install_string); + } if (has_non_user_requested_packages) System::println("Additional packages (*) will be installed to complete this operation."); -- cgit v1.2.3 From 3c34cca36adfce1d3388b30e643294be58b3ec8f Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Wed, 23 Aug 2017 16:16:31 -0700 Subject: [vcpkg] Fix typo --- toolsrc/src/commands_remove.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/commands_remove.cpp b/toolsrc/src/commands_remove.cpp index e480f02dd..db5357514 100644 --- a/toolsrc/src/commands_remove.cpp +++ b/toolsrc/src/commands_remove.cpp @@ -151,7 +151,7 @@ namespace vcpkg::Commands::Remove if (specs.empty()) { - System::println(System::Color::success, "There are no oudated packages."); + System::println(System::Color::success, "There are no outdated packages."); Checks::exit_success(VCPKG_LINE_INFO); } } -- cgit v1.2.3 From bed70f54bc2dd7181a54bbbb94d2fe3a1a0b35cc Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Wed, 23 Aug 2017 22:46:28 -0700 Subject: [vcpkg] Add stringify for BuildResult::FILE_CONFLICTS --- toolsrc/include/vcpkg_Build.h | 3 ++- toolsrc/src/vcpkg_Build.cpp | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg_Build.h b/toolsrc/include/vcpkg_Build.h index 32909f4e1..e12ed3b1d 100644 --- a/toolsrc/include/vcpkg_Build.h +++ b/toolsrc/include/vcpkg_Build.h @@ -56,10 +56,11 @@ namespace vcpkg::Build CASCADED_DUE_TO_MISSING_DEPENDENCIES }; - static constexpr std::array BuildResult_values = { + static constexpr std::array BuildResult_values = { BuildResult::SUCCEEDED, BuildResult::BUILD_FAILED, BuildResult::POST_BUILD_CHECKS_FAILED, + BuildResult::FILE_CONFLICTS, BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES}; const std::string& to_string(const BuildResult build_result); diff --git a/toolsrc/src/vcpkg_Build.cpp b/toolsrc/src/vcpkg_Build.cpp index 124efb7f2..ca89ccf37 100644 --- a/toolsrc/src/vcpkg_Build.cpp +++ b/toolsrc/src/vcpkg_Build.cpp @@ -240,6 +240,7 @@ namespace vcpkg::Build static const std::string NULLVALUE_STRING = Enums::nullvalue_to_string("vcpkg::Commands::Build::BuildResult"); static const std::string SUCCEEDED_STRING = "SUCCEEDED"; static const std::string BUILD_FAILED_STRING = "BUILD_FAILED"; + static const std::string FILE_CONFLICTS_STRING = "FILE_CONFLICTS"; static const std::string POST_BUILD_CHECKS_FAILED_STRING = "POST_BUILD_CHECKS_FAILED"; static const std::string CASCADED_DUE_TO_MISSING_DEPENDENCIES_STRING = "CASCADED_DUE_TO_MISSING_DEPENDENCIES"; @@ -250,6 +251,7 @@ namespace vcpkg::Build case BuildResult::BUILD_FAILED: return BUILD_FAILED_STRING; case BuildResult::POST_BUILD_CHECKS_FAILED: return POST_BUILD_CHECKS_FAILED_STRING; case BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES: return CASCADED_DUE_TO_MISSING_DEPENDENCIES_STRING; + case BuildResult::FILE_CONFLICTS: return FILE_CONFLICTS_STRING; default: Checks::unreachable(VCPKG_LINE_INFO); } } -- cgit v1.2.3 From 7dd082cad7b1b8323fb5409399614e8e0f4cddf2 Mon Sep 17 00:00:00 2001 From: Mikhail Paulyshka Date: Thu, 24 Aug 2017 13:26:42 +0300 Subject: [vcpkg] testing for architectures supported by toolset --- toolsrc/include/VcpkgPaths.h | 13 ++++++++++++ toolsrc/include/vcpkg_System.h | 2 ++ toolsrc/src/VcpkgPaths.cpp | 44 +++++++++++++++++++++++++++++++++++++--- toolsrc/src/vcpkg_Build.cpp | 46 +++++++++++++++++++----------------------- toolsrc/src/vcpkg_System.cpp | 14 +++++++++++++ 5 files changed, 91 insertions(+), 28 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/VcpkgPaths.h b/toolsrc/include/VcpkgPaths.h index e4e7ba83d..7964129e5 100644 --- a/toolsrc/include/VcpkgPaths.h +++ b/toolsrc/include/VcpkgPaths.h @@ -8,11 +8,24 @@ namespace vcpkg { + struct ToolsetArchOption + { + CWStringView name; + System::CPUArchitecture host_arch; + System::CPUArchitecture target_arch; + + bool operator==(const ToolsetArchOption& a) const + { + return (name == a.name && host_arch == a.host_arch && target_arch == a.target_arch); + } + }; + struct Toolset { fs::path dumpbin; fs::path vcvarsall; CWStringView version; + std::vector supported_architectures; }; struct VcpkgPaths diff --git a/toolsrc/include/vcpkg_System.h b/toolsrc/include/vcpkg_System.h index 2ea0241f6..32da6e39c 100644 --- a/toolsrc/include/vcpkg_System.h +++ b/toolsrc/include/vcpkg_System.h @@ -77,6 +77,8 @@ namespace vcpkg::System CPUArchitecture get_host_processor(); + std::vector get_supported_host_architectures(); + const fs::path& get_ProgramFiles_32_bit(); const fs::path& get_ProgramFiles_platform_bitness(); diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp index 4be636650..642ca6a9c 100644 --- a/toolsrc/src/VcpkgPaths.cpp +++ b/toolsrc/src/VcpkgPaths.cpp @@ -279,6 +279,8 @@ namespace vcpkg static std::vector find_toolset_instances(const VcpkgPaths& paths) { + using CPU = System::CPUArchitecture; + const auto& fs = paths.get_filesystem(); const std::vector vs2017_installation_instances = get_VS2017_installation_instances(paths); @@ -298,9 +300,27 @@ namespace vcpkg { const fs::path vs2015_dumpbin_exe = *v / "VC" / "bin" / "dumpbin.exe"; paths_examined.push_back(vs2015_dumpbin_exe); + + const fs::path vs2015_bin_dir = vs2015_vcvarsall_bat.parent_path() / "bin"; + std::vector supported_archictectures; + if(fs.exists(vs2015_bin_dir / "vcvars32.bat")) + supported_archictectures.push_back({L"x86", CPU::X86, CPU::X86}); + if (fs.exists(vs2015_bin_dir / "amd64\\vcvars64.bat")) + supported_archictectures.push_back({L"x64", CPU::X64, CPU::X64}); + if (fs.exists(vs2015_bin_dir / "arm\\vcvarsarm.bat")) + supported_archictectures.push_back({L"arm", CPU::ARM, CPU::ARM}); + if (fs.exists(vs2015_bin_dir / "x86_amd64\\vcvarsx86_amd64.bat")) + supported_archictectures.push_back({L"x86_amd64", CPU::X86, CPU::X64}); + if (fs.exists(vs2015_bin_dir / "x86_arm\\vcvarsx86_arm.bat")) + supported_archictectures.push_back({L"x86_arm" , CPU::X86, CPU::ARM}); + if (fs.exists(vs2015_bin_dir / "amd64_x86\\vcvarsamd64_x86.bat")) + supported_archictectures.push_back({L"amd64_x86", CPU::X64, CPU::X86}); + if (fs.exists(vs2015_bin_dir / "amd64_arm\\vcvarsamd64_arm.bat")) + supported_archictectures.push_back({L"amd64_arm", CPU::X64, CPU::ARM}); + if (fs.exists(vs2015_dumpbin_exe)) { - found_toolsets.push_back({vs2015_dumpbin_exe, vs2015_vcvarsall_bat, L"v140"}); + found_toolsets.push_back({vs2015_dumpbin_exe, vs2015_vcvarsall_bat, L"v140", supported_archictectures }); } } } @@ -312,10 +332,28 @@ namespace vcpkg const fs::path vc_dir = instance / "VC"; // Skip any instances that do not have vcvarsall. - const fs::path vcvarsall_bat = vc_dir / "Auxiliary" / "Build" / "vcvarsall.bat"; + const fs::path vcvarsall_dir = vc_dir / "Auxiliary" / "Build"; + const fs::path vcvarsall_bat = vcvarsall_dir / "vcvarsall.bat"; paths_examined.push_back(vcvarsall_bat); if (!fs.exists(vcvarsall_bat)) continue; + //Get all supported architecturs + std::vector supported_architectures; + if (fs.exists(vcvarsall_dir / "vcvars32.bat")) + supported_architectures.push_back({L"x86", CPU::X86,CPU::X86 }); + if (fs.exists(vcvarsall_dir / "vcvars64.bat")) + supported_architectures.push_back({L"amd64", CPU::X64,CPU::X64 }); + if (fs.exists(vcvarsall_dir / "vcvarsarm.bat")) + supported_architectures.push_back({L"arm", CPU::ARM,CPU::ARM }); + if (fs.exists(vcvarsall_dir / "vcvarsx86_amd64.bat")) + supported_architectures.push_back({L"x86_amd64",CPU::X86,CPU::X64 }); + if (fs.exists(vcvarsall_dir / "vcvarsx86_arm.bat")) + supported_architectures.push_back({L"x86_arm", CPU::X86,CPU::ARM }); + if (fs.exists(vcvarsall_dir / "vcvarsamd64_x86.bat")) + supported_architectures.push_back({L"amd64_x86", CPU::X64,CPU::X86 }); + if (fs.exists(vcvarsall_dir / "vcvarsamd64_arm.bat")) + supported_architectures.push_back({L"amd64_arm", CPU::X64,CPU::ARM }); + // Locate the "best" MSVC toolchain version const fs::path msvc_path = vc_dir / "Tools" / "MSVC"; std::vector msvc_subdirectories = fs.get_files_non_recursive(msvc_path); @@ -332,7 +370,7 @@ namespace vcpkg paths_examined.push_back(dumpbin_path); if (fs.exists(dumpbin_path)) { - vs2017_toolset = Toolset{dumpbin_path, vcvarsall_bat, L"v141"}; + vs2017_toolset = Toolset{dumpbin_path, vcvarsall_bat, L"v141", supported_architectures}; break; } } diff --git a/toolsrc/src/vcpkg_Build.cpp b/toolsrc/src/vcpkg_Build.cpp index ca89ccf37..2c9a147a4 100644 --- a/toolsrc/src/vcpkg_Build.cpp +++ b/toolsrc/src/vcpkg_Build.cpp @@ -36,39 +36,35 @@ namespace vcpkg::Build Checks::exit_with_message(VCPKG_LINE_INFO, "Unsupported vcvarsall target %s", cmake_system_name); } - CWStringView to_vcvarsall_toolchain(const std::string& target_architecture) + CWStringView to_vcvarsall_toolchain(const std::string& target_architecture, const Toolset& toolset) { using CPU = System::CPUArchitecture; - struct ArchOption - { - CWStringView name; - CPU host_arch; - CPU target_arch; - }; - - static constexpr ArchOption X86 = {L"x86", CPU::X86, CPU::X86}; - static constexpr ArchOption X86_X64 = {L"x86_x64", CPU::X86, CPU::X64}; - static constexpr ArchOption X86_ARM = {L"x86_arm", CPU::X86, CPU::ARM}; - static constexpr ArchOption X86_ARM64 = {L"x86_arm64", CPU::X86, CPU::ARM64}; - - static constexpr ArchOption X64 = {L"amd64", CPU::X64, CPU::X64}; - static constexpr ArchOption X64_X86 = {L"amd64_x86", CPU::X64, CPU::X86}; - static constexpr ArchOption X64_ARM = {L"amd64_arm", CPU::X64, CPU::ARM}; - static constexpr ArchOption X64_ARM64 = {L"amd64_arm64", CPU::X64, CPU::ARM64}; - - static constexpr std::array VALUES = { + static constexpr ToolsetArchOption X86 = {L"x86", CPU::X86, CPU::X86}; + static constexpr ToolsetArchOption X86_X64 = {L"x86_x64", CPU::X86, CPU::X64}; + static constexpr ToolsetArchOption X86_ARM = {L"x86_arm", CPU::X86, CPU::ARM}; + static constexpr ToolsetArchOption X86_ARM64 = {L"x86_arm64", CPU::X86, CPU::ARM64}; + + static constexpr ToolsetArchOption X64 = {L"amd64", CPU::X64, CPU::X64}; + static constexpr ToolsetArchOption X64_X86 = {L"amd64_x86", CPU::X64, CPU::X86}; + static constexpr ToolsetArchOption X64_ARM = {L"amd64_arm", CPU::X64, CPU::ARM}; + static constexpr ToolsetArchOption X64_ARM64 = {L"amd64_arm64", CPU::X64, CPU::ARM64}; + + static constexpr std::array VALUES = { X86, X86_X64, X86_ARM, X86_ARM64, X64, X64_X86, X64_ARM, X64_ARM64}; auto target_arch = System::to_cpu_architecture(target_architecture); - auto host_arch = System::get_host_processor(); + auto host_architectures = System::get_supported_host_architectures(); for (auto&& value : VALUES) { - if (target_arch == value.target_arch && host_arch == value.host_arch) - { - return value.name; - } + if (target_arch != value.target_arch || + std::find(host_architectures.begin(), host_architectures.end(), value.host_arch) == host_architectures.end() || + std::find(toolset.supported_architectures.begin(), toolset.supported_architectures.end(), value) == toolset.supported_architectures.end() + ) + continue; + + return value.name; } Checks::exit_with_message(VCPKG_LINE_INFO, "Unsupported toolchain combination %s", target_architecture); @@ -82,7 +78,7 @@ namespace vcpkg::Build tonull = L""; } - auto arch = to_vcvarsall_toolchain(pre_build_info.target_architecture); + auto arch = to_vcvarsall_toolchain(pre_build_info.target_architecture, toolset); auto target = to_vcvarsall_target(pre_build_info.cmake_system_name); return Strings::wformat(LR"("%s" %s %s %s 2>&1)", toolset.vcvarsall.native(), arch, target, tonull); diff --git a/toolsrc/src/vcpkg_System.cpp b/toolsrc/src/vcpkg_System.cpp index 883fe6612..3288ec7a2 100644 --- a/toolsrc/src/vcpkg_System.cpp +++ b/toolsrc/src/vcpkg_System.cpp @@ -42,6 +42,20 @@ namespace vcpkg::System return to_cpu_architecture(Strings::to_utf8(procarch)).value_or_exit(VCPKG_LINE_INFO); } + std::vector get_supported_host_architectures() + { + std::vector supported_architectures; + supported_architectures.push_back(get_host_processor()); + + //AMD64 machines support to run x86 applications + if(supported_architectures.back()==CPUArchitecture::X64) + { + supported_architectures.push_back(CPUArchitecture::X86); + } + + return supported_architectures; + } + int cmd_execute_clean(const CWStringView cmd_line) { static const std::wstring system_root = get_environment_variable(L"SystemRoot").value_or_exit(VCPKG_LINE_INFO); -- cgit v1.2.3 From 14f42a66d3e3eca8c2d917fc391a1f8e8bfa7de8 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 24 Aug 2017 12:06:22 -0700 Subject: [Strings::format] Add overload for unisigned long --- toolsrc/include/vcpkg_Strings.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg_Strings.h b/toolsrc/include/vcpkg_Strings.h index 325a2cb4c..e94742c8f 100644 --- a/toolsrc/include/vcpkg_Strings.h +++ b/toolsrc/include/vcpkg_Strings.h @@ -19,10 +19,12 @@ namespace vcpkg::Strings::details inline long long to_printf_arg(const long long s) { return s; } - inline double to_printf_arg(const double s) { return s; } + inline unsigned long to_printf_arg(const unsigned long s) { return s; } inline size_t to_printf_arg(const size_t s) { return s; } + inline double to_printf_arg(const double s) { return s; } + std::string format_internal(const char* fmtstr, ...); inline const wchar_t* to_wprintf_arg(const std::wstring& s) { return s.c_str(); } -- cgit v1.2.3 From 52d606e6ac6650271fc2fd02718eb107dd33e797 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 24 Aug 2017 12:06:28 -0700 Subject: Use CreateProcess instead of _wspawnlpe --- toolsrc/src/vcpkg_System.cpp | 50 +++++++++++++++++++++++++++++++++----------- 1 file changed, 38 insertions(+), 12 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg_System.cpp b/toolsrc/src/vcpkg_System.cpp index 883fe6612..2ad120e4c 100644 --- a/toolsrc/src/vcpkg_System.cpp +++ b/toolsrc/src/vcpkg_System.cpp @@ -96,8 +96,7 @@ namespace vcpkg::System // Flush stdout before launching external process fflush(nullptr); - std::vector env_cstr; - env_cstr.reserve(env_wstrings.size() + 2); + std::wstring env_cstr; for (auto&& env_wstring : env_wstrings) { @@ -105,20 +104,47 @@ namespace vcpkg::System auto v = value.get(); if (!v || v->empty()) continue; - env_wstring.push_back(L'='); - env_wstring.append(*v); - env_cstr.push_back(env_wstring.c_str()); + env_cstr.append(env_wstring); + env_cstr.push_back(L'='); + env_cstr.append(*v); + env_cstr.push_back(L'\0'); } - env_cstr.push_back(new_PATH.c_str()); - env_cstr.push_back(nullptr); + env_cstr.append(new_PATH); + env_cstr.push_back(L'\0'); + + STARTUPINFOW startup_info; + memset(&startup_info, 0, sizeof(STARTUPINFOW)); + startup_info.cb = sizeof(STARTUPINFOW); + + PROCESS_INFORMATION process_info; + memset(&process_info, 0, sizeof(PROCESS_INFORMATION)); // Basically we are wrapping it in quotes - const std::wstring& actual_cmd_line = Strings::wformat(LR"###("%s")###", cmd_line); - Debug::println("_wspawnlpe(cmd.exe /c %s)", Strings::to_utf8(actual_cmd_line)); - auto exit_code = - _wspawnlpe(_P_WAIT, L"cmd.exe", L"cmd.exe", L"/c", actual_cmd_line.c_str(), nullptr, env_cstr.data()); - Debug::println("_wspawnlpe() returned %d", exit_code); + std::wstring actual_cmd_line = Strings::wformat(LR"###(cmd.exe /c "%s")###", cmd_line); + Debug::println("CreateProcessW(%s)", Strings::to_utf8(actual_cmd_line)); + bool succeeded = TRUE == CreateProcessW(nullptr, + actual_cmd_line.data(), + nullptr, + nullptr, + FALSE, + BELOW_NORMAL_PRIORITY_CLASS | CREATE_UNICODE_ENVIRONMENT, + env_cstr.data(), + nullptr, + &startup_info, + &process_info); + + Checks::check_exit(VCPKG_LINE_INFO, succeeded, "Process creation failed with error code: %lu", GetLastError()); + + CloseHandle(process_info.hThread); + + DWORD result = WaitForSingleObject(process_info.hProcess, INFINITE); + Checks::check_exit(VCPKG_LINE_INFO, result != WAIT_FAILED, "WaitForSingleObject failed"); + + DWORD exit_code = 0; + GetExitCodeProcess(process_info.hProcess, &exit_code); + + Debug::println("CreateProcessW() returned %lu", exit_code); return static_cast(exit_code); } -- cgit v1.2.3 From ceb54bae8754f707bec17ac6ff3e35a32b0966e3 Mon Sep 17 00:00:00 2001 From: Mikhail Paulyshka Date: Fri, 25 Aug 2017 00:45:11 +0300 Subject: [vcpkg] prefer AMD64 host architecture --- toolsrc/src/vcpkg_Build.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg_Build.cpp b/toolsrc/src/vcpkg_Build.cpp index 2c9a147a4..b0053766e 100644 --- a/toolsrc/src/vcpkg_Build.cpp +++ b/toolsrc/src/vcpkg_Build.cpp @@ -51,7 +51,7 @@ namespace vcpkg::Build static constexpr ToolsetArchOption X64_ARM64 = {L"amd64_arm64", CPU::X64, CPU::ARM64}; static constexpr std::array VALUES = { - X86, X86_X64, X86_ARM, X86_ARM64, X64, X64_X86, X64_ARM, X64_ARM64}; + X64, X64_X86, X64_ARM, X64_ARM64, X86, X86_X64, X86_ARM, X86_ARM64}; auto target_arch = System::to_cpu_architecture(target_architecture); auto host_architectures = System::get_supported_host_architectures(); -- cgit v1.2.3 From e237682cad4eaa582a10b5ad03a59ca6449e0795 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 23 Aug 2017 16:17:53 -0700 Subject: Introduce GlobalState struct --- toolsrc/include/SourceParagraph.h | 2 -- toolsrc/include/vcpkg_GlobalState.h | 13 +++++++++++++ toolsrc/include/vcpkglib.h | 2 -- toolsrc/src/Paragraphs.cpp | 3 ++- toolsrc/src/SourceParagraph.cpp | 1 - toolsrc/src/VcpkgCmdArguments.cpp | 3 ++- toolsrc/src/commands_search.cpp | 3 ++- toolsrc/src/vcpkg.cpp | 14 +++++++------- toolsrc/src/vcpkg_Build.cpp | 7 ++++--- toolsrc/src/vcpkg_GlobalState.cpp | 10 ++++++++++ toolsrc/src/vcpkg_System.cpp | 9 +++++---- toolsrc/src/vcpkglib.cpp | 2 -- toolsrc/vcpkglib/vcpkglib.vcxproj | 2 ++ toolsrc/vcpkglib/vcpkglib.vcxproj.filters | 6 ++++++ 14 files changed, 53 insertions(+), 24 deletions(-) create mode 100644 toolsrc/include/vcpkg_GlobalState.h create mode 100644 toolsrc/src/vcpkg_GlobalState.cpp (limited to 'toolsrc') diff --git a/toolsrc/include/SourceParagraph.h b/toolsrc/include/SourceParagraph.h index 05f18f940..8563d83b0 100644 --- a/toolsrc/include/SourceParagraph.h +++ b/toolsrc/include/SourceParagraph.h @@ -12,8 +12,6 @@ namespace vcpkg { - extern bool g_feature_packages; - struct Dependency { Features depend; diff --git a/toolsrc/include/vcpkg_GlobalState.h b/toolsrc/include/vcpkg_GlobalState.h new file mode 100644 index 000000000..15b8867f7 --- /dev/null +++ b/toolsrc/include/vcpkg_GlobalState.h @@ -0,0 +1,13 @@ +#pragma once + +#include + +namespace vcpkg +{ + struct GlobalState + { + static ElapsedTime timer; + static bool debugging; + static bool feature_packages; + }; +} \ No newline at end of file diff --git a/toolsrc/include/vcpkglib.h b/toolsrc/include/vcpkglib.h index 63b358d74..0bb75f9b5 100644 --- a/toolsrc/include/vcpkglib.h +++ b/toolsrc/include/vcpkglib.h @@ -6,8 +6,6 @@ namespace vcpkg { - extern bool g_debugging; - StatusParagraphs database_load_check(const VcpkgPaths& paths); void write_update(const VcpkgPaths& paths, const StatusParagraph& p); diff --git a/toolsrc/src/Paragraphs.cpp b/toolsrc/src/Paragraphs.cpp index 3a30f66a3..a7dee4fd3 100644 --- a/toolsrc/src/Paragraphs.cpp +++ b/toolsrc/src/Paragraphs.cpp @@ -3,6 +3,7 @@ #include "ParagraphParseResult.h" #include "Paragraphs.h" #include "vcpkg_Files.h" +#include "vcpkg_GlobalState.h" #include "vcpkg_Util.h" using namespace vcpkg::Parse; @@ -210,7 +211,7 @@ namespace vcpkg::Paragraphs if (auto vector_pghs = pghs.get()) { auto csf = SourceControlFile::parse_control_file(std::move(*vector_pghs)); - if (!g_feature_packages) + if (!GlobalState::feature_packages) { if (auto ptr = csf.get()) { diff --git a/toolsrc/src/SourceParagraph.cpp b/toolsrc/src/SourceParagraph.cpp index 54f34cbd3..c69770ae1 100644 --- a/toolsrc/src/SourceParagraph.cpp +++ b/toolsrc/src/SourceParagraph.cpp @@ -13,7 +13,6 @@ namespace vcpkg { using namespace vcpkg::Parse; - bool g_feature_packages = false; namespace Fields { static const std::string BUILD_DEPENDS = "Build-Depends"; diff --git a/toolsrc/src/VcpkgCmdArguments.cpp b/toolsrc/src/VcpkgCmdArguments.cpp index ebf4c5fc5..a72e5226f 100644 --- a/toolsrc/src/VcpkgCmdArguments.cpp +++ b/toolsrc/src/VcpkgCmdArguments.cpp @@ -3,6 +3,7 @@ #include "VcpkgCmdArguments.h" #include "metrics.h" #include "vcpkg_Commands.h" +#include "vcpkg_GlobalState.h" #include "vcpkg_System.h" namespace vcpkg @@ -119,7 +120,7 @@ namespace vcpkg } if (arg == "--featurepackages") { - g_feature_packages = true; + GlobalState::feature_packages = true; continue; } diff --git a/toolsrc/src/commands_search.cpp b/toolsrc/src/commands_search.cpp index b1bd7ea6f..529d52a8b 100644 --- a/toolsrc/src/commands_search.cpp +++ b/toolsrc/src/commands_search.cpp @@ -3,6 +3,7 @@ #include "Paragraphs.h" #include "SourceParagraph.h" #include "vcpkg_Commands.h" +#include "vcpkg_GlobalState.h" #include "vcpkg_System.h" #include "vcpkglib.h" @@ -90,7 +91,7 @@ namespace vcpkg::Commands::Search if (!sources_and_errors.errors.empty()) { - if (vcpkg::g_debugging) + if (GlobalState::debugging) { print_error_message(sources_and_errors.errors); } diff --git a/toolsrc/src/vcpkg.cpp b/toolsrc/src/vcpkg.cpp index 738b7b284..3ccb33aad 100644 --- a/toolsrc/src/vcpkg.cpp +++ b/toolsrc/src/vcpkg.cpp @@ -6,6 +6,7 @@ #include "vcpkg_Chrono.h" #include "vcpkg_Commands.h" #include "vcpkg_Files.h" +#include "vcpkg_GlobalState.h" #include "vcpkg_Input.h" #include "vcpkg_Strings.h" #include "vcpkg_System.h" @@ -184,17 +185,16 @@ static std::string trim_path_from_command_line(const std::string& full_command_l return std::string(it, full_command_line.cend()); } -static ElapsedTime g_timer; - int wmain(const int argc, const wchar_t* const* const argv) { if (argc == 0) std::abort(); - g_timer = ElapsedTime::create_started(); + GlobalState::timer = ElapsedTime::create_started(); + atexit([]() { - auto elapsed_us = g_timer.microseconds(); + auto elapsed_us = GlobalState::timer.microseconds(); Metrics::track_metric("elapsed_us", elapsed_us); - g_debugging = false; + GlobalState::debugging = false; Metrics::flush(); }); @@ -209,9 +209,9 @@ int wmain(const int argc, const wchar_t* const* const argv) if (auto p = args.printmetrics.get()) Metrics::set_print_metrics(*p); if (auto p = args.sendmetrics.get()) Metrics::set_send_metrics(*p); - if (auto p = args.debug.get()) g_debugging = *p; + if (auto p = args.debug.get()) GlobalState::debugging = *p; - if (g_debugging) + if (GlobalState::debugging) { inner(args); Checks::exit_fail(VCPKG_LINE_INFO); diff --git a/toolsrc/src/vcpkg_Build.cpp b/toolsrc/src/vcpkg_Build.cpp index ca89ccf37..d4632afaa 100644 --- a/toolsrc/src/vcpkg_Build.cpp +++ b/toolsrc/src/vcpkg_Build.cpp @@ -8,6 +8,7 @@ #include "vcpkg_Chrono.h" #include "vcpkg_Commands.h" #include "vcpkg_Enums.h" +#include "vcpkg_GlobalState.h" #include "vcpkg_System.h" #include "vcpkg_optional.h" #include "vcpkglib.h" @@ -77,7 +78,7 @@ namespace vcpkg::Build std::wstring make_build_env_cmd(const PreBuildInfo& pre_build_info, const Toolset& toolset) { const wchar_t* tonull = L" >nul"; - if (g_debugging) + if (GlobalState::debugging) { tonull = L""; } @@ -155,7 +156,7 @@ namespace vcpkg::Build const auto cmd_set_environment = make_build_env_cmd(pre_build_info, toolset); std::string features; - if (g_feature_packages) + if (GlobalState::feature_packages) { if (config.feature_list) { @@ -212,7 +213,7 @@ namespace vcpkg::Build { return {BuildResult::POST_BUILD_CHECKS_FAILED, {}}; } - if (g_feature_packages) + if (GlobalState::feature_packages) { if (config.feature_list) { diff --git a/toolsrc/src/vcpkg_GlobalState.cpp b/toolsrc/src/vcpkg_GlobalState.cpp new file mode 100644 index 000000000..cae2b2f8e --- /dev/null +++ b/toolsrc/src/vcpkg_GlobalState.cpp @@ -0,0 +1,10 @@ +#include "pch.h" + +#include "vcpkg_GlobalState.h" + +namespace vcpkg +{ + ElapsedTime GlobalState::timer; + bool GlobalState::debugging = false; + bool GlobalState::feature_packages = false; +} diff --git a/toolsrc/src/vcpkg_System.cpp b/toolsrc/src/vcpkg_System.cpp index 2ad120e4c..2d6246d19 100644 --- a/toolsrc/src/vcpkg_System.cpp +++ b/toolsrc/src/vcpkg_System.cpp @@ -1,6 +1,7 @@ #include "pch.h" #include "vcpkg_Checks.h" +#include "vcpkg_GlobalState.h" #include "vcpkg_System.h" #include "vcpkglib.h" @@ -94,7 +95,7 @@ namespace vcpkg::System }; // Flush stdout before launching external process - fflush(nullptr); + fflush(nullptr); std::wstring env_cstr; @@ -151,7 +152,7 @@ namespace vcpkg::System int cmd_execute(const CWStringView cmd_line) { // Flush stdout before launching external process - fflush(nullptr); + fflush(nullptr); // Basically we are wrapping it in quotes const std::wstring& actual_cmd_line = Strings::wformat(LR"###("%s")###", cmd_line); @@ -302,7 +303,7 @@ namespace vcpkg::Debug { void println(const CStringView message) { - if (g_debugging) + if (GlobalState::debugging) { System::println("[DEBUG] %s", message); } @@ -310,7 +311,7 @@ namespace vcpkg::Debug void println(const System::Color c, const CStringView message) { - if (g_debugging) + if (GlobalState::debugging) { System::println(c, "[DEBUG] %s", message); } diff --git a/toolsrc/src/vcpkglib.cpp b/toolsrc/src/vcpkglib.cpp index 6e90695de..b52f49d62 100644 --- a/toolsrc/src/vcpkglib.cpp +++ b/toolsrc/src/vcpkglib.cpp @@ -9,8 +9,6 @@ namespace vcpkg { - bool g_debugging = false; - static StatusParagraphs load_current_database(Files::Filesystem& fs, const fs::path& vcpkg_dir_status_file, const fs::path& vcpkg_dir_status_file_old) diff --git a/toolsrc/vcpkglib/vcpkglib.vcxproj b/toolsrc/vcpkglib/vcpkglib.vcxproj index 200f91d1c..edecd7720 100644 --- a/toolsrc/vcpkglib/vcpkglib.vcxproj +++ b/toolsrc/vcpkglib/vcpkglib.vcxproj @@ -161,6 +161,7 @@ + @@ -227,6 +228,7 @@ + diff --git a/toolsrc/vcpkglib/vcpkglib.vcxproj.filters b/toolsrc/vcpkglib/vcpkglib.vcxproj.filters index 4f51dfa9a..2fbf3d929 100644 --- a/toolsrc/vcpkglib/vcpkglib.vcxproj.filters +++ b/toolsrc/vcpkglib/vcpkglib.vcxproj.filters @@ -177,6 +177,9 @@ Source Files + + Source Files + @@ -302,5 +305,8 @@ Header Files + + Header Files + \ No newline at end of file -- cgit v1.2.3 From 88d96a3699118cf21f6ec92284eb591db25d3a6a Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 23 Aug 2017 16:47:54 -0700 Subject: Run cleanup before exiting instead of calling atexit --- toolsrc/include/vcpkg_Checks.h | 2 ++ toolsrc/src/vcpkg.cpp | 7 +------ toolsrc/src/vcpkg_Checks.cpp | 24 ++++++++++++++++++++++-- 3 files changed, 25 insertions(+), 8 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg_Checks.h b/toolsrc/include/vcpkg_Checks.h index 754b44f75..01cb7209b 100644 --- a/toolsrc/include/vcpkg_Checks.h +++ b/toolsrc/include/vcpkg_Checks.h @@ -5,6 +5,8 @@ namespace vcpkg::Checks { + void register_console_ctrl_handler(); + // Indicate that an internal error has occurred and exit the tool. This should be used when invariants have been // broken. [[noreturn]] void unreachable(const LineInfo& line_info); diff --git a/toolsrc/src/vcpkg.cpp b/toolsrc/src/vcpkg.cpp index 3ccb33aad..7294d8692 100644 --- a/toolsrc/src/vcpkg.cpp +++ b/toolsrc/src/vcpkg.cpp @@ -191,12 +191,7 @@ int wmain(const int argc, const wchar_t* const* const argv) GlobalState::timer = ElapsedTime::create_started(); - atexit([]() { - auto elapsed_us = GlobalState::timer.microseconds(); - Metrics::track_metric("elapsed_us", elapsed_us); - GlobalState::debugging = false; - Metrics::flush(); - }); + // Checks::register_console_ctrl_handler(); Metrics::track_property("version", Commands::Version::version()); diff --git a/toolsrc/src/vcpkg_Checks.cpp b/toolsrc/src/vcpkg_Checks.cpp index 2674b889a..6ae595a54 100644 --- a/toolsrc/src/vcpkg_Checks.cpp +++ b/toolsrc/src/vcpkg_Checks.cpp @@ -1,11 +1,31 @@ #include "pch.h" +#include "metrics.h" #include "vcpkg_Checks.h" +#include "vcpkg_GlobalState.h" #include "vcpkg_System.h" #include "vcpkglib.h" namespace vcpkg::Checks { + [[noreturn]] static void cleanup_and_exit(const int exit_code) + { + auto elapsed_us = GlobalState::timer.microseconds(); + Metrics::track_metric("elapsed_us", elapsed_us); + GlobalState::debugging = false; + Metrics::flush(); + + ::exit(exit_code); + } + + static BOOL CtrlHandler(DWORD fdwCtrlType) + { + Metrics::track_metric("SignalCaptured", fdwCtrlType); + cleanup_and_exit(EXIT_FAILURE); + } + + void register_console_ctrl_handler() { SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlHandler, TRUE); } + [[noreturn]] void unreachable(const LineInfo& line_info) { System::println(System::Color::error, "Error: Unreachable code was reached"); @@ -13,14 +33,14 @@ namespace vcpkg::Checks #ifndef NDEBUG std::abort(); #else - ::exit(EXIT_FAILURE); + cleanup_and_exit(EXIT_FAILURE); #endif } [[noreturn]] void exit_with_code(const LineInfo& line_info, const int exit_code) { Debug::println(System::Color::error, line_info.to_string()); - ::exit(exit_code); + cleanup_and_exit(exit_code); } [[noreturn]] void exit_with_message(const LineInfo& line_info, const CStringView errorMessage) -- cgit v1.2.3 From 34bd87c9fcfb1ac9269c75db96852b64ed754d11 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 24 Aug 2017 16:32:06 -0700 Subject: Fix merge issues --- toolsrc/src/commands_install.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/commands_install.cpp b/toolsrc/src/commands_install.cpp index bd14bf7e3..659418a38 100644 --- a/toolsrc/src/commands_install.cpp +++ b/toolsrc/src/commands_install.cpp @@ -6,6 +6,7 @@ #include "vcpkg_Commands.h" #include "vcpkg_Dependencies.h" #include "vcpkg_Files.h" +#include "vcpkg_GlobalState.h" #include "vcpkg_Input.h" #include "vcpkg_System.h" #include "vcpkg_Util.h" @@ -252,7 +253,8 @@ namespace vcpkg::Commands::Install { const InstallPlanType& plan_type = action.plan_type; const std::string display_name = action.spec.to_string(); - const std::string display_name_with_features = g_feature_packages ? action.displayname() : display_name; + const std::string display_name_with_features = + GlobalState::feature_packages ? action.displayname() : display_name; const bool is_user_requested = action.request_type == RequestType::USER_REQUESTED; const bool use_head_version = to_bool(build_package_options.use_head_version); @@ -275,7 +277,7 @@ namespace vcpkg::Commands::Install System::println("Building package %s... ", display_name_with_features); const auto result = [&]() -> Build::ExtendedBuildResult { - if (g_feature_packages) + if (GlobalState::feature_packages) { const Build::BuildPackageConfig build_config{ *action.any_paragraph.source_control_file.value_or_exit(VCPKG_LINE_INFO), @@ -459,7 +461,7 @@ namespace vcpkg::Commands::Install for (auto&& spec : specs) { Input::check_triplet(spec.package_spec.triplet(), paths); - if (!spec.features.empty() && !g_feature_packages) + if (!spec.features.empty() && !GlobalState::feature_packages) { Checks::exit_with_message( VCPKG_LINE_INFO, "Feature packages are experimentally available under the --featurepackages flag."); @@ -481,7 +483,7 @@ namespace vcpkg::Commands::Install std::vector action_plan; - if (g_feature_packages) + if (GlobalState::feature_packages) { std::unordered_map scf_map; auto all_ports = Paragraphs::try_load_all_ports(paths.get_filesystem(), paths.ports); @@ -522,7 +524,7 @@ namespace vcpkg::Commands::Install } // execute the plan - if (g_feature_packages) + if (GlobalState::feature_packages) { for (const auto& action : action_plan) { -- cgit v1.2.3 From 98ee8a949ad4bfdfa9bf0411b552a23c923eaff7 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Fri, 25 Aug 2017 16:03:57 -0700 Subject: [vcpkg] Trap Ctrl-C, enable thread safety for global data structures --- toolsrc/include/metrics.h | 30 +++++++++++++++++++----------- toolsrc/include/pch.h | 2 ++ toolsrc/include/vcpkg_GlobalState.h | 11 +++++++---- toolsrc/include/vcpkg_Util.h | 31 +++++++++++++++++++++++++++++++ toolsrc/src/VcpkgCmdArguments.cpp | 8 ++++---- toolsrc/src/VcpkgPaths.cpp | 9 ++++++--- toolsrc/src/commands_install.cpp | 3 ++- toolsrc/src/metrics.cpp | 20 +++++++++++--------- toolsrc/src/vcpkg.cpp | 32 ++++++++++++++++++++------------ toolsrc/src/vcpkg_Build.cpp | 13 ++++++++----- toolsrc/src/vcpkg_Checks.cpp | 14 ++++++++++---- toolsrc/src/vcpkg_GlobalState.cpp | 6 +++--- toolsrc/src/vcpkg_Input.cpp | 2 +- toolsrc/src/vcpkg_metrics_uploader.cpp | 3 ++- toolsrc/src/vcpkglib.cpp | 2 +- 15 files changed, 127 insertions(+), 59 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/metrics.h b/toolsrc/include/metrics.h index 1f5ae2f32..8eae426de 100644 --- a/toolsrc/include/metrics.h +++ b/toolsrc/include/metrics.h @@ -2,19 +2,27 @@ #include +#include "vcpkg_Util.h" + namespace vcpkg::Metrics { - void set_send_metrics(bool should_send_metrics); - void set_print_metrics(bool should_print_metrics); - void set_user_information(const std::string& user_id, const std::string& first_use_time); - void init_user_information(std::string& user_id, std::string& first_use_time); + struct Metrics : Util::ResourceBase + { + void set_send_metrics(bool should_send_metrics); + void set_print_metrics(bool should_print_metrics); + void set_user_information(const std::string& user_id, const std::string& first_use_time); + void init_user_information(std::string& user_id, std::string& first_use_time); - void track_metric(const std::string& name, double value); - void track_property(const std::string& name, const std::string& value); - void track_property(const std::string& name, const std::wstring& value); - bool get_compiled_metrics_enabled(); - std::wstring get_SQM_user(); + void track_metric(const std::string& name, double value); + void track_property(const std::string& name, const std::string& value); + void track_property(const std::string& name, const std::wstring& value); + + void upload(const std::string& payload); + void flush(); + }; - void upload(const std::string& payload); - void flush(); + extern Util::LockGuarded g_metrics; + + std::wstring get_SQM_user(); + bool get_compiled_metrics_enabled(); } diff --git a/toolsrc/include/pch.h b/toolsrc/include/pch.h index 406d0741e..770bcf07a 100644 --- a/toolsrc/include/pch.h +++ b/toolsrc/include/pch.h @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -22,6 +23,7 @@ #include #include #include +#include #include #include #include diff --git a/toolsrc/include/vcpkg_GlobalState.h b/toolsrc/include/vcpkg_GlobalState.h index 15b8867f7..8f47fa00f 100644 --- a/toolsrc/include/vcpkg_GlobalState.h +++ b/toolsrc/include/vcpkg_GlobalState.h @@ -1,13 +1,16 @@ #pragma once -#include +#include + +#include "vcpkg_Chrono.h" +#include "vcpkg_Util.h" namespace vcpkg { struct GlobalState { - static ElapsedTime timer; - static bool debugging; - static bool feature_packages; + static Util::LockGuarded timer; + static std::atomic debugging; + static std::atomic feature_packages; }; } \ No newline at end of file diff --git a/toolsrc/include/vcpkg_Util.h b/toolsrc/include/vcpkg_Util.h index cfbd23020..c76ca01ac 100644 --- a/toolsrc/include/vcpkg_Util.h +++ b/toolsrc/include/vcpkg_Util.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include @@ -95,4 +96,34 @@ namespace vcpkg::Util ResourceBase& operator=(const ResourceBase&) = delete; ResourceBase& operator=(ResourceBase&&) = delete; }; + + template + struct LockGuardPtr; + + template + struct LockGuarded + { + friend struct LockGuardPtr; + + LockGuardPtr lock() { return *this; } + + private: + std::mutex m_mutex; + T m_t; + }; + + template + struct LockGuardPtr + { + T& operator*() { return m_ptr; } + T* operator->() { return &m_ptr; } + + T* get() { return &m_ptr; } + + LockGuardPtr(LockGuarded& sync) : m_lock(sync.m_mutex), m_ptr(sync.m_t) {} + + private: + std::unique_lock m_lock; + T& m_ptr; + }; } \ No newline at end of file diff --git a/toolsrc/src/VcpkgCmdArguments.cpp b/toolsrc/src/VcpkgCmdArguments.cpp index a72e5226f..cf6c7b562 100644 --- a/toolsrc/src/VcpkgCmdArguments.cpp +++ b/toolsrc/src/VcpkgCmdArguments.cpp @@ -16,7 +16,7 @@ namespace vcpkg if (arg_begin == arg_end) { System::println(System::Color::error, "Error: expected value after %s", option_name); - Metrics::track_property("error", "error option name"); + Metrics::g_metrics.lock()->track_property("error", "error option name"); Commands::Help::print_usage(); Checks::exit_fail(VCPKG_LINE_INFO); } @@ -24,7 +24,7 @@ namespace vcpkg if (option_field != nullptr) { System::println(System::Color::error, "Error: %s specified multiple times", option_name); - Metrics::track_property("error", "error option specified multiple times"); + Metrics::g_metrics.lock()->track_property("error", "error option specified multiple times"); Commands::Help::print_usage(); Checks::exit_fail(VCPKG_LINE_INFO); } @@ -37,7 +37,7 @@ namespace vcpkg if (option_field && option_field != new_setting) { System::println(System::Color::error, "Error: conflicting values specified for --%s", option_name); - Metrics::track_property("error", "error conflicting switches"); + Metrics::g_metrics.lock()->track_property("error", "error conflicting switches"); Commands::Help::print_usage(); Checks::exit_fail(VCPKG_LINE_INFO); } @@ -71,7 +71,7 @@ namespace vcpkg if (arg[0] == '-' && arg[1] != '-') { - Metrics::track_property("error", "error short options are not supported"); + Metrics::g_metrics.lock()->track_property("error", "error short options are not supported"); Checks::exit_with_message(VCPKG_LINE_INFO, "Error: short options are not supported: %s", arg); } diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp index 4be636650..1b76fdc24 100644 --- a/toolsrc/src/VcpkgPaths.cpp +++ b/toolsrc/src/VcpkgPaths.cpp @@ -87,8 +87,11 @@ namespace vcpkg "(No sufficient installed version was found)", Strings::to_utf8(tool_name), version_as_string); - Metrics::track_property("error", "powershell install failed"); - Metrics::track_property("installcmd", install_cmd); + { + auto locked_metrics = Metrics::g_metrics.lock(); + locked_metrics->track_property("error", "powershell install failed"); + locked_metrics->track_property("installcmd", install_cmd); + } Checks::exit_with_code(VCPKG_LINE_INFO, rc.exit_code); } @@ -186,7 +189,7 @@ namespace vcpkg if (paths.root.empty()) { - Metrics::track_property("error", "Invalid vcpkg root directory"); + Metrics::g_metrics.lock()->track_property("error", "Invalid vcpkg root directory"); Checks::exit_with_message(VCPKG_LINE_INFO, "Invalid vcpkg root directory: %s", paths.root.string()); } diff --git a/toolsrc/src/commands_install.cpp b/toolsrc/src/commands_install.cpp index 659418a38..a2e95eb48 100644 --- a/toolsrc/src/commands_install.cpp +++ b/toolsrc/src/commands_install.cpp @@ -514,7 +514,8 @@ namespace vcpkg::Commands::Install return "R$" + raction->spec.to_string(); Checks::unreachable(VCPKG_LINE_INFO); }); - Metrics::track_property("installplan", specs_string); + + Metrics::g_metrics.lock()->track_property("installplan", specs_string); print_plan(action_plan, is_recursive); diff --git a/toolsrc/src/metrics.cpp b/toolsrc/src/metrics.cpp index 7992f3e51..6263c0fcb 100644 --- a/toolsrc/src/metrics.cpp +++ b/toolsrc/src/metrics.cpp @@ -8,6 +8,8 @@ namespace vcpkg::Metrics { + Util::LockGuarded g_metrics; + static std::string get_current_date_time() { struct tm newtime; @@ -223,25 +225,25 @@ namespace vcpkg::Metrics return hkcu_sqmclient.value_or(L"{}"); } - void set_user_information(const std::string& user_id, const std::string& first_use_time) + void Metrics::set_user_information(const std::string& user_id, const std::string& first_use_time) { g_metricmessage.user_id = user_id; g_metricmessage.user_timestamp = first_use_time; } - void init_user_information(std::string& user_id, std::string& first_use_time) + void Metrics::init_user_information(std::string& user_id, std::string& first_use_time) { user_id = generate_random_UUID(); first_use_time = get_current_date_time(); } - void set_send_metrics(bool should_send_metrics) { g_should_send_metrics = should_send_metrics; } + void Metrics::set_send_metrics(bool should_send_metrics) { g_should_send_metrics = should_send_metrics; } - void set_print_metrics(bool should_print_metrics) { g_should_print_metrics = should_print_metrics; } + void Metrics::set_print_metrics(bool should_print_metrics) { g_should_print_metrics = should_print_metrics; } - void track_metric(const std::string& name, double value) { g_metricmessage.TrackMetric(name, value); } + void Metrics::track_metric(const std::string& name, double value) { g_metricmessage.TrackMetric(name, value); } - void track_property(const std::string& name, const std::wstring& value) + void Metrics::track_property(const std::string& name, const std::wstring& value) { // Note: this is not valid UTF-16 -> UTF-8, it just yields a close enough approximation for our purposes. std::string converted_value; @@ -252,12 +254,12 @@ namespace vcpkg::Metrics g_metricmessage.TrackProperty(name, converted_value); } - void track_property(const std::string& name, const std::string& value) + void Metrics::track_property(const std::string& name, const std::string& value) { g_metricmessage.TrackProperty(name, value); } - void upload(const std::string& payload) + void Metrics::upload(const std::string& payload) { HINTERNET hSession = nullptr, hConnect = nullptr, hRequest = nullptr; BOOL bResults = FALSE; @@ -349,7 +351,7 @@ namespace vcpkg::Metrics return fs::path(buf, buf + bytes); } - void flush() + void Metrics::flush() { std::string payload = g_metricmessage.format_event_data_template(); if (g_should_print_metrics) std::cerr << payload << "\n"; diff --git a/toolsrc/src/vcpkg.cpp b/toolsrc/src/vcpkg.cpp index 7294d8692..9da501ec0 100644 --- a/toolsrc/src/vcpkg.cpp +++ b/toolsrc/src/vcpkg.cpp @@ -27,7 +27,7 @@ void invalid_command(const std::string& cmd) static void inner(const VcpkgCmdArguments& args) { - Metrics::track_property("command", args.command); + Metrics::g_metrics.lock()->track_property("command", args.command); if (args.command.empty()) { Commands::Help::print_usage(); @@ -135,7 +135,7 @@ static void loadConfig() auto user_time = keys["User-Since"]; if (!user_id.empty() && !user_time.empty()) { - Metrics::set_user_information(user_id, user_time); + Metrics::g_metrics.lock()->set_user_information(user_id, user_time); return; } } @@ -146,8 +146,11 @@ static void loadConfig() // config file not found, could not be read, or invalid std::string user_id, user_time; - Metrics::init_user_information(user_id, user_time); - Metrics::set_user_information(user_id, user_time); + { + auto locked_metrics = Metrics::g_metrics.lock(); + locked_metrics->init_user_information(user_id, user_time); + locked_metrics->set_user_information(user_id, user_time); + } try { std::error_code ec; @@ -189,23 +192,28 @@ int wmain(const int argc, const wchar_t* const* const argv) { if (argc == 0) std::abort(); - GlobalState::timer = ElapsedTime::create_started(); + *GlobalState::timer.lock() = ElapsedTime::create_started(); // Checks::register_console_ctrl_handler(); - Metrics::track_property("version", Commands::Version::version()); - const std::string trimmed_command_line = trim_path_from_command_line(Strings::to_utf8(GetCommandLineW())); - Metrics::track_property("cmdline", trimmed_command_line); + + { + auto locked_metrics = Metrics::g_metrics.lock(); + locked_metrics->track_property("version", Commands::Version::version()); + locked_metrics->track_property("cmdline", trimmed_command_line); + } loadConfig(); - Metrics::track_property("sqmuser", Metrics::get_SQM_user()); + Metrics::g_metrics.lock()->track_property("sqmuser", Metrics::get_SQM_user()); const VcpkgCmdArguments args = VcpkgCmdArguments::create_from_command_line(argc, argv); - if (auto p = args.printmetrics.get()) Metrics::set_print_metrics(*p); - if (auto p = args.sendmetrics.get()) Metrics::set_send_metrics(*p); + if (auto p = args.printmetrics.get()) Metrics::g_metrics.lock()->set_print_metrics(*p); + if (auto p = args.sendmetrics.get()) Metrics::g_metrics.lock()->set_send_metrics(*p); if (auto p = args.debug.get()) GlobalState::debugging = *p; + vcpkg::Checks::register_console_ctrl_handler(); + if (GlobalState::debugging) { inner(args); @@ -226,7 +234,7 @@ int wmain(const int argc, const wchar_t* const* const argv) { exc_msg = "unknown error(...)"; } - Metrics::track_property("error", exc_msg); + Metrics::g_metrics.lock()->track_property("error", exc_msg); fflush(stdout); System::print("vcpkg.exe has crashed.\n" diff --git a/toolsrc/src/vcpkg_Build.cpp b/toolsrc/src/vcpkg_Build.cpp index d4632afaa..89f95ee9b 100644 --- a/toolsrc/src/vcpkg_Build.cpp +++ b/toolsrc/src/vcpkg_Build.cpp @@ -193,13 +193,16 @@ namespace vcpkg::Build int return_code = System::cmd_execute_clean(command); auto buildtimeus = timer.microseconds(); const auto spec_string = spec.to_string(); - Metrics::track_metric("buildtimeus-" + spec_string, buildtimeus); - if (return_code != 0) { - Metrics::track_property("error", "build failed"); - Metrics::track_property("build_error", spec_string); - return {BuildResult::BUILD_FAILED, {}}; + auto locked_metrics = Metrics::g_metrics.lock(); + locked_metrics->track_metric("buildtimeus-" + spec_string, buildtimeus); + if (return_code != 0) + { + locked_metrics->track_property("error", "build failed"); + locked_metrics->track_property("build_error", spec_string); + return {BuildResult::BUILD_FAILED, {}}; + } } auto build_info = read_build_info(paths.get_filesystem(), paths.build_info_file_path(spec)); diff --git a/toolsrc/src/vcpkg_Checks.cpp b/toolsrc/src/vcpkg_Checks.cpp index 6ae595a54..d8d857daa 100644 --- a/toolsrc/src/vcpkg_Checks.cpp +++ b/toolsrc/src/vcpkg_Checks.cpp @@ -10,17 +10,23 @@ namespace vcpkg::Checks { [[noreturn]] static void cleanup_and_exit(const int exit_code) { - auto elapsed_us = GlobalState::timer.microseconds(); - Metrics::track_metric("elapsed_us", elapsed_us); + auto elapsed_us = GlobalState::timer.lock()->microseconds(); + + auto metrics = Metrics::g_metrics.lock(); + metrics->track_metric("elapsed_us", elapsed_us); GlobalState::debugging = false; - Metrics::flush(); + metrics->flush(); ::exit(exit_code); } static BOOL CtrlHandler(DWORD fdwCtrlType) { - Metrics::track_metric("SignalCaptured", fdwCtrlType); + { + auto locked_metrics = Metrics::g_metrics.lock(); + locked_metrics->track_property("CtrlHandler", std::to_string(fdwCtrlType)); + locked_metrics->track_property("error", "CtrlHandler was fired."); + } cleanup_and_exit(EXIT_FAILURE); } diff --git a/toolsrc/src/vcpkg_GlobalState.cpp b/toolsrc/src/vcpkg_GlobalState.cpp index cae2b2f8e..c194da466 100644 --- a/toolsrc/src/vcpkg_GlobalState.cpp +++ b/toolsrc/src/vcpkg_GlobalState.cpp @@ -4,7 +4,7 @@ namespace vcpkg { - ElapsedTime GlobalState::timer; - bool GlobalState::debugging = false; - bool GlobalState::feature_packages = false; + Util::LockGuarded GlobalState::timer; + std::atomic GlobalState::debugging = false; + std::atomic GlobalState::feature_packages = false; } diff --git a/toolsrc/src/vcpkg_Input.cpp b/toolsrc/src/vcpkg_Input.cpp index f4e9a07c2..153e6a942 100644 --- a/toolsrc/src/vcpkg_Input.cpp +++ b/toolsrc/src/vcpkg_Input.cpp @@ -29,7 +29,7 @@ namespace vcpkg::Input if (!paths.is_valid_triplet(t)) { System::println(System::Color::error, "Error: invalid triplet: %s", t); - Metrics::track_property("error", "invalid triplet: " + t.to_string()); + Metrics::g_metrics.lock()->track_property("error", "invalid triplet: " + t.to_string()); Commands::Help::help_topic_valid_triplet(paths); Checks::exit_fail(VCPKG_LINE_INFO); } diff --git a/toolsrc/src/vcpkg_metrics_uploader.cpp b/toolsrc/src/vcpkg_metrics_uploader.cpp index 38bf7ff9c..c6670c625 100644 --- a/toolsrc/src/vcpkg_metrics_uploader.cpp +++ b/toolsrc/src/vcpkg_metrics_uploader.cpp @@ -11,5 +11,6 @@ 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::get_real_filesystem().read_contents(szArgList[1]).value_or_exit(VCPKG_LINE_INFO)); + auto v = Files::get_real_filesystem().read_contents(szArgList[1]).value_or_exit(VCPKG_LINE_INFO); + Metrics::g_metrics.lock()->upload(v); } diff --git a/toolsrc/src/vcpkglib.cpp b/toolsrc/src/vcpkglib.cpp index b52f49d62..96e9f05e1 100644 --- a/toolsrc/src/vcpkglib.cpp +++ b/toolsrc/src/vcpkglib.cpp @@ -117,7 +117,7 @@ namespace vcpkg if (!was_tracked) { was_tracked = true; - Metrics::track_property("listfile", "update to new format"); + Metrics::g_metrics.lock()->track_property("listfile", "update to new format"); } // The files are sorted such that directories are placed just before the files they contain -- cgit v1.2.3 From af017922974c4612517fe9c512df7cdd1ac79b43 Mon Sep 17 00:00:00 2001 From: Mikhail Paulyshka Date: Wed, 23 Aug 2017 00:48:39 +0300 Subject: [vcpkg] use UTF-8 for console input/output --- toolsrc/src/vcpkg.cpp | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg.cpp b/toolsrc/src/vcpkg.cpp index 9da501ec0..fc9b1a016 100644 --- a/toolsrc/src/vcpkg.cpp +++ b/toolsrc/src/vcpkg.cpp @@ -18,6 +18,30 @@ using namespace vcpkg; +UINT console_cp_input; +UINT console_cp_output; + +void console_cp_set() +{ + console_cp_input = GetConsoleCP(); + console_cp_output = GetConsoleOutputCP(); + + SetConsoleCP(CP_UTF8); + SetConsoleOutputCP(CP_UTF8); +} + +void console_cp_reset() +{ + SetConsoleCP(console_cp_input); + SetConsoleOutputCP(console_cp_output); +} + +BOOL console_ctrl_handler(DWORD fdwCtrlType) +{ + console_cp_reset(); + return TRUE; +} + void invalid_command(const std::string& cmd) { System::println(System::Color::error, "invalid command: %s", cmd); @@ -192,6 +216,10 @@ int wmain(const int argc, const wchar_t* const* const argv) { if (argc == 0) std::abort(); + console_cp_set(); + SetConsoleCtrlHandler(PHANDLER_ROUTINE(console_ctrl_handler), TRUE); + atexit(console_cp_reset); + *GlobalState::timer.lock() = ElapsedTime::create_started(); // Checks::register_console_ctrl_handler(); -- cgit v1.2.3 From 67b9475ef29496508640f73410a10ecf737389eb Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Fri, 25 Aug 2017 16:55:14 -0700 Subject: [vcpkg] Set codepage to 65001, duplicate of #1682, fixes #1660 #1631 #1644 --- toolsrc/include/vcpkg_GlobalState.h | 3 +++ toolsrc/src/vcpkg.cpp | 36 ++++++------------------------------ toolsrc/src/vcpkg_Checks.cpp | 3 +++ toolsrc/src/vcpkg_GlobalState.cpp | 3 +++ 4 files changed, 15 insertions(+), 30 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg_GlobalState.h b/toolsrc/include/vcpkg_GlobalState.h index 8f47fa00f..6522a25bf 100644 --- a/toolsrc/include/vcpkg_GlobalState.h +++ b/toolsrc/include/vcpkg_GlobalState.h @@ -12,5 +12,8 @@ namespace vcpkg static Util::LockGuarded timer; static std::atomic debugging; static std::atomic feature_packages; + + static std::atomic g_init_console_cp; + static std::atomic g_init_console_output_cp; }; } \ No newline at end of file diff --git a/toolsrc/src/vcpkg.cpp b/toolsrc/src/vcpkg.cpp index fc9b1a016..f37d079a6 100644 --- a/toolsrc/src/vcpkg.cpp +++ b/toolsrc/src/vcpkg.cpp @@ -18,30 +18,6 @@ using namespace vcpkg; -UINT console_cp_input; -UINT console_cp_output; - -void console_cp_set() -{ - console_cp_input = GetConsoleCP(); - console_cp_output = GetConsoleOutputCP(); - - SetConsoleCP(CP_UTF8); - SetConsoleOutputCP(CP_UTF8); -} - -void console_cp_reset() -{ - SetConsoleCP(console_cp_input); - SetConsoleOutputCP(console_cp_output); -} - -BOOL console_ctrl_handler(DWORD fdwCtrlType) -{ - console_cp_reset(); - return TRUE; -} - void invalid_command(const std::string& cmd) { System::println(System::Color::error, "invalid command: %s", cmd); @@ -216,13 +192,13 @@ int wmain(const int argc, const wchar_t* const* const argv) { if (argc == 0) std::abort(); - console_cp_set(); - SetConsoleCtrlHandler(PHANDLER_ROUTINE(console_ctrl_handler), TRUE); - atexit(console_cp_reset); + GlobalState::g_init_console_cp = GetConsoleCP(); + GlobalState::g_init_console_output_cp = GetConsoleOutputCP(); - *GlobalState::timer.lock() = ElapsedTime::create_started(); + SetConsoleCP(65001); + SetConsoleOutputCP(65001); - // Checks::register_console_ctrl_handler(); + *GlobalState::timer.lock() = ElapsedTime::create_started(); const std::string trimmed_command_line = trim_path_from_command_line(Strings::to_utf8(GetCommandLineW())); @@ -240,7 +216,7 @@ int wmain(const int argc, const wchar_t* const* const argv) if (auto p = args.sendmetrics.get()) Metrics::g_metrics.lock()->set_send_metrics(*p); if (auto p = args.debug.get()) GlobalState::debugging = *p; - vcpkg::Checks::register_console_ctrl_handler(); + Checks::register_console_ctrl_handler(); if (GlobalState::debugging) { diff --git a/toolsrc/src/vcpkg_Checks.cpp b/toolsrc/src/vcpkg_Checks.cpp index d8d857daa..2ad2d06ab 100644 --- a/toolsrc/src/vcpkg_Checks.cpp +++ b/toolsrc/src/vcpkg_Checks.cpp @@ -17,6 +17,9 @@ namespace vcpkg::Checks GlobalState::debugging = false; metrics->flush(); + SetConsoleCP(GlobalState::g_init_console_cp); + SetConsoleOutputCP(GlobalState::g_init_console_output_cp); + ::exit(exit_code); } diff --git a/toolsrc/src/vcpkg_GlobalState.cpp b/toolsrc/src/vcpkg_GlobalState.cpp index c194da466..2221222c0 100644 --- a/toolsrc/src/vcpkg_GlobalState.cpp +++ b/toolsrc/src/vcpkg_GlobalState.cpp @@ -7,4 +7,7 @@ namespace vcpkg Util::LockGuarded GlobalState::timer; std::atomic GlobalState::debugging = false; std::atomic GlobalState::feature_packages = false; + + std::atomic GlobalState::g_init_console_cp = 0; + std::atomic GlobalState::g_init_console_output_cp = 0; } -- cgit v1.2.3 From 581aea74fb9737ee1efb0ae5d662ede8268b8e49 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Fri, 25 Aug 2017 23:34:44 -0700 Subject: [vcpkg] Use fgetws instead of fgets to accomodate non-ascii results --- toolsrc/src/vcpkg_System.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg_System.cpp b/toolsrc/src/vcpkg_System.cpp index 2d6246d19..140f7d1b0 100644 --- a/toolsrc/src/vcpkg_System.cpp +++ b/toolsrc/src/vcpkg_System.cpp @@ -170,24 +170,24 @@ namespace vcpkg::System const std::wstring& actual_cmd_line = Strings::wformat(LR"###("%s 2>&1")###", cmd_line); Debug::println("_wpopen(%s)", Strings::to_utf8(actual_cmd_line)); - std::string output; - char buf[1024]; + std::wstring output; + wchar_t buf[1024]; auto pipe = _wpopen(actual_cmd_line.c_str(), L"r"); if (pipe == nullptr) { - return {1, output}; + return {1, Strings::to_utf8(output)}; } - while (fgets(buf, 1024, pipe)) + while (fgetws(buf, 1024, pipe)) { output.append(buf); } if (!feof(pipe)) { - return {1, output}; + return {1, Strings::to_utf8(output)}; } auto ec = _pclose(pipe); - Debug::println("_wpopen() returned %d", ec); - return {ec, output}; + Debug::println("_pclose() returned %d", ec); + return {ec, Strings::to_utf8(output)}; } std::wstring create_powershell_script_cmd(const fs::path& script_path, const CWStringView args) -- cgit v1.2.3 From 70949b0d814c469d76b8ddecc514ae0af6686347 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Sat, 26 Aug 2017 00:19:51 -0700 Subject: [vcpkg] Use vcvars argument strings from detected toolset. Avoid c-string pointer comparison. --- toolsrc/include/VcpkgPaths.h | 5 ----- toolsrc/src/VcpkgPaths.cpp | 37 +++++++++++++++++-------------------- toolsrc/src/vcpkg_Build.cpp | 33 +++++++++------------------------ 3 files changed, 26 insertions(+), 49 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/VcpkgPaths.h b/toolsrc/include/VcpkgPaths.h index 7964129e5..d55c95fe1 100644 --- a/toolsrc/include/VcpkgPaths.h +++ b/toolsrc/include/VcpkgPaths.h @@ -13,11 +13,6 @@ namespace vcpkg CWStringView name; System::CPUArchitecture host_arch; System::CPUArchitecture target_arch; - - bool operator==(const ToolsetArchOption& a) const - { - return (name == a.name && host_arch == a.host_arch && target_arch == a.target_arch); - } }; struct Toolset diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp index 642ca6a9c..7e3e5c736 100644 --- a/toolsrc/src/VcpkgPaths.cpp +++ b/toolsrc/src/VcpkgPaths.cpp @@ -302,25 +302,24 @@ namespace vcpkg paths_examined.push_back(vs2015_dumpbin_exe); const fs::path vs2015_bin_dir = vs2015_vcvarsall_bat.parent_path() / "bin"; - std::vector supported_archictectures; - if(fs.exists(vs2015_bin_dir / "vcvars32.bat")) - supported_archictectures.push_back({L"x86", CPU::X86, CPU::X86}); + std::vector supported_architectures; + if (fs.exists(vs2015_bin_dir / "vcvars32.bat")) + supported_architectures.push_back({L"x86", CPU::X86, CPU::X86}); if (fs.exists(vs2015_bin_dir / "amd64\\vcvars64.bat")) - supported_archictectures.push_back({L"x64", CPU::X64, CPU::X64}); - if (fs.exists(vs2015_bin_dir / "arm\\vcvarsarm.bat")) - supported_archictectures.push_back({L"arm", CPU::ARM, CPU::ARM}); + supported_architectures.push_back({L"x64", CPU::X64, CPU::X64}); if (fs.exists(vs2015_bin_dir / "x86_amd64\\vcvarsx86_amd64.bat")) - supported_archictectures.push_back({L"x86_amd64", CPU::X86, CPU::X64}); + supported_architectures.push_back({L"x86_amd64", CPU::X86, CPU::X64}); if (fs.exists(vs2015_bin_dir / "x86_arm\\vcvarsx86_arm.bat")) - supported_archictectures.push_back({L"x86_arm" , CPU::X86, CPU::ARM}); + supported_architectures.push_back({L"x86_arm", CPU::X86, CPU::ARM}); if (fs.exists(vs2015_bin_dir / "amd64_x86\\vcvarsamd64_x86.bat")) - supported_archictectures.push_back({L"amd64_x86", CPU::X64, CPU::X86}); + supported_architectures.push_back({L"amd64_x86", CPU::X64, CPU::X86}); if (fs.exists(vs2015_bin_dir / "amd64_arm\\vcvarsamd64_arm.bat")) - supported_archictectures.push_back({L"amd64_arm", CPU::X64, CPU::ARM}); + supported_architectures.push_back({L"amd64_arm", CPU::X64, CPU::ARM}); if (fs.exists(vs2015_dumpbin_exe)) { - found_toolsets.push_back({vs2015_dumpbin_exe, vs2015_vcvarsall_bat, L"v140", supported_archictectures }); + found_toolsets.push_back( + {vs2015_dumpbin_exe, vs2015_vcvarsall_bat, L"v140", supported_architectures}); } } } @@ -337,22 +336,20 @@ namespace vcpkg paths_examined.push_back(vcvarsall_bat); if (!fs.exists(vcvarsall_bat)) continue; - //Get all supported architecturs + // Get all supported architectures std::vector supported_architectures; if (fs.exists(vcvarsall_dir / "vcvars32.bat")) - supported_architectures.push_back({L"x86", CPU::X86,CPU::X86 }); + supported_architectures.push_back({L"x86", CPU::X86, CPU::X86}); if (fs.exists(vcvarsall_dir / "vcvars64.bat")) - supported_architectures.push_back({L"amd64", CPU::X64,CPU::X64 }); - if (fs.exists(vcvarsall_dir / "vcvarsarm.bat")) - supported_architectures.push_back({L"arm", CPU::ARM,CPU::ARM }); + supported_architectures.push_back({L"amd64", CPU::X64, CPU::X64}); if (fs.exists(vcvarsall_dir / "vcvarsx86_amd64.bat")) - supported_architectures.push_back({L"x86_amd64",CPU::X86,CPU::X64 }); + supported_architectures.push_back({L"x86_amd64", CPU::X86, CPU::X64}); if (fs.exists(vcvarsall_dir / "vcvarsx86_arm.bat")) - supported_architectures.push_back({L"x86_arm", CPU::X86,CPU::ARM }); + supported_architectures.push_back({L"x86_arm", CPU::X86, CPU::ARM}); if (fs.exists(vcvarsall_dir / "vcvarsamd64_x86.bat")) - supported_architectures.push_back({L"amd64_x86", CPU::X64,CPU::X86 }); + supported_architectures.push_back({L"amd64_x86", CPU::X64, CPU::X86}); if (fs.exists(vcvarsall_dir / "vcvarsamd64_arm.bat")) - supported_architectures.push_back({L"amd64_arm", CPU::X64,CPU::ARM }); + supported_architectures.push_back({L"amd64_arm", CPU::X64, CPU::ARM}); // Locate the "best" MSVC toolchain version const fs::path msvc_path = vc_dir / "Tools" / "MSVC"; diff --git a/toolsrc/src/vcpkg_Build.cpp b/toolsrc/src/vcpkg_Build.cpp index b0053766e..2b6950bc0 100644 --- a/toolsrc/src/vcpkg_Build.cpp +++ b/toolsrc/src/vcpkg_Build.cpp @@ -38,33 +38,18 @@ namespace vcpkg::Build CWStringView to_vcvarsall_toolchain(const std::string& target_architecture, const Toolset& toolset) { - using CPU = System::CPUArchitecture; - - static constexpr ToolsetArchOption X86 = {L"x86", CPU::X86, CPU::X86}; - static constexpr ToolsetArchOption X86_X64 = {L"x86_x64", CPU::X86, CPU::X64}; - static constexpr ToolsetArchOption X86_ARM = {L"x86_arm", CPU::X86, CPU::ARM}; - static constexpr ToolsetArchOption X86_ARM64 = {L"x86_arm64", CPU::X86, CPU::ARM64}; - - static constexpr ToolsetArchOption X64 = {L"amd64", CPU::X64, CPU::X64}; - static constexpr ToolsetArchOption X64_X86 = {L"amd64_x86", CPU::X64, CPU::X86}; - static constexpr ToolsetArchOption X64_ARM = {L"amd64_arm", CPU::X64, CPU::ARM}; - static constexpr ToolsetArchOption X64_ARM64 = {L"amd64_arm64", CPU::X64, CPU::ARM64}; - - static constexpr std::array VALUES = { - X64, X64_X86, X64_ARM, X64_ARM64, X86, X86_X64, X86_ARM, X86_ARM64}; - - auto target_arch = System::to_cpu_architecture(target_architecture); + auto maybe_target_arch = System::to_cpu_architecture(target_architecture); + Checks::check_exit( + VCPKG_LINE_INFO, maybe_target_arch.has_value(), "Invalid architecture string: %s", target_architecture); + auto target_arch = maybe_target_arch.value_or_exit(VCPKG_LINE_INFO); auto host_architectures = System::get_supported_host_architectures(); - for (auto&& value : VALUES) + for (auto&& host : host_architectures) { - if (target_arch != value.target_arch || - std::find(host_architectures.begin(), host_architectures.end(), value.host_arch) == host_architectures.end() || - std::find(toolset.supported_architectures.begin(), toolset.supported_architectures.end(), value) == toolset.supported_architectures.end() - ) - continue; - - return value.name; + auto it = Util::find_if(toolset.supported_architectures, [&](const ToolsetArchOption& opt) { + return host == opt.host_arch && target_arch == opt.target_arch; + }); + if (it != toolset.supported_architectures.end()) return it->name; } Checks::exit_with_message(VCPKG_LINE_INFO, "Unsupported toolchain combination %s", target_architecture); -- cgit v1.2.3 From 330b29732c8b178639f78c6fad10b9ec84f7669b Mon Sep 17 00:00:00 2001 From: atkawa7 Date: Sat, 26 Aug 2017 12:17:39 -0700 Subject: [vcpkg] free memory CommandLineToArgvW --- toolsrc/src/vcpkg_metrics_uploader.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg_metrics_uploader.cpp b/toolsrc/src/vcpkg_metrics_uploader.cpp index c6670c625..cef4f4756 100644 --- a/toolsrc/src/vcpkg_metrics_uploader.cpp +++ b/toolsrc/src/vcpkg_metrics_uploader.cpp @@ -13,4 +13,6 @@ int WINAPI WinMain(_In_ HINSTANCE, _In_opt_ HINSTANCE, _In_ LPSTR, _In_ int) Checks::check_exit(VCPKG_LINE_INFO, argCount == 2, "Requires exactly one argument, the path to the payload file"); auto v = Files::get_real_filesystem().read_contents(szArgList[1]).value_or_exit(VCPKG_LINE_INFO); Metrics::g_metrics.lock()->upload(v); + LocalFree(szArgList); + return 0; } -- cgit v1.2.3 From 8a79566c645e4b2862d7b094d2e2c4a1fd889b7f Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Sun, 27 Aug 2017 22:03:18 -0700 Subject: Update CHANGELOG and bump version to v0.0.85 --- toolsrc/VERSION.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/VERSION.txt b/toolsrc/VERSION.txt index fef58cb81..d27b8ca83 100644 --- a/toolsrc/VERSION.txt +++ b/toolsrc/VERSION.txt @@ -1 +1 @@ -"0.0.84" \ No newline at end of file +"0.0.85" \ No newline at end of file -- cgit v1.2.3 From 21402365061b454f525bbc2dfb1a2ae889eaa286 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 28 Aug 2017 14:42:44 -0700 Subject: Fix /permissive- issue --- toolsrc/include/vcpkg_Dependencies.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg_Dependencies.h b/toolsrc/include/vcpkg_Dependencies.h index c1f6ad9a5..235abb839 100644 --- a/toolsrc/include/vcpkg_Dependencies.h +++ b/toolsrc/include/vcpkg_Dependencies.h @@ -45,9 +45,9 @@ namespace vcpkg::Dependencies InstallPlanAction(); - InstallPlanAction::InstallPlanAction(const PackageSpec& spec, - const std::unordered_set& features, - const RequestType& request_type); + InstallPlanAction(const PackageSpec& spec, + const std::unordered_set& features, + const RequestType& request_type); InstallPlanAction(const PackageSpec& spec, const AnyParagraph& any_paragraph, const RequestType& request_type); InstallPlanAction(const PackageSpec& spec, const SourceControlFile& any_paragraph, -- cgit v1.2.3 From da299cb49cccd6cbcdcd18d66108311628337846 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 28 Aug 2017 16:59:59 -0700 Subject: Add missing const keywords --- toolsrc/src/commands_export.cpp | 18 ++++++++---------- toolsrc/src/vcpkg.cpp | 20 ++++++++++---------- 2 files changed, 18 insertions(+), 20 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/commands_export.cpp b/toolsrc/src/commands_export.cpp index cbcb219b6..dbfb09aab 100644 --- a/toolsrc/src/commands_export.cpp +++ b/toolsrc/src/commands_export.cpp @@ -67,7 +67,7 @@ namespace vcpkg::Commands::Export for (const ExportPlanType plan_type : order) { - auto it = group_by_plan_type.find(plan_type); + const auto it = group_by_plan_type.find(plan_type); if (it == group_by_plan_type.cend()) { continue; @@ -205,11 +205,9 @@ namespace vcpkg::Commands::Export static Optional maybe_lookup(std::unordered_map const& m, std::string const& key) { - auto it = m.find(key); - if (it != m.end()) - return it->second; - else - return nullopt; + const auto it = m.find(key); + if (it != m.end()) return it->second; + return nullopt; } void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) @@ -266,7 +264,7 @@ namespace vcpkg::Commands::Export VCPKG_LINE_INFO, !maybe_nuget_version || nuget, "--nuget-version is only valid with --nuget"); // create the plan - StatusParagraphs status_db = database_load_check(paths); + const StatusParagraphs status_db = database_load_check(paths); std::vector export_plan = Dependencies::create_export_plan(paths, specs, status_db); Checks::check_exit(VCPKG_LINE_INFO, !export_plan.empty(), "Export plan cannot be empty"); @@ -285,7 +283,7 @@ namespace vcpkg::Commands::Export "Additional packages (*) need to be exported to complete this operation."); } - auto it = group_by_plan_type.find(ExportPlanType::PORT_AVAILABLE_BUT_NOT_BUILT); + const auto it = group_by_plan_type.find(ExportPlanType::PORT_AVAILABLE_BUT_NOT_BUILT); if (it != group_by_plan_type.cend() && !it->second.empty()) { System::println(System::Color::error, "There are packages that have not been built."); @@ -295,7 +293,7 @@ namespace vcpkg::Commands::Export Util::erase_remove_if( unbuilt, [](const ExportPlanAction* a) { return a->request_type != RequestType::USER_REQUESTED; }); - auto s = Strings::join(" ", unbuilt, [](const ExportPlanAction* a) { return a->spec.to_string(); }); + const auto s = Strings::join(" ", unbuilt, [](const ExportPlanAction* a) { return a->spec.to_string(); }); System::println("To build them, run:\n" " vcpkg install %s", s); @@ -360,7 +358,7 @@ namespace vcpkg::Commands::Export Checks::check_exit(VCPKG_LINE_INFO, !ec); } - auto print_next_step_info = [](const fs::path& prefix) { + const auto print_next_step_info = [](const fs::path& prefix) { const fs::path cmake_toolchain = prefix / "scripts" / "buildsystems" / "vcpkg.cmake"; const CMakeVariable cmake_variable = CMakeVariable(L"CMAKE_TOOLCHAIN_FILE", cmake_toolchain.generic_string()); diff --git a/toolsrc/src/vcpkg.cpp b/toolsrc/src/vcpkg.cpp index f37d079a6..781f03585 100644 --- a/toolsrc/src/vcpkg.cpp +++ b/toolsrc/src/vcpkg.cpp @@ -34,7 +34,7 @@ static void inner(const VcpkgCmdArguments& args) Checks::exit_fail(VCPKG_LINE_INFO); } - if (auto command_function = Commands::find(args.command, Commands::get_available_commands_type_c())) + if (const auto command_function = Commands::find(args.command, Commands::get_available_commands_type_c())) { return command_function(args); } @@ -47,7 +47,7 @@ static void inner(const VcpkgCmdArguments& args) else { const Optional vcpkg_root_dir_env = System::get_environment_variable(L"VCPKG_ROOT"); - if (auto v = vcpkg_root_dir_env.get()) + if (const auto v = vcpkg_root_dir_env.get()) { vcpkg_root_dir = fs::stdfs::absolute(*v); } @@ -67,10 +67,10 @@ static void inner(const VcpkgCmdArguments& args) vcpkg_root_dir.string(), expected_paths.error().message()); const VcpkgPaths paths = expected_paths.value_or_exit(VCPKG_LINE_INFO); - int exit_code = _wchdir(paths.root.c_str()); + const int exit_code = _wchdir(paths.root.c_str()); Checks::check_exit(VCPKG_LINE_INFO, exit_code == 0, "Changing the working dir failed"); - if (auto command_function = Commands::find(args.command, Commands::get_available_commands_type_b())) + if (const auto command_function = Commands::find(args.command, Commands::get_available_commands_type_b())) { return command_function(args, paths); } @@ -84,7 +84,7 @@ static void inner(const VcpkgCmdArguments& args) { const Optional vcpkg_default_triplet_env = System::get_environment_variable(L"VCPKG_DEFAULT_TRIPLET"); - if (auto v = vcpkg_default_triplet_env.get()) + if (const auto v = vcpkg_default_triplet_env.get()) { default_triplet = Triplet::from_canonical_name(Strings::to_utf8(*v)); } @@ -96,7 +96,7 @@ static void inner(const VcpkgCmdArguments& args) Input::check_triplet(default_triplet, paths); - if (auto command_function = Commands::find(args.command, Commands::get_available_commands_type_a())) + if (const auto command_function = Commands::find(args.command, Commands::get_available_commands_type_a())) { return command_function(args, paths, default_triplet); } @@ -118,7 +118,7 @@ static void loadConfig() try { auto maybe_pghs = Paragraphs::get_paragraphs(Files::get_real_filesystem(), localappdata / "vcpkg" / "config"); - if (auto p_pghs = maybe_pghs.get()) + if (const auto p_pghs = maybe_pghs.get()) { const auto& pghs = *p_pghs; @@ -212,9 +212,9 @@ int wmain(const int argc, const wchar_t* const* const argv) const VcpkgCmdArguments args = VcpkgCmdArguments::create_from_command_line(argc, argv); - if (auto p = args.printmetrics.get()) Metrics::g_metrics.lock()->set_print_metrics(*p); - if (auto p = args.sendmetrics.get()) Metrics::g_metrics.lock()->set_send_metrics(*p); - if (auto p = args.debug.get()) GlobalState::debugging = *p; + if (const auto p = args.printmetrics.get()) Metrics::g_metrics.lock()->set_print_metrics(*p); + if (const auto p = args.sendmetrics.get()) Metrics::g_metrics.lock()->set_send_metrics(*p); + if (const auto p = args.debug.get()) GlobalState::debugging = *p; Checks::register_console_ctrl_handler(); -- cgit v1.2.3 From 75cc10b0f3351241588d307c625138aa358499fe Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 28 Aug 2017 17:10:50 -0700 Subject: Add missing const --- toolsrc/include/vcpkg_Build.h | 2 +- toolsrc/include/vcpkg_Strings.h | 2 +- toolsrc/src/BinaryParagraph.cpp | 2 +- toolsrc/src/coff_file_reader.cpp | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg_Build.h b/toolsrc/include/vcpkg_Build.h index e12ed3b1d..fc6f28e24 100644 --- a/toolsrc/include/vcpkg_Build.h +++ b/toolsrc/include/vcpkg_Build.h @@ -161,7 +161,7 @@ namespace vcpkg::Build inline bool is_enabled(BuildPolicy policy) const { - auto it = m_policies.find(policy); + const auto it = m_policies.find(policy); if (it != m_policies.cend()) return it->second; return false; } diff --git a/toolsrc/include/vcpkg_Strings.h b/toolsrc/include/vcpkg_Strings.h index e94742c8f..7cea63676 100644 --- a/toolsrc/include/vcpkg_Strings.h +++ b/toolsrc/include/vcpkg_Strings.h @@ -71,7 +71,7 @@ namespace vcpkg::Strings } std::basic_string output; - size_t size = v.size(); + const size_t size = v.size(); output.append(transformer(v[0])); diff --git a/toolsrc/src/BinaryParagraph.cpp b/toolsrc/src/BinaryParagraph.cpp index 9abd388b9..97923c3c4 100644 --- a/toolsrc/src/BinaryParagraph.cpp +++ b/toolsrc/src/BinaryParagraph.cpp @@ -56,7 +56,7 @@ namespace vcpkg this->default_features = parse_comma_list(parser.optional_field(Fields::DEFAULTFEATURES)); } - if (auto err = parser.error_info(this->spec.to_string())) + if (const auto err = parser.error_info(this->spec.to_string())) { System::println( System::Color::error, "Error: while parsing the Binary Paragraph for %s", this->spec.to_string()); diff --git a/toolsrc/src/coff_file_reader.cpp b/toolsrc/src/coff_file_reader.cpp index 6c38c452b..10c1437c6 100644 --- a/toolsrc/src/coff_file_reader.cpp +++ b/toolsrc/src/coff_file_reader.cpp @@ -24,7 +24,7 @@ namespace vcpkg::COFFFileReader template static T peek_value_from_stream(fstream& fs) { - fpos_t original_pos = fs.tellg().seekpos(); + const fpos_t original_pos = fs.tellg().seekpos(); T data; fs.read(reinterpret_cast(&data), sizeof data); fs.seekg(original_pos); @@ -236,7 +236,7 @@ namespace vcpkg::COFFFileReader read_and_verify_PE_signature(fs); CoffFileHeader header = CoffFileHeader::read(fs); - MachineType machine = header.machine_type(); + const MachineType machine = header.machine_type(); return {machine}; } @@ -282,7 +282,7 @@ namespace vcpkg::COFFFileReader marker.advance_by(ArchiveMemberHeader::HEADER_SIZE + second_linker_member_header.member_size()); marker.seek_to_marker(fs); - bool hasLongnameMemberHeader = peek_value_from_stream(fs) == 0x2F2F; + const bool hasLongnameMemberHeader = peek_value_from_stream(fs) == 0x2F2F; if (hasLongnameMemberHeader) { const ArchiveMemberHeader longnames_member_header = ArchiveMemberHeader::read(fs); -- cgit v1.2.3 From 269c6b4d55192492d8ad254723b5883f13794314 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 28 Aug 2017 17:12:42 -0700 Subject: Use const. Take str by reference --- toolsrc/src/commands_build.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/commands_build.cpp b/toolsrc/src/commands_build.cpp index 4da9cede2..71cd1b845 100644 --- a/toolsrc/src/commands_build.cpp +++ b/toolsrc/src/commands_build.cpp @@ -29,8 +29,8 @@ namespace vcpkg::Commands::BuildCommand const PackageSpec& spec = full_spec.package_spec; if (options.find(OPTION_CHECKS_ONLY) != options.end()) { - auto pre_build_info = Build::PreBuildInfo::from_triplet_file(paths, spec.triplet()); - auto build_info = Build::read_build_info(paths.get_filesystem(), paths.build_info_file_path(spec)); + const auto pre_build_info = Build::PreBuildInfo::from_triplet_file(paths, spec.triplet()); + const auto build_info = Build::read_build_info(paths.get_filesystem(), paths.build_info_file_path(spec)); const size_t error_count = PostBuildLint::perform_all_checks(spec, paths, pre_build_info, build_info); Checks::check_exit(VCPKG_LINE_INFO, error_count == 0); Checks::exit_success(VCPKG_LINE_INFO); @@ -45,7 +45,7 @@ namespace vcpkg::Commands::BuildCommand Checks::exit_fail(VCPKG_LINE_INFO); } - for (std::string str : full_spec.features) + for (const std::string& str : full_spec.features) { System::println("%s \n", str); } @@ -56,8 +56,8 @@ namespace vcpkg::Commands::BuildCommand scf->core_paragraph->name, spec.name()); - StatusParagraphs status_db = database_load_check(paths); - Build::BuildPackageOptions build_package_options{Build::UseHeadVersion::NO, Build::AllowDownloads::YES}; + const StatusParagraphs status_db = database_load_check(paths); + const Build::BuildPackageOptions build_package_options{Build::UseHeadVersion::NO, Build::AllowDownloads::YES}; const Build::BuildPackageConfig build_config{ *scf->core_paragraph, spec.triplet(), paths.port_dir(spec), build_package_options}; @@ -92,7 +92,7 @@ namespace vcpkg::Commands::BuildCommand static const std::string example = Commands::Help::create_example_string("build zlib:x64-windows"); args.check_exact_arg_count( 1, example); // Build only takes a single package and all dependencies must already be installed - std::string command_argument = args.command_arguments.at(0); + const std::string command_argument = args.command_arguments.at(0); const FullPackageSpec spec = Input::check_and_get_full_package_spec(command_argument, default_triplet, example); Input::check_triplet(spec.package_spec.triplet(), paths); const std::unordered_set options = -- cgit v1.2.3 From 4a43e3e7f954cb79a71ab05dde6b5345d011db83 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 28 Aug 2017 17:16:38 -0700 Subject: Use const --- toolsrc/src/commands_cache.cpp | 2 +- toolsrc/src/commands_depends.cpp | 2 +- toolsrc/src/commands_edit.cpp | 9 +++++---- 3 files changed, 7 insertions(+), 6 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/commands_cache.cpp b/toolsrc/src/commands_cache.cpp index 75de78461..fa0c62ee4 100644 --- a/toolsrc/src/commands_cache.cpp +++ b/toolsrc/src/commands_cache.cpp @@ -15,7 +15,7 @@ namespace vcpkg::Commands::Cache { const Expected> pghs = Paragraphs::get_single_paragraph(paths.get_filesystem(), path / "CONTROL"); - if (auto p = pghs.get()) + if (const auto p = pghs.get()) { const BinaryParagraph binary_paragraph = BinaryParagraph(*p); output.push_back(binary_paragraph); diff --git a/toolsrc/src/commands_depends.cpp b/toolsrc/src/commands_depends.cpp index 49e1c6c01..ffad91226 100644 --- a/toolsrc/src/commands_depends.cpp +++ b/toolsrc/src/commands_depends.cpp @@ -46,7 +46,7 @@ namespace vcpkg::Commands::DependInfo for (auto&& source_control_file : source_control_files) { const SourceParagraph& source_paragraph = *source_control_file->core_paragraph; - auto s = Strings::join(", ", source_paragraph.depends, [](const Dependency& d) { return d.name(); }); + const auto s = Strings::join(", ", source_paragraph.depends, [](const Dependency& d) { return d.name(); }); System::println("%s: %s", source_paragraph.name, s); } diff --git a/toolsrc/src/commands_edit.cpp b/toolsrc/src/commands_edit.cpp index 72005a461..c0fe27fde 100644 --- a/toolsrc/src/commands_edit.cpp +++ b/toolsrc/src/commands_edit.cpp @@ -27,7 +27,7 @@ namespace vcpkg::Commands::Edit if (env_EDITOR.empty()) { const Optional env_EDITOR_optional = System::get_environment_variable(L"EDITOR"); - if (auto e = env_EDITOR_optional.get()) + if (const auto e = env_EDITOR_optional.get()) { env_EDITOR = *e; } @@ -63,7 +63,7 @@ namespace vcpkg::Commands::Edit { const Optional code_installpath = System::get_registry_string(HKEY_LOCAL_MACHINE, keypath, L"InstallLocation"); - if (auto c = code_installpath.get()) + if (const auto c = code_installpath.get()) { auto p = fs::path(*c) / "Code.exe"; if (fs.exists(p)) @@ -91,11 +91,12 @@ namespace vcpkg::Commands::Edit { const auto buildtrees_current_dir = paths.buildtrees / port_name; - std::wstring cmdLine = Strings::wformat(LR"("%s" "%s" -n)", env_EDITOR, buildtrees_current_dir.native()); + const std::wstring cmdLine = + Strings::wformat(LR"("%s" "%s" -n)", env_EDITOR, buildtrees_current_dir.native()); Checks::exit_with_code(VCPKG_LINE_INFO, System::cmd_execute(cmdLine)); } - std::wstring cmdLine = Strings::wformat( + const std::wstring cmdLine = Strings::wformat( LR"("%s" "%s" "%s" -n)", env_EDITOR, portpath.native(), (portpath / "portfile.cmake").native()); Checks::exit_with_code(VCPKG_LINE_INFO, System::cmd_execute(cmdLine)); } -- cgit v1.2.3 From 0404a51e4a13f37a280241812ccddd745a4ca129 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 28 Aug 2017 17:20:29 -0700 Subject: [edit] Fix variable names to be consistence with vcpkg's convention --- toolsrc/src/commands_edit.cpp | 54 +++++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 27 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/commands_edit.cpp b/toolsrc/src/commands_edit.cpp index c0fe27fde..e72931e63 100644 --- a/toolsrc/src/commands_edit.cpp +++ b/toolsrc/src/commands_edit.cpp @@ -12,8 +12,8 @@ namespace vcpkg::Commands::Edit auto& fs = paths.get_filesystem(); - static const std::string example = Commands::Help::create_example_string("edit zlib"); - args.check_exact_arg_count(1, example); + static const std::string EXAMPLE = Commands::Help::create_example_string("edit zlib"); + args.check_exact_arg_count(1, EXAMPLE); const std::unordered_set options = args.check_and_get_optional_command_arguments({OPTION_BUILDTREES}); const std::string port_name = args.command_arguments.at(0); @@ -22,44 +22,44 @@ namespace vcpkg::Commands::Edit 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; + std::wstring env_editor; - if (env_EDITOR.empty()) + if (env_editor.empty()) { - const Optional env_EDITOR_optional = System::get_environment_variable(L"EDITOR"); - if (const auto e = env_EDITOR_optional.get()) + const Optional env_editor_optional = System::get_environment_variable(L"EDITOR"); + if (const auto e = env_editor_optional.get()) { - env_EDITOR = *e; + env_editor = *e; } } - if (env_EDITOR.empty()) + if (env_editor.empty()) { - const fs::path CODE_EXE_PATH = System::get_ProgramFiles_platform_bitness() / "Microsoft VS Code/Code.exe"; - if (fs.exists(CODE_EXE_PATH)) + const fs::path code_exe_path = System::get_ProgramFiles_platform_bitness() / "Microsoft VS Code/Code.exe"; + if (fs.exists(code_exe_path)) { - env_EDITOR = CODE_EXE_PATH; + env_editor = code_exe_path; } } - if (env_EDITOR.empty()) + 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)) + const fs::path code_exe_path = System::get_ProgramFiles_32_bit() / "Microsoft VS Code/Code.exe"; + if (fs.exists(code_exe_path)) { - env_EDITOR = CODE_EXE_PATH; + env_editor = code_exe_path; } } - if (env_EDITOR.empty()) + if (env_editor.empty()) { - static const std::array regkeys = { + static const std::array REGKEYS = { LR"(SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{C26E74D1-022E-4238-8B9D-1E7564A36CC9}_is1)", LR"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{C26E74D1-022E-4238-8B9D-1E7564A36CC9}_is1)", LR"(SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{F8A2A208-72B3-4D61-95FC-8A65D340689B}_is1)", LR"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{F8A2A208-72B3-4D61-95FC-8A65D340689B}_is1)", }; - for (auto&& keypath : regkeys) + for (auto&& keypath : REGKEYS) { const Optional code_installpath = System::get_registry_string(HKEY_LOCAL_MACHINE, keypath, L"InstallLocation"); @@ -68,20 +68,20 @@ namespace vcpkg::Commands::Edit auto p = fs::path(*c) / "Code.exe"; if (fs.exists(p)) { - env_EDITOR = p.native(); + env_editor = p.native(); break; } auto p_insiders = fs::path(*c) / "Code - Insiders.exe"; if (fs.exists(p_insiders)) { - env_EDITOR = p_insiders.native(); + env_editor = p_insiders.native(); break; } } } } - if (env_EDITOR.empty()) + if (env_editor.empty()) { Checks::exit_with_message( VCPKG_LINE_INFO, "Visual Studio Code was not found and the environment variable EDITOR is not set"); @@ -91,13 +91,13 @@ namespace vcpkg::Commands::Edit { const auto buildtrees_current_dir = paths.buildtrees / port_name; - const std::wstring cmdLine = - Strings::wformat(LR"("%s" "%s" -n)", env_EDITOR, buildtrees_current_dir.native()); - Checks::exit_with_code(VCPKG_LINE_INFO, System::cmd_execute(cmdLine)); + const std::wstring cmd_line = + Strings::wformat(LR"("%s" "%s" -n)", env_editor, buildtrees_current_dir.native()); + Checks::exit_with_code(VCPKG_LINE_INFO, System::cmd_execute(cmd_line)); } - const std::wstring cmdLine = Strings::wformat( - LR"("%s" "%s" "%s" -n)", env_EDITOR, portpath.native(), (portpath / "portfile.cmake").native()); - Checks::exit_with_code(VCPKG_LINE_INFO, System::cmd_execute(cmdLine)); + const std::wstring cmd_line = Strings::wformat( + LR"("%s" "%s" "%s" -n)", env_editor, portpath.native(), (portpath / "portfile.cmake").native()); + Checks::exit_with_code(VCPKG_LINE_INFO, System::cmd_execute(cmd_line)); } } -- cgit v1.2.3 From 98074f5a21717a851323019b75d9c0fdb599eaae Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 28 Aug 2017 17:21:34 -0700 Subject: [commands_env.cpp] Use const. Naming scheme --- toolsrc/src/commands_env.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/commands_env.cpp b/toolsrc/src/commands_env.cpp index dd7172b89..073c501f5 100644 --- a/toolsrc/src/commands_env.cpp +++ b/toolsrc/src/commands_env.cpp @@ -8,12 +8,13 @@ namespace vcpkg::Commands::Env { void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) { - static const std::string example = Commands::Help::create_example_string(R"(env --Triplet x64-windows)"); - args.check_exact_arg_count(0, example); + static const std::string EXAMPLE = Commands::Help::create_example_string(R"(env --Triplet x64-windows)"); + args.check_exact_arg_count(0, EXAMPLE); args.check_and_get_optional_command_arguments({}); - auto pre_build_info = Build::PreBuildInfo::from_triplet_file(paths, default_triplet); - System::cmd_execute_clean(Build::make_build_env_cmd(pre_build_info, paths.get_toolset(pre_build_info.platform_toolset)) + L" && cmd"); + const auto pre_build_info = Build::PreBuildInfo::from_triplet_file(paths, default_triplet); + System::cmd_execute_clean( + Build::make_build_env_cmd(pre_build_info, paths.get_toolset(pre_build_info.platform_toolset)) + L" && cmd"); Checks::exit_success(VCPKG_LINE_INFO); } -- cgit v1.2.3 From 4d952a5e1d286e281a837f332fbac9e43866d933 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 28 Aug 2017 17:22:40 -0700 Subject: [commands_hash.cpp] Use const. Naming scheme. --- toolsrc/src/commands_hash.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/commands_hash.cpp b/toolsrc/src/commands_hash.cpp index 0da2b031f..b3211b9f8 100644 --- a/toolsrc/src/commands_hash.cpp +++ b/toolsrc/src/commands_hash.cpp @@ -6,22 +6,22 @@ namespace vcpkg::Commands::Hash { - static void do_file_hash(fs::path const& path, std::wstring const& hashType) + static void do_file_hash(fs::path const& path, std::wstring const& hash_type) { - auto cmd_line = Strings::wformat(LR"(CertUtil.exe -hashfile "%s" %s)", path.c_str(), hashType); - auto ec_data = System::cmd_execute_and_capture_output(cmd_line); + const auto cmd_line = Strings::wformat(LR"(CertUtil.exe -hashfile "%s" %s)", path.c_str(), hash_type); + const auto ec_data = System::cmd_execute_and_capture_output(cmd_line); Checks::check_exit( VCPKG_LINE_INFO, ec_data.exit_code == 0, "Running command:\n %s\n failed", Strings::to_utf8(cmd_line)); std::string const& output = ec_data.output; - auto start = output.find_first_of("\r\n"); + const auto start = output.find_first_of("\r\n"); Checks::check_exit(VCPKG_LINE_INFO, start != std::string::npos, "Unexpected output format from command: %s", Strings::to_utf8(cmd_line)); - auto end = output.find_first_of("\r\n", start + 1); + const auto end = output.find_first_of("\r\n", start + 1); Checks::check_exit(VCPKG_LINE_INFO, end != std::string::npos, "Unexpected output format from command: %s", @@ -34,11 +34,11 @@ namespace vcpkg::Commands::Hash void perform_and_exit(const VcpkgCmdArguments& args) { - static const std::string example = + static const std::string EXAMPLE = Strings::format("The argument should be a file path\n%s", Commands::Help::create_example_string("hash boost_1_62_0.tar.bz2")); - args.check_min_arg_count(1, example); - args.check_max_arg_count(2, example); + args.check_min_arg_count(1, EXAMPLE); + args.check_max_arg_count(2, EXAMPLE); args.check_and_get_optional_command_arguments({}); if (args.command_arguments.size() == 1) -- cgit v1.2.3 From 5b42ec9b5d7277d9a4452c4c3a109770d9437205 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Mon, 28 Aug 2017 17:26:01 -0700 Subject: [vcpkg] Hack to fix codepage problems -- root cause unknown --- toolsrc/src/VcpkgPaths.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp index 1b76fdc24..4bceff784 100644 --- a/toolsrc/src/VcpkgPaths.cpp +++ b/toolsrc/src/VcpkgPaths.cpp @@ -264,7 +264,14 @@ namespace vcpkg const std::wstring cmd = System::create_powershell_script_cmd(script); System::ExitCodeAndOutput ec_data = System::cmd_execute_and_capture_output(cmd); Checks::check_exit(VCPKG_LINE_INFO, ec_data.exit_code == 0, "Could not run script to detect VS 2017 instances"); - return Strings::split(ec_data.output, "\n"); + return Util::fmap(Strings::split(ec_data.output, "\n"), [](const std::string& line) { + auto colon_pos = line.find(':'); + if (colon_pos != std::string::npos && colon_pos > 0) + { + return line.substr(colon_pos - 1); + } + return line; + }); } static Optional get_VS2015_installation_instance() -- cgit v1.2.3 From f3156ae3e4b62159c178f12cdba58e6a661832d0 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 28 Aug 2017 18:01:24 -0700 Subject: [vcpkg_Build.cpp] USe const. Misc fixes --- toolsrc/src/vcpkg_Build.cpp | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg_Build.cpp b/toolsrc/src/vcpkg_Build.cpp index 0ae63d4e3..bec9c9ef7 100644 --- a/toolsrc/src/vcpkg_Build.cpp +++ b/toolsrc/src/vcpkg_Build.cpp @@ -64,8 +64,8 @@ namespace vcpkg::Build tonull = L""; } - auto arch = to_vcvarsall_toolchain(pre_build_info.target_architecture, toolset); - auto target = to_vcvarsall_target(pre_build_info.cmake_system_name); + const auto arch = to_vcvarsall_toolchain(pre_build_info.target_architecture, toolset); + const auto target = to_vcvarsall_target(pre_build_info.cmake_system_name); return Strings::wformat(LR"("%s" %s %s %s 2>&1)", toolset.vcvarsall.native(), arch, target, tonull); } @@ -85,7 +85,7 @@ namespace vcpkg::Build BinaryControlFile& bcf) { BinaryParagraph bpgh(source_paragraph, triplet); - if (auto p_ver = build_info.version.get()) + if (const auto p_ver = build_info.version.get()) { bpgh.version = *p_ver; } @@ -132,7 +132,7 @@ namespace vcpkg::Build const fs::path& git_exe_path = paths.get_git_exe(); const fs::path ports_cmake_script_path = paths.ports_cmake; - auto pre_build_info = PreBuildInfo::from_triplet_file(paths, triplet); + const auto pre_build_info = PreBuildInfo::from_triplet_file(paths, triplet); const Toolset& toolset = paths.get_toolset(pre_build_info.platform_toolset); const auto cmd_set_environment = make_build_env_cmd(pre_build_info, toolset); @@ -171,8 +171,8 @@ namespace vcpkg::Build const ElapsedTime timer = ElapsedTime::create_started(); - int return_code = System::cmd_execute_clean(command); - auto buildtimeus = timer.microseconds(); + const int return_code = System::cmd_execute_clean(command); + const auto buildtimeus = timer.microseconds(); const auto spec_string = spec.to_string(); { @@ -186,7 +186,7 @@ namespace vcpkg::Build } } - auto build_info = read_build_info(paths.get_filesystem(), paths.build_info_file_path(spec)); + const BuildInfo build_info = read_build_info(paths.get_filesystem(), paths.build_info_file_path(spec)); const size_t error_count = PostBuildLint::perform_all_checks(spec, paths, pre_build_info, build_info); BinaryControlFile bcf; @@ -269,7 +269,7 @@ namespace vcpkg::Build parser.required_field(BuildInfoRequiredField::CRT_LINKAGE, crt_linkage_as_string); auto crtlinkage = to_linkage_type(crt_linkage_as_string); - if (auto p = crtlinkage.get()) + if (const auto p = crtlinkage.get()) build_info.crt_linkage = *p; else Checks::exit_with_message(VCPKG_LINE_INFO, "Invalid crt linkage type: [%s]", crt_linkage_as_string); @@ -279,7 +279,7 @@ namespace vcpkg::Build std::string library_linkage_as_string; parser.required_field(BuildInfoRequiredField::LIBRARY_LINKAGE, library_linkage_as_string); auto liblinkage = to_linkage_type(library_linkage_as_string); - if (auto p = liblinkage.get()) + if (const auto p = liblinkage.get()) build_info.library_linkage = *p; else Checks::exit_with_message( @@ -292,9 +292,8 @@ namespace vcpkg::Build for (auto policy : g_all_policies) { const auto setting = parser.optional_field(to_string(policy)); - if (setting.empty()) - continue; - else if (setting == "enabled") + if (setting.empty()) continue; + if (setting == "enabled") policies.emplace(policy, true); else if (setting == "disabled") policies.emplace(policy, false); @@ -303,7 +302,7 @@ namespace vcpkg::Build VCPKG_LINE_INFO, "Unknown setting for policy '%s': %s", to_string(policy), setting); } - if (auto err = parser.error_info("PostBuildInformation")) + if (const auto err = parser.error_info("PostBuildInformation")) { print_error_message(err); Checks::exit_fail(VCPKG_LINE_INFO); @@ -337,14 +336,14 @@ namespace vcpkg::Build }); const std::wstring command = Strings::wformat(LR"(%s)", cmd_launch_cmake); - auto ec_data = System::cmd_execute_and_capture_output(command); + const auto ec_data = System::cmd_execute_and_capture_output(command); Checks::check_exit(VCPKG_LINE_INFO, ec_data.exit_code == 0); const std::vector lines = Strings::split(ec_data.output, "\n"); PreBuildInfo pre_build_info; - auto e = lines.cend(); + const auto e = lines.cend(); auto cur = std::find(lines.cbegin(), e, FLAG_GUID); if (cur != e) ++cur; -- cgit v1.2.3 From 63a9572ecfeccc143de6bc10a23c453823996dff Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 28 Aug 2017 18:03:01 -0700 Subject: [vcpkg_Dependencies.cpp] Order of initialization --- toolsrc/src/vcpkg_Dependencies.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg_Dependencies.cpp b/toolsrc/src/vcpkg_Dependencies.cpp index 4525fa02a..279f5f870 100644 --- a/toolsrc/src/vcpkg_Dependencies.cpp +++ b/toolsrc/src/vcpkg_Dependencies.cpp @@ -166,7 +166,7 @@ namespace vcpkg::Dependencies InstallPlanAction::InstallPlanAction(const PackageSpec& spec, const AnyParagraph& any_paragraph, const RequestType& request_type) - : spec(spec), request_type(request_type), plan_type(InstallPlanType::UNKNOWN), any_paragraph(any_paragraph) + : spec(spec), any_paragraph(any_paragraph), plan_type(InstallPlanType::UNKNOWN), request_type(request_type) { if (auto p = any_paragraph.status_paragraph.get()) { -- cgit v1.2.3 From 174c264b449dc77ab71ae07aa78673239ebd0c48 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 28 Aug 2017 18:03:43 -0700 Subject: [vcpkg_Dependencies.cpp] Remove redundant else --- toolsrc/src/vcpkg_Dependencies.cpp | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg_Dependencies.cpp b/toolsrc/src/vcpkg_Dependencies.cpp index 279f5f870..2c619c3ac 100644 --- a/toolsrc/src/vcpkg_Dependencies.cpp +++ b/toolsrc/src/vcpkg_Dependencies.cpp @@ -193,17 +193,15 @@ namespace vcpkg::Dependencies { return this->spec.to_string(); } - else - { - std::string features; - for (auto&& feature : this->feature_list) - { - features += feature + ","; - } - features.pop_back(); - return this->spec.name() + "[" + features + "]:" + this->spec.triplet().to_string(); + std::string features; + for (auto&& feature : this->feature_list) + { + features += feature + ","; } + features.pop_back(); + + return this->spec.name() + "[" + features + "]:" + this->spec.triplet().to_string(); } bool InstallPlanAction::compare_by_name(const InstallPlanAction* left, const InstallPlanAction* right) -- cgit v1.2.3 From dc46f68f6a2e7a4079c6ad1e1545705d379b9a51 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 28 Aug 2017 18:36:25 -0700 Subject: [Strings::join()] Modify to work for any container --- toolsrc/include/vcpkg_Strings.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg_Strings.h b/toolsrc/include/vcpkg_Strings.h index 7cea63676..a7c6148d7 100644 --- a/toolsrc/include/vcpkg_Strings.h +++ b/toolsrc/include/vcpkg_Strings.h @@ -65,20 +65,20 @@ namespace vcpkg::Strings template std::basic_string join(const CharType* delimiter, const Container& v, Transformer transformer) { - if (v.size() == 0) + const auto begin = v.begin(); + const auto end = v.end(); + + if (begin == end) { return std::basic_string(); } std::basic_string output; - const size_t size = v.size(); - - output.append(transformer(v[0])); - - for (size_t i = 1; i < size; ++i) + output.append(transformer(*begin)); + for (auto it = std::next(begin); it != end; ++it) { output.append(delimiter); - output.append(transformer(v[i])); + output.append(transformer(*it)); } return output; @@ -86,7 +86,7 @@ namespace vcpkg::Strings template std::basic_string join(const CharType* delimiter, const Container& v) { - using Element = decltype(v[0]); + using Element = decltype(*v.begin()); return join(delimiter, v, [](const Element& x) -> const Element& { return x; }); } -- cgit v1.2.3 From c2571cf8bca08bc6d1de7e23025a0dfdb1db4bb9 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 28 Aug 2017 18:37:36 -0700 Subject: Use Strings::join() and Strings::format() --- toolsrc/src/vcpkg_Dependencies.cpp | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg_Dependencies.cpp b/toolsrc/src/vcpkg_Dependencies.cpp index 2c619c3ac..57f475df5 100644 --- a/toolsrc/src/vcpkg_Dependencies.cpp +++ b/toolsrc/src/vcpkg_Dependencies.cpp @@ -7,6 +7,7 @@ #include "vcpkg_Dependencies.h" #include "vcpkg_Files.h" #include "vcpkg_Graphs.h" +#include "vcpkg_Strings.h" #include "vcpkg_Util.h" #include "vcpkglib.h" @@ -194,14 +195,8 @@ namespace vcpkg::Dependencies return this->spec.to_string(); } - std::string features; - for (auto&& feature : this->feature_list) - { - features += feature + ","; - } - features.pop_back(); - - return this->spec.name() + "[" + features + "]:" + this->spec.triplet().to_string(); + const std::string features = Strings::join(",", this->feature_list); + return Strings::format("%s[%s]:%s", this->spec.name(), features, this->spec.triplet()); } bool InstallPlanAction::compare_by_name(const InstallPlanAction* left, const InstallPlanAction* right) -- cgit v1.2.3 From b1cebc0740765b90af905d6f1c90ea9830506e1b Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 28 Aug 2017 18:39:10 -0700 Subject: Make member functions const --- toolsrc/src/vcpkg_Dependencies.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg_Dependencies.cpp b/toolsrc/src/vcpkg_Dependencies.cpp index 57f475df5..4d0c3c928 100644 --- a/toolsrc/src/vcpkg_Dependencies.cpp +++ b/toolsrc/src/vcpkg_Dependencies.cpp @@ -37,7 +37,7 @@ namespace vcpkg::Dependencies { Cluster* ptr; - Cluster* operator->() { return ptr; } + Cluster* operator->() const { return ptr; } }; bool operator==(const ClusterPtr& l, const ClusterPtr& r) { return l.ptr == r.ptr; } @@ -87,7 +87,7 @@ namespace vcpkg::Dependencies } private: - void cluster_from_scf(const SourceControlFile& scf, Cluster& out_cluster) + void cluster_from_scf(const SourceControlFile& scf, Cluster& out_cluster) const { FeatureNodeEdges core_dependencies; core_dependencies.build_edges = -- cgit v1.2.3 From 259d6f83b46da9b7127eb8c7907cdcb74ce5bdf4 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 28 Aug 2017 18:45:30 -0700 Subject: Introduce Strings::EMPTY --- toolsrc/include/vcpkg_Strings.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg_Strings.h b/toolsrc/include/vcpkg_Strings.h index a7c6148d7..5dd420232 100644 --- a/toolsrc/include/vcpkg_Strings.h +++ b/toolsrc/include/vcpkg_Strings.h @@ -36,6 +36,9 @@ namespace vcpkg::Strings::details namespace vcpkg::Strings { + static constexpr const CStringView EMPTY = ""; + static constexpr const CWStringView WEMPTY = L""; + template std::string format(const char* fmtstr, const Args&... args) { -- cgit v1.2.3 From 7d46adb47ca332a072ffb382e4a533aa68a17062 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 28 Aug 2017 18:46:28 -0700 Subject: Use Strings::EMPTY --- toolsrc/include/vcpkg_System.h | 2 +- toolsrc/src/BinaryParagraph.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg_System.h b/toolsrc/include/vcpkg_System.h index 32da6e39c..86bb24aad 100644 --- a/toolsrc/include/vcpkg_System.h +++ b/toolsrc/include/vcpkg_System.h @@ -23,7 +23,7 @@ namespace vcpkg::System ExitCodeAndOutput cmd_execute_and_capture_output(const CWStringView cmd_line); - std::wstring create_powershell_script_cmd(const fs::path& script_path, const CWStringView args = L""); + std::wstring create_powershell_script_cmd(const fs::path& script_path, const CWStringView args = Strings::WEMPTY); enum class Color { diff --git a/toolsrc/src/BinaryParagraph.cpp b/toolsrc/src/BinaryParagraph.cpp index 97923c3c4..783fa6ace 100644 --- a/toolsrc/src/BinaryParagraph.cpp +++ b/toolsrc/src/BinaryParagraph.cpp @@ -80,10 +80,10 @@ namespace vcpkg BinaryParagraph::BinaryParagraph(const SourceParagraph& spgh, const FeatureParagraph& fpgh, const Triplet& triplet) { this->spec = PackageSpec::from_name_and_triplet(spgh.name, triplet).value_or_exit(VCPKG_LINE_INFO); - this->version = ""; + this->version = Strings::EMPTY; this->feature = fpgh.name; this->description = fpgh.description; - this->maintainer = ""; + this->maintainer = Strings::EMPTY; this->depends = filter_dependencies(fpgh.depends, triplet); } -- cgit v1.2.3 From f3d803addfb3d84d828786d2e6b0b8a34f2fc494 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 28 Aug 2017 18:54:48 -0700 Subject: Introduce Strings::is_empty() --- toolsrc/include/vcpkg_Strings.h | 3 +++ toolsrc/src/vcpkg_Strings.cpp | 3 +++ 2 files changed, 6 insertions(+) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg_Strings.h b/toolsrc/include/vcpkg_Strings.h index 5dd420232..5af7c6f7c 100644 --- a/toolsrc/include/vcpkg_Strings.h +++ b/toolsrc/include/vcpkg_Strings.h @@ -39,6 +39,9 @@ namespace vcpkg::Strings static constexpr const CStringView EMPTY = ""; static constexpr const CWStringView WEMPTY = L""; + bool is_empty(const CStringView s); + bool is_empty(const CWStringView s); + template std::string format(const char* fmtstr, const Args&... args) { diff --git a/toolsrc/src/vcpkg_Strings.cpp b/toolsrc/src/vcpkg_Strings.cpp index 0c1c1f9f9..b5ea338de 100644 --- a/toolsrc/src/vcpkg_Strings.cpp +++ b/toolsrc/src/vcpkg_Strings.cpp @@ -71,6 +71,9 @@ namespace vcpkg::Strings::details namespace vcpkg::Strings { + bool is_empty(const CStringView s) { return s == EMPTY; } + bool is_empty(const CWStringView s) { return s == WEMPTY; } + std::wstring to_utf16(const CStringView s) { std::wstring_convert, wchar_t> conversion; -- cgit v1.2.3 From 4a6b43c15a2b6c121686355f37443da6e2d05c9b Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 28 Aug 2017 18:55:27 -0700 Subject: Improve BinaryParagraph::displayname() --- toolsrc/src/BinaryParagraph.cpp | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/BinaryParagraph.cpp b/toolsrc/src/BinaryParagraph.cpp index 783fa6ace..1ab1aa63e 100644 --- a/toolsrc/src/BinaryParagraph.cpp +++ b/toolsrc/src/BinaryParagraph.cpp @@ -89,14 +89,8 @@ namespace vcpkg std::string BinaryParagraph::displayname() const { - if (this->feature == "") - { - return this->spec.name() + "[core]:" + this->spec.triplet().to_string(); - } - else - { - return this->spec.name() + "[" + this->feature + "]:" + this->spec.triplet().to_string(); - } + const auto f = Strings::is_empty(this->feature) ? "core" : this->feature; + return Strings::format("%s[%s]:%s", this->spec.name(), f, this->spec.triplet()); } std::string BinaryParagraph::dir() const { return this->spec.dir(); } -- cgit v1.2.3 From d02d44b0f12ae0603c5578bdcc4c0a51a3e309c7 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 28 Aug 2017 18:58:59 -0700 Subject: Use Strings::EMPTY instead of "" --- toolsrc/src/commands_build.cpp | 4 ++-- toolsrc/src/commands_install.cpp | 2 +- toolsrc/src/commands_version.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/commands_build.cpp b/toolsrc/src/commands_build.cpp index 71cd1b845..421568ce5 100644 --- a/toolsrc/src/commands_build.cpp +++ b/toolsrc/src/commands_build.cpp @@ -68,12 +68,12 @@ namespace vcpkg::Commands::BuildCommand System::println(System::Color::error, "The build command requires all dependencies to be already installed."); System::println("The following dependencies are missing:"); - System::println(""); + System::println(Strings::EMPTY); for (const auto& p : result.unmet_dependencies) { System::println(" %s", p); } - System::println(""); + System::println(Strings::EMPTY); Checks::exit_fail(VCPKG_LINE_INFO); } diff --git a/toolsrc/src/commands_install.cpp b/toolsrc/src/commands_install.cpp index a2e95eb48..1c474f7b0 100644 --- a/toolsrc/src/commands_install.cpp +++ b/toolsrc/src/commands_install.cpp @@ -199,7 +199,7 @@ namespace vcpkg::Commands::Install bcf.core_paragraph.spec); System::print("\n "); System::println(Strings::join("\n ", intersection)); - System::println(""); + System::println(Strings::EMPTY); return InstallResult::FILE_CONFLICTS; } diff --git a/toolsrc/src/commands_version.cpp b/toolsrc/src/commands_version.cpp index cd21f2561..af81cd26e 100644 --- a/toolsrc/src/commands_version.cpp +++ b/toolsrc/src/commands_version.cpp @@ -20,7 +20,7 @@ namespace vcpkg::Commands::Version #ifndef NDEBUG + std::string("-debug") #endif - + std::string(Metrics::get_compiled_metrics_enabled() ? "" : "-external"); + + std::string(Metrics::get_compiled_metrics_enabled() ? Strings::EMPTY : "-external"); return s_version; } -- cgit v1.2.3 From 5b91a84230e85e8f560fb78de1fd4bf6b68e8756 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 28 Aug 2017 19:27:32 -0700 Subject: Change Strings::EMPTY to char * --- toolsrc/include/vcpkg_Strings.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg_Strings.h b/toolsrc/include/vcpkg_Strings.h index 5af7c6f7c..2607caf4c 100644 --- a/toolsrc/include/vcpkg_Strings.h +++ b/toolsrc/include/vcpkg_Strings.h @@ -36,8 +36,8 @@ namespace vcpkg::Strings::details namespace vcpkg::Strings { - static constexpr const CStringView EMPTY = ""; - static constexpr const CWStringView WEMPTY = L""; + static constexpr const char* EMPTY = ""; + static constexpr const wchar_t* WEMPTY = L""; bool is_empty(const CStringView s); bool is_empty(const CWStringView s); -- cgit v1.2.3 From 992f192c5e937f22877117e64ff7a38a6447c4bc Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 28 Aug 2017 19:29:12 -0700 Subject: Add System::println() with no args --- toolsrc/include/vcpkg_System.h | 1 + toolsrc/src/vcpkg_System.cpp | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg_System.h b/toolsrc/include/vcpkg_System.h index 86bb24aad..9dd9ea8bd 100644 --- a/toolsrc/include/vcpkg_System.h +++ b/toolsrc/include/vcpkg_System.h @@ -32,6 +32,7 @@ namespace vcpkg::System warning = 14, }; + void println(); void print(const CStringView message); void println(const CStringView message); void print(const Color c, const CStringView message); diff --git a/toolsrc/src/vcpkg_System.cpp b/toolsrc/src/vcpkg_System.cpp index 481f2431e..c48f719e1 100644 --- a/toolsrc/src/vcpkg_System.cpp +++ b/toolsrc/src/vcpkg_System.cpp @@ -48,8 +48,8 @@ namespace vcpkg::System std::vector supported_architectures; supported_architectures.push_back(get_host_processor()); - //AMD64 machines support to run x86 applications - if(supported_architectures.back()==CPUArchitecture::X64) + // AMD64 machines support to run x86 applications + if (supported_architectures.back() == CPUArchitecture::X64) { supported_architectures.push_back(CPUArchitecture::X86); } @@ -211,6 +211,8 @@ namespace vcpkg::System LR"(powershell -NoProfile -ExecutionPolicy Bypass -Command "& {& '%s' %s}")", script_path.native(), args); } + void println() { println(Strings::EMPTY); } + void print(const CStringView message) { fputs(message, stdout); } void println(const CStringView message) -- cgit v1.2.3 From 6684240090512f745bf7530b2fb4bcd31c3fb02e Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 28 Aug 2017 19:29:55 -0700 Subject: Use Strings::EMPTY --- toolsrc/src/PackageSpec.cpp | 4 ++-- toolsrc/src/commands_remove.cpp | 2 +- toolsrc/src/metrics.cpp | 10 +++++----- 3 files changed, 8 insertions(+), 8 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/PackageSpec.cpp b/toolsrc/src/PackageSpec.cpp index a43bc5ff5..890de8899 100644 --- a/toolsrc/src/PackageSpec.cpp +++ b/toolsrc/src/PackageSpec.cpp @@ -38,7 +38,7 @@ namespace vcpkg for (auto&& feature : spec->features) f_specs.push_back(FeatureSpec{pspec, feature}); - if (spec->features.empty()) f_specs.push_back(FeatureSpec{pspec, ""}); + if (spec->features.empty()) f_specs.push_back(FeatureSpec{pspec, Strings::EMPTY}); } else { @@ -56,7 +56,7 @@ namespace vcpkg std::vector ret; for (auto&& spec : specs) { - ret.emplace_back(spec.package_spec, ""); + ret.emplace_back(spec.package_spec, Strings::EMPTY); for (auto&& feature : spec.features) ret.emplace_back(spec.package_spec, feature); } diff --git a/toolsrc/src/commands_remove.cpp b/toolsrc/src/commands_remove.cpp index db5357514..cca541c85 100644 --- a/toolsrc/src/commands_remove.cpp +++ b/toolsrc/src/commands_remove.cpp @@ -18,7 +18,7 @@ namespace vcpkg::Commands::Remove { auto& fs = paths.get_filesystem(); auto spghs = status_db->find_all(spec.name(), spec.triplet()); - auto core_pkg = **status_db->find(spec.name(), spec.triplet(), ""); + auto core_pkg = **status_db->find(spec.name(), spec.triplet(), Strings::EMPTY); for (auto&& spgh : spghs) { diff --git a/toolsrc/src/metrics.cpp b/toolsrc/src/metrics.cpp index 6263c0fcb..8a7d02a30 100644 --- a/toolsrc/src/metrics.cpp +++ b/toolsrc/src/metrics.cpp @@ -25,7 +25,7 @@ namespace vcpkg::Metrics errno_t err = gmtime_s(&newtime, &now); if (err) { - return ""; + return Strings::EMPTY; } strftime(&date[0], date.size(), "%Y-%m-%dT%H:%M:%S", &newtime); @@ -125,16 +125,16 @@ namespace vcpkg::Metrics path += L"\\kernel32.dll"; auto versz = GetFileVersionInfoSizeW(path.c_str(), nullptr); - if (versz == 0) return ""; + if (versz == 0) return Strings::EMPTY; std::vector verbuf; verbuf.resize(versz); - if (!GetFileVersionInfoW(path.c_str(), 0, static_cast(verbuf.size()), &verbuf[0])) return ""; + if (!GetFileVersionInfoW(path.c_str(), 0, static_cast(verbuf.size()), &verbuf[0])) return Strings::EMPTY; void* rootblock; UINT rootblocksize; - if (!VerQueryValueW(&verbuf[0], L"\\", &rootblock, &rootblocksize)) return ""; + if (!VerQueryValueW(&verbuf[0], L"\\", &rootblock, &rootblocksize)) return Strings::EMPTY; auto rootblock_ffi = static_cast(rootblock); @@ -377,7 +377,7 @@ namespace vcpkg::Metrics path = vcpkgdir / "scripts" / "vcpkgmetricsuploader.exe"; if (fs.exists(path)) return path; - return L""; + return Strings::WEMPTY; }(); std::error_code ec; -- cgit v1.2.3 From 03c4c7f8c49d103f57fe12899526b27fc8ccc452 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 28 Aug 2017 19:32:07 -0700 Subject: Use System::println() with no args --- toolsrc/src/PostBuildLint.cpp | 16 ++++++++-------- toolsrc/src/commands_build.cpp | 4 ++-- toolsrc/src/commands_install.cpp | 2 +- toolsrc/src/vcpkg_Files.cpp | 4 ++-- 4 files changed, 13 insertions(+), 13 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/PostBuildLint.cpp b/toolsrc/src/PostBuildLint.cpp index a5d923ad2..473c81cfa 100644 --- a/toolsrc/src/PostBuildLint.cpp +++ b/toolsrc/src/PostBuildLint.cpp @@ -10,9 +10,9 @@ #include "vcpkg_System.h" #include "vcpkg_Util.h" -using vcpkg::Build::PreBuildInfo; using vcpkg::Build::BuildInfo; using vcpkg::Build::BuildPolicy; +using vcpkg::Build::PreBuildInfo; namespace vcpkg::PostBuildLint { @@ -369,12 +369,12 @@ namespace vcpkg::PostBuildLint std::vector binaries_with_invalid_architecture) { System::println(System::Color::warning, "The following files were built for an incorrect architecture:"); - System::println(""); + System::println(); for (const FileAndArch& b : binaries_with_invalid_architecture) { System::println(" %s", b.file.generic_string()); System::println("Expected %s, but was: %s", expected_architecture, b.actual_arch); - System::println(""); + System::println(); } } @@ -487,7 +487,7 @@ namespace vcpkg::PostBuildLint System::println(System::Color::warning, "Release binaries were not found"); } - System::println(""); + System::println(); return LintStatus::ERROR_DETECTED; } @@ -621,12 +621,12 @@ namespace vcpkg::PostBuildLint System::println(System::Color::warning, "Expected %s crt linkage, but the following libs had invalid crt linkage:", expected_build_type.to_string()); - System::println(""); + System::println(); for (const BuildType_and_file btf : libs_with_invalid_crt) { System::println(" %s: %s", btf.file.generic_string(), btf.build_type.to_string()); } - System::println(""); + System::println(); System::println(System::Color::warning, "To inspect the lib files, use:\n dumpbin.exe /directives mylibfile.lib"); @@ -675,12 +675,12 @@ namespace vcpkg::PostBuildLint if (!dlls_with_outdated_crt.empty()) { System::println(System::Color::warning, "Detected outdated dynamic CRT in the following files:"); - System::println(""); + System::println(); for (const OutdatedDynamicCrt_and_file btf : dlls_with_outdated_crt) { System::println(" %s: %s", btf.file.generic_string(), btf.outdated_crt.name); } - System::println(""); + System::println(); System::println(System::Color::warning, "To inspect the dll files, use:\n dumpbin.exe /dependents mydllfile.dll"); diff --git a/toolsrc/src/commands_build.cpp b/toolsrc/src/commands_build.cpp index 421568ce5..26a783a4b 100644 --- a/toolsrc/src/commands_build.cpp +++ b/toolsrc/src/commands_build.cpp @@ -68,12 +68,12 @@ namespace vcpkg::Commands::BuildCommand System::println(System::Color::error, "The build command requires all dependencies to be already installed."); System::println("The following dependencies are missing:"); - System::println(Strings::EMPTY); + System::println(); for (const auto& p : result.unmet_dependencies) { System::println(" %s", p); } - System::println(Strings::EMPTY); + System::println(); Checks::exit_fail(VCPKG_LINE_INFO); } diff --git a/toolsrc/src/commands_install.cpp b/toolsrc/src/commands_install.cpp index 1c474f7b0..8b1eec5eb 100644 --- a/toolsrc/src/commands_install.cpp +++ b/toolsrc/src/commands_install.cpp @@ -199,7 +199,7 @@ namespace vcpkg::Commands::Install bcf.core_paragraph.spec); System::print("\n "); System::println(Strings::join("\n ", intersection)); - System::println(Strings::EMPTY); + System::println(); return InstallResult::FILE_CONFLICTS; } diff --git a/toolsrc/src/vcpkg_Files.cpp b/toolsrc/src/vcpkg_Files.cpp index 29da7e684..24edb779f 100644 --- a/toolsrc/src/vcpkg_Files.cpp +++ b/toolsrc/src/vcpkg_Files.cpp @@ -186,11 +186,11 @@ namespace vcpkg::Files void print_paths(const std::vector& paths) { - System::println(""); + System::println(); for (const fs::path& p : paths) { System::println(" %s", p.generic_string()); } - System::println(""); + System::println(); } } -- cgit v1.2.3 From 28e581599e263e3f0b021ad5b6914d80fa9640f8 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 28 Aug 2017 19:39:33 -0700 Subject: Use Strings::EMPTY --- toolsrc/src/SourceParagraph.cpp | 4 ++-- toolsrc/src/VcpkgCmdArguments.cpp | 6 +++--- toolsrc/src/VcpkgPaths.cpp | 2 +- toolsrc/src/vcpkg_Build.cpp | 8 ++++---- toolsrc/src/vcpkg_Checks.cpp | 2 +- toolsrc/src/vcpkg_Parse.cpp | 2 +- toolsrc/src/vcpkg_Strings.cpp | 2 +- toolsrc/src/vcpkglib.cpp | 2 +- 8 files changed, 14 insertions(+), 14 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/SourceParagraph.cpp b/toolsrc/src/SourceParagraph.cpp index c69770ae1..50d6ecf07 100644 --- a/toolsrc/src/SourceParagraph.cpp +++ b/toolsrc/src/SourceParagraph.cpp @@ -187,7 +187,7 @@ namespace vcpkg { return Util::fmap(depends, [&](const std::string& depend_string) -> Dependency { auto pos = depend_string.find(' '); - if (pos == std::string::npos) return Dependency::parse_dependency(depend_string, ""); + if (pos == std::string::npos) return Dependency::parse_dependency(depend_string, Strings::EMPTY); // expect of the form "\w+ \[\w+\]" Dependency dep; @@ -195,7 +195,7 @@ namespace vcpkg if (depend_string.c_str()[pos + 1] != '(' || depend_string[depend_string.size() - 1] != ')') { // Error, but for now just slurp the entire string. - return Dependency::parse_dependency(depend_string, ""); + return Dependency::parse_dependency(depend_string, Strings::EMPTY); } dep.qualifier = depend_string.substr(pos + 2, depend_string.size() - pos - 3); return dep; diff --git a/toolsrc/src/VcpkgCmdArguments.cpp b/toolsrc/src/VcpkgCmdArguments.cpp index cf6c7b562..e7a9b8057 100644 --- a/toolsrc/src/VcpkgCmdArguments.cpp +++ b/toolsrc/src/VcpkgCmdArguments.cpp @@ -222,17 +222,17 @@ namespace vcpkg void VcpkgCmdArguments::check_max_arg_count(const size_t expected_arg_count) const { - return check_max_arg_count(expected_arg_count, ""); + return check_max_arg_count(expected_arg_count, Strings::EMPTY); } void VcpkgCmdArguments::check_min_arg_count(const size_t expected_arg_count) const { - return check_min_arg_count(expected_arg_count, ""); + return check_min_arg_count(expected_arg_count, Strings::EMPTY); } void VcpkgCmdArguments::check_exact_arg_count(const size_t expected_arg_count) const { - return check_exact_arg_count(expected_arg_count, ""); + return check_exact_arg_count(expected_arg_count, Strings::EMPTY); } void VcpkgCmdArguments::check_max_arg_count(const size_t expected_arg_count, const std::string& example_text) const diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp index 17a11b1a9..94fbf9a93 100644 --- a/toolsrc/src/VcpkgPaths.cpp +++ b/toolsrc/src/VcpkgPaths.cpp @@ -133,7 +133,7 @@ namespace vcpkg fs::path get_nuget_path(const fs::path& downloads_folder, const fs::path& scripts_folder) { static constexpr std::array expected_version = {4, 1, 0}; - static const std::wstring version_check_arguments = L""; + static const std::wstring version_check_arguments = Strings::WEMPTY; const fs::path downloaded_copy = downloads_folder / "nuget-4.1.0" / "nuget.exe"; const std::vector from_path = find_from_PATH(L"nuget"); diff --git a/toolsrc/src/vcpkg_Build.cpp b/toolsrc/src/vcpkg_Build.cpp index bec9c9ef7..a2fa99ac8 100644 --- a/toolsrc/src/vcpkg_Build.cpp +++ b/toolsrc/src/vcpkg_Build.cpp @@ -30,8 +30,8 @@ namespace vcpkg::Build CWStringView to_vcvarsall_target(const std::string& cmake_system_name) { - if (cmake_system_name == "") return L""; - if (cmake_system_name == "Windows") return L""; + if (cmake_system_name == Strings::EMPTY) return Strings::WEMPTY; + if (cmake_system_name == "Windows") return Strings::WEMPTY; if (cmake_system_name == "WindowsStore") return L"store"; Checks::exit_with_message(VCPKG_LINE_INFO, "Unsupported vcvarsall target %s", cmake_system_name); @@ -61,7 +61,7 @@ namespace vcpkg::Build const wchar_t* tonull = L" >nul"; if (GlobalState::debugging) { - tonull = L""; + tonull = Strings::WEMPTY; } const auto arch = to_vcvarsall_toolchain(pre_build_info.target_architecture, toolset); @@ -359,7 +359,7 @@ namespace vcpkg::Build const bool variable_with_no_value = s.size() == 1; const std::string variable_name = s.at(0); - const std::string variable_value = variable_with_no_value ? "" : s.at(1); + const std::string variable_value = variable_with_no_value ? Strings::EMPTY : s.at(1); if (variable_name == "VCPKG_TARGET_ARCHITECTURE") { diff --git a/toolsrc/src/vcpkg_Checks.cpp b/toolsrc/src/vcpkg_Checks.cpp index 2ad2d06ab..b6a88a011 100644 --- a/toolsrc/src/vcpkg_Checks.cpp +++ b/toolsrc/src/vcpkg_Checks.cpp @@ -62,7 +62,7 @@ namespace vcpkg::Checks { if (!expression) { - exit_with_message(line_info, ""); + exit_with_message(line_info, Strings::EMPTY); } } diff --git a/toolsrc/src/vcpkg_Parse.cpp b/toolsrc/src/vcpkg_Parse.cpp index 118cde900..b54f7360b 100644 --- a/toolsrc/src/vcpkg_Parse.cpp +++ b/toolsrc/src/vcpkg_Parse.cpp @@ -30,7 +30,7 @@ namespace vcpkg::Parse } std::string ParagraphParser::optional_field(const std::string& fieldname) { - return remove_field(&fields, fieldname).value_or(""); + return remove_field(&fields, fieldname).value_or(Strings::EMPTY); } std::unique_ptr ParagraphParser::error_info(const std::string& name) const { diff --git a/toolsrc/src/vcpkg_Strings.cpp b/toolsrc/src/vcpkg_Strings.cpp index b5ea338de..d08898bce 100644 --- a/toolsrc/src/vcpkg_Strings.cpp +++ b/toolsrc/src/vcpkg_Strings.cpp @@ -133,7 +133,7 @@ namespace vcpkg::Strings trim(&s); } - Util::erase_remove_if(*strings, [](const std::string& s) { return s == ""; }); + Util::erase_remove_if(*strings, [](const std::string& s) { return Strings::is_empty(s); }); } std::vector split(const std::string& s, const std::string& delimiter) diff --git a/toolsrc/src/vcpkglib.cpp b/toolsrc/src/vcpkglib.cpp index 96e9f05e1..9f47c9d61 100644 --- a/toolsrc/src/vcpkglib.cpp +++ b/toolsrc/src/vcpkglib.cpp @@ -189,7 +189,7 @@ namespace vcpkg for (const std::unique_ptr& pgh : status_db) { - if (pgh->state != InstallState::INSTALLED || pgh->package.feature != "") + if (pgh->state != InstallState::INSTALLED || !Strings::is_empty(pgh->package.feature)) { continue; } -- cgit v1.2.3 From 5337adf1078f27c993f01662b7dadb8da2801356 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 29 Aug 2017 16:20:21 -0700 Subject: Remove Strings::is_empty(). Use std::string.empty() --- toolsrc/include/vcpkg_Strings.h | 3 --- toolsrc/src/BinaryParagraph.cpp | 2 +- toolsrc/src/vcpkg_Dependencies.cpp | 6 +++--- toolsrc/src/vcpkg_Strings.cpp | 5 +---- toolsrc/src/vcpkglib.cpp | 2 +- 5 files changed, 6 insertions(+), 12 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg_Strings.h b/toolsrc/include/vcpkg_Strings.h index 2607caf4c..61f6fab61 100644 --- a/toolsrc/include/vcpkg_Strings.h +++ b/toolsrc/include/vcpkg_Strings.h @@ -39,9 +39,6 @@ namespace vcpkg::Strings static constexpr const char* EMPTY = ""; static constexpr const wchar_t* WEMPTY = L""; - bool is_empty(const CStringView s); - bool is_empty(const CWStringView s); - template std::string format(const char* fmtstr, const Args&... args) { diff --git a/toolsrc/src/BinaryParagraph.cpp b/toolsrc/src/BinaryParagraph.cpp index 1ab1aa63e..1504912ab 100644 --- a/toolsrc/src/BinaryParagraph.cpp +++ b/toolsrc/src/BinaryParagraph.cpp @@ -89,7 +89,7 @@ namespace vcpkg std::string BinaryParagraph::displayname() const { - const auto f = Strings::is_empty(this->feature) ? "core" : this->feature; + const auto f = this->feature.empty() ? "core" : this->feature; return Strings::format("%s[%s]:%s", this->spec.name(), f, this->spec.triplet()); } diff --git a/toolsrc/src/vcpkg_Dependencies.cpp b/toolsrc/src/vcpkg_Dependencies.cpp index 4d0c3c928..1a0f0a6ed 100644 --- a/toolsrc/src/vcpkg_Dependencies.cpp +++ b/toolsrc/src/vcpkg_Dependencies.cpp @@ -443,7 +443,7 @@ namespace vcpkg::Dependencies MarkPlusResult mark_plus(const std::string& feature, Cluster& cluster, ClusterGraph& graph, GraphPlan& graph_plan) { - if (feature == "") + if (feature.empty()) { // Indicates that core was not specified in the reference return mark_plus("core", cluster, graph, graph_plan); @@ -551,7 +551,7 @@ namespace vcpkg::Dependencies auto& status_paragraph_feature = status_paragraph->package.feature; // In this case, empty string indicates the "core" paragraph for a package. - if (status_paragraph_feature == "") + if (status_paragraph_feature.empty()) { cluster.original_features.insert("core"); } @@ -573,7 +573,7 @@ namespace vcpkg::Dependencies auto& dep_cluster = graph.get(dependency.spec()); auto depends_name = dependency.feature(); - if (depends_name == "") depends_name = "core"; + if (depends_name.empty()) depends_name = "core"; auto& target_node = dep_cluster.edges[depends_name]; target_node.remove_edges.emplace_back(FeatureSpec{spec, status_paragraph_feature}); diff --git a/toolsrc/src/vcpkg_Strings.cpp b/toolsrc/src/vcpkg_Strings.cpp index d08898bce..15851829d 100644 --- a/toolsrc/src/vcpkg_Strings.cpp +++ b/toolsrc/src/vcpkg_Strings.cpp @@ -71,9 +71,6 @@ namespace vcpkg::Strings::details namespace vcpkg::Strings { - bool is_empty(const CStringView s) { return s == EMPTY; } - bool is_empty(const CWStringView s) { return s == WEMPTY; } - std::wstring to_utf16(const CStringView s) { std::wstring_convert, wchar_t> conversion; @@ -133,7 +130,7 @@ namespace vcpkg::Strings trim(&s); } - Util::erase_remove_if(*strings, [](const std::string& s) { return Strings::is_empty(s); }); + Util::erase_remove_if(*strings, [](const std::string& s) { return s.empty(); }); } std::vector split(const std::string& s, const std::string& delimiter) diff --git a/toolsrc/src/vcpkglib.cpp b/toolsrc/src/vcpkglib.cpp index 9f47c9d61..14d062468 100644 --- a/toolsrc/src/vcpkglib.cpp +++ b/toolsrc/src/vcpkglib.cpp @@ -189,7 +189,7 @@ namespace vcpkg for (const std::unique_ptr& pgh : status_db) { - if (pgh->state != InstallState::INSTALLED || !Strings::is_empty(pgh->package.feature)) + if (pgh->state != InstallState::INSTALLED || !pgh->package.feature.empty()) { continue; } -- cgit v1.2.3 From 526b1436a16b5c60760cbfc16a7f64e49cf13a01 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Tue, 29 Aug 2017 17:02:33 -0700 Subject: [vcpkg] Dependency instead of installcmd --- toolsrc/src/VcpkgPaths.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp index 94fbf9a93..1a8693efc 100644 --- a/toolsrc/src/VcpkgPaths.cpp +++ b/toolsrc/src/VcpkgPaths.cpp @@ -90,7 +90,7 @@ namespace vcpkg { auto locked_metrics = Metrics::g_metrics.lock(); locked_metrics->track_property("error", "powershell install failed"); - locked_metrics->track_property("installcmd", install_cmd); + locked_metrics->track_property("dependency", tool_name); } Checks::exit_with_code(VCPKG_LINE_INFO, rc.exit_code); } -- cgit v1.2.3 From 765068fa70259be5487db2ffc4ea3e6b6e4d73bd Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Tue, 29 Aug 2017 19:04:47 -0700 Subject: [vcpkg] Refactor workaround for issue #1712. This should be removed once the root cause is found. --- toolsrc/src/VcpkgPaths.cpp | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp index 1fe92014c..ef9209b78 100644 --- a/toolsrc/src/VcpkgPaths.cpp +++ b/toolsrc/src/VcpkgPaths.cpp @@ -10,6 +10,16 @@ namespace vcpkg { + static std::string WORKAROUND_ISSUE_1712(const std::string& line) + { + auto colon_pos = line.find(':'); + if (colon_pos != std::string::npos && colon_pos > 0) + { + return line.substr(colon_pos - 1); + } + return line; + } + static bool exists_and_has_equal_or_greater_version(const std::wstring& version_cmd, const std::array& expected_version) { @@ -95,7 +105,7 @@ namespace vcpkg Checks::exit_with_code(VCPKG_LINE_INFO, rc.exit_code); } - const fs::path actual_downloaded_path = Strings::trimmed(rc.output); + const fs::path actual_downloaded_path = WORKAROUND_ISSUE_1712(Strings::trimmed(rc.output)); std::error_code ec; auto eq = fs::stdfs::equivalent(expected_downloaded_path, actual_downloaded_path, ec); Checks::check_exit(VCPKG_LINE_INFO, @@ -264,14 +274,7 @@ namespace vcpkg const std::wstring cmd = System::create_powershell_script_cmd(script); System::ExitCodeAndOutput ec_data = System::cmd_execute_and_capture_output(cmd); Checks::check_exit(VCPKG_LINE_INFO, ec_data.exit_code == 0, "Could not run script to detect VS 2017 instances"); - return Util::fmap(Strings::split(ec_data.output, "\n"), [](const std::string& line) { - auto colon_pos = line.find(':'); - if (colon_pos != std::string::npos && colon_pos > 0) - { - return line.substr(colon_pos - 1); - } - return line; - }); + return Util::fmap(Strings::split(ec_data.output, "\n"), WORKAROUND_ISSUE_1712); } static Optional get_VS2015_installation_instance() -- cgit v1.2.3 From 673bb9e19e37efc62181e6d5e195053f9ee48886 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 29 Aug 2017 18:57:38 -0700 Subject: Add missing const --- toolsrc/src/vcpkg_System.cpp | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg_System.cpp b/toolsrc/src/vcpkg_System.cpp index db4dfec9b..b769d6d57 100644 --- a/toolsrc/src/vcpkg_System.cpp +++ b/toolsrc/src/vcpkg_System.cpp @@ -19,7 +19,7 @@ namespace vcpkg::System fs::path get_exe_path_of_current_process() { wchar_t buf[_MAX_PATH]; - int bytes = GetModuleFileNameW(nullptr, buf, _MAX_PATH); + const int bytes = GetModuleFileNameW(nullptr, buf, _MAX_PATH); if (bytes == 0) std::abort(); return fs::path(buf, buf + bytes); } @@ -37,9 +37,9 @@ namespace vcpkg::System CPUArchitecture get_host_processor() { auto w6432 = get_environment_variable(L"PROCESSOR_ARCHITEW6432"); - if (auto p = w6432.get()) return to_cpu_architecture(Strings::to_utf8(*p)).value_or_exit(VCPKG_LINE_INFO); + if (const auto p = w6432.get()) return to_cpu_architecture(Strings::to_utf8(*p)).value_or_exit(VCPKG_LINE_INFO); - auto procarch = get_environment_variable(L"PROCESSOR_ARCHITECTURE").value_or_exit(VCPKG_LINE_INFO); + const auto procarch = get_environment_variable(L"PROCESSOR_ARCHITECTURE").value_or_exit(VCPKG_LINE_INFO); return to_cpu_architecture(Strings::to_utf8(procarch)).value_or_exit(VCPKG_LINE_INFO); } @@ -59,10 +59,10 @@ namespace vcpkg::System int cmd_execute_clean(const CWStringView cmd_line) { - static const std::wstring system_root = get_environment_variable(L"SystemRoot").value_or_exit(VCPKG_LINE_INFO); - static const std::wstring system_32 = system_root + LR"(\system32)"; - static const std::wstring new_PATH = Strings::wformat( - LR"(Path=%s;%s;%s\Wbem;%s\WindowsPowerShell\v1.0\)", system_32, system_root, system_32, system_32); + static const std::wstring SYSTEM_ROOT = get_environment_variable(L"SystemRoot").value_or_exit(VCPKG_LINE_INFO); + static const std::wstring SYSTEM_32 = SYSTEM_ROOT + LR"(\system32)"; + static const std::wstring NEW_PATH = Strings::wformat( + LR"(Path=%s;%s;%s\Wbem;%s\WindowsPowerShell\v1.0\)", SYSTEM_32, SYSTEM_ROOT, SYSTEM_32, SYSTEM_32); std::vector env_wstrings = { L"ALLUSERSPROFILE", @@ -116,7 +116,7 @@ namespace vcpkg::System for (auto&& env_wstring : env_wstrings) { const Optional value = System::get_environment_variable(env_wstring); - auto v = value.get(); + const auto v = value.get(); if (!v || v->empty()) continue; env_cstr.append(env_wstring); @@ -125,7 +125,7 @@ namespace vcpkg::System env_cstr.push_back(L'\0'); } - env_cstr.append(new_PATH); + env_cstr.append(NEW_PATH); env_cstr.push_back(L'\0'); STARTUPINFOW startup_info; @@ -153,7 +153,7 @@ namespace vcpkg::System CloseHandle(process_info.hThread); - DWORD result = WaitForSingleObject(process_info.hProcess, INFINITE); + const DWORD result = WaitForSingleObject(process_info.hProcess, INFINITE); Checks::check_exit(VCPKG_LINE_INFO, result != WAIT_FAILED, "WaitForSingleObject failed"); DWORD exit_code = 0; @@ -171,7 +171,7 @@ namespace vcpkg::System // Basically we are wrapping it in quotes const std::wstring& actual_cmd_line = Strings::wformat(LR"###("%s")###", cmd_line); Debug::println("_wsystem(%s)", Strings::to_utf8(actual_cmd_line)); - int exit_code = _wsystem(actual_cmd_line.c_str()); + const int exit_code = _wsystem(actual_cmd_line.c_str()); Debug::println("_wsystem() returned %d", exit_code); return exit_code; } @@ -186,7 +186,7 @@ namespace vcpkg::System Debug::println("_wpopen(%s)", Strings::to_utf8(actual_cmd_line)); std::wstring output; wchar_t buf[1024]; - auto pipe = _wpopen(actual_cmd_line.c_str(), L"r"); + const auto pipe = _wpopen(actual_cmd_line.c_str(), L"r"); if (pipe == nullptr) { return {1, Strings::to_utf8(output)}; @@ -199,7 +199,8 @@ namespace vcpkg::System { return {1, Strings::to_utf8(output)}; } - auto ec = _pclose(pipe); + + const auto ec = _pclose(pipe); Debug::println("_pclose() returned %d", ec); return {ec, Strings::to_utf8(output)}; } @@ -223,11 +224,11 @@ namespace vcpkg::System void print(const Color c, const CStringView message) { - HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); + const HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); CONSOLE_SCREEN_BUFFER_INFO consoleScreenBufferInfo{}; GetConsoleScreenBufferInfo(hConsole, &consoleScreenBufferInfo); - auto original_color = consoleScreenBufferInfo.wAttributes; + const auto original_color = consoleScreenBufferInfo.wAttributes; SetConsoleTextAttribute(hConsole, static_cast(c) | (original_color & 0xF0)); print(message); @@ -242,13 +243,13 @@ namespace vcpkg::System Optional get_environment_variable(const CWStringView varname) noexcept { - auto sz = GetEnvironmentVariableW(varname, nullptr, 0); + const auto sz = GetEnvironmentVariableW(varname, nullptr, 0); if (sz == 0) return nullopt; std::wstring ret(sz, L'\0'); Checks::check_exit(VCPKG_LINE_INFO, MAXDWORD >= ret.size()); - auto sz2 = GetEnvironmentVariableW(varname, ret.data(), static_cast(ret.size())); + const auto sz2 = GetEnvironmentVariableW(varname, ret.data(), static_cast(ret.size())); Checks::check_exit(VCPKG_LINE_INFO, sz2 + 1 == sz); ret.pop_back(); return ret; @@ -262,7 +263,7 @@ namespace vcpkg::System Optional get_registry_string(HKEY base, const CWStringView subKey, const CWStringView valuename) { HKEY k = nullptr; - LSTATUS ec = RegOpenKeyExW(base, subKey, NULL, KEY_READ, &k); + const LSTATUS ec = RegOpenKeyExW(base, subKey, NULL, KEY_READ, &k); if (ec != ERROR_SUCCESS) return nullopt; DWORD dwBufferSize = 0; -- cgit v1.2.3 From 130d9019dfddc491dafe762a0dde41f5d3ada87e Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 29 Aug 2017 18:59:00 -0700 Subject: Naming convention fixes --- toolsrc/src/vcpkg_System.cpp | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg_System.cpp b/toolsrc/src/vcpkg_System.cpp index b769d6d57..f5106b25e 100644 --- a/toolsrc/src/vcpkg_System.cpp +++ b/toolsrc/src/vcpkg_System.cpp @@ -224,15 +224,15 @@ namespace vcpkg::System void print(const Color c, const CStringView message) { - const HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); + const HANDLE console_handle = GetStdHandle(STD_OUTPUT_HANDLE); - CONSOLE_SCREEN_BUFFER_INFO consoleScreenBufferInfo{}; - GetConsoleScreenBufferInfo(hConsole, &consoleScreenBufferInfo); - const auto original_color = consoleScreenBufferInfo.wAttributes; + CONSOLE_SCREEN_BUFFER_INFO console_screen_buffer_info{}; + GetConsoleScreenBufferInfo(console_handle, &console_screen_buffer_info); + const auto original_color = console_screen_buffer_info.wAttributes; - SetConsoleTextAttribute(hConsole, static_cast(c) | (original_color & 0xF0)); + SetConsoleTextAttribute(console_handle, static_cast(c) | (original_color & 0xF0)); print(message); - SetConsoleTextAttribute(hConsole, original_color); + SetConsoleTextAttribute(console_handle, original_color); } void println(const Color c, const CStringView message) @@ -260,23 +260,23 @@ namespace vcpkg::System return hkey_type == REG_SZ || hkey_type == REG_MULTI_SZ || hkey_type == REG_EXPAND_SZ; } - Optional get_registry_string(HKEY base, const CWStringView subKey, const CWStringView valuename) + Optional get_registry_string(HKEY base, const CWStringView sub_key, const CWStringView valuename) { HKEY k = nullptr; - const LSTATUS ec = RegOpenKeyExW(base, subKey, NULL, KEY_READ, &k); + const LSTATUS ec = RegOpenKeyExW(base, sub_key, NULL, KEY_READ, &k); if (ec != ERROR_SUCCESS) return nullopt; - DWORD dwBufferSize = 0; - DWORD dwType = 0; - auto rc = RegQueryValueExW(k, valuename, nullptr, &dwType, nullptr, &dwBufferSize); - if (rc != ERROR_SUCCESS || !is_string_keytype(dwType) || dwBufferSize == 0 || - dwBufferSize % sizeof(wchar_t) != 0) + DWORD dw_buffer_size = 0; + DWORD dw_type = 0; + auto rc = RegQueryValueExW(k, valuename, nullptr, &dw_type, nullptr, &dw_buffer_size); + if (rc != ERROR_SUCCESS || !is_string_keytype(dw_type) || dw_buffer_size == 0 || + dw_buffer_size % sizeof(wchar_t) != 0) return nullopt; std::wstring ret; - ret.resize(dwBufferSize / sizeof(wchar_t)); + ret.resize(dw_buffer_size / sizeof(wchar_t)); - rc = RegQueryValueExW(k, valuename, nullptr, &dwType, reinterpret_cast(ret.data()), &dwBufferSize); - if (rc != ERROR_SUCCESS || !is_string_keytype(dwType) || dwBufferSize != sizeof(wchar_t) * ret.size()) + rc = RegQueryValueExW(k, valuename, nullptr, &dw_type, reinterpret_cast(ret.data()), &dw_buffer_size); + if (rc != ERROR_SUCCESS || !is_string_keytype(dw_type) || dw_buffer_size != sizeof(wchar_t) * ret.size()) return nullopt; ret.pop_back(); // remove extra trailing null byte -- cgit v1.2.3 From 3063bf5be34f9a285e1a84fb9c70195933122d72 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 29 Aug 2017 19:02:22 -0700 Subject: Add missing const --- toolsrc/src/vcpkglib.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkglib.cpp b/toolsrc/src/vcpkglib.cpp index 14d062468..5cdafdbc8 100644 --- a/toolsrc/src/vcpkglib.cpp +++ b/toolsrc/src/vcpkglib.cpp @@ -39,7 +39,7 @@ namespace vcpkg { auto& fs = paths.get_filesystem(); - auto updates_dir = paths.vcpkg_dir_updates; + const auto updates_dir = paths.vcpkg_dir_updates; std::error_code ec; fs.create_directory(paths.installed, ec); @@ -90,9 +90,9 @@ namespace vcpkg 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); + const auto my_update_id = update_id++; + const auto tmp_update_filename = paths.vcpkg_dir_updates / "incomplete"; + const auto update_filename = paths.vcpkg_dir_updates / std::to_string(my_update_id); fs.write_contents(tmp_update_filename, Strings::serialize(p)); fs.rename(tmp_update_filename, update_filename); @@ -233,7 +233,7 @@ namespace vcpkg const fs::path& cmake_script, const std::vector& pass_variables) { - std::wstring cmd_cmake_pass_variables = Strings::join(L" ", pass_variables, [](auto&& v) { return v.s; }); + const std::wstring cmd_cmake_pass_variables = Strings::join(L" ", pass_variables, [](auto&& v) { return v.s; }); return Strings::wformat( LR"("%s" %s -P "%s")", cmake_exe.native(), cmd_cmake_pass_variables, cmake_script.generic_wstring()); } -- cgit v1.2.3 From 6b1fc769a64eb18ec25e289347ce2043968f706f Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 29 Aug 2017 19:21:01 -0700 Subject: Add missing const --- toolsrc/src/VcpkgCmdArguments.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/VcpkgCmdArguments.cpp b/toolsrc/src/VcpkgCmdArguments.cpp index e7a9b8057..cb261930e 100644 --- a/toolsrc/src/VcpkgCmdArguments.cpp +++ b/toolsrc/src/VcpkgCmdArguments.cpp @@ -124,7 +124,7 @@ namespace vcpkg continue; } - auto eq_pos = arg.find('='); + const auto eq_pos = arg.find('='); if (eq_pos != std::string::npos) { args.optional_command_arguments.emplace(arg.substr(0, eq_pos), arg.substr(eq_pos + 1)); @@ -158,7 +158,7 @@ namespace vcpkg auto options_copy = this->optional_command_arguments; for (const std::string& option : valid_switches) { - auto it = options_copy.find(option); + const auto it = options_copy.find(option); if (it != options_copy.end()) { if (it->second.has_value()) @@ -177,7 +177,7 @@ namespace vcpkg for (const std::string& option : valid_settings) { - auto it = options_copy.find(option); + const auto it = options_copy.find(option); if (it != options_copy.end()) { if (!it->second.has_value()) -- cgit v1.2.3 From d35a5c98e48a32ef66fe2aaabe154edee2323d0e Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 30 Aug 2017 12:34:12 -0700 Subject: Fix /permissive- issue --- toolsrc/include/StatusParagraphs.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/StatusParagraphs.h b/toolsrc/include/StatusParagraphs.h index bf2ef2f3e..1a9ee6a03 100644 --- a/toolsrc/include/StatusParagraphs.h +++ b/toolsrc/include/StatusParagraphs.h @@ -17,8 +17,7 @@ namespace vcpkg const_iterator find(const PackageSpec& spec) const { return find(spec.name(), spec.triplet()); } const_iterator find(const std::string& name, const Triplet& triplet) const; iterator find(const std::string& name, const Triplet& triplet); - std::vector*> StatusParagraphs::find_all(const std::string& name, - const Triplet& triplet); + std::vector*> find_all(const std::string& name, const Triplet& triplet); iterator find(const std::string& name, const Triplet& triplet, const std::string& feature); const_iterator find_installed(const PackageSpec& spec) const -- cgit v1.2.3 From 62cde6598ddbf30f6872895aaf9715fc87f7b7aa Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 30 Aug 2017 22:42:43 -0700 Subject: Move function to Files::find_from_PATH() --- toolsrc/include/vcpkg_Files.h | 2 ++ toolsrc/src/VcpkgPaths.cpp | 20 ++++---------------- toolsrc/src/vcpkg_Files.cpp | 13 +++++++++++++ 3 files changed, 19 insertions(+), 16 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg_Files.h b/toolsrc/include/vcpkg_Files.h index ad29ffa14..855e8ea45 100644 --- a/toolsrc/include/vcpkg_Files.h +++ b/toolsrc/include/vcpkg_Files.h @@ -38,4 +38,6 @@ namespace vcpkg::Files bool has_invalid_chars_for_filesystem(const std::string& s); void print_paths(const std::vector& paths); + + std::vector find_from_PATH(const std::wstring& name); } diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp index ef9209b78..865f2ce44 100644 --- a/toolsrc/src/VcpkgPaths.cpp +++ b/toolsrc/src/VcpkgPaths.cpp @@ -13,7 +13,7 @@ namespace vcpkg static std::string WORKAROUND_ISSUE_1712(const std::string& line) { auto colon_pos = line.find(':'); - if (colon_pos != std::string::npos && colon_pos > 0) + if (colon_pos != std::string::npos && colon_pos > 1) { return line.substr(colon_pos - 1); } @@ -68,18 +68,6 @@ namespace vcpkg return nullopt; } - static std::vector find_from_PATH(const std::wstring& name) - { - const std::wstring cmd = Strings::wformat(L"where.exe %s", name); - auto out = System::cmd_execute_and_capture_output(cmd); - if (out.exit_code != 0) - { - return {}; - } - - return Util::fmap(Strings::split(out.output, "\n"), [](auto&& s) { return fs::path(s); }); - } - static fs::path fetch_dependency(const fs::path& scripts_folder, const std::wstring& tool_name, const fs::path& expected_downloaded_path, @@ -122,7 +110,7 @@ namespace vcpkg static const std::wstring version_check_arguments = L"--version"; const fs::path downloaded_copy = downloads_folder / "cmake-3.9.1-win32-x86" / "bin" / "cmake.exe"; - const std::vector from_path = find_from_PATH(L"cmake"); + const std::vector from_path = Files::find_from_PATH(L"cmake"); std::vector candidate_paths; candidate_paths.push_back(downloaded_copy); @@ -146,7 +134,7 @@ namespace vcpkg static const std::wstring version_check_arguments = Strings::WEMPTY; const fs::path downloaded_copy = downloads_folder / "nuget-4.1.0" / "nuget.exe"; - const std::vector from_path = find_from_PATH(L"nuget"); + const std::vector from_path = Files::find_from_PATH(L"nuget"); std::vector candidate_paths; candidate_paths.push_back(downloaded_copy); @@ -167,7 +155,7 @@ namespace vcpkg static const std::wstring version_check_arguments = L"--version"; const fs::path downloaded_copy = downloads_folder / "MinGit-2.14.1-32-bit" / "cmd" / "git.exe"; - const std::vector from_path = find_from_PATH(L"git"); + const std::vector from_path = Files::find_from_PATH(L"git"); std::vector candidate_paths; candidate_paths.push_back(downloaded_copy); diff --git a/toolsrc/src/vcpkg_Files.cpp b/toolsrc/src/vcpkg_Files.cpp index 24edb779f..ad1fcebc6 100644 --- a/toolsrc/src/vcpkg_Files.cpp +++ b/toolsrc/src/vcpkg_Files.cpp @@ -2,6 +2,7 @@ #include "vcpkg_Files.h" #include "vcpkg_System.h" +#include "vcpkg_Util.h" #include namespace vcpkg::Files @@ -193,4 +194,16 @@ namespace vcpkg::Files } System::println(); } + + std::vector find_from_PATH(const std::wstring& name) + { + const std::wstring cmd = Strings::wformat(L"where.exe %s", name); + auto out = System::cmd_execute_and_capture_output(cmd); + if (out.exit_code != 0) + { + return {}; + } + + return Util::fmap(Strings::split(out.output, "\n"), [](auto&& s) { return fs::path(s); }); + } } -- cgit v1.2.3 From aa1e928c79d78aad0086960bec971fcfec2d2133 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 30 Aug 2017 23:26:34 -0700 Subject: Improve `vcpkg edit` and feedback when no editor is found --- toolsrc/src/commands_edit.cpp | 101 +++++++++++++++++------------------------- 1 file changed, 40 insertions(+), 61 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/commands_edit.cpp b/toolsrc/src/commands_edit.cpp index e72931e63..f71d4d44c 100644 --- a/toolsrc/src/commands_edit.cpp +++ b/toolsrc/src/commands_edit.cpp @@ -6,6 +6,30 @@ namespace vcpkg::Commands::Edit { + static std::vector find_from_registry() + { + static const std::array REGKEYS = { + LR"(SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{C26E74D1-022E-4238-8B9D-1E7564A36CC9}_is1)", + LR"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{C26E74D1-022E-4238-8B9D-1E7564A36CC9}_is1)", + LR"(SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{F8A2A208-72B3-4D61-95FC-8A65D340689B}_is1)", + LR"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{F8A2A208-72B3-4D61-95FC-8A65D340689B}_is1)", + }; + + std::vector output; + for (auto&& keypath : REGKEYS) + { + const Optional code_installpath = + System::get_registry_string(HKEY_LOCAL_MACHINE, keypath, L"InstallLocation"); + if (const auto c = code_installpath.get()) + { + const fs::path install_path = fs::path(*c); + output.push_back(install_path / "Code.exe"); + output.push_back(install_path / "Code - Insiders.exe"); + } + } + return output; + } + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { static const std::string OPTION_BUILDTREES = "--buildtrees"; @@ -21,72 +45,27 @@ namespace vcpkg::Commands::Edit 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); - // Find the user's selected editor - std::wstring env_editor; + std::vector candidate_paths; + const std::vector from_path = Files::find_from_PATH(L"EDITOR"); + candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); + candidate_paths.push_back(System::get_ProgramFiles_platform_bitness() / "Microsoft VS Code" / "Code.exe"); + candidate_paths.push_back(System::get_ProgramFiles_32_bit() / "Microsoft VS Code" / "Code.exe"); - if (env_editor.empty()) - { - const Optional env_editor_optional = System::get_environment_variable(L"EDITOR"); - if (const auto e = env_editor_optional.get()) - { - env_editor = *e; - } - } - - if (env_editor.empty()) - { - const fs::path code_exe_path = System::get_ProgramFiles_platform_bitness() / "Microsoft VS Code/Code.exe"; - if (fs.exists(code_exe_path)) - { - env_editor = code_exe_path; - } - } - - 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)) - { - env_editor = code_exe_path; - } - } - - if (env_editor.empty()) - { - static const std::array REGKEYS = { - LR"(SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{C26E74D1-022E-4238-8B9D-1E7564A36CC9}_is1)", - LR"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{C26E74D1-022E-4238-8B9D-1E7564A36CC9}_is1)", - LR"(SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{F8A2A208-72B3-4D61-95FC-8A65D340689B}_is1)", - LR"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{F8A2A208-72B3-4D61-95FC-8A65D340689B}_is1)", - }; - for (auto&& keypath : REGKEYS) - { - const Optional code_installpath = - System::get_registry_string(HKEY_LOCAL_MACHINE, keypath, L"InstallLocation"); - if (const auto c = code_installpath.get()) - { - auto p = fs::path(*c) / "Code.exe"; - if (fs.exists(p)) - { - env_editor = p.native(); - break; - } - auto p_insiders = fs::path(*c) / "Code - Insiders.exe"; - if (fs.exists(p_insiders)) - { - env_editor = p_insiders.native(); - break; - } - } - } - } + const std::vector from_registry = find_from_registry(); + candidate_paths.insert(candidate_paths.end(), from_registry.cbegin(), from_registry.cend()); - if (env_editor.empty()) + auto it = Util::find_if(candidate_paths, [&](const fs::path& p) { return fs.exists(p); }); + if (it == candidate_paths.cend()) { - Checks::exit_with_message( - VCPKG_LINE_INFO, "Visual Studio Code was not found and the environment variable EDITOR is not set"); + System::println(System::Color::error, + "Error: Visual Studio Code was not found and the environment variable EDITOR is not set."); + System::println("The following paths were examined:"); + Files::print_paths(candidate_paths); + System::println("You can also set the environmental variable EDITOR to your editor of choice."); + Checks::exit_fail(VCPKG_LINE_INFO); } + const fs::path env_editor = *it; if (options.find(OPTION_BUILDTREES) != options.cend()) { const auto buildtrees_current_dir = paths.buildtrees / port_name; -- cgit v1.2.3 From f76244f700f3ae0fe353c53c19d209589e8cdaf7 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 30 Aug 2017 23:32:41 -0700 Subject: Use ::TerminateProcess() instead of ::exit() --- toolsrc/src/vcpkg_Checks.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg_Checks.cpp b/toolsrc/src/vcpkg_Checks.cpp index b6a88a011..3692a0e9a 100644 --- a/toolsrc/src/vcpkg_Checks.cpp +++ b/toolsrc/src/vcpkg_Checks.cpp @@ -20,7 +20,9 @@ namespace vcpkg::Checks SetConsoleCP(GlobalState::g_init_console_cp); SetConsoleOutputCP(GlobalState::g_init_console_output_cp); - ::exit(exit_code); + fflush(nullptr); + + ::TerminateProcess(::GetCurrentProcess(), exit_code); } static BOOL CtrlHandler(DWORD fdwCtrlType) -- cgit v1.2.3 From f1867a8e899748673b2696de4b837f3e9d94bd69 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 31 Aug 2017 18:01:23 -0700 Subject: Naming scheme --- toolsrc/src/vcpkg_System.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg_System.cpp b/toolsrc/src/vcpkg_System.cpp index f5106b25e..5313d419e 100644 --- a/toolsrc/src/vcpkg_System.cpp +++ b/toolsrc/src/vcpkg_System.cpp @@ -283,36 +283,36 @@ namespace vcpkg::System return ret; } - static const fs::path& get_ProgramFiles() + static const fs::path& get_program_files() { - static const fs::path p = System::get_environment_variable(L"PROGRAMFILES").value_or_exit(VCPKG_LINE_INFO); - return p; + static const fs::path PATH = System::get_environment_variable(L"PROGRAMFILES").value_or_exit(VCPKG_LINE_INFO); + return PATH; } const fs::path& get_ProgramFiles_32_bit() { - static const fs::path p = []() -> fs::path { + static const fs::path PATH = []() -> fs::path { auto value = System::get_environment_variable(L"ProgramFiles(x86)"); if (auto v = value.get()) { return std::move(*v); } - return get_ProgramFiles(); + return get_program_files(); }(); - return p; + return PATH; } const fs::path& get_ProgramFiles_platform_bitness() { - static const fs::path p = []() -> fs::path { + static const fs::path PATH = []() -> fs::path { auto value = System::get_environment_variable(L"ProgramW6432"); if (auto v = value.get()) { return std::move(*v); } - return get_ProgramFiles(); + return get_program_files(); }(); - return p; + return PATH; } } -- cgit v1.2.3 From d86d9727f6802a5f642e550db13e97a9a2ea8a29 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 31 Aug 2017 18:02:12 -0700 Subject: Function naming convention --- toolsrc/include/vcpkg_System.h | 2 +- toolsrc/src/VcpkgPaths.cpp | 4 ++-- toolsrc/src/commands_edit.cpp | 2 +- toolsrc/src/commands_integrate.cpp | 6 +++--- toolsrc/src/vcpkg_System.cpp | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg_System.h b/toolsrc/include/vcpkg_System.h index 9dd9ea8bd..dc57e02df 100644 --- a/toolsrc/include/vcpkg_System.h +++ b/toolsrc/include/vcpkg_System.h @@ -80,7 +80,7 @@ namespace vcpkg::System std::vector get_supported_host_architectures(); - const fs::path& get_ProgramFiles_32_bit(); + const fs::path& get_program_files_32_bit(); const fs::path& get_ProgramFiles_platform_bitness(); } diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp index 865f2ce44..c08612df2 100644 --- a/toolsrc/src/VcpkgPaths.cpp +++ b/toolsrc/src/VcpkgPaths.cpp @@ -116,7 +116,7 @@ namespace vcpkg candidate_paths.push_back(downloaded_copy); candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); candidate_paths.push_back(System::get_ProgramFiles_platform_bitness() / "CMake" / "bin" / "cmake.exe"); - candidate_paths.push_back(System::get_ProgramFiles_32_bit() / "CMake" / "bin"); + candidate_paths.push_back(System::get_program_files_32_bit() / "CMake" / "bin"); const Optional path = find_if_has_equal_or_greater_version(candidate_paths, version_check_arguments, expected_version); @@ -161,7 +161,7 @@ namespace vcpkg candidate_paths.push_back(downloaded_copy); candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); candidate_paths.push_back(System::get_ProgramFiles_platform_bitness() / "git" / "cmd" / "git.exe"); - candidate_paths.push_back(System::get_ProgramFiles_32_bit() / "git" / "cmd" / "git.exe"); + candidate_paths.push_back(System::get_program_files_32_bit() / "git" / "cmd" / "git.exe"); const Optional path = find_if_has_equal_or_greater_version(candidate_paths, version_check_arguments, expected_version); diff --git a/toolsrc/src/commands_edit.cpp b/toolsrc/src/commands_edit.cpp index f71d4d44c..c9886d82e 100644 --- a/toolsrc/src/commands_edit.cpp +++ b/toolsrc/src/commands_edit.cpp @@ -49,7 +49,7 @@ namespace vcpkg::Commands::Edit const std::vector from_path = Files::find_from_PATH(L"EDITOR"); candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); candidate_paths.push_back(System::get_ProgramFiles_platform_bitness() / "Microsoft VS Code" / "Code.exe"); - candidate_paths.push_back(System::get_ProgramFiles_32_bit() / "Microsoft VS Code" / "Code.exe"); + candidate_paths.push_back(System::get_program_files_32_bit() / "Microsoft VS Code" / "Code.exe"); const std::vector from_registry = find_from_registry(); candidate_paths.insert(candidate_paths.end(), from_registry.cbegin(), from_registry.cend()); diff --git a/toolsrc/src/commands_integrate.cpp b/toolsrc/src/commands_integrate.cpp index c5942f9fc..fce9e4121 100644 --- a/toolsrc/src/commands_integrate.cpp +++ b/toolsrc/src/commands_integrate.cpp @@ -9,10 +9,10 @@ namespace vcpkg::Commands::Integrate { static const std::array old_system_target_files = { - System::get_ProgramFiles_32_bit() / "MSBuild/14.0/Microsoft.Common.Targets/ImportBefore/vcpkg.nuget.targets", - System::get_ProgramFiles_32_bit() / "MSBuild/14.0/Microsoft.Common.Targets/ImportBefore/vcpkg.system.targets"}; + System::get_program_files_32_bit() / "MSBuild/14.0/Microsoft.Common.Targets/ImportBefore/vcpkg.nuget.targets", + System::get_program_files_32_bit() / "MSBuild/14.0/Microsoft.Common.Targets/ImportBefore/vcpkg.system.targets"}; static const fs::path system_wide_targets_file = - System::get_ProgramFiles_32_bit() / "MSBuild/Microsoft.Cpp/v4.0/V140/ImportBefore/Default/vcpkg.system.props"; + System::get_program_files_32_bit() / "MSBuild/Microsoft.Cpp/v4.0/V140/ImportBefore/Default/vcpkg.system.props"; static std::string create_appdata_targets_shortcut(const std::string& target_path) noexcept { diff --git a/toolsrc/src/vcpkg_System.cpp b/toolsrc/src/vcpkg_System.cpp index 5313d419e..d9d10f37b 100644 --- a/toolsrc/src/vcpkg_System.cpp +++ b/toolsrc/src/vcpkg_System.cpp @@ -289,7 +289,7 @@ namespace vcpkg::System return PATH; } - const fs::path& get_ProgramFiles_32_bit() + const fs::path& get_program_files_32_bit() { static const fs::path PATH = []() -> fs::path { auto value = System::get_environment_variable(L"ProgramFiles(x86)"); -- cgit v1.2.3 From 72394491b20753c3ee3987c5f15aedfc0742a0d8 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 31 Aug 2017 18:02:51 -0700 Subject: Naming convention --- toolsrc/include/vcpkg_System.h | 2 +- toolsrc/src/VcpkgPaths.cpp | 4 ++-- toolsrc/src/commands_edit.cpp | 2 +- toolsrc/src/vcpkg_System.cpp | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg_System.h b/toolsrc/include/vcpkg_System.h index dc57e02df..65f80ae6d 100644 --- a/toolsrc/include/vcpkg_System.h +++ b/toolsrc/include/vcpkg_System.h @@ -82,7 +82,7 @@ namespace vcpkg::System const fs::path& get_program_files_32_bit(); - const fs::path& get_ProgramFiles_platform_bitness(); + const fs::path& get_program_files_platform_bitness(); } namespace vcpkg::Debug diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp index c08612df2..e2004c67b 100644 --- a/toolsrc/src/VcpkgPaths.cpp +++ b/toolsrc/src/VcpkgPaths.cpp @@ -115,7 +115,7 @@ namespace vcpkg std::vector candidate_paths; candidate_paths.push_back(downloaded_copy); candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); - candidate_paths.push_back(System::get_ProgramFiles_platform_bitness() / "CMake" / "bin" / "cmake.exe"); + candidate_paths.push_back(System::get_program_files_platform_bitness() / "CMake" / "bin" / "cmake.exe"); candidate_paths.push_back(System::get_program_files_32_bit() / "CMake" / "bin"); const Optional path = @@ -160,7 +160,7 @@ namespace vcpkg std::vector candidate_paths; candidate_paths.push_back(downloaded_copy); candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); - candidate_paths.push_back(System::get_ProgramFiles_platform_bitness() / "git" / "cmd" / "git.exe"); + candidate_paths.push_back(System::get_program_files_platform_bitness() / "git" / "cmd" / "git.exe"); candidate_paths.push_back(System::get_program_files_32_bit() / "git" / "cmd" / "git.exe"); const Optional path = diff --git a/toolsrc/src/commands_edit.cpp b/toolsrc/src/commands_edit.cpp index c9886d82e..dc28de737 100644 --- a/toolsrc/src/commands_edit.cpp +++ b/toolsrc/src/commands_edit.cpp @@ -48,7 +48,7 @@ namespace vcpkg::Commands::Edit std::vector candidate_paths; const std::vector from_path = Files::find_from_PATH(L"EDITOR"); candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); - candidate_paths.push_back(System::get_ProgramFiles_platform_bitness() / "Microsoft VS Code" / "Code.exe"); + candidate_paths.push_back(System::get_program_files_platform_bitness() / "Microsoft VS Code" / "Code.exe"); candidate_paths.push_back(System::get_program_files_32_bit() / "Microsoft VS Code" / "Code.exe"); const std::vector from_registry = find_from_registry(); diff --git a/toolsrc/src/vcpkg_System.cpp b/toolsrc/src/vcpkg_System.cpp index d9d10f37b..beaa997b8 100644 --- a/toolsrc/src/vcpkg_System.cpp +++ b/toolsrc/src/vcpkg_System.cpp @@ -302,7 +302,7 @@ namespace vcpkg::System return PATH; } - const fs::path& get_ProgramFiles_platform_bitness() + const fs::path& get_program_files_platform_bitness() { static const fs::path PATH = []() -> fs::path { auto value = System::get_environment_variable(L"ProgramW6432"); -- cgit v1.2.3 From badecd4207902b5faebb07a2c2f807f345994040 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 31 Aug 2017 18:03:54 -0700 Subject: CoffFileReader naming convention --- toolsrc/include/coff_file_reader.h | 2 +- toolsrc/src/PostBuildLint.cpp | 4 ++-- toolsrc/src/coff_file_reader.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/coff_file_reader.h b/toolsrc/include/coff_file_reader.h index 09f6447c2..7287211a1 100644 --- a/toolsrc/include/coff_file_reader.h +++ b/toolsrc/include/coff_file_reader.h @@ -3,7 +3,7 @@ #include "filesystem_fs.h" #include -namespace vcpkg::COFFFileReader +namespace vcpkg::CoffFileReader { struct DllInfo { diff --git a/toolsrc/src/PostBuildLint.cpp b/toolsrc/src/PostBuildLint.cpp index 473c81cfa..8c04b94a0 100644 --- a/toolsrc/src/PostBuildLint.cpp +++ b/toolsrc/src/PostBuildLint.cpp @@ -389,7 +389,7 @@ namespace vcpkg::PostBuildLint file.extension() == ".dll", "The file extension was not .dll: %s", file.generic_string()); - COFFFileReader::DllInfo info = COFFFileReader::read_dll(file); + CoffFileReader::DllInfo info = CoffFileReader::read_dll(file); const std::string actual_architecture = get_actual_architecture(info.machine_type); if (expected_architecture != actual_architecture) @@ -418,7 +418,7 @@ namespace vcpkg::PostBuildLint file.extension() == ".lib", "The file extension was not .lib: %s", file.generic_string()); - COFFFileReader::LibInfo info = COFFFileReader::read_lib(file); + CoffFileReader::LibInfo info = CoffFileReader::read_lib(file); // This is zero for folly's debug library // TODO: Why? diff --git a/toolsrc/src/coff_file_reader.cpp b/toolsrc/src/coff_file_reader.cpp index 10c1437c6..bb3a6cefd 100644 --- a/toolsrc/src/coff_file_reader.cpp +++ b/toolsrc/src/coff_file_reader.cpp @@ -5,7 +5,7 @@ using namespace std; -namespace vcpkg::COFFFileReader +namespace vcpkg::CoffFileReader { template static T reinterpret_bytes(const char* data) -- cgit v1.2.3 From 07c963f36930a34050c57119c227cd95ea6d60aa Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 31 Aug 2017 18:04:39 -0700 Subject: Add missing const --- toolsrc/src/PostBuildLint.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/PostBuildLint.cpp b/toolsrc/src/PostBuildLint.cpp index 8c04b94a0..a30648163 100644 --- a/toolsrc/src/PostBuildLint.cpp +++ b/toolsrc/src/PostBuildLint.cpp @@ -389,7 +389,7 @@ namespace vcpkg::PostBuildLint file.extension() == ".dll", "The file extension was not .dll: %s", file.generic_string()); - CoffFileReader::DllInfo info = CoffFileReader::read_dll(file); + const CoffFileReader::DllInfo info = CoffFileReader::read_dll(file); const std::string actual_architecture = get_actual_architecture(info.machine_type); if (expected_architecture != actual_architecture) -- cgit v1.2.3 From b72c904719953c3b372c392c3a925609f4861f10 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 31 Aug 2017 18:05:13 -0700 Subject: Naming convention fixes --- toolsrc/src/PostBuildLint.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/PostBuildLint.cpp b/toolsrc/src/PostBuildLint.cpp index a30648163..1fd48d3ec 100644 --- a/toolsrc/src/PostBuildLint.cpp +++ b/toolsrc/src/PostBuildLint.cpp @@ -40,7 +40,7 @@ namespace vcpkg::PostBuildLint const std::vector& get_outdated_dynamic_crts() { - static const std::vector v_no_msvcrt = { + static const std::vector V_NO_MSVCRT = { {"msvcp100.dll", R"(msvcp100\.dll)"}, {"msvcp100d.dll", R"(msvcp100d\.dll)"}, {"msvcp110.dll", R"(msvcp110\.dll)"}, @@ -59,7 +59,7 @@ namespace vcpkg::PostBuildLint {"msvcrt20.dll", R"(msvcrt20\.dll)"}, {"msvcrt40.dll", R"(msvcrt40\.dll)"}}; - return v_no_msvcrt; + return V_NO_MSVCRT; } static LintStatus check_for_files_in_include_directory(const Files::Filesystem& fs, @@ -580,7 +580,7 @@ namespace vcpkg::PostBuildLint return LintStatus::SUCCESS; } - struct BuildType_and_file + struct BuildTypeAndFile { fs::path file; BuildType build_type; @@ -594,7 +594,7 @@ namespace vcpkg::PostBuildLint bad_build_types.erase(std::remove(bad_build_types.begin(), bad_build_types.end(), expected_build_type), bad_build_types.end()); - std::vector libs_with_invalid_crt; + std::vector libs_with_invalid_crt; for (const fs::path& lib : libs) { @@ -622,7 +622,7 @@ namespace vcpkg::PostBuildLint "Expected %s crt linkage, but the following libs had invalid crt linkage:", expected_build_type.to_string()); System::println(); - for (const BuildType_and_file btf : libs_with_invalid_crt) + for (const BuildTypeAndFile btf : libs_with_invalid_crt) { System::println(" %s: %s", btf.file.generic_string(), btf.build_type.to_string()); } @@ -636,12 +636,12 @@ namespace vcpkg::PostBuildLint return LintStatus::SUCCESS; } - struct OutdatedDynamicCrt_and_file + struct OutdatedDynamicCrtAndFile { fs::path file; OutdatedDynamicCrt outdated_crt; - OutdatedDynamicCrt_and_file() = delete; + OutdatedDynamicCrtAndFile() = delete; }; static LintStatus check_outdated_crt_linkage_of_dlls(const std::vector& dlls, @@ -650,7 +650,7 @@ namespace vcpkg::PostBuildLint { if (build_info.policies.is_enabled(BuildPolicy::ALLOW_OBSOLETE_MSVCRT)) return LintStatus::SUCCESS; - std::vector dlls_with_outdated_crt; + std::vector dlls_with_outdated_crt; for (const fs::path& dll : dlls) { @@ -676,7 +676,7 @@ namespace vcpkg::PostBuildLint { System::println(System::Color::warning, "Detected outdated dynamic CRT in the following files:"); System::println(); - for (const OutdatedDynamicCrt_and_file btf : dlls_with_outdated_crt) + for (const OutdatedDynamicCrtAndFile btf : dlls_with_outdated_crt) { System::println(" %s: %s", btf.file.generic_string(), btf.outdated_crt.name); } -- cgit v1.2.3 From 81c9445376e677aa04d33b125917a61020cafda9 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 31 Aug 2017 18:05:58 -0700 Subject: example -> EXAMPLE --- toolsrc/src/commands_build.cpp | 8 ++++---- toolsrc/src/commands_build_external.cpp | 7 +++---- toolsrc/src/commands_cache.cpp | 4 ++-- toolsrc/src/commands_ci.cpp | 6 +++--- toolsrc/src/commands_create.cpp | 6 +++--- toolsrc/src/commands_depends.cpp | 4 ++-- toolsrc/src/commands_export.cpp | 8 ++++---- toolsrc/src/commands_import.cpp | 4 ++-- toolsrc/src/commands_install.cpp | 8 ++++---- toolsrc/src/commands_integrate.cpp | 4 ++-- toolsrc/src/commands_list.cpp | 4 ++-- toolsrc/src/commands_owns.cpp | 4 ++-- toolsrc/src/commands_portsdiff.cpp | 6 +++--- toolsrc/src/commands_remove.cpp | 10 +++++----- toolsrc/src/commands_search.cpp | 4 ++-- 15 files changed, 43 insertions(+), 44 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/commands_build.cpp b/toolsrc/src/commands_build.cpp index 26a783a4b..a69958058 100644 --- a/toolsrc/src/commands_build.cpp +++ b/toolsrc/src/commands_build.cpp @@ -89,11 +89,11 @@ namespace vcpkg::Commands::BuildCommand void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) { - static const std::string example = Commands::Help::create_example_string("build zlib:x64-windows"); - args.check_exact_arg_count( - 1, example); // Build only takes a single package and all dependencies must already be installed + static const std::string EXAMPLE = Commands::Help::create_example_string("build zlib:x64-windows"); + // Build only takes a single package and all dependencies must already be installed + args.check_exact_arg_count(1, EXAMPLE); const std::string command_argument = args.command_arguments.at(0); - const FullPackageSpec spec = Input::check_and_get_full_package_spec(command_argument, default_triplet, example); + const FullPackageSpec spec = Input::check_and_get_full_package_spec(command_argument, default_triplet, EXAMPLE); Input::check_triplet(spec.package_spec.triplet(), paths); const std::unordered_set options = args.check_and_get_optional_command_arguments({OPTION_CHECKS_ONLY}); diff --git a/toolsrc/src/commands_build_external.cpp b/toolsrc/src/commands_build_external.cpp index ff70e9cf2..7e85f2250 100644 --- a/toolsrc/src/commands_build_external.cpp +++ b/toolsrc/src/commands_build_external.cpp @@ -2,17 +2,16 @@ #include "vcpkg_Commands.h" #include "vcpkg_Input.h" -#include "vcpkg_System.h" namespace vcpkg::Commands::BuildExternal { void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) { - static const std::string example = + static const std::string EXAMPLE = Commands::Help::create_example_string(R"(build_external zlib2 C:\path\to\dir\with\controlfile\)"); - args.check_exact_arg_count(2, example); + args.check_exact_arg_count(2, EXAMPLE); const FullPackageSpec spec = - Input::check_and_get_full_package_spec(args.command_arguments.at(0), default_triplet, example); + Input::check_and_get_full_package_spec(args.command_arguments.at(0), default_triplet, EXAMPLE); Input::check_triplet(spec.package_spec.triplet(), paths); const std::unordered_set options = args.check_and_get_optional_command_arguments({}); diff --git a/toolsrc/src/commands_cache.cpp b/toolsrc/src/commands_cache.cpp index fa0c62ee4..5b65b197f 100644 --- a/toolsrc/src/commands_cache.cpp +++ b/toolsrc/src/commands_cache.cpp @@ -27,10 +27,10 @@ namespace vcpkg::Commands::Cache void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { - static const std::string example = Strings::format( + static const std::string EXAMPLE = Strings::format( "The argument should be a substring to search for, or no argument to display all cached libraries.\n%s", Commands::Help::create_example_string("cache png")); - args.check_max_arg_count(1, example); + args.check_max_arg_count(1, EXAMPLE); args.check_and_get_optional_command_arguments({}); const std::vector binary_paragraphs = read_all_binary_paragraphs(paths); diff --git a/toolsrc/src/commands_ci.cpp b/toolsrc/src/commands_ci.cpp index f781adf69..ca5e8a9a9 100644 --- a/toolsrc/src/commands_ci.cpp +++ b/toolsrc/src/commands_ci.cpp @@ -13,9 +13,9 @@ namespace vcpkg::Commands::CI { + using Build::BuildResult; using Dependencies::InstallPlanAction; using Dependencies::InstallPlanType; - using Build::BuildResult; static std::vector load_all_package_specs(Files::Filesystem& fs, const fs::path& ports_directory, @@ -30,8 +30,8 @@ namespace vcpkg::Commands::CI void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) { - static const std::string example = Commands::Help::create_example_string("ci x64-windows"); - args.check_max_arg_count(1, example); + static const std::string EXAMPLE = Commands::Help::create_example_string("ci x64-windows"); + args.check_max_arg_count(1, EXAMPLE); const Triplet triplet = args.command_arguments.size() == 1 ? Triplet::from_canonical_name(args.command_arguments.at(0)) : default_triplet; diff --git a/toolsrc/src/commands_create.cpp b/toolsrc/src/commands_create.cpp index 7f85b776a..99c1b7401 100644 --- a/toolsrc/src/commands_create.cpp +++ b/toolsrc/src/commands_create.cpp @@ -10,10 +10,10 @@ namespace vcpkg::Commands::Create { void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { - static const std::string example = Commands::Help::create_example_string( + static const std::string EXAMPLE = Commands::Help::create_example_string( R"###(create zlib2 http://zlib.net/zlib1211.zip "zlib1211-2.zip")###"); - args.check_max_arg_count(3, example); - args.check_min_arg_count(2, example); + args.check_max_arg_count(3, EXAMPLE); + args.check_min_arg_count(2, EXAMPLE); args.check_and_get_optional_command_arguments({}); const std::string port_name = args.command_arguments.at(0); const std::string url = args.command_arguments.at(1); diff --git a/toolsrc/src/commands_depends.cpp b/toolsrc/src/commands_depends.cpp index ffad91226..17cd9c881 100644 --- a/toolsrc/src/commands_depends.cpp +++ b/toolsrc/src/commands_depends.cpp @@ -10,8 +10,8 @@ namespace vcpkg::Commands::DependInfo { void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { - static const std::string example = Commands::Help::create_example_string(R"###(depend-info [pat])###"); - args.check_max_arg_count(1, example); + static const std::string EXAMPLE = Commands::Help::create_example_string(R"###(depend-info [pat])###"); + args.check_max_arg_count(1, EXAMPLE); args.check_and_get_optional_command_arguments({}); std::vector> source_control_files = diff --git a/toolsrc/src/commands_export.cpp b/toolsrc/src/commands_export.cpp index dbfb09aab..9e87d7b01 100644 --- a/toolsrc/src/commands_export.cpp +++ b/toolsrc/src/commands_export.cpp @@ -221,12 +221,12 @@ namespace vcpkg::Commands::Export static const std::string OPTION_NUGET_VERSION = "--nuget-version"; // input sanitization - static const std::string example = + static const std::string EXAMPLE = Commands::Help::create_example_string("export zlib zlib:x64-windows boost --nuget"); - args.check_min_arg_count(1, example); + args.check_min_arg_count(1, EXAMPLE); const std::vector specs = Util::fmap(args.command_arguments, [&](auto&& arg) { - return Input::check_and_get_package_spec(arg, default_triplet, example); + return Input::check_and_get_package_spec(arg, default_triplet, EXAMPLE); }); for (auto&& spec : specs) Input::check_triplet(spec.triplet(), paths); @@ -252,7 +252,7 @@ namespace vcpkg::Commands::Export if (!raw && !nuget && !zip && !_7zip && !dryRun) { System::println(System::Color::error, "Must provide at least one export type: --raw --nuget --zip --7zip"); - System::print(example); + System::print(EXAMPLE); Checks::exit_fail(VCPKG_LINE_INFO); } diff --git a/toolsrc/src/commands_import.cpp b/toolsrc/src/commands_import.cpp index 5db1885b2..007e8c204 100644 --- a/toolsrc/src/commands_import.cpp +++ b/toolsrc/src/commands_import.cpp @@ -93,9 +93,9 @@ namespace vcpkg::Commands::Import void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { - static const std::string example = Commands::Help::create_example_string( + static const std::string EXAMPLE = Commands::Help::create_example_string( R"(import C:\path\to\CONTROLfile C:\path\to\includedir C:\path\to\projectdir)"); - args.check_exact_arg_count(3, example); + args.check_exact_arg_count(3, EXAMPLE); args.check_and_get_optional_command_arguments({}); const fs::path control_file_path(args.command_arguments[0]); diff --git a/toolsrc/src/commands_install.cpp b/toolsrc/src/commands_install.cpp index 8b1eec5eb..d7c14f39c 100644 --- a/toolsrc/src/commands_install.cpp +++ b/toolsrc/src/commands_install.cpp @@ -450,12 +450,12 @@ namespace vcpkg::Commands::Install static const std::string OPTION_RECURSE = "--recurse"; // input sanitization - static const std::string example = + static const std::string EXAMPLE = Commands::Help::create_example_string("install zlib zlib:x64-windows curl boost"); - args.check_min_arg_count(1, example); + args.check_min_arg_count(1, EXAMPLE); const std::vector specs = Util::fmap(args.command_arguments, [&](auto&& arg) { - return Input::check_and_get_full_package_spec(arg, default_triplet, example); + return Input::check_and_get_full_package_spec(arg, default_triplet, EXAMPLE); }); for (auto&& spec : specs) @@ -549,7 +549,7 @@ namespace vcpkg::Commands::Install { // User specified --purge and --no-purge System::println(System::Color::error, "Error: cannot specify both --no-purge and --purge."); - System::print(example); + System::print(EXAMPLE); Checks::exit_fail(VCPKG_LINE_INFO); } const std::string display_name = remove_action->spec.to_string(); diff --git a/toolsrc/src/commands_integrate.cpp b/toolsrc/src/commands_integrate.cpp index fce9e4121..b0ce5edee 100644 --- a/toolsrc/src/commands_integrate.cpp +++ b/toolsrc/src/commands_integrate.cpp @@ -317,10 +317,10 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { - static const std::string example = Strings::format("Commands:\n" + static const std::string EXAMPLE = Strings::format("Commands:\n" "%s", INTEGRATE_COMMAND_HELPSTRING); - args.check_exact_arg_count(1, example); + args.check_exact_arg_count(1, EXAMPLE); args.check_and_get_optional_command_arguments({}); if (args.command_arguments[0] == "install") diff --git a/toolsrc/src/commands_list.cpp b/toolsrc/src/commands_list.cpp index 3cfa7e184..98e26f3d0 100644 --- a/toolsrc/src/commands_list.cpp +++ b/toolsrc/src/commands_list.cpp @@ -25,10 +25,10 @@ namespace vcpkg::Commands::List void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { - static const std::string example = Strings::format( + static const std::string EXAMPLE = Strings::format( "The argument should be a substring to search for, or no argument to display all installed libraries.\n%s", Commands::Help::create_example_string("list png")); - args.check_max_arg_count(1, example); + args.check_max_arg_count(1, EXAMPLE); const std::unordered_set options = args.check_and_get_optional_command_arguments({OPTION_FULLDESC}); diff --git a/toolsrc/src/commands_owns.cpp b/toolsrc/src/commands_owns.cpp index 757292e96..718a0277f 100644 --- a/toolsrc/src/commands_owns.cpp +++ b/toolsrc/src/commands_owns.cpp @@ -25,9 +25,9 @@ namespace vcpkg::Commands::Owns void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { - static const std::string example = Strings::format("The argument should be a pattern to search for. %s", + static const std::string EXAMPLE = Strings::format("The argument should be a pattern to search for. %s", Commands::Help::create_example_string("owns zlib.dll")); - args.check_exact_arg_count(1, example); + args.check_exact_arg_count(1, EXAMPLE); args.check_and_get_optional_command_arguments({}); StatusParagraphs status_db = database_load_check(paths); diff --git a/toolsrc/src/commands_portsdiff.cpp b/toolsrc/src/commands_portsdiff.cpp index 83d62896f..09299cb09 100644 --- a/toolsrc/src/commands_portsdiff.cpp +++ b/toolsrc/src/commands_portsdiff.cpp @@ -117,11 +117,11 @@ namespace vcpkg::Commands::PortsDiff void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { - static const std::string example = + static const std::string EXAMPLE = Strings::format("The argument should be a branch/tag/hash to checkout.\n%s", Commands::Help::create_example_string("portsdiff mybranchname")); - args.check_min_arg_count(1, example); - args.check_max_arg_count(2, example); + args.check_min_arg_count(1, EXAMPLE); + args.check_max_arg_count(2, EXAMPLE); args.check_and_get_optional_command_arguments({}); const fs::path& git_exe = paths.get_git_exe(); diff --git a/toolsrc/src/commands_remove.cpp b/toolsrc/src/commands_remove.cpp index cca541c85..2b5033166 100644 --- a/toolsrc/src/commands_remove.cpp +++ b/toolsrc/src/commands_remove.cpp @@ -136,7 +136,7 @@ namespace vcpkg::Commands::Remove static const std::string OPTION_RECURSE = "--recurse"; static const std::string OPTION_DRY_RUN = "--dry-run"; static const std::string OPTION_OUTDATED = "--outdated"; - static const std::string example = + static const std::string EXAMPLE = Commands::Help::create_example_string("remove zlib zlib:x64-windows curl boost"); const std::unordered_set options = args.check_and_get_optional_command_arguments( {OPTION_PURGE, OPTION_NO_PURGE, OPTION_RECURSE, OPTION_DRY_RUN, OPTION_OUTDATED}); @@ -145,7 +145,7 @@ namespace vcpkg::Commands::Remove std::vector specs; if (options.find(OPTION_OUTDATED) != options.cend()) { - args.check_exact_arg_count(0, example); + args.check_exact_arg_count(0, EXAMPLE); specs = Util::fmap(Update::find_outdated_packages(paths, status_db), [](auto&& outdated) { return outdated.spec; }); @@ -157,9 +157,9 @@ namespace vcpkg::Commands::Remove } else { - args.check_min_arg_count(1, example); + args.check_min_arg_count(1, EXAMPLE); specs = Util::fmap(args.command_arguments, [&](auto&& arg) { - return Input::check_and_get_package_spec(arg, default_triplet, example); + return Input::check_and_get_package_spec(arg, default_triplet, EXAMPLE); }); for (auto&& spec : specs) @@ -171,7 +171,7 @@ namespace vcpkg::Commands::Remove { // User specified --purge and --no-purge System::println(System::Color::error, "Error: cannot specify both --no-purge and --purge."); - System::print(example); + System::print(EXAMPLE); Checks::exit_fail(VCPKG_LINE_INFO); } const bool isRecursive = options.find(OPTION_RECURSE) != options.cend(); diff --git a/toolsrc/src/commands_search.cpp b/toolsrc/src/commands_search.cpp index 529d52a8b..1ccec9fbe 100644 --- a/toolsrc/src/commands_search.cpp +++ b/toolsrc/src/commands_search.cpp @@ -80,10 +80,10 @@ namespace vcpkg::Commands::Search void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { - static const std::string example = Strings::format( + static const std::string EXAMPLE = Strings::format( "The argument should be a substring to search for, or no argument to display all libraries.\n%s", Commands::Help::create_example_string("search png")); - args.check_max_arg_count(1, example); + args.check_max_arg_count(1, EXAMPLE); const std::unordered_set options = args.check_and_get_optional_command_arguments({OPTION_GRAPH, OPTION_FULLDESC}); -- cgit v1.2.3 From ef33eb96cf1b27bee88aa84b6f2cb3a8c43bb952 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 31 Aug 2017 18:13:12 -0700 Subject: [vcpkg contact] Naming convention fix --- toolsrc/src/commands_contact.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/commands_contact.cpp b/toolsrc/src/commands_contact.cpp index 7f4161802..8374350ee 100644 --- a/toolsrc/src/commands_contact.cpp +++ b/toolsrc/src/commands_contact.cpp @@ -7,8 +7,8 @@ namespace vcpkg::Commands::Contact { const std::string& email() { - static const std::string s_email = R"(vcpkg@microsoft.com)"; - return s_email; + static const std::string S_EMAIL = R"(vcpkg@microsoft.com)"; + return S_EMAIL; } void perform_and_exit(const VcpkgCmdArguments& args) -- cgit v1.2.3 From 78cbe5d52fc7661e59126f322826e71e2c3e66cc Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 31 Aug 2017 18:13:22 -0700 Subject: [vcpkg export] Naming convention fixes --- toolsrc/src/commands_export.cpp | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/commands_export.cpp b/toolsrc/src/commands_export.cpp index 9e87d7b01..b416a6f3c 100644 --- a/toolsrc/src/commands_export.cpp +++ b/toolsrc/src/commands_export.cpp @@ -21,7 +21,7 @@ namespace vcpkg::Commands::Export const std::string& nuget_id, const std::string& nupkg_version) { - static constexpr auto content_template = R"( + static constexpr auto CONTENT_TEMPLATE = R"( @NUGET_ID@ @@ -40,7 +40,7 @@ namespace vcpkg::Commands::Export )"; - std::string nuspec_file_content = std::regex_replace(content_template, std::regex("@NUGET_ID@"), nuget_id); + std::string nuspec_file_content = std::regex_replace(CONTENT_TEMPLATE, std::regex("@NUGET_ID@"), nuget_id); nuspec_file_content = std::regex_replace(nuspec_file_content, std::regex("@VERSION@"), nupkg_version); nuspec_file_content = std::regex_replace(nuspec_file_content, std::regex("@RAW_EXPORTED_DIR@"), raw_exported_dir); @@ -62,10 +62,10 @@ namespace vcpkg::Commands::Export static void print_plan(const std::map>& group_by_plan_type) { - static constexpr std::array order = {ExportPlanType::ALREADY_BUILT, + static constexpr std::array ORDER = {ExportPlanType::ALREADY_BUILT, ExportPlanType::PORT_AVAILABLE_BUT_NOT_BUILT}; - for (const ExportPlanType plan_type : order) + for (const ExportPlanType plan_type : ORDER) { const auto it = group_by_plan_type.find(plan_type); if (it == group_by_plan_type.cend()) @@ -151,7 +151,7 @@ namespace vcpkg::Commands::Export enum class BackingEnum { ZIP = 1, - _7ZIP, + SEVEN_ZIP, }; constexpr ArchiveFormat() = delete; @@ -174,7 +174,7 @@ namespace vcpkg::Commands::Export namespace ArchiveFormatC { constexpr const ArchiveFormat ZIP(ArchiveFormat::BackingEnum::ZIP, L"zip", L"zip"); - constexpr const ArchiveFormat _7ZIP(ArchiveFormat::BackingEnum::_7ZIP, L"7z", L"7zip"); + constexpr const ArchiveFormat SEVEN_ZIP(ArchiveFormat::BackingEnum::SEVEN_ZIP, L"7z", L"7zip"); } static fs::path do_archive_export(const VcpkgPaths& paths, @@ -216,7 +216,7 @@ namespace vcpkg::Commands::Export static const std::string OPTION_RAW = "--raw"; static const std::string OPTION_NUGET = "--nuget"; static const std::string OPTION_ZIP = "--zip"; - static const std::string OPTION_7ZIP = "--7zip"; + static const std::string OPTION_SEVEN_ZIP = "--7zip"; static const std::string OPTION_NUGET_ID = "--nuget-id"; static const std::string OPTION_NUGET_VERSION = "--nuget-version"; @@ -237,19 +237,19 @@ namespace vcpkg::Commands::Export OPTION_RAW, OPTION_NUGET, OPTION_ZIP, - OPTION_7ZIP, + OPTION_SEVEN_ZIP, }, { OPTION_NUGET_ID, OPTION_NUGET_VERSION, }); - const bool dryRun = options.switches.find(OPTION_DRY_RUN) != options.switches.cend(); + const bool dry_run = options.switches.find(OPTION_DRY_RUN) != options.switches.cend(); const bool raw = options.switches.find(OPTION_RAW) != options.switches.cend(); const bool nuget = options.switches.find(OPTION_NUGET) != options.switches.cend(); const bool zip = options.switches.find(OPTION_ZIP) != options.switches.cend(); - const bool _7zip = options.switches.find(OPTION_7ZIP) != options.switches.cend(); + const bool seven_zip = options.switches.find(OPTION_SEVEN_ZIP) != options.switches.cend(); - if (!raw && !nuget && !zip && !_7zip && !dryRun) + if (!raw && !nuget && !zip && !seven_zip && !dry_run) { System::println(System::Color::error, "Must provide at least one export type: --raw --nuget --zip --7zip"); System::print(EXAMPLE); @@ -300,7 +300,7 @@ namespace vcpkg::Commands::Export Checks::exit_fail(VCPKG_LINE_INFO); } - if (dryRun) + if (dry_run) { Checks::exit_success(VCPKG_LINE_INFO); } @@ -407,11 +407,11 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console print_next_step_info("[...]"); } - if (_7zip) + if (seven_zip) { System::println("Creating 7zip archive... "); const fs::path output_path = - do_archive_export(paths, raw_exported_dir_path, export_to_path, ArchiveFormatC::_7ZIP); + do_archive_export(paths, raw_exported_dir_path, export_to_path, ArchiveFormatC::SEVEN_ZIP); System::println(System::Color::success, "Creating 7zip archive... done"); System::println(System::Color::success, "7zip archive exported at: %s", output_path.generic_string()); print_next_step_info("[...]"); -- cgit v1.2.3 From b17480b0b44ddab04b7036766b58c41faa59afa7 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 31 Aug 2017 18:13:30 -0700 Subject: Remove unused #include --- toolsrc/src/commands_create.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/commands_create.cpp b/toolsrc/src/commands_create.cpp index 99c1b7401..6898f7399 100644 --- a/toolsrc/src/commands_create.cpp +++ b/toolsrc/src/commands_create.cpp @@ -2,7 +2,6 @@ #include "vcpkg_Commands.h" #include "vcpkg_Files.h" -#include "vcpkg_Input.h" #include "vcpkg_System.h" #include "vcpkglib.h" -- cgit v1.2.3 From 170cfa3f39d969ed5ebab7693610ffff9a313530 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 31 Aug 2017 18:20:52 -0700 Subject: Add missing const --- toolsrc/src/MachineType.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/MachineType.cpp b/toolsrc/src/MachineType.cpp index 2f44ce21a..af6378c88 100644 --- a/toolsrc/src/MachineType.cpp +++ b/toolsrc/src/MachineType.cpp @@ -7,7 +7,7 @@ namespace vcpkg { MachineType to_machine_type(const uint16_t value) { - MachineType t = static_cast(value); + const MachineType t = static_cast(value); switch (t) { case MachineType::UNKNOWN: -- cgit v1.2.3 From 03edddef2402d7a578c7714b6b28d3734e3d3940 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 31 Aug 2017 18:22:02 -0700 Subject: [vcpkg list] Naming convention fix --- toolsrc/src/commands_list.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/commands_list.cpp b/toolsrc/src/commands_list.cpp index 98e26f3d0..640885860 100644 --- a/toolsrc/src/commands_list.cpp +++ b/toolsrc/src/commands_list.cpp @@ -8,9 +8,9 @@ namespace vcpkg::Commands::List { static const std::string OPTION_FULLDESC = "--x-full-desc"; // TODO: This should find a better home, eventually - static void do_print(const StatusParagraph& pgh, bool FullDesc) + static void do_print(const StatusParagraph& pgh, bool full_desc) { - if (FullDesc) + if (full_desc) { System::println("%-30s %-16s %s", pgh.package.displayname(), pgh.package.version, pgh.package.description); } -- cgit v1.2.3 From 775dc8ce4017395406f9699676b1e8a117afcac5 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 31 Aug 2017 18:22:56 -0700 Subject: [vcpkg integrate] Naming convention fixes --- toolsrc/src/commands_integrate.cpp | 56 +++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 28 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/commands_integrate.cpp b/toolsrc/src/commands_integrate.cpp index b0ce5edee..abfb676da 100644 --- a/toolsrc/src/commands_integrate.cpp +++ b/toolsrc/src/commands_integrate.cpp @@ -8,10 +8,10 @@ namespace vcpkg::Commands::Integrate { - static const std::array old_system_target_files = { + static const std::array OLD_SYSTEM_TARGET_FILES = { System::get_program_files_32_bit() / "MSBuild/14.0/Microsoft.Common.Targets/ImportBefore/vcpkg.nuget.targets", System::get_program_files_32_bit() / "MSBuild/14.0/Microsoft.Common.Targets/ImportBefore/vcpkg.system.targets"}; - static const fs::path system_wide_targets_file = + static const fs::path SYSTEM_WIDE_TARGETS_FILE = System::get_program_files_32_bit() / "MSBuild/Microsoft.Cpp/v4.0/V140/ImportBefore/Default/vcpkg.system.props"; static std::string create_appdata_targets_shortcut(const std::string& target_path) noexcept @@ -82,7 +82,7 @@ namespace vcpkg::Commands::Integrate const std::string& nuget_id, const std::string& nupkg_version) { - static constexpr auto content_template = R"( + static constexpr auto CONTENT_TEMPLATE = R"( @NUGET_ID@ @@ -99,7 +99,7 @@ namespace vcpkg::Commands::Integrate )"; - std::string content = std::regex_replace(content_template, std::regex("@NUGET_ID@"), nuget_id); + std::string content = std::regex_replace(CONTENT_TEMPLATE, std::regex("@NUGET_ID@"), nuget_id); content = std::regex_replace(content, std::regex("@VCPKG_DIR@"), vcpkg_root_dir.string()); content = std::regex_replace(content, std::regex("@VERSION@"), nupkg_version); return content; @@ -113,36 +113,36 @@ namespace vcpkg::Commands::Integrate static ElevationPromptChoice elevated_cmd_execute(const std::string& param) { - SHELLEXECUTEINFO shExInfo = {0}; - shExInfo.cbSize = sizeof(shExInfo); - shExInfo.fMask = SEE_MASK_NOCLOSEPROCESS; - shExInfo.hwnd = nullptr; - shExInfo.lpVerb = "runas"; - shExInfo.lpFile = "cmd"; // Application to start - - shExInfo.lpParameters = param.c_str(); // Additional parameters - shExInfo.lpDirectory = nullptr; - shExInfo.nShow = SW_HIDE; - shExInfo.hInstApp = nullptr; - - if (!ShellExecuteExA(&shExInfo)) + SHELLEXECUTEINFO sh_ex_info = {0}; + sh_ex_info.cbSize = sizeof(sh_ex_info); + sh_ex_info.fMask = SEE_MASK_NOCLOSEPROCESS; + sh_ex_info.hwnd = nullptr; + sh_ex_info.lpVerb = "runas"; + sh_ex_info.lpFile = "cmd"; // Application to start + + sh_ex_info.lpParameters = param.c_str(); // Additional parameters + sh_ex_info.lpDirectory = nullptr; + sh_ex_info.nShow = SW_HIDE; + sh_ex_info.hInstApp = nullptr; + + if (!ShellExecuteExA(&sh_ex_info)) { return ElevationPromptChoice::NO; } - if (shExInfo.hProcess == nullptr) + if (sh_ex_info.hProcess == nullptr) { return ElevationPromptChoice::NO; } - WaitForSingleObject(shExInfo.hProcess, INFINITE); - CloseHandle(shExInfo.hProcess); + WaitForSingleObject(sh_ex_info.hProcess, INFINITE); + CloseHandle(sh_ex_info.hProcess); return ElevationPromptChoice::YES; } static fs::path get_appdata_targets_path() { - static const fs::path local_app_data = + static const fs::path LOCAL_APP_DATA = fs::path(System::get_environment_variable(L"LOCALAPPDATA").value_or_exit(VCPKG_LINE_INFO)); - return local_app_data / "vcpkg" / "vcpkg.user.targets"; + return LOCAL_APP_DATA / "vcpkg" / "vcpkg.user.targets"; } static void integrate_install(const VcpkgPaths& paths) @@ -150,7 +150,7 @@ namespace vcpkg::Commands::Integrate 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) + for (auto&& old_system_wide_targets_file : OLD_SYSTEM_TARGET_FILES) { if (fs.exists(old_system_wide_targets_file)) { @@ -174,7 +174,7 @@ namespace vcpkg::Commands::Integrate fs.create_directory(tmp_dir, ec); bool should_install_system = true; - const Expected system_wide_file_contents = fs.read_contents(system_wide_targets_file); + const Expected system_wide_file_contents = fs.read_contents(SYSTEM_WIDE_TARGETS_FILE); if (auto contents_data = system_wide_file_contents.get()) { std::regex re(R"###()###"); @@ -193,9 +193,9 @@ namespace vcpkg::Commands::Integrate 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(), + SYSTEM_WIDE_TARGETS_FILE.parent_path().string(), sys_src_path.string(), - system_wide_targets_file.string()); + SYSTEM_WIDE_TARGETS_FILE.string()); ElevationPromptChoice user_choice = elevated_cmd_execute(param); switch (user_choice) { @@ -207,9 +207,9 @@ namespace vcpkg::Commands::Integrate } Checks::check_exit(VCPKG_LINE_INFO, - fs.exists(system_wide_targets_file), + fs.exists(SYSTEM_WIDE_TARGETS_FILE), "Error: failed to copy targets file to %s", - system_wide_targets_file.string()); + SYSTEM_WIDE_TARGETS_FILE.string()); } const fs::path appdata_src_path = tmp_dir / "vcpkg.user.targets"; -- cgit v1.2.3 From dff6b22b430d27fac6239076d7511aaa5df6c9ca Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 31 Aug 2017 18:24:44 -0700 Subject: [vcpkg integrate] Change regex to static const, add missing consts --- toolsrc/src/commands_integrate.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/commands_integrate.cpp b/toolsrc/src/commands_integrate.cpp index abfb676da..1bf26910c 100644 --- a/toolsrc/src/commands_integrate.cpp +++ b/toolsrc/src/commands_integrate.cpp @@ -156,7 +156,7 @@ namespace vcpkg::Commands::Integrate { 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); + const ElevationPromptChoice user_choice = elevated_cmd_execute(param); switch (user_choice) { case ElevationPromptChoice::YES: break; @@ -175,14 +175,14 @@ namespace vcpkg::Commands::Integrate bool should_install_system = true; const Expected system_wide_file_contents = fs.read_contents(SYSTEM_WIDE_TARGETS_FILE); - if (auto contents_data = system_wide_file_contents.get()) + static const std::regex RE(R"###()###"); + if (const auto contents_data = system_wide_file_contents.get()) { - std::regex re(R"###()###"); std::match_results match; - auto found = std::regex_search(*contents_data, match, re); + const auto found = std::regex_search(*contents_data, match, RE); if (found) { - int ver = atoi(match[1].str().c_str()); + const int ver = atoi(match[1].str().c_str()); if (ver >= 1) should_install_system = false; } } @@ -196,7 +196,7 @@ namespace vcpkg::Commands::Integrate SYSTEM_WIDE_TARGETS_FILE.parent_path().string(), sys_src_path.string(), SYSTEM_WIDE_TARGETS_FILE.string()); - ElevationPromptChoice user_choice = elevated_cmd_execute(param); + const ElevationPromptChoice user_choice = elevated_cmd_execute(param); switch (user_choice) { case ElevationPromptChoice::YES: break; @@ -217,7 +217,7 @@ namespace vcpkg::Commands::Integrate create_appdata_targets_shortcut(paths.buildsystems_msbuild_targets.string())); auto appdata_dst_path = get_appdata_targets_path(); - auto rc = fs.copy_file(appdata_src_path, appdata_dst_path, fs::copy_options::overwrite_existing, ec); + const auto rc = fs.copy_file(appdata_src_path, appdata_dst_path, fs::copy_options::overwrite_existing, ec); if (!rc || ec) { @@ -245,7 +245,7 @@ namespace vcpkg::Commands::Integrate const fs::path path = get_appdata_targets_path(); std::error_code ec; - bool was_deleted = fs.remove(path, ec); + const bool was_deleted = fs.remove(path, ec); Checks::check_exit(VCPKG_LINE_INFO, !ec, "Error: Unable to remove user-wide integration: %d", ec.message()); -- cgit v1.2.3 From 61e5b6980b41bb73daaac3c3e1e15f4b04f960d9 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 31 Aug 2017 18:27:10 -0700 Subject: [vcpkg import] Add missing consts --- toolsrc/src/commands_import.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/commands_import.cpp b/toolsrc/src/commands_import.cpp index 007e8c204..412a03d7f 100644 --- a/toolsrc/src/commands_import.cpp +++ b/toolsrc/src/commands_import.cpp @@ -28,7 +28,7 @@ namespace vcpkg::Commands::Import for (auto&& file : files) { if (fs.is_directory(file)) continue; - auto ext = file.extension(); + const auto ext = file.extension(); if (ext == ".dll") binaries.dlls.push_back(std::move(file)); else if (ext == ".lib") @@ -46,7 +46,7 @@ namespace vcpkg::Commands::Import for (auto const& src_path : files) { - fs::path dest_path = destination_folder / src_path.filename(); + const fs::path dest_path = destination_folder / src_path.filename(); fs.copy(src_path, dest_path, fs::copy_options::overwrite_existing); } } @@ -59,10 +59,10 @@ namespace vcpkg::Commands::Import 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"); + const Binaries debug_binaries = find_binaries_in_dir(fs, project_directory / "Debug"); + const Binaries release_binaries = find_binaries_in_dir(fs, project_directory / "Release"); - fs::path destination_include_directory = destination_path / "include"; + const fs::path destination_include_directory = destination_path / "include"; fs.copy(include_directory, destination_include_directory, fs::copy_options::recursive | fs::copy_options::overwrite_existing); @@ -82,12 +82,12 @@ namespace vcpkg::Commands::Import const BinaryParagraph& control_file_data) { auto& fs = paths.get_filesystem(); - fs::path library_destination_path = paths.package_dir(control_file_data.spec); + const fs::path library_destination_path = paths.package_dir(control_file_data.spec); 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"; + const fs::path control_file_path = library_destination_path / "CONTROL"; fs.write_contents(control_file_path, Strings::serialize(control_file_data)); } -- cgit v1.2.3 From f0d5d94348a95c502688816c3ab360cd087aca95 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 31 Aug 2017 18:33:52 -0700 Subject: [vcpkg portsdiff] Add missing const, remove unused #include --- toolsrc/src/commands_portsdiff.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/commands_portsdiff.cpp b/toolsrc/src/commands_portsdiff.cpp index 09299cb09..32bc3de3c 100644 --- a/toolsrc/src/commands_portsdiff.cpp +++ b/toolsrc/src/commands_portsdiff.cpp @@ -2,7 +2,6 @@ #include "Paragraphs.h" #include "SortedVector.h" -#include "SourceParagraph.h" #include "vcpkg_Commands.h" #include "vcpkg_Maps.h" #include "vcpkg_System.h" @@ -139,8 +138,8 @@ namespace vcpkg::Commands::PortsDiff read_ports_from_commit(paths, git_commit_id_for_previous_snapshot); // Already sorted, so set_difference can work on std::vector too - std::vector current_ports = Maps::extract_keys(current_names_and_versions); - std::vector previous_ports = Maps::extract_keys(previous_names_and_versions); + const std::vector current_ports = Maps::extract_keys(current_names_and_versions); + const std::vector previous_ports = Maps::extract_keys(previous_names_and_versions); const SetElementPresence setp = SetElementPresence::create(current_ports, previous_ports); -- cgit v1.2.3 From 97063965b06280025eb123347f0145d6d817a29f Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 1 Sep 2017 16:26:52 -0700 Subject: Remove #1712 workaround. Clean Byte-Order-Mark if present --- toolsrc/src/VcpkgPaths.cpp | 14 ++------------ toolsrc/src/vcpkg_System.cpp | 12 ++++++++++++ 2 files changed, 14 insertions(+), 12 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp index e2004c67b..64c4ae630 100644 --- a/toolsrc/src/VcpkgPaths.cpp +++ b/toolsrc/src/VcpkgPaths.cpp @@ -10,16 +10,6 @@ namespace vcpkg { - static std::string WORKAROUND_ISSUE_1712(const std::string& line) - { - auto colon_pos = line.find(':'); - if (colon_pos != std::string::npos && colon_pos > 1) - { - return line.substr(colon_pos - 1); - } - return line; - } - static bool exists_and_has_equal_or_greater_version(const std::wstring& version_cmd, const std::array& expected_version) { @@ -93,7 +83,7 @@ namespace vcpkg Checks::exit_with_code(VCPKG_LINE_INFO, rc.exit_code); } - const fs::path actual_downloaded_path = WORKAROUND_ISSUE_1712(Strings::trimmed(rc.output)); + const fs::path actual_downloaded_path = Strings::trimmed(rc.output); std::error_code ec; auto eq = fs::stdfs::equivalent(expected_downloaded_path, actual_downloaded_path, ec); Checks::check_exit(VCPKG_LINE_INFO, @@ -262,7 +252,7 @@ namespace vcpkg const std::wstring cmd = System::create_powershell_script_cmd(script); System::ExitCodeAndOutput ec_data = System::cmd_execute_and_capture_output(cmd); Checks::check_exit(VCPKG_LINE_INFO, ec_data.exit_code == 0, "Could not run script to detect VS 2017 instances"); - return Util::fmap(Strings::split(ec_data.output, "\n"), WORKAROUND_ISSUE_1712); + return Strings::split(ec_data.output, "\n"); } static Optional get_VS2015_installation_instance() diff --git a/toolsrc/src/vcpkg_System.cpp b/toolsrc/src/vcpkg_System.cpp index beaa997b8..40e335117 100644 --- a/toolsrc/src/vcpkg_System.cpp +++ b/toolsrc/src/vcpkg_System.cpp @@ -176,6 +176,17 @@ namespace vcpkg::System return exit_code; } + // On Win7, output from powershell calls contain a byte order mark, so we strip it out if it is present + static void remove_byte_order_mark(std::wstring* s) + { + const wchar_t* a = s->c_str(); + // This is the UTF-8 byte-order mark + if (a[0] == 0xEF && a[1] == 0xBB && a[2] == 0xBF) + { + s->erase(0, 3); + } + } + ExitCodeAndOutput cmd_execute_and_capture_output(const CWStringView cmd_line) { // Flush stdout before launching external process @@ -202,6 +213,7 @@ namespace vcpkg::System const auto ec = _pclose(pipe); Debug::println("_pclose() returned %d", ec); + remove_byte_order_mark(&output); return {ec, Strings::to_utf8(output)}; } -- cgit v1.2.3 From 86dc3107ca03575519d020cdf3dcebbf45c5d462 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 1 Sep 2017 16:55:26 -0700 Subject: [VcpkgPaths.cpp] Naming conventions and const fixes --- toolsrc/src/VcpkgPaths.cpp | 67 +++++++++++++++++++++++----------------------- 1 file changed, 34 insertions(+), 33 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp index 64c4ae630..50032b740 100644 --- a/toolsrc/src/VcpkgPaths.cpp +++ b/toolsrc/src/VcpkgPaths.cpp @@ -13,24 +13,24 @@ namespace vcpkg static bool exists_and_has_equal_or_greater_version(const std::wstring& version_cmd, const std::array& expected_version) { - static const std::regex re(R"###((\d+)\.(\d+)\.(\d+))###"); + static const std::regex RE(R"###((\d+)\.(\d+)\.(\d+))###"); - auto rc = System::cmd_execute_and_capture_output(Strings::wformat(LR"(%s)", version_cmd)); + const auto rc = System::cmd_execute_and_capture_output(Strings::wformat(LR"(%s)", version_cmd)); if (rc.exit_code != 0) { return false; } std::match_results match; - auto found = std::regex_search(rc.output, match, re); + const auto found = std::regex_search(rc.output, match, RE); if (!found) { return false; } - int d1 = atoi(match[1].str().c_str()); - int d2 = atoi(match[2].str().c_str()); - int d3 = atoi(match[3].str().c_str()); + const int d1 = atoi(match[1].str().c_str()); + const int d2 = atoi(match[2].str().c_str()); + const int d3 = atoi(match[3].str().c_str()); if (d1 > expected_version[0] || (d1 == expected_version[0] && d2 > expected_version[1]) || (d1 == expected_version[0] && d2 == expected_version[1] && d3 >= expected_version[2])) { @@ -64,8 +64,9 @@ namespace vcpkg const std::array& version) { const fs::path script = scripts_folder / "fetchDependency.ps1"; - auto install_cmd = System::create_powershell_script_cmd(script, Strings::wformat(L"-Dependency %s", tool_name)); - System::ExitCodeAndOutput rc = System::cmd_execute_and_capture_output(install_cmd); + const auto install_cmd = + System::create_powershell_script_cmd(script, Strings::wformat(L"-Dependency %s", tool_name)); + const System::ExitCodeAndOutput rc = System::cmd_execute_and_capture_output(install_cmd); if (rc.exit_code) { const std::string version_as_string = Strings::format("%d.%d.%d", version[0], version[1], version[2]); @@ -85,7 +86,7 @@ namespace vcpkg const fs::path actual_downloaded_path = Strings::trimmed(rc.output); std::error_code ec; - auto eq = fs::stdfs::equivalent(expected_downloaded_path, actual_downloaded_path, ec); + const auto eq = fs::stdfs::equivalent(expected_downloaded_path, actual_downloaded_path, ec); Checks::check_exit(VCPKG_LINE_INFO, eq && !ec, "Expected dependency downloaded path to be %s, but was %s", @@ -96,8 +97,8 @@ namespace vcpkg static fs::path get_cmake_path(const fs::path& downloads_folder, const fs::path& scripts_folder) { - static constexpr std::array expected_version = {3, 9, 1}; - static const std::wstring version_check_arguments = L"--version"; + static constexpr std::array EXPECTED_VERSION = {3, 9, 1}; + static const std::wstring VERSION_CHECK_ARGUMENTS = L"--version"; const fs::path downloaded_copy = downloads_folder / "cmake-3.9.1-win32-x86" / "bin" / "cmake.exe"; const std::vector from_path = Files::find_from_PATH(L"cmake"); @@ -109,19 +110,19 @@ namespace vcpkg candidate_paths.push_back(System::get_program_files_32_bit() / "CMake" / "bin"); const Optional path = - find_if_has_equal_or_greater_version(candidate_paths, version_check_arguments, expected_version); - if (auto p = path.get()) + find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, EXPECTED_VERSION); + if (const auto p = path.get()) { return *p; } - return fetch_dependency(scripts_folder, L"cmake", downloaded_copy, expected_version); + return fetch_dependency(scripts_folder, L"cmake", downloaded_copy, EXPECTED_VERSION); } fs::path get_nuget_path(const fs::path& downloads_folder, const fs::path& scripts_folder) { - static constexpr std::array expected_version = {4, 1, 0}; - static const std::wstring version_check_arguments = Strings::WEMPTY; + static constexpr std::array EXPECTED_VERSION = {4, 1, 0}; + static const std::wstring VERSION_CHECK_ARGUMENTS = Strings::WEMPTY; const fs::path downloaded_copy = downloads_folder / "nuget-4.1.0" / "nuget.exe"; const std::vector from_path = Files::find_from_PATH(L"nuget"); @@ -130,19 +131,19 @@ namespace vcpkg candidate_paths.push_back(downloaded_copy); candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); - auto path = find_if_has_equal_or_greater_version(candidate_paths, version_check_arguments, expected_version); - if (auto p = path.get()) + auto path = find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, EXPECTED_VERSION); + if (const auto p = path.get()) { return *p; } - return fetch_dependency(scripts_folder, L"nuget", downloaded_copy, expected_version); + return fetch_dependency(scripts_folder, L"nuget", downloaded_copy, EXPECTED_VERSION); } fs::path get_git_path(const fs::path& downloads_folder, const fs::path& scripts_folder) { - static constexpr std::array expected_version = {2, 14, 1}; - static const std::wstring version_check_arguments = L"--version"; + static constexpr std::array EXPECTED_VERSION = {2, 14, 1}; + static const std::wstring VERSION_CHECK_ARGUMENTS = L"--version"; const fs::path downloaded_copy = downloads_folder / "MinGit-2.14.1-32-bit" / "cmd" / "git.exe"; const std::vector from_path = Files::find_from_PATH(L"git"); @@ -154,13 +155,13 @@ namespace vcpkg candidate_paths.push_back(System::get_program_files_32_bit() / "git" / "cmd" / "git.exe"); const Optional path = - find_if_has_equal_or_greater_version(candidate_paths, version_check_arguments, expected_version); - if (auto p = path.get()) + find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, EXPECTED_VERSION); + if (const auto p = path.get()) { return *p; } - return fetch_dependency(scripts_folder, L"git", downloaded_copy, expected_version); + return fetch_dependency(scripts_folder, L"git", downloaded_copy, EXPECTED_VERSION); } Expected VcpkgPaths::create(const fs::path& vcpkg_root_dir) @@ -221,7 +222,7 @@ namespace vcpkg { for (auto&& path : get_filesystem().get_files_non_recursive(this->triplets)) { - std::string triplet_file_name = path.stem().generic_u8string(); + const 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 @@ -246,19 +247,19 @@ namespace vcpkg return this->nuget_exe.get_lazy([this]() { return get_nuget_path(this->downloads, this->scripts); }); } - static std::vector get_VS2017_installation_instances(const VcpkgPaths& paths) + static std::vector get_vs2017_installation_instances(const VcpkgPaths& paths) { const fs::path script = paths.scripts / "findVisualStudioInstallationInstances.ps1"; const std::wstring cmd = System::create_powershell_script_cmd(script); - System::ExitCodeAndOutput ec_data = System::cmd_execute_and_capture_output(cmd); + const System::ExitCodeAndOutput ec_data = System::cmd_execute_and_capture_output(cmd); Checks::check_exit(VCPKG_LINE_INFO, ec_data.exit_code == 0, "Could not run script to detect VS 2017 instances"); return Strings::split(ec_data.output, "\n"); } - static Optional get_VS2015_installation_instance() + static Optional get_vs2015_installation_instance() { const Optional vs2015_cmntools_optional = System::get_environment_variable(L"VS140COMNTOOLS"); - if (auto v = vs2015_cmntools_optional.get()) + if (const auto v = vs2015_cmntools_optional.get()) { const fs::path vs2015_cmntools = fs::path(*v).parent_path(); // The call to parent_path() is needed because // the env variable has a trailing backslash @@ -274,15 +275,15 @@ namespace vcpkg const auto& fs = paths.get_filesystem(); - const std::vector vs2017_installation_instances = get_VS2017_installation_instances(paths); + const std::vector vs2017_installation_instances = get_vs2017_installation_instances(paths); // Note: this will contain a mix of vcvarsall.bat locations and dumpbin.exe locations. std::vector paths_examined; std::vector found_toolsets; // VS2015 - const Optional vs_2015_installation_instance = get_VS2015_installation_instance(); - if (auto v = vs_2015_installation_instance.get()) + const Optional vs_2015_installation_instance = get_vs2015_installation_instance(); + if (const auto v = vs_2015_installation_instance.get()) { const fs::path vs2015_vcvarsall_bat = *v / "VC" / "vcvarsall.bat"; @@ -362,7 +363,7 @@ namespace vcpkg break; } } - if (auto value = vs2017_toolset.get()) + if (const auto value = vs2017_toolset.get()) { found_toolsets.push_back(*value); break; -- cgit v1.2.3 From 797c94caecc3df34e82a9d0a1d774551cdc8ff66 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 1 Sep 2017 16:56:53 -0700 Subject: Remove uneeded else branch. Fix variable hiding --- toolsrc/src/VcpkgPaths.cpp | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp index 50032b740..7d574006e 100644 --- a/toolsrc/src/VcpkgPaths.cpp +++ b/toolsrc/src/VcpkgPaths.cpp @@ -393,15 +393,12 @@ namespace vcpkg { return vs_toolsets.back(); } - else - { - const auto toolset = Util::find_if(vs_toolsets, [&](const Toolset& toolset) { - return toolset_version == Strings::to_utf8(toolset.version); - }); - Checks::check_exit( - VCPKG_LINE_INFO, toolset != vs_toolsets.end(), "Could not find toolset '%s'", toolset_version); - return *toolset; - } + + const auto toolset = Util::find_if( + vs_toolsets, [&](const Toolset& t) { return toolset_version == Strings::to_utf8(t.version); }); + Checks::check_exit( + VCPKG_LINE_INFO, toolset != vs_toolsets.end(), "Could not find toolset '%s'", toolset_version); + return *toolset; } Files::Filesystem& VcpkgPaths::get_filesystem() const { return Files::get_real_filesystem(); } -- cgit v1.2.3 From 95eadb8ddd7dfb7f0899055a98fa91485ed74dc8 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 1 Sep 2017 16:58:51 -0700 Subject: [VcpkgPaths.cpp] Don't modify and ref on the fly --- toolsrc/src/VcpkgPaths.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp index 7d574006e..906a5e67f 100644 --- a/toolsrc/src/VcpkgPaths.cpp +++ b/toolsrc/src/VcpkgPaths.cpp @@ -318,9 +318,9 @@ namespace vcpkg // VS2017 Optional vs2017_toolset; - for (const fs::path& instance : vs2017_installation_instances) + for (const std::string& instance : vs2017_installation_instances) { - const fs::path vc_dir = instance / "VC"; + const fs::path vc_dir = fs::path{instance} / "VC"; // Skip any instances that do not have vcvarsall. const fs::path vcvarsall_dir = vc_dir / "Auxiliary" / "Build"; -- cgit v1.2.3 From c15c80e802f432f1b8d3775c7abff5e91531b641 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 1 Sep 2017 17:01:02 -0700 Subject: [vcpkg_Parse] Add missing const --- toolsrc/include/vcpkg_Parse.h | 2 +- toolsrc/src/vcpkg_Parse.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg_Parse.h b/toolsrc/include/vcpkg_Parse.h index e663448b9..2dda033b3 100644 --- a/toolsrc/include/vcpkg_Parse.h +++ b/toolsrc/include/vcpkg_Parse.h @@ -26,7 +26,7 @@ namespace vcpkg::Parse ParagraphParser(RawParagraph&& fields) : fields(std::move(fields)) {} void required_field(const std::string& fieldname, std::string& out); - std::string optional_field(const std::string& fieldname); + std::string optional_field(const std::string& fieldname) const; std::unique_ptr error_info(const std::string& name) const; private: diff --git a/toolsrc/src/vcpkg_Parse.cpp b/toolsrc/src/vcpkg_Parse.cpp index b54f7360b..e671a1a05 100644 --- a/toolsrc/src/vcpkg_Parse.cpp +++ b/toolsrc/src/vcpkg_Parse.cpp @@ -23,12 +23,12 @@ namespace vcpkg::Parse void ParagraphParser::required_field(const std::string& fieldname, std::string& out) { auto maybe_field = remove_field(&fields, fieldname); - if (auto field = maybe_field.get()) + if (const auto field = maybe_field.get()) out = std::move(*field); else missing_fields.push_back(fieldname); } - std::string ParagraphParser::optional_field(const std::string& fieldname) + std::string ParagraphParser::optional_field(const std::string& fieldname) const { return remove_field(&fields, fieldname).value_or(Strings::EMPTY); } -- cgit v1.2.3 From 3a43e190209719ea2789f1e50dc5a6a2a3e5d4b9 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 1 Sep 2017 17:02:12 -0700 Subject: [vcpkg_Input] Add missing const --- toolsrc/src/vcpkg_Input.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg_Input.cpp b/toolsrc/src/vcpkg_Input.cpp index 153e6a942..f1cac9632 100644 --- a/toolsrc/src/vcpkg_Input.cpp +++ b/toolsrc/src/vcpkg_Input.cpp @@ -13,7 +13,7 @@ namespace vcpkg::Input { const std::string as_lowercase = Strings::ascii_to_lowercase(package_spec_as_string); auto expected_spec = FullPackageSpec::from_string(as_lowercase, default_triplet); - if (auto spec = expected_spec.get()) + if (const auto spec = expected_spec.get()) { return PackageSpec{spec->package_spec}; } @@ -41,7 +41,7 @@ namespace vcpkg::Input { const std::string as_lowercase = Strings::ascii_to_lowercase(full_package_spec_as_string); auto expected_spec = FullPackageSpec::from_string(as_lowercase, default_triplet); - if (auto spec = expected_spec.get()) + if (const auto spec = expected_spec.get()) { return *spec; } -- cgit v1.2.3 From 9e7275c5dfeb9400492ceb8bed6635208a3d3cda Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 1 Sep 2017 17:03:23 -0700 Subject: [vcpkg_Chrono] Add missing consts --- toolsrc/src/vcpkg_Chrono.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg_Chrono.cpp b/toolsrc/src/vcpkg_Chrono.cpp index d70f4a054..d96f30987 100644 --- a/toolsrc/src/vcpkg_Chrono.cpp +++ b/toolsrc/src/vcpkg_Chrono.cpp @@ -7,43 +7,43 @@ namespace vcpkg { static std::string format_time_userfriendly(const std::chrono::nanoseconds& nanos) { + using std::chrono::duration_cast; using std::chrono::hours; - using std::chrono::minutes; - using std::chrono::seconds; - using std::chrono::milliseconds; using std::chrono::microseconds; + using std::chrono::milliseconds; + using std::chrono::minutes; using std::chrono::nanoseconds; - using std::chrono::duration_cast; + using std::chrono::seconds; const double nanos_as_double = static_cast(nanos.count()); if (duration_cast(nanos) > hours()) { - auto t = nanos_as_double / duration_cast(hours(1)).count(); + const auto t = nanos_as_double / duration_cast(hours(1)).count(); return Strings::format("%.4g h", t); } if (duration_cast(nanos) > minutes()) { - auto t = nanos_as_double / duration_cast(minutes(1)).count(); + const auto t = nanos_as_double / duration_cast(minutes(1)).count(); return Strings::format("%.4g min", t); } if (duration_cast(nanos) > seconds()) { - auto t = nanos_as_double / duration_cast(seconds(1)).count(); + const auto t = nanos_as_double / duration_cast(seconds(1)).count(); return Strings::format("%.4g s", t); } if (duration_cast(nanos) > milliseconds()) { - auto t = nanos_as_double / duration_cast(milliseconds(1)).count(); + const auto t = nanos_as_double / duration_cast(milliseconds(1)).count(); return Strings::format("%.4g ms", t); } if (duration_cast(nanos) > microseconds()) { - auto t = nanos_as_double / duration_cast(microseconds(1)).count(); + const auto t = nanos_as_double / duration_cast(microseconds(1)).count(); return Strings::format("%.4g us", t); } -- cgit v1.2.3 From 2d758beea9d8068f189f79d79b4087e40d42154b Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 1 Sep 2017 17:05:22 -0700 Subject: [vcpkg_Checks] Naming convention fixes --- toolsrc/include/vcpkg_Checks.h | 22 ++++++++++++---------- toolsrc/src/vcpkg_Checks.cpp | 19 +++++++++++-------- 2 files changed, 23 insertions(+), 18 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg_Checks.h b/toolsrc/include/vcpkg_Checks.h index 01cb7209b..ce486ac19 100644 --- a/toolsrc/include/vcpkg_Checks.h +++ b/toolsrc/include/vcpkg_Checks.h @@ -20,33 +20,35 @@ namespace vcpkg::Checks [[noreturn]] inline void exit_success(const LineInfo& line_info) { exit_with_code(line_info, EXIT_SUCCESS); } // Display an error message to the user and exit the tool. - [[noreturn]] void exit_with_message(const LineInfo& line_info, const CStringView errorMessage); + [[noreturn]] void exit_with_message(const LineInfo& line_info, const CStringView error_message); template // Display an error message to the user and exit the tool. [[noreturn]] void exit_with_message(const LineInfo& line_info, - const char* errorMessageTemplate, - const Arg1 errorMessageArg1, - const Args&... errorMessageArgs) + const char* error_message_template, + const Arg1 error_message_arg1, + const Args&... error_message_args) { - exit_with_message(line_info, Strings::format(errorMessageTemplate, errorMessageArg1, errorMessageArgs...)); + exit_with_message(line_info, + Strings::format(error_message_template, error_message_arg1, error_message_args...)); } void check_exit(const LineInfo& line_info, bool expression); - void check_exit(const LineInfo& line_info, bool expression, const CStringView errorMessage); + void check_exit(const LineInfo& line_info, bool expression, const CStringView error_message); template void check_exit(const LineInfo& line_info, Conditional&& expression, - const char* errorMessageTemplate, - const Arg1 errorMessageArg1, - const Args&... errorMessageArgs) + const char* error_message_template, + const Arg1 error_message_arg1, + const Args&... error_message_args) { if (!expression) { // Only create the string if the expression is false - exit_with_message(line_info, Strings::format(errorMessageTemplate, errorMessageArg1, errorMessageArgs...)); + exit_with_message(line_info, + Strings::format(error_message_template, error_message_arg1, error_message_args...)); } } } diff --git a/toolsrc/src/vcpkg_Checks.cpp b/toolsrc/src/vcpkg_Checks.cpp index 3692a0e9a..e7c9046a4 100644 --- a/toolsrc/src/vcpkg_Checks.cpp +++ b/toolsrc/src/vcpkg_Checks.cpp @@ -10,7 +10,7 @@ namespace vcpkg::Checks { [[noreturn]] static void cleanup_and_exit(const int exit_code) { - auto elapsed_us = GlobalState::timer.lock()->microseconds(); + const auto elapsed_us = GlobalState::timer.lock()->microseconds(); auto metrics = Metrics::g_metrics.lock(); metrics->track_metric("elapsed_us", elapsed_us); @@ -25,17 +25,20 @@ namespace vcpkg::Checks ::TerminateProcess(::GetCurrentProcess(), exit_code); } - static BOOL CtrlHandler(DWORD fdwCtrlType) + static BOOL ctrl_handler(DWORD fdw_ctrl_type) { { auto locked_metrics = Metrics::g_metrics.lock(); - locked_metrics->track_property("CtrlHandler", std::to_string(fdwCtrlType)); + locked_metrics->track_property("CtrlHandler", std::to_string(fdw_ctrl_type)); locked_metrics->track_property("error", "CtrlHandler was fired."); } cleanup_and_exit(EXIT_FAILURE); } - void register_console_ctrl_handler() { SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlHandler, TRUE); } + void register_console_ctrl_handler() + { + SetConsoleCtrlHandler(reinterpret_cast(ctrl_handler), TRUE); + } [[noreturn]] void unreachable(const LineInfo& line_info) { @@ -54,9 +57,9 @@ namespace vcpkg::Checks cleanup_and_exit(exit_code); } - [[noreturn]] void exit_with_message(const LineInfo& line_info, const CStringView errorMessage) + [[noreturn]] void exit_with_message(const LineInfo& line_info, const CStringView error_message) { - System::println(System::Color::error, errorMessage); + System::println(System::Color::error, error_message); exit_fail(line_info); } @@ -68,11 +71,11 @@ namespace vcpkg::Checks } } - void check_exit(const LineInfo& line_info, bool expression, const CStringView errorMessage) + void check_exit(const LineInfo& line_info, bool expression, const CStringView error_message) { if (!expression) { - exit_with_message(line_info, errorMessage); + exit_with_message(line_info, error_message); } } } -- cgit v1.2.3 From 66eeab0015866417f4386a3822127ce7d40c49f9 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 1 Sep 2017 17:08:21 -0700 Subject: [Triplet] Naming convention and missing const --- toolsrc/include/triplet.h | 4 ++-- toolsrc/src/triplet.cpp | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/triplet.h b/toolsrc/include/triplet.h index be3bcf5b3..46a52f8e6 100644 --- a/toolsrc/include/triplet.h +++ b/toolsrc/include/triplet.h @@ -9,7 +9,7 @@ namespace vcpkg struct Triplet { public: - constexpr Triplet() : m_instance(&default_instance) {} + constexpr Triplet() : m_instance(&DEFAULT_INSTANCE) {} static Triplet from_canonical_name(const std::string& triplet_as_string); @@ -26,7 +26,7 @@ namespace vcpkg bool operator==(const Triplet& other) const; private: - static const TripletInstance default_instance; + static const TripletInstance DEFAULT_INSTANCE; constexpr Triplet(const TripletInstance* ptr) : m_instance(ptr) {} diff --git a/toolsrc/src/triplet.cpp b/toolsrc/src/triplet.cpp index 451deb040..3b56da02a 100644 --- a/toolsrc/src/triplet.cpp +++ b/toolsrc/src/triplet.cpp @@ -15,7 +15,7 @@ namespace vcpkg bool operator==(const TripletInstance& o) const { return o.value == value; } }; - const TripletInstance Triplet::default_instance({}); + const TripletInstance Triplet::DEFAULT_INSTANCE({}); } template<> @@ -41,10 +41,10 @@ namespace vcpkg Triplet Triplet::from_canonical_name(const std::string& triplet_as_string) { std::string s(Strings::ascii_to_lowercase(triplet_as_string)); - auto it = std::find(s.cbegin(), s.cend(), '-'); + const auto it = std::find(s.cbegin(), s.cend(), '-'); Checks::check_exit(VCPKG_LINE_INFO, it != s.cend(), "Invalid triplet: %s", triplet_as_string); - auto p = g_triplet_instances.emplace(std::move(s)); + const auto p = g_triplet_instances.emplace(std::move(s)); return &*p.first; } -- cgit v1.2.3 From b76ac1da157c9c86cb451c871ea5ae0ddf74dbb9 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 1 Sep 2017 17:12:58 -0700 Subject: Add missing consts --- toolsrc/src/SourceParagraph.cpp | 6 +++--- toolsrc/src/StatusParagraphs.cpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/SourceParagraph.cpp b/toolsrc/src/SourceParagraph.cpp index 50d6ecf07..64b7bbad1 100644 --- a/toolsrc/src/SourceParagraph.cpp +++ b/toolsrc/src/SourceParagraph.cpp @@ -137,7 +137,7 @@ namespace vcpkg auto control_file = std::make_unique(); auto maybe_source = parse_source_paragraph(std::move(control_paragraphs.front())); - if (auto source = maybe_source.get()) + if (const auto source = maybe_source.get()) control_file->core_paragraph = std::move(*source); else return std::move(maybe_source).error(); @@ -147,7 +147,7 @@ namespace vcpkg for (auto&& feature_pgh : control_paragraphs) { auto maybe_feature = parse_feature_paragraph(std::move(feature_pgh)); - if (auto feature = maybe_feature.get()) + if (const auto feature = maybe_feature.get()) control_file->feature_paragraphs.emplace_back(std::move(*feature)); else return std::move(maybe_feature).error(); @@ -263,7 +263,7 @@ namespace vcpkg bool Supports::is_supported(Architecture arch, Platform plat, Linkage crt, ToolsetVersion tools) { - auto is_in_or_empty = [](auto v, auto&& c) -> bool { return c.empty() || c.end() != Util::find(c, v); }; + const auto is_in_or_empty = [](auto v, auto&& c) -> bool { return c.empty() || c.end() != Util::find(c, v); }; if (!is_in_or_empty(arch, architectures)) return false; if (!is_in_or_empty(plat, platforms)) return false; if (!is_in_or_empty(crt, crt_linkages)) return false; diff --git a/toolsrc/src/StatusParagraphs.cpp b/toolsrc/src/StatusParagraphs.cpp index 02ee61f75..aaba95eb9 100644 --- a/toolsrc/src/StatusParagraphs.cpp +++ b/toolsrc/src/StatusParagraphs.cpp @@ -67,7 +67,7 @@ namespace vcpkg { Checks::check_exit(VCPKG_LINE_INFO, pgh != nullptr, "Inserted null paragraph"); const PackageSpec& spec = pgh->package.spec; - auto ptr = find(spec.name(), spec.triplet(), pgh->package.feature); + const auto ptr = find(spec.name(), spec.triplet(), pgh->package.feature); if (ptr == end()) { paragraphs.push_back(std::move(pgh)); -- cgit v1.2.3 From e25a125d8540f13410008dff7281b5d679ac9fcb Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 1 Sep 2017 17:13:45 -0700 Subject: Don't return by const copy --- toolsrc/include/SourceParagraph.h | 2 +- toolsrc/src/SourceParagraph.cpp | 6 +----- 2 files changed, 2 insertions(+), 6 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/SourceParagraph.h b/toolsrc/include/SourceParagraph.h index 8563d83b0..3ee2138f1 100644 --- a/toolsrc/include/SourceParagraph.h +++ b/toolsrc/include/SourceParagraph.h @@ -27,7 +27,7 @@ namespace vcpkg // zlib[uwp] becomes Dependency{"zlib", "uwp"} std::vector expand_qualified_dependencies(const std::vector& depends); - const std::string to_string(const Dependency& dep); + std::string to_string(const Dependency& dep); struct FeatureParagraph { diff --git a/toolsrc/src/SourceParagraph.cpp b/toolsrc/src/SourceParagraph.cpp index 64b7bbad1..d8fa37914 100644 --- a/toolsrc/src/SourceParagraph.cpp +++ b/toolsrc/src/SourceParagraph.cpp @@ -220,11 +220,7 @@ namespace vcpkg return FeatureSpec::from_strings_and_triplet(filter_dependencies(deps, t), t); } - const std::string to_string(const Dependency& dep) - { - std::string name = dep.name(); - return name; - } + std::string to_string(const Dependency& dep) { return dep.name(); } ExpectedT> Supports::parse(const std::vector& strs) { -- cgit v1.2.3 From 95fa51a12a6e01c08a6b39ac45ecf711c45841fa Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 1 Sep 2017 17:14:26 -0700 Subject: Remove unused #include --- toolsrc/include/SourceParagraph.h | 1 - 1 file changed, 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/include/SourceParagraph.h b/toolsrc/include/SourceParagraph.h index 3ee2138f1..1357b3769 100644 --- a/toolsrc/include/SourceParagraph.h +++ b/toolsrc/include/SourceParagraph.h @@ -7,7 +7,6 @@ #include "vcpkg_expected.h" #include -#include #include namespace vcpkg -- cgit v1.2.3 From db06c7fa69da2f8b84431b8b79b0ef64e0bf00bf Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 1 Sep 2017 17:14:50 -0700 Subject: Add missing consts --- toolsrc/src/StatusParagraph.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/StatusParagraph.cpp b/toolsrc/src/StatusParagraph.cpp index 5b5c3978f..f8ae293c2 100644 --- a/toolsrc/src/StatusParagraph.cpp +++ b/toolsrc/src/StatusParagraph.cpp @@ -33,8 +33,8 @@ namespace vcpkg this->package = BinaryParagraph(std::move(fields)); auto b = status_field.begin(); - auto mark = b; - auto e = status_field.end(); + const auto mark = b; + const auto e = status_field.end(); // Todo: improve error handling while (b != e && *b != ' ') -- cgit v1.2.3 From 35a9d223bc14fb4b35d6ad876d208897c8ce590a Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 1 Sep 2017 17:22:55 -0700 Subject: Use Strings::join() and Strings::format() --- toolsrc/src/SourceParagraph.cpp | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/SourceParagraph.cpp b/toolsrc/src/SourceParagraph.cpp index d8fa37914..171689ce7 100644 --- a/toolsrc/src/SourceParagraph.cpp +++ b/toolsrc/src/SourceParagraph.cpp @@ -170,17 +170,10 @@ namespace vcpkg std::string Dependency::name() const { - std::string str = this->depend.name; - if (this->depend.features.empty()) return str; + if (this->depend.features.empty()) return this->depend.name; - str += "["; - for (auto&& s : this->depend.features) - { - str += s + ","; - } - str.pop_back(); - str += "]"; - return str; + const std::string features = Strings::join(",", this->depend.features); + return Strings::format("%s[%s]", this->depend.name, features); } std::vector vcpkg::expand_qualified_dependencies(const std::vector& depends) -- cgit v1.2.3 From c167c70c272a417779e601fffcbdb72278da1848 Mon Sep 17 00:00:00 2001 From: martin-s Date: Sat, 2 Sep 2017 16:48:29 +0200 Subject: - Added support for VS2013 build chain tools. --- toolsrc/include/VcpkgPaths.h | 2 +- toolsrc/src/PostBuildLint.cpp | 8 +++---- toolsrc/src/VcpkgPaths.cpp | 50 ++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 54 insertions(+), 6 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/VcpkgPaths.h b/toolsrc/include/VcpkgPaths.h index d55c95fe1..9b650bb6d 100644 --- a/toolsrc/include/VcpkgPaths.h +++ b/toolsrc/include/VcpkgPaths.h @@ -60,7 +60,7 @@ namespace vcpkg /// Retrieve a toolset matching a VS version /// - /// Valid version strings are "v140", "v141", and "". Empty string gets the latest. + /// Valid version strings are "v120", "v140", "v141", and "". Empty string gets the latest. /// const Toolset& get_toolset(const std::string& toolset_version) const; diff --git a/toolsrc/src/PostBuildLint.cpp b/toolsrc/src/PostBuildLint.cpp index 1fd48d3ec..33dc446cf 100644 --- a/toolsrc/src/PostBuildLint.cpp +++ b/toolsrc/src/PostBuildLint.cpp @@ -45,8 +45,8 @@ namespace vcpkg::PostBuildLint {"msvcp100d.dll", R"(msvcp100d\.dll)"}, {"msvcp110.dll", R"(msvcp110\.dll)"}, {"msvcp110_win.dll", R"(msvcp110_win\.dll)"}, - {"msvcp120.dll", R"(msvcp120\.dll)"}, - {"msvcp120_clr0400.dll", R"(msvcp120_clr0400\.dll)"}, + //{"msvcp120.dll", R"(msvcp120\.dll)"}, + //{"msvcp120_clr0400.dll", R"(msvcp120_clr0400\.dll)"}, {"msvcp60.dll", R"(msvcp60\.dll)"}, {"msvcp60.dll", R"(msvcp60\.dll)"}, @@ -54,8 +54,8 @@ namespace vcpkg::PostBuildLint {"msvcr100d.dll", R"(msvcr100d\.dll)"}, {"msvcr100_clr0400.dll", R"(msvcr100_clr0400\.dll)"}, {"msvcr110.dll", R"(msvcr110\.dll)"}, - {"msvcr120.dll", R"(msvcr120\.dll)"}, - {"msvcr120_clr0400.dll", R"(msvcr120_clr0400\.dll)"}, + //{"msvcr120.dll", R"(msvcr120\.dll)"}, + //{"msvcr120_clr0400.dll", R"(msvcr120_clr0400\.dll)"}, {"msvcrt20.dll", R"(msvcrt20\.dll)"}, {"msvcrt40.dll", R"(msvcrt40\.dll)"}}; diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp index 906a5e67f..71a35d24c 100644 --- a/toolsrc/src/VcpkgPaths.cpp +++ b/toolsrc/src/VcpkgPaths.cpp @@ -268,6 +268,19 @@ namespace vcpkg return nullopt; } + + static Optional get_vs2013_installation_instance() + { + const Optional vs2013_cmntools_optional = System::get_environment_variable(L"VS120COMNTOOLS"); + if (const auto v = vs2013_cmntools_optional.get()) + { + const fs::path vs2013_cmntools = fs::path(*v).parent_path(); // The call to parent_path() is needed because + // the env variable has a trailing backslash + return vs2013_cmntools.parent_path().parent_path(); + } + + return nullopt; + } static std::vector find_toolset_instances(const VcpkgPaths& paths) { @@ -275,12 +288,46 @@ namespace vcpkg const auto& fs = paths.get_filesystem(); - const std::vector vs2017_installation_instances = get_vs2017_installation_instances(paths); // Note: this will contain a mix of vcvarsall.bat locations and dumpbin.exe locations. std::vector paths_examined; std::vector found_toolsets; + // VS2013 + const Optional vs_2013_installation_instance = get_vs2013_installation_instance(); + if (const auto v = vs_2013_installation_instance.get()) + { + const fs::path vs2013_vcvarsall_bat = *v / "VC" / "vcvarsall.bat"; + + paths_examined.push_back(vs2013_vcvarsall_bat); + if (fs.exists(vs2013_vcvarsall_bat)) + { + const fs::path vs2013_dumpbin_exe = *v / "VC" / "bin" / "dumpbin.exe"; + paths_examined.push_back(vs2013_dumpbin_exe); + + const fs::path vs2013_bin_dir = vs2013_vcvarsall_bat.parent_path() / "bin"; + std::vector supported_architectures; + if (fs.exists(vs2013_bin_dir / "vcvars32.bat")) + supported_architectures.push_back({L"x86", CPU::X86, CPU::X86}); + if (fs.exists(3 / "amd64\\vcvars64.bat")) + supported_architectures.push_back({L"x64", CPU::X64, CPU::X64}); + if (fs.exists(vs2013_bin_dir / "x86_amd64\\vcvarsx86_amd64.bat")) + supported_architectures.push_back({L"x86_amd64", CPU::X86, CPU::X64}); + if (fs.exists(vs2013_bin_dir / "x86_arm\\vcvarsx86_arm.bat")) + supported_architectures.push_back({L"x86_arm", CPU::X86, CPU::ARM}); + if (fs.exists(vs2013_bin_dir / "amd64_x86\\vcvarsamd64_x86.bat")) + supported_architectures.push_back({L"amd64_x86", CPU::X64, CPU::X86}); + if (fs.exists(vs2013_bin_dir / "amd64_arm\\vcvarsamd64_arm.bat")) + supported_architectures.push_back({L"amd64_arm", CPU::X64, CPU::ARM}); + + if (fs.exists(vs2013_dumpbin_exe)) + { + found_toolsets.push_back( + {vs2013_dumpbin_exe, vs2013_vcvarsall_bat, L"v120", supported_architectures}); + } + } + } + // VS2015 const Optional vs_2015_installation_instance = get_vs2015_installation_instance(); if (const auto v = vs_2015_installation_instance.get()) @@ -318,6 +365,7 @@ namespace vcpkg // VS2017 Optional vs2017_toolset; + const std::vector vs2017_installation_instances = get_vs2017_installation_instances(paths); for (const std::string& instance : vs2017_installation_instances) { const fs::path vc_dir = fs::path{instance} / "VC"; -- cgit v1.2.3 From 97104258a782630a1a0d9a2504a533a550c50b69 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 4 Sep 2017 02:11:41 -0700 Subject: Update CHANGELOG and bump version to v0.0.86 --- toolsrc/VERSION.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/VERSION.txt b/toolsrc/VERSION.txt index d27b8ca83..df2e96a41 100644 --- a/toolsrc/VERSION.txt +++ b/toolsrc/VERSION.txt @@ -1 +1 @@ -"0.0.85" \ No newline at end of file +"0.0.86" \ No newline at end of file -- cgit v1.2.3 From bafe4f2fe071503458b4f7c2bf1c645420dbc6ff Mon Sep 17 00:00:00 2001 From: atkawa7 Date: Wed, 6 Sep 2017 10:33:51 -0700 Subject: an empty delimiter causes the split function to fail --- toolsrc/src/vcpkg_Strings.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg_Strings.cpp b/toolsrc/src/vcpkg_Strings.cpp index 15851829d..5ad951399 100644 --- a/toolsrc/src/vcpkg_Strings.cpp +++ b/toolsrc/src/vcpkg_Strings.cpp @@ -136,6 +136,11 @@ namespace vcpkg::Strings std::vector split(const std::string& s, const std::string& delimiter) { std::vector output; + + if(delimiter.empty()){ + output.push_back(s); + return output; + } size_t i = 0; for (size_t pos = s.find(delimiter); pos != std::string::npos; pos = s.find(delimiter, pos)) -- cgit v1.2.3 From d2de7d3e7d1a0bea3dba9a0a7f6cfff68ae513a0 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 7 Sep 2017 16:16:30 -0700 Subject: [vcpkg_Build.h] Naming scheme, unneeded #include, unneeded inline --- toolsrc/include/vcpkg_Build.h | 7 +++---- toolsrc/src/commands_ci.cpp | 2 +- toolsrc/src/vcpkg_Build.cpp | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg_Build.h b/toolsrc/include/vcpkg_Build.h index fc6f28e24..78e89d4de 100644 --- a/toolsrc/include/vcpkg_Build.h +++ b/toolsrc/include/vcpkg_Build.h @@ -9,7 +9,6 @@ #include #include -#include #include namespace vcpkg::Build @@ -56,7 +55,7 @@ namespace vcpkg::Build CASCADED_DUE_TO_MISSING_DEPENDENCIES }; - static constexpr std::array BuildResult_values = { + static constexpr std::array BUILD_RESULT_VALUES = { BuildResult::SUCCEEDED, BuildResult::BUILD_FAILED, BuildResult::POST_BUILD_CHECKS_FAILED, @@ -143,7 +142,7 @@ namespace vcpkg::Build COUNT, }; - constexpr std::array g_all_policies = { + constexpr std::array G_ALL_POLICIES = { BuildPolicy::EMPTY_PACKAGE, BuildPolicy::DLLS_WITHOUT_LIBS, BuildPolicy::ONLY_RELEASE_CRT, @@ -159,7 +158,7 @@ namespace vcpkg::Build BuildPolicies() = default; BuildPolicies(std::map&& map) : m_policies(std::move(map)) {} - inline bool is_enabled(BuildPolicy policy) const + bool is_enabled(BuildPolicy policy) const { const auto it = m_policies.find(policy); if (it != m_policies.cend()) return it->second; diff --git a/toolsrc/src/commands_ci.cpp b/toolsrc/src/commands_ci.cpp index ca5e8a9a9..fda9f1716 100644 --- a/toolsrc/src/commands_ci.cpp +++ b/toolsrc/src/commands_ci.cpp @@ -77,7 +77,7 @@ namespace vcpkg::Commands::CI } std::map summary; - for (const BuildResult& v : Build::BuildResult_values) + for (const BuildResult& v : Build::BUILD_RESULT_VALUES) { summary[v] = 0; } diff --git a/toolsrc/src/vcpkg_Build.cpp b/toolsrc/src/vcpkg_Build.cpp index a2fa99ac8..d40140aca 100644 --- a/toolsrc/src/vcpkg_Build.cpp +++ b/toolsrc/src/vcpkg_Build.cpp @@ -289,7 +289,7 @@ namespace vcpkg::Build if (!version.empty()) build_info.version = std::move(version); std::map policies; - for (auto policy : g_all_policies) + for (auto policy : G_ALL_POLICIES) { const auto setting = parser.optional_field(to_string(policy)); if (setting.empty()) continue; -- cgit v1.2.3 From c7589e76c0f3d2e266a5724ea57fd328d2ee44ad Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 8 Sep 2017 22:09:57 -0700 Subject: Update CHANGELOG and bump version to v0.0.87 --- toolsrc/VERSION.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/VERSION.txt b/toolsrc/VERSION.txt index df2e96a41..422bb25f0 100644 --- a/toolsrc/VERSION.txt +++ b/toolsrc/VERSION.txt @@ -1 +1 @@ -"0.0.86" \ No newline at end of file +"0.0.87" \ No newline at end of file -- cgit v1.2.3 From 3ef9df647299eeec7bcaf06aedb4281359e1a816 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Sat, 9 Sep 2017 00:20:16 -0700 Subject: Update CHANGELOG and bump version to v0.0.88 --- toolsrc/VERSION.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/VERSION.txt b/toolsrc/VERSION.txt index 422bb25f0..feb2033f0 100644 --- a/toolsrc/VERSION.txt +++ b/toolsrc/VERSION.txt @@ -1 +1 @@ -"0.0.87" \ No newline at end of file +"0.0.88" \ No newline at end of file -- cgit v1.2.3 From 43dde3f4892be55558b012b845d864e7be95c7b9 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 13 Sep 2017 16:10:25 -0700 Subject: Refactor package removal code to eliminate its duplication --- toolsrc/include/vcpkg_Commands.h | 13 +++++++ toolsrc/src/commands_install.cpp | 73 ++++++++-------------------------------- toolsrc/src/commands_remove.cpp | 63 +++++++++++++++++++--------------- 3 files changed, 63 insertions(+), 86 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg_Commands.h b/toolsrc/include/vcpkg_Commands.h index 756a12f01..079388587 100644 --- a/toolsrc/include/vcpkg_Commands.h +++ b/toolsrc/include/vcpkg_Commands.h @@ -82,6 +82,19 @@ namespace vcpkg::Commands namespace Remove { + enum class Purge + { + NO = 0, + YES + }; + + inline Purge to_purge(const bool value) { return value ? Purge::YES : Purge::NO; } + + void perform_remove_plan_action(const VcpkgPaths& paths, + const Dependencies::RemovePlanAction& action, + const Purge purge, + StatusParagraphs& status_db); + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet); void remove_package(const VcpkgPaths& paths, const PackageSpec& spec, StatusParagraphs* status_db); } diff --git a/toolsrc/src/commands_install.cpp b/toolsrc/src/commands_install.cpp index d7c14f39c..2473ad599 100644 --- a/toolsrc/src/commands_install.cpp +++ b/toolsrc/src/commands_install.cpp @@ -524,72 +524,27 @@ namespace vcpkg::Commands::Install Checks::exit_success(VCPKG_LINE_INFO); } - // execute the plan - if (GlobalState::feature_packages) - { - for (const auto& action : action_plan) - { - if (auto install_action = action.install_plan.get()) - { - const BuildResult result = - perform_install_plan_action(paths, *install_action, install_plan_options, status_db); - if (result != BuildResult::SUCCEEDED) - { - System::println(Build::create_user_troubleshooting_message(install_action->spec)); - Checks::exit_fail(VCPKG_LINE_INFO); - } - } - else if (auto remove_action = action.remove_plan.get()) - { - static const std::string OPTION_PURGE = "--purge"; - static const std::string OPTION_NO_PURGE = "--no-purge"; - - const bool alsoRemoveFolderFromPackages = options.find(OPTION_NO_PURGE) == options.end(); - if (options.find(OPTION_PURGE) != options.end() && !alsoRemoveFolderFromPackages) - { - // User specified --purge and --no-purge - System::println(System::Color::error, "Error: cannot specify both --no-purge and --purge."); - System::print(EXAMPLE); - Checks::exit_fail(VCPKG_LINE_INFO); - } - const std::string display_name = remove_action->spec.to_string(); - switch (remove_action->plan_type) - { - case RemovePlanType::NOT_INSTALLED: - System::println(System::Color::success, "Package %s is not installed", display_name); - break; - case RemovePlanType::REMOVE: - System::println("Removing package %s... ", display_name); - Commands::Remove::remove_package(paths, remove_action->spec, &status_db); - System::println(System::Color::success, "Removing package %s... done", display_name); - break; - case RemovePlanType::UNKNOWN: - default: Checks::unreachable(VCPKG_LINE_INFO); - } - - if (alsoRemoveFolderFromPackages) - { - System::println("Purging package %s... ", display_name); - Files::Filesystem& fs = paths.get_filesystem(); - std::error_code ec; - fs.remove_all(paths.packages / remove_action->spec.dir(), ec); - System::println(System::Color::success, "Purging package %s... done", display_name); - } - } - } - } - else + for (const auto& action : action_plan) { - for (const auto& action : action_plan) + if (auto install_action = action.install_plan.get()) { - const auto& iaction = action.install_plan.value_or_exit(VCPKG_LINE_INFO); - const BuildResult result = perform_install_plan_action(paths, iaction, install_plan_options, status_db); + const BuildResult result = + perform_install_plan_action(paths, *install_action, install_plan_options, status_db); if (result != BuildResult::SUCCEEDED) { - System::println(Build::create_user_troubleshooting_message(iaction.spec)); + System::println(Build::create_user_troubleshooting_message(install_action->spec)); Checks::exit_fail(VCPKG_LINE_INFO); } } + else if (auto remove_action = action.remove_plan.get()) + { + Checks::check_exit(VCPKG_LINE_INFO, GlobalState::feature_packages); + Remove::perform_remove_plan_action(paths, *remove_action, Remove::Purge::YES, status_db); + } + else + { + Checks::unreachable(VCPKG_LINE_INFO); + } } Checks::exit_success(VCPKG_LINE_INFO); diff --git a/toolsrc/src/commands_remove.cpp b/toolsrc/src/commands_remove.cpp index 2b5033166..453e0ec96 100644 --- a/toolsrc/src/commands_remove.cpp +++ b/toolsrc/src/commands_remove.cpp @@ -129,6 +129,37 @@ namespace vcpkg::Commands::Remove } } + void perform_remove_plan_action(const VcpkgPaths& paths, + const RemovePlanAction& action, + const Purge purge, + StatusParagraphs& status_db) + { + const std::string display_name = action.spec.to_string(); + + switch (action.plan_type) + { + case RemovePlanType::NOT_INSTALLED: + System::println(System::Color::success, "Package %s is not installed", display_name); + break; + case RemovePlanType::REMOVE: + System::println("Removing package %s... ", display_name); + remove_package(paths, action.spec, &status_db); + System::println(System::Color::success, "Removing package %s... done", display_name); + break; + case RemovePlanType::UNKNOWN: + default: Checks::unreachable(VCPKG_LINE_INFO); + } + + if (purge == Purge::YES) + { + System::println("Purging package %s... ", display_name); + Files::Filesystem& fs = paths.get_filesystem(); + std::error_code ec; + fs.remove_all(paths.packages / action.spec.dir(), ec); + System::println(System::Color::success, "Purging package %s... done", display_name); + } + } + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) { static const std::string OPTION_PURGE = "--purge"; @@ -166,14 +197,15 @@ namespace vcpkg::Commands::Remove Input::check_triplet(spec.triplet(), paths); } - const bool alsoRemoveFolderFromPackages = options.find(OPTION_NO_PURGE) == options.end(); - if (options.find(OPTION_PURGE) != options.end() && !alsoRemoveFolderFromPackages) + const bool no_purge_was_passed = options.find(OPTION_NO_PURGE) != options.end(); + const bool purge_was_passed = options.find(OPTION_PURGE) != options.end(); + if (purge_was_passed && no_purge_was_passed) { - // User specified --purge and --no-purge System::println(System::Color::error, "Error: cannot specify both --no-purge and --purge."); System::print(EXAMPLE); Checks::exit_fail(VCPKG_LINE_INFO); } + const Purge purge = to_purge(purge_was_passed || !no_purge_was_passed); const bool isRecursive = options.find(OPTION_RECURSE) != options.cend(); const bool dryRun = options.find(OPTION_DRY_RUN) != options.cend(); @@ -209,30 +241,7 @@ namespace vcpkg::Commands::Remove for (const RemovePlanAction& action : remove_plan) { - const std::string display_name = action.spec.to_string(); - - switch (action.plan_type) - { - case RemovePlanType::NOT_INSTALLED: - System::println(System::Color::success, "Package %s is not installed", display_name); - break; - case RemovePlanType::REMOVE: - System::println("Removing package %s... ", display_name); - remove_package(paths, action.spec, &status_db); - System::println(System::Color::success, "Removing package %s... done", display_name); - break; - case RemovePlanType::UNKNOWN: - default: Checks::unreachable(VCPKG_LINE_INFO); - } - - if (alsoRemoveFolderFromPackages) - { - System::println("Purging package %s... ", display_name); - Files::Filesystem& fs = paths.get_filesystem(); - std::error_code ec; - fs.remove_all(paths.packages / action.spec.dir(), ec); - System::println(System::Color::success, "Purging package %s... done", display_name); - } + perform_remove_plan_action(paths, action, purge, status_db); } Checks::exit_success(VCPKG_LINE_INFO); -- cgit v1.2.3 From 32a01e68516d51b998ec80878eb20c000f6c95ba Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 13 Sep 2017 16:12:08 -0700 Subject: [install] Naming scheme and const --- toolsrc/src/commands_install.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/commands_install.cpp b/toolsrc/src/commands_install.cpp index 2473ad599..2e169e8af 100644 --- a/toolsrc/src/commands_install.cpp +++ b/toolsrc/src/commands_install.cpp @@ -59,7 +59,7 @@ namespace vcpkg::Commands::Install auto files = fs.get_files_recursive(source_dir); for (auto&& file : files) { - auto status = fs.status(file, ec); + const auto status = fs.status(file, ec); if (ec) { System::println(System::Color::error, "failed: %s: %s", file.u8string(), ec.message()); @@ -309,7 +309,7 @@ namespace vcpkg::Commands::Install const BinaryControlFile bcf = Paragraphs::try_load_cached_control_package(paths, action.spec).value_or_exit(VCPKG_LINE_INFO); System::println("Installing package %s... ", display_name_with_features); - auto install_result = install_package(paths, bcf, &status_db); + const auto install_result = install_package(paths, bcf, &status_db); switch (install_result) { case InstallResult::SUCCESS: @@ -328,7 +328,7 @@ namespace vcpkg::Commands::Install System::Color::warning, "Package %s is already built -- not building from HEAD", display_name); } System::println("Installing package %s... ", display_name); - auto install_result = install_package( + const auto install_result = install_package( paths, action.any_paragraph.binary_control_file.value_or_exit(VCPKG_LINE_INFO), &status_db); switch (install_result) { @@ -470,7 +470,7 @@ namespace vcpkg::Commands::Install const std::unordered_set options = args.check_and_get_optional_command_arguments( {OPTION_DRY_RUN, OPTION_USE_HEAD_VERSION, OPTION_NO_DOWNLOADS, OPTION_RECURSE}); - const bool dryRun = options.find(OPTION_DRY_RUN) != options.cend(); + const bool dry_run = options.find(OPTION_DRY_RUN) != options.cend(); const bool use_head_version = options.find(OPTION_USE_HEAD_VERSION) != options.cend(); const bool no_downloads = options.find(OPTION_NO_DOWNLOADS) != options.cend(); const bool is_recursive = options.find(OPTION_RECURSE) != options.cend(); @@ -519,14 +519,14 @@ namespace vcpkg::Commands::Install print_plan(action_plan, is_recursive); - if (dryRun) + if (dry_run) { Checks::exit_success(VCPKG_LINE_INFO); } for (const auto& action : action_plan) { - if (auto install_action = action.install_plan.get()) + if (const auto install_action = action.install_plan.get()) { const BuildResult result = perform_install_plan_action(paths, *install_action, install_plan_options, status_db); @@ -536,7 +536,7 @@ namespace vcpkg::Commands::Install Checks::exit_fail(VCPKG_LINE_INFO); } } - else if (auto remove_action = action.remove_plan.get()) + else if (const auto remove_action = action.remove_plan.get()) { Checks::check_exit(VCPKG_LINE_INFO, GlobalState::feature_packages); Remove::perform_remove_plan_action(paths, *remove_action, Remove::Purge::YES, status_db); -- cgit v1.2.3 From d521d366b278e9e963c18d34a7c5f41f42ea9ec7 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 13 Sep 2017 17:23:04 -0700 Subject: Rework vcpkg install (and vcpkg ci) - Refactor install-plan-execution code to reduce duplication - Add `vcpkg install --keep-going` option - Add elapsed time to each invidial package and total time - Add a counter to the install (e.g. Starting package 3/12: ) --- toolsrc/include/vcpkg_Commands.h | 24 ++++++++ toolsrc/include/vcpkg_Dependencies.h | 2 + toolsrc/src/commands_ci.cpp | 52 +++------------- toolsrc/src/commands_install.cpp | 112 ++++++++++++++++++++++++++++------- toolsrc/src/vcpkg_Dependencies.cpp | 15 +++++ 5 files changed, 137 insertions(+), 68 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg_Commands.h b/toolsrc/include/vcpkg_Commands.h index 079388587..070a8ec49 100644 --- a/toolsrc/include/vcpkg_Commands.h +++ b/toolsrc/include/vcpkg_Commands.h @@ -33,6 +33,22 @@ namespace vcpkg::Commands namespace Install { + enum class KeepGoing + { + NO = 0, + YES + }; + + inline KeepGoing to_keep_going(const bool value) { return value ? KeepGoing::YES : KeepGoing::NO; } + + enum class PrintSummary + { + NO = 0, + YES + }; + + inline PrintSummary to_print_summary(const bool value) { return value ? PrintSummary::YES : PrintSummary::NO; } + struct InstallDir { static InstallDir from_destination_root(const fs::path& destination_root, @@ -67,6 +83,14 @@ namespace vcpkg::Commands InstallResult install_package(const VcpkgPaths& paths, const BinaryControlFile& binary_paragraph, StatusParagraphs* status_db); + + void perform_and_exit(const std::vector& action_plan, + const Build::BuildPackageOptions& install_plan_options, + const KeepGoing keep_going, + const PrintSummary print_summary, + const VcpkgPaths& paths, + StatusParagraphs& status_db); + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet); } diff --git a/toolsrc/include/vcpkg_Dependencies.h b/toolsrc/include/vcpkg_Dependencies.h index 235abb839..d67122e48 100644 --- a/toolsrc/include/vcpkg_Dependencies.h +++ b/toolsrc/include/vcpkg_Dependencies.h @@ -89,6 +89,8 @@ namespace vcpkg::Dependencies Optional install_plan; Optional remove_plan; + + const PackageSpec& spec() const; }; enum class ExportPlanType diff --git a/toolsrc/src/commands_ci.cpp b/toolsrc/src/commands_ci.cpp index fda9f1716..75ff65556 100644 --- a/toolsrc/src/commands_ci.cpp +++ b/toolsrc/src/commands_ci.cpp @@ -41,57 +41,19 @@ namespace vcpkg::Commands::CI StatusParagraphs status_db = database_load_check(paths); const auto& paths_port_file = Dependencies::PathsPortFile(paths); - const std::vector install_plan = + std::vector install_plan = Dependencies::create_install_plan(paths_port_file, specs, status_db); Checks::check_exit(VCPKG_LINE_INFO, !install_plan.empty(), "Install plan cannot be empty"); - std::vector results; - std::vector timing; - const ElapsedTime timer = ElapsedTime::create_started(); - size_t counter = 0; - const size_t package_count = install_plan.size(); const Build::BuildPackageOptions install_plan_options = {Build::UseHeadVersion::NO, Build::AllowDownloads::YES}; - for (const InstallPlanAction& action : install_plan) - { - const ElapsedTime build_timer = ElapsedTime::create_started(); - counter++; - const std::string display_name = action.spec.to_string(); - System::println("Starting package %d/%d: %s", counter, package_count, display_name); + const std::vector action_plan = + Util::fmap(install_plan, [](InstallPlanAction& install_action) { + return Dependencies::AnyAction(std::move(install_action)); + }); - timing.push_back("0"); - results.push_back(BuildResult::NULLVALUE); - - const BuildResult result = - Install::perform_install_plan_action(paths, action, install_plan_options, status_db); - timing.back() = build_timer.to_string(); - results.back() = result; - System::println("Elapsed time for package %s: %s", action.spec, build_timer.to_string()); - } - - System::println("Total time taken: %s", timer.to_string()); - - for (size_t i = 0; i < results.size(); i++) - { - System::println("%s: %s: %s", install_plan[i].spec, Build::to_string(results[i]), timing[i]); - } - - std::map summary; - for (const BuildResult& v : Build::BUILD_RESULT_VALUES) - { - summary[v] = 0; - } - - for (const BuildResult& r : results) - { - summary[r]++; - } - - System::println("\n\nSUMMARY"); - for (const std::pair& entry : summary) - { - System::println(" %s: %d", Build::to_string(entry.first), entry.second); - } + Install::perform_and_exit( + action_plan, install_plan_options, Install::KeepGoing::YES, Install::PrintSummary::YES, paths, status_db); Checks::exit_success(VCPKG_LINE_INFO); } diff --git a/toolsrc/src/commands_install.cpp b/toolsrc/src/commands_install.cpp index 2e169e8af..d4cb94775 100644 --- a/toolsrc/src/commands_install.cpp +++ b/toolsrc/src/commands_install.cpp @@ -442,12 +442,98 @@ namespace vcpkg::Commands::Install } } + void perform_and_exit(const std::vector& action_plan, + const Build::BuildPackageOptions& install_plan_options, + const KeepGoing keep_going, + const PrintSummary print_summary, + const VcpkgPaths& paths, + StatusParagraphs& status_db) + { + std::vector results; + std::vector timing; + const ElapsedTime timer = ElapsedTime::create_started(); + size_t counter = 0; + const size_t package_count = action_plan.size(); + + for (const auto& action : action_plan) + { + const ElapsedTime build_timer = ElapsedTime::create_started(); + counter++; + + if (counter > 2) + { + break; + } + + const std::string display_name = action.spec().to_string(); + System::println("Starting package %d/%d: %s", counter, package_count, display_name); + + timing.push_back("0"); + results.push_back(BuildResult::NULLVALUE); + + if (const auto install_action = action.install_plan.get()) + { + const BuildResult result = + perform_install_plan_action(paths, *install_action, install_plan_options, status_db); + if (result != BuildResult::SUCCEEDED && keep_going == KeepGoing::NO) + { + System::println(Build::create_user_troubleshooting_message(install_action->spec)); + Checks::exit_fail(VCPKG_LINE_INFO); + } + + results.back() = result; + } + else if (const auto remove_action = action.remove_plan.get()) + { + Checks::check_exit(VCPKG_LINE_INFO, GlobalState::feature_packages); + Remove::perform_remove_plan_action(paths, *remove_action, Remove::Purge::YES, status_db); + } + else + { + Checks::unreachable(VCPKG_LINE_INFO); + } + + timing.back() = build_timer.to_string(); + System::println("Elapsed time for package %s: %s", display_name, build_timer.to_string()); + } + + System::println("Total time taken: %s", timer.to_string()); + + if (print_summary == PrintSummary::YES) + { + for (size_t i = 0; i < results.size(); i++) + { + System::println("%s: %s: %s", action_plan[i].spec(), Build::to_string(results[i]), timing[i]); + } + + std::map summary; + for (const BuildResult& v : Build::BUILD_RESULT_VALUES) + { + summary[v] = 0; + } + + for (const BuildResult& r : results) + { + summary[r]++; + } + + System::println("\n\nSUMMARY"); + for (const std::pair& entry : summary) + { + System::println(" %s: %d", Build::to_string(entry.first), entry.second); + } + } + + Checks::exit_success(VCPKG_LINE_INFO); + } + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) { static const std::string OPTION_DRY_RUN = "--dry-run"; static const std::string OPTION_USE_HEAD_VERSION = "--head"; static const std::string OPTION_NO_DOWNLOADS = "--no-downloads"; static const std::string OPTION_RECURSE = "--recurse"; + static const std::string OPTION_KEEP_GOING = "--keep-going"; // input sanitization static const std::string EXAMPLE = @@ -469,11 +555,12 @@ namespace vcpkg::Commands::Install } const std::unordered_set options = args.check_and_get_optional_command_arguments( - {OPTION_DRY_RUN, OPTION_USE_HEAD_VERSION, OPTION_NO_DOWNLOADS, OPTION_RECURSE}); + {OPTION_DRY_RUN, OPTION_USE_HEAD_VERSION, OPTION_NO_DOWNLOADS, OPTION_RECURSE, OPTION_KEEP_GOING}); const bool dry_run = options.find(OPTION_DRY_RUN) != options.cend(); const bool use_head_version = options.find(OPTION_USE_HEAD_VERSION) != options.cend(); const bool no_downloads = options.find(OPTION_NO_DOWNLOADS) != options.cend(); const bool is_recursive = options.find(OPTION_RECURSE) != options.cend(); + const KeepGoing keep_going = to_keep_going(options.find(OPTION_KEEP_GOING) != options.cend()); // create the plan StatusParagraphs status_db = database_load_check(paths); @@ -524,28 +611,7 @@ namespace vcpkg::Commands::Install Checks::exit_success(VCPKG_LINE_INFO); } - for (const auto& action : action_plan) - { - if (const auto install_action = action.install_plan.get()) - { - const BuildResult result = - perform_install_plan_action(paths, *install_action, install_plan_options, status_db); - if (result != BuildResult::SUCCEEDED) - { - System::println(Build::create_user_troubleshooting_message(install_action->spec)); - Checks::exit_fail(VCPKG_LINE_INFO); - } - } - else if (const auto remove_action = action.remove_plan.get()) - { - Checks::check_exit(VCPKG_LINE_INFO, GlobalState::feature_packages); - Remove::perform_remove_plan_action(paths, *remove_action, Remove::Purge::YES, status_db); - } - else - { - Checks::unreachable(VCPKG_LINE_INFO); - } - } + perform_and_exit(action_plan, install_plan_options, keep_going, PrintSummary::NO, paths, status_db); Checks::exit_success(VCPKG_LINE_INFO); } diff --git a/toolsrc/src/vcpkg_Dependencies.cpp b/toolsrc/src/vcpkg_Dependencies.cpp index 1a0f0a6ed..8dd60a2eb 100644 --- a/toolsrc/src/vcpkg_Dependencies.cpp +++ b/toolsrc/src/vcpkg_Dependencies.cpp @@ -213,6 +213,21 @@ namespace vcpkg::Dependencies { } + const PackageSpec& AnyAction::spec() const + { + if (const auto p = install_plan.get()) + { + return p->spec; + } + + if (const auto p = remove_plan.get()) + { + return p->spec; + } + + Checks::exit_with_message(VCPKG_LINE_INFO, "Null action"); + } + bool ExportPlanAction::compare_by_name(const ExportPlanAction* left, const ExportPlanAction* right) { return left->spec.name() < right->spec.name(); -- cgit v1.2.3 From d080439ce408c4fd0312f0925f10543179e79b27 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 13 Sep 2017 21:46:48 -0700 Subject: [commands_remove.cpp] Naming scheme and missing const --- toolsrc/src/commands_remove.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/commands_remove.cpp b/toolsrc/src/commands_remove.cpp index 453e0ec96..a9f1b2564 100644 --- a/toolsrc/src/commands_remove.cpp +++ b/toolsrc/src/commands_remove.cpp @@ -18,7 +18,7 @@ namespace vcpkg::Commands::Remove { auto& fs = paths.get_filesystem(); auto spghs = status_db->find_all(spec.name(), spec.triplet()); - auto core_pkg = **status_db->find(spec.name(), spec.triplet(), Strings::EMPTY); + const auto core_pkg = **status_db->find(spec.name(), spec.triplet(), Strings::EMPTY); for (auto&& spgh : spghs) { @@ -31,7 +31,7 @@ namespace vcpkg::Commands::Remove auto maybe_lines = fs.read_lines(paths.listfile_path(core_pkg.package)); - if (auto lines = maybe_lines.get()) + if (const auto lines = maybe_lines.get()) { std::vector dirs_touched; for (auto&& suffix : *lines) @@ -42,7 +42,7 @@ namespace vcpkg::Commands::Remove auto target = paths.installed / suffix; - auto status = fs.status(target, ec); + const auto status = fs.status(target, ec); if (ec) { System::println(System::Color::error, "failed: %s", ec.message()); @@ -72,7 +72,7 @@ namespace vcpkg::Commands::Remove } auto b = dirs_touched.rbegin(); - auto e = dirs_touched.rend(); + const auto e = dirs_touched.rend(); for (; b != e; ++b) { if (fs.is_empty(*b)) @@ -100,11 +100,11 @@ namespace vcpkg::Commands::Remove static void print_plan(const std::map>& group_by_plan_type) { - static constexpr std::array order = {RemovePlanType::NOT_INSTALLED, RemovePlanType::REMOVE}; + static constexpr std::array ORDER = {RemovePlanType::NOT_INSTALLED, RemovePlanType::REMOVE}; - for (const RemovePlanType plan_type : order) + for (const RemovePlanType plan_type : ORDER) { - auto it = group_by_plan_type.find(plan_type); + const auto it = group_by_plan_type.find(plan_type); if (it == group_by_plan_type.cend()) { continue; @@ -206,8 +206,8 @@ namespace vcpkg::Commands::Remove Checks::exit_fail(VCPKG_LINE_INFO); } const Purge purge = to_purge(purge_was_passed || !no_purge_was_passed); - const bool isRecursive = options.find(OPTION_RECURSE) != options.cend(); - const bool dryRun = options.find(OPTION_DRY_RUN) != options.cend(); + const bool is_recursive = options.find(OPTION_RECURSE) != options.cend(); + const bool dry_run = options.find(OPTION_DRY_RUN) != options.cend(); const std::vector remove_plan = Dependencies::create_remove_plan(specs, status_db); Checks::check_exit(VCPKG_LINE_INFO, !remove_plan.empty(), "Remove plan cannot be empty"); @@ -226,7 +226,7 @@ namespace vcpkg::Commands::Remove System::println(System::Color::warning, "Additional packages (*) need to be removed to complete this operation."); - if (!isRecursive) + if (!is_recursive) { System::println(System::Color::warning, "If you are sure you want to remove them, run the command with the --recurse option"); @@ -234,7 +234,7 @@ namespace vcpkg::Commands::Remove } } - if (dryRun) + if (dry_run) { Checks::exit_success(VCPKG_LINE_INFO); } -- cgit v1.2.3 From 2d1bee6bb5f776e6f7281d0245ef7f0030cb7412 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 13 Sep 2017 21:48:38 -0700 Subject: [vcpkg.cpp] Naming scheme --- toolsrc/src/vcpkg.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg.cpp b/toolsrc/src/vcpkg.cpp index 781f03585..75b61f952 100644 --- a/toolsrc/src/vcpkg.cpp +++ b/toolsrc/src/vcpkg.cpp @@ -104,7 +104,7 @@ static void inner(const VcpkgCmdArguments& args) return invalid_command(args.command); } -static void loadConfig() +static void load_config() { fs::path localappdata; { @@ -207,7 +207,7 @@ int wmain(const int argc, const wchar_t* const* const argv) locked_metrics->track_property("version", Commands::Version::version()); locked_metrics->track_property("cmdline", trimmed_command_line); } - loadConfig(); + load_config(); Metrics::g_metrics.lock()->track_property("sqmuser", Metrics::get_SQM_user()); const VcpkgCmdArguments args = VcpkgCmdArguments::create_from_command_line(argc, argv); -- cgit v1.2.3 From c6af9797fd5a4df5f3b709784c95e9590beb2d32 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 13 Sep 2017 23:08:01 -0700 Subject: [metrics.cpp] Naming scheme and missing const --- toolsrc/src/metrics.cpp | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/metrics.cpp b/toolsrc/src/metrics.cpp index 8a7d02a30..3c352f1a6 100644 --- a/toolsrc/src/metrics.cpp +++ b/toolsrc/src/metrics.cpp @@ -20,9 +20,9 @@ namespace vcpkg::Metrics _ftime_s(&timebuffer); time_t now = timebuffer.time; - int milli = timebuffer.millitm; + const int milli = timebuffer.millitm; - errno_t err = gmtime_s(&newtime, &now); + const errno_t err = gmtime_s(&newtime, &now); if (err) { return Strings::EMPTY; @@ -34,7 +34,7 @@ namespace vcpkg::Metrics static std::string generate_random_UUID() { - int partSizes[] = {8, 4, 4, 4, 12}; + int part_sizes[] = {8, 4, 4, 4, 12}; char uuid[37]; memset(uuid, 0, sizeof(uuid)); int num; @@ -50,7 +50,7 @@ namespace vcpkg::Metrics // Generating UUID format version 4 // http://en.wikipedia.org/wiki/Universally_unique_identifier - for (int i = 0; i < partSizes[part]; i++, index++) + for (int i = 0; i < part_sizes[part]; i++, index++) { if (part == 2 && i == 0) { @@ -81,8 +81,8 @@ namespace vcpkg::Metrics static const std::string& get_session_id() { - static const std::string id = generate_random_UUID(); - return id; + static const std::string ID = generate_random_UUID(); + return ID; } static std::string to_json_string(const std::string& str) @@ -101,11 +101,11 @@ namespace vcpkg::Metrics else if (ch < 0x20 || ch >= 0x80) { // Note: this treats incoming Strings as Latin-1 - static constexpr const char hex[16] = { + static constexpr const char HEX[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; encoded.append("\\u00"); - encoded.push_back(hex[ch / 16]); - encoded.push_back(hex[ch % 16]); + encoded.push_back(HEX[ch / 16]); + encoded.push_back(HEX[ch % 16]); } else { @@ -120,7 +120,7 @@ namespace vcpkg::Metrics { std::wstring path; path.resize(MAX_PATH); - auto n = GetSystemDirectoryW(&path[0], static_cast(path.size())); + const auto n = GetSystemDirectoryW(&path[0], static_cast(path.size())); path.resize(n); path += L"\\kernel32.dll"; @@ -282,10 +282,11 @@ namespace vcpkg::Metrics { if (MAXDWORD <= payload.size()) abort(); std::wstring hdrs = L"Content-Type: application/json\r\n"; + std::string& p = const_cast(payload); bResults = WinHttpSendRequest(hRequest, hdrs.c_str(), static_cast(hdrs.size()), - (void*)&payload[0], + static_cast(&p[0]), static_cast(payload.size()), static_cast(payload.size()), 0); @@ -308,24 +309,24 @@ namespace vcpkg::Metrics WINHTTP_NO_HEADER_INDEX); } - std::vector responseBuffer; + std::vector response_buffer; if (bResults) { - DWORD availableData = 0, readData = 0, totalData = 0; - while ((bResults = WinHttpQueryDataAvailable(hRequest, &availableData)) == TRUE && availableData > 0) + DWORD available_data = 0, read_data = 0, total_data = 0; + while ((bResults = WinHttpQueryDataAvailable(hRequest, &available_data)) == TRUE && available_data > 0) { - responseBuffer.resize(responseBuffer.size() + availableData); + response_buffer.resize(response_buffer.size() + available_data); - bResults = WinHttpReadData(hRequest, &responseBuffer.data()[totalData], availableData, &readData); + bResults = WinHttpReadData(hRequest, &response_buffer.data()[total_data], available_data, &read_data); if (!bResults) { break; } - totalData += readData; + total_data += read_data; - responseBuffer.resize(totalData); + response_buffer.resize(total_data); } } @@ -388,8 +389,8 @@ namespace vcpkg::Metrics const fs::path vcpkg_metrics_txt_path = temp_folder_path / ("vcpkg" + generate_random_UUID() + ".txt"); fs.write_contents(vcpkg_metrics_txt_path, payload); - const std::wstring cmdLine = + const std::wstring cmd_line = Strings::wformat(L"start %s %s", temp_folder_path_exe.native(), vcpkg_metrics_txt_path.native()); - System::cmd_execute_clean(cmdLine); + System::cmd_execute_clean(cmd_line); } } -- cgit v1.2.3 From 263466642face5485d50bccb60b45e774fe31fd9 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 13 Sep 2017 23:10:53 -0700 Subject: [metrics.cpp] More naming scheme and const fixes --- toolsrc/src/metrics.cpp | 95 ++++++++++++++++++++++++------------------------- 1 file changed, 47 insertions(+), 48 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/metrics.cpp b/toolsrc/src/metrics.cpp index 3c352f1a6..8a0050bfc 100644 --- a/toolsrc/src/metrics.cpp +++ b/toolsrc/src/metrics.cpp @@ -124,7 +124,7 @@ namespace vcpkg::Metrics path.resize(n); path += L"\\kernel32.dll"; - auto versz = GetFileVersionInfoSizeW(path.c_str(), nullptr); + const auto versz = GetFileVersionInfoSizeW(path.c_str(), nullptr); if (versz == 0) return Strings::EMPTY; std::vector verbuf; @@ -152,7 +152,7 @@ namespace vcpkg::Metrics std::string properties; std::string measurements; - void TrackProperty(const std::string& name, const std::string& value) + void track_property(const std::string& name, const std::string& value) { if (properties.size() != 0) properties.push_back(','); properties.append(to_json_string(name)); @@ -160,7 +160,7 @@ namespace vcpkg::Metrics properties.append(to_json_string(value)); } - void TrackMetric(const std::string& name, double value) + void track_metric(const std::string& name, double value) { if (measurements.size() != 0) measurements.push_back(','); measurements.append(to_json_string(name)); @@ -241,7 +241,7 @@ namespace vcpkg::Metrics void Metrics::set_print_metrics(bool should_print_metrics) { g_should_print_metrics = should_print_metrics; } - void Metrics::track_metric(const std::string& name, double value) { g_metricmessage.TrackMetric(name, value); } + void Metrics::track_metric(const std::string& name, double value) { g_metricmessage.track_metric(name, value); } void Metrics::track_property(const std::string& name, const std::wstring& value) { @@ -251,75 +251,74 @@ namespace vcpkg::Metrics std::transform( value.begin(), value.end(), converted_value.begin(), [](wchar_t ch) { return static_cast(ch); }); - g_metricmessage.TrackProperty(name, converted_value); + g_metricmessage.track_property(name, converted_value); } void Metrics::track_property(const std::string& name, const std::string& value) { - g_metricmessage.TrackProperty(name, value); + g_metricmessage.track_property(name, value); } void Metrics::upload(const std::string& payload) { - HINTERNET hSession = nullptr, hConnect = nullptr, hRequest = nullptr; - BOOL bResults = FALSE; + HINTERNET connect = nullptr, request = nullptr; + BOOL results = FALSE; - hSession = WinHttpOpen( + const HINTERNET session = WinHttpOpen( L"vcpkg/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); - if (hSession) - hConnect = WinHttpConnect(hSession, L"dc.services.visualstudio.com", INTERNET_DEFAULT_HTTPS_PORT, 0); - - if (hConnect) - hRequest = WinHttpOpenRequest(hConnect, - L"POST", - L"/v2/track", - nullptr, - WINHTTP_NO_REFERER, - WINHTTP_DEFAULT_ACCEPT_TYPES, - WINHTTP_FLAG_SECURE); - - if (hRequest) + if (session) connect = WinHttpConnect(session, L"dc.services.visualstudio.com", INTERNET_DEFAULT_HTTPS_PORT, 0); + + if (connect) + request = WinHttpOpenRequest(connect, + L"POST", + L"/v2/track", + nullptr, + WINHTTP_NO_REFERER, + WINHTTP_DEFAULT_ACCEPT_TYPES, + WINHTTP_FLAG_SECURE); + + if (request) { if (MAXDWORD <= payload.size()) abort(); std::wstring hdrs = L"Content-Type: application/json\r\n"; std::string& p = const_cast(payload); - bResults = WinHttpSendRequest(hRequest, - hdrs.c_str(), - static_cast(hdrs.size()), - static_cast(&p[0]), - static_cast(payload.size()), - static_cast(payload.size()), - 0); + results = WinHttpSendRequest(request, + hdrs.c_str(), + static_cast(hdrs.size()), + static_cast(&p[0]), + static_cast(payload.size()), + static_cast(payload.size()), + 0); } - if (bResults) + if (results) { - bResults = WinHttpReceiveResponse(hRequest, nullptr); + results = WinHttpReceiveResponse(request, nullptr); } DWORD http_code = 0, junk = sizeof(DWORD); - if (bResults) + if (results) { - bResults = WinHttpQueryHeaders(hRequest, - WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, - nullptr, - &http_code, - &junk, - WINHTTP_NO_HEADER_INDEX); + results = WinHttpQueryHeaders(request, + WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, + nullptr, + &http_code, + &junk, + WINHTTP_NO_HEADER_INDEX); } std::vector response_buffer; - if (bResults) + if (results) { DWORD available_data = 0, read_data = 0, total_data = 0; - while ((bResults = WinHttpQueryDataAvailable(hRequest, &available_data)) == TRUE && available_data > 0) + while ((results = WinHttpQueryDataAvailable(request, &available_data)) == TRUE && available_data > 0) { response_buffer.resize(response_buffer.size() + available_data); - bResults = WinHttpReadData(hRequest, &response_buffer.data()[total_data], available_data, &read_data); + results = WinHttpReadData(request, &response_buffer.data()[total_data], available_data, &read_data); - if (!bResults) + if (!results) { break; } @@ -330,7 +329,7 @@ namespace vcpkg::Metrics } } - if (!bResults) + if (!results) { #ifndef NDEBUG __debugbreak(); @@ -339,22 +338,22 @@ namespace vcpkg::Metrics #endif } - if (hRequest) WinHttpCloseHandle(hRequest); - if (hConnect) WinHttpCloseHandle(hConnect); - if (hSession) WinHttpCloseHandle(hSession); + if (request) WinHttpCloseHandle(request); + if (connect) WinHttpCloseHandle(connect); + if (session) WinHttpCloseHandle(session); } static fs::path get_bindir() { wchar_t buf[_MAX_PATH]; - int bytes = GetModuleFileNameW(nullptr, buf, _MAX_PATH); + const int bytes = GetModuleFileNameW(nullptr, buf, _MAX_PATH); if (bytes == 0) std::abort(); return fs::path(buf, buf + bytes); } void Metrics::flush() { - std::string payload = g_metricmessage.format_event_data_template(); + const std::string payload = g_metricmessage.format_event_data_template(); if (g_should_print_metrics) std::cerr << payload << "\n"; if (!g_should_send_metrics) return; -- cgit v1.2.3 From 2d6029e41c68fd44b22f8cef1b13fbaa44c8fad9 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 14 Sep 2017 04:04:15 -0700 Subject: Introduce Version::warn_if_vcpkg_version_mismatch() --- toolsrc/include/vcpkg_Commands.h | 1 + toolsrc/src/commands_update.cpp | 28 ++-------------------------- toolsrc/src/commands_version.cpp | 32 ++++++++++++++++++++++++++++++-- 3 files changed, 33 insertions(+), 28 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg_Commands.h b/toolsrc/include/vcpkg_Commands.h index 070a8ec49..590f0208c 100644 --- a/toolsrc/include/vcpkg_Commands.h +++ b/toolsrc/include/vcpkg_Commands.h @@ -210,6 +210,7 @@ namespace vcpkg::Commands namespace Version { const std::string& version(); + void warn_if_vcpkg_version_mismatch(const VcpkgPaths& paths); void perform_and_exit(const VcpkgCmdArguments& args); } diff --git a/toolsrc/src/commands_update.cpp b/toolsrc/src/commands_update.cpp index 35f24af12..42a8333bd 100644 --- a/toolsrc/src/commands_update.cpp +++ b/toolsrc/src/commands_update.cpp @@ -2,7 +2,6 @@ #include "Paragraphs.h" #include "vcpkg_Commands.h" -#include "vcpkg_Files.h" #include "vcpkg_System.h" #include "vcpkglib.h" @@ -22,7 +21,7 @@ namespace vcpkg::Commands::Update std::vector output; for (const StatusParagraph* pgh : installed_packages) { - auto it = src_names_to_versions.find(pgh->package.spec.name()); + const auto it = src_names_to_versions.find(pgh->package.spec.name()); if (it == src_names_to_versions.end()) { // Package was not installed from portfile @@ -69,30 +68,7 @@ namespace vcpkg::Commands::Update install_line); } - auto version_file = paths.get_filesystem().read_contents(paths.root / "toolsrc" / "VERSION.txt"); - if (auto version_contents = version_file.get()) - { - int maj1, min1, rev1; - auto num1 = sscanf_s(version_contents->c_str(), "\"%d.%d.%d\"", &maj1, &min1, &rev1); - - int maj2, min2, rev2; - auto num2 = sscanf_s(Version::version().c_str(), "%d.%d.%d-", &maj2, &min2, &rev2); - - if (num1 == 3 && num2 == 3) - { - if (maj1 != maj2 || min1 != min2 || rev1 != rev2) - { - System::println("Different source is available for vcpkg (%d.%d.%d -> %d.%d.%d). Use " - ".\\bootstrap-vcpkg.bat to update.", - maj2, - min2, - rev2, - maj1, - min1, - rev1); - } - } - } + Version::warn_if_vcpkg_version_mismatch(paths); Checks::exit_success(VCPKG_LINE_INFO); } diff --git a/toolsrc/src/commands_version.cpp b/toolsrc/src/commands_version.cpp index af81cd26e..fdbe7b66c 100644 --- a/toolsrc/src/commands_version.cpp +++ b/toolsrc/src/commands_version.cpp @@ -13,7 +13,7 @@ namespace vcpkg::Commands::Version { const std::string& version() { - static const std::string s_version = + static const std::string S_VERSION = #include "../VERSION.txt" +std::string(VCPKG_VERSION_AS_STRING) @@ -21,7 +21,35 @@ namespace vcpkg::Commands::Version + std::string("-debug") #endif + std::string(Metrics::get_compiled_metrics_enabled() ? Strings::EMPTY : "-external"); - return s_version; + return S_VERSION; + } + + void warn_if_vcpkg_version_mismatch(const VcpkgPaths& paths) + { + auto version_file = paths.get_filesystem().read_contents(paths.root / "toolsrc" / "VERSION.txt"); + if (const auto version_contents = version_file.get()) + { + int maj1, min1, rev1; + const auto num1 = sscanf_s(version_contents->c_str(), "\"%d.%d.%d\"", &maj1, &min1, &rev1); + + int maj2, min2, rev2; + const auto num2 = sscanf_s(Version::version().c_str(), "%d.%d.%d-", &maj2, &min2, &rev2); + + if (num1 == 3 && num2 == 3) + { + if (maj1 != maj2 || min1 != min2 || rev1 != rev2) + { + System::println("Different source is available for vcpkg (%d.%d.%d -> %d.%d.%d). Use " + ".\\bootstrap-vcpkg.bat to update.", + maj2, + min2, + rev2, + maj1, + min1, + rev1); + } + } + } } void perform_and_exit(const VcpkgCmdArguments& args) -- cgit v1.2.3 From d55036a7978d122292f3e33c84ae49269ba5498b Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 14 Sep 2017 04:12:13 -0700 Subject: Change message of version mismach to a warning --- toolsrc/src/commands_version.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/commands_version.cpp b/toolsrc/src/commands_version.cpp index fdbe7b66c..5744ea9ef 100644 --- a/toolsrc/src/commands_version.cpp +++ b/toolsrc/src/commands_version.cpp @@ -39,7 +39,8 @@ namespace vcpkg::Commands::Version { if (maj1 != maj2 || min1 != min2 || rev1 != rev2) { - System::println("Different source is available for vcpkg (%d.%d.%d -> %d.%d.%d). Use " + System::println(System::Color::warning, + "Warning: Different source is available for vcpkg (%d.%d.%d -> %d.%d.%d). Use " ".\\bootstrap-vcpkg.bat to update.", maj2, min2, -- cgit v1.2.3 From be27ae05f081997556b3273ba23c6e574d469854 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 14 Sep 2017 04:13:03 -0700 Subject: Version check is now performed before running any command (except vcpkg version/hash/contact) --- toolsrc/src/commands_update.cpp | 2 -- toolsrc/src/vcpkg.cpp | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/commands_update.cpp b/toolsrc/src/commands_update.cpp index 42a8333bd..71ea4b063 100644 --- a/toolsrc/src/commands_update.cpp +++ b/toolsrc/src/commands_update.cpp @@ -68,8 +68,6 @@ namespace vcpkg::Commands::Update install_line); } - Version::warn_if_vcpkg_version_mismatch(paths); - Checks::exit_success(VCPKG_LINE_INFO); } } diff --git a/toolsrc/src/vcpkg.cpp b/toolsrc/src/vcpkg.cpp index 75b61f952..f4300a73c 100644 --- a/toolsrc/src/vcpkg.cpp +++ b/toolsrc/src/vcpkg.cpp @@ -69,6 +69,7 @@ static void inner(const VcpkgCmdArguments& args) const VcpkgPaths paths = expected_paths.value_or_exit(VCPKG_LINE_INFO); const int exit_code = _wchdir(paths.root.c_str()); Checks::check_exit(VCPKG_LINE_INFO, exit_code == 0, "Changing the working dir failed"); + Commands::Version::warn_if_vcpkg_version_mismatch(paths); if (const auto command_function = Commands::find(args.command, Commands::get_available_commands_type_b())) { -- cgit v1.2.3 From aa72ecc6a4ef205526c5e435a54e18ec042fe260 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Thu, 14 Sep 2017 08:14:41 -0700 Subject: [vcpkg] hotfix for ci/install merge Disables accidental testing statement that was left in during the commit. --- toolsrc/src/commands_install.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/commands_install.cpp b/toolsrc/src/commands_install.cpp index d4cb94775..b530a394c 100644 --- a/toolsrc/src/commands_install.cpp +++ b/toolsrc/src/commands_install.cpp @@ -462,7 +462,7 @@ namespace vcpkg::Commands::Install if (counter > 2) { - break; + // break; } const std::string display_name = action.spec().to_string(); -- cgit v1.2.3 From 8339f29df5fb5657cdeeb2b8eaa4f48d7d08a0c2 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 14 Sep 2017 13:41:07 -0700 Subject: Remove stray debugging code --- toolsrc/src/commands_install.cpp | 5 ----- 1 file changed, 5 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/commands_install.cpp b/toolsrc/src/commands_install.cpp index b530a394c..aca25996e 100644 --- a/toolsrc/src/commands_install.cpp +++ b/toolsrc/src/commands_install.cpp @@ -460,11 +460,6 @@ namespace vcpkg::Commands::Install const ElapsedTime build_timer = ElapsedTime::create_started(); counter++; - if (counter > 2) - { - // break; - } - const std::string display_name = action.spec().to_string(); System::println("Starting package %d/%d: %s", counter, package_count, display_name); -- cgit v1.2.3 From 6363910319a082512179269fb6329ecbc367b3bc Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 14 Sep 2017 15:45:32 -0700 Subject: `vcpkg edit`: Improve detection for VSCode - Insiders. Prefer it if available --- toolsrc/src/commands_edit.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/commands_edit.cpp b/toolsrc/src/commands_edit.cpp index dc28de737..7f400f48b 100644 --- a/toolsrc/src/commands_edit.cpp +++ b/toolsrc/src/commands_edit.cpp @@ -8,11 +8,10 @@ namespace vcpkg::Commands::Edit { static std::vector find_from_registry() { - static const std::array REGKEYS = { + static const std::array REGKEYS = { LR"(SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{C26E74D1-022E-4238-8B9D-1E7564A36CC9}_is1)", - LR"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{C26E74D1-022E-4238-8B9D-1E7564A36CC9}_is1)", + LR"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{1287CAD5-7C8D-410D-88B9-0D1EE4A83FF2}_is1)", LR"(SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{F8A2A208-72B3-4D61-95FC-8A65D340689B}_is1)", - LR"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{F8A2A208-72B3-4D61-95FC-8A65D340689B}_is1)", }; std::vector output; @@ -23,8 +22,8 @@ namespace vcpkg::Commands::Edit if (const auto c = code_installpath.get()) { const fs::path install_path = fs::path(*c); - output.push_back(install_path / "Code.exe"); output.push_back(install_path / "Code - Insiders.exe"); + output.push_back(install_path / "Code.exe"); } } return output; @@ -34,6 +33,9 @@ namespace vcpkg::Commands::Edit { static const std::string OPTION_BUILDTREES = "--buildtrees"; + static const fs::path VS_CODE_INSIDERS = fs::path{"Microsoft VS Code Insiders"} / "Code - Insiders.exe"; + static const fs::path VS_CODE = fs::path{"Microsoft VS Code Insiders"} / "Code - Insiders.exe"; + auto& fs = paths.get_filesystem(); static const std::string EXAMPLE = Commands::Help::create_example_string("edit zlib"); @@ -48,8 +50,10 @@ namespace vcpkg::Commands::Edit std::vector candidate_paths; const std::vector from_path = Files::find_from_PATH(L"EDITOR"); candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); - candidate_paths.push_back(System::get_program_files_platform_bitness() / "Microsoft VS Code" / "Code.exe"); - candidate_paths.push_back(System::get_program_files_32_bit() / "Microsoft VS Code" / "Code.exe"); + candidate_paths.push_back(System::get_program_files_platform_bitness() / VS_CODE_INSIDERS); + candidate_paths.push_back(System::get_program_files_32_bit() / VS_CODE_INSIDERS); + candidate_paths.push_back(System::get_program_files_platform_bitness() / VS_CODE); + candidate_paths.push_back(System::get_program_files_32_bit() / VS_CODE); const std::vector from_registry = find_from_registry(); candidate_paths.insert(candidate_paths.end(), from_registry.cbegin(), from_registry.cend()); -- cgit v1.2.3 From bff6bdb53f74f742ebb6e245732145da3a088d23 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 14 Sep 2017 15:57:00 -0700 Subject: Update CHANGELOG and bump version to v0.0.89 --- toolsrc/VERSION.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/VERSION.txt b/toolsrc/VERSION.txt index feb2033f0..7e1c0e952 100644 --- a/toolsrc/VERSION.txt +++ b/toolsrc/VERSION.txt @@ -1 +1 @@ -"0.0.88" \ No newline at end of file +"0.0.89" \ No newline at end of file -- cgit v1.2.3 From b08f2a02e73721cc63acecccc2c25f2c0f488d45 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 19 Sep 2017 12:45:37 -0700 Subject: [vcpkg edit] Fix VSCode path --- toolsrc/src/commands_edit.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/commands_edit.cpp b/toolsrc/src/commands_edit.cpp index 7f400f48b..823c87534 100644 --- a/toolsrc/src/commands_edit.cpp +++ b/toolsrc/src/commands_edit.cpp @@ -34,7 +34,7 @@ namespace vcpkg::Commands::Edit static const std::string OPTION_BUILDTREES = "--buildtrees"; static const fs::path VS_CODE_INSIDERS = fs::path{"Microsoft VS Code Insiders"} / "Code - Insiders.exe"; - static const fs::path VS_CODE = fs::path{"Microsoft VS Code Insiders"} / "Code - Insiders.exe"; + static const fs::path VS_CODE = fs::path{"Microsoft VS Code"} / "Code.exe"; auto& fs = paths.get_filesystem(); -- cgit v1.2.3 From 39a96fc2f4a7d471ab3fa16c480fc0d9965605b1 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 15 Sep 2017 16:47:07 -0700 Subject: Bump required version of CMake to 3.9.2 --- toolsrc/src/VcpkgPaths.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp index 906a5e67f..29edbb260 100644 --- a/toolsrc/src/VcpkgPaths.cpp +++ b/toolsrc/src/VcpkgPaths.cpp @@ -97,10 +97,10 @@ namespace vcpkg static fs::path get_cmake_path(const fs::path& downloads_folder, const fs::path& scripts_folder) { - static constexpr std::array EXPECTED_VERSION = {3, 9, 1}; + static constexpr std::array EXPECTED_VERSION = {3, 9, 2}; static const std::wstring VERSION_CHECK_ARGUMENTS = L"--version"; - const fs::path downloaded_copy = downloads_folder / "cmake-3.9.1-win32-x86" / "bin" / "cmake.exe"; + const fs::path downloaded_copy = downloads_folder / "cmake-3.9.2-win32-x86" / "bin" / "cmake.exe"; const std::vector from_path = Files::find_from_PATH(L"cmake"); std::vector candidate_paths; -- cgit v1.2.3 From 548b7f69197fad294f44b6e3ae5f587116220fae Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 22 Sep 2017 14:20:27 -0700 Subject: Bump required version of CMake to 3.9.3 3.9.3 contains this interesting change: FindBoost: Add support for Boost 1.65.0 and 1.65.1 to CMake 3.9 --- toolsrc/src/VcpkgPaths.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp index 29edbb260..02e238b3f 100644 --- a/toolsrc/src/VcpkgPaths.cpp +++ b/toolsrc/src/VcpkgPaths.cpp @@ -97,10 +97,10 @@ namespace vcpkg static fs::path get_cmake_path(const fs::path& downloads_folder, const fs::path& scripts_folder) { - static constexpr std::array EXPECTED_VERSION = {3, 9, 2}; + static constexpr std::array EXPECTED_VERSION = {3, 9, 3}; static const std::wstring VERSION_CHECK_ARGUMENTS = L"--version"; - const fs::path downloaded_copy = downloads_folder / "cmake-3.9.2-win32-x86" / "bin" / "cmake.exe"; + const fs::path downloaded_copy = downloads_folder / "cmake-3.9.3-win32-x86" / "bin" / "cmake.exe"; const std::vector from_path = Files::find_from_PATH(L"cmake"); std::vector candidate_paths; -- cgit v1.2.3 From 2c3def2f865188fd088f5f10ccffeb9e5464f815 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Sun, 24 Sep 2017 03:07:25 -0700 Subject: `vcpkg portsdiff` Make output format closer to the CHANGELOG formatting --- toolsrc/src/commands_portsdiff.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/commands_portsdiff.cpp b/toolsrc/src/commands_portsdiff.cpp index 32bc3de3c..2334b2270 100644 --- a/toolsrc/src/commands_portsdiff.cpp +++ b/toolsrc/src/commands_portsdiff.cpp @@ -68,7 +68,7 @@ namespace vcpkg::Commands::PortsDiff for (const std::string& name : ports_to_print) { const VersionT& version = names_and_versions.at(name); - System::println("%-20s %-16s", name, version); + System::println(" - %-14s %-16s", name, version); } } @@ -147,14 +147,14 @@ namespace vcpkg::Commands::PortsDiff const std::vector& added_ports = setp.only_left; if (!added_ports.empty()) { - System::println("\nThe following %d ports were added:\n", added_ports.size()); + System::println("\nThe following %d ports were added:", added_ports.size()); do_print_name_and_version(added_ports, current_names_and_versions); } const std::vector& removed_ports = setp.only_right; if (!removed_ports.empty()) { - System::println("\nThe following %d ports were removed:\n", removed_ports.size()); + System::println("\nThe following %d ports were removed:", removed_ports.size()); do_print_name_and_version(removed_ports, previous_names_and_versions); } @@ -164,10 +164,10 @@ namespace vcpkg::Commands::PortsDiff if (!updated_ports.empty()) { - System::println("\nThe following %d ports were updated:\n", updated_ports.size()); + System::println("\nThe following %d ports were updated:", updated_ports.size()); for (const UpdatedPort& p : updated_ports) { - System::println("%-20s %-16s", p.port, p.version_diff.to_string()); + System::println(" - %-14s %-16s", p.port, p.version_diff.to_string()); } } -- cgit v1.2.3 From 392a9adfca20a55a0952aa9a7720a70edc738e80 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Sun, 24 Sep 2017 03:30:31 -0700 Subject: Update CHANGELOG and bump version to v0.0.90 --- toolsrc/VERSION.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/VERSION.txt b/toolsrc/VERSION.txt index 7e1c0e952..c47961221 100644 --- a/toolsrc/VERSION.txt +++ b/toolsrc/VERSION.txt @@ -1 +1 @@ -"0.0.89" \ No newline at end of file +"0.0.90" \ No newline at end of file -- cgit v1.2.3 From ba0cc3f1d7edb7e2fee271761b2f37d0c740604f Mon Sep 17 00:00:00 2001 From: Konstantin Podsvirov Date: Mon, 28 Aug 2017 13:54:19 +0300 Subject: WIP: Export IFW Add export to binary crossplatform repository/installer with GUI based on QtIFW: http://doc.qt.io/qtinstallerframework/ifw-overview.html For correct operation of these changes, you must use the corrected QtIFW: https://codereview.qt-project.org/#/c/203958 --- toolsrc/include/vcpkg_Commands_Export_IFW.h | 13 ++ toolsrc/src/commands_export.cpp | 57 ++++- toolsrc/src/commands_export_ifw.cpp | 319 ++++++++++++++++++++++++++++ toolsrc/vcpkglib/vcpkglib.vcxproj | 2 + toolsrc/vcpkglib/vcpkglib.vcxproj.filters | 6 + 5 files changed, 390 insertions(+), 7 deletions(-) create mode 100644 toolsrc/include/vcpkg_Commands_Export_IFW.h create mode 100644 toolsrc/src/commands_export_ifw.cpp (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg_Commands_Export_IFW.h b/toolsrc/include/vcpkg_Commands_Export_IFW.h new file mode 100644 index 000000000..b25e943eb --- /dev/null +++ b/toolsrc/include/vcpkg_Commands_Export_IFW.h @@ -0,0 +1,13 @@ +#pragma once + +#include "vcpkg_Files.h" +#include "vcpkg_Dependencies.h" + +namespace vcpkg::Commands::Export::IFW +{ + fs::path export_real_package(const fs::path &raw_exported_dir_path, const Dependencies::ExportPlanAction& action, Files::Filesystem& fs); + void export_unique_packages(const fs::path &raw_exported_dir_path, std::map unique_packages, Files::Filesystem& fs); + void export_unique_triplets(const fs::path &raw_exported_dir_path, std::set unique_triplets, Files::Filesystem& fs); + void export_integration(const fs::path &raw_exported_dir_path, Files::Filesystem& fs); + void export_config(const fs::path &raw_exported_dir_path, const std::string ifw_repository_url, Files::Filesystem& fs); +} diff --git a/toolsrc/src/commands_export.cpp b/toolsrc/src/commands_export.cpp index b416a6f3c..139f19026 100644 --- a/toolsrc/src/commands_export.cpp +++ b/toolsrc/src/commands_export.cpp @@ -2,6 +2,7 @@ #include "Paragraphs.h" #include "vcpkg_Commands.h" +#include "vcpkg_Commands_Export_IFW.h" #include "vcpkg_Dependencies.h" #include "vcpkg_Input.h" #include "vcpkg_System.h" @@ -215,10 +216,12 @@ namespace vcpkg::Commands::Export static const std::string OPTION_DRY_RUN = "--dry-run"; static const std::string OPTION_RAW = "--raw"; static const std::string OPTION_NUGET = "--nuget"; + static const std::string OPTION_IFW = "--ifw"; static const std::string OPTION_ZIP = "--zip"; static const std::string OPTION_SEVEN_ZIP = "--7zip"; static const std::string OPTION_NUGET_ID = "--nuget-id"; static const std::string OPTION_NUGET_VERSION = "--nuget-version"; + static const std::string OPTION_IFW_REPOSITORY_URL = "--ifw-repository-url"; // input sanitization static const std::string EXAMPLE = @@ -236,22 +239,25 @@ namespace vcpkg::Commands::Export OPTION_DRY_RUN, OPTION_RAW, OPTION_NUGET, + OPTION_IFW, OPTION_ZIP, OPTION_SEVEN_ZIP, }, { OPTION_NUGET_ID, OPTION_NUGET_VERSION, + OPTION_IFW_REPOSITORY_URL, }); const bool dry_run = options.switches.find(OPTION_DRY_RUN) != options.switches.cend(); const bool raw = options.switches.find(OPTION_RAW) != options.switches.cend(); const bool nuget = options.switches.find(OPTION_NUGET) != options.switches.cend(); + const bool ifw = options.switches.find(OPTION_IFW) != options.switches.cend(); const bool zip = options.switches.find(OPTION_ZIP) != options.switches.cend(); const bool seven_zip = options.switches.find(OPTION_SEVEN_ZIP) != options.switches.cend(); - if (!raw && !nuget && !zip && !seven_zip && !dry_run) + if (!raw && !nuget && !ifw && !zip && !seven_zip && !dry_run) { - System::println(System::Color::error, "Must provide at least one export type: --raw --nuget --zip --7zip"); + System::println(System::Color::error, "Must provide at least one export type: --raw --nuget --ifw --zip --7zip"); System::print(EXAMPLE); Checks::exit_fail(VCPKG_LINE_INFO); } @@ -263,6 +269,10 @@ namespace vcpkg::Commands::Export Checks::check_exit( VCPKG_LINE_INFO, !maybe_nuget_version || nuget, "--nuget-version is only valid with --nuget"); + auto maybe_ifw_repository_url = maybe_lookup(options.settings, OPTION_IFW_REPOSITORY_URL); + + Checks::check_exit(VCPKG_LINE_INFO, !maybe_ifw_repository_url || ifw, "--ifw-repository-url is only valid with --ifw"); + // create the plan const StatusParagraphs status_db = database_load_check(paths); std::vector export_plan = Dependencies::create_export_plan(paths, specs, status_db); @@ -305,7 +315,11 @@ namespace vcpkg::Commands::Export Checks::exit_success(VCPKG_LINE_INFO); } - const std::string export_id = create_export_id(); + std::string export_id = create_export_id(); + if (ifw) + { + export_id = "vcpkg-export"; // TODO: Remove after debugging + } Files::Filesystem& fs = paths.get_filesystem(); const fs::path export_to_path = paths.root; @@ -315,6 +329,8 @@ namespace vcpkg::Commands::Export fs.create_directory(raw_exported_dir_path, ec); // execute the plan + std::map unique_packages; + std::set unique_triplets; for (const ExportPlanAction& action : export_plan) { if (action.plan_type != ExportPlanType::ALREADY_BUILT) @@ -327,10 +343,21 @@ namespace vcpkg::Commands::Export const BinaryParagraph& binary_paragraph = action.any_paragraph.binary_control_file.value_or_exit(VCPKG_LINE_INFO).core_paragraph; + + unique_packages[action.spec.name()] = &action; + unique_triplets.insert(action.spec.triplet().canonical_name()); + + fs::path spec_exported_dir_path = raw_exported_dir_path / "installed"; + if (ifw) + { + // Export real package and return data dir for installation + spec_exported_dir_path = IFW::export_real_package(raw_exported_dir_path, action, fs); + } + const InstallDir dirs = InstallDir::from_destination_root( - raw_exported_dir_path / "installed", + spec_exported_dir_path, action.spec.triplet().to_string(), - raw_exported_dir_path / "installed" / "vcpkg" / "info" / (binary_paragraph.fullstem() + ".list")); + spec_exported_dir_path / "vcpkg" / "info" / (binary_paragraph.fullstem() + ".list")); Install::install_files_and_write_listfile(paths.get_filesystem(), paths.package_dir(action.spec), dirs); System::println(System::Color::success, "Exporting package %s... done", display_name); @@ -351,13 +378,29 @@ namespace vcpkg::Commands::Export for (const fs::path& file : integration_files_relative_to_root) { const fs::path source = paths.root / file; - const fs::path destination = raw_exported_dir_path / file; + fs::path destination = raw_exported_dir_path / file; + if (ifw) + { + destination = raw_exported_dir_path / "integration" / "data" / file; + } fs.create_directories(destination.parent_path(), ec); Checks::check_exit(VCPKG_LINE_INFO, !ec); fs.copy_file(source, destination, fs::copy_options::overwrite_existing, ec); Checks::check_exit(VCPKG_LINE_INFO, !ec); } + if (ifw) + { + // Unigue packages + IFW::export_unique_packages(raw_exported_dir_path, unique_packages, fs); + // Unigue triplets + IFW::export_unique_triplets(raw_exported_dir_path, unique_triplets, fs); + // Integration + IFW::export_integration(raw_exported_dir_path, fs); + // Configuration + IFW::export_config(raw_exported_dir_path, maybe_ifw_repository_url.value_or(""), fs); + } + const auto print_next_step_info = [](const fs::path& prefix) { const fs::path cmake_toolchain = prefix / "scripts" / "buildsystems" / "vcpkg.cmake"; const CMakeVariable cmake_variable = @@ -417,7 +460,7 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console print_next_step_info("[...]"); } - if (!raw) + if (!raw && !ifw) { fs.remove_all(raw_exported_dir_path, ec); } diff --git a/toolsrc/src/commands_export_ifw.cpp b/toolsrc/src/commands_export_ifw.cpp new file mode 100644 index 000000000..ceedac9a3 --- /dev/null +++ b/toolsrc/src/commands_export_ifw.cpp @@ -0,0 +1,319 @@ +#include "pch.h" + +#include "vcpkg_Commands_Export_IFW.h" + +namespace vcpkg::Commands::Export::IFW +{ + using Dependencies::ExportPlanAction; + + fs::path export_real_package(const fs::path &raw_exported_dir_path, const ExportPlanAction& action, Files::Filesystem& fs) + { + std::error_code ec; + + const BinaryParagraph& binary_paragraph = + action.any_paragraph.binary_control_file.value_or_exit(VCPKG_LINE_INFO).core_paragraph; + + // Prepare meta dir + const fs::path package_xml_file_path = raw_exported_dir_path / Strings::format("packages.%s.%s", action.spec.name(), action.spec.triplet().canonical_name()) / "meta" / "package.xml"; + const fs::path package_xml_dir_path = package_xml_file_path.parent_path(); + fs.create_directories(package_xml_dir_path, ec); + Checks::check_exit( + VCPKG_LINE_INFO, !ec, "Could not create directory for package file %s", package_xml_file_path.generic_string()); + std::vector lines; + std::string line; std::string skip = " "; + line = ""; + lines.push_back(line); line.clear(); + line += ""; + lines.push_back(line); line = skip; + line += ""; + line += action.spec.to_string(); + line += ""; + lines.push_back(line); line = skip; + line += ""; + line += binary_paragraph.version; // TODO: Check IFW version format + line += ""; + lines.push_back(line); line = skip; + line += ""; + line += "2017-08-31"; // TODO: Get real package release date + line += ""; + //if (!binary_paragraph.depends.empty()) + //{ + // lines.push_back(line); line = skip; + // line += ""; + //// line += Strings::format("triplets.%s:", action.spec.triplet().canonical_name()); + // line += Strings::format("packages.%s.%s:", binary_paragraph.depends[0], action.spec.triplet().canonical_name()); + // for (size_t i = 1; i < binary_paragraph.depends.size(); ++i) + // { + // line += Strings::format(",packages.%s.%s:", binary_paragraph.depends[i], action.spec.triplet().canonical_name()); + // } + // line += ""; + //} + lines.push_back(line); line = skip; + line += ""; + line += Strings::format("packages.%s:,triplets.%s:", action.spec.name(), action.spec.triplet().canonical_name()); + line += ""; + lines.push_back(line); line = skip; + line += ""; + line += "true"; // NOTE: hide real package + line += ""; + lines.push_back(line); line = skip; + line += ""; + line += "true"; + line += ""; + lines.push_back(line); line.clear(); + line = ""; + lines.push_back(line); line.clear(); + fs.write_lines(package_xml_file_path, lines); + + // Return dir path for export package data + return raw_exported_dir_path / Strings::format("packages.%s.%s", action.spec.name(), action.spec.triplet().canonical_name()) / "data" / "installed"; + } + + void export_unique_packages(const fs::path &raw_exported_dir_path, std::map unique_packages, Files::Filesystem& fs) + { + std::error_code ec; + + // packages + + fs::path package_xml_file_path = raw_exported_dir_path / "packages" / "meta" / "package.xml"; + fs::path package_xml_dir_path = package_xml_file_path.parent_path(); + fs.create_directories(package_xml_dir_path, ec); + Checks::check_exit( + VCPKG_LINE_INFO, !ec, "Could not create directory for package file %s", package_xml_file_path.generic_string()); + std::vector lines; + std::string line; std::string skip = " "; + line = ""; + lines.push_back(line); line.clear(); + line += ""; + lines.push_back(line); line = skip; + line += ""; + line += "Packages"; + line += ""; + lines.push_back(line); line = skip; + line = ""; + line += "1.0.0"; // TODO: Get real packages package version + line += ""; + lines.push_back(line); line = skip; + line += ""; + line += "2017-08-31"; // TODO: Get real package release date + line += ""; + lines.push_back(line); line = skip; + line += ""; + line += "true"; + line += ""; + lines.push_back(line); line.clear(); + line = ""; + lines.push_back(line); line.clear(); + fs.write_lines(package_xml_file_path, lines); + + for (auto package = unique_packages.begin(); package != unique_packages.end(); ++package) + { + const ExportPlanAction& action = *(package->second); + const BinaryParagraph& binary_paragraph = + action.any_paragraph.binary_control_file.value_or_exit(VCPKG_LINE_INFO).core_paragraph; + + package_xml_file_path = raw_exported_dir_path / Strings::format("packages.%s", package->first) / "meta" / "package.xml"; + package_xml_dir_path = package_xml_file_path.parent_path(); + fs.create_directories(package_xml_dir_path, ec); + Checks::check_exit( + VCPKG_LINE_INFO, !ec, "Could not create directory for package file %s", package_xml_file_path.generic_string()); + lines.clear(); + line.clear(); + skip = " "; + line = ""; + lines.push_back(line); line.clear(); + line += ""; + lines.push_back(line); line = skip; + line += ""; + line += action.spec.name(); + line += ""; + lines.push_back(line); line = skip; + line += ""; + line += binary_paragraph.description; + line += ""; + lines.push_back(line); line = skip; + line += ""; + line += binary_paragraph.version; // TODO: Check IFW version format + line += ""; + lines.push_back(line); line = skip; + line += ""; + line += "2017-08-31"; // TODO: Get real package release date + line += ""; + if (!binary_paragraph.depends.empty()) + { + lines.push_back(line); line = skip; + line += ""; + line += Strings::format("packages.%s:", binary_paragraph.depends[0]); + for (size_t i = 1; i < binary_paragraph.depends.size(); ++i) + { + line += Strings::format(",packages.%s:", binary_paragraph.depends[i]); + } + line += ""; + } + lines.push_back(line); line = skip; + line += ""; + line += "true"; + line += ""; + lines.push_back(line); line.clear(); + line = ""; + lines.push_back(line); line.clear(); + fs.write_lines(package_xml_file_path, lines); + } + } + + void export_unique_triplets(const fs::path &raw_exported_dir_path, std::set unique_triplets, Files::Filesystem& fs) + { + std::error_code ec; + + // triplets + + fs::path package_xml_file_path = raw_exported_dir_path / "triplets" / "meta" / "package.xml"; + fs::path package_xml_dir_path = package_xml_file_path.parent_path(); + fs.create_directories(package_xml_dir_path, ec); + Checks::check_exit( + VCPKG_LINE_INFO, !ec, "Could not create directory for package file %s", package_xml_file_path.generic_string()); + std::vector lines; + std::string line; std::string skip = " "; + line = ""; + lines.push_back(line); line.clear(); + line += ""; + lines.push_back(line); line = skip; + line += ""; + line += "Triplets"; + line += ""; + lines.push_back(line); line = skip; + line = ""; + line += "1.0.0"; // TODO: Get real triplits package version + line += ""; + lines.push_back(line); line = skip; + line += ""; + line += "2017-08-31"; // TODO: Get real package release date + line += ""; + lines.push_back(line); line = skip; + line += ""; + line += "true"; + line += ""; + lines.push_back(line); line.clear(); + line = ""; + lines.push_back(line); line.clear(); + fs.write_lines(package_xml_file_path, lines); + + for (const std::string &triplet : unique_triplets) + { + package_xml_file_path = raw_exported_dir_path / Strings::format("triplets.%s", triplet) / "meta" / "package.xml"; + package_xml_dir_path = package_xml_file_path.parent_path(); + fs.create_directories(package_xml_dir_path, ec); + Checks::check_exit( + VCPKG_LINE_INFO, !ec, "Could not create directory for package file %s", package_xml_file_path.generic_string()); + lines.clear(); + line.clear(); + skip = " "; + line = ""; + lines.push_back(line); line.clear(); + line += ""; + lines.push_back(line); line = skip; + line += ""; + line += triplet; + line += ""; + lines.push_back(line); line = skip; + line += ""; + line += "1.0.0"; // TODO: Get real package version + line += ""; + lines.push_back(line); line = skip; + line += ""; + line += "2017-08-31"; // TODO: Get real package release date + line += ""; + lines.push_back(line); line = skip; + line += ""; + line += "true"; + line += ""; + lines.push_back(line); line.clear(); + line = ""; + lines.push_back(line); line.clear(); + fs.write_lines(package_xml_file_path, lines); + } + } + + void export_integration(const fs::path &raw_exported_dir_path, Files::Filesystem& fs) + { + std::error_code ec; + + // integration + fs::path package_xml_file_path = raw_exported_dir_path / "integration" / "meta" / "package.xml"; + fs::path package_xml_dir_path = package_xml_file_path.parent_path(); + fs.create_directories(package_xml_dir_path, ec); + Checks::check_exit( + VCPKG_LINE_INFO, !ec, "Could not create directory for package file %s", package_xml_file_path.generic_string()); + std::vector lines; + std::string line; std::string skip = " "; + line = ""; + lines.push_back(line); line.clear(); + line += ""; + lines.push_back(line); line = skip; + line += ""; + line += "Integration"; + line += ""; + lines.push_back(line); line = skip; + line = ""; + line += "1.0.0"; // TODO: Get real integration package version + line += ""; + lines.push_back(line); line = skip; + line += ""; + line += "2017-08-31"; // TODO: Get real package release date + line += ""; + lines.push_back(line); line.clear(); + line = ""; + lines.push_back(line); line.clear(); + fs.write_lines(package_xml_file_path, lines); + } + + void export_config(const fs::path &raw_exported_dir_path, const std::string ifw_repository_url, Files::Filesystem& fs) + { + std::error_code ec; + + // config.xml + fs::path config_xml_file_path = raw_exported_dir_path / "config.xml"; + fs::path config_xml_dir_path = config_xml_file_path.parent_path(); + fs.create_directories(config_xml_dir_path, ec); + Checks::check_exit( + VCPKG_LINE_INFO, !ec, "Could not create directory for configuration file %s", config_xml_file_path.generic_string()); + std::vector lines; + std::string line; std::string skip = " "; + line = ""; + lines.push_back(line); line.clear(); + line += ""; + lines.push_back(line); line = skip; + line += ""; + line += "vcpkg"; + line += ""; + lines.push_back(line); line = skip; + line += ""; + line += "1.0.0"; // TODO: Get real vcpkg installer version + line += ""; + //lines.push_back(line); line = skip; + //line += "true"; + lines.push_back(line); line = skip; + line += ""; + line += "@RootDir@/src/vcpkg"; + line += ""; + if (!ifw_repository_url.empty()) + { + lines.push_back(line); line = skip; + line += ""; + lines.push_back(line); line = skip + skip; + line += ""; + lines.push_back(line); line = skip + skip + skip; + line += ""; + line += ifw_repository_url; + line += ""; + lines.push_back(line); line = skip + skip; + line += ""; + lines.push_back(line); line = skip; + line += ""; + } + lines.push_back(line); line.clear(); + line = ""; + lines.push_back(line); line.clear(); + fs.write_lines(config_xml_file_path, lines); + } +} diff --git a/toolsrc/vcpkglib/vcpkglib.vcxproj b/toolsrc/vcpkglib/vcpkglib.vcxproj index edecd7720..3f17ecb3c 100644 --- a/toolsrc/vcpkglib/vcpkglib.vcxproj +++ b/toolsrc/vcpkglib/vcpkglib.vcxproj @@ -166,6 +166,7 @@ + @@ -185,6 +186,7 @@ + diff --git a/toolsrc/vcpkglib/vcpkglib.vcxproj.filters b/toolsrc/vcpkglib/vcpkglib.vcxproj.filters index 2fbf3d929..7eb077019 100644 --- a/toolsrc/vcpkglib/vcpkglib.vcxproj.filters +++ b/toolsrc/vcpkglib/vcpkglib.vcxproj.filters @@ -165,6 +165,9 @@ Source Files + + Source Files + Source Files @@ -218,6 +221,9 @@ Header Files + + Header Files + Header Files -- cgit v1.2.3 From 5199507a5892ab997b1beee2f1b7d2a6c7e75115 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Thu, 21 Sep 2017 02:27:00 -0700 Subject: [vcpkg-export-ifw] Use template approach for xml instead of line-by-line --- toolsrc/src/commands_export.cpp | 18 +- toolsrc/src/commands_export_ifw.cpp | 397 ++++++++++++++---------------------- 2 files changed, 161 insertions(+), 254 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/commands_export.cpp b/toolsrc/src/commands_export.cpp index 139f19026..c143fb9c7 100644 --- a/toolsrc/src/commands_export.cpp +++ b/toolsrc/src/commands_export.cpp @@ -257,7 +257,8 @@ namespace vcpkg::Commands::Export if (!raw && !nuget && !ifw && !zip && !seven_zip && !dry_run) { - System::println(System::Color::error, "Must provide at least one export type: --raw --nuget --ifw --zip --7zip"); + System::println(System::Color::error, + "Must provide at least one export type: --raw --nuget --ifw --zip --7zip"); System::print(EXAMPLE); Checks::exit_fail(VCPKG_LINE_INFO); } @@ -271,7 +272,8 @@ namespace vcpkg::Commands::Export auto maybe_ifw_repository_url = maybe_lookup(options.settings, OPTION_IFW_REPOSITORY_URL); - Checks::check_exit(VCPKG_LINE_INFO, !maybe_ifw_repository_url || ifw, "--ifw-repository-url is only valid with --ifw"); + Checks::check_exit( + VCPKG_LINE_INFO, !maybe_ifw_repository_url || ifw, "--ifw-repository-url is only valid with --ifw"); // create the plan const StatusParagraphs status_db = database_load_check(paths); @@ -354,10 +356,10 @@ namespace vcpkg::Commands::Export spec_exported_dir_path = IFW::export_real_package(raw_exported_dir_path, action, fs); } - const InstallDir dirs = InstallDir::from_destination_root( - spec_exported_dir_path, - action.spec.triplet().to_string(), - spec_exported_dir_path / "vcpkg" / "info" / (binary_paragraph.fullstem() + ".list")); + const InstallDir dirs = InstallDir::from_destination_root(spec_exported_dir_path, + action.spec.triplet().to_string(), + spec_exported_dir_path / "vcpkg" / "info" / + (binary_paragraph.fullstem() + ".list")); Install::install_files_and_write_listfile(paths.get_filesystem(), paths.package_dir(action.spec), dirs); System::println(System::Color::success, "Exporting package %s... done", display_name); @@ -391,9 +393,9 @@ namespace vcpkg::Commands::Export if (ifw) { - // Unigue packages + // Unique packages IFW::export_unique_packages(raw_exported_dir_path, unique_packages, fs); - // Unigue triplets + // Unique triplets IFW::export_unique_triplets(raw_exported_dir_path, unique_triplets, fs); // Integration IFW::export_integration(raw_exported_dir_path, fs); diff --git a/toolsrc/src/commands_export_ifw.cpp b/toolsrc/src/commands_export_ifw.cpp index ceedac9a3..4b5bdb902 100644 --- a/toolsrc/src/commands_export_ifw.cpp +++ b/toolsrc/src/commands_export_ifw.cpp @@ -6,7 +6,9 @@ namespace vcpkg::Commands::Export::IFW { using Dependencies::ExportPlanAction; - fs::path export_real_package(const fs::path &raw_exported_dir_path, const ExportPlanAction& action, Files::Filesystem& fs) + fs::path export_real_package(const fs::path& raw_exported_dir_path, + const ExportPlanAction& action, + Files::Filesystem& fs) { std::error_code ec; @@ -14,97 +16,64 @@ namespace vcpkg::Commands::Export::IFW action.any_paragraph.binary_control_file.value_or_exit(VCPKG_LINE_INFO).core_paragraph; // Prepare meta dir - const fs::path package_xml_file_path = raw_exported_dir_path / Strings::format("packages.%s.%s", action.spec.name(), action.spec.triplet().canonical_name()) / "meta" / "package.xml"; + const fs::path package_xml_file_path = + raw_exported_dir_path / + Strings::format("packages.%s.%s", action.spec.name(), action.spec.triplet().canonical_name()) / "meta" / + "package.xml"; const fs::path package_xml_dir_path = package_xml_file_path.parent_path(); fs.create_directories(package_xml_dir_path, ec); - Checks::check_exit( - VCPKG_LINE_INFO, !ec, "Could not create directory for package file %s", package_xml_file_path.generic_string()); - std::vector lines; - std::string line; std::string skip = " "; - line = ""; - lines.push_back(line); line.clear(); - line += ""; - lines.push_back(line); line = skip; - line += ""; - line += action.spec.to_string(); - line += ""; - lines.push_back(line); line = skip; - line += ""; - line += binary_paragraph.version; // TODO: Check IFW version format - line += ""; - lines.push_back(line); line = skip; - line += ""; - line += "2017-08-31"; // TODO: Get real package release date - line += ""; - //if (!binary_paragraph.depends.empty()) - //{ - // lines.push_back(line); line = skip; - // line += ""; - //// line += Strings::format("triplets.%s:", action.spec.triplet().canonical_name()); - // line += Strings::format("packages.%s.%s:", binary_paragraph.depends[0], action.spec.triplet().canonical_name()); - // for (size_t i = 1; i < binary_paragraph.depends.size(); ++i) - // { - // line += Strings::format(",packages.%s.%s:", binary_paragraph.depends[i], action.spec.triplet().canonical_name()); - // } - // line += ""; - //} - lines.push_back(line); line = skip; - line += ""; - line += Strings::format("packages.%s:,triplets.%s:", action.spec.name(), action.spec.triplet().canonical_name()); - line += ""; - lines.push_back(line); line = skip; - line += ""; - line += "true"; // NOTE: hide real package - line += ""; - lines.push_back(line); line = skip; - line += ""; - line += "true"; - line += ""; - lines.push_back(line); line.clear(); - line = ""; - lines.push_back(line); line.clear(); - fs.write_lines(package_xml_file_path, lines); + Checks::check_exit(VCPKG_LINE_INFO, + !ec, + "Could not create directory for package file %s", + package_xml_file_path.generic_string()); + + fs.write_contents(package_xml_file_path, + Strings::format(R"###( + + + %s + %s + 2017-08-31 + packages.%s:,triplets.%s: + true + true + +)###", + action.spec.to_string(), + binary_paragraph.version, + action.spec.name(), + action.spec.triplet().canonical_name())); // Return dir path for export package data - return raw_exported_dir_path / Strings::format("packages.%s.%s", action.spec.name(), action.spec.triplet().canonical_name()) / "data" / "installed"; + return raw_exported_dir_path / + Strings::format("packages.%s.%s", action.spec.name(), action.spec.triplet().canonical_name()) / "data" / + "installed"; } - void export_unique_packages(const fs::path &raw_exported_dir_path, std::map unique_packages, Files::Filesystem& fs) - { - std::error_code ec; - + void export_unique_packages(const fs::path& raw_exported_dir_path, + std::map unique_packages, + Files::Filesystem& fs) + { + std::error_code ec; + // packages fs::path package_xml_file_path = raw_exported_dir_path / "packages" / "meta" / "package.xml"; fs::path package_xml_dir_path = package_xml_file_path.parent_path(); fs.create_directories(package_xml_dir_path, ec); - Checks::check_exit( - VCPKG_LINE_INFO, !ec, "Could not create directory for package file %s", package_xml_file_path.generic_string()); - std::vector lines; - std::string line; std::string skip = " "; - line = ""; - lines.push_back(line); line.clear(); - line += ""; - lines.push_back(line); line = skip; - line += ""; - line += "Packages"; - line += ""; - lines.push_back(line); line = skip; - line = ""; - line += "1.0.0"; // TODO: Get real packages package version - line += ""; - lines.push_back(line); line = skip; - line += ""; - line += "2017-08-31"; // TODO: Get real package release date - line += ""; - lines.push_back(line); line = skip; - line += ""; - line += "true"; - line += ""; - lines.push_back(line); line.clear(); - line = ""; - lines.push_back(line); line.clear(); - fs.write_lines(package_xml_file_path, lines); + Checks::check_exit(VCPKG_LINE_INFO, + !ec, + "Could not create directory for package file %s", + package_xml_file_path.generic_string()); + fs.write_contents(package_xml_file_path, R"###( + + + Packages + 1.0.0 + 2017-08-31 + true + +)###"); for (auto package = unique_packages.begin(); package != unique_packages.end(); ++package) { @@ -112,56 +81,41 @@ namespace vcpkg::Commands::Export::IFW const BinaryParagraph& binary_paragraph = action.any_paragraph.binary_control_file.value_or_exit(VCPKG_LINE_INFO).core_paragraph; - package_xml_file_path = raw_exported_dir_path / Strings::format("packages.%s", package->first) / "meta" / "package.xml"; + package_xml_file_path = + raw_exported_dir_path / Strings::format("packages.%s", package->first) / "meta" / "package.xml"; package_xml_dir_path = package_xml_file_path.parent_path(); fs.create_directories(package_xml_dir_path, ec); - Checks::check_exit( - VCPKG_LINE_INFO, !ec, "Could not create directory for package file %s", package_xml_file_path.generic_string()); - lines.clear(); - line.clear(); - skip = " "; - line = ""; - lines.push_back(line); line.clear(); - line += ""; - lines.push_back(line); line = skip; - line += ""; - line += action.spec.name(); - line += ""; - lines.push_back(line); line = skip; - line += ""; - line += binary_paragraph.description; - line += ""; - lines.push_back(line); line = skip; - line += ""; - line += binary_paragraph.version; // TODO: Check IFW version format - line += ""; - lines.push_back(line); line = skip; - line += ""; - line += "2017-08-31"; // TODO: Get real package release date - line += ""; - if (!binary_paragraph.depends.empty()) - { - lines.push_back(line); line = skip; - line += ""; - line += Strings::format("packages.%s:", binary_paragraph.depends[0]); - for (size_t i = 1; i < binary_paragraph.depends.size(); ++i) - { - line += Strings::format(",packages.%s:", binary_paragraph.depends[i]); - } - line += ""; - } - lines.push_back(line); line = skip; - line += ""; - line += "true"; - line += ""; - lines.push_back(line); line.clear(); - line = ""; - lines.push_back(line); line.clear(); - fs.write_lines(package_xml_file_path, lines); + Checks::check_exit(VCPKG_LINE_INFO, + !ec, + "Could not create directory for package file %s", + package_xml_file_path.generic_string()); + + auto deps = Strings::join( + ",", binary_paragraph.depends, [](const std::string& dep) { return "packages." + dep + ":"; }); + + if (!deps.empty()) deps = "\n " + deps; + + fs.write_contents(package_xml_file_path, + Strings::format(R"###( + + + %s + %s + %s + 2017-08-31%s + true + +)###", + action.spec.name(), + binary_paragraph.description, + binary_paragraph.version, + deps)); } } - void export_unique_triplets(const fs::path &raw_exported_dir_path, std::set unique_triplets, Files::Filesystem& fs) + void export_unique_triplets(const fs::path& raw_exported_dir_path, + std::set unique_triplets, + Files::Filesystem& fs) { std::error_code ec; @@ -170,71 +124,43 @@ namespace vcpkg::Commands::Export::IFW fs::path package_xml_file_path = raw_exported_dir_path / "triplets" / "meta" / "package.xml"; fs::path package_xml_dir_path = package_xml_file_path.parent_path(); fs.create_directories(package_xml_dir_path, ec); - Checks::check_exit( - VCPKG_LINE_INFO, !ec, "Could not create directory for package file %s", package_xml_file_path.generic_string()); - std::vector lines; - std::string line; std::string skip = " "; - line = ""; - lines.push_back(line); line.clear(); - line += ""; - lines.push_back(line); line = skip; - line += ""; - line += "Triplets"; - line += ""; - lines.push_back(line); line = skip; - line = ""; - line += "1.0.0"; // TODO: Get real triplits package version - line += ""; - lines.push_back(line); line = skip; - line += ""; - line += "2017-08-31"; // TODO: Get real package release date - line += ""; - lines.push_back(line); line = skip; - line += ""; - line += "true"; - line += ""; - lines.push_back(line); line.clear(); - line = ""; - lines.push_back(line); line.clear(); - fs.write_lines(package_xml_file_path, lines); - - for (const std::string &triplet : unique_triplets) + Checks::check_exit(VCPKG_LINE_INFO, + !ec, + "Could not create directory for package file %s", + package_xml_file_path.generic_string()); + fs.write_contents(package_xml_file_path, R"###( + + + Triplets + 1.0.0 + 2017-08-31 + true + +)###"); + + for (const std::string& triplet : unique_triplets) { - package_xml_file_path = raw_exported_dir_path / Strings::format("triplets.%s", triplet) / "meta" / "package.xml"; + package_xml_file_path = + raw_exported_dir_path / Strings::format("triplets.%s", triplet) / "meta" / "package.xml"; package_xml_dir_path = package_xml_file_path.parent_path(); fs.create_directories(package_xml_dir_path, ec); - Checks::check_exit( - VCPKG_LINE_INFO, !ec, "Could not create directory for package file %s", package_xml_file_path.generic_string()); - lines.clear(); - line.clear(); - skip = " "; - line = ""; - lines.push_back(line); line.clear(); - line += ""; - lines.push_back(line); line = skip; - line += ""; - line += triplet; - line += ""; - lines.push_back(line); line = skip; - line += ""; - line += "1.0.0"; // TODO: Get real package version - line += ""; - lines.push_back(line); line = skip; - line += ""; - line += "2017-08-31"; // TODO: Get real package release date - line += ""; - lines.push_back(line); line = skip; - line += ""; - line += "true"; - line += ""; - lines.push_back(line); line.clear(); - line = ""; - lines.push_back(line); line.clear(); - fs.write_lines(package_xml_file_path, lines); + Checks::check_exit(VCPKG_LINE_INFO, + !ec, + "Could not create directory for package file %s", + package_xml_file_path.generic_string()); + fs.write_contents(package_xml_file_path, Strings::format(R"###( + + + %s + 1.0.0 + 2017-08-31 + true + +)###", triplet)); } } - void export_integration(const fs::path &raw_exported_dir_path, Files::Filesystem& fs) + void export_integration(const fs::path& raw_exported_dir_path, Files::Filesystem& fs) { std::error_code ec; @@ -242,32 +168,25 @@ namespace vcpkg::Commands::Export::IFW fs::path package_xml_file_path = raw_exported_dir_path / "integration" / "meta" / "package.xml"; fs::path package_xml_dir_path = package_xml_file_path.parent_path(); fs.create_directories(package_xml_dir_path, ec); - Checks::check_exit( - VCPKG_LINE_INFO, !ec, "Could not create directory for package file %s", package_xml_file_path.generic_string()); - std::vector lines; - std::string line; std::string skip = " "; - line = ""; - lines.push_back(line); line.clear(); - line += ""; - lines.push_back(line); line = skip; - line += ""; - line += "Integration"; - line += ""; - lines.push_back(line); line = skip; - line = ""; - line += "1.0.0"; // TODO: Get real integration package version - line += ""; - lines.push_back(line); line = skip; - line += ""; - line += "2017-08-31"; // TODO: Get real package release date - line += ""; - lines.push_back(line); line.clear(); - line = ""; - lines.push_back(line); line.clear(); - fs.write_lines(package_xml_file_path, lines); + Checks::check_exit(VCPKG_LINE_INFO, + !ec, + "Could not create directory for package file %s", + package_xml_file_path.generic_string()); + + fs.write_contents(package_xml_file_path, R"###( + + + Integration + 1.0.0 + 2017-08-31 + true + +)###"); } - void export_config(const fs::path &raw_exported_dir_path, const std::string ifw_repository_url, Files::Filesystem& fs) + void export_config(const fs::path& raw_exported_dir_path, + const std::string ifw_repository_url, + Files::Filesystem& fs) { std::error_code ec; @@ -275,45 +194,31 @@ namespace vcpkg::Commands::Export::IFW fs::path config_xml_file_path = raw_exported_dir_path / "config.xml"; fs::path config_xml_dir_path = config_xml_file_path.parent_path(); fs.create_directories(config_xml_dir_path, ec); - Checks::check_exit( - VCPKG_LINE_INFO, !ec, "Could not create directory for configuration file %s", config_xml_file_path.generic_string()); - std::vector lines; - std::string line; std::string skip = " "; - line = ""; - lines.push_back(line); line.clear(); - line += ""; - lines.push_back(line); line = skip; - line += ""; - line += "vcpkg"; - line += ""; - lines.push_back(line); line = skip; - line += ""; - line += "1.0.0"; // TODO: Get real vcpkg installer version - line += ""; - //lines.push_back(line); line = skip; - //line += "true"; - lines.push_back(line); line = skip; - line += ""; - line += "@RootDir@/src/vcpkg"; - line += ""; + Checks::check_exit(VCPKG_LINE_INFO, + !ec, + "Could not create directory for configuration file %s", + config_xml_file_path.generic_string()); + std::string formatted_repo_url; if (!ifw_repository_url.empty()) { - lines.push_back(line); line = skip; - line += ""; - lines.push_back(line); line = skip + skip; - line += ""; - lines.push_back(line); line = skip + skip + skip; - line += ""; - line += ifw_repository_url; - line += ""; - lines.push_back(line); line = skip + skip; - line += ""; - lines.push_back(line); line = skip; - line += ""; + formatted_repo_url = Strings::format(R"###( + + + %s + + +)###", + formatted_repo_url); } - lines.push_back(line); line.clear(); - line = ""; - lines.push_back(line); line.clear(); - fs.write_lines(config_xml_file_path, lines); + + fs.write_contents(config_xml_file_path, Strings::format(R"###( + + + vcpkg + 1.0.0 + 2017-08-31 + @RootDir@/src/vcpkg%s + +)###", formatted_repo_url)); } } -- cgit v1.2.3 From 68b9c2d8b9119acb48643447a7561a5c2b733d25 Mon Sep 17 00:00:00 2001 From: Konstantin Podsvirov Date: Fri, 22 Sep 2017 02:16:14 +0300 Subject: [vcpkg-export-ifw] Separate IFW loop Separate IFW loop compatible with main export loop Fixed mistakes in templates Set current date to ReleaseDate tag --- toolsrc/include/vcpkg_Commands_Export.h | 14 ++ toolsrc/include/vcpkg_Commands_Export_IFW.h | 13 +- toolsrc/src/commands_export.cpp | 253 ++++++++++++++-------------- toolsrc/src/commands_export_ifw.cpp | 183 +++++++++++++++----- toolsrc/vcpkglib/vcpkglib.vcxproj | 1 + toolsrc/vcpkglib/vcpkglib.vcxproj.filters | 3 + 6 files changed, 294 insertions(+), 173 deletions(-) create mode 100644 toolsrc/include/vcpkg_Commands_Export.h (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg_Commands_Export.h b/toolsrc/include/vcpkg_Commands_Export.h new file mode 100644 index 000000000..31003422d --- /dev/null +++ b/toolsrc/include/vcpkg_Commands_Export.h @@ -0,0 +1,14 @@ +#pragma once + +#include "StatusParagraphs.h" +#include "VcpkgCmdArguments.h" +#include "VcpkgPaths.h" +#include "VersionT.h" +#include "vcpkg_Build.h" +#include "vcpkg_Dependencies.h" +#include + +namespace vcpkg::Commands::Export +{ + void export_integration_files(const fs::path &raw_exported_dir_path, const VcpkgPaths& paths); +} diff --git a/toolsrc/include/vcpkg_Commands_Export_IFW.h b/toolsrc/include/vcpkg_Commands_Export_IFW.h index b25e943eb..881bbaf63 100644 --- a/toolsrc/include/vcpkg_Commands_Export_IFW.h +++ b/toolsrc/include/vcpkg_Commands_Export_IFW.h @@ -5,9 +5,12 @@ namespace vcpkg::Commands::Export::IFW { - fs::path export_real_package(const fs::path &raw_exported_dir_path, const Dependencies::ExportPlanAction& action, Files::Filesystem& fs); - void export_unique_packages(const fs::path &raw_exported_dir_path, std::map unique_packages, Files::Filesystem& fs); - void export_unique_triplets(const fs::path &raw_exported_dir_path, std::set unique_triplets, Files::Filesystem& fs); - void export_integration(const fs::path &raw_exported_dir_path, Files::Filesystem& fs); - void export_config(const fs::path &raw_exported_dir_path, const std::string ifw_repository_url, Files::Filesystem& fs); + struct Options + { + Optional maybe_repository_url; + Optional maybe_packages_dir_path; + Optional maybe_config_file_path; + }; + + void do_export(const std::vector &export_plan, const std::string &export_id, const Options &ifw_options, const VcpkgPaths& paths); } diff --git a/toolsrc/src/commands_export.cpp b/toolsrc/src/commands_export.cpp index c143fb9c7..6632dfe67 100644 --- a/toolsrc/src/commands_export.cpp +++ b/toolsrc/src/commands_export.cpp @@ -211,6 +211,32 @@ namespace vcpkg::Commands::Export return nullopt; } + void export_integration_files(const fs::path &raw_exported_dir_path, const VcpkgPaths& paths) + { + const std::vector integration_files_relative_to_root = { + { ".vcpkg-root" }, + { fs::path{ "scripts" } / "buildsystems" / "msbuild" / "applocal.ps1" }, + { fs::path{ "scripts" } / "buildsystems" / "msbuild" / "vcpkg.targets" }, + { fs::path{ "scripts" } / "buildsystems" / "vcpkg.cmake" }, + { fs::path{ "scripts" } / "cmake" / "vcpkg_get_windows_sdk.cmake" }, + { fs::path{ "scripts" } / "getWindowsSDK.ps1" }, + { fs::path{ "scripts" } / "getProgramFilesPlatformBitness.ps1" }, + { fs::path{ "scripts" } / "getProgramFiles32bit.ps1" }, + }; + + for (const fs::path& file : integration_files_relative_to_root) + { + const fs::path source = paths.root / file; + fs::path destination = raw_exported_dir_path / file; + Files::Filesystem& fs = paths.get_filesystem(); + std::error_code ec; + fs.create_directories(destination.parent_path(), ec); + Checks::check_exit(VCPKG_LINE_INFO, !ec); + fs.copy_file(source, destination, fs::copy_options::overwrite_existing, ec); + Checks::check_exit(VCPKG_LINE_INFO, !ec); + } + } + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) { static const std::string OPTION_DRY_RUN = "--dry-run"; @@ -222,6 +248,8 @@ namespace vcpkg::Commands::Export static const std::string OPTION_NUGET_ID = "--nuget-id"; static const std::string OPTION_NUGET_VERSION = "--nuget-version"; static const std::string OPTION_IFW_REPOSITORY_URL = "--ifw-repository-url"; + static const std::string OPTION_IFW_PACKAGES_DIR_PATH = "--ifw-packages-directory-path"; + static const std::string OPTION_IFW_CONFIG_FILE_PATH = "--ifw-configuration-file-path"; // input sanitization static const std::string EXAMPLE = @@ -247,6 +275,8 @@ namespace vcpkg::Commands::Export OPTION_NUGET_ID, OPTION_NUGET_VERSION, OPTION_IFW_REPOSITORY_URL, + OPTION_IFW_PACKAGES_DIR_PATH, + OPTION_IFW_CONFIG_FILE_PATH }); const bool dry_run = options.switches.find(OPTION_DRY_RUN) != options.switches.cend(); const bool raw = options.switches.find(OPTION_RAW) != options.switches.cend(); @@ -270,10 +300,19 @@ namespace vcpkg::Commands::Export Checks::check_exit( VCPKG_LINE_INFO, !maybe_nuget_version || nuget, "--nuget-version is only valid with --nuget"); - auto maybe_ifw_repository_url = maybe_lookup(options.settings, OPTION_IFW_REPOSITORY_URL); + IFW::Options ifw_options; + + ifw_options.maybe_repository_url = maybe_lookup(options.settings, OPTION_IFW_REPOSITORY_URL); + Checks::check_exit( + VCPKG_LINE_INFO, !ifw_options.maybe_repository_url || ifw, "--ifw-repository-url is only valid with --ifw"); + + ifw_options.maybe_packages_dir_path = maybe_lookup(options.settings, OPTION_IFW_PACKAGES_DIR_PATH); + Checks::check_exit( + VCPKG_LINE_INFO, !ifw_options.maybe_packages_dir_path || ifw, "--ifw-packages-directory-path is only valid with --ifw"); + ifw_options.maybe_config_file_path = maybe_lookup(options.settings, OPTION_IFW_CONFIG_FILE_PATH); Checks::check_exit( - VCPKG_LINE_INFO, !maybe_ifw_repository_url || ifw, "--ifw-repository-url is only valid with --ifw"); + VCPKG_LINE_INFO, !ifw_options.maybe_config_file_path || ifw, "--ifw-configuration-file-path is only valid with --ifw"); // create the plan const StatusParagraphs status_db = database_load_check(paths); @@ -318,153 +357,117 @@ namespace vcpkg::Commands::Export } std::string export_id = create_export_id(); - if (ifw) - { - export_id = "vcpkg-export"; // TODO: Remove after debugging - } - Files::Filesystem& fs = paths.get_filesystem(); - const fs::path export_to_path = paths.root; - const fs::path raw_exported_dir_path = export_to_path / export_id; - std::error_code ec; - fs.remove_all(raw_exported_dir_path, ec); - fs.create_directory(raw_exported_dir_path, ec); + const auto print_next_step_info = [](const fs::path& prefix) { + const fs::path cmake_toolchain = prefix / "scripts" / "buildsystems" / "vcpkg.cmake"; + const CMakeVariable cmake_variable = + CMakeVariable(L"CMAKE_TOOLCHAIN_FILE", cmake_toolchain.generic_string()); + System::println("\n" + "To use the exported libraries in CMake projects use:" + "\n" + " %s" + "\n", + Strings::to_utf8(cmake_variable.s)); + }; - // execute the plan - std::map unique_packages; - std::set unique_triplets; - for (const ExportPlanAction& action : export_plan) + // Main loop + if (raw || nuget || zip || seven_zip) { - if (action.plan_type != ExportPlanType::ALREADY_BUILT) + Files::Filesystem& fs = paths.get_filesystem(); + const fs::path export_to_path = paths.root; + const fs::path raw_exported_dir_path = export_to_path / export_id; + std::error_code ec; + fs.remove_all(raw_exported_dir_path, ec); + fs.create_directory(raw_exported_dir_path, ec); + + // execute the plan + for (const ExportPlanAction& action : export_plan) { - Checks::unreachable(VCPKG_LINE_INFO); - } + if (action.plan_type != ExportPlanType::ALREADY_BUILT) + { + Checks::unreachable(VCPKG_LINE_INFO); + } - const std::string display_name = action.spec.to_string(); - System::println("Exporting package %s... ", display_name); + const std::string display_name = action.spec.to_string(); + System::println("Exporting package %s... ", display_name); - const BinaryParagraph& binary_paragraph = - action.any_paragraph.binary_control_file.value_or_exit(VCPKG_LINE_INFO).core_paragraph; + const BinaryParagraph& binary_paragraph = + action.any_paragraph.binary_control_file.value_or_exit(VCPKG_LINE_INFO).core_paragraph; - unique_packages[action.spec.name()] = &action; - unique_triplets.insert(action.spec.triplet().canonical_name()); + const InstallDir dirs = InstallDir::from_destination_root( + raw_exported_dir_path / "installed", + action.spec.triplet().to_string(), + raw_exported_dir_path / "installed" / "vcpkg" / "info" / (binary_paragraph.fullstem() + ".list")); - fs::path spec_exported_dir_path = raw_exported_dir_path / "installed"; - if (ifw) - { - // Export real package and return data dir for installation - spec_exported_dir_path = IFW::export_real_package(raw_exported_dir_path, action, fs); + Install::install_files_and_write_listfile(paths.get_filesystem(), paths.package_dir(action.spec), dirs); + System::println(System::Color::success, "Exporting package %s... done", display_name); } - const InstallDir dirs = InstallDir::from_destination_root(spec_exported_dir_path, - action.spec.triplet().to_string(), - spec_exported_dir_path / "vcpkg" / "info" / - (binary_paragraph.fullstem() + ".list")); - - Install::install_files_and_write_listfile(paths.get_filesystem(), paths.package_dir(action.spec), dirs); - System::println(System::Color::success, "Exporting package %s... done", display_name); - } - - // Copy files needed for integration - const std::vector integration_files_relative_to_root = { - {".vcpkg-root"}, - {fs::path{"scripts"} / "buildsystems" / "msbuild" / "applocal.ps1"}, - {fs::path{"scripts"} / "buildsystems" / "msbuild" / "vcpkg.targets"}, - {fs::path{"scripts"} / "buildsystems" / "vcpkg.cmake"}, - {fs::path{"scripts"} / "cmake" / "vcpkg_get_windows_sdk.cmake"}, - {fs::path{"scripts"} / "getWindowsSDK.ps1"}, - {fs::path{"scripts"} / "getProgramFilesPlatformBitness.ps1"}, - {fs::path{"scripts"} / "getProgramFiles32bit.ps1"}, - }; + // Copy files needed for integration + export_integration_files(raw_exported_dir_path, paths); - for (const fs::path& file : integration_files_relative_to_root) - { - const fs::path source = paths.root / file; - fs::path destination = raw_exported_dir_path / file; - if (ifw) + if (raw) { - destination = raw_exported_dir_path / "integration" / "data" / file; + System::println( + System::Color::success, R"(Files exported at: "%s")", raw_exported_dir_path.generic_string()); + print_next_step_info(export_to_path); } - fs.create_directories(destination.parent_path(), ec); - Checks::check_exit(VCPKG_LINE_INFO, !ec); - fs.copy_file(source, destination, fs::copy_options::overwrite_existing, ec); - Checks::check_exit(VCPKG_LINE_INFO, !ec); - } - if (ifw) - { - // Unique packages - IFW::export_unique_packages(raw_exported_dir_path, unique_packages, fs); - // Unique triplets - IFW::export_unique_triplets(raw_exported_dir_path, unique_triplets, fs); - // Integration - IFW::export_integration(raw_exported_dir_path, fs); - // Configuration - IFW::export_config(raw_exported_dir_path, maybe_ifw_repository_url.value_or(""), fs); - } - - const auto print_next_step_info = [](const fs::path& prefix) { - const fs::path cmake_toolchain = prefix / "scripts" / "buildsystems" / "vcpkg.cmake"; - const CMakeVariable cmake_variable = - CMakeVariable(L"CMAKE_TOOLCHAIN_FILE", cmake_toolchain.generic_string()); - System::println("\n" - "To use the exported libraries in CMake projects use:" - "\n" - " %s" - "\n", - Strings::to_utf8(cmake_variable.s)); - }; - - if (raw) - { - System::println( - System::Color::success, R"(Files exported at: "%s")", raw_exported_dir_path.generic_string()); - print_next_step_info(export_to_path); - } - - if (nuget) - { - System::println("Creating nuget package... "); + if (nuget) + { + System::println("Creating nuget package... "); - const std::string nuget_id = maybe_nuget_id.value_or(raw_exported_dir_path.filename().string()); - const std::string nuget_version = maybe_nuget_version.value_or("1.0.0"); - const fs::path output_path = - do_nuget_export(paths, nuget_id, nuget_version, raw_exported_dir_path, export_to_path); - System::println(System::Color::success, "Creating nuget package... done"); - System::println(System::Color::success, "NuGet package exported at: %s", output_path.generic_string()); + const std::string nuget_id = maybe_nuget_id.value_or(raw_exported_dir_path.filename().string()); + const std::string nuget_version = maybe_nuget_version.value_or("1.0.0"); + const fs::path output_path = + do_nuget_export(paths, nuget_id, nuget_version, raw_exported_dir_path, export_to_path); + System::println(System::Color::success, "Creating nuget package... done"); + System::println(System::Color::success, "NuGet package exported at: %s", output_path.generic_string()); - System::println(R"( + System::println(R"( With a project open, go to Tools->NuGet Package Manager->Package Manager Console and paste: Install-Package %s -Source "%s" )" - "\n", - nuget_id, - output_path.parent_path().u8string()); - } + "\n", + nuget_id, + output_path.parent_path().u8string()); + } - if (zip) - { - System::println("Creating zip archive... "); - const fs::path output_path = - do_archive_export(paths, raw_exported_dir_path, export_to_path, ArchiveFormatC::ZIP); - System::println(System::Color::success, "Creating zip archive... done"); - System::println(System::Color::success, "Zip archive exported at: %s", output_path.generic_string()); - print_next_step_info("[...]"); - } + if (zip) + { + System::println("Creating zip archive... "); + const fs::path output_path = + do_archive_export(paths, raw_exported_dir_path, export_to_path, ArchiveFormatC::ZIP); + System::println(System::Color::success, "Creating zip archive... done"); + System::println(System::Color::success, "Zip archive exported at: %s", output_path.generic_string()); + print_next_step_info("[...]"); + } - if (seven_zip) - { - System::println("Creating 7zip archive... "); - const fs::path output_path = - do_archive_export(paths, raw_exported_dir_path, export_to_path, ArchiveFormatC::SEVEN_ZIP); - System::println(System::Color::success, "Creating 7zip archive... done"); - System::println(System::Color::success, "7zip archive exported at: %s", output_path.generic_string()); - print_next_step_info("[...]"); + if (seven_zip) + { + System::println("Creating 7zip archive... "); + const fs::path output_path = + do_archive_export(paths, raw_exported_dir_path, export_to_path, ArchiveFormatC::SEVEN_ZIP); + System::println(System::Color::success, "Creating 7zip archive... done"); + System::println(System::Color::success, "7zip archive exported at: %s", output_path.generic_string()); + print_next_step_info("[...]"); + } + + if (!raw) + { + fs.remove_all(raw_exported_dir_path, ec); + } } - if (!raw && !ifw) + // IFW loop + if (ifw) { - fs.remove_all(raw_exported_dir_path, ec); + IFW::do_export(export_plan, export_id, ifw_options, paths); + + // TODO: Download corrected QtIFW tools and automate installer creation + System::println("Use corrected QtIFW tools (for more info see: https://codereview.qt-project.org/#/c/203958) to create installer..."); + + print_next_step_info("[...]"); } Checks::exit_success(VCPKG_LINE_INFO); diff --git a/toolsrc/src/commands_export_ifw.cpp b/toolsrc/src/commands_export_ifw.cpp index 4b5bdb902..e2499b75d 100644 --- a/toolsrc/src/commands_export_ifw.cpp +++ b/toolsrc/src/commands_export_ifw.cpp @@ -1,10 +1,30 @@ #include "pch.h" +#include "vcpkg_Commands.h" +#include "vcpkg_Commands_Export.h" #include "vcpkg_Commands_Export_IFW.h" namespace vcpkg::Commands::Export::IFW { using Dependencies::ExportPlanAction; + using Dependencies::ExportPlanType; + using Install::InstallDir; + + static std::string create_release_date() + { + const tm date_time = System::get_current_date_time(); + + // Format is: YYYY-mm-dd + // 10 characters + 1 null terminating character will be written for a total of 11 chars + char mbstr[11]; + const size_t bytes_written = std::strftime(mbstr, sizeof(mbstr), "%Y-%m-%d", &date_time); + Checks::check_exit(VCPKG_LINE_INFO, + bytes_written == 10, + "Expected 10 bytes to be written, but %u were written", + bytes_written); + const std::string date_time_as_string(mbstr); + return date_time_as_string; + } fs::path export_real_package(const fs::path& raw_exported_dir_path, const ExportPlanAction& action, @@ -28,19 +48,19 @@ namespace vcpkg::Commands::Export::IFW package_xml_file_path.generic_string()); fs.write_contents(package_xml_file_path, - Strings::format(R"###( - + Strings::format( +R"###( %s %s - 2017-08-31 - packages.%s:,triplets.%s: + %s + packages.%s:,triplets.%s: true - true )###", action.spec.to_string(), binary_paragraph.version, + create_release_date(), action.spec.name(), action.spec.triplet().canonical_name())); @@ -65,15 +85,15 @@ namespace vcpkg::Commands::Export::IFW !ec, "Could not create directory for package file %s", package_xml_file_path.generic_string()); - fs.write_contents(package_xml_file_path, R"###( - + fs.write_contents(package_xml_file_path, Strings::format( +R"###( Packages 1.0.0 - 2017-08-31 - true + %s -)###"); +)###", + create_release_date())); for (auto package = unique_packages.begin(); package != unique_packages.end(); ++package) { @@ -93,22 +113,22 @@ namespace vcpkg::Commands::Export::IFW auto deps = Strings::join( ",", binary_paragraph.depends, [](const std::string& dep) { return "packages." + dep + ":"; }); - if (!deps.empty()) deps = "\n " + deps; + if (!deps.empty()) deps = "\n " + deps + ""; fs.write_contents(package_xml_file_path, - Strings::format(R"###( - + Strings::format( +R"###( %s %s %s - 2017-08-31%s - true + %s%s )###", action.spec.name(), binary_paragraph.description, binary_paragraph.version, + create_release_date(), deps)); } } @@ -128,15 +148,15 @@ namespace vcpkg::Commands::Export::IFW !ec, "Could not create directory for package file %s", package_xml_file_path.generic_string()); - fs.write_contents(package_xml_file_path, R"###( - + fs.write_contents(package_xml_file_path, Strings::format( +R"###( Triplets 1.0.0 - 2017-08-31 - true + %s -)###"); +)###", + create_release_date())); for (const std::string& triplet : unique_triplets) { @@ -148,15 +168,16 @@ namespace vcpkg::Commands::Export::IFW !ec, "Could not create directory for package file %s", package_xml_file_path.generic_string()); - fs.write_contents(package_xml_file_path, Strings::format(R"###( - + fs.write_contents(package_xml_file_path, Strings::format( +R"###( %s 1.0.0 - 2017-08-31 - true + %s -)###", triplet)); +)###", + triplet, + create_release_date())); } } @@ -173,52 +194,128 @@ namespace vcpkg::Commands::Export::IFW "Could not create directory for package file %s", package_xml_file_path.generic_string()); - fs.write_contents(package_xml_file_path, R"###( - + fs.write_contents(package_xml_file_path, Strings::format( +R"###( Integration 1.0.0 - 2017-08-31 - true + %s -)###"); +)###", + create_release_date())); } - void export_config(const fs::path& raw_exported_dir_path, - const std::string ifw_repository_url, - Files::Filesystem& fs) + void export_config(const std::string &export_id, const Options &ifw_options, const VcpkgPaths& paths) { std::error_code ec; + Files::Filesystem& fs = paths.get_filesystem(); + + const fs::path config_xml_file_path = ifw_options.maybe_config_file_path.has_value() ? + fs::path(ifw_options.maybe_config_file_path.value_or_exit(VCPKG_LINE_INFO)) + : paths.root / (export_id + "-ifw-configuration") / "config.xml"; - // config.xml - fs::path config_xml_file_path = raw_exported_dir_path / "config.xml"; fs::path config_xml_dir_path = config_xml_file_path.parent_path(); fs.create_directories(config_xml_dir_path, ec); Checks::check_exit(VCPKG_LINE_INFO, !ec, "Could not create directory for configuration file %s", config_xml_file_path.generic_string()); + std::string formatted_repo_url; - if (!ifw_repository_url.empty()) + std::string ifw_repo_url = ifw_options.maybe_repository_url.value_or(""); + if (!ifw_repo_url.empty()) { formatted_repo_url = Strings::format(R"###( %s - -)###", - formatted_repo_url); + )###", + ifw_repo_url); } - fs.write_contents(config_xml_file_path, Strings::format(R"###( - + fs.write_contents(config_xml_file_path, Strings::format( +R"###( vcpkg 1.0.0 - 2017-08-31 @RootDir@/src/vcpkg%s -)###", formatted_repo_url)); +)###", + formatted_repo_url)); + + System::println("Created ifw configuration file: %s", config_xml_file_path.generic_string()); + } + + void do_export(const std::vector &export_plan, const std::string &export_id, const Options &ifw_options, const VcpkgPaths& paths) + { + System::println("Creating ifw packages... "); + + std::error_code ec; + Files::Filesystem& fs = paths.get_filesystem(); + + const fs::path ifw_packages_dir_path = ifw_options.maybe_packages_dir_path.has_value() ? + fs::path(ifw_options.maybe_packages_dir_path.value_or_exit(VCPKG_LINE_INFO)) + : paths.root / (export_id + "-ifw-packages"); + + fs.remove_all(ifw_packages_dir_path, ec); + Checks::check_exit(VCPKG_LINE_INFO, + !ec, + "Could not remove outdated packages directory %s", + ifw_packages_dir_path.generic_string()); + + fs.create_directory(ifw_packages_dir_path, ec); + Checks::check_exit(VCPKG_LINE_INFO, + !ec, + "Could not create packages directory %s", + ifw_packages_dir_path.generic_string()); + + // execute the plan + std::map unique_packages; + std::set unique_triplets; + for (const ExportPlanAction& action : export_plan) + { + if (action.plan_type != ExportPlanType::ALREADY_BUILT) + { + Checks::unreachable(VCPKG_LINE_INFO); + } + + const std::string display_name = action.spec.to_string(); + System::println("Exporting package %s... ", display_name); + + const BinaryParagraph& binary_paragraph = + action.any_paragraph.binary_control_file.value_or_exit(VCPKG_LINE_INFO).core_paragraph; + + unique_packages[action.spec.name()] = &action; + unique_triplets.insert(action.spec.triplet().canonical_name()); + + // Export real package and return data dir for installation + fs::path ifw_package_dir_path = export_real_package(ifw_packages_dir_path, action, fs); + + // Copy package data + const InstallDir dirs = InstallDir::from_destination_root(ifw_package_dir_path, + action.spec.triplet().to_string(), + 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); + System::println(System::Color::success, "Exporting package %s... done", display_name); + } + + // Unique packages + export_unique_packages(ifw_packages_dir_path, unique_packages, fs); + + // Unique triplets + export_unique_triplets(ifw_packages_dir_path, unique_triplets, fs); + + // Copy files needed for integration + export_integration_files(ifw_packages_dir_path / "integration" / "data", paths); + // Integration + export_integration(ifw_packages_dir_path, fs); + + System::println("Created ifw packages directory: %s", ifw_packages_dir_path.generic_string()); + + // Configuration + export_config(export_id, ifw_options, paths); } } diff --git a/toolsrc/vcpkglib/vcpkglib.vcxproj b/toolsrc/vcpkglib/vcpkglib.vcxproj index 3f17ecb3c..7c5537e15 100644 --- a/toolsrc/vcpkglib/vcpkglib.vcxproj +++ b/toolsrc/vcpkglib/vcpkglib.vcxproj @@ -166,6 +166,7 @@ + diff --git a/toolsrc/vcpkglib/vcpkglib.vcxproj.filters b/toolsrc/vcpkglib/vcpkglib.vcxproj.filters index 7eb077019..cc82198ee 100644 --- a/toolsrc/vcpkglib/vcpkglib.vcxproj.filters +++ b/toolsrc/vcpkglib/vcpkglib.vcxproj.filters @@ -221,6 +221,9 @@ Header Files + + Header Files + Header Files -- cgit v1.2.3 From c6149fae2f9f33d9ed363650aee6aea642574b0a Mon Sep 17 00:00:00 2001 From: Konstantin Podsvirov Date: Wed, 27 Sep 2017 02:57:51 +0300 Subject: [vcpkg-export-ifw] Usage QtIFW tools Download and use tools to make repository and installer --- toolsrc/include/VcpkgPaths.h | 6 ++ toolsrc/include/vcpkg_Commands_Export_IFW.h | 2 + toolsrc/src/VcpkgPaths.cpp | 40 ++++++++ toolsrc/src/commands_export.cpp | 19 +++- toolsrc/src/commands_export_ifw.cpp | 145 +++++++++++++++++++++++----- 5 files changed, 182 insertions(+), 30 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/VcpkgPaths.h b/toolsrc/include/VcpkgPaths.h index d55c95fe1..e7893ba15 100644 --- a/toolsrc/include/VcpkgPaths.h +++ b/toolsrc/include/VcpkgPaths.h @@ -57,6 +57,9 @@ namespace vcpkg const fs::path& get_cmake_exe() const; const fs::path& get_git_exe() const; const fs::path& get_nuget_exe() const; + const fs::path& get_ifw_installerbase_exe() const; + const fs::path& get_ifw_binarycreator_exe() const; + const fs::path& get_ifw_repogen_exe() const; /// Retrieve a toolset matching a VS version /// @@ -70,6 +73,9 @@ namespace vcpkg Lazy cmake_exe; Lazy git_exe; Lazy nuget_exe; + Lazy ifw_installerbase_exe; + Lazy ifw_binarycreator_exe; + Lazy ifw_repogen_exe; Lazy> toolsets; }; } diff --git a/toolsrc/include/vcpkg_Commands_Export_IFW.h b/toolsrc/include/vcpkg_Commands_Export_IFW.h index 881bbaf63..c066ca021 100644 --- a/toolsrc/include/vcpkg_Commands_Export_IFW.h +++ b/toolsrc/include/vcpkg_Commands_Export_IFW.h @@ -9,7 +9,9 @@ namespace vcpkg::Commands::Export::IFW { Optional maybe_repository_url; Optional maybe_packages_dir_path; + Optional maybe_repository_dir_path; Optional maybe_config_file_path; + Optional maybe_installer_file_path; }; void do_export(const std::vector &export_plan, const std::string &export_id, const Options &ifw_options, const VcpkgPaths& paths); diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp index 02e238b3f..89435cd38 100644 --- a/toolsrc/src/VcpkgPaths.cpp +++ b/toolsrc/src/VcpkgPaths.cpp @@ -164,6 +164,31 @@ namespace vcpkg return fetch_dependency(scripts_folder, L"git", downloaded_copy, EXPECTED_VERSION); } + static fs::path get_ifw_installerbase_path(const fs::path& downloads_folder, const fs::path& scripts_folder) + { + static constexpr std::array EXPECTED_VERSION = { 3, 1, 81 }; + static const std::wstring VERSION_CHECK_ARGUMENTS = L"--framework-version"; + + const fs::path downloaded_copy = downloads_folder / "QtInstallerFramework-win-x86" / "bin" / "installerbase.exe"; + + std::vector candidate_paths; + candidate_paths.push_back(downloaded_copy); + // TODO: Uncomment later + //const std::vector from_path = Files::find_from_PATH(L"installerbase"); + //candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); + //candidate_paths.push_back(fs::path(System::get_environment_variable(L"HOMEDRIVE").value_or("C:")) / "Qt" / "Tools" / "QtInstallerFramework" / "3.1" / "bin" / "installerbase.exe"); + //candidate_paths.push_back(fs::path(System::get_environment_variable(L"HOMEDRIVE").value_or("C:")) / "Qt" / "QtIFW-3.1.0" / "bin" / "installerbase.exe"); + + const Optional path = + find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, EXPECTED_VERSION); + if (const auto p = path.get()) + { + return *p; + } + + return fetch_dependency(scripts_folder, L"installerbase", downloaded_copy, EXPECTED_VERSION); + } + Expected VcpkgPaths::create(const fs::path& vcpkg_root_dir) { std::error_code ec; @@ -247,6 +272,21 @@ namespace vcpkg return this->nuget_exe.get_lazy([this]() { return get_nuget_path(this->downloads, this->scripts); }); } + const fs::path& VcpkgPaths::get_ifw_installerbase_exe() const + { + return this->ifw_installerbase_exe.get_lazy([this]() { return get_ifw_installerbase_path(this->downloads, this->scripts); }); + } + + const fs::path& VcpkgPaths::get_ifw_binarycreator_exe() const + { + return this->ifw_binarycreator_exe.get_lazy([this]() { return get_ifw_installerbase_exe().parent_path() / "binarycreator.exe"; }); + } + + const fs::path& VcpkgPaths::get_ifw_repogen_exe() const + { + return this->ifw_repogen_exe.get_lazy([this]() { return get_ifw_installerbase_exe().parent_path() / "repogen.exe"; }); + } + static std::vector get_vs2017_installation_instances(const VcpkgPaths& paths) { const fs::path script = paths.scripts / "findVisualStudioInstallationInstances.ps1"; diff --git a/toolsrc/src/commands_export.cpp b/toolsrc/src/commands_export.cpp index 6632dfe67..3662a46d8 100644 --- a/toolsrc/src/commands_export.cpp +++ b/toolsrc/src/commands_export.cpp @@ -249,7 +249,9 @@ namespace vcpkg::Commands::Export static const std::string OPTION_NUGET_VERSION = "--nuget-version"; static const std::string OPTION_IFW_REPOSITORY_URL = "--ifw-repository-url"; static const std::string OPTION_IFW_PACKAGES_DIR_PATH = "--ifw-packages-directory-path"; + static const std::string OPTION_IFW_REPOSITORY_DIR_PATH = "--ifw-repository-directory-path"; static const std::string OPTION_IFW_CONFIG_FILE_PATH = "--ifw-configuration-file-path"; + static const std::string OPTION_IFW_INSTALLER_FILE_PATH = "--ifw-installer-file-path"; // input sanitization static const std::string EXAMPLE = @@ -276,7 +278,9 @@ namespace vcpkg::Commands::Export OPTION_NUGET_VERSION, OPTION_IFW_REPOSITORY_URL, OPTION_IFW_PACKAGES_DIR_PATH, - OPTION_IFW_CONFIG_FILE_PATH + OPTION_IFW_REPOSITORY_DIR_PATH, + OPTION_IFW_CONFIG_FILE_PATH, + OPTION_IFW_INSTALLER_FILE_PATH }); const bool dry_run = options.switches.find(OPTION_DRY_RUN) != options.switches.cend(); const bool raw = options.switches.find(OPTION_RAW) != options.switches.cend(); @@ -310,10 +314,18 @@ namespace vcpkg::Commands::Export Checks::check_exit( VCPKG_LINE_INFO, !ifw_options.maybe_packages_dir_path || ifw, "--ifw-packages-directory-path is only valid with --ifw"); + ifw_options.maybe_repository_dir_path = maybe_lookup(options.settings, OPTION_IFW_REPOSITORY_DIR_PATH); + Checks::check_exit( + VCPKG_LINE_INFO, !ifw_options.maybe_repository_dir_path || ifw, "--ifw-repository-directory-path is only valid with --ifw"); + ifw_options.maybe_config_file_path = maybe_lookup(options.settings, OPTION_IFW_CONFIG_FILE_PATH); Checks::check_exit( VCPKG_LINE_INFO, !ifw_options.maybe_config_file_path || ifw, "--ifw-configuration-file-path is only valid with --ifw"); + ifw_options.maybe_installer_file_path = maybe_lookup(options.settings, OPTION_IFW_INSTALLER_FILE_PATH); + Checks::check_exit( + VCPKG_LINE_INFO, !ifw_options.maybe_installer_file_path || ifw, "--ifw-installer-file-path is only valid with --ifw"); + // create the plan const StatusParagraphs status_db = database_load_check(paths); std::vector export_plan = Dependencies::create_export_plan(paths, specs, status_db); @@ -464,10 +476,7 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console { IFW::do_export(export_plan, export_id, ifw_options, paths); - // TODO: Download corrected QtIFW tools and automate installer creation - System::println("Use corrected QtIFW tools (for more info see: https://codereview.qt-project.org/#/c/203958) to create installer..."); - - print_next_step_info("[...]"); + print_next_step_info("@RootDir@/src/vcpkg"); } Checks::exit_success(VCPKG_LINE_INFO); diff --git a/toolsrc/src/commands_export_ifw.cpp b/toolsrc/src/commands_export_ifw.cpp index e2499b75d..d1428f5d1 100644 --- a/toolsrc/src/commands_export_ifw.cpp +++ b/toolsrc/src/commands_export_ifw.cpp @@ -26,7 +26,35 @@ namespace vcpkg::Commands::Export::IFW return date_time_as_string; } - fs::path export_real_package(const fs::path& raw_exported_dir_path, + fs::path get_packages_dir_path(const std::string &export_id, const Options &ifw_options, const VcpkgPaths& paths) + { + return ifw_options.maybe_packages_dir_path.has_value() ? + fs::path(ifw_options.maybe_packages_dir_path.value_or_exit(VCPKG_LINE_INFO)) + : paths.root / (export_id + "-ifw-packages"); + } + + fs::path get_repository_dir_path(const std::string &export_id, const Options &ifw_options, const VcpkgPaths& paths) + { + return ifw_options.maybe_packages_dir_path.has_value() ? + fs::path(ifw_options.maybe_repository_dir_path.value_or_exit(VCPKG_LINE_INFO)) + : paths.root / (export_id + "-ifw-repository"); + } + + fs::path get_config_file_path(const std::string &export_id, const Options &ifw_options, const VcpkgPaths& paths) + { + return ifw_options.maybe_config_file_path.has_value() ? + fs::path(ifw_options.maybe_config_file_path.value_or_exit(VCPKG_LINE_INFO)) + : paths.root / (export_id + "-ifw-configuration.xml"); + } + + fs::path get_installer_file_path(const std::string &export_id, const Options &ifw_options, const VcpkgPaths& paths) + { + return ifw_options.maybe_config_file_path.has_value() ? + fs::path(ifw_options.maybe_installer_file_path.value_or_exit(VCPKG_LINE_INFO)) + : paths.root / (export_id + "-ifw-installer.exe"); + } + + fs::path export_real_package(const fs::path& ifw_packages_dir_path, const ExportPlanAction& action, Files::Filesystem& fs) { @@ -37,7 +65,7 @@ namespace vcpkg::Commands::Export::IFW // Prepare meta dir const fs::path package_xml_file_path = - raw_exported_dir_path / + ifw_packages_dir_path / Strings::format("packages.%s.%s", action.spec.name(), action.spec.triplet().canonical_name()) / "meta" / "package.xml"; const fs::path package_xml_dir_path = package_xml_file_path.parent_path(); @@ -47,6 +75,11 @@ namespace vcpkg::Commands::Export::IFW "Could not create directory for package file %s", package_xml_file_path.generic_string()); + auto deps = Strings::join( + ",", binary_paragraph.depends, [](const std::string& dep) { return "packages." + dep + ":"; }); + + if (!deps.empty()) deps = "\n " + deps + ""; + fs.write_contents(package_xml_file_path, Strings::format( R"###( @@ -54,7 +87,7 @@ R"###( %s %s %s - packages.%s:,triplets.%s: + packages.%s:,triplets.%s:%s true )###", @@ -62,10 +95,11 @@ R"###( binary_paragraph.version, create_release_date(), action.spec.name(), - action.spec.triplet().canonical_name())); + action.spec.triplet().canonical_name(), + deps)); // Return dir path for export package data - return raw_exported_dir_path / + return ifw_packages_dir_path / Strings::format("packages.%s.%s", action.spec.name(), action.spec.triplet().canonical_name()) / "data" / "installed"; } @@ -110,11 +144,6 @@ R"###( "Could not create directory for package file %s", package_xml_file_path.generic_string()); - auto deps = Strings::join( - ",", binary_paragraph.depends, [](const std::string& dep) { return "packages." + dep + ":"; }); - - if (!deps.empty()) deps = "\n " + deps + ""; - fs.write_contents(package_xml_file_path, Strings::format( R"###( @@ -122,14 +151,13 @@ R"###( %s %s %s - %s%s + %s )###", action.spec.name(), binary_paragraph.description, binary_paragraph.version, - create_release_date(), - deps)); + create_release_date())); } } @@ -210,9 +238,7 @@ R"###( std::error_code ec; Files::Filesystem& fs = paths.get_filesystem(); - const fs::path config_xml_file_path = ifw_options.maybe_config_file_path.has_value() ? - fs::path(ifw_options.maybe_config_file_path.value_or_exit(VCPKG_LINE_INFO)) - : paths.root / (export_id + "-ifw-configuration") / "config.xml"; + const fs::path config_xml_file_path = get_config_file_path(export_id, ifw_options, paths); fs::path config_xml_dir_path = config_xml_file_path.parent_path(); fs.create_directories(config_xml_dir_path, ec); @@ -243,21 +269,76 @@ R"###( )###", formatted_repo_url)); + } + + void do_repository(const std::string &export_id, const Options &ifw_options, const VcpkgPaths& paths) + { + const fs::path& repogen_exe = paths.get_ifw_repogen_exe(); + const fs::path packages_dir = get_packages_dir_path(export_id, ifw_options, paths); + const fs::path repository_dir = get_repository_dir_path(export_id, ifw_options, paths); + + System::println("Generating repository %s...", repository_dir.generic_string()); - System::println("Created ifw configuration file: %s", config_xml_file_path.generic_string()); + const std::wstring cmd_line = + Strings::wformat(LR"("%s" --packages "%s" "%s" > nul)", + repogen_exe.native(), + packages_dir.native(), + repository_dir.native()); + + const int exit_code = System::cmd_execute_clean(cmd_line); + Checks::check_exit(VCPKG_LINE_INFO, exit_code == 0, "Error: IFW repository generating failed"); + + System::println(System::Color::success, "Generating repository %s... done.", repository_dir.generic_string()); + } + + void do_installer(const std::string &export_id, const Options &ifw_options, const VcpkgPaths& paths) + { + const fs::path& binarycreator_exe = paths.get_ifw_binarycreator_exe(); + const fs::path config_file = get_config_file_path(export_id, ifw_options, paths); + const fs::path packages_dir = get_packages_dir_path(export_id, ifw_options, paths); + const fs::path repository_dir = get_repository_dir_path(export_id, ifw_options, paths); + const fs::path installer_file = get_installer_file_path(export_id, ifw_options, paths); + + System::println("Generating installer %s...", installer_file.generic_string()); + + std::wstring cmd_line; + + std::string ifw_repo_url = ifw_options.maybe_repository_url.value_or(""); + if (!ifw_repo_url.empty()) + { + cmd_line = + Strings::wformat(LR"("%s" --online-only --config "%s" --repository "%s" "%s" > nul)", + binarycreator_exe.native(), + config_file.native(), + repository_dir.native(), + installer_file.native()); + } + else + { + cmd_line = + Strings::wformat(LR"("%s" --config "%s" --packages "%s" "%s" > nul)", + binarycreator_exe.native(), + config_file.native(), + packages_dir.native(), + installer_file.native()); + } + + const int exit_code = System::cmd_execute_clean(cmd_line); + Checks::check_exit(VCPKG_LINE_INFO, exit_code == 0, "Error: IFW installer generating failed"); + + System::println(System::Color::success, "Generating installer %s... done.", installer_file.generic_string()); } void do_export(const std::vector &export_plan, const std::string &export_id, const Options &ifw_options, const VcpkgPaths& paths) { - System::println("Creating ifw packages... "); + const fs::path ifw_packages_dir_path = get_packages_dir_path(export_id, ifw_options, paths); + const fs::path config_file = get_config_file_path(export_id, ifw_options, paths); + + System::println("Exporting packages %s... ", ifw_packages_dir_path.generic_string()); std::error_code ec; Files::Filesystem& fs = paths.get_filesystem(); - const fs::path ifw_packages_dir_path = ifw_options.maybe_packages_dir_path.has_value() ? - fs::path(ifw_options.maybe_packages_dir_path.value_or_exit(VCPKG_LINE_INFO)) - : paths.root / (export_id + "-ifw-packages"); - fs.remove_all(ifw_packages_dir_path, ec); Checks::check_exit(VCPKG_LINE_INFO, !ec, @@ -299,9 +380,13 @@ R"###( (binary_paragraph.fullstem() + ".list")); Install::install_files_and_write_listfile(paths.get_filesystem(), paths.package_dir(action.spec), dirs); - System::println(System::Color::success, "Exporting package %s... done", display_name); + System::println("Exporting package %s... done", display_name); } + System::println("Exporting packages %s... done", ifw_packages_dir_path.generic_string()); + + System::println("Generating configuration %s...", config_file.generic_string()); + // Unique packages export_unique_packages(ifw_packages_dir_path, unique_packages, fs); @@ -313,9 +398,19 @@ R"###( // Integration export_integration(ifw_packages_dir_path, fs); - System::println("Created ifw packages directory: %s", ifw_packages_dir_path.generic_string()); - // Configuration export_config(export_id, ifw_options, paths); + + System::println("Generating configuration %s... done.", config_file.generic_string()); + + // Do repository (optional) + std::string ifw_repo_url = ifw_options.maybe_repository_url.value_or(""); + if (!ifw_repo_url.empty()) + { + do_repository(export_id, ifw_options, paths); + } + + // Do installer + do_installer(export_id, ifw_options, paths); } } -- cgit v1.2.3 From d25fd5c7b3b0f21581dd9c44a915c9156683877a Mon Sep 17 00:00:00 2001 From: Konstantin Podsvirov Date: Thu, 28 Sep 2017 01:00:40 +0300 Subject: [vcpkg-export-ifw] Some improvements Improvements: - fix typos; - remove outdated repository directory. --- toolsrc/src/commands_export_ifw.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/commands_export_ifw.cpp b/toolsrc/src/commands_export_ifw.cpp index d1428f5d1..a0692c11e 100644 --- a/toolsrc/src/commands_export_ifw.cpp +++ b/toolsrc/src/commands_export_ifw.cpp @@ -35,7 +35,7 @@ namespace vcpkg::Commands::Export::IFW fs::path get_repository_dir_path(const std::string &export_id, const Options &ifw_options, const VcpkgPaths& paths) { - return ifw_options.maybe_packages_dir_path.has_value() ? + return ifw_options.maybe_repository_dir_path.has_value() ? fs::path(ifw_options.maybe_repository_dir_path.value_or_exit(VCPKG_LINE_INFO)) : paths.root / (export_id + "-ifw-repository"); } @@ -49,7 +49,7 @@ namespace vcpkg::Commands::Export::IFW fs::path get_installer_file_path(const std::string &export_id, const Options &ifw_options, const VcpkgPaths& paths) { - return ifw_options.maybe_config_file_path.has_value() ? + return ifw_options.maybe_installer_file_path.has_value() ? fs::path(ifw_options.maybe_installer_file_path.value_or_exit(VCPKG_LINE_INFO)) : paths.root / (export_id + "-ifw-installer.exe"); } @@ -279,6 +279,15 @@ R"###( System::println("Generating repository %s...", repository_dir.generic_string()); + std::error_code ec; + Files::Filesystem& fs = paths.get_filesystem(); + + fs.remove_all(repository_dir, ec); + Checks::check_exit(VCPKG_LINE_INFO, + !ec, + "Could not remove outdated repository directory %s", + repository_dir.generic_string()); + const std::wstring cmd_line = Strings::wformat(LR"("%s" --packages "%s" "%s" > nul)", repogen_exe.native(), -- cgit v1.2.3 From eca068e4c5673b888d6470b42d6b5b44b21c4007 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 27 Sep 2017 17:22:40 -0700 Subject: Extract function for duplicated code --- toolsrc/src/VcpkgPaths.cpp | 51 ++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 27 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp index 02e238b3f..00f4691cd 100644 --- a/toolsrc/src/VcpkgPaths.cpp +++ b/toolsrc/src/VcpkgPaths.cpp @@ -269,10 +269,29 @@ namespace vcpkg return nullopt; } - static std::vector find_toolset_instances(const VcpkgPaths& paths) + static std::vector detect_supported_architectures(const Files::Filesystem& fs, + const fs::path& vcvarsall_dir) { using CPU = System::CPUArchitecture; + std::vector supported_architectures; + + if (fs.exists(vcvarsall_dir / "vcvars32.bat")) supported_architectures.push_back({L"x86", CPU::X86, CPU::X86}); + if (fs.exists(vcvarsall_dir / "vcvars64.bat")) + supported_architectures.push_back({L"amd64", CPU::X64, CPU::X64}); + if (fs.exists(vcvarsall_dir / "vcvarsx86_amd64.bat")) + supported_architectures.push_back({L"x86_amd64", CPU::X86, CPU::X64}); + if (fs.exists(vcvarsall_dir / "vcvarsx86_arm.bat")) + supported_architectures.push_back({L"x86_arm", CPU::X86, CPU::ARM}); + if (fs.exists(vcvarsall_dir / "vcvarsamd64_x86.bat")) + supported_architectures.push_back({L"amd64_x86", CPU::X64, CPU::X86}); + if (fs.exists(vcvarsall_dir / "vcvarsamd64_arm.bat")) + supported_architectures.push_back({L"amd64_arm", CPU::X64, CPU::ARM}); + + return supported_architectures; + } + static std::vector find_toolset_instances(const VcpkgPaths& paths) + { const auto& fs = paths.get_filesystem(); const std::vector vs2017_installation_instances = get_vs2017_installation_instances(paths); @@ -294,19 +313,8 @@ namespace vcpkg paths_examined.push_back(vs2015_dumpbin_exe); const fs::path vs2015_bin_dir = vs2015_vcvarsall_bat.parent_path() / "bin"; - std::vector supported_architectures; - if (fs.exists(vs2015_bin_dir / "vcvars32.bat")) - supported_architectures.push_back({L"x86", CPU::X86, CPU::X86}); - if (fs.exists(vs2015_bin_dir / "amd64\\vcvars64.bat")) - supported_architectures.push_back({L"x64", CPU::X64, CPU::X64}); - if (fs.exists(vs2015_bin_dir / "x86_amd64\\vcvarsx86_amd64.bat")) - supported_architectures.push_back({L"x86_amd64", CPU::X86, CPU::X64}); - if (fs.exists(vs2015_bin_dir / "x86_arm\\vcvarsx86_arm.bat")) - supported_architectures.push_back({L"x86_arm", CPU::X86, CPU::ARM}); - if (fs.exists(vs2015_bin_dir / "amd64_x86\\vcvarsamd64_x86.bat")) - supported_architectures.push_back({L"amd64_x86", CPU::X64, CPU::X86}); - if (fs.exists(vs2015_bin_dir / "amd64_arm\\vcvarsamd64_arm.bat")) - supported_architectures.push_back({L"amd64_arm", CPU::X64, CPU::ARM}); + const std::vector supported_architectures = + detect_supported_architectures(fs, vs2015_bin_dir); if (fs.exists(vs2015_dumpbin_exe)) { @@ -329,19 +337,8 @@ namespace vcpkg if (!fs.exists(vcvarsall_bat)) continue; // Get all supported architectures - std::vector supported_architectures; - if (fs.exists(vcvarsall_dir / "vcvars32.bat")) - supported_architectures.push_back({L"x86", CPU::X86, CPU::X86}); - if (fs.exists(vcvarsall_dir / "vcvars64.bat")) - supported_architectures.push_back({L"amd64", CPU::X64, CPU::X64}); - if (fs.exists(vcvarsall_dir / "vcvarsx86_amd64.bat")) - supported_architectures.push_back({L"x86_amd64", CPU::X86, CPU::X64}); - if (fs.exists(vcvarsall_dir / "vcvarsx86_arm.bat")) - supported_architectures.push_back({L"x86_arm", CPU::X86, CPU::ARM}); - if (fs.exists(vcvarsall_dir / "vcvarsamd64_x86.bat")) - supported_architectures.push_back({L"amd64_x86", CPU::X64, CPU::X86}); - if (fs.exists(vcvarsall_dir / "vcvarsamd64_arm.bat")) - supported_architectures.push_back({L"amd64_arm", CPU::X64, CPU::ARM}); + const std::vector supported_architectures = + detect_supported_architectures(fs, vcvarsall_dir); // Locate the "best" MSVC toolchain version const fs::path msvc_path = vc_dir / "Tools" / "MSVC"; -- cgit v1.2.3 From 712491c8223616803220b7f8b807ecb5a3e64ece Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 27 Sep 2017 17:48:51 -0700 Subject: Place line closer to usage --- toolsrc/src/VcpkgPaths.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp index 00f4691cd..b831b6f46 100644 --- a/toolsrc/src/VcpkgPaths.cpp +++ b/toolsrc/src/VcpkgPaths.cpp @@ -294,7 +294,6 @@ namespace vcpkg { const auto& fs = paths.get_filesystem(); - const std::vector vs2017_installation_instances = get_vs2017_installation_instances(paths); // Note: this will contain a mix of vcvarsall.bat locations and dumpbin.exe locations. std::vector paths_examined; @@ -324,6 +323,8 @@ namespace vcpkg } } + const std::vector vs2017_installation_instances = get_vs2017_installation_instances(paths); + // VS2017 Optional vs2017_toolset; for (const std::string& instance : vs2017_installation_instances) -- cgit v1.2.3 From f617a711ec4c3d5527911c32340238053901269d Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 27 Sep 2017 18:41:28 -0700 Subject: Fix: Don't break before finding all VS2017 instances --- toolsrc/src/VcpkgPaths.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp index b831b6f46..8ce4df3df 100644 --- a/toolsrc/src/VcpkgPaths.cpp +++ b/toolsrc/src/VcpkgPaths.cpp @@ -364,7 +364,6 @@ namespace vcpkg if (const auto value = vs2017_toolset.get()) { found_toolsets.push_back(*value); - break; } } -- cgit v1.2.3 From 0ccea4f3677d92a20935e03c2cb301d8300b43d1 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 27 Sep 2017 18:55:09 -0700 Subject: [Toolset selection] Use VS2017 vcvarsall for v140 if available --- toolsrc/include/VcpkgPaths.h | 2 ++ toolsrc/src/VcpkgPaths.cpp | 59 +++++++++++++++++++++++++++++++++++++++----- toolsrc/src/vcpkg_Build.cpp | 7 +++++- 3 files changed, 61 insertions(+), 7 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/VcpkgPaths.h b/toolsrc/include/VcpkgPaths.h index d55c95fe1..3c1955204 100644 --- a/toolsrc/include/VcpkgPaths.h +++ b/toolsrc/include/VcpkgPaths.h @@ -19,6 +19,7 @@ namespace vcpkg { fs::path dumpbin; fs::path vcvarsall; + std::vector vcvarsall_options; CWStringView version; std::vector supported_architectures; }; @@ -71,5 +72,6 @@ namespace vcpkg Lazy git_exe; Lazy nuget_exe; Lazy> toolsets; + Lazy> toolsets_vs2017_v140; }; } diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp index 8ce4df3df..8892207bd 100644 --- a/toolsrc/src/VcpkgPaths.cpp +++ b/toolsrc/src/VcpkgPaths.cpp @@ -10,6 +10,10 @@ namespace vcpkg { + // Intentionally wstring so we can easily use operator== with CWStringView. + static const std::wstring V_140 = L"v140"; + static const std::wstring V_141 = L"v141"; + static bool exists_and_has_equal_or_greater_version(const std::wstring& version_cmd, const std::array& expected_version) { @@ -318,7 +322,7 @@ namespace vcpkg if (fs.exists(vs2015_dumpbin_exe)) { found_toolsets.push_back( - {vs2015_dumpbin_exe, vs2015_vcvarsall_bat, L"v140", supported_architectures}); + {vs2015_dumpbin_exe, vs2015_vcvarsall_bat, {}, V_140, supported_architectures}); } } } @@ -357,7 +361,7 @@ namespace vcpkg paths_examined.push_back(dumpbin_path); if (fs.exists(dumpbin_path)) { - vs2017_toolset = Toolset{dumpbin_path, vcvarsall_bat, L"v141", supported_architectures}; + vs2017_toolset = Toolset{dumpbin_path, vcvarsall_bat, {}, V_141, supported_architectures}; break; } } @@ -381,20 +385,63 @@ namespace vcpkg return found_toolsets; } + static std::vector create_vs2017_v140_toolset_instances(const std::vector& vs_toolsets) + { + std::vector vs2017_v140_toolsets; + + // In constrast to v141 and above, there can only be a single instance of v140 (VS2017 vs VS2015). + const auto it = Util::find_if(vs_toolsets, [&](const Toolset& t) { return t.version == V_140; }); + + // If v140 is not available, then VS2017 cant use them. Return empty. + if (it == vs_toolsets.cend()) + { + return vs2017_v140_toolsets; + } + + // If it does exist, then create a matching v140 toolset for each v141 toolset + const Toolset v140_toolset = *it; + for (const Toolset& toolset : vs_toolsets) + { + if (toolset.version != V_141) + { + continue; + } + + Toolset t = Toolset{ + toolset.dumpbin, toolset.vcvarsall, {L"-vcvars_ver=14.0"}, V_140, toolset.supported_architectures}; + vs2017_v140_toolsets.push_back(std::move(t)); + } + + return vs2017_v140_toolsets; + } + const Toolset& VcpkgPaths::get_toolset(const std::string& toolset_version) const { + const std::wstring& w_toolset_version = Strings::to_utf16(toolset_version); + // Invariant: toolsets are non-empty and sorted with newest at back() - const auto& vs_toolsets = this->toolsets.get_lazy([this]() { return find_toolset_instances(*this); }); + const std::vector& vs_toolsets = + this->toolsets.get_lazy([this]() { return find_toolset_instances(*this); }); - if (toolset_version.empty()) + if (w_toolset_version.empty()) { return vs_toolsets.back(); } - const auto toolset = Util::find_if( - vs_toolsets, [&](const Toolset& t) { return toolset_version == Strings::to_utf8(t.version); }); + const auto toolset = + Util::find_if(vs_toolsets, [&](const Toolset& t) { return w_toolset_version == t.version; }); Checks::check_exit( VCPKG_LINE_INFO, toolset != vs_toolsets.end(), "Could not find toolset '%s'", toolset_version); + + // If v140 is the selected toolset and VS2017 is available, then use VS2017's vcvarsall with the + // -vcvars_ver=14.0 option + const std::vector& vs2017_v140_toolsets = this->toolsets_vs2017_v140.get_lazy( + [&vs_toolsets]() { return create_vs2017_v140_toolset_instances(vs_toolsets); }); + if (w_toolset_version == V_140 && !vs2017_v140_toolsets.empty()) + { + return vs2017_v140_toolsets.back(); + } + return *toolset; } diff --git a/toolsrc/src/vcpkg_Build.cpp b/toolsrc/src/vcpkg_Build.cpp index d40140aca..5ac13c6c6 100644 --- a/toolsrc/src/vcpkg_Build.cpp +++ b/toolsrc/src/vcpkg_Build.cpp @@ -67,7 +67,12 @@ namespace vcpkg::Build const auto arch = to_vcvarsall_toolchain(pre_build_info.target_architecture, toolset); const auto target = to_vcvarsall_target(pre_build_info.cmake_system_name); - return Strings::wformat(LR"("%s" %s %s %s 2>&1)", toolset.vcvarsall.native(), arch, target, tonull); + return Strings::wformat(LR"("%s" %s %s %s %s 2>&1)", + toolset.vcvarsall.native(), + Strings::join(L" ", toolset.vcvarsall_options), + arch, + target, + tonull); } static void create_binary_feature_control_file(const SourceParagraph& source_paragraph, -- cgit v1.2.3 From 450cb8591a5023f762b4b928cb36ca632d0fe7b3 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 28 Sep 2017 19:39:11 -0700 Subject: Revert "Extract function for duplicated code" This reverts commit eca068e4c5673b888d6470b42d6b5b44b21c4007. --- toolsrc/src/VcpkgPaths.cpp | 51 ++++++++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 24 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp index 8892207bd..4634a87c0 100644 --- a/toolsrc/src/VcpkgPaths.cpp +++ b/toolsrc/src/VcpkgPaths.cpp @@ -273,29 +273,10 @@ namespace vcpkg return nullopt; } - static std::vector detect_supported_architectures(const Files::Filesystem& fs, - const fs::path& vcvarsall_dir) + static std::vector find_toolset_instances(const VcpkgPaths& paths) { using CPU = System::CPUArchitecture; - std::vector supported_architectures; - - if (fs.exists(vcvarsall_dir / "vcvars32.bat")) supported_architectures.push_back({L"x86", CPU::X86, CPU::X86}); - if (fs.exists(vcvarsall_dir / "vcvars64.bat")) - supported_architectures.push_back({L"amd64", CPU::X64, CPU::X64}); - if (fs.exists(vcvarsall_dir / "vcvarsx86_amd64.bat")) - supported_architectures.push_back({L"x86_amd64", CPU::X86, CPU::X64}); - if (fs.exists(vcvarsall_dir / "vcvarsx86_arm.bat")) - supported_architectures.push_back({L"x86_arm", CPU::X86, CPU::ARM}); - if (fs.exists(vcvarsall_dir / "vcvarsamd64_x86.bat")) - supported_architectures.push_back({L"amd64_x86", CPU::X64, CPU::X86}); - if (fs.exists(vcvarsall_dir / "vcvarsamd64_arm.bat")) - supported_architectures.push_back({L"amd64_arm", CPU::X64, CPU::ARM}); - - return supported_architectures; - } - static std::vector find_toolset_instances(const VcpkgPaths& paths) - { const auto& fs = paths.get_filesystem(); // Note: this will contain a mix of vcvarsall.bat locations and dumpbin.exe locations. @@ -316,8 +297,19 @@ namespace vcpkg paths_examined.push_back(vs2015_dumpbin_exe); const fs::path vs2015_bin_dir = vs2015_vcvarsall_bat.parent_path() / "bin"; - const std::vector supported_architectures = - detect_supported_architectures(fs, vs2015_bin_dir); + std::vector supported_architectures; + if (fs.exists(vs2015_bin_dir / "vcvars32.bat")) + supported_architectures.push_back({L"x86", CPU::X86, CPU::X86}); + if (fs.exists(vs2015_bin_dir / "amd64\\vcvars64.bat")) + supported_architectures.push_back({L"x64", CPU::X64, CPU::X64}); + if (fs.exists(vs2015_bin_dir / "x86_amd64\\vcvarsx86_amd64.bat")) + supported_architectures.push_back({L"x86_amd64", CPU::X86, CPU::X64}); + if (fs.exists(vs2015_bin_dir / "x86_arm\\vcvarsx86_arm.bat")) + supported_architectures.push_back({L"x86_arm", CPU::X86, CPU::ARM}); + if (fs.exists(vs2015_bin_dir / "amd64_x86\\vcvarsamd64_x86.bat")) + supported_architectures.push_back({L"amd64_x86", CPU::X64, CPU::X86}); + if (fs.exists(vs2015_bin_dir / "amd64_arm\\vcvarsamd64_arm.bat")) + supported_architectures.push_back({L"amd64_arm", CPU::X64, CPU::ARM}); if (fs.exists(vs2015_dumpbin_exe)) { @@ -342,8 +334,19 @@ namespace vcpkg if (!fs.exists(vcvarsall_bat)) continue; // Get all supported architectures - const std::vector supported_architectures = - detect_supported_architectures(fs, vcvarsall_dir); + std::vector supported_architectures; + if (fs.exists(vcvarsall_dir / "vcvars32.bat")) + supported_architectures.push_back({L"x86", CPU::X86, CPU::X86}); + if (fs.exists(vcvarsall_dir / "vcvars64.bat")) + supported_architectures.push_back({L"amd64", CPU::X64, CPU::X64}); + if (fs.exists(vcvarsall_dir / "vcvarsx86_amd64.bat")) + supported_architectures.push_back({L"x86_amd64", CPU::X86, CPU::X64}); + if (fs.exists(vcvarsall_dir / "vcvarsx86_arm.bat")) + supported_architectures.push_back({L"x86_arm", CPU::X86, CPU::ARM}); + if (fs.exists(vcvarsall_dir / "vcvarsamd64_x86.bat")) + supported_architectures.push_back({L"amd64_x86", CPU::X64, CPU::X86}); + if (fs.exists(vcvarsall_dir / "vcvarsamd64_arm.bat")) + supported_architectures.push_back({L"amd64_arm", CPU::X64, CPU::ARM}); // Locate the "best" MSVC toolchain version const fs::path msvc_path = vc_dir / "Tools" / "MSVC"; -- cgit v1.2.3 From 53d5076f64daa08c18802fda1b7bf8e100109103 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Sun, 1 Oct 2017 13:04:10 -0700 Subject: size_t instead of int --- toolsrc/src/tests_package_spec.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/tests_package_spec.cpp b/toolsrc/src/tests_package_spec.cpp index fa201b372..a6b9d5b13 100644 --- a/toolsrc/src/tests_package_spec.cpp +++ b/toolsrc/src/tests_package_spec.cpp @@ -43,7 +43,7 @@ namespace UnitTest1 std::array features = {"", "0", "1", "", "2", "3"}; std::array specs = {&a_spec, &a_spec, &a_spec, &b_spec, &b_spec, &b_spec}; - for (int i = 0; i < features.size(); ++i) + for (size_t i = 0; i < features.size(); ++i) { Assert::AreEqual(features[i], fspecs[i].feature().c_str()); Assert::AreEqual(*specs[i], fspecs[i].spec()); -- cgit v1.2.3 From 2de9f83ff22774d0f70e3ee8158b26c494f5ea30 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Sun, 1 Oct 2017 13:22:29 -0700 Subject: Introduce Strings::case_insensitive_ascii_starts_with(); --- toolsrc/include/vcpkg_Strings.h | 2 ++ toolsrc/src/vcpkg_Strings.cpp | 10 ++++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg_Strings.h b/toolsrc/include/vcpkg_Strings.h index 61f6fab61..c44ce2b99 100644 --- a/toolsrc/include/vcpkg_Strings.h +++ b/toolsrc/include/vcpkg_Strings.h @@ -65,6 +65,8 @@ namespace vcpkg::Strings std::string ascii_to_lowercase(const std::string& input); + bool case_insensitive_ascii_starts_with(const std::string& s, const std::string& pattern); + template std::basic_string join(const CharType* delimiter, const Container& v, Transformer transformer) { diff --git a/toolsrc/src/vcpkg_Strings.cpp b/toolsrc/src/vcpkg_Strings.cpp index 5ad951399..1bd96fc12 100644 --- a/toolsrc/src/vcpkg_Strings.cpp +++ b/toolsrc/src/vcpkg_Strings.cpp @@ -110,6 +110,11 @@ namespace vcpkg::Strings return output; } + bool case_insensitive_ascii_starts_with(const std::string& s, const std::string& pattern) + { + return _strnicmp(s.c_str(), pattern.c_str(), pattern.size()) == 0; + } + void trim(std::string* s) { s->erase(std::find_if_not(s->rbegin(), s->rend(), details::isspace).base(), s->end()); @@ -136,8 +141,9 @@ namespace vcpkg::Strings std::vector split(const std::string& s, const std::string& delimiter) { std::vector output; - - if(delimiter.empty()){ + + if (delimiter.empty()) + { output.push_back(s); return output; } -- cgit v1.2.3 From b3e06443eab560d5de848f2a066e1baa477fa57b Mon Sep 17 00:00:00 2001 From: Maria Tavlaki Date: Sun, 1 Oct 2017 22:17:33 +0300 Subject: Create stub autocomplete function --- toolsrc/include/vcpkg_Commands.h | 5 +++++ toolsrc/src/commands_autocomplete.cpp | 22 ++++++++++++++++++++++ toolsrc/src/commands_available_commands.cpp | 2 +- toolsrc/vcpkglib/vcpkglib.vcxproj | 1 + toolsrc/vcpkglib/vcpkglib.vcxproj.filters | 3 +++ 5 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 toolsrc/src/commands_autocomplete.cpp (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg_Commands.h b/toolsrc/include/vcpkg_Commands.h index 590f0208c..7cfa2760e 100644 --- a/toolsrc/include/vcpkg_Commands.h +++ b/toolsrc/include/vcpkg_Commands.h @@ -194,6 +194,11 @@ namespace vcpkg::Commands void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); } + namespace Autocomplete + { + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); + } + namespace Help { void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); diff --git a/toolsrc/src/commands_autocomplete.cpp b/toolsrc/src/commands_autocomplete.cpp new file mode 100644 index 000000000..71154445d --- /dev/null +++ b/toolsrc/src/commands_autocomplete.cpp @@ -0,0 +1,22 @@ +#include "pch.h" + +#include "Paragraphs.h" +#include "SortedVector.h" +#include "vcpkg_Commands.h" +#include "vcpkg_Maps.h" +#include "vcpkg_System.h" + +namespace vcpkg::Commands::Autocomplete +{ + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) + { + static const std::string EXAMPLE = + Strings::format("The argument should be a command line to autocomplete.\n%s", + Commands::Help::create_example_string("autocomplete install z")); + + args.check_max_arg_count(1, EXAMPLE); + args.check_and_get_optional_command_arguments({}); + + Checks::exit_success(VCPKG_LINE_INFO); + } +} diff --git a/toolsrc/src/commands_available_commands.cpp b/toolsrc/src/commands_available_commands.cpp index 87cc43dca..d3280e6d7 100644 --- a/toolsrc/src/commands_available_commands.cpp +++ b/toolsrc/src/commands_available_commands.cpp @@ -34,7 +34,7 @@ namespace vcpkg::Commands {"import", &Import::perform_and_exit}, {"cache", &Cache::perform_and_exit}, {"portsdiff", &PortsDiff::perform_and_exit}, - }; + {"autocomplete", &Autocomplete::perform_and_exit}}; return t; } diff --git a/toolsrc/vcpkglib/vcpkglib.vcxproj b/toolsrc/vcpkglib/vcpkglib.vcxproj index edecd7720..0c3c7105d 100644 --- a/toolsrc/vcpkglib/vcpkglib.vcxproj +++ b/toolsrc/vcpkglib/vcpkglib.vcxproj @@ -181,6 +181,7 @@ + diff --git a/toolsrc/vcpkglib/vcpkglib.vcxproj.filters b/toolsrc/vcpkglib/vcpkglib.vcxproj.filters index 2fbf3d929..668aa48d6 100644 --- a/toolsrc/vcpkglib/vcpkglib.vcxproj.filters +++ b/toolsrc/vcpkglib/vcpkglib.vcxproj.filters @@ -180,6 +180,9 @@ Source Files + + Source Files + -- cgit v1.2.3 From fe89e72e9565f0515834b925f015fe19324c38da Mon Sep 17 00:00:00 2001 From: Maria Tavlaki Date: Sun, 1 Oct 2017 23:26:36 +0300 Subject: Autocomplete: handle arguments --- toolsrc/src/commands_autocomplete.cpp | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/commands_autocomplete.cpp b/toolsrc/src/commands_autocomplete.cpp index 71154445d..a67113aff 100644 --- a/toolsrc/src/commands_autocomplete.cpp +++ b/toolsrc/src/commands_autocomplete.cpp @@ -14,9 +14,34 @@ namespace vcpkg::Commands::Autocomplete Strings::format("The argument should be a command line to autocomplete.\n%s", Commands::Help::create_example_string("autocomplete install z")); - args.check_max_arg_count(1, EXAMPLE); + args.check_min_arg_count(1, EXAMPLE); + args.check_max_arg_count(2, EXAMPLE); args.check_and_get_optional_command_arguments({}); + const std::string requested_command = args.command_arguments.at(0); + const std::string start_with = + args.command_arguments.size() > 1 ? args.command_arguments.at(1) : Strings::EMPTY; + + auto sources_and_errors = Paragraphs::try_load_all_ports(paths.get_filesystem(), paths.ports); + auto& source_paragraphs = sources_and_errors.paragraphs; + + const auto& istartswith = Strings::case_insensitive_ascii_starts_with; + + std::vector results; + for (const auto& source_control_file : source_paragraphs) + { + auto&& sp = *source_control_file->core_paragraph; + + if (istartswith(sp.name, start_with)) + { + results.push_back(sp.name); + } + } + + System::println(Strings::join(" ", results)); + + auto all_ports = Paragraphs::try_load_all_ports(paths.get_filesystem(), paths.ports); + Checks::exit_success(VCPKG_LINE_INFO); } } -- cgit v1.2.3 From 7c2239f980197096a13e8fb4b96297b08616eb78 Mon Sep 17 00:00:00 2001 From: Maria Tavlaki Date: Mon, 2 Oct 2017 00:03:39 +0300 Subject: Autocomplete: check if first argument is "install" --- toolsrc/src/commands_autocomplete.cpp | 37 ++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 16 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/commands_autocomplete.cpp b/toolsrc/src/commands_autocomplete.cpp index a67113aff..013cea320 100644 --- a/toolsrc/src/commands_autocomplete.cpp +++ b/toolsrc/src/commands_autocomplete.cpp @@ -8,6 +8,23 @@ namespace vcpkg::Commands::Autocomplete { + std::vector autocomplete_install( + const std::vector>& source_paragraphs, const std::string& start_with) + { + std::vector results; + const auto& istartswith = Strings::case_insensitive_ascii_starts_with; + + for (const auto& source_control_file : source_paragraphs) + { + auto&& sp = *source_control_file->core_paragraph; + + if (istartswith(sp.name, start_with)) + { + results.push_back(sp.name); + } + } + return results; + } void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { static const std::string EXAMPLE = @@ -21,27 +38,15 @@ namespace vcpkg::Commands::Autocomplete const std::string requested_command = args.command_arguments.at(0); const std::string start_with = args.command_arguments.size() > 1 ? args.command_arguments.at(1) : Strings::EMPTY; - - auto sources_and_errors = Paragraphs::try_load_all_ports(paths.get_filesystem(), paths.ports); - auto& source_paragraphs = sources_and_errors.paragraphs; - - const auto& istartswith = Strings::case_insensitive_ascii_starts_with; - std::vector results; - for (const auto& source_control_file : source_paragraphs) + if (requested_command == "install") { - auto&& sp = *source_control_file->core_paragraph; + auto sources_and_errors = Paragraphs::try_load_all_ports(paths.get_filesystem(), paths.ports); + auto& source_paragraphs = sources_and_errors.paragraphs; - if (istartswith(sp.name, start_with)) - { - results.push_back(sp.name); - } + results = autocomplete_install(source_paragraphs, start_with); } - System::println(Strings::join(" ", results)); - - auto all_ports = Paragraphs::try_load_all_ports(paths.get_filesystem(), paths.ports); - Checks::exit_success(VCPKG_LINE_INFO); } } -- cgit v1.2.3 From 016c53e231f353bdfa35f8e265b281e8d56031ed Mon Sep 17 00:00:00 2001 From: Maria Tavlaki Date: Mon, 2 Oct 2017 00:38:53 +0300 Subject: Autocomplete: remove --- toolsrc/src/commands_autocomplete.cpp | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'toolsrc') diff --git a/toolsrc/src/commands_autocomplete.cpp b/toolsrc/src/commands_autocomplete.cpp index 013cea320..3963f904b 100644 --- a/toolsrc/src/commands_autocomplete.cpp +++ b/toolsrc/src/commands_autocomplete.cpp @@ -5,6 +5,7 @@ #include "vcpkg_Commands.h" #include "vcpkg_Maps.h" #include "vcpkg_System.h" +#include "vcpkglib.h" namespace vcpkg::Commands::Autocomplete { @@ -25,6 +26,25 @@ namespace vcpkg::Commands::Autocomplete } return results; } + + std::vector autocomplete_remove(std::vector installed_packages, + const std::string& start_with) + { + std::vector results; + const auto& istartswith = Strings::case_insensitive_ascii_starts_with; + + for (const auto& installed_package : installed_packages) + { + auto sp = installed_package->package.displayname(); + + if (istartswith(sp, start_with)) + { + results.push_back(sp); + } + } + return results; + } + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { static const std::string EXAMPLE = @@ -46,6 +66,13 @@ namespace vcpkg::Commands::Autocomplete results = autocomplete_install(source_paragraphs, start_with); } + else if (requested_command == "remove") + { + const StatusParagraphs status_db = database_load_check(paths); + std::vector installed_packages = get_installed_ports(status_db); + results = autocomplete_remove(installed_packages, start_with); + } + System::println(Strings::join(" ", results)); Checks::exit_success(VCPKG_LINE_INFO); } -- cgit v1.2.3 From 20d911a91508c16bd01272ae94a3ca239a4d984e Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Mon, 2 Oct 2017 13:57:55 -0700 Subject: [vcpkg] Fix use of UNICODE-sensitive Windows APIs --- toolsrc/src/commands_integrate.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/commands_integrate.cpp b/toolsrc/src/commands_integrate.cpp index 1bf26910c..fd2f11294 100644 --- a/toolsrc/src/commands_integrate.cpp +++ b/toolsrc/src/commands_integrate.cpp @@ -113,19 +113,20 @@ namespace vcpkg::Commands::Integrate static ElevationPromptChoice elevated_cmd_execute(const std::string& param) { - SHELLEXECUTEINFO sh_ex_info = {0}; + SHELLEXECUTEINFOW sh_ex_info = {0}; sh_ex_info.cbSize = sizeof(sh_ex_info); sh_ex_info.fMask = SEE_MASK_NOCLOSEPROCESS; sh_ex_info.hwnd = nullptr; - sh_ex_info.lpVerb = "runas"; - sh_ex_info.lpFile = "cmd"; // Application to start + sh_ex_info.lpVerb = L"runas"; + sh_ex_info.lpFile = L"cmd"; // Application to start - sh_ex_info.lpParameters = param.c_str(); // Additional parameters + auto wparam = Strings::to_utf16(param); + sh_ex_info.lpParameters = wparam.c_str(); // Additional parameters sh_ex_info.lpDirectory = nullptr; sh_ex_info.nShow = SW_HIDE; sh_ex_info.hInstApp = nullptr; - if (!ShellExecuteExA(&sh_ex_info)) + if (!ShellExecuteExW(&sh_ex_info)) { return ElevationPromptChoice::NO; } -- cgit v1.2.3 From bdbf00c7ab6f7dc5ca096391c913a0af5e291d19 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 2 Oct 2017 14:44:41 -0700 Subject: Add message when downloading cmake/git/nuget --- toolsrc/src/VcpkgPaths.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp index 4634a87c0..f227f9114 100644 --- a/toolsrc/src/VcpkgPaths.cpp +++ b/toolsrc/src/VcpkgPaths.cpp @@ -67,14 +67,18 @@ namespace vcpkg const fs::path& expected_downloaded_path, const std::array& version) { + const std::string version_as_string = Strings::format("%d.%d.%d", version[0], version[1], version[2]); + System::println("A suitable version of %s was not found (required v%s). Downloading portable %s v%s...", + Strings::to_utf8(tool_name), + version_as_string, + Strings::to_utf8(tool_name), + version_as_string); const fs::path script = scripts_folder / "fetchDependency.ps1"; const auto install_cmd = System::create_powershell_script_cmd(script, Strings::wformat(L"-Dependency %s", tool_name)); const System::ExitCodeAndOutput rc = System::cmd_execute_and_capture_output(install_cmd); if (rc.exit_code) { - const std::string version_as_string = Strings::format("%d.%d.%d", version[0], version[1], version[2]); - System::println(System::Color::error, "Launching powershell failed or was denied when trying to fetch %s version %s.\n" "(No sufficient installed version was found)", -- cgit v1.2.3 From d25a072c76ff81934813f20116788140621619ba Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 2 Oct 2017 14:57:52 -0700 Subject: Show warning instead of failing if port cannot be parsed --- toolsrc/src/Paragraphs.cpp | 18 +++++++++++++++--- toolsrc/src/commands_install.cpp | 4 ++-- toolsrc/src/commands_search.cpp | 21 +-------------------- 3 files changed, 18 insertions(+), 25 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/Paragraphs.cpp b/toolsrc/src/Paragraphs.cpp index a7dee4fd3..6a6f191df 100644 --- a/toolsrc/src/Paragraphs.cpp +++ b/toolsrc/src/Paragraphs.cpp @@ -254,7 +254,7 @@ namespace vcpkg::Paragraphs for (auto&& path : fs.get_files_non_recursive(ports_dir)) { auto maybe_spgh = try_load_port(fs, path); - if (auto spgh = maybe_spgh.get()) + if (const auto spgh = maybe_spgh.get()) { ret.paragraphs.emplace_back(std::move(*spgh)); } @@ -272,8 +272,20 @@ namespace vcpkg::Paragraphs auto results = try_load_all_ports(fs, ports_dir); if (!results.errors.empty()) { - print_error_message(results.errors); - Checks::exit_fail(VCPKG_LINE_INFO); + if (GlobalState::debugging) + { + print_error_message(results.errors); + } + else + { + for (auto&& error : results.errors) + { + System::println( + System::Color::warning, "Warning: an error occurred while parsing '%s'", error->name); + } + System::println(System::Color::warning, + "Use '--debug' to get more information about the parse failures.\n"); + } } return std::move(results.paragraphs); } diff --git a/toolsrc/src/commands_install.cpp b/toolsrc/src/commands_install.cpp index aca25996e..d815332fe 100644 --- a/toolsrc/src/commands_install.cpp +++ b/toolsrc/src/commands_install.cpp @@ -568,8 +568,8 @@ namespace vcpkg::Commands::Install if (GlobalState::feature_packages) { std::unordered_map scf_map; - auto all_ports = Paragraphs::try_load_all_ports(paths.get_filesystem(), paths.ports); - for (auto&& port : all_ports.paragraphs) + auto all_ports = Paragraphs::load_all_ports(paths.get_filesystem(), paths.ports); + for (auto&& port : all_ports) { scf_map[port->core_paragraph->name] = std::move(*port); } diff --git a/toolsrc/src/commands_search.cpp b/toolsrc/src/commands_search.cpp index 1ccec9fbe..d35a546c4 100644 --- a/toolsrc/src/commands_search.cpp +++ b/toolsrc/src/commands_search.cpp @@ -87,27 +87,8 @@ namespace vcpkg::Commands::Search const std::unordered_set options = args.check_and_get_optional_command_arguments({OPTION_GRAPH, OPTION_FULLDESC}); - auto sources_and_errors = Paragraphs::try_load_all_ports(paths.get_filesystem(), paths.ports); + auto source_paragraphs = Paragraphs::load_all_ports(paths.get_filesystem(), paths.ports); - if (!sources_and_errors.errors.empty()) - { - if (GlobalState::debugging) - { - print_error_message(sources_and_errors.errors); - } - else - { - for (auto&& error : sources_and_errors.errors) - { - System::println( - System::Color::warning, "Warning: an error occurred while parsing '%s'", error->name); - } - System::println(System::Color::warning, - "Use '--debug' to get more information about the parse failures.\n"); - } - } - - auto& source_paragraphs = sources_and_errors.paragraphs; if (options.find(OPTION_GRAPH) != options.cend()) { const std::string graph_as_string = create_graph_as_string(source_paragraphs); -- cgit v1.2.3 From 4c4e6c7c7af52732de07ca247cf62e2a3c5d2f25 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 2 Oct 2017 16:00:45 -0700 Subject: Extract local variable --- toolsrc/src/VcpkgPaths.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp index f227f9114..d491cb7fb 100644 --- a/toolsrc/src/VcpkgPaths.cpp +++ b/toolsrc/src/VcpkgPaths.cpp @@ -67,11 +67,12 @@ namespace vcpkg const fs::path& expected_downloaded_path, const std::array& version) { + const std::string tool_name_utf8 = Strings::to_utf8(tool_name); const std::string version_as_string = Strings::format("%d.%d.%d", version[0], version[1], version[2]); System::println("A suitable version of %s was not found (required v%s). Downloading portable %s v%s...", - Strings::to_utf8(tool_name), + tool_name_utf8, version_as_string, - Strings::to_utf8(tool_name), + tool_name_utf8, version_as_string); const fs::path script = scripts_folder / "fetchDependency.ps1"; const auto install_cmd = @@ -82,7 +83,7 @@ namespace vcpkg System::println(System::Color::error, "Launching powershell failed or was denied when trying to fetch %s version %s.\n" "(No sufficient installed version was found)", - Strings::to_utf8(tool_name), + tool_name_utf8, version_as_string); { auto locked_metrics = Metrics::g_metrics.lock(); -- cgit v1.2.3 From ca692e52cee55da2f9d65d66e5f3997f3a335743 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 2 Oct 2017 16:40:18 -0700 Subject: Replace deprecated std::codecvt/std::wstring_convert. Fixes building with v141 --- toolsrc/src/vcpkg_Strings.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg_Strings.cpp b/toolsrc/src/vcpkg_Strings.cpp index 1bd96fc12..964ed73d0 100644 --- a/toolsrc/src/vcpkg_Strings.cpp +++ b/toolsrc/src/vcpkg_Strings.cpp @@ -73,14 +73,20 @@ namespace vcpkg::Strings { std::wstring to_utf16(const CStringView s) { - std::wstring_convert, wchar_t> conversion; - return conversion.from_bytes(s); + const size_t size = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, nullptr, 0); + std::wstring output; + output.resize(size - 1); + MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, output.data(), size - 1); + return output; } std::string to_utf8(const CWStringView w) { - std::wstring_convert, wchar_t> conversion; - return conversion.to_bytes(w); + const size_t size = WideCharToMultiByte(CP_UTF8, 0, w.c_str(), -1, nullptr, 0, nullptr, nullptr); + std::string output; + output.resize(size - 1); + WideCharToMultiByte(CP_UTF8, 0, w.c_str(), -1, output.data(), size - 1, nullptr, nullptr); + return output; } std::string::const_iterator case_insensitive_ascii_find(const std::string& s, const std::string& pattern) -- cgit v1.2.3 From f72cf87ab21c1b6966c09ec3e7fd5d7f9052ea0a Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 2 Oct 2017 16:41:52 -0700 Subject: Change size_t to int (which is the actual return type) --- toolsrc/src/vcpkg_Strings.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg_Strings.cpp b/toolsrc/src/vcpkg_Strings.cpp index 964ed73d0..07147862f 100644 --- a/toolsrc/src/vcpkg_Strings.cpp +++ b/toolsrc/src/vcpkg_Strings.cpp @@ -73,7 +73,7 @@ namespace vcpkg::Strings { std::wstring to_utf16(const CStringView s) { - const size_t size = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, nullptr, 0); + const int size = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, nullptr, 0); std::wstring output; output.resize(size - 1); MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, output.data(), size - 1); @@ -82,7 +82,7 @@ namespace vcpkg::Strings std::string to_utf8(const CWStringView w) { - const size_t size = WideCharToMultiByte(CP_UTF8, 0, w.c_str(), -1, nullptr, 0, nullptr, nullptr); + const int size = WideCharToMultiByte(CP_UTF8, 0, w.c_str(), -1, nullptr, 0, nullptr, nullptr); std::string output; output.resize(size - 1); WideCharToMultiByte(CP_UTF8, 0, w.c_str(), -1, output.data(), size - 1, nullptr, nullptr); -- cgit v1.2.3 From e25a31eca8550780ce96586ef27063728441b2e2 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 2 Oct 2017 16:55:06 -0700 Subject: Suppress 4768 warning from shlobj.h --- toolsrc/include/pch.h | 7 +++++-- toolsrc/src/vcpkg.cpp | 3 +++ 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/pch.h b/toolsrc/include/pch.h index 770bcf07a..0f34063f8 100644 --- a/toolsrc/include/pch.h +++ b/toolsrc/include/pch.h @@ -2,7 +2,7 @@ #define NOMINMAX #define WIN32_LEAN_AND_MEAN - +#pragma warning(suppress : 4768) #include #include @@ -28,7 +28,10 @@ #include #include #include -#include +#pragma warning(push) +#pragma warning(disable : 4768) +#include +#pragma warning(pop) #include #include #include diff --git a/toolsrc/src/vcpkg.cpp b/toolsrc/src/vcpkg.cpp index f4300a73c..706c641fb 100644 --- a/toolsrc/src/vcpkg.cpp +++ b/toolsrc/src/vcpkg.cpp @@ -11,7 +11,10 @@ #include "vcpkg_Strings.h" #include "vcpkg_System.h" #include "vcpkglib.h" +#pragma warning(push) +#pragma warning(disable : 4768) #include +#pragma warning(pop) #include #include #include -- cgit v1.2.3 From 3838d5880470fdc884f035ed3d1c67d3bdd1e16e Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Tue, 3 Oct 2017 15:51:04 -0700 Subject: [vcpkg] Add more operator== to CStringView. Uppercase Span to follow naming convention. --- toolsrc/include/CStringView.h | 44 ++++++++++++++++++++++++++++++++++++++- toolsrc/include/SourceParagraph.h | 2 +- toolsrc/include/Span.h | 28 ++++++++++++++++++------- toolsrc/src/PostBuildLint.cpp | 4 ++-- toolsrc/src/SourceParagraph.cpp | 4 ++-- toolsrc/src/VcpkgPaths.cpp | 6 +++--- toolsrc/src/vcpkg_Build.cpp | 2 +- toolsrc/src/vcpkg_Strings.cpp | 2 +- toolsrc/src/vcpkg_System.cpp | 13 ++++++------ 9 files changed, 80 insertions(+), 25 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/CStringView.h b/toolsrc/include/CStringView.h index 282caad3a..c1810b4f1 100644 --- a/toolsrc/include/CStringView.h +++ b/toolsrc/include/CStringView.h @@ -11,13 +11,36 @@ namespace vcpkg constexpr BasicCStringView(const BasicCStringView&) = default; BasicCStringView(const std::basic_string& str) : cstr(str.c_str()) {} - constexpr operator const CharType*() const { return cstr; } constexpr const CharType* c_str() const { return cstr; } private: const CharType* cstr; }; + namespace details + { + inline bool vcpkg_strcmp(const char* l, const char* r) { return strcmp(l, r) == 0; } + inline bool vcpkg_strcmp(const wchar_t* l, const wchar_t* r) { return wcscmp(l, r) == 0; } + } + + template + bool operator==(const BasicCStringView& l, const BasicCStringView& r) + { + return details::vcpkg_strcmp(l.c_str(), r.c_str()); + } + + template + bool operator==(const CharType* l, const BasicCStringView& r) + { + return details::vcpkg_strcmp(l, r.c_str()); + } + + template + bool operator==(const BasicCStringView& r, const CharType* l) + { + return details::vcpkg_strcmp(l, r.c_str()); + } + template bool operator==(const std::basic_string& l, const BasicCStringView& r) { @@ -30,6 +53,25 @@ namespace vcpkg return l == r.c_str(); } + // notequals + template + bool operator!=(const BasicCStringView& l, const BasicCStringView& r) + { + return !details::vcpkg_strcmp(l.c_str(), r.c_str()); + } + + template + bool operator!=(const CharType* l, const BasicCStringView& r) + { + return !details::vcpkg_strcmp(l, r.c_str()); + } + + template + bool operator!=(const BasicCStringView& r, const CharType* l) + { + return !details::vcpkg_strcmp(l, r.c_str()); + } + template bool operator!=(const BasicCStringView& r, const std::basic_string& l) { diff --git a/toolsrc/include/SourceParagraph.h b/toolsrc/include/SourceParagraph.h index 1357b3769..ccf9faf4f 100644 --- a/toolsrc/include/SourceParagraph.h +++ b/toolsrc/include/SourceParagraph.h @@ -57,7 +57,7 @@ namespace vcpkg std::vector> feature_paragraphs; }; - void print_error_message(span> error_info_list); + void print_error_message(Span> error_info_list); inline void print_error_message(const std::unique_ptr& error_info_list) { return print_error_message({&error_info_list, 1}); diff --git a/toolsrc/include/Span.h b/toolsrc/include/Span.h index b16af2cef..b2c9acdbc 100644 --- a/toolsrc/include/Span.h +++ b/toolsrc/include/Span.h @@ -5,7 +5,7 @@ #include template -struct span +struct Span { public: using element_type = T; @@ -13,18 +13,18 @@ public: using reference = T&; using iterator = T*; - constexpr span() noexcept : m_ptr(nullptr), m_count(0) {} - constexpr span(std::nullptr_t) noexcept : span() {} - constexpr span(T* ptr, size_t count) noexcept : m_ptr(ptr), m_count(count) {} - constexpr span(T* ptr_begin, T* ptr_end) noexcept : m_ptr(ptr_begin), m_count(ptr_end - ptr_begin) {} + constexpr Span() noexcept : m_ptr(nullptr), m_count(0) {} + constexpr Span(std::nullptr_t) noexcept : Span() {} + constexpr Span(T* ptr, size_t count) noexcept : m_ptr(ptr), m_count(count) {} + constexpr Span(T* ptr_begin, T* ptr_end) noexcept : m_ptr(ptr_begin), m_count(ptr_end - ptr_begin) {} template - constexpr span(T (&arr)[N]) noexcept : span(arr, N) + constexpr Span(T (&arr)[N]) noexcept : Span(arr, N) { } - span(std::vector& v) noexcept : span(v.data(), v.size()) {} - span(const std::vector>& v) noexcept : span(v.data(), v.size()) {} + Span(std::vector& v) noexcept : Span(v.data(), v.size()) {} + Span(const std::vector>& v) noexcept : Span(v.data(), v.size()) {} constexpr iterator begin() const { return m_ptr; } constexpr iterator end() const { return m_ptr + m_count; } @@ -36,3 +36,15 @@ private: pointer m_ptr; size_t m_count; }; + +template +Span make_span(std::vector& v) +{ + return {v.data(), v.size()}; +} + +template +Span make_span(const std::vector& v) +{ + return {v.data(), v.size()}; +} diff --git a/toolsrc/src/PostBuildLint.cpp b/toolsrc/src/PostBuildLint.cpp index 1fd48d3ec..416d4a636 100644 --- a/toolsrc/src/PostBuildLint.cpp +++ b/toolsrc/src/PostBuildLint.cpp @@ -38,7 +38,7 @@ namespace vcpkg::PostBuildLint } }; - const std::vector& get_outdated_dynamic_crts() + Span get_outdated_dynamic_crts(CStringView toolset) { static const std::vector V_NO_MSVCRT = { {"msvcp100.dll", R"(msvcp100\.dll)"}, @@ -662,7 +662,7 @@ namespace vcpkg::PostBuildLint "Running command:\n %s\n failed", Strings::to_utf8(cmd_line)); - for (const OutdatedDynamicCrt& outdated_crt : get_outdated_dynamic_crts()) + for (const OutdatedDynamicCrt& outdated_crt : get_outdated_dynamic_crts("v141")) { if (std::regex_search(ec_data.output.cbegin(), ec_data.output.cend(), outdated_crt.regex)) { diff --git a/toolsrc/src/SourceParagraph.cpp b/toolsrc/src/SourceParagraph.cpp index 171689ce7..0f1a38d19 100644 --- a/toolsrc/src/SourceParagraph.cpp +++ b/toolsrc/src/SourceParagraph.cpp @@ -25,7 +25,7 @@ namespace vcpkg static const std::string VERSION = "Version"; } - static span get_list_of_valid_fields() + static Span get_list_of_valid_fields() { static const std::string valid_fields[] = { Fields::SOURCE, @@ -38,7 +38,7 @@ namespace vcpkg return valid_fields; } - void print_error_message(span> error_info_list) + void print_error_message(Span> error_info_list) { Checks::check_exit(VCPKG_LINE_INFO, error_info_list.size() > 0); diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp index d491cb7fb..cb00183fd 100644 --- a/toolsrc/src/VcpkgPaths.cpp +++ b/toolsrc/src/VcpkgPaths.cpp @@ -10,9 +10,9 @@ namespace vcpkg { - // Intentionally wstring so we can easily use operator== with CWStringView. - static const std::wstring V_140 = L"v140"; - static const std::wstring V_141 = L"v141"; + static constexpr CWStringView V_120 = L"v120"; + static constexpr CWStringView V_140 = L"v140"; + static constexpr CWStringView V_141 = L"v141"; static bool exists_and_has_equal_or_greater_version(const std::wstring& version_cmd, const std::array& expected_version) diff --git a/toolsrc/src/vcpkg_Build.cpp b/toolsrc/src/vcpkg_Build.cpp index 5ac13c6c6..853f84998 100644 --- a/toolsrc/src/vcpkg_Build.cpp +++ b/toolsrc/src/vcpkg_Build.cpp @@ -165,7 +165,7 @@ namespace vcpkg::Build {L"PORT", config.src.name}, {L"CURRENT_PORT_DIR", config.port_dir / "/."}, {L"TARGET_TRIPLET", triplet.canonical_name()}, - {L"VCPKG_PLATFORM_TOOLSET", toolset.version}, + {L"VCPKG_PLATFORM_TOOLSET", toolset.version.c_str()}, {L"VCPKG_USE_HEAD_VERSION", to_bool(config.build_package_options.use_head_version) ? L"1" : L"0"}, {L"_VCPKG_NO_DOWNLOADS", !to_bool(config.build_package_options.allow_downloads) ? L"1" : L"0"}, {L"GIT", git_exe_path}, diff --git a/toolsrc/src/vcpkg_Strings.cpp b/toolsrc/src/vcpkg_Strings.cpp index 07147862f..21df2c309 100644 --- a/toolsrc/src/vcpkg_Strings.cpp +++ b/toolsrc/src/vcpkg_Strings.cpp @@ -106,7 +106,7 @@ namespace vcpkg::Strings int case_insensitive_ascii_compare(const CStringView left, const CStringView right) { - return _stricmp(left, right); + return _stricmp(left.c_str(), right.c_str()); } std::string ascii_to_lowercase(const std::string& input) diff --git a/toolsrc/src/vcpkg_System.cpp b/toolsrc/src/vcpkg_System.cpp index 40e335117..4d2e88b73 100644 --- a/toolsrc/src/vcpkg_System.cpp +++ b/toolsrc/src/vcpkg_System.cpp @@ -226,7 +226,7 @@ namespace vcpkg::System void println() { println(Strings::EMPTY); } - void print(const CStringView message) { fputs(message, stdout); } + void print(const CStringView message) { fputs(message.c_str(), stdout); } void println(const CStringView message) { @@ -255,13 +255,13 @@ namespace vcpkg::System Optional get_environment_variable(const CWStringView varname) noexcept { - const auto sz = GetEnvironmentVariableW(varname, nullptr, 0); + const auto sz = GetEnvironmentVariableW(varname.c_str(), nullptr, 0); if (sz == 0) return nullopt; std::wstring ret(sz, L'\0'); Checks::check_exit(VCPKG_LINE_INFO, MAXDWORD >= ret.size()); - const auto sz2 = GetEnvironmentVariableW(varname, ret.data(), static_cast(ret.size())); + const auto sz2 = GetEnvironmentVariableW(varname.c_str(), ret.data(), static_cast(ret.size())); Checks::check_exit(VCPKG_LINE_INFO, sz2 + 1 == sz); ret.pop_back(); return ret; @@ -275,19 +275,20 @@ namespace vcpkg::System Optional get_registry_string(HKEY base, const CWStringView sub_key, const CWStringView valuename) { HKEY k = nullptr; - const LSTATUS ec = RegOpenKeyExW(base, sub_key, NULL, KEY_READ, &k); + const LSTATUS ec = RegOpenKeyExW(base, sub_key.c_str(), NULL, KEY_READ, &k); if (ec != ERROR_SUCCESS) return nullopt; DWORD dw_buffer_size = 0; DWORD dw_type = 0; - auto rc = RegQueryValueExW(k, valuename, nullptr, &dw_type, nullptr, &dw_buffer_size); + auto rc = RegQueryValueExW(k, valuename.c_str(), nullptr, &dw_type, nullptr, &dw_buffer_size); if (rc != ERROR_SUCCESS || !is_string_keytype(dw_type) || dw_buffer_size == 0 || dw_buffer_size % sizeof(wchar_t) != 0) return nullopt; std::wstring ret; ret.resize(dw_buffer_size / sizeof(wchar_t)); - rc = RegQueryValueExW(k, valuename, nullptr, &dw_type, reinterpret_cast(ret.data()), &dw_buffer_size); + rc = RegQueryValueExW( + k, valuename.c_str(), nullptr, &dw_type, reinterpret_cast(ret.data()), &dw_buffer_size); if (rc != ERROR_SUCCESS || !is_string_keytype(dw_type) || dw_buffer_size != sizeof(wchar_t) * ret.size()) return nullopt; -- cgit v1.2.3 From 63753e86a60ef508760d9f4dd98b7f2336cd089c Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Tue, 3 Oct 2017 16:00:23 -0700 Subject: [vcpkg] Split toolset searches based on triplet's specification (don't pick v120 if it's blank). --- toolsrc/include/VcpkgPaths.h | 1 + toolsrc/src/PostBuildLint.cpp | 31 +++++++++++++------ toolsrc/src/VcpkgPaths.cpp | 71 ++++++++++++++++++++++++++++--------------- 3 files changed, 68 insertions(+), 35 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/VcpkgPaths.h b/toolsrc/include/VcpkgPaths.h index 9914c6f35..9f55dc5ac 100644 --- a/toolsrc/include/VcpkgPaths.h +++ b/toolsrc/include/VcpkgPaths.h @@ -73,5 +73,6 @@ namespace vcpkg Lazy nuget_exe; Lazy> toolsets; Lazy> toolsets_vs2017_v140; + Lazy> toolsets_vs2013; }; } diff --git a/toolsrc/src/PostBuildLint.cpp b/toolsrc/src/PostBuildLint.cpp index 69008fab3..58d6f987b 100644 --- a/toolsrc/src/PostBuildLint.cpp +++ b/toolsrc/src/PostBuildLint.cpp @@ -40,26 +40,36 @@ namespace vcpkg::PostBuildLint Span get_outdated_dynamic_crts(CStringView toolset) { - static const std::vector V_NO_MSVCRT = { + static const std::vector V_NO_120 = { {"msvcp100.dll", R"(msvcp100\.dll)"}, {"msvcp100d.dll", R"(msvcp100d\.dll)"}, {"msvcp110.dll", R"(msvcp110\.dll)"}, {"msvcp110_win.dll", R"(msvcp110_win\.dll)"}, - //{"msvcp120.dll", R"(msvcp120\.dll)"}, - //{"msvcp120_clr0400.dll", R"(msvcp120_clr0400\.dll)"}, {"msvcp60.dll", R"(msvcp60\.dll)"}, {"msvcp60.dll", R"(msvcp60\.dll)"}, + {"msvcrt.dll", R"(msvcrt\.dll)"}, {"msvcr100.dll", R"(msvcr100\.dll)"}, {"msvcr100d.dll", R"(msvcr100d\.dll)"}, {"msvcr100_clr0400.dll", R"(msvcr100_clr0400\.dll)"}, {"msvcr110.dll", R"(msvcr110\.dll)"}, - //{"msvcr120.dll", R"(msvcr120\.dll)"}, - //{"msvcr120_clr0400.dll", R"(msvcr120_clr0400\.dll)"}, {"msvcrt20.dll", R"(msvcrt20\.dll)"}, - {"msvcrt40.dll", R"(msvcrt40\.dll)"}}; + {"msvcrt40.dll", R"(msvcrt40\.dll)"}, + }; - return V_NO_MSVCRT; + static const std::vector V = [&]() { + auto ret = V_NO_120; + ret.push_back({"msvcp120.dll", R"(msvcp120\.dll)"}); + ret.push_back({"msvcp120_clr0400.dll", R"(msvcp120_clr0400\.dll)"}); + ret.push_back({"msvcr120.dll", R"(msvcr120\.dll)"}); + ret.push_back({"msvcr120_clr0400.dll", R"(msvcr120_clr0400\.dll)"}); + return ret; + }(); + + if (toolset == "v120") + return V_NO_120; + else + return V; } static LintStatus check_for_files_in_include_directory(const Files::Filesystem& fs, @@ -646,7 +656,8 @@ namespace vcpkg::PostBuildLint static LintStatus check_outdated_crt_linkage_of_dlls(const std::vector& dlls, const fs::path dumpbin_exe, - const BuildInfo& build_info) + const BuildInfo& build_info, + const PreBuildInfo& pre_build_info) { if (build_info.policies.is_enabled(BuildPolicy::ALLOW_OBSOLETE_MSVCRT)) return LintStatus::SUCCESS; @@ -662,7 +673,7 @@ namespace vcpkg::PostBuildLint "Running command:\n %s\n failed", Strings::to_utf8(cmd_line)); - for (const OutdatedDynamicCrt& outdated_crt : get_outdated_dynamic_crts("v141")) + for (const OutdatedDynamicCrt& outdated_crt : get_outdated_dynamic_crts(pre_build_info.platform_toolset)) { if (std::regex_search(ec_data.output.cbegin(), ec_data.output.cend(), outdated_crt.regex)) { @@ -788,7 +799,7 @@ namespace vcpkg::PostBuildLint error_count += check_uwp_bit_of_dlls(pre_build_info.cmake_system_name, dlls, toolset.dumpbin); error_count += check_dll_architecture(pre_build_info.target_architecture, dlls); - error_count += check_outdated_crt_linkage_of_dlls(dlls, toolset.dumpbin, build_info); + error_count += check_outdated_crt_linkage_of_dlls(dlls, toolset.dumpbin, build_info, pre_build_info); break; } case Build::LinkageType::STATIC: diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp index 651d4d834..e8eb4f01c 100644 --- a/toolsrc/src/VcpkgPaths.cpp +++ b/toolsrc/src/VcpkgPaths.cpp @@ -277,48 +277,38 @@ namespace vcpkg return nullopt; } - - static Optional get_vs2013_installation_instance() - { - const Optional vs2013_cmntools_optional = System::get_environment_variable(L"VS120COMNTOOLS"); - if (const auto v = vs2013_cmntools_optional.get()) - { - const fs::path vs2013_cmntools = fs::path(*v).parent_path(); // The call to parent_path() is needed because - // the env variable has a trailing backslash - return vs2013_cmntools.parent_path().parent_path(); - } - return nullopt; - } - - static std::vector find_toolset_instances(const VcpkgPaths& paths) + static std::vector find_v120_toolset_instances(const Files::Filesystem& fs) { using CPU = System::CPUArchitecture; - const auto& fs = paths.get_filesystem(); - // Note: this will contain a mix of vcvarsall.bat locations and dumpbin.exe locations. std::vector paths_examined; std::vector found_toolsets; // VS2013 - const Optional vs_2013_installation_instance = get_vs2013_installation_instance(); - if (const auto v = vs_2013_installation_instance.get()) + const Optional vs2013_cmntools_optional = System::get_environment_variable(L"VS120COMNTOOLS"); + if (const auto vs120comntools = vs2013_cmntools_optional.get()) { - const fs::path vs2013_vcvarsall_bat = *v / "VC" / "vcvarsall.bat"; + const fs::path vs2013_cmntools = + fs::path(*vs120comntools).parent_path(); // The call to parent_path() is needed because + // the env variable has a trailing backslash + auto v = vs2013_cmntools.parent_path().parent_path(); + + const fs::path vs2013_vcvarsall_bat = v / "VC" / "vcvarsall.bat"; paths_examined.push_back(vs2013_vcvarsall_bat); if (fs.exists(vs2013_vcvarsall_bat)) { - const fs::path vs2013_dumpbin_exe = *v / "VC" / "bin" / "dumpbin.exe"; + const fs::path vs2013_dumpbin_exe = v / "VC" / "bin" / "dumpbin.exe"; paths_examined.push_back(vs2013_dumpbin_exe); const fs::path vs2013_bin_dir = vs2013_vcvarsall_bat.parent_path() / "bin"; std::vector supported_architectures; if (fs.exists(vs2013_bin_dir / "vcvars32.bat")) supported_architectures.push_back({L"x86", CPU::X86, CPU::X86}); - if (fs.exists(3 / "amd64\\vcvars64.bat")) + if (fs.exists(vs2013_bin_dir / "amd64\\vcvars64.bat")) supported_architectures.push_back({L"x64", CPU::X64, CPU::X64}); if (fs.exists(vs2013_bin_dir / "x86_amd64\\vcvarsx86_amd64.bat")) supported_architectures.push_back({L"x86_amd64", CPU::X86, CPU::X64}); @@ -332,11 +322,36 @@ namespace vcpkg if (fs.exists(vs2013_dumpbin_exe)) { found_toolsets.push_back( - {vs2013_dumpbin_exe, vs2013_vcvarsall_bat, L"v120", supported_architectures}); + {vs2013_dumpbin_exe, vs2013_vcvarsall_bat, {}, V_120, supported_architectures}); } } } - + + if (found_toolsets.empty()) + { + System::println(System::Color::error, "Could not locate a complete toolset."); + System::println("The following paths were examined:"); + for (const fs::path& path : paths_examined) + { + System::println(" %s", path.u8string()); + } + Checks::exit_fail(VCPKG_LINE_INFO); + } + + return found_toolsets; + } + + static std::vector find_toolset_instances(const VcpkgPaths& paths) + { + using CPU = System::CPUArchitecture; + + const auto& fs = paths.get_filesystem(); + + // Note: this will contain a mix of vcvarsall.bat locations and dumpbin.exe locations. + std::vector paths_examined; + + std::vector found_toolsets; + // VS2015 const Optional vs_2015_installation_instance = get_vs2015_installation_instance(); if (const auto v = vs_2015_installation_instance.get()) @@ -372,8 +387,6 @@ namespace vcpkg } } - const std::vector vs2017_installation_instances = get_vs2017_installation_instances(paths); - // VS2017 Optional vs2017_toolset; const std::vector vs2017_installation_instances = get_vs2017_installation_instances(paths); @@ -476,6 +489,14 @@ namespace vcpkg { const std::wstring& w_toolset_version = Strings::to_utf16(toolset_version); + if (w_toolset_version == V_120) + { + const auto& v120_toolsets = this->toolsets_vs2013.get_lazy( + [this]() { return find_v120_toolset_instances(this->get_filesystem()); }); + Checks::check_exit(VCPKG_LINE_INFO, v120_toolsets.size() > 0); + return v120_toolsets.back(); + } + // Invariant: toolsets are non-empty and sorted with newest at back() const std::vector& vs_toolsets = this->toolsets.get_lazy([this]() { return find_toolset_instances(*this); }); -- cgit v1.2.3 From ddbd57f5058b78e7df27497af844a41a1c79b986 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Wed, 4 Oct 2017 15:58:05 -0700 Subject: [vcpkg] Reformat and fix headers. --- toolsrc/include/vcpkg_Commands_Export.h | 8 +------- toolsrc/include/vcpkg_Commands_Export_IFW.h | 11 +++++++++-- 2 files changed, 10 insertions(+), 9 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg_Commands_Export.h b/toolsrc/include/vcpkg_Commands_Export.h index 31003422d..6e698c1b4 100644 --- a/toolsrc/include/vcpkg_Commands_Export.h +++ b/toolsrc/include/vcpkg_Commands_Export.h @@ -1,14 +1,8 @@ #pragma once -#include "StatusParagraphs.h" -#include "VcpkgCmdArguments.h" #include "VcpkgPaths.h" -#include "VersionT.h" -#include "vcpkg_Build.h" -#include "vcpkg_Dependencies.h" -#include namespace vcpkg::Commands::Export { - void export_integration_files(const fs::path &raw_exported_dir_path, const VcpkgPaths& paths); + void export_integration_files(const fs::path& raw_exported_dir_path, const VcpkgPaths& paths); } diff --git a/toolsrc/include/vcpkg_Commands_Export_IFW.h b/toolsrc/include/vcpkg_Commands_Export_IFW.h index c066ca021..7bee45eaf 100644 --- a/toolsrc/include/vcpkg_Commands_Export_IFW.h +++ b/toolsrc/include/vcpkg_Commands_Export_IFW.h @@ -1,7 +1,11 @@ #pragma once -#include "vcpkg_Files.h" +#include "VcpkgPaths.h" #include "vcpkg_Dependencies.h" +#include "vcpkg_Files.h" + +#include +#include namespace vcpkg::Commands::Export::IFW { @@ -14,5 +18,8 @@ namespace vcpkg::Commands::Export::IFW Optional maybe_installer_file_path; }; - void do_export(const std::vector &export_plan, const std::string &export_id, const Options &ifw_options, const VcpkgPaths& paths); + void do_export(const std::vector& export_plan, + const std::string& export_id, + const Options& ifw_options, + const VcpkgPaths& paths); } -- cgit v1.2.3 From 1b71053ad9954ffb0cb3c2955f42a86f62f66372 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Wed, 4 Oct 2017 16:01:29 -0700 Subject: [vcpkg] Reformat and refactor to reduce function size --- toolsrc/src/VcpkgPaths.cpp | 24 ++- toolsrc/src/commands_export.cpp | 324 ++++++++++++++++++++---------------- toolsrc/src/commands_export_ifw.cpp | 167 ++++++++++--------- 3 files changed, 278 insertions(+), 237 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp index 19210facf..9f85992be 100644 --- a/toolsrc/src/VcpkgPaths.cpp +++ b/toolsrc/src/VcpkgPaths.cpp @@ -175,18 +175,21 @@ namespace vcpkg static fs::path get_ifw_installerbase_path(const fs::path& downloads_folder, const fs::path& scripts_folder) { - static constexpr std::array EXPECTED_VERSION = { 3, 1, 81 }; + static constexpr std::array EXPECTED_VERSION = {3, 1, 81}; static const std::wstring VERSION_CHECK_ARGUMENTS = L"--framework-version"; - const fs::path downloaded_copy = downloads_folder / "QtInstallerFramework-win-x86" / "bin" / "installerbase.exe"; + const fs::path downloaded_copy = + downloads_folder / "QtInstallerFramework-win-x86" / "bin" / "installerbase.exe"; std::vector candidate_paths; candidate_paths.push_back(downloaded_copy); // TODO: Uncomment later - //const std::vector from_path = Files::find_from_PATH(L"installerbase"); - //candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); - //candidate_paths.push_back(fs::path(System::get_environment_variable(L"HOMEDRIVE").value_or("C:")) / "Qt" / "Tools" / "QtInstallerFramework" / "3.1" / "bin" / "installerbase.exe"); - //candidate_paths.push_back(fs::path(System::get_environment_variable(L"HOMEDRIVE").value_or("C:")) / "Qt" / "QtIFW-3.1.0" / "bin" / "installerbase.exe"); + // const std::vector from_path = Files::find_from_PATH(L"installerbase"); + // candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); + // candidate_paths.push_back(fs::path(System::get_environment_variable(L"HOMEDRIVE").value_or("C:")) / "Qt" / + // "Tools" / "QtInstallerFramework" / "3.1" / "bin" / "installerbase.exe"); + // candidate_paths.push_back(fs::path(System::get_environment_variable(L"HOMEDRIVE").value_or("C:")) / "Qt" / + // "QtIFW-3.1.0" / "bin" / "installerbase.exe"); const Optional path = find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, EXPECTED_VERSION); @@ -283,17 +286,20 @@ namespace vcpkg const fs::path& VcpkgPaths::get_ifw_installerbase_exe() const { - return this->ifw_installerbase_exe.get_lazy([this]() { return get_ifw_installerbase_path(this->downloads, this->scripts); }); + return this->ifw_installerbase_exe.get_lazy( + [this]() { return get_ifw_installerbase_path(this->downloads, this->scripts); }); } const fs::path& VcpkgPaths::get_ifw_binarycreator_exe() const { - return this->ifw_binarycreator_exe.get_lazy([this]() { return get_ifw_installerbase_exe().parent_path() / "binarycreator.exe"; }); + return this->ifw_binarycreator_exe.get_lazy( + [this]() { return get_ifw_installerbase_exe().parent_path() / "binarycreator.exe"; }); } const fs::path& VcpkgPaths::get_ifw_repogen_exe() const { - return this->ifw_repogen_exe.get_lazy([this]() { return get_ifw_installerbase_exe().parent_path() / "repogen.exe"; }); + return this->ifw_repogen_exe.get_lazy( + [this]() { return get_ifw_installerbase_exe().parent_path() / "repogen.exe"; }); } static std::vector get_vs2017_installation_instances(const VcpkgPaths& paths) diff --git a/toolsrc/src/commands_export.cpp b/toolsrc/src/commands_export.cpp index 3662a46d8..a24f2eac7 100644 --- a/toolsrc/src/commands_export.cpp +++ b/toolsrc/src/commands_export.cpp @@ -211,17 +211,17 @@ namespace vcpkg::Commands::Export return nullopt; } - void export_integration_files(const fs::path &raw_exported_dir_path, const VcpkgPaths& paths) + void export_integration_files(const fs::path& raw_exported_dir_path, const VcpkgPaths& paths) { const std::vector integration_files_relative_to_root = { - { ".vcpkg-root" }, - { fs::path{ "scripts" } / "buildsystems" / "msbuild" / "applocal.ps1" }, - { fs::path{ "scripts" } / "buildsystems" / "msbuild" / "vcpkg.targets" }, - { fs::path{ "scripts" } / "buildsystems" / "vcpkg.cmake" }, - { fs::path{ "scripts" } / "cmake" / "vcpkg_get_windows_sdk.cmake" }, - { fs::path{ "scripts" } / "getWindowsSDK.ps1" }, - { fs::path{ "scripts" } / "getProgramFilesPlatformBitness.ps1" }, - { fs::path{ "scripts" } / "getProgramFiles32bit.ps1" }, + {".vcpkg-root"}, + {fs::path{"scripts"} / "buildsystems" / "msbuild" / "applocal.ps1"}, + {fs::path{"scripts"} / "buildsystems" / "msbuild" / "vcpkg.targets"}, + {fs::path{"scripts"} / "buildsystems" / "vcpkg.cmake"}, + {fs::path{"scripts"} / "cmake" / "vcpkg_get_windows_sdk.cmake"}, + {fs::path{"scripts"} / "getWindowsSDK.ps1"}, + {fs::path{"scripts"} / "getProgramFilesPlatformBitness.ps1"}, + {fs::path{"scripts"} / "getProgramFiles32bit.ps1"}, }; for (const fs::path& file : integration_files_relative_to_root) @@ -237,8 +237,27 @@ namespace vcpkg::Commands::Export } } - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) + struct ExportArguments + { + bool dry_run; + bool raw; + bool nuget; + bool ifw; + bool zip; + bool seven_zip; + + Optional maybe_nuget_id; + Optional maybe_nuget_version; + + IFW::Options ifw_options; + std::vector specs; + }; + + static ExportArguments handle_export_command_arguments(const VcpkgCmdArguments& args, + const Triplet& default_triplet) { + ExportArguments ret; + static const std::string OPTION_DRY_RUN = "--dry-run"; static const std::string OPTION_RAW = "--raw"; static const std::string OPTION_NUGET = "--nuget"; @@ -258,11 +277,9 @@ namespace vcpkg::Commands::Export Commands::Help::create_example_string("export zlib zlib:x64-windows boost --nuget"); args.check_min_arg_count(1, EXAMPLE); - const std::vector specs = Util::fmap(args.command_arguments, [&](auto&& arg) { + ret.specs = Util::fmap(args.command_arguments, [&](auto&& arg) { return Input::check_and_get_package_spec(arg, default_triplet, EXAMPLE); }); - for (auto&& spec : specs) - Input::check_triplet(spec.triplet(), paths); const auto options = args.check_and_get_optional_command_arguments( { @@ -280,16 +297,16 @@ namespace vcpkg::Commands::Export OPTION_IFW_PACKAGES_DIR_PATH, OPTION_IFW_REPOSITORY_DIR_PATH, OPTION_IFW_CONFIG_FILE_PATH, - OPTION_IFW_INSTALLER_FILE_PATH + OPTION_IFW_INSTALLER_FILE_PATH, }); - const bool dry_run = options.switches.find(OPTION_DRY_RUN) != options.switches.cend(); - const bool raw = options.switches.find(OPTION_RAW) != options.switches.cend(); - const bool nuget = options.switches.find(OPTION_NUGET) != options.switches.cend(); - const bool ifw = options.switches.find(OPTION_IFW) != options.switches.cend(); - const bool zip = options.switches.find(OPTION_ZIP) != options.switches.cend(); - const bool seven_zip = options.switches.find(OPTION_SEVEN_ZIP) != options.switches.cend(); - - if (!raw && !nuget && !ifw && !zip && !seven_zip && !dry_run) + ret.dry_run = options.switches.find(OPTION_DRY_RUN) != options.switches.cend(); + ret.raw = options.switches.find(OPTION_RAW) != options.switches.cend(); + ret.nuget = options.switches.find(OPTION_NUGET) != options.switches.cend(); + ret.ifw = options.switches.find(OPTION_IFW) != options.switches.cend(); + ret.zip = options.switches.find(OPTION_ZIP) != options.switches.cend(); + ret.seven_zip = options.switches.find(OPTION_SEVEN_ZIP) != options.switches.cend(); + + if (!ret.raw && !ret.nuget && !ret.ifw && !ret.zip && !ret.seven_zip && !ret.dry_run) { System::println(System::Color::error, "Must provide at least one export type: --raw --nuget --ifw --zip --7zip"); @@ -297,38 +314,152 @@ namespace vcpkg::Commands::Export Checks::exit_fail(VCPKG_LINE_INFO); } - auto maybe_nuget_id = maybe_lookup(options.settings, OPTION_NUGET_ID); - auto maybe_nuget_version = maybe_lookup(options.settings, OPTION_NUGET_VERSION); + ret.maybe_nuget_id = maybe_lookup(options.settings, OPTION_NUGET_ID); + ret.maybe_nuget_version = maybe_lookup(options.settings, OPTION_NUGET_VERSION); - Checks::check_exit(VCPKG_LINE_INFO, !maybe_nuget_id || nuget, "--nuget-id is only valid with --nuget"); + Checks::check_exit(VCPKG_LINE_INFO, !ret.maybe_nuget_id || ret.nuget, "--nuget-id is only valid with --nuget"); Checks::check_exit( - VCPKG_LINE_INFO, !maybe_nuget_version || nuget, "--nuget-version is only valid with --nuget"); + VCPKG_LINE_INFO, !ret.maybe_nuget_version || ret.nuget, "--nuget-version is only valid with --nuget"); - IFW::Options ifw_options; + ret.ifw_options.maybe_repository_url = maybe_lookup(options.settings, OPTION_IFW_REPOSITORY_URL); + Checks::check_exit(VCPKG_LINE_INFO, + !ret.ifw_options.maybe_repository_url || ret.ifw, + "--ifw-repository-url is only valid with --ifw"); - ifw_options.maybe_repository_url = maybe_lookup(options.settings, OPTION_IFW_REPOSITORY_URL); - Checks::check_exit( - VCPKG_LINE_INFO, !ifw_options.maybe_repository_url || ifw, "--ifw-repository-url is only valid with --ifw"); + ret.ifw_options.maybe_packages_dir_path = maybe_lookup(options.settings, OPTION_IFW_PACKAGES_DIR_PATH); + Checks::check_exit(VCPKG_LINE_INFO, + !ret.ifw_options.maybe_packages_dir_path || ret.ifw, + "--ifw-packages-directory-path is only valid with --ifw"); - ifw_options.maybe_packages_dir_path = maybe_lookup(options.settings, OPTION_IFW_PACKAGES_DIR_PATH); - Checks::check_exit( - VCPKG_LINE_INFO, !ifw_options.maybe_packages_dir_path || ifw, "--ifw-packages-directory-path is only valid with --ifw"); + ret.ifw_options.maybe_repository_dir_path = maybe_lookup(options.settings, OPTION_IFW_REPOSITORY_DIR_PATH); + Checks::check_exit(VCPKG_LINE_INFO, + !ret.ifw_options.maybe_repository_dir_path || ret.ifw, + "--ifw-repository-directory-path is only valid with --ifw"); - ifw_options.maybe_repository_dir_path = maybe_lookup(options.settings, OPTION_IFW_REPOSITORY_DIR_PATH); - Checks::check_exit( - VCPKG_LINE_INFO, !ifw_options.maybe_repository_dir_path || ifw, "--ifw-repository-directory-path is only valid with --ifw"); + ret.ifw_options.maybe_config_file_path = maybe_lookup(options.settings, OPTION_IFW_CONFIG_FILE_PATH); + Checks::check_exit(VCPKG_LINE_INFO, + !ret.ifw_options.maybe_config_file_path || ret.ifw, + "--ifw-configuration-file-path is only valid with --ifw"); - ifw_options.maybe_config_file_path = maybe_lookup(options.settings, OPTION_IFW_CONFIG_FILE_PATH); - Checks::check_exit( - VCPKG_LINE_INFO, !ifw_options.maybe_config_file_path || ifw, "--ifw-configuration-file-path is only valid with --ifw"); + ret.ifw_options.maybe_installer_file_path = maybe_lookup(options.settings, OPTION_IFW_INSTALLER_FILE_PATH); + Checks::check_exit(VCPKG_LINE_INFO, + !ret.ifw_options.maybe_installer_file_path || ret.ifw, + "--ifw-installer-file-path is only valid with --ifw"); + return ret; + } - ifw_options.maybe_installer_file_path = maybe_lookup(options.settings, OPTION_IFW_INSTALLER_FILE_PATH); - Checks::check_exit( - VCPKG_LINE_INFO, !ifw_options.maybe_installer_file_path || ifw, "--ifw-installer-file-path is only valid with --ifw"); + static void print_next_step_info(const fs::path& prefix) + { + const fs::path cmake_toolchain = prefix / "scripts" / "buildsystems" / "vcpkg.cmake"; + const CMakeVariable cmake_variable = CMakeVariable(L"CMAKE_TOOLCHAIN_FILE", cmake_toolchain.generic_string()); + System::println("\n" + "To use the exported libraries in CMake projects use:" + "\n" + " %s" + "\n", + Strings::to_utf8(cmake_variable.s)); + }; + + static void handle_raw_based_export(Span export_plan, + const ExportArguments& opts, + const std::string& export_id, + const VcpkgPaths& paths) + { + Files::Filesystem& fs = paths.get_filesystem(); + const fs::path export_to_path = paths.root; + const fs::path raw_exported_dir_path = export_to_path / export_id; + std::error_code ec; + fs.remove_all(raw_exported_dir_path, ec); + fs.create_directory(raw_exported_dir_path, ec); + + // execute the plan + for (const ExportPlanAction& action : export_plan) + { + if (action.plan_type != ExportPlanType::ALREADY_BUILT) + { + Checks::unreachable(VCPKG_LINE_INFO); + } + + const std::string display_name = action.spec.to_string(); + System::println("Exporting package %s... ", display_name); + + const BinaryParagraph& binary_paragraph = + action.any_paragraph.binary_control_file.value_or_exit(VCPKG_LINE_INFO).core_paragraph; + + const InstallDir dirs = InstallDir::from_destination_root( + raw_exported_dir_path / "installed", + 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); + System::println(System::Color::success, "Exporting package %s... done", display_name); + } + + // Copy files needed for integration + export_integration_files(raw_exported_dir_path, paths); + + if (opts.raw) + { + System::println( + System::Color::success, R"(Files exported at: "%s")", raw_exported_dir_path.generic_string()); + print_next_step_info(export_to_path); + } + + if (opts.nuget) + { + System::println("Creating nuget package... "); + + const std::string nuget_id = opts.maybe_nuget_id.value_or(raw_exported_dir_path.filename().string()); + const std::string nuget_version = opts.maybe_nuget_version.value_or("1.0.0"); + const fs::path output_path = + do_nuget_export(paths, nuget_id, nuget_version, raw_exported_dir_path, export_to_path); + System::println(System::Color::success, "Creating nuget package... done"); + System::println(System::Color::success, "NuGet package exported at: %s", output_path.generic_string()); + + System::println(R"( +With a project open, go to Tools->NuGet Package Manager->Package Manager Console and paste: + Install-Package %s -Source "%s" +)" + "\n", + nuget_id, + output_path.parent_path().u8string()); + } + + if (opts.zip) + { + System::println("Creating zip archive... "); + const fs::path output_path = + do_archive_export(paths, raw_exported_dir_path, export_to_path, ArchiveFormatC::ZIP); + System::println(System::Color::success, "Creating zip archive... done"); + System::println(System::Color::success, "Zip archive exported at: %s", output_path.generic_string()); + print_next_step_info("[...]"); + } + + if (opts.seven_zip) + { + System::println("Creating 7zip archive... "); + const fs::path output_path = + do_archive_export(paths, raw_exported_dir_path, export_to_path, ArchiveFormatC::SEVEN_ZIP); + System::println(System::Color::success, "Creating 7zip archive... done"); + System::println(System::Color::success, "7zip archive exported at: %s", output_path.generic_string()); + print_next_step_info("[...]"); + } + + if (!opts.raw) + { + fs.remove_all(raw_exported_dir_path, ec); + } + } + + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) + { + const auto opts = handle_export_command_arguments(args, default_triplet); + for (auto&& spec : opts.specs) + Input::check_triplet(spec.triplet(), paths); // create the plan const StatusParagraphs status_db = database_load_check(paths); - std::vector export_plan = Dependencies::create_export_plan(paths, specs, status_db); + std::vector export_plan = Dependencies::create_export_plan(paths, opts.specs, status_db); Checks::check_exit(VCPKG_LINE_INFO, !export_plan.empty(), "Export plan cannot be empty"); std::map> group_by_plan_type; @@ -363,118 +494,21 @@ namespace vcpkg::Commands::Export Checks::exit_fail(VCPKG_LINE_INFO); } - if (dry_run) + if (opts.dry_run) { Checks::exit_success(VCPKG_LINE_INFO); } std::string export_id = create_export_id(); - const auto print_next_step_info = [](const fs::path& prefix) { - const fs::path cmake_toolchain = prefix / "scripts" / "buildsystems" / "vcpkg.cmake"; - const CMakeVariable cmake_variable = - CMakeVariable(L"CMAKE_TOOLCHAIN_FILE", cmake_toolchain.generic_string()); - System::println("\n" - "To use the exported libraries in CMake projects use:" - "\n" - " %s" - "\n", - Strings::to_utf8(cmake_variable.s)); - }; - - // Main loop - if (raw || nuget || zip || seven_zip) + if (opts.raw || opts.nuget || opts.zip || opts.seven_zip) { - Files::Filesystem& fs = paths.get_filesystem(); - const fs::path export_to_path = paths.root; - const fs::path raw_exported_dir_path = export_to_path / export_id; - std::error_code ec; - fs.remove_all(raw_exported_dir_path, ec); - fs.create_directory(raw_exported_dir_path, ec); - - // execute the plan - for (const ExportPlanAction& action : export_plan) - { - if (action.plan_type != ExportPlanType::ALREADY_BUILT) - { - Checks::unreachable(VCPKG_LINE_INFO); - } - - const std::string display_name = action.spec.to_string(); - System::println("Exporting package %s... ", display_name); - - const BinaryParagraph& binary_paragraph = - action.any_paragraph.binary_control_file.value_or_exit(VCPKG_LINE_INFO).core_paragraph; - - const InstallDir dirs = InstallDir::from_destination_root( - raw_exported_dir_path / "installed", - 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); - System::println(System::Color::success, "Exporting package %s... done", display_name); - } - - // Copy files needed for integration - export_integration_files(raw_exported_dir_path, paths); - - if (raw) - { - System::println( - System::Color::success, R"(Files exported at: "%s")", raw_exported_dir_path.generic_string()); - print_next_step_info(export_to_path); - } - - if (nuget) - { - System::println("Creating nuget package... "); - - const std::string nuget_id = maybe_nuget_id.value_or(raw_exported_dir_path.filename().string()); - const std::string nuget_version = maybe_nuget_version.value_or("1.0.0"); - const fs::path output_path = - do_nuget_export(paths, nuget_id, nuget_version, raw_exported_dir_path, export_to_path); - System::println(System::Color::success, "Creating nuget package... done"); - System::println(System::Color::success, "NuGet package exported at: %s", output_path.generic_string()); - - System::println(R"( -With a project open, go to Tools->NuGet Package Manager->Package Manager Console and paste: - Install-Package %s -Source "%s" -)" - "\n", - nuget_id, - output_path.parent_path().u8string()); - } - - if (zip) - { - System::println("Creating zip archive... "); - const fs::path output_path = - do_archive_export(paths, raw_exported_dir_path, export_to_path, ArchiveFormatC::ZIP); - System::println(System::Color::success, "Creating zip archive... done"); - System::println(System::Color::success, "Zip archive exported at: %s", output_path.generic_string()); - print_next_step_info("[...]"); - } - - if (seven_zip) - { - System::println("Creating 7zip archive... "); - const fs::path output_path = - do_archive_export(paths, raw_exported_dir_path, export_to_path, ArchiveFormatC::SEVEN_ZIP); - System::println(System::Color::success, "Creating 7zip archive... done"); - System::println(System::Color::success, "7zip archive exported at: %s", output_path.generic_string()); - print_next_step_info("[...]"); - } - - if (!raw) - { - fs.remove_all(raw_exported_dir_path, ec); - } + handle_raw_based_export(export_plan, opts, export_id, paths); } - // IFW loop - if (ifw) + if (opts.ifw) { - IFW::do_export(export_plan, export_id, ifw_options, paths); + IFW::do_export(export_plan, export_id, opts.ifw_options, paths); print_next_step_info("@RootDir@/src/vcpkg"); } diff --git a/toolsrc/src/commands_export_ifw.cpp b/toolsrc/src/commands_export_ifw.cpp index a0692c11e..0dc8a7d31 100644 --- a/toolsrc/src/commands_export_ifw.cpp +++ b/toolsrc/src/commands_export_ifw.cpp @@ -19,39 +19,39 @@ namespace vcpkg::Commands::Export::IFW char mbstr[11]; const size_t bytes_written = std::strftime(mbstr, sizeof(mbstr), "%Y-%m-%d", &date_time); Checks::check_exit(VCPKG_LINE_INFO, - bytes_written == 10, - "Expected 10 bytes to be written, but %u were written", - bytes_written); + bytes_written == 10, + "Expected 10 bytes to be written, but %u were written", + bytes_written); const std::string date_time_as_string(mbstr); return date_time_as_string; } - fs::path get_packages_dir_path(const std::string &export_id, const Options &ifw_options, const VcpkgPaths& paths) + fs::path get_packages_dir_path(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths) { - return ifw_options.maybe_packages_dir_path.has_value() ? - fs::path(ifw_options.maybe_packages_dir_path.value_or_exit(VCPKG_LINE_INFO)) - : paths.root / (export_id + "-ifw-packages"); + return ifw_options.maybe_packages_dir_path.has_value() + ? fs::path(ifw_options.maybe_packages_dir_path.value_or_exit(VCPKG_LINE_INFO)) + : paths.root / (export_id + "-ifw-packages"); } - fs::path get_repository_dir_path(const std::string &export_id, const Options &ifw_options, const VcpkgPaths& paths) + fs::path get_repository_dir_path(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths) { - return ifw_options.maybe_repository_dir_path.has_value() ? - fs::path(ifw_options.maybe_repository_dir_path.value_or_exit(VCPKG_LINE_INFO)) - : paths.root / (export_id + "-ifw-repository"); + return ifw_options.maybe_repository_dir_path.has_value() + ? fs::path(ifw_options.maybe_repository_dir_path.value_or_exit(VCPKG_LINE_INFO)) + : paths.root / (export_id + "-ifw-repository"); } - fs::path get_config_file_path(const std::string &export_id, const Options &ifw_options, const VcpkgPaths& paths) + fs::path get_config_file_path(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths) { - return ifw_options.maybe_config_file_path.has_value() ? - fs::path(ifw_options.maybe_config_file_path.value_or_exit(VCPKG_LINE_INFO)) - : paths.root / (export_id + "-ifw-configuration.xml"); + return ifw_options.maybe_config_file_path.has_value() + ? fs::path(ifw_options.maybe_config_file_path.value_or_exit(VCPKG_LINE_INFO)) + : paths.root / (export_id + "-ifw-configuration.xml"); } - fs::path get_installer_file_path(const std::string &export_id, const Options &ifw_options, const VcpkgPaths& paths) + fs::path get_installer_file_path(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths) { - return ifw_options.maybe_installer_file_path.has_value() ? - fs::path(ifw_options.maybe_installer_file_path.value_or_exit(VCPKG_LINE_INFO)) - : paths.root / (export_id + "-ifw-installer.exe"); + return ifw_options.maybe_installer_file_path.has_value() + ? fs::path(ifw_options.maybe_installer_file_path.value_or_exit(VCPKG_LINE_INFO)) + : paths.root / (export_id + "-ifw-installer.exe"); } fs::path export_real_package(const fs::path& ifw_packages_dir_path, @@ -82,7 +82,7 @@ namespace vcpkg::Commands::Export::IFW fs.write_contents(package_xml_file_path, Strings::format( -R"###( + R"###( %s %s @@ -91,12 +91,12 @@ R"###( true )###", - action.spec.to_string(), - binary_paragraph.version, - create_release_date(), - action.spec.name(), - action.spec.triplet().canonical_name(), - deps)); + action.spec.to_string(), + binary_paragraph.version, + create_release_date(), + action.spec.name(), + action.spec.triplet().canonical_name(), + deps)); // Return dir path for export package data return ifw_packages_dir_path / @@ -119,15 +119,16 @@ R"###( !ec, "Could not create directory for package file %s", package_xml_file_path.generic_string()); - fs.write_contents(package_xml_file_path, Strings::format( -R"###( + fs.write_contents(package_xml_file_path, + Strings::format( + R"###( Packages 1.0.0 %s )###", - create_release_date())); + create_release_date())); for (auto package = unique_packages.begin(); package != unique_packages.end(); ++package) { @@ -146,7 +147,7 @@ R"###( fs.write_contents(package_xml_file_path, Strings::format( -R"###( + R"###( %s %s @@ -154,10 +155,10 @@ R"###( %s )###", - action.spec.name(), - binary_paragraph.description, - binary_paragraph.version, - create_release_date())); + action.spec.name(), + binary_paragraph.description, + binary_paragraph.version, + create_release_date())); } } @@ -176,15 +177,16 @@ R"###( !ec, "Could not create directory for package file %s", package_xml_file_path.generic_string()); - fs.write_contents(package_xml_file_path, Strings::format( -R"###( + fs.write_contents(package_xml_file_path, + Strings::format( + R"###( Triplets 1.0.0 %s )###", - create_release_date())); + create_release_date())); for (const std::string& triplet : unique_triplets) { @@ -196,16 +198,17 @@ R"###( !ec, "Could not create directory for package file %s", package_xml_file_path.generic_string()); - fs.write_contents(package_xml_file_path, Strings::format( -R"###( + fs.write_contents(package_xml_file_path, + Strings::format( + R"###( %s 1.0.0 %s )###", - triplet, - create_release_date())); + triplet, + create_release_date())); } } @@ -222,18 +225,19 @@ R"###( "Could not create directory for package file %s", package_xml_file_path.generic_string()); - fs.write_contents(package_xml_file_path, Strings::format( -R"###( + fs.write_contents(package_xml_file_path, + Strings::format( + R"###( Integration 1.0.0 %s )###", - create_release_date())); + create_release_date())); } - void export_config(const std::string &export_id, const Options &ifw_options, const VcpkgPaths& paths) + void export_config(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths) { std::error_code ec; Files::Filesystem& fs = paths.get_filesystem(); @@ -257,21 +261,22 @@ R"###( %s )###", - ifw_repo_url); + ifw_repo_url); } - fs.write_contents(config_xml_file_path, Strings::format( -R"###( + fs.write_contents(config_xml_file_path, + Strings::format( + R"###( vcpkg 1.0.0 @RootDir@/src/vcpkg%s )###", - formatted_repo_url)); + formatted_repo_url)); } - void do_repository(const std::string &export_id, const Options &ifw_options, const VcpkgPaths& paths) + void do_repository(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths) { const fs::path& repogen_exe = paths.get_ifw_repogen_exe(); const fs::path packages_dir = get_packages_dir_path(export_id, ifw_options, paths); @@ -283,16 +288,13 @@ R"###( Files::Filesystem& fs = paths.get_filesystem(); fs.remove_all(repository_dir, ec); - Checks::check_exit(VCPKG_LINE_INFO, - !ec, - "Could not remove outdated repository directory %s", - repository_dir.generic_string()); + Checks::check_exit( + VCPKG_LINE_INFO, !ec, "Could not remove outdated repository directory %s", repository_dir.generic_string()); - const std::wstring cmd_line = - Strings::wformat(LR"("%s" --packages "%s" "%s" > nul)", - repogen_exe.native(), - packages_dir.native(), - repository_dir.native()); + const std::wstring cmd_line = Strings::wformat(LR"("%s" --packages "%s" "%s" > nul)", + repogen_exe.native(), + packages_dir.native(), + repository_dir.native()); const int exit_code = System::cmd_execute_clean(cmd_line); Checks::check_exit(VCPKG_LINE_INFO, exit_code == 0, "Error: IFW repository generating failed"); @@ -300,7 +302,7 @@ R"###( System::println(System::Color::success, "Generating repository %s... done.", repository_dir.generic_string()); } - void do_installer(const std::string &export_id, const Options &ifw_options, const VcpkgPaths& paths) + void do_installer(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths) { const fs::path& binarycreator_exe = paths.get_ifw_binarycreator_exe(); const fs::path config_file = get_config_file_path(export_id, ifw_options, paths); @@ -315,21 +317,19 @@ R"###( std::string ifw_repo_url = ifw_options.maybe_repository_url.value_or(""); if (!ifw_repo_url.empty()) { - cmd_line = - Strings::wformat(LR"("%s" --online-only --config "%s" --repository "%s" "%s" > nul)", - binarycreator_exe.native(), - config_file.native(), - repository_dir.native(), - installer_file.native()); + cmd_line = Strings::wformat(LR"("%s" --online-only --config "%s" --repository "%s" "%s" > nul)", + binarycreator_exe.native(), + config_file.native(), + repository_dir.native(), + installer_file.native()); } else { - cmd_line = - Strings::wformat(LR"("%s" --config "%s" --packages "%s" "%s" > nul)", - binarycreator_exe.native(), - config_file.native(), - packages_dir.native(), - installer_file.native()); + cmd_line = Strings::wformat(LR"("%s" --config "%s" --packages "%s" "%s" > nul)", + binarycreator_exe.native(), + config_file.native(), + packages_dir.native(), + installer_file.native()); } const int exit_code = System::cmd_execute_clean(cmd_line); @@ -338,7 +338,10 @@ R"###( System::println(System::Color::success, "Generating installer %s... done.", installer_file.generic_string()); } - void do_export(const std::vector &export_plan, const std::string &export_id, const Options &ifw_options, const VcpkgPaths& paths) + void do_export(const std::vector& export_plan, + const std::string& export_id, + const Options& ifw_options, + const VcpkgPaths& paths) { const fs::path ifw_packages_dir_path = get_packages_dir_path(export_id, ifw_options, paths); const fs::path config_file = get_config_file_path(export_id, ifw_options, paths); @@ -350,15 +353,13 @@ R"###( fs.remove_all(ifw_packages_dir_path, ec); Checks::check_exit(VCPKG_LINE_INFO, - !ec, - "Could not remove outdated packages directory %s", - ifw_packages_dir_path.generic_string()); + !ec, + "Could not remove outdated packages directory %s", + ifw_packages_dir_path.generic_string()); fs.create_directory(ifw_packages_dir_path, ec); - Checks::check_exit(VCPKG_LINE_INFO, - !ec, - "Could not create packages directory %s", - ifw_packages_dir_path.generic_string()); + Checks::check_exit( + VCPKG_LINE_INFO, !ec, "Could not create packages directory %s", ifw_packages_dir_path.generic_string()); // execute the plan std::map unique_packages; @@ -384,9 +385,9 @@ R"###( // Copy package data const InstallDir dirs = InstallDir::from_destination_root(ifw_package_dir_path, - action.spec.triplet().to_string(), - ifw_package_dir_path / "vcpkg" / "info" / - (binary_paragraph.fullstem() + ".list")); + action.spec.triplet().to_string(), + 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); System::println("Exporting package %s... done", display_name); -- cgit v1.2.3 From c98db7541594eadccf6823d4fdde2ff8c53c5fe9 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Wed, 4 Oct 2017 16:24:03 -0700 Subject: [vcpkg] Refactor out implication in option parsing for export --- toolsrc/include/Span.h | 2 ++ toolsrc/src/commands_export.cpp | 70 +++++++++++++++++++++++------------------ 2 files changed, 41 insertions(+), 31 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/Span.h b/toolsrc/include/Span.h index b2c9acdbc..a43e8f992 100644 --- a/toolsrc/include/Span.h +++ b/toolsrc/include/Span.h @@ -2,6 +2,7 @@ #include #include +#include #include template @@ -17,6 +18,7 @@ public: constexpr Span(std::nullptr_t) noexcept : Span() {} constexpr Span(T* ptr, size_t count) noexcept : m_ptr(ptr), m_count(count) {} constexpr Span(T* ptr_begin, T* ptr_end) noexcept : m_ptr(ptr_begin), m_count(ptr_end - ptr_begin) {} + constexpr Span(std::initializer_list l) noexcept : m_ptr(l.begin()), m_count(l.size()) {} template constexpr Span(T (&arr)[N]) noexcept : Span(arr, N) diff --git a/toolsrc/src/commands_export.cpp b/toolsrc/src/commands_export.cpp index a24f2eac7..20838f5a5 100644 --- a/toolsrc/src/commands_export.cpp +++ b/toolsrc/src/commands_export.cpp @@ -314,37 +314,45 @@ namespace vcpkg::Commands::Export Checks::exit_fail(VCPKG_LINE_INFO); } - ret.maybe_nuget_id = maybe_lookup(options.settings, OPTION_NUGET_ID); - ret.maybe_nuget_version = maybe_lookup(options.settings, OPTION_NUGET_VERSION); - - Checks::check_exit(VCPKG_LINE_INFO, !ret.maybe_nuget_id || ret.nuget, "--nuget-id is only valid with --nuget"); - Checks::check_exit( - VCPKG_LINE_INFO, !ret.maybe_nuget_version || ret.nuget, "--nuget-version is only valid with --nuget"); - - ret.ifw_options.maybe_repository_url = maybe_lookup(options.settings, OPTION_IFW_REPOSITORY_URL); - Checks::check_exit(VCPKG_LINE_INFO, - !ret.ifw_options.maybe_repository_url || ret.ifw, - "--ifw-repository-url is only valid with --ifw"); - - ret.ifw_options.maybe_packages_dir_path = maybe_lookup(options.settings, OPTION_IFW_PACKAGES_DIR_PATH); - Checks::check_exit(VCPKG_LINE_INFO, - !ret.ifw_options.maybe_packages_dir_path || ret.ifw, - "--ifw-packages-directory-path is only valid with --ifw"); - - ret.ifw_options.maybe_repository_dir_path = maybe_lookup(options.settings, OPTION_IFW_REPOSITORY_DIR_PATH); - Checks::check_exit(VCPKG_LINE_INFO, - !ret.ifw_options.maybe_repository_dir_path || ret.ifw, - "--ifw-repository-directory-path is only valid with --ifw"); - - ret.ifw_options.maybe_config_file_path = maybe_lookup(options.settings, OPTION_IFW_CONFIG_FILE_PATH); - Checks::check_exit(VCPKG_LINE_INFO, - !ret.ifw_options.maybe_config_file_path || ret.ifw, - "--ifw-configuration-file-path is only valid with --ifw"); - - ret.ifw_options.maybe_installer_file_path = maybe_lookup(options.settings, OPTION_IFW_INSTALLER_FILE_PATH); - Checks::check_exit(VCPKG_LINE_INFO, - !ret.ifw_options.maybe_installer_file_path || ret.ifw, - "--ifw-installer-file-path is only valid with --ifw"); + struct OptionPair + { + const std::string& name; + Optional& out_opt; + }; + const auto options_implies = + [&](const std::string& main_opt_name, bool main_opt, Span implying_opts) { + if (main_opt) + { + for (auto&& opt : implying_opts) + opt.out_opt = maybe_lookup(options.settings, opt.name); + } + else + { + for (auto&& opt : implying_opts) + Checks::check_exit(VCPKG_LINE_INFO, + !maybe_lookup(options.settings, opt.name), + "%s is only valid with %s", + opt.name, + main_opt_name); + } + }; + + options_implies(OPTION_NUGET, + ret.nuget, + { + {OPTION_NUGET_ID, ret.maybe_nuget_id}, + {OPTION_NUGET_VERSION, ret.maybe_nuget_version}, + }); + + options_implies(OPTION_IFW, + ret.ifw, + { + {OPTION_IFW_REPOSITORY_URL, ret.ifw_options.maybe_repository_url}, + {OPTION_IFW_PACKAGES_DIR_PATH, ret.ifw_options.maybe_packages_dir_path}, + {OPTION_IFW_REPOSITORY_DIR_PATH, ret.ifw_options.maybe_repository_dir_path}, + {OPTION_IFW_CONFIG_FILE_PATH, ret.ifw_options.maybe_config_file_path}, + {OPTION_IFW_INSTALLER_FILE_PATH, ret.ifw_options.maybe_installer_file_path}, + }); return ret; } -- cgit v1.2.3 From 6f763c5ca830c9e461e106c63959a60d33eb5e5b Mon Sep 17 00:00:00 2001 From: Konstantin Podsvirov Date: Thu, 5 Oct 2017 21:24:32 +0300 Subject: [vcpkg-export-ifw] Maintenance Tool Install maintenance tool and create Start menu shortcuts to manage, update and uninstall packages. --- toolsrc/src/commands_export_ifw.cpp | 69 ++++++++++++++++++++++++++++++++++--- 1 file changed, 64 insertions(+), 5 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/commands_export_ifw.cpp b/toolsrc/src/commands_export_ifw.cpp index 0dc8a7d31..4ab0ae537 100644 --- a/toolsrc/src/commands_export_ifw.cpp +++ b/toolsrc/src/commands_export_ifw.cpp @@ -270,12 +270,66 @@ namespace vcpkg::Commands::Export::IFW vcpkg 1.0.0 + vcpkg @RootDir@/src/vcpkg%s )###", formatted_repo_url)); } + void export_maintenance_tool(const fs::path& ifw_packages_dir_path, const VcpkgPaths& paths) + { + System::println("Exporting maintenance tool... "); + + std::error_code ec; + Files::Filesystem& fs = paths.get_filesystem(); + + const fs::path& installerbase_exe = paths.get_ifw_installerbase_exe(); + fs::path tempmaintenancetool = ifw_packages_dir_path / "maintenance" / "data" / "tempmaintenancetool.exe"; + fs.create_directories(tempmaintenancetool.parent_path(), ec); + Checks::check_exit(VCPKG_LINE_INFO, + !ec, + "Could not create directory for package file %s", + tempmaintenancetool.generic_string()); + fs.copy_file(installerbase_exe, tempmaintenancetool, fs::copy_options::overwrite_existing, ec); + Checks::check_exit(VCPKG_LINE_INFO, + !ec, + "Could not write package file %s", + tempmaintenancetool.generic_string()); + + fs::path package_xml_file_path = ifw_packages_dir_path / "maintenance" / "meta" / "package.xml"; + fs::path package_xml_dir_path = package_xml_file_path.parent_path(); + fs.create_directories(package_xml_dir_path, ec); + Checks::check_exit(VCPKG_LINE_INFO, + !ec, + "Could not create directory for package file %s", + package_xml_file_path.generic_string()); + fs.write_contents(package_xml_file_path, + Strings::format( + R"###( + + Maintenance Tool + Maintenance Tool + 1.0.0 + %s + + true + true + true + +)###", +create_release_date())); + const fs::path script_source = paths.root / "scripts" / "ifw" / "maintenance.qs"; + const fs::path script_destination = ifw_packages_dir_path / "maintenance" / "meta" / "maintenance.qs"; + fs.copy_file(script_source, script_destination, fs::copy_options::overwrite_existing, ec); + Checks::check_exit(VCPKG_LINE_INFO, + !ec, + "Could not write package file %s", + script_destination.generic_string()); + + System::println("Exporting maintenance tool... done"); + } + void do_repository(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths) { const fs::path& repogen_exe = paths.get_ifw_repogen_exe(); @@ -343,14 +397,12 @@ namespace vcpkg::Commands::Export::IFW const Options& ifw_options, const VcpkgPaths& paths) { - const fs::path ifw_packages_dir_path = get_packages_dir_path(export_id, ifw_options, paths); - const fs::path config_file = get_config_file_path(export_id, ifw_options, paths); - - System::println("Exporting packages %s... ", ifw_packages_dir_path.generic_string()); - std::error_code ec; Files::Filesystem& fs = paths.get_filesystem(); + // Prepare packages directory + const fs::path ifw_packages_dir_path = get_packages_dir_path(export_id, ifw_options, paths); + fs.remove_all(ifw_packages_dir_path, ec); Checks::check_exit(VCPKG_LINE_INFO, !ec, @@ -361,6 +413,11 @@ namespace vcpkg::Commands::Export::IFW Checks::check_exit( VCPKG_LINE_INFO, !ec, "Could not create packages directory %s", ifw_packages_dir_path.generic_string()); + // Export maintenance tool + export_maintenance_tool(ifw_packages_dir_path, paths); + + System::println("Exporting packages %s... ", ifw_packages_dir_path.generic_string()); + // execute the plan std::map unique_packages; std::set unique_triplets; @@ -395,6 +452,8 @@ namespace vcpkg::Commands::Export::IFW System::println("Exporting packages %s... done", ifw_packages_dir_path.generic_string()); + const fs::path config_file = get_config_file_path(export_id, ifw_options, paths); + System::println("Generating configuration %s...", config_file.generic_string()); // Unique packages -- cgit v1.2.3 From a518ded266259141edd278e3f4025a3ab3211215 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Thu, 5 Oct 2017 14:36:29 -0700 Subject: [vcpkg] Check size and don't perform stripping if string is too small. --- toolsrc/src/vcpkg_System.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg_System.cpp b/toolsrc/src/vcpkg_System.cpp index 4d2e88b73..7a6e7f028 100644 --- a/toolsrc/src/vcpkg_System.cpp +++ b/toolsrc/src/vcpkg_System.cpp @@ -179,6 +179,7 @@ namespace vcpkg::System // On Win7, output from powershell calls contain a byte order mark, so we strip it out if it is present static void remove_byte_order_mark(std::wstring* s) { + if (s->size() < 3) return; const wchar_t* a = s->c_str(); // This is the UTF-8 byte-order mark if (a[0] == 0xEF && a[1] == 0xBB && a[2] == 0xBF) -- cgit v1.2.3 From 9b0c2cb2524ef3fa1e8e7e8f2512c32e40eb5815 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Thu, 5 Oct 2017 18:07:29 -0700 Subject: [vcpkg] Remove multiple byte order marks --- toolsrc/src/vcpkg_System.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg_System.cpp b/toolsrc/src/vcpkg_System.cpp index 7a6e7f028..3b4c440d8 100644 --- a/toolsrc/src/vcpkg_System.cpp +++ b/toolsrc/src/vcpkg_System.cpp @@ -177,12 +177,11 @@ namespace vcpkg::System } // On Win7, output from powershell calls contain a byte order mark, so we strip it out if it is present - static void remove_byte_order_mark(std::wstring* s) + static void remove_byte_order_marks(std::wstring* s) { - if (s->size() < 3) return; const wchar_t* a = s->c_str(); // This is the UTF-8 byte-order mark - if (a[0] == 0xEF && a[1] == 0xBB && a[2] == 0xBF) + while (s->size() >= 3 && a[0] == 0xEF && a[1] == 0xBB && a[2] == 0xBF) { s->erase(0, 3); } @@ -214,7 +213,7 @@ namespace vcpkg::System const auto ec = _pclose(pipe); Debug::println("_pclose() returned %d", ec); - remove_byte_order_mark(&output); + remove_byte_order_marks(&output); return {ec, Strings::to_utf8(output)}; } -- cgit v1.2.3 From 13385293e62561166c490671630e92458e630b1b Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Thu, 5 Oct 2017 18:14:08 -0700 Subject: [vcpkg] Clang-format on commands_export_ifw --- toolsrc/src/commands_export_ifw.cpp | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/commands_export_ifw.cpp b/toolsrc/src/commands_export_ifw.cpp index 4ab0ae537..191dbb763 100644 --- a/toolsrc/src/commands_export_ifw.cpp +++ b/toolsrc/src/commands_export_ifw.cpp @@ -288,25 +288,23 @@ namespace vcpkg::Commands::Export::IFW fs::path tempmaintenancetool = ifw_packages_dir_path / "maintenance" / "data" / "tempmaintenancetool.exe"; fs.create_directories(tempmaintenancetool.parent_path(), ec); Checks::check_exit(VCPKG_LINE_INFO, - !ec, - "Could not create directory for package file %s", - tempmaintenancetool.generic_string()); + !ec, + "Could not create directory for package file %s", + tempmaintenancetool.generic_string()); fs.copy_file(installerbase_exe, tempmaintenancetool, fs::copy_options::overwrite_existing, ec); - Checks::check_exit(VCPKG_LINE_INFO, - !ec, - "Could not write package file %s", - tempmaintenancetool.generic_string()); + Checks::check_exit( + VCPKG_LINE_INFO, !ec, "Could not write package file %s", tempmaintenancetool.generic_string()); fs::path package_xml_file_path = ifw_packages_dir_path / "maintenance" / "meta" / "package.xml"; fs::path package_xml_dir_path = package_xml_file_path.parent_path(); fs.create_directories(package_xml_dir_path, ec); Checks::check_exit(VCPKG_LINE_INFO, - !ec, - "Could not create directory for package file %s", - package_xml_file_path.generic_string()); + !ec, + "Could not create directory for package file %s", + package_xml_file_path.generic_string()); fs.write_contents(package_xml_file_path, - Strings::format( - R"###( + Strings::format( + R"###( Maintenance Tool Maintenance Tool @@ -318,14 +316,12 @@ namespace vcpkg::Commands::Export::IFW true )###", -create_release_date())); + create_release_date())); const fs::path script_source = paths.root / "scripts" / "ifw" / "maintenance.qs"; const fs::path script_destination = ifw_packages_dir_path / "maintenance" / "meta" / "maintenance.qs"; fs.copy_file(script_source, script_destination, fs::copy_options::overwrite_existing, ec); - Checks::check_exit(VCPKG_LINE_INFO, - !ec, - "Could not write package file %s", - script_destination.generic_string()); + Checks::check_exit( + VCPKG_LINE_INFO, !ec, "Could not write package file %s", script_destination.generic_string()); System::println("Exporting maintenance tool... done"); } -- cgit v1.2.3 From 7f68aa6630f96f474e85cd332dbbdc1ce6226d50 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 4 Oct 2017 15:50:48 -0700 Subject: Introduce Util::stable_keep_if() --- toolsrc/include/vcpkg_Util.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg_Util.h b/toolsrc/include/vcpkg_Util.h index c76ca01ac..e5ead6d3a 100644 --- a/toolsrc/include/vcpkg_Util.h +++ b/toolsrc/include/vcpkg_Util.h @@ -37,6 +37,12 @@ namespace vcpkg::Util return ret; } + template + void stable_keep_if(Container& cont, Pred pred) + { + cont.erase(std::stable_partition(cont.begin(), cont.end(), pred), cont.end()); + } + template void unstable_keep_if(Container& cont, Pred pred) { -- cgit v1.2.3 From 9a963f7eff1981d4e894ea8b297d092cda60b764 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 5 Oct 2017 13:51:28 -0700 Subject: Overhaul VS selection. Add triplet option to specify VS instance --- toolsrc/include/VcpkgPaths.h | 5 +- toolsrc/include/vcpkg_Build.h | 3 +- toolsrc/include/vcpkg_Util.h | 15 ++++++ toolsrc/src/PostBuildLint.cpp | 2 +- toolsrc/src/VcpkgPaths.cpp | 120 ++++++++++++++++++++++-------------------- toolsrc/src/commands_env.cpp | 4 +- toolsrc/src/vcpkg_Build.cpp | 12 ++++- 7 files changed, 95 insertions(+), 66 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/VcpkgPaths.h b/toolsrc/include/VcpkgPaths.h index 4b4527434..d4640fba2 100644 --- a/toolsrc/include/VcpkgPaths.h +++ b/toolsrc/include/VcpkgPaths.h @@ -17,6 +17,7 @@ namespace vcpkg struct Toolset { + fs::path visual_studio_root_path; fs::path dumpbin; fs::path vcvarsall; std::vector vcvarsall_options; @@ -66,7 +67,8 @@ namespace vcpkg /// /// Valid version strings are "v140", "v141", and "". Empty string gets the latest. /// - const Toolset& get_toolset(const std::string& toolset_version) const; + const Toolset& VcpkgPaths::get_toolset(const Optional& toolset_version, + const Optional& visual_studio_path) const; Files::Filesystem& get_filesystem() const; @@ -78,6 +80,5 @@ namespace vcpkg Lazy ifw_binarycreator_exe; Lazy ifw_repogen_exe; Lazy> toolsets; - Lazy> toolsets_vs2017_v140; }; } diff --git a/toolsrc/include/vcpkg_Build.h b/toolsrc/include/vcpkg_Build.h index 78e89d4de..5ba675757 100644 --- a/toolsrc/include/vcpkg_Build.h +++ b/toolsrc/include/vcpkg_Build.h @@ -79,7 +79,8 @@ namespace vcpkg::Build std::string target_architecture; std::string cmake_system_name; std::string cmake_system_version; - std::string platform_toolset; + Optional platform_toolset; + Optional visual_studio_path; }; std::wstring make_build_env_cmd(const PreBuildInfo& pre_build_info, const Toolset& toolset); diff --git a/toolsrc/include/vcpkg_Util.h b/toolsrc/include/vcpkg_Util.h index e5ead6d3a..a87045d73 100644 --- a/toolsrc/include/vcpkg_Util.h +++ b/toolsrc/include/vcpkg_Util.h @@ -67,6 +67,21 @@ namespace vcpkg::Util return std::find_if(cont.cbegin(), cont.cend(), pred); } + template + using ToVectorOfConstPointersT = std::decay_t()))>; + + template> + std::vector to_vector_of_const_pointers(const Container& cont) + { + std::vector output; + for (auto i = cont.cbegin(), cend = cont.end(); i != cend; ++i) + { + output.push_back(&(*i)); + } + + return output; + } + template auto find_if_not(const Container& cont, Pred pred) { diff --git a/toolsrc/src/PostBuildLint.cpp b/toolsrc/src/PostBuildLint.cpp index 416d4a636..a0699e15c 100644 --- a/toolsrc/src/PostBuildLint.cpp +++ b/toolsrc/src/PostBuildLint.cpp @@ -722,7 +722,7 @@ namespace vcpkg::PostBuildLint const auto& fs = paths.get_filesystem(); // for dumpbin - const Toolset& toolset = paths.get_toolset(pre_build_info.platform_toolset); + const Toolset& toolset = paths.get_toolset(pre_build_info.platform_toolset, pre_build_info.visual_studio_path); const fs::path package_dir = paths.package_dir(spec); size_t error_count = 0; diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp index 9f85992be..f080783c4 100644 --- a/toolsrc/src/VcpkgPaths.cpp +++ b/toolsrc/src/VcpkgPaths.cpp @@ -337,14 +337,14 @@ namespace vcpkg // VS2015 const Optional vs_2015_installation_instance = get_vs2015_installation_instance(); - if (const auto v = vs_2015_installation_instance.get()) + if (const auto vs_2015_root_path = vs_2015_installation_instance.get()) { - const fs::path vs2015_vcvarsall_bat = *v / "VC" / "vcvarsall.bat"; + const fs::path vs2015_vcvarsall_bat = *vs_2015_root_path / "VC" / "vcvarsall.bat"; paths_examined.push_back(vs2015_vcvarsall_bat); if (fs.exists(vs2015_vcvarsall_bat)) { - const fs::path vs2015_dumpbin_exe = *v / "VC" / "bin" / "dumpbin.exe"; + const fs::path vs2015_dumpbin_exe = *vs_2015_root_path / "VC" / "bin" / "dumpbin.exe"; paths_examined.push_back(vs2015_dumpbin_exe); const fs::path vs2015_bin_dir = vs2015_vcvarsall_bat.parent_path() / "bin"; @@ -364,19 +364,25 @@ namespace vcpkg if (fs.exists(vs2015_dumpbin_exe)) { - found_toolsets.push_back( - {vs2015_dumpbin_exe, vs2015_vcvarsall_bat, {}, V_140, supported_architectures}); + found_toolsets.push_back({*vs_2015_root_path, + vs2015_dumpbin_exe, + vs2015_vcvarsall_bat, + {}, + V_140, + supported_architectures}); } } } + const bool v140_is_available = !found_toolsets.empty(); + const std::vector vs2017_installation_instances = get_vs2017_installation_instances(paths); // VS2017 - Optional vs2017_toolset; for (const std::string& instance : vs2017_installation_instances) { - const fs::path vc_dir = fs::path{instance} / "VC"; + const fs::path vs_root_path = fs::path{instance}; + const fs::path vc_dir = vs_root_path / "VC"; // Skip any instances that do not have vcvarsall. const fs::path vcvarsall_dir = vc_dir / "Auxiliary" / "Build"; @@ -415,14 +421,22 @@ namespace vcpkg paths_examined.push_back(dumpbin_path); if (fs.exists(dumpbin_path)) { - vs2017_toolset = Toolset{dumpbin_path, vcvarsall_bat, {}, V_141, supported_architectures}; + found_toolsets.push_back( + Toolset{vs_root_path, dumpbin_path, vcvarsall_bat, {}, V_141, supported_architectures}); + + if (v140_is_available) + { + found_toolsets.push_back(Toolset{vs_root_path, + dumpbin_path, + vcvarsall_bat, + {L"-vcvars_ver=14.0"}, + V_140, + supported_architectures}); + } + break; } } - if (const auto value = vs2017_toolset.get()) - { - found_toolsets.push_back(*value); - } } if (found_toolsets.empty()) @@ -439,64 +453,54 @@ namespace vcpkg return found_toolsets; } - static std::vector create_vs2017_v140_toolset_instances(const std::vector& vs_toolsets) - { - std::vector vs2017_v140_toolsets; - - // In constrast to v141 and above, there can only be a single instance of v140 (VS2017 vs VS2015). - const auto it = Util::find_if(vs_toolsets, [&](const Toolset& t) { return t.version == V_140; }); - - // If v140 is not available, then VS2017 cant use them. Return empty. - if (it == vs_toolsets.cend()) - { - return vs2017_v140_toolsets; - } - - // If it does exist, then create a matching v140 toolset for each v141 toolset - const Toolset v140_toolset = *it; - for (const Toolset& toolset : vs_toolsets) - { - if (toolset.version != V_141) - { - continue; - } - - Toolset t = Toolset{ - toolset.dumpbin, toolset.vcvarsall, {L"-vcvars_ver=14.0"}, V_140, toolset.supported_architectures}; - vs2017_v140_toolsets.push_back(std::move(t)); - } - - return vs2017_v140_toolsets; - } - - const Toolset& VcpkgPaths::get_toolset(const std::string& toolset_version) const + const Toolset& VcpkgPaths::get_toolset(const Optional& toolset_version, + const Optional& visual_studio_path) const { - const std::wstring& w_toolset_version = Strings::to_utf16(toolset_version); - // Invariant: toolsets are non-empty and sorted with newest at back() const std::vector& vs_toolsets = this->toolsets.get_lazy([this]() { return find_toolset_instances(*this); }); - if (w_toolset_version.empty()) + std::vector candidates = Util::to_vector_of_const_pointers(vs_toolsets); + const auto tsv = toolset_version.get(); + const auto vsp = visual_studio_path.get(); + + if (tsv && vsp) { - return vs_toolsets.back(); + const std::wstring w_toolset_version = Strings::to_utf16(*tsv); + const fs::path vs_root_path = *vsp; + Util::stable_keep_if(candidates, [&](const Toolset* t) { + return w_toolset_version == t->version && vs_root_path == t->visual_studio_root_path; + }); + Checks::check_exit(VCPKG_LINE_INFO, + !candidates.empty(), + "Could not find Visual Studio instace at %s with %s toolset.", + vs_root_path.generic_string(), + *tsv); + + Checks::check_exit(VCPKG_LINE_INFO, candidates.size() == 1); + return *candidates.back(); } - const auto toolset = - Util::find_if(vs_toolsets, [&](const Toolset& t) { return w_toolset_version == t.version; }); - Checks::check_exit( - VCPKG_LINE_INFO, toolset != vs_toolsets.end(), "Could not find toolset '%s'", toolset_version); + if (tsv) + { + const std::wstring w_toolset_version = Strings::to_utf16(*tsv); + Util::stable_keep_if(candidates, [&](const Toolset* t) { return w_toolset_version == t->version; }); + Checks::check_exit( + VCPKG_LINE_INFO, !candidates.empty(), "Could not find Visual Studio instace with %s toolset.", *tsv); + } - // If v140 is the selected toolset and VS2017 is available, then use VS2017's vcvarsall with the - // -vcvars_ver=14.0 option - const std::vector& vs2017_v140_toolsets = this->toolsets_vs2017_v140.get_lazy( - [&vs_toolsets]() { return create_vs2017_v140_toolset_instances(vs_toolsets); }); - if (w_toolset_version == V_140 && !vs2017_v140_toolsets.empty()) + if (vsp) { - return vs2017_v140_toolsets.back(); + const fs::path vs_root_path = *vsp; + Util::stable_keep_if(candidates, + [&](const Toolset* t) { return vs_root_path == t->visual_studio_root_path; }); + Checks::check_exit(VCPKG_LINE_INFO, + !candidates.empty(), + "Could not find Visual Studio instace at %s.", + vs_root_path.generic_string()); } - return *toolset; + return *candidates.back(); } Files::Filesystem& VcpkgPaths::get_filesystem() const { return Files::get_real_filesystem(); } diff --git a/toolsrc/src/commands_env.cpp b/toolsrc/src/commands_env.cpp index 073c501f5..6dad3e882 100644 --- a/toolsrc/src/commands_env.cpp +++ b/toolsrc/src/commands_env.cpp @@ -13,8 +13,8 @@ namespace vcpkg::Commands::Env args.check_and_get_optional_command_arguments({}); const auto pre_build_info = Build::PreBuildInfo::from_triplet_file(paths, default_triplet); - System::cmd_execute_clean( - Build::make_build_env_cmd(pre_build_info, paths.get_toolset(pre_build_info.platform_toolset)) + L" && cmd"); + const Toolset& toolset = paths.get_toolset(pre_build_info.platform_toolset, pre_build_info.visual_studio_path); + System::cmd_execute_clean(Build::make_build_env_cmd(pre_build_info, toolset) + L" && cmd"); Checks::exit_success(VCPKG_LINE_INFO); } diff --git a/toolsrc/src/vcpkg_Build.cpp b/toolsrc/src/vcpkg_Build.cpp index 853f84998..9be20629d 100644 --- a/toolsrc/src/vcpkg_Build.cpp +++ b/toolsrc/src/vcpkg_Build.cpp @@ -138,7 +138,7 @@ namespace vcpkg::Build const fs::path ports_cmake_script_path = paths.ports_cmake; const auto pre_build_info = PreBuildInfo::from_triplet_file(paths, triplet); - const Toolset& toolset = paths.get_toolset(pre_build_info.platform_toolset); + const Toolset& toolset = paths.get_toolset(pre_build_info.platform_toolset, pre_build_info.visual_studio_path); const auto cmd_set_environment = make_build_env_cmd(pre_build_info, toolset); std::string features; @@ -386,7 +386,15 @@ namespace vcpkg::Build if (variable_name == "VCPKG_PLATFORM_TOOLSET") { - pre_build_info.platform_toolset = variable_value; + pre_build_info.platform_toolset = + variable_value.empty() ? nullopt : Optional{variable_value}; + continue; + } + + if (variable_name == "VCPKG_VISUAL_STUDIO_PATH") + { + pre_build_info.visual_studio_path = + variable_value.empty() ? nullopt : Optional{variable_value}; continue; } -- cgit v1.2.3 From 86f3a9dbbdc360db3716b878dd37f2dbec8e983c Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 5 Oct 2017 18:12:17 -0700 Subject: Fix Strings::split() to handle delimiters of arbitrary size --- toolsrc/src/vcpkg_Strings.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg_Strings.cpp b/toolsrc/src/vcpkg_Strings.cpp index 21df2c309..bbe6b29cd 100644 --- a/toolsrc/src/vcpkg_Strings.cpp +++ b/toolsrc/src/vcpkg_Strings.cpp @@ -154,11 +154,13 @@ namespace vcpkg::Strings return output; } + const size_t delimiter_length = delimiter.length(); size_t i = 0; for (size_t pos = s.find(delimiter); pos != std::string::npos; pos = s.find(delimiter, pos)) { output.push_back(s.substr(i, pos - i)); - i = ++pos; + pos += delimiter_length; + i = pos; } // Add the rest of the string after the last delimiter, unless there is nothing after it -- cgit v1.2.3 From f0c23aeb6b238ee0ba2dc272ee4c193f2f777460 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 5 Oct 2017 18:25:34 -0700 Subject: Completely rework Visual Studio detection - Now using vswhere.exe to detect all VS instance (2015 + 2017) - Default version preference order is now: stable, prerelease, legacy - Within each preference weight, the latest one is chosen - findVisualStudioInstallationInstances.ps1 now has a parameter to choose VS instance --- toolsrc/include/vcpkg_Util.h | 14 +-- toolsrc/src/VcpkgPaths.cpp | 209 +++++++++++++++++++++++-------------------- 2 files changed, 117 insertions(+), 106 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg_Util.h b/toolsrc/include/vcpkg_Util.h index a87045d73..facb7dd26 100644 --- a/toolsrc/include/vcpkg_Util.h +++ b/toolsrc/include/vcpkg_Util.h @@ -68,18 +68,12 @@ namespace vcpkg::Util } template - using ToVectorOfConstPointersT = std::decay_t()))>; + using ElementT = std::remove_reference_t()))>; - template> - std::vector to_vector_of_const_pointers(const Container& cont) + template> + std::vector element_pointers(Container&& cont) { - std::vector output; - for (auto i = cont.cbegin(), cend = cont.end(); i != cend; ++i) - { - output.push_back(&(*i)); - } - - return output; + return fmap(cont, [](auto&& x) { return &x; }); } template diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp index f080783c4..8264ec293 100644 --- a/toolsrc/src/VcpkgPaths.cpp +++ b/toolsrc/src/VcpkgPaths.cpp @@ -302,26 +302,33 @@ namespace vcpkg [this]() { return get_ifw_installerbase_exe().parent_path() / "repogen.exe"; }); } - static std::vector get_vs2017_installation_instances(const VcpkgPaths& paths) + struct VisualStudioInstance + { + fs::path root_path; + std::string version; + std::string release_type; + std::string preference_weight; // Mostly unused, just for verification that order is as intended + + std::string major_version() const { return version.substr(0, 2); } + }; + + static std::vector get_visual_studio_instances(const VcpkgPaths& paths) { const fs::path script = paths.scripts / "findVisualStudioInstallationInstances.ps1"; const std::wstring cmd = System::create_powershell_script_cmd(script); const System::ExitCodeAndOutput ec_data = System::cmd_execute_and_capture_output(cmd); - Checks::check_exit(VCPKG_LINE_INFO, ec_data.exit_code == 0, "Could not run script to detect VS 2017 instances"); - return Strings::split(ec_data.output, "\n"); - } + Checks::check_exit( + VCPKG_LINE_INFO, ec_data.exit_code == 0, "Could not run script to detect Visual Studio instances"); - static Optional get_vs2015_installation_instance() - { - const Optional vs2015_cmntools_optional = System::get_environment_variable(L"VS140COMNTOOLS"); - if (const auto v = vs2015_cmntools_optional.get()) + const std::vector instances_as_strings = Strings::split(ec_data.output, "\n"); + std::vector output; + for (const std::string& instance_as_string : instances_as_strings) { - const fs::path vs2015_cmntools = fs::path(*v).parent_path(); // The call to parent_path() is needed because - // the env variable has a trailing backslash - return vs2015_cmntools.parent_path().parent_path(); + const std::vector split = Strings::split(instance_as_string, "::"); + output.push_back({split.at(3), split.at(2), split.at(1), split.at(0)}); } - return nullopt; + return output; } static std::vector find_toolset_instances(const VcpkgPaths& paths) @@ -335,108 +342,118 @@ namespace vcpkg std::vector found_toolsets; - // VS2015 - const Optional vs_2015_installation_instance = get_vs2015_installation_instance(); - if (const auto vs_2015_root_path = vs_2015_installation_instance.get()) - { - const fs::path vs2015_vcvarsall_bat = *vs_2015_root_path / "VC" / "vcvarsall.bat"; + const std::vector vs_instances = get_visual_studio_instances(paths); + const bool v140_is_available = Util::find_if(vs_instances, [&](const VisualStudioInstance& vs_instance) { + return vs_instance.major_version() == "14"; + }) != vs_instances.cend(); - paths_examined.push_back(vs2015_vcvarsall_bat); - if (fs.exists(vs2015_vcvarsall_bat)) + // VS2017 + for (const VisualStudioInstance& vs_instance : vs_instances) + { + const std::string major_version = vs_instance.major_version(); + if (major_version == "15") { - const fs::path vs2015_dumpbin_exe = *vs_2015_root_path / "VC" / "bin" / "dumpbin.exe"; - paths_examined.push_back(vs2015_dumpbin_exe); + const fs::path vc_dir = vs_instance.root_path / "VC"; + + // Skip any instances that do not have vcvarsall. + const fs::path vcvarsall_dir = vc_dir / "Auxiliary" / "Build"; + const fs::path vcvarsall_bat = vcvarsall_dir / "vcvarsall.bat"; + paths_examined.push_back(vcvarsall_bat); + if (!fs.exists(vcvarsall_bat)) continue; - const fs::path vs2015_bin_dir = vs2015_vcvarsall_bat.parent_path() / "bin"; + // Get all supported architectures std::vector supported_architectures; - if (fs.exists(vs2015_bin_dir / "vcvars32.bat")) + if (fs.exists(vcvarsall_dir / "vcvars32.bat")) supported_architectures.push_back({L"x86", CPU::X86, CPU::X86}); - if (fs.exists(vs2015_bin_dir / "amd64\\vcvars64.bat")) - supported_architectures.push_back({L"x64", CPU::X64, CPU::X64}); - if (fs.exists(vs2015_bin_dir / "x86_amd64\\vcvarsx86_amd64.bat")) + if (fs.exists(vcvarsall_dir / "vcvars64.bat")) + supported_architectures.push_back({L"amd64", CPU::X64, CPU::X64}); + if (fs.exists(vcvarsall_dir / "vcvarsx86_amd64.bat")) supported_architectures.push_back({L"x86_amd64", CPU::X86, CPU::X64}); - if (fs.exists(vs2015_bin_dir / "x86_arm\\vcvarsx86_arm.bat")) + if (fs.exists(vcvarsall_dir / "vcvarsx86_arm.bat")) supported_architectures.push_back({L"x86_arm", CPU::X86, CPU::ARM}); - if (fs.exists(vs2015_bin_dir / "amd64_x86\\vcvarsamd64_x86.bat")) + if (fs.exists(vcvarsall_dir / "vcvarsamd64_x86.bat")) supported_architectures.push_back({L"amd64_x86", CPU::X64, CPU::X86}); - if (fs.exists(vs2015_bin_dir / "amd64_arm\\vcvarsamd64_arm.bat")) + if (fs.exists(vcvarsall_dir / "vcvarsamd64_arm.bat")) supported_architectures.push_back({L"amd64_arm", CPU::X64, CPU::ARM}); - if (fs.exists(vs2015_dumpbin_exe)) + // Locate the "best" MSVC toolchain version + const fs::path msvc_path = vc_dir / "Tools" / "MSVC"; + std::vector 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) { return left.filename() > right.filename(); }); + + for (const fs::path& subdir : msvc_subdirectories) { - found_toolsets.push_back({*vs_2015_root_path, - vs2015_dumpbin_exe, - vs2015_vcvarsall_bat, - {}, - V_140, - supported_architectures}); + const fs::path dumpbin_path = subdir / "bin" / "HostX86" / "x86" / "dumpbin.exe"; + paths_examined.push_back(dumpbin_path); + if (fs.exists(dumpbin_path)) + { + found_toolsets.push_back(Toolset{ + vs_instance.root_path, dumpbin_path, vcvarsall_bat, {}, V_141, supported_architectures}); + + if (v140_is_available) + { + found_toolsets.push_back(Toolset{vs_instance.root_path, + dumpbin_path, + vcvarsall_bat, + {L"-vcvars_ver=14.0"}, + V_140, + supported_architectures}); + } + + break; + } } - } - } - const bool v140_is_available = !found_toolsets.empty(); - - const std::vector vs2017_installation_instances = get_vs2017_installation_instances(paths); + continue; + } - // VS2017 - for (const std::string& instance : vs2017_installation_instances) - { - const fs::path vs_root_path = fs::path{instance}; - const fs::path vc_dir = vs_root_path / "VC"; - - // Skip any instances that do not have vcvarsall. - const fs::path vcvarsall_dir = vc_dir / "Auxiliary" / "Build"; - const fs::path vcvarsall_bat = vcvarsall_dir / "vcvarsall.bat"; - paths_examined.push_back(vcvarsall_bat); - if (!fs.exists(vcvarsall_bat)) continue; - - // Get all supported architectures - std::vector supported_architectures; - if (fs.exists(vcvarsall_dir / "vcvars32.bat")) - supported_architectures.push_back({L"x86", CPU::X86, CPU::X86}); - if (fs.exists(vcvarsall_dir / "vcvars64.bat")) - supported_architectures.push_back({L"amd64", CPU::X64, CPU::X64}); - if (fs.exists(vcvarsall_dir / "vcvarsx86_amd64.bat")) - supported_architectures.push_back({L"x86_amd64", CPU::X86, CPU::X64}); - if (fs.exists(vcvarsall_dir / "vcvarsx86_arm.bat")) - supported_architectures.push_back({L"x86_arm", CPU::X86, CPU::ARM}); - if (fs.exists(vcvarsall_dir / "vcvarsamd64_x86.bat")) - supported_architectures.push_back({L"amd64_x86", CPU::X64, CPU::X86}); - if (fs.exists(vcvarsall_dir / "vcvarsamd64_arm.bat")) - supported_architectures.push_back({L"amd64_arm", CPU::X64, CPU::ARM}); - - // Locate the "best" MSVC toolchain version - const fs::path msvc_path = vc_dir / "Tools" / "MSVC"; - std::vector 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) { return left.filename() > right.filename(); }); - - for (const fs::path& subdir : msvc_subdirectories) + if (major_version == "14") { - const fs::path dumpbin_path = subdir / "bin" / "HostX86" / "x86" / "dumpbin.exe"; - paths_examined.push_back(dumpbin_path); - if (fs.exists(dumpbin_path)) - { - found_toolsets.push_back( - Toolset{vs_root_path, dumpbin_path, vcvarsall_bat, {}, V_141, supported_architectures}); + const fs::path vcvarsall_bat = vs_instance.root_path / "VC" / "vcvarsall.bat"; - if (v140_is_available) + paths_examined.push_back(vcvarsall_bat); + if (fs.exists(vcvarsall_bat)) + { + const fs::path vs2015_dumpbin_exe = vs_instance.root_path / "VC" / "bin" / "dumpbin.exe"; + paths_examined.push_back(vs2015_dumpbin_exe); + + const fs::path vs2015_bin_dir = vcvarsall_bat.parent_path() / "bin"; + std::vector supported_architectures; + if (fs.exists(vs2015_bin_dir / "vcvars32.bat")) + supported_architectures.push_back({L"x86", CPU::X86, CPU::X86}); + if (fs.exists(vs2015_bin_dir / "amd64\\vcvars64.bat")) + supported_architectures.push_back({L"x64", CPU::X64, CPU::X64}); + if (fs.exists(vs2015_bin_dir / "x86_amd64\\vcvarsx86_amd64.bat")) + supported_architectures.push_back({L"x86_amd64", CPU::X86, CPU::X64}); + if (fs.exists(vs2015_bin_dir / "x86_arm\\vcvarsx86_arm.bat")) + supported_architectures.push_back({L"x86_arm", CPU::X86, CPU::ARM}); + if (fs.exists(vs2015_bin_dir / "amd64_x86\\vcvarsamd64_x86.bat")) + supported_architectures.push_back({L"amd64_x86", CPU::X64, CPU::X86}); + if (fs.exists(vs2015_bin_dir / "amd64_arm\\vcvarsamd64_arm.bat")) + supported_architectures.push_back({L"amd64_arm", CPU::X64, CPU::ARM}); + + if (fs.exists(vs2015_dumpbin_exe)) { - found_toolsets.push_back(Toolset{vs_root_path, - dumpbin_path, - vcvarsall_bat, - {L"-vcvars_ver=14.0"}, - V_140, - supported_architectures}); + found_toolsets.push_back({vs_instance.root_path, + vs2015_dumpbin_exe, + vcvarsall_bat, + {}, + V_140, + supported_architectures}); } - - break; } + + continue; } + + Checks::exit_with_message(VCPKG_LINE_INFO, "Expected major version 14 or 15 but got: %s", major_version); } if (found_toolsets.empty()) @@ -460,7 +477,7 @@ namespace vcpkg const std::vector& vs_toolsets = this->toolsets.get_lazy([this]() { return find_toolset_instances(*this); }); - std::vector candidates = Util::to_vector_of_const_pointers(vs_toolsets); + std::vector candidates = Util::element_pointers(vs_toolsets); const auto tsv = toolset_version.get(); const auto vsp = visual_studio_path.get(); @@ -500,7 +517,7 @@ namespace vcpkg vs_root_path.generic_string()); } - return *candidates.back(); + return *candidates.front(); } Files::Filesystem& VcpkgPaths::get_filesystem() const { return Files::get_real_filesystem(); } -- cgit v1.2.3 From 9ae4b9f885c6bb3ede212d42c51f2b96fbfc86dd Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 5 Oct 2017 19:01:48 -0700 Subject: Update CHANGELOG and bump version to v0.0.91 --- toolsrc/VERSION.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/VERSION.txt b/toolsrc/VERSION.txt index c47961221..04ab0d2c9 100644 --- a/toolsrc/VERSION.txt +++ b/toolsrc/VERSION.txt @@ -1 +1 @@ -"0.0.90" \ No newline at end of file +"0.0.91" \ No newline at end of file -- cgit v1.2.3 From 540046b564f95d262f5e4d2a4f988485e6469742 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Thu, 5 Oct 2017 22:16:43 -0700 Subject: [vcpkg] Remove assert that vswhere returns only 14 or 15. --- toolsrc/src/VcpkgPaths.cpp | 2 -- 1 file changed, 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp index 8264ec293..d84a2d281 100644 --- a/toolsrc/src/VcpkgPaths.cpp +++ b/toolsrc/src/VcpkgPaths.cpp @@ -452,8 +452,6 @@ namespace vcpkg continue; } - - Checks::exit_with_message(VCPKG_LINE_INFO, "Expected major version 14 or 15 but got: %s", major_version); } if (found_toolsets.empty()) -- cgit v1.2.3 From 3a6e34804a878ce0c3f74b208f9a5c0bdc75ec7b Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 5 Oct 2017 22:46:55 -0700 Subject: Remove stray comment --- toolsrc/src/VcpkgPaths.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp index d84a2d281..08f21df34 100644 --- a/toolsrc/src/VcpkgPaths.cpp +++ b/toolsrc/src/VcpkgPaths.cpp @@ -347,7 +347,6 @@ namespace vcpkg return vs_instance.major_version() == "14"; }) != vs_instances.cend(); - // VS2017 for (const VisualStudioInstance& vs_instance : vs_instances) { const std::string major_version = vs_instance.major_version(); -- cgit v1.2.3 From 03c17e20268bb8bdbfec8710be80fd1310d38dff Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 5 Oct 2017 22:47:45 -0700 Subject: Remove unneeded "continue" --- toolsrc/src/VcpkgPaths.cpp | 2 -- 1 file changed, 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp index 08f21df34..e3e83af30 100644 --- a/toolsrc/src/VcpkgPaths.cpp +++ b/toolsrc/src/VcpkgPaths.cpp @@ -448,8 +448,6 @@ namespace vcpkg supported_architectures}); } } - - continue; } } -- cgit v1.2.3 From cd4142d3cac144c6f4e558cdfe8403e1987ff833 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 6 Oct 2017 14:06:02 -0700 Subject: Bump version of nuget to 4.3.0 (was 4.1.0) --- toolsrc/src/VcpkgPaths.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp index e3e83af30..d14002e47 100644 --- a/toolsrc/src/VcpkgPaths.cpp +++ b/toolsrc/src/VcpkgPaths.cpp @@ -130,10 +130,10 @@ namespace vcpkg fs::path get_nuget_path(const fs::path& downloads_folder, const fs::path& scripts_folder) { - static constexpr std::array EXPECTED_VERSION = {4, 1, 0}; + static constexpr std::array EXPECTED_VERSION = {4, 3, 0}; static const std::wstring VERSION_CHECK_ARGUMENTS = Strings::WEMPTY; - const fs::path downloaded_copy = downloads_folder / "nuget-4.1.0" / "nuget.exe"; + const fs::path downloaded_copy = downloads_folder / "nuget-4.3.0" / "nuget.exe"; const std::vector from_path = Files::find_from_PATH(L"nuget"); std::vector candidate_paths; -- cgit v1.2.3 From 7cd465b8897bd9487db6d990e58dcac472b3d4d6 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 11 Oct 2017 17:56:01 -0700 Subject: `vcpkg install` Print summary when using the --keep-going flag --- toolsrc/src/commands_install.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/commands_install.cpp b/toolsrc/src/commands_install.cpp index d815332fe..4411dd3ae 100644 --- a/toolsrc/src/commands_install.cpp +++ b/toolsrc/src/commands_install.cpp @@ -556,6 +556,7 @@ namespace vcpkg::Commands::Install const bool no_downloads = options.find(OPTION_NO_DOWNLOADS) != options.cend(); const bool is_recursive = options.find(OPTION_RECURSE) != options.cend(); const KeepGoing keep_going = to_keep_going(options.find(OPTION_KEEP_GOING) != options.cend()); + const PrintSummary print_summary = to_print_summary(keep_going == KeepGoing::YES); // create the plan StatusParagraphs status_db = database_load_check(paths); @@ -606,7 +607,7 @@ namespace vcpkg::Commands::Install Checks::exit_success(VCPKG_LINE_INFO); } - perform_and_exit(action_plan, install_plan_options, keep_going, PrintSummary::NO, paths, status_db); + perform_and_exit(action_plan, install_plan_options, keep_going, print_summary, paths, status_db); Checks::exit_success(VCPKG_LINE_INFO); } -- cgit v1.2.3 From 00d89dbd66a658174233920d6be2a85f282ef29f Mon Sep 17 00:00:00 2001 From: Mikhail Paulyshka Date: Sun, 24 Sep 2017 16:01:37 +0300 Subject: vcpkg: initial ARM64 support --- toolsrc/src/PostBuildLint.cpp | 1 + toolsrc/src/VcpkgPaths.cpp | 4 ++++ 2 files changed, 5 insertions(+) (limited to 'toolsrc') diff --git a/toolsrc/src/PostBuildLint.cpp b/toolsrc/src/PostBuildLint.cpp index a0699e15c..6d9a0da73 100644 --- a/toolsrc/src/PostBuildLint.cpp +++ b/toolsrc/src/PostBuildLint.cpp @@ -361,6 +361,7 @@ namespace vcpkg::PostBuildLint case MachineType::I386: return "x86"; case MachineType::ARM: case MachineType::ARMNT: return "arm"; + case MachineType::ARM64: return "arm64"; default: return "Machine Type Code = " + std::to_string(static_cast(machine_type)); } } diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp index d14002e47..dac9e40e7 100644 --- a/toolsrc/src/VcpkgPaths.cpp +++ b/toolsrc/src/VcpkgPaths.cpp @@ -370,10 +370,14 @@ namespace vcpkg supported_architectures.push_back({L"x86_amd64", CPU::X86, CPU::X64}); if (fs.exists(vcvarsall_dir / "vcvarsx86_arm.bat")) supported_architectures.push_back({L"x86_arm", CPU::X86, CPU::ARM}); + if (fs.exists(vcvarsall_dir / "vcvarsx86_arm64.bat")) + supported_architectures.push_back({L"x86_arm64", CPU::X86, CPU::ARM64}); if (fs.exists(vcvarsall_dir / "vcvarsamd64_x86.bat")) supported_architectures.push_back({L"amd64_x86", CPU::X64, CPU::X86}); if (fs.exists(vcvarsall_dir / "vcvarsamd64_arm.bat")) supported_architectures.push_back({L"amd64_arm", CPU::X64, CPU::ARM}); + if (fs.exists(vcvarsall_dir / "vcvarsamd64_arm64.bat")) + supported_architectures.push_back({L"amd64_arm64", CPU::X64, CPU::ARM64}); // Locate the "best" MSVC toolchain version const fs::path msvc_path = vc_dir / "Tools" / "MSVC"; -- cgit v1.2.3 From dcfb9d45c13ba3adc22a47d62642f6acd2ee239b Mon Sep 17 00:00:00 2001 From: jasjuang Date: Thu, 12 Oct 2017 04:09:52 -0700 Subject: add NVCUDASAMPLES_ROOT to whitelist --- toolsrc/src/vcpkg_System.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg_System.cpp b/toolsrc/src/vcpkg_System.cpp index 3b4c440d8..5293638e3 100644 --- a/toolsrc/src/vcpkg_System.cpp +++ b/toolsrc/src/vcpkg_System.cpp @@ -106,6 +106,8 @@ namespace vcpkg::System L"HTTPS_PROXY", // Enables find_package(CUDA) in CMake L"CUDA_PATH", + // Environmental variable generated automatically by CUDA after installation + L"NVCUDASAMPLES_ROOT", }; // Flush stdout before launching external process -- cgit v1.2.3 From 3efcc3d377750b753d516fd21b9009bfcd6e3877 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 12 Oct 2017 11:45:08 -0700 Subject: Fix #1963 (permissive- issue) --- toolsrc/include/VcpkgPaths.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/VcpkgPaths.h b/toolsrc/include/VcpkgPaths.h index d4640fba2..a38865a3f 100644 --- a/toolsrc/include/VcpkgPaths.h +++ b/toolsrc/include/VcpkgPaths.h @@ -67,8 +67,8 @@ namespace vcpkg /// /// Valid version strings are "v140", "v141", and "". Empty string gets the latest. /// - const Toolset& VcpkgPaths::get_toolset(const Optional& toolset_version, - const Optional& visual_studio_path) const; + const Toolset& get_toolset(const Optional& toolset_version, + const Optional& visual_studio_path) const; Files::Filesystem& get_filesystem() const; -- cgit v1.2.3 From 9e19c24d2911ff1ef648aeed0c596e3987eafebf Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 12 Oct 2017 14:03:01 -0700 Subject: `vcpkg autocomplete` More work on autocomplete --- toolsrc/src/commands_autocomplete.cpp | 83 +++++++++++++++++++++++++---------- 1 file changed, 61 insertions(+), 22 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/commands_autocomplete.cpp b/toolsrc/src/commands_autocomplete.cpp index 3963f904b..abad19df7 100644 --- a/toolsrc/src/commands_autocomplete.cpp +++ b/toolsrc/src/commands_autocomplete.cpp @@ -1,9 +1,8 @@ #include "pch.h" #include "Paragraphs.h" -#include "SortedVector.h" +#include "metrics.h" #include "vcpkg_Commands.h" -#include "vcpkg_Maps.h" #include "vcpkg_System.h" #include "vcpkglib.h" @@ -35,7 +34,7 @@ namespace vcpkg::Commands::Autocomplete for (const auto& installed_package : installed_packages) { - auto sp = installed_package->package.displayname(); + const auto sp = installed_package->package.displayname(); if (istartswith(sp, start_with)) { @@ -47,33 +46,73 @@ namespace vcpkg::Commands::Autocomplete void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { - static const std::string EXAMPLE = - Strings::format("The argument should be a command line to autocomplete.\n%s", - Commands::Help::create_example_string("autocomplete install z")); + Metrics::g_metrics.lock()->set_send_metrics(false); - args.check_min_arg_count(1, EXAMPLE); - args.check_max_arg_count(2, EXAMPLE); - args.check_and_get_optional_command_arguments({}); + if (args.command_arguments.size() != 1) + { + Checks::exit_success(VCPKG_LINE_INFO); + } - const std::string requested_command = args.command_arguments.at(0); - const std::string start_with = - args.command_arguments.size() > 1 ? args.command_arguments.at(1) : Strings::EMPTY; - std::vector results; - if (requested_command == "install") + const std::string to_autocomplete = args.command_arguments.at(0); + const std::vector tokens = Strings::split(to_autocomplete, " "); + if (tokens.size() == 1) { - auto sources_and_errors = Paragraphs::try_load_all_ports(paths.get_filesystem(), paths.ports); - auto& source_paragraphs = sources_and_errors.paragraphs; + const std::string requested_command = tokens[0]; + + std::vector valid_commands = {"install", + "search", + "remove", + "list", + "update", + "hash", + "help", + "integrate", + "export", + "edit", + "create", + "owns", + "cache", + "version", + "contact"}; + + Util::unstable_keep_if(valid_commands, [&](const std::string& s) { + return Strings::case_insensitive_ascii_starts_with(s, requested_command); + }); - results = autocomplete_install(source_paragraphs, start_with); + if (valid_commands.size() == 1) + { + System::println(valid_commands[0] + " "); + } + else + { + System::println(Strings::join("\n", valid_commands)); + } + + Checks::exit_success(VCPKG_LINE_INFO); } - else if (requested_command == "remove") + + if (tokens.size() == 2) { - const StatusParagraphs status_db = database_load_check(paths); - std::vector installed_packages = get_installed_ports(status_db); - results = autocomplete_remove(installed_packages, start_with); + const std::string requested_command = tokens[0]; + const std::string start_with = tokens[1]; + std::vector results; + if (requested_command == "install") + { + auto sources_and_errors = Paragraphs::try_load_all_ports(paths.get_filesystem(), paths.ports); + auto& source_paragraphs = sources_and_errors.paragraphs; + + results = autocomplete_install(source_paragraphs, start_with); + } + else if (requested_command == "remove") + { + const StatusParagraphs status_db = database_load_check(paths); + const std::vector installed_packages = get_installed_ports(status_db); + results = autocomplete_remove(installed_packages, start_with); + } + + System::println(Strings::join("\n", results)); } - System::println(Strings::join(" ", results)); Checks::exit_success(VCPKG_LINE_INFO); } } -- cgit v1.2.3 From 37fba399ef5c57573a1218206cb2c55f5f6bc13c Mon Sep 17 00:00:00 2001 From: Konstantin Podsvirov Date: Fri, 13 Oct 2017 05:33:32 +0300 Subject: [vcpkg-export-ifw] Safe description QtIFW support rich text for component description, bu some port has not safe ampersand symbol in description text (for example 'openexr' package), that should be replaced to '&' symbol name --- toolsrc/src/commands_export_ifw.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/commands_export_ifw.cpp b/toolsrc/src/commands_export_ifw.cpp index 191dbb763..c001a93ed 100644 --- a/toolsrc/src/commands_export_ifw.cpp +++ b/toolsrc/src/commands_export_ifw.cpp @@ -26,6 +26,14 @@ namespace vcpkg::Commands::Export::IFW return date_time_as_string; } + std::string safe_rich_from_plain_text(const std::string& text) + { + // match standalone ampersand, no HTML number or name + std::regex standalone_ampersand(R"###(&(?!(#[0-9]+|\w+);))###"); + + return std::regex_replace(text, standalone_ampersand, "&"); + } + fs::path get_packages_dir_path(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths) { return ifw_options.maybe_packages_dir_path.has_value() @@ -156,7 +164,7 @@ namespace vcpkg::Commands::Export::IFW )###", action.spec.name(), - binary_paragraph.description, + safe_rich_from_plain_text(binary_paragraph.description), binary_paragraph.version, create_release_date())); } -- cgit v1.2.3 From f6a0d78c82789af482eb3c885cbbb73aba7dfb38 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 13 Oct 2017 14:54:31 -0700 Subject: `autocomplete` Rework command, fixing a lot of corner cases in the process --- toolsrc/include/vcpkg_Commands.h | 8 ++--- toolsrc/src/commands_autocomplete.cpp | 66 ++++++++++++++++------------------- 2 files changed, 34 insertions(+), 40 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg_Commands.h b/toolsrc/include/vcpkg_Commands.h index 7cfa2760e..c9a33a8f4 100644 --- a/toolsrc/include/vcpkg_Commands.h +++ b/toolsrc/include/vcpkg_Commands.h @@ -194,10 +194,10 @@ namespace vcpkg::Commands void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); } - namespace Autocomplete - { - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); - } + namespace Autocomplete + { + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); + } namespace Help { diff --git a/toolsrc/src/commands_autocomplete.cpp b/toolsrc/src/commands_autocomplete.cpp index abad19df7..478a3c478 100644 --- a/toolsrc/src/commands_autocomplete.cpp +++ b/toolsrc/src/commands_autocomplete.cpp @@ -5,6 +5,7 @@ #include "vcpkg_Commands.h" #include "vcpkg_System.h" #include "vcpkglib.h" +#include namespace vcpkg::Commands::Autocomplete { @@ -44,20 +45,26 @@ namespace vcpkg::Commands::Autocomplete return results; } + [[noreturn]] static void output_sorted_results_and_exit(const LineInfo& line_info, + std::vector&& results) + { + const SortedVector sorted_results(results); + System::println(Strings::join("\n", sorted_results)); + Checks::exit_success(line_info); + } + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { Metrics::g_metrics.lock()->set_send_metrics(false); + const std::string to_autocomplete = Strings::join(" ", args.command_arguments); + const std::vector tokens = Strings::split(to_autocomplete, " "); - if (args.command_arguments.size() != 1) - { - Checks::exit_success(VCPKG_LINE_INFO); - } + std::smatch match; - const std::string to_autocomplete = args.command_arguments.at(0); - const std::vector tokens = Strings::split(to_autocomplete, " "); - if (tokens.size() == 1) + // Handles vcpkg + if (std::regex_match(to_autocomplete, match, std::regex{R"###(^(\S*)$)###"})) { - const std::string requested_command = tokens[0]; + const std::string requested_command = match[1].str(); std::vector valid_commands = {"install", "search", @@ -79,38 +86,25 @@ namespace vcpkg::Commands::Autocomplete return Strings::case_insensitive_ascii_starts_with(s, requested_command); }); - if (valid_commands.size() == 1) - { - System::println(valid_commands[0] + " "); - } - else - { - System::println(Strings::join("\n", valid_commands)); - } - - Checks::exit_success(VCPKG_LINE_INFO); + output_sorted_results_and_exit(VCPKG_LINE_INFO, std::move(valid_commands)); } - if (tokens.size() == 2) + // Handles vcpkg install + if (std::regex_match(to_autocomplete, match, std::regex{R"###(^install.* (\S*)$)###"})) { - const std::string requested_command = tokens[0]; - const std::string start_with = tokens[1]; - std::vector results; - if (requested_command == "install") - { - auto sources_and_errors = Paragraphs::try_load_all_ports(paths.get_filesystem(), paths.ports); - auto& source_paragraphs = sources_and_errors.paragraphs; - - results = autocomplete_install(source_paragraphs, start_with); - } - else if (requested_command == "remove") - { - const StatusParagraphs status_db = database_load_check(paths); - const std::vector installed_packages = get_installed_ports(status_db); - results = autocomplete_remove(installed_packages, start_with); - } + const std::string start_with = match[1].str(); + auto sources_and_errors = Paragraphs::try_load_all_ports(paths.get_filesystem(), paths.ports); + auto& source_paragraphs = sources_and_errors.paragraphs; + output_sorted_results_and_exit(VCPKG_LINE_INFO, autocomplete_install(source_paragraphs, start_with)); + } - System::println(Strings::join("\n", results)); + // Handles vcpkg remove + if (std::regex_match(to_autocomplete, match, std::regex{R"###(^remove.* (\S*)$)###"})) + { + const std::string start_with = match[1].str(); + const StatusParagraphs status_db = database_load_check(paths); + const std::vector installed_packages = get_installed_ports(status_db); + output_sorted_results_and_exit(VCPKG_LINE_INFO, autocomplete_remove(installed_packages, start_with)); } Checks::exit_success(VCPKG_LINE_INFO); -- cgit v1.2.3 From d46a992b3cbbbf3479ad3906aecd07e73174cd40 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 13 Oct 2017 15:17:11 -0700 Subject: Don't do function "aliasing" --- toolsrc/src/commands_autocomplete.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/commands_autocomplete.cpp b/toolsrc/src/commands_autocomplete.cpp index 478a3c478..6ded74f9b 100644 --- a/toolsrc/src/commands_autocomplete.cpp +++ b/toolsrc/src/commands_autocomplete.cpp @@ -13,13 +13,12 @@ namespace vcpkg::Commands::Autocomplete const std::vector>& source_paragraphs, const std::string& start_with) { std::vector results; - const auto& istartswith = Strings::case_insensitive_ascii_starts_with; for (const auto& source_control_file : source_paragraphs) { auto&& sp = *source_control_file->core_paragraph; - if (istartswith(sp.name, start_with)) + if (Strings::case_insensitive_ascii_starts_with(sp.name, start_with)) { results.push_back(sp.name); } @@ -31,13 +30,12 @@ namespace vcpkg::Commands::Autocomplete const std::string& start_with) { std::vector results; - const auto& istartswith = Strings::case_insensitive_ascii_starts_with; for (const auto& installed_package : installed_packages) { const auto sp = installed_package->package.displayname(); - if (istartswith(sp, start_with)) + if (Strings::case_insensitive_ascii_starts_with(sp, start_with)) { results.push_back(sp); } -- cgit v1.2.3 From e17de99599a2f114faab1bb4821fbaad4d266c95 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Fri, 13 Oct 2017 18:37:41 -0700 Subject: [vcpkg] Re-layout all files using new organization scheme. All filenames and directories are lowercase. Use dots for namespace separation. --- toolsrc/include/BinaryParagraph.h | 41 - toolsrc/include/CStringView.h | 96 --- toolsrc/include/LineInfo.h | 19 - toolsrc/include/MachineType.h | 36 - toolsrc/include/PackageSpec.h | 95 --- toolsrc/include/PackageSpecParseResult.h | 32 - toolsrc/include/ParagraphParseResult.h | 32 - toolsrc/include/Paragraphs.h | 38 - toolsrc/include/PostBuildLint.h | 12 - toolsrc/include/PostBuildLint_BuildType.h | 66 -- toolsrc/include/SortedVector.h | 50 -- toolsrc/include/SourceParagraph.h | 96 --- toolsrc/include/Span.h | 52 -- toolsrc/include/StatusParagraph.h | 44 -- toolsrc/include/StatusParagraphs.h | 46 -- toolsrc/include/VcpkgCmdArguments.h | 49 -- toolsrc/include/VcpkgPaths.h | 84 -- toolsrc/include/VersionT.h | 29 - toolsrc/include/coff_file_reader.h | 21 - toolsrc/include/filesystem_fs.h | 16 - toolsrc/include/lazy.h | 26 - toolsrc/include/metrics.h | 28 - toolsrc/include/pch.h | 8 +- toolsrc/include/triplet.h | 43 -- toolsrc/include/vcpkg/base/checks.h | 55 ++ toolsrc/include/vcpkg/base/chrono.h | 28 + toolsrc/include/vcpkg/base/cofffilereader.h | 23 + toolsrc/include/vcpkg/base/cstringview.h | 97 +++ toolsrc/include/vcpkg/base/enums.h | 12 + toolsrc/include/vcpkg/base/expected.h | 115 +++ toolsrc/include/vcpkg/base/files.h | 57 ++ toolsrc/include/vcpkg/base/graphs.h | 161 ++++ toolsrc/include/vcpkg/base/lazy.h | 26 + toolsrc/include/vcpkg/base/lineinfo.h | 19 + toolsrc/include/vcpkg/base/machinetype.h | 37 + toolsrc/include/vcpkg/base/optional.h | 99 +++ toolsrc/include/vcpkg/base/sortedvector.h | 50 ++ toolsrc/include/vcpkg/base/span.h | 60 ++ toolsrc/include/vcpkg/base/strings.h | 114 +++ toolsrc/include/vcpkg/base/system.h | 108 +++ toolsrc/include/vcpkg/base/util.h | 156 ++++ toolsrc/include/vcpkg/binaryparagraph.h | 42 + toolsrc/include/vcpkg/build.h | 205 +++++ toolsrc/include/vcpkg/commands.h | 134 ++++ toolsrc/include/vcpkg/dependencies.h | 149 ++++ toolsrc/include/vcpkg/export.h | 10 + toolsrc/include/vcpkg/export.ifw.h | 26 + toolsrc/include/vcpkg/globalstate.h | 19 + toolsrc/include/vcpkg/help.h | 19 + toolsrc/include/vcpkg/input.h | 15 + toolsrc/include/vcpkg/install.h | 69 ++ toolsrc/include/vcpkg/metrics.h | 28 + toolsrc/include/vcpkg/packagespec.h | 95 +++ toolsrc/include/vcpkg/packagespecparseresult.h | 33 + toolsrc/include/vcpkg/paragraphparseresult.h | 33 + toolsrc/include/vcpkg/paragraphs.h | 38 + toolsrc/include/vcpkg/parse.h | 38 + toolsrc/include/vcpkg/postbuildlint.buildtype.h | 68 ++ toolsrc/include/vcpkg/postbuildlint.h | 13 + toolsrc/include/vcpkg/remove.h | 24 + toolsrc/include/vcpkg/sourceparagraph.h | 97 +++ toolsrc/include/vcpkg/statusparagraph.h | 45 ++ toolsrc/include/vcpkg/statusparagraphs.h | 47 ++ toolsrc/include/vcpkg/triplet.h | 43 ++ toolsrc/include/vcpkg/update.h | 21 + toolsrc/include/vcpkg/vcpkgcmdarguments.h | 50 ++ toolsrc/include/vcpkg/vcpkglib.h | 38 + toolsrc/include/vcpkg/vcpkgpaths.h | 85 +++ toolsrc/include/vcpkg/versiont.h | 29 + toolsrc/include/vcpkg_Build.h | 192 ----- toolsrc/include/vcpkg_Checks.h | 54 -- toolsrc/include/vcpkg_Chrono.h | 28 - toolsrc/include/vcpkg_Commands.h | 258 ------- toolsrc/include/vcpkg_Commands_Export.h | 8 - toolsrc/include/vcpkg_Commands_Export_IFW.h | 25 - toolsrc/include/vcpkg_Dependencies.h | 147 ---- toolsrc/include/vcpkg_Enums.h | 10 - toolsrc/include/vcpkg_Files.h | 43 -- toolsrc/include/vcpkg_GlobalState.h | 19 - toolsrc/include/vcpkg_Graphs.h | 159 ---- toolsrc/include/vcpkg_Input.h | 14 - toolsrc/include/vcpkg_Maps.h | 30 - toolsrc/include/vcpkg_Parse.h | 38 - toolsrc/include/vcpkg_Strings.h | 113 --- toolsrc/include/vcpkg_System.h | 107 --- toolsrc/include/vcpkg_Util.h | 144 ---- toolsrc/include/vcpkg_expected.h | 114 --- toolsrc/include/vcpkg_optional.h | 98 --- toolsrc/include/vcpkglib.h | 38 - toolsrc/src/BinaryParagraph.cpp | 123 --- toolsrc/src/LineInfo.cpp | 9 - toolsrc/src/MachineType.cpp | 41 - toolsrc/src/PackageSpec.cpp | 175 ----- toolsrc/src/PackageSpecParseResult.cpp | 20 - toolsrc/src/ParagraphParseResult.cpp | 34 - toolsrc/src/Paragraphs.cpp | 304 -------- toolsrc/src/PostBuildLint.cpp | 846 --------------------- toolsrc/src/PostBuildLint_BuildType.cpp | 70 -- toolsrc/src/SourceParagraph.cpp | 262 ------- toolsrc/src/StatusParagraph.cpp | 86 --- toolsrc/src/StatusParagraphs.cpp | 90 --- toolsrc/src/VcpkgCmdArguments.cpp | 283 ------- toolsrc/src/VcpkgPaths.cpp | 519 ------------- toolsrc/src/VersionT.cpp | 19 - toolsrc/src/coff_file_reader.cpp | 308 -------- toolsrc/src/commands_autocomplete.cpp | 79 -- toolsrc/src/commands_available_commands.cpp | 50 -- toolsrc/src/commands_build.cpp | 102 --- toolsrc/src/commands_build_external.cpp | 21 - toolsrc/src/commands_cache.cpp | 68 -- toolsrc/src/commands_ci.cpp | 60 -- toolsrc/src/commands_contact.cpp | 22 - toolsrc/src/commands_create.cpp | 38 - toolsrc/src/commands_depends.cpp | 55 -- toolsrc/src/commands_edit.cpp | 86 --- toolsrc/src/commands_env.cpp | 21 - toolsrc/src/commands_export.cpp | 526 ------------- toolsrc/src/commands_export_ifw.cpp | 481 ------------ toolsrc/src/commands_hash.cpp | 55 -- toolsrc/src/commands_help.cpp | 131 ---- toolsrc/src/commands_import.cpp | 119 --- toolsrc/src/commands_install.cpp | 613 --------------- toolsrc/src/commands_integrate.cpp | 342 --------- toolsrc/src/commands_list.cpp | 74 -- toolsrc/src/commands_owns.cpp | 37 - toolsrc/src/commands_portsdiff.cpp | 181 ----- toolsrc/src/commands_remove.cpp | 249 ------ toolsrc/src/commands_search.cpp | 145 ---- toolsrc/src/commands_update.cpp | 73 -- toolsrc/src/commands_version.cpp | 67 -- toolsrc/src/metrics.cpp | 395 ---------- toolsrc/src/test_install_plan.cpp | 486 ------------ toolsrc/src/tests.arguments.cpp | 58 ++ toolsrc/src/tests.dependencies.cpp | 110 +++ toolsrc/src/tests.installplan.cpp | 487 ++++++++++++ toolsrc/src/tests.packagespec.cpp | 120 +++ toolsrc/src/tests.paragraph.cpp | 389 ++++++++++ toolsrc/src/tests_arguments.cpp | 58 -- toolsrc/src/tests_dependencies.cpp | 110 --- toolsrc/src/tests_package_spec.cpp | 119 --- toolsrc/src/tests_paragraph.cpp | 388 ---------- toolsrc/src/triplet.cpp | 55 -- toolsrc/src/vcpkg.cpp | 56 +- toolsrc/src/vcpkg/base/checks.cpp | 81 ++ toolsrc/src/vcpkg/base/chrono.cpp | 61 ++ toolsrc/src/vcpkg/base/cofffilereader.cpp | 308 ++++++++ toolsrc/src/vcpkg/base/enums.cpp | 14 + toolsrc/src/vcpkg/base/files.cpp | 208 +++++ toolsrc/src/vcpkg/base/lineinfo.cpp | 9 + toolsrc/src/vcpkg/base/machinetype.cpp | 41 + toolsrc/src/vcpkg/base/strings.cpp | 174 +++++ toolsrc/src/vcpkg/base/system.cpp | 350 +++++++++ toolsrc/src/vcpkg/binaryparagraph.cpp | 123 +++ toolsrc/src/vcpkg/build.cpp | 533 +++++++++++++ toolsrc/src/vcpkg/commands.autocomplete.cpp | 78 ++ toolsrc/src/vcpkg/commands.buildexternal.cpp | 23 + toolsrc/src/vcpkg/commands.cache.cpp | 69 ++ toolsrc/src/vcpkg/commands.ci.cpp | 62 ++ toolsrc/src/vcpkg/commands.contact.cpp | 22 + toolsrc/src/vcpkg/commands.cpp | 56 ++ toolsrc/src/vcpkg/commands.create.cpp | 39 + toolsrc/src/vcpkg/commands.dependinfo.cpp | 56 ++ toolsrc/src/vcpkg/commands.edit.cpp | 87 +++ toolsrc/src/vcpkg/commands.env.cpp | 22 + toolsrc/src/vcpkg/commands.exportifw.cpp | 482 ++++++++++++ toolsrc/src/vcpkg/commands.hash.cpp | 55 ++ toolsrc/src/vcpkg/commands.import.cpp | 120 +++ toolsrc/src/vcpkg/commands.integrate.cpp | 342 +++++++++ toolsrc/src/vcpkg/commands.list.cpp | 75 ++ toolsrc/src/vcpkg/commands.owns.cpp | 38 + toolsrc/src/vcpkg/commands.portsdiff.cpp | 182 +++++ toolsrc/src/vcpkg/commands.search.cpp | 146 ++++ toolsrc/src/vcpkg/commands.version.cpp | 67 ++ toolsrc/src/vcpkg/dependencies.cpp | 669 ++++++++++++++++ toolsrc/src/vcpkg/export.cpp | 528 +++++++++++++ toolsrc/src/vcpkg/globalstate.cpp | 13 + toolsrc/src/vcpkg/help.cpp | 131 ++++ toolsrc/src/vcpkg/input.cpp | 55 ++ toolsrc/src/vcpkg/install.cpp | 615 +++++++++++++++ toolsrc/src/vcpkg/metrics.cpp | 398 ++++++++++ toolsrc/src/vcpkg/packagespec.cpp | 175 +++++ toolsrc/src/vcpkg/packagespecparseresult.cpp | 21 + toolsrc/src/vcpkg/paragraphparseresult.cpp | 34 + toolsrc/src/vcpkg/paragraphs.cpp | 304 ++++++++ toolsrc/src/vcpkg/parse.cpp | 81 ++ toolsrc/src/vcpkg/postbuildlint.buildtype.cpp | 70 ++ toolsrc/src/vcpkg/postbuildlint.cpp | 846 +++++++++++++++++++++ toolsrc/src/vcpkg/remove.cpp | 251 ++++++ toolsrc/src/vcpkg/sourceparagraph.cpp | 264 +++++++ toolsrc/src/vcpkg/statusparagraph.cpp | 86 +++ toolsrc/src/vcpkg/statusparagraphs.cpp | 89 +++ toolsrc/src/vcpkg/triplet.cpp | 55 ++ toolsrc/src/vcpkg/update.cpp | 75 ++ toolsrc/src/vcpkg/vcpkgcmdarguments.cpp | 284 +++++++ toolsrc/src/vcpkg/vcpkglib.cpp | 247 ++++++ toolsrc/src/vcpkg/vcpkgpaths.cpp | 519 +++++++++++++ toolsrc/src/vcpkg/versiont.cpp | 19 + toolsrc/src/vcpkg_Build.cpp | 406 ---------- toolsrc/src/vcpkg_Build_BuildPolicy.cpp | 40 - toolsrc/src/vcpkg_Checks.cpp | 81 -- toolsrc/src/vcpkg_Chrono.cpp | 61 -- toolsrc/src/vcpkg_Dependencies.cpp | 669 ---------------- toolsrc/src/vcpkg_Enums.cpp | 14 - toolsrc/src/vcpkg_Files.cpp | 209 ----- toolsrc/src/vcpkg_GlobalState.cpp | 13 - toolsrc/src/vcpkg_Input.cpp | 54 -- toolsrc/src/vcpkg_Parse.cpp | 80 -- toolsrc/src/vcpkg_Strings.cpp | 174 ----- toolsrc/src/vcpkg_System.cpp | 349 --------- toolsrc/src/vcpkg_metrics_uploader.cpp | 18 - toolsrc/src/vcpkglib.cpp | 247 ------ toolsrc/src/vcpkgmetricsuploader.cpp | 20 + toolsrc/vcpkglib/vcpkglib.vcxproj | 198 ++--- toolsrc/vcpkglib/vcpkglib.vcxproj.filters | 416 +++++----- .../vcpkgmetricsuploader.vcxproj | 2 +- .../vcpkgmetricsuploader.vcxproj.filters | 2 +- toolsrc/vcpkgtest/vcpkgtest.vcxproj | 10 +- toolsrc/vcpkgtest/vcpkgtest.vcxproj.filters | 10 +- 218 files changed, 14032 insertions(+), 13936 deletions(-) delete mode 100644 toolsrc/include/BinaryParagraph.h delete mode 100644 toolsrc/include/CStringView.h delete mode 100644 toolsrc/include/LineInfo.h delete mode 100644 toolsrc/include/MachineType.h delete mode 100644 toolsrc/include/PackageSpec.h delete mode 100644 toolsrc/include/PackageSpecParseResult.h delete mode 100644 toolsrc/include/ParagraphParseResult.h delete mode 100644 toolsrc/include/Paragraphs.h delete mode 100644 toolsrc/include/PostBuildLint.h delete mode 100644 toolsrc/include/PostBuildLint_BuildType.h delete mode 100644 toolsrc/include/SortedVector.h delete mode 100644 toolsrc/include/SourceParagraph.h delete mode 100644 toolsrc/include/Span.h delete mode 100644 toolsrc/include/StatusParagraph.h delete mode 100644 toolsrc/include/StatusParagraphs.h delete mode 100644 toolsrc/include/VcpkgCmdArguments.h delete mode 100644 toolsrc/include/VcpkgPaths.h delete mode 100644 toolsrc/include/VersionT.h delete mode 100644 toolsrc/include/coff_file_reader.h delete mode 100644 toolsrc/include/filesystem_fs.h delete mode 100644 toolsrc/include/lazy.h delete mode 100644 toolsrc/include/metrics.h delete mode 100644 toolsrc/include/triplet.h create mode 100644 toolsrc/include/vcpkg/base/checks.h create mode 100644 toolsrc/include/vcpkg/base/chrono.h create mode 100644 toolsrc/include/vcpkg/base/cofffilereader.h create mode 100644 toolsrc/include/vcpkg/base/cstringview.h create mode 100644 toolsrc/include/vcpkg/base/enums.h create mode 100644 toolsrc/include/vcpkg/base/expected.h create mode 100644 toolsrc/include/vcpkg/base/files.h create mode 100644 toolsrc/include/vcpkg/base/graphs.h create mode 100644 toolsrc/include/vcpkg/base/lazy.h create mode 100644 toolsrc/include/vcpkg/base/lineinfo.h create mode 100644 toolsrc/include/vcpkg/base/machinetype.h create mode 100644 toolsrc/include/vcpkg/base/optional.h create mode 100644 toolsrc/include/vcpkg/base/sortedvector.h create mode 100644 toolsrc/include/vcpkg/base/span.h create mode 100644 toolsrc/include/vcpkg/base/strings.h create mode 100644 toolsrc/include/vcpkg/base/system.h create mode 100644 toolsrc/include/vcpkg/base/util.h create mode 100644 toolsrc/include/vcpkg/binaryparagraph.h create mode 100644 toolsrc/include/vcpkg/build.h create mode 100644 toolsrc/include/vcpkg/commands.h create mode 100644 toolsrc/include/vcpkg/dependencies.h create mode 100644 toolsrc/include/vcpkg/export.h create mode 100644 toolsrc/include/vcpkg/export.ifw.h create mode 100644 toolsrc/include/vcpkg/globalstate.h create mode 100644 toolsrc/include/vcpkg/help.h create mode 100644 toolsrc/include/vcpkg/input.h create mode 100644 toolsrc/include/vcpkg/install.h create mode 100644 toolsrc/include/vcpkg/metrics.h create mode 100644 toolsrc/include/vcpkg/packagespec.h create mode 100644 toolsrc/include/vcpkg/packagespecparseresult.h create mode 100644 toolsrc/include/vcpkg/paragraphparseresult.h create mode 100644 toolsrc/include/vcpkg/paragraphs.h create mode 100644 toolsrc/include/vcpkg/parse.h create mode 100644 toolsrc/include/vcpkg/postbuildlint.buildtype.h create mode 100644 toolsrc/include/vcpkg/postbuildlint.h create mode 100644 toolsrc/include/vcpkg/remove.h create mode 100644 toolsrc/include/vcpkg/sourceparagraph.h create mode 100644 toolsrc/include/vcpkg/statusparagraph.h create mode 100644 toolsrc/include/vcpkg/statusparagraphs.h create mode 100644 toolsrc/include/vcpkg/triplet.h create mode 100644 toolsrc/include/vcpkg/update.h create mode 100644 toolsrc/include/vcpkg/vcpkgcmdarguments.h create mode 100644 toolsrc/include/vcpkg/vcpkglib.h create mode 100644 toolsrc/include/vcpkg/vcpkgpaths.h create mode 100644 toolsrc/include/vcpkg/versiont.h delete mode 100644 toolsrc/include/vcpkg_Build.h delete mode 100644 toolsrc/include/vcpkg_Checks.h delete mode 100644 toolsrc/include/vcpkg_Chrono.h delete mode 100644 toolsrc/include/vcpkg_Commands.h delete mode 100644 toolsrc/include/vcpkg_Commands_Export.h delete mode 100644 toolsrc/include/vcpkg_Commands_Export_IFW.h delete mode 100644 toolsrc/include/vcpkg_Dependencies.h delete mode 100644 toolsrc/include/vcpkg_Enums.h delete mode 100644 toolsrc/include/vcpkg_Files.h delete mode 100644 toolsrc/include/vcpkg_GlobalState.h delete mode 100644 toolsrc/include/vcpkg_Graphs.h delete mode 100644 toolsrc/include/vcpkg_Input.h delete mode 100644 toolsrc/include/vcpkg_Maps.h delete mode 100644 toolsrc/include/vcpkg_Parse.h delete mode 100644 toolsrc/include/vcpkg_Strings.h delete mode 100644 toolsrc/include/vcpkg_System.h delete mode 100644 toolsrc/include/vcpkg_Util.h delete mode 100644 toolsrc/include/vcpkg_expected.h delete mode 100644 toolsrc/include/vcpkg_optional.h delete mode 100644 toolsrc/include/vcpkglib.h delete mode 100644 toolsrc/src/BinaryParagraph.cpp delete mode 100644 toolsrc/src/LineInfo.cpp delete mode 100644 toolsrc/src/MachineType.cpp delete mode 100644 toolsrc/src/PackageSpec.cpp delete mode 100644 toolsrc/src/PackageSpecParseResult.cpp delete mode 100644 toolsrc/src/ParagraphParseResult.cpp delete mode 100644 toolsrc/src/Paragraphs.cpp delete mode 100644 toolsrc/src/PostBuildLint.cpp delete mode 100644 toolsrc/src/PostBuildLint_BuildType.cpp delete mode 100644 toolsrc/src/SourceParagraph.cpp delete mode 100644 toolsrc/src/StatusParagraph.cpp delete mode 100644 toolsrc/src/StatusParagraphs.cpp delete mode 100644 toolsrc/src/VcpkgCmdArguments.cpp delete mode 100644 toolsrc/src/VcpkgPaths.cpp delete mode 100644 toolsrc/src/VersionT.cpp delete mode 100644 toolsrc/src/coff_file_reader.cpp delete mode 100644 toolsrc/src/commands_autocomplete.cpp delete mode 100644 toolsrc/src/commands_available_commands.cpp delete mode 100644 toolsrc/src/commands_build.cpp delete mode 100644 toolsrc/src/commands_build_external.cpp delete mode 100644 toolsrc/src/commands_cache.cpp delete mode 100644 toolsrc/src/commands_ci.cpp delete mode 100644 toolsrc/src/commands_contact.cpp delete mode 100644 toolsrc/src/commands_create.cpp delete mode 100644 toolsrc/src/commands_depends.cpp delete mode 100644 toolsrc/src/commands_edit.cpp delete mode 100644 toolsrc/src/commands_env.cpp delete mode 100644 toolsrc/src/commands_export.cpp delete mode 100644 toolsrc/src/commands_export_ifw.cpp delete mode 100644 toolsrc/src/commands_hash.cpp delete mode 100644 toolsrc/src/commands_help.cpp delete mode 100644 toolsrc/src/commands_import.cpp delete mode 100644 toolsrc/src/commands_install.cpp delete mode 100644 toolsrc/src/commands_integrate.cpp delete mode 100644 toolsrc/src/commands_list.cpp delete mode 100644 toolsrc/src/commands_owns.cpp delete mode 100644 toolsrc/src/commands_portsdiff.cpp delete mode 100644 toolsrc/src/commands_remove.cpp delete mode 100644 toolsrc/src/commands_search.cpp delete mode 100644 toolsrc/src/commands_update.cpp delete mode 100644 toolsrc/src/commands_version.cpp delete mode 100644 toolsrc/src/metrics.cpp delete mode 100644 toolsrc/src/test_install_plan.cpp create mode 100644 toolsrc/src/tests.arguments.cpp create mode 100644 toolsrc/src/tests.dependencies.cpp create mode 100644 toolsrc/src/tests.installplan.cpp create mode 100644 toolsrc/src/tests.packagespec.cpp create mode 100644 toolsrc/src/tests.paragraph.cpp delete mode 100644 toolsrc/src/tests_arguments.cpp delete mode 100644 toolsrc/src/tests_dependencies.cpp delete mode 100644 toolsrc/src/tests_package_spec.cpp delete mode 100644 toolsrc/src/tests_paragraph.cpp delete mode 100644 toolsrc/src/triplet.cpp create mode 100644 toolsrc/src/vcpkg/base/checks.cpp create mode 100644 toolsrc/src/vcpkg/base/chrono.cpp create mode 100644 toolsrc/src/vcpkg/base/cofffilereader.cpp create mode 100644 toolsrc/src/vcpkg/base/enums.cpp create mode 100644 toolsrc/src/vcpkg/base/files.cpp create mode 100644 toolsrc/src/vcpkg/base/lineinfo.cpp create mode 100644 toolsrc/src/vcpkg/base/machinetype.cpp create mode 100644 toolsrc/src/vcpkg/base/strings.cpp create mode 100644 toolsrc/src/vcpkg/base/system.cpp create mode 100644 toolsrc/src/vcpkg/binaryparagraph.cpp create mode 100644 toolsrc/src/vcpkg/build.cpp create mode 100644 toolsrc/src/vcpkg/commands.autocomplete.cpp create mode 100644 toolsrc/src/vcpkg/commands.buildexternal.cpp create mode 100644 toolsrc/src/vcpkg/commands.cache.cpp create mode 100644 toolsrc/src/vcpkg/commands.ci.cpp create mode 100644 toolsrc/src/vcpkg/commands.contact.cpp create mode 100644 toolsrc/src/vcpkg/commands.cpp create mode 100644 toolsrc/src/vcpkg/commands.create.cpp create mode 100644 toolsrc/src/vcpkg/commands.dependinfo.cpp create mode 100644 toolsrc/src/vcpkg/commands.edit.cpp create mode 100644 toolsrc/src/vcpkg/commands.env.cpp create mode 100644 toolsrc/src/vcpkg/commands.exportifw.cpp create mode 100644 toolsrc/src/vcpkg/commands.hash.cpp create mode 100644 toolsrc/src/vcpkg/commands.import.cpp create mode 100644 toolsrc/src/vcpkg/commands.integrate.cpp create mode 100644 toolsrc/src/vcpkg/commands.list.cpp create mode 100644 toolsrc/src/vcpkg/commands.owns.cpp create mode 100644 toolsrc/src/vcpkg/commands.portsdiff.cpp create mode 100644 toolsrc/src/vcpkg/commands.search.cpp create mode 100644 toolsrc/src/vcpkg/commands.version.cpp create mode 100644 toolsrc/src/vcpkg/dependencies.cpp create mode 100644 toolsrc/src/vcpkg/export.cpp create mode 100644 toolsrc/src/vcpkg/globalstate.cpp create mode 100644 toolsrc/src/vcpkg/help.cpp create mode 100644 toolsrc/src/vcpkg/input.cpp create mode 100644 toolsrc/src/vcpkg/install.cpp create mode 100644 toolsrc/src/vcpkg/metrics.cpp create mode 100644 toolsrc/src/vcpkg/packagespec.cpp create mode 100644 toolsrc/src/vcpkg/packagespecparseresult.cpp create mode 100644 toolsrc/src/vcpkg/paragraphparseresult.cpp create mode 100644 toolsrc/src/vcpkg/paragraphs.cpp create mode 100644 toolsrc/src/vcpkg/parse.cpp create mode 100644 toolsrc/src/vcpkg/postbuildlint.buildtype.cpp create mode 100644 toolsrc/src/vcpkg/postbuildlint.cpp create mode 100644 toolsrc/src/vcpkg/remove.cpp create mode 100644 toolsrc/src/vcpkg/sourceparagraph.cpp create mode 100644 toolsrc/src/vcpkg/statusparagraph.cpp create mode 100644 toolsrc/src/vcpkg/statusparagraphs.cpp create mode 100644 toolsrc/src/vcpkg/triplet.cpp create mode 100644 toolsrc/src/vcpkg/update.cpp create mode 100644 toolsrc/src/vcpkg/vcpkgcmdarguments.cpp create mode 100644 toolsrc/src/vcpkg/vcpkglib.cpp create mode 100644 toolsrc/src/vcpkg/vcpkgpaths.cpp create mode 100644 toolsrc/src/vcpkg/versiont.cpp delete mode 100644 toolsrc/src/vcpkg_Build.cpp delete mode 100644 toolsrc/src/vcpkg_Build_BuildPolicy.cpp delete mode 100644 toolsrc/src/vcpkg_Checks.cpp delete mode 100644 toolsrc/src/vcpkg_Chrono.cpp delete mode 100644 toolsrc/src/vcpkg_Dependencies.cpp delete mode 100644 toolsrc/src/vcpkg_Enums.cpp delete mode 100644 toolsrc/src/vcpkg_Files.cpp delete mode 100644 toolsrc/src/vcpkg_GlobalState.cpp delete mode 100644 toolsrc/src/vcpkg_Input.cpp delete mode 100644 toolsrc/src/vcpkg_Parse.cpp delete mode 100644 toolsrc/src/vcpkg_Strings.cpp delete mode 100644 toolsrc/src/vcpkg_System.cpp delete mode 100644 toolsrc/src/vcpkg_metrics_uploader.cpp delete mode 100644 toolsrc/src/vcpkglib.cpp create mode 100644 toolsrc/src/vcpkgmetricsuploader.cpp (limited to 'toolsrc') diff --git a/toolsrc/include/BinaryParagraph.h b/toolsrc/include/BinaryParagraph.h deleted file mode 100644 index 61e03343a..000000000 --- a/toolsrc/include/BinaryParagraph.h +++ /dev/null @@ -1,41 +0,0 @@ -#pragma once - -#include "PackageSpec.h" -#include "SourceParagraph.h" -#include - -namespace vcpkg -{ - /// - /// Built package metadata - /// - struct BinaryParagraph - { - BinaryParagraph(); - explicit BinaryParagraph(std::unordered_map fields); - BinaryParagraph(const SourceParagraph& spgh, const Triplet& triplet); - BinaryParagraph(const SourceParagraph& spgh, const FeatureParagraph& fpgh, const Triplet& triplet); - - std::string displayname() const; - - std::string fullstem() const; - - std::string dir() const; - - PackageSpec spec; - std::string version; - std::string description; - std::string maintainer; - std::string feature; - std::vector default_features; - std::vector depends; - }; - - struct BinaryControlFile - { - BinaryParagraph core_paragraph; - std::vector features; - }; - - void serialize(const BinaryParagraph& pgh, std::string& out_str); -} \ No newline at end of file diff --git a/toolsrc/include/CStringView.h b/toolsrc/include/CStringView.h deleted file mode 100644 index c1810b4f1..000000000 --- a/toolsrc/include/CStringView.h +++ /dev/null @@ -1,96 +0,0 @@ -#pragma once -#include - -namespace vcpkg -{ - template - struct BasicCStringView - { - constexpr BasicCStringView() : cstr(nullptr) {} - constexpr BasicCStringView(const CharType* cstr) : cstr(cstr) {} - constexpr BasicCStringView(const BasicCStringView&) = default; - BasicCStringView(const std::basic_string& str) : cstr(str.c_str()) {} - - constexpr const CharType* c_str() const { return cstr; } - - private: - const CharType* cstr; - }; - - namespace details - { - inline bool vcpkg_strcmp(const char* l, const char* r) { return strcmp(l, r) == 0; } - inline bool vcpkg_strcmp(const wchar_t* l, const wchar_t* r) { return wcscmp(l, r) == 0; } - } - - template - bool operator==(const BasicCStringView& l, const BasicCStringView& r) - { - return details::vcpkg_strcmp(l.c_str(), r.c_str()); - } - - template - bool operator==(const CharType* l, const BasicCStringView& r) - { - return details::vcpkg_strcmp(l, r.c_str()); - } - - template - bool operator==(const BasicCStringView& r, const CharType* l) - { - return details::vcpkg_strcmp(l, r.c_str()); - } - - template - bool operator==(const std::basic_string& l, const BasicCStringView& r) - { - return l == r.c_str(); - } - - template - bool operator==(const BasicCStringView& r, const std::basic_string& l) - { - return l == r.c_str(); - } - - // notequals - template - bool operator!=(const BasicCStringView& l, const BasicCStringView& r) - { - return !details::vcpkg_strcmp(l.c_str(), r.c_str()); - } - - template - bool operator!=(const CharType* l, const BasicCStringView& r) - { - return !details::vcpkg_strcmp(l, r.c_str()); - } - - template - bool operator!=(const BasicCStringView& r, const CharType* l) - { - return !details::vcpkg_strcmp(l, r.c_str()); - } - - template - bool operator!=(const BasicCStringView& r, const std::basic_string& l) - { - return l != r.c_str(); - } - - template - bool operator!=(const std::basic_string& l, const BasicCStringView& r) - { - return l != r.c_str(); - } - - using CStringView = BasicCStringView; - using CWStringView = BasicCStringView; - - inline const char* to_printf_arg(const CStringView string_view) { return string_view.c_str(); } - - inline const wchar_t* to_wprintf_arg(const CWStringView string_view) { return string_view.c_str(); } - - static_assert(sizeof(CStringView) == sizeof(void*), "CStringView must be a simple wrapper around char*"); - static_assert(sizeof(CWStringView) == sizeof(void*), "CWStringView must be a simple wrapper around wchar_t*"); -} diff --git a/toolsrc/include/LineInfo.h b/toolsrc/include/LineInfo.h deleted file mode 100644 index 62973462a..000000000 --- a/toolsrc/include/LineInfo.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include - -namespace vcpkg -{ - struct LineInfo - { - int line_number; - const char* file_name; - - constexpr LineInfo() : line_number(0), file_name(nullptr) {} - constexpr LineInfo(const int lineno, const char* filename) : line_number(lineno), file_name(filename) {} - - std::string to_string() const; - }; -} - -#define VCPKG_LINE_INFO vcpkg::LineInfo(__LINE__, __FILE__) diff --git a/toolsrc/include/MachineType.h b/toolsrc/include/MachineType.h deleted file mode 100644 index 6f61bbd53..000000000 --- a/toolsrc/include/MachineType.h +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once -#include - -namespace vcpkg -{ - enum class MachineType : uint16_t - { - UNKNOWN = 0x0, // The contents of this field are assumed to be applicable to any machine type - AM33 = 0x1d3, // Matsushita AM33 - AMD64 = 0x8664, // x64 - ARM = 0x1c0, // ARM little endian - ARM64 = 0xaa64, // ARM64 little endian - ARMNT = 0x1c4, // ARM Thumb-2 little endian - EBC = 0xebc, // EFI byte code - I386 = 0x14c, // Intel 386 or later processors and compatible processors - IA64 = 0x200, // Intel Itanium processor family - M32R = 0x9041, // Mitsubishi M32R little endian - MIPS16 = 0x266, // MIPS16 - MIPSFPU = 0x366, // MIPS with FPU - MIPSFPU16 = 0x466, // MIPS16 with FPU - POWERPC = 0x1f0, // Power PC little endian - POWERPCFP = 0x1f1, // Power PC with floating point support - R4000 = 0x166, // MIPS little endian - RISCV32 = 0x5032, // RISC-V 32-bit address space - RISCV64 = 0x5064, // RISC-V 64-bit address space - RISCV128 = 0x5128, // RISC-V 128-bit address space - SH3 = 0x1a2, // Hitachi SH3 - SH3DSP = 0x1a3, // Hitachi SH3 DSP - SH4 = 0x1a6, // Hitachi SH4 - SH5 = 0x1a8, // Hitachi SH5 - THUMB = 0x1c2, // Thumb - WCEMIPSV2 = 0x169, // MIPS little-endian WCE v2 - }; - - MachineType to_machine_type(const uint16_t value); -} diff --git a/toolsrc/include/PackageSpec.h b/toolsrc/include/PackageSpec.h deleted file mode 100644 index c5ce767f9..000000000 --- a/toolsrc/include/PackageSpec.h +++ /dev/null @@ -1,95 +0,0 @@ -#pragma once - -#include "PackageSpecParseResult.h" -#include "Triplet.h" -#include "vcpkg_expected.h" - -namespace vcpkg -{ - struct ParsedSpecifier - { - std::string name; - std::vector features; - std::string triplet; - - static ExpectedT from_string(const std::string& input); - }; - - struct PackageSpec - { - static ExpectedT from_name_and_triplet(const std::string& name, - const Triplet& triplet); - - const std::string& name() const; - - const Triplet& triplet() const; - - std::string dir() const; - - std::string to_string() const; - - private: - std::string m_name; - Triplet m_triplet; - }; - - struct FeatureSpec - { - FeatureSpec(const PackageSpec& spec, const std::string& feature) : m_spec(spec), m_feature(feature) {} - - const std::string& name() const { return m_spec.name(); } - const std::string& feature() const { return m_feature; } - const Triplet& triplet() const { return m_spec.triplet(); } - - const PackageSpec& spec() const { return m_spec; } - - std::string to_string() const; - - static std::vector from_strings_and_triplet(const std::vector& depends, - const Triplet& t); - - private: - PackageSpec m_spec; - std::string m_feature; - }; - - struct FullPackageSpec - { - PackageSpec package_spec; - std::vector features; - - static std::vector to_feature_specs(const std::vector& specs); - - static ExpectedT from_string(const std::string& spec_as_string, - const Triplet& default_triplet); - }; - - struct Features - { - std::string name; - std::vector features; - - static ExpectedT from_string(const std::string& input); - }; - - bool operator==(const PackageSpec& left, const PackageSpec& right); - bool operator!=(const PackageSpec& left, const PackageSpec& right); -} - -template<> -struct std::hash -{ - size_t operator()(const vcpkg::PackageSpec& value) const - { - size_t hash = 17; - hash = hash * 31 + std::hash()(value.name()); - hash = hash * 31 + std::hash()(value.triplet()); - return hash; - } -}; - -template<> -struct std::equal_to -{ - bool operator()(const vcpkg::PackageSpec& left, const vcpkg::PackageSpec& right) const { return left == right; } -}; diff --git a/toolsrc/include/PackageSpecParseResult.h b/toolsrc/include/PackageSpecParseResult.h deleted file mode 100644 index 1462b8073..000000000 --- a/toolsrc/include/PackageSpecParseResult.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -#include "vcpkg_expected.h" - -namespace vcpkg -{ - enum class PackageSpecParseResult - { - SUCCESS = 0, - TOO_MANY_COLONS, - INVALID_CHARACTERS - }; - - CStringView to_string(PackageSpecParseResult ev) noexcept; - - template<> - struct ErrorHolder - { - ErrorHolder() : m_err(PackageSpecParseResult::SUCCESS) {} - ErrorHolder(PackageSpecParseResult err) : m_err(err) {} - - constexpr bool has_error() const { return m_err != PackageSpecParseResult::SUCCESS; } - - const PackageSpecParseResult& error() const { return m_err; } - PackageSpecParseResult& error() { return m_err; } - - CStringView to_string() const { return vcpkg::to_string(m_err); } - - private: - PackageSpecParseResult m_err; - }; -} diff --git a/toolsrc/include/ParagraphParseResult.h b/toolsrc/include/ParagraphParseResult.h deleted file mode 100644 index eaa7e6327..000000000 --- a/toolsrc/include/ParagraphParseResult.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once -#include - -namespace vcpkg -{ - enum class ParagraphParseResult - { - SUCCESS = 0, - EXPECTED_ONE_PARAGRAPH - }; - - struct ParagraphParseResultCategoryImpl final : std::error_category - { - virtual const char* name() const noexcept override; - - virtual std::string message(int ev) const noexcept override; - }; - - const std::error_category& paragraph_parse_result_category(); - - std::error_code make_error_code(ParagraphParseResult e); - - ParagraphParseResult to_paragraph_parse_result(int i); - - ParagraphParseResult to_paragraph_parse_result(std::error_code ec); -} - -// Enable implicit conversion to std::error_code -template<> -struct std::is_error_code_enum : ::std::true_type -{ -}; diff --git a/toolsrc/include/Paragraphs.h b/toolsrc/include/Paragraphs.h deleted file mode 100644 index aae46f7da..000000000 --- a/toolsrc/include/Paragraphs.h +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once - -#include - -#include "BinaryParagraph.h" -#include "VcpkgPaths.h" -#include "VersionT.h" -#include "filesystem_fs.h" -#include "vcpkg_Parse.h" -#include "vcpkg_expected.h" - -namespace vcpkg::Paragraphs -{ - using RawParagraph = Parse::RawParagraph; - - Expected get_single_paragraph(const Files::Filesystem& fs, const fs::path& control_path); - Expected> get_paragraphs(const Files::Filesystem& fs, const fs::path& control_path); - Expected parse_single_paragraph(const std::string& str); - Expected> parse_paragraphs(const std::string& str); - - Parse::ParseExpected try_load_port(const Files::Filesystem& fs, const fs::path& control_path); - - Expected try_load_cached_control_package(const VcpkgPaths& paths, const PackageSpec& spec); - - struct LoadResults - { - std::vector> paragraphs; - std::vector> errors; - }; - - LoadResults try_load_all_ports(const Files::Filesystem& fs, const fs::path& ports_dir); - - std::vector> load_all_ports(const Files::Filesystem& fs, - const fs::path& ports_dir); - - std::map load_all_port_names_and_versions(const Files::Filesystem& fs, - const fs::path& ports_dir); -} diff --git a/toolsrc/include/PostBuildLint.h b/toolsrc/include/PostBuildLint.h deleted file mode 100644 index 69fafc9f7..000000000 --- a/toolsrc/include/PostBuildLint.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once -#include "PackageSpec.h" -#include "VcpkgPaths.h" -#include "vcpkg_Build.h" - -namespace vcpkg::PostBuildLint -{ - size_t perform_all_checks(const PackageSpec& spec, - const VcpkgPaths& paths, - const Build::PreBuildInfo& pre_build_info, - const Build::BuildInfo& build_info); -} diff --git a/toolsrc/include/PostBuildLint_BuildType.h b/toolsrc/include/PostBuildLint_BuildType.h deleted file mode 100644 index 38ad3084e..000000000 --- a/toolsrc/include/PostBuildLint_BuildType.h +++ /dev/null @@ -1,66 +0,0 @@ -#pragma once -#include "CStringView.h" -#include "vcpkg_Build.h" -#include -#include - -namespace vcpkg::PostBuildLint -{ - enum class ConfigurationType - { - DEBUG, - RELEASE, - }; - - struct BuildType - { - enum class BackingEnum - { - DEBUG_STATIC = 1, - DEBUG_DYNAMIC, - RELEASE_STATIC, - RELEASE_DYNAMIC - }; - - static BuildType value_of(const ConfigurationType& config, const Build::LinkageType& linkage); - - BuildType() = delete; - - constexpr BuildType(const BackingEnum backing_enum, - const ConfigurationType config, - const Build::LinkageType linkage) - : backing_enum(backing_enum), m_config(config), m_linkage(linkage) - { - } - - constexpr operator BackingEnum() const { return backing_enum; } - - const ConfigurationType& config() const; - const Build::LinkageType& linkage() const; - const std::regex& crt_regex() const; - const std::string& to_string() const; - - private: - BackingEnum backing_enum; - ConfigurationType m_config; - Build::LinkageType m_linkage; - }; - - namespace BuildTypeC - { - using Build::LinkageType; - using BE = BuildType::BackingEnum; - - static constexpr CStringView ENUM_NAME = "vcpkg::PostBuildLint::BuildType"; - - static constexpr BuildType DEBUG_STATIC = {BE::DEBUG_STATIC, ConfigurationType::DEBUG, LinkageType::STATIC}; - static constexpr BuildType DEBUG_DYNAMIC = {BE::DEBUG_DYNAMIC, ConfigurationType::DEBUG, LinkageType::DYNAMIC}; - static constexpr BuildType RELEASE_STATIC = { - BE::RELEASE_STATIC, ConfigurationType::RELEASE, LinkageType::STATIC}; - static constexpr BuildType RELEASE_DYNAMIC = { - BE::RELEASE_DYNAMIC, ConfigurationType::RELEASE, LinkageType::DYNAMIC}; - - static constexpr std::array VALUES = { - DEBUG_STATIC, DEBUG_DYNAMIC, RELEASE_STATIC, RELEASE_DYNAMIC}; - } -} diff --git a/toolsrc/include/SortedVector.h b/toolsrc/include/SortedVector.h deleted file mode 100644 index 62808cc2f..000000000 --- a/toolsrc/include/SortedVector.h +++ /dev/null @@ -1,50 +0,0 @@ -#pragma once - -#include -#include - -// Add more forwarding functions to the m_data std::vector as needed. -namespace vcpkg -{ - template - class SortedVector - { - public: - using size_type = typename std::vector::size_type; - using iterator = typename std::vector::const_iterator; - - SortedVector() : m_data() {} - - explicit SortedVector(std::vector v) : m_data(std::move(v)) - { - if (!std::is_sorted(m_data.begin(), m_data.end())) - { - std::sort(m_data.begin(), m_data.end()); - } - } - - template - SortedVector(std::vector v, Compare comp) : m_data(std::move(v)) - { - if (!std::is_sorted(m_data.cbegin(), m_data.cend(), comp)) - { - std::sort(m_data.begin(), m_data.end(), comp); - } - } - - iterator begin() const { return this->m_data.cbegin(); } - - iterator end() const { return this->m_data.cend(); } - - iterator cbegin() const { return this->m_data.cbegin(); } - - iterator cend() const { return this->m_data.cend(); } - - bool empty() const { return this->m_data.empty(); } - - size_type size() const { return this->m_data.size(); } - - private: - std::vector m_data; - }; -} diff --git a/toolsrc/include/SourceParagraph.h b/toolsrc/include/SourceParagraph.h deleted file mode 100644 index ccf9faf4f..000000000 --- a/toolsrc/include/SourceParagraph.h +++ /dev/null @@ -1,96 +0,0 @@ -#pragma once - -#include "PackageSpec.h" -#include "Span.h" -#include "vcpkg_Parse.h" -#include "vcpkg_System.h" -#include "vcpkg_expected.h" - -#include -#include - -namespace vcpkg -{ - struct Dependency - { - Features depend; - std::string qualifier; - - std::string name() const; - static Dependency parse_dependency(std::string name, std::string qualifier); - }; - - std::vector filter_dependencies(const std::vector& deps, const Triplet& t); - std::vector filter_dependencies_to_specs(const std::vector& deps, const Triplet& t); - - // zlib[uwp] becomes Dependency{"zlib", "uwp"} - std::vector expand_qualified_dependencies(const std::vector& depends); - - std::string to_string(const Dependency& dep); - - struct FeatureParagraph - { - std::string name; - std::string description; - std::vector depends; - }; - - /// - /// Port metadata (CONTROL file) - /// - struct SourceParagraph - { - std::string name; - std::string version; - std::string description; - std::string maintainer; - std::vector supports; - std::vector depends; - std::vector default_features; - }; - struct SourceControlFile - { - static Parse::ParseExpected parse_control_file( - std::vector&& control_paragraphs); - - std::unique_ptr core_paragraph; - std::vector> feature_paragraphs; - }; - - void print_error_message(Span> error_info_list); - inline void print_error_message(const std::unique_ptr& error_info_list) - { - return print_error_message({&error_info_list, 1}); - } - - struct Supports - { - static ExpectedT> parse(const std::vector& strs); - - using Architecture = System::CPUArchitecture; - - enum class Platform - { - WINDOWS, - UWP, - }; - enum class Linkage - { - DYNAMIC, - STATIC, - }; - enum class ToolsetVersion - { - V140, - V141, - }; - - bool is_supported(Architecture arch, Platform plat, Linkage crt, ToolsetVersion tools); - - private: - std::vector architectures; - std::vector platforms; - std::vector crt_linkages; - std::vector toolsets; - }; -} diff --git a/toolsrc/include/Span.h b/toolsrc/include/Span.h deleted file mode 100644 index a43e8f992..000000000 --- a/toolsrc/include/Span.h +++ /dev/null @@ -1,52 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -template -struct Span -{ -public: - using element_type = T; - using pointer = T*; - using reference = T&; - using iterator = T*; - - constexpr Span() noexcept : m_ptr(nullptr), m_count(0) {} - constexpr Span(std::nullptr_t) noexcept : Span() {} - constexpr Span(T* ptr, size_t count) noexcept : m_ptr(ptr), m_count(count) {} - constexpr Span(T* ptr_begin, T* ptr_end) noexcept : m_ptr(ptr_begin), m_count(ptr_end - ptr_begin) {} - constexpr Span(std::initializer_list l) noexcept : m_ptr(l.begin()), m_count(l.size()) {} - - template - constexpr Span(T (&arr)[N]) noexcept : Span(arr, N) - { - } - - Span(std::vector& v) noexcept : Span(v.data(), v.size()) {} - Span(const std::vector>& v) noexcept : Span(v.data(), v.size()) {} - - constexpr iterator begin() const { return m_ptr; } - constexpr iterator end() const { return m_ptr + m_count; } - - constexpr reference operator[](size_t i) const { return m_ptr[i]; } - constexpr size_t size() const { return m_count; } - -private: - pointer m_ptr; - size_t m_count; -}; - -template -Span make_span(std::vector& v) -{ - return {v.data(), v.size()}; -} - -template -Span make_span(const std::vector& v) -{ - return {v.data(), v.size()}; -} diff --git a/toolsrc/include/StatusParagraph.h b/toolsrc/include/StatusParagraph.h deleted file mode 100644 index b56533d65..000000000 --- a/toolsrc/include/StatusParagraph.h +++ /dev/null @@ -1,44 +0,0 @@ -#pragma once - -#include "BinaryParagraph.h" -#include - -namespace vcpkg -{ - enum class InstallState - { - ERROR_STATE, - NOT_INSTALLED, - HALF_INSTALLED, - INSTALLED, - }; - - enum class Want - { - ERROR_STATE, - UNKNOWN, - INSTALL, - HOLD, - DEINSTALL, - PURGE - }; - - /// - /// Installed package metadata - /// - struct StatusParagraph - { - StatusParagraph(); - explicit StatusParagraph(std::unordered_map&& fields); - - BinaryParagraph package; - Want want; - InstallState state; - }; - - void serialize(const StatusParagraph& pgh, std::string& out_str); - - std::string to_string(InstallState f); - - std::string to_string(Want f); -} diff --git a/toolsrc/include/StatusParagraphs.h b/toolsrc/include/StatusParagraphs.h deleted file mode 100644 index 1a9ee6a03..000000000 --- a/toolsrc/include/StatusParagraphs.h +++ /dev/null @@ -1,46 +0,0 @@ -#pragma once -#include "StatusParagraph.h" -#include -#include - -namespace vcpkg -{ - struct StatusParagraphs - { - StatusParagraphs(); - explicit StatusParagraphs(std::vector>&& ps); - - using container = std::vector>; - using iterator = container::reverse_iterator; - using const_iterator = container::const_reverse_iterator; - - const_iterator find(const PackageSpec& spec) const { return find(spec.name(), spec.triplet()); } - const_iterator find(const std::string& name, const Triplet& triplet) const; - iterator find(const std::string& name, const Triplet& triplet); - std::vector*> find_all(const std::string& name, const Triplet& triplet); - iterator find(const std::string& name, const Triplet& triplet, const std::string& feature); - - const_iterator find_installed(const PackageSpec& spec) const - { - return find_installed(spec.name(), spec.triplet()); - } - const_iterator find_installed(const std::string& name, const Triplet& triplet) const; - - iterator insert(std::unique_ptr); - - friend void serialize(const StatusParagraphs& pgh, std::string& out_str); - - iterator end() { return paragraphs.rend(); } - - const_iterator end() const { return paragraphs.rend(); } - - iterator begin() { return paragraphs.rbegin(); } - - const_iterator begin() const { return paragraphs.rbegin(); } - - private: - std::vector> paragraphs; - }; - - void serialize(const StatusParagraphs& pgh, std::string& out_str); -} diff --git a/toolsrc/include/VcpkgCmdArguments.h b/toolsrc/include/VcpkgCmdArguments.h deleted file mode 100644 index 0de5747b1..000000000 --- a/toolsrc/include/VcpkgCmdArguments.h +++ /dev/null @@ -1,49 +0,0 @@ -#pragma once - -#include "vcpkg_optional.h" -#include -#include -#include -#include - -namespace vcpkg -{ - struct ParsedArguments - { - std::unordered_set switches; - std::unordered_map settings; - }; - - struct VcpkgCmdArguments - { - static VcpkgCmdArguments create_from_command_line(const int argc, const wchar_t* const* const argv); - static VcpkgCmdArguments create_from_arg_sequence(const std::string* arg_begin, const std::string* arg_end); - - std::unique_ptr vcpkg_root_dir; - std::unique_ptr triplet; - Optional debug = nullopt; - Optional sendmetrics = nullopt; - Optional printmetrics = nullopt; - - std::string command; - std::vector command_arguments; - std::unordered_set check_and_get_optional_command_arguments( - const std::vector& valid_options) const - { - return std::move(check_and_get_optional_command_arguments(valid_options, {}).switches); - } - - ParsedArguments check_and_get_optional_command_arguments(const std::vector& valid_switches, - const std::vector& valid_settings) const; - - void check_max_arg_count(const size_t expected_arg_count) const; - void check_max_arg_count(const size_t expected_arg_count, const std::string& example_text) const; - void check_min_arg_count(const size_t expected_arg_count) const; - void check_min_arg_count(const size_t expected_arg_count, const std::string& example_text) const; - void check_exact_arg_count(const size_t expected_arg_count) const; - void check_exact_arg_count(const size_t expected_arg_count, const std::string& example_text) const; - - private: - std::unordered_map> optional_command_arguments; - }; -} diff --git a/toolsrc/include/VcpkgPaths.h b/toolsrc/include/VcpkgPaths.h deleted file mode 100644 index d4640fba2..000000000 --- a/toolsrc/include/VcpkgPaths.h +++ /dev/null @@ -1,84 +0,0 @@ -#pragma once -#include "BinaryParagraph.h" -#include "Lazy.h" -#include "PackageSpec.h" -#include "filesystem_fs.h" -#include "vcpkg_Files.h" -#include "vcpkg_expected.h" - -namespace vcpkg -{ - struct ToolsetArchOption - { - CWStringView name; - System::CPUArchitecture host_arch; - System::CPUArchitecture target_arch; - }; - - struct Toolset - { - fs::path visual_studio_root_path; - fs::path dumpbin; - fs::path vcvarsall; - std::vector vcvarsall_options; - CWStringView version; - std::vector supported_architectures; - }; - - struct VcpkgPaths - { - static Expected create(const fs::path& vcpkg_root_dir); - - fs::path package_dir(const PackageSpec& spec) const; - fs::path port_dir(const PackageSpec& spec) const; - fs::path port_dir(const std::string& name) const; - fs::path build_info_file_path(const PackageSpec& spec) const; - fs::path listfile_path(const BinaryParagraph& pgh) const; - - bool is_valid_triplet(const Triplet& t) const; - - fs::path root; - fs::path packages; - fs::path buildtrees; - fs::path downloads; - fs::path ports; - fs::path installed; - fs::path triplets; - fs::path scripts; - - fs::path buildsystems; - fs::path buildsystems_msbuild_targets; - - fs::path vcpkg_dir; - fs::path vcpkg_dir_status_file; - fs::path vcpkg_dir_info; - fs::path vcpkg_dir_updates; - - fs::path ports_cmake; - - const fs::path& get_cmake_exe() const; - const fs::path& get_git_exe() const; - const fs::path& get_nuget_exe() const; - const fs::path& get_ifw_installerbase_exe() const; - const fs::path& get_ifw_binarycreator_exe() const; - const fs::path& get_ifw_repogen_exe() const; - - /// Retrieve a toolset matching a VS version - /// - /// Valid version strings are "v140", "v141", and "". Empty string gets the latest. - /// - const Toolset& VcpkgPaths::get_toolset(const Optional& toolset_version, - const Optional& visual_studio_path) const; - - Files::Filesystem& get_filesystem() const; - - private: - Lazy cmake_exe; - Lazy git_exe; - Lazy nuget_exe; - Lazy ifw_installerbase_exe; - Lazy ifw_binarycreator_exe; - Lazy ifw_repogen_exe; - Lazy> toolsets; - }; -} diff --git a/toolsrc/include/VersionT.h b/toolsrc/include/VersionT.h deleted file mode 100644 index 67efd8da3..000000000 --- a/toolsrc/include/VersionT.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once -#include - -namespace vcpkg -{ - struct VersionT - { - VersionT(); - VersionT(const std::string& value); - - std::string to_string() const; - - std::string value; - }; - - bool operator==(const VersionT& left, const VersionT& right); - bool operator!=(const VersionT& left, const VersionT& right); - - struct VersionDiff - { - VersionT left; - VersionT right; - - VersionDiff(); - VersionDiff(const VersionT& left, const VersionT& right); - - std::string to_string() const; - }; -} diff --git a/toolsrc/include/coff_file_reader.h b/toolsrc/include/coff_file_reader.h deleted file mode 100644 index 7287211a1..000000000 --- a/toolsrc/include/coff_file_reader.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once -#include "MachineType.h" -#include "filesystem_fs.h" -#include - -namespace vcpkg::CoffFileReader -{ - struct DllInfo - { - MachineType machine_type; - }; - - struct LibInfo - { - std::vector machine_types; - }; - - DllInfo read_dll(const fs::path& path); - - LibInfo read_lib(const fs::path& path); -} diff --git a/toolsrc/include/filesystem_fs.h b/toolsrc/include/filesystem_fs.h deleted file mode 100644 index 0651ebf25..000000000 --- a/toolsrc/include/filesystem_fs.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include - -namespace fs -{ - namespace stdfs = std::experimental::filesystem; - - using stdfs::path; - using stdfs::copy_options; - using stdfs::file_status; - - inline bool is_regular_file(file_status s) { return stdfs::is_regular_file(s); } - inline bool is_directory(file_status s) { return stdfs::is_directory(s); } - inline bool status_known(file_status s) { return stdfs::status_known(s); } -} \ No newline at end of file diff --git a/toolsrc/include/lazy.h b/toolsrc/include/lazy.h deleted file mode 100644 index 58c11c002..000000000 --- a/toolsrc/include/lazy.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -namespace vcpkg -{ - template - class Lazy - { - public: - Lazy() : value(T()), initialized(false) {} - - template - T const& get_lazy(const F& f) const - { - if (!initialized) - { - value = f(); - initialized = true; - } - return value; - } - - private: - mutable T value; - mutable bool initialized; - }; -} diff --git a/toolsrc/include/metrics.h b/toolsrc/include/metrics.h deleted file mode 100644 index 8eae426de..000000000 --- a/toolsrc/include/metrics.h +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once - -#include - -#include "vcpkg_Util.h" - -namespace vcpkg::Metrics -{ - struct Metrics : Util::ResourceBase - { - void set_send_metrics(bool should_send_metrics); - void set_print_metrics(bool should_print_metrics); - void set_user_information(const std::string& user_id, const std::string& first_use_time); - void init_user_information(std::string& user_id, std::string& first_use_time); - - void track_metric(const std::string& name, double value); - void track_property(const std::string& name, const std::string& value); - void track_property(const std::string& name, const std::wstring& value); - - void upload(const std::string& payload); - void flush(); - }; - - extern Util::LockGuarded g_metrics; - - std::wstring get_SQM_user(); - bool get_compiled_metrics_enabled(); -} diff --git a/toolsrc/include/pch.h b/toolsrc/include/pch.h index 0f34063f8..8333eb927 100644 --- a/toolsrc/include/pch.h +++ b/toolsrc/include/pch.h @@ -2,9 +2,13 @@ #define NOMINMAX #define WIN32_LEAN_AND_MEAN + #pragma warning(suppress : 4768) #include +#pragma warning(suppress : 4768) +#include + #include #include #include @@ -28,10 +32,6 @@ #include #include #include -#pragma warning(push) -#pragma warning(disable : 4768) -#include -#pragma warning(pop) #include #include #include diff --git a/toolsrc/include/triplet.h b/toolsrc/include/triplet.h deleted file mode 100644 index 46a52f8e6..000000000 --- a/toolsrc/include/triplet.h +++ /dev/null @@ -1,43 +0,0 @@ -#pragma once - -#include - -namespace vcpkg -{ - struct TripletInstance; - - struct Triplet - { - public: - constexpr Triplet() : m_instance(&DEFAULT_INSTANCE) {} - - static Triplet from_canonical_name(const std::string& triplet_as_string); - - static const Triplet X86_WINDOWS; - static const Triplet X64_WINDOWS; - static const Triplet X86_UWP; - static const Triplet X64_UWP; - static const Triplet ARM_UWP; - - const std::string& canonical_name() const; - const std::string& to_string() const; - size_t hash_code() const; - - bool operator==(const Triplet& other) const; - - private: - static const TripletInstance DEFAULT_INSTANCE; - - constexpr Triplet(const TripletInstance* ptr) : m_instance(ptr) {} - - const TripletInstance* m_instance; - }; - - bool operator!=(const Triplet& left, const Triplet& right); -} - -template<> -struct std::hash -{ - size_t operator()(const vcpkg::Triplet& t) const { return t.hash_code(); } -}; diff --git a/toolsrc/include/vcpkg/base/checks.h b/toolsrc/include/vcpkg/base/checks.h new file mode 100644 index 000000000..fb162c897 --- /dev/null +++ b/toolsrc/include/vcpkg/base/checks.h @@ -0,0 +1,55 @@ +#pragma once + +#include +#include +#include + +namespace vcpkg::Checks +{ + void register_console_ctrl_handler(); + + // Indicate that an internal error has occurred and exit the tool. This should be used when invariants have been + // broken. + [[noreturn]] void unreachable(const LineInfo& line_info); + + [[noreturn]] void exit_with_code(const LineInfo& line_info, const int exit_code); + + // Exit the tool without an error message. + [[noreturn]] inline void exit_fail(const LineInfo& line_info) { exit_with_code(line_info, EXIT_FAILURE); } + + // Exit the tool successfully. + [[noreturn]] inline void exit_success(const LineInfo& line_info) { exit_with_code(line_info, EXIT_SUCCESS); } + + // Display an error message to the user and exit the tool. + [[noreturn]] void exit_with_message(const LineInfo& line_info, const CStringView error_message); + + template + // Display an error message to the user and exit the tool. + [[noreturn]] void exit_with_message(const LineInfo& line_info, + const char* error_message_template, + const Arg1 error_message_arg1, + const Args&... error_message_args) + { + exit_with_message(line_info, + Strings::format(error_message_template, error_message_arg1, error_message_args...)); + } + + void check_exit(const LineInfo& line_info, bool expression); + + void check_exit(const LineInfo& line_info, bool expression, const CStringView error_message); + + template + void check_exit(const LineInfo& line_info, + Conditional&& expression, + const char* error_message_template, + const Arg1 error_message_arg1, + const Args&... error_message_args) + { + if (!expression) + { + // Only create the string if the expression is false + exit_with_message(line_info, + Strings::format(error_message_template, error_message_arg1, error_message_args...)); + } + } +} diff --git a/toolsrc/include/vcpkg/base/chrono.h b/toolsrc/include/vcpkg/base/chrono.h new file mode 100644 index 000000000..b525852f2 --- /dev/null +++ b/toolsrc/include/vcpkg/base/chrono.h @@ -0,0 +1,28 @@ +#pragma once + +#include +#include + +namespace vcpkg::Chrono +{ + class ElapsedTime + { + public: + static ElapsedTime create_started(); + + constexpr ElapsedTime() : m_start_tick() {} + + template + TimeUnit elapsed() const + { + return std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - this->m_start_tick); + } + + double microseconds() const { return elapsed>().count(); } + + std::string to_string() const; + + private: + std::chrono::high_resolution_clock::time_point m_start_tick; + }; +} diff --git a/toolsrc/include/vcpkg/base/cofffilereader.h b/toolsrc/include/vcpkg/base/cofffilereader.h new file mode 100644 index 000000000..ad2cc7b12 --- /dev/null +++ b/toolsrc/include/vcpkg/base/cofffilereader.h @@ -0,0 +1,23 @@ +#pragma once + +#include +#include + +#include + +namespace vcpkg::CoffFileReader +{ + struct DllInfo + { + MachineType machine_type; + }; + + struct LibInfo + { + std::vector machine_types; + }; + + DllInfo read_dll(const fs::path& path); + + LibInfo read_lib(const fs::path& path); +} diff --git a/toolsrc/include/vcpkg/base/cstringview.h b/toolsrc/include/vcpkg/base/cstringview.h new file mode 100644 index 000000000..341830f05 --- /dev/null +++ b/toolsrc/include/vcpkg/base/cstringview.h @@ -0,0 +1,97 @@ +#pragma once + +#include + +namespace vcpkg +{ + template + struct BasicCStringView + { + constexpr BasicCStringView() : cstr(nullptr) {} + constexpr BasicCStringView(const CharType* cstr) : cstr(cstr) {} + constexpr BasicCStringView(const BasicCStringView&) = default; + BasicCStringView(const std::basic_string& str) : cstr(str.c_str()) {} + + constexpr const CharType* c_str() const { return cstr; } + + private: + const CharType* cstr; + }; + + namespace details + { + inline bool vcpkg_strcmp(const char* l, const char* r) { return strcmp(l, r) == 0; } + inline bool vcpkg_strcmp(const wchar_t* l, const wchar_t* r) { return wcscmp(l, r) == 0; } + } + + template + bool operator==(const BasicCStringView& l, const BasicCStringView& r) + { + return details::vcpkg_strcmp(l.c_str(), r.c_str()); + } + + template + bool operator==(const CharType* l, const BasicCStringView& r) + { + return details::vcpkg_strcmp(l, r.c_str()); + } + + template + bool operator==(const BasicCStringView& r, const CharType* l) + { + return details::vcpkg_strcmp(l, r.c_str()); + } + + template + bool operator==(const std::basic_string& l, const BasicCStringView& r) + { + return l == r.c_str(); + } + + template + bool operator==(const BasicCStringView& r, const std::basic_string& l) + { + return l == r.c_str(); + } + + // notequals + template + bool operator!=(const BasicCStringView& l, const BasicCStringView& r) + { + return !details::vcpkg_strcmp(l.c_str(), r.c_str()); + } + + template + bool operator!=(const CharType* l, const BasicCStringView& r) + { + return !details::vcpkg_strcmp(l, r.c_str()); + } + + template + bool operator!=(const BasicCStringView& r, const CharType* l) + { + return !details::vcpkg_strcmp(l, r.c_str()); + } + + template + bool operator!=(const BasicCStringView& r, const std::basic_string& l) + { + return l != r.c_str(); + } + + template + bool operator!=(const std::basic_string& l, const BasicCStringView& r) + { + return l != r.c_str(); + } + + using CStringView = BasicCStringView; + using CWStringView = BasicCStringView; + + inline const char* to_printf_arg(const CStringView string_view) { return string_view.c_str(); } + + inline const wchar_t* to_wprintf_arg(const CWStringView string_view) { return string_view.c_str(); } + + static_assert(sizeof(CStringView) == sizeof(void*), "CStringView must be a simple wrapper around char*"); + static_assert(sizeof(CWStringView) == sizeof(void*), "CWStringView must be a simple wrapper around wchar_t*"); +} diff --git a/toolsrc/include/vcpkg/base/enums.h b/toolsrc/include/vcpkg/base/enums.h new file mode 100644 index 000000000..6eca2cfe1 --- /dev/null +++ b/toolsrc/include/vcpkg/base/enums.h @@ -0,0 +1,12 @@ +#pragma once + +#include + +#include + +namespace vcpkg::Enums +{ + std::string nullvalue_to_string(const CStringView enum_name); + + [[noreturn]] void nullvalue_used(const LineInfo& line_info, const CStringView enum_name); +} diff --git a/toolsrc/include/vcpkg/base/expected.h b/toolsrc/include/vcpkg/base/expected.h new file mode 100644 index 000000000..a946c442e --- /dev/null +++ b/toolsrc/include/vcpkg/base/expected.h @@ -0,0 +1,115 @@ +#pragma once + +#include + +#include + +namespace vcpkg +{ + template + struct ErrorHolder + { + ErrorHolder() : m_is_error(false) {} + template + ErrorHolder(U&& err) : m_is_error(true), m_err(std::forward(err)) + { + } + + constexpr bool has_error() const { return m_is_error; } + + const Err& error() const { return m_err; } + Err& error() { return m_err; } + + CStringView to_string() const { return "value was error"; } + + private: + bool m_is_error; + Err m_err; + }; + + template<> + struct ErrorHolder + { + ErrorHolder() = default; + ErrorHolder(const std::error_code& err) : m_err(err) {} + + constexpr bool has_error() const { return bool(m_err); } + + const std::error_code& error() const { return m_err; } + std::error_code& error() { return m_err; } + + CStringView to_string() const { return "value was error"; } + + private: + std::error_code m_err; + }; + + template + class ExpectedT + { + public: + constexpr ExpectedT() = default; + + // Constructors are intentionally implicit + + ExpectedT(const S& s) : m_s(s) {} + ExpectedT(S&& s) : m_s(std::move(s)) {} + + ExpectedT(const T& t) : m_t(t) {} + ExpectedT(T&& t) : m_t(std::move(t)) {} + + ExpectedT(const ExpectedT&) = default; + ExpectedT(ExpectedT&&) = default; + ExpectedT& operator=(const ExpectedT&) = default; + ExpectedT& operator=(ExpectedT&&) = default; + + explicit constexpr operator bool() const noexcept { return !m_s.has_error(); } + constexpr bool has_value() const noexcept { return !m_s.has_error(); } + + T&& value_or_exit(const LineInfo& line_info) && + { + exit_if_error(line_info); + return std::move(this->m_t); + } + + const T& value_or_exit(const LineInfo& line_info) const& + { + exit_if_error(line_info); + return this->m_t; + } + + const S& error() const& { return this->m_s.error(); } + + S&& error() && { return std::move(this->m_s.error()); } + + const T* get() const + { + if (!this->has_value()) + { + return nullptr; + } + return &this->m_t; + } + + T* get() + { + if (!this->has_value()) + { + return nullptr; + } + return &this->m_t; + } + + private: + void exit_if_error(const LineInfo& line_info) const + { + Checks::check_exit(line_info, !m_s.has_error(), m_s.to_string()); + } + + ErrorHolder m_s; + T m_t; + }; + + template + using Expected = ExpectedT; +} diff --git a/toolsrc/include/vcpkg/base/files.h b/toolsrc/include/vcpkg/base/files.h new file mode 100644 index 000000000..f4bcf742c --- /dev/null +++ b/toolsrc/include/vcpkg/base/files.h @@ -0,0 +1,57 @@ +#pragma once + +#include + +#include + +namespace fs +{ + namespace stdfs = std::experimental::filesystem; + + using stdfs::copy_options; + using stdfs::file_status; + using stdfs::path; + + inline bool is_regular_file(file_status s) { return stdfs::is_regular_file(s); } + inline bool is_directory(file_status s) { return stdfs::is_directory(s); } + inline bool status_known(file_status s) { return stdfs::status_known(s); } +} + +namespace vcpkg::Files +{ + __interface Filesystem + { + virtual Expected read_contents(const fs::path& file_path) const = 0; + 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; + virtual std::vector get_files_non_recursive(const fs::path& dir) const = 0; + + virtual void write_lines(const fs::path& file_path, const std::vector& lines) = 0; + virtual void write_contents(const fs::path& file_path, const std::string& data) = 0; + virtual void rename(const fs::path& oldpath, const fs::path& newpath) = 0; + virtual bool remove(const fs::path& path) = 0; + virtual bool remove(const fs::path& path, std::error_code& ec) = 0; + virtual std::uintmax_t remove_all(const fs::path& path, std::error_code& ec) = 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 bool create_directories(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 bool copy_file( + const fs::path& oldpath, const fs::path& newpath, fs::copy_options opts, std::error_code& ec) = 0; + virtual fs::file_status status(const fs::path& path, std::error_code& ec) const = 0; + }; + + Filesystem& get_real_filesystem(); + + static const char* FILESYSTEM_INVALID_CHARACTERS = R"(\/:*?"<>|)"; + + bool has_invalid_chars_for_filesystem(const std::string& s); + + void print_paths(const std::vector& paths); + + std::vector find_from_PATH(const std::wstring& name); +} diff --git a/toolsrc/include/vcpkg/base/graphs.h b/toolsrc/include/vcpkg/base/graphs.h new file mode 100644 index 000000000..ff56cb298 --- /dev/null +++ b/toolsrc/include/vcpkg/base/graphs.h @@ -0,0 +1,161 @@ +#pragma once + +#include +#include + +#include + +namespace vcpkg::Graphs +{ + enum class ExplorationStatus + { + // We have not visited this vertex + NOT_EXPLORED, + + // We have visited this vertex but haven't visited all vertices in its subtree + PARTIALLY_EXPLORED, + + // We have visited this vertex and all vertices in its subtree + FULLY_EXPLORED + }; + + template + __interface AdjacencyProvider + { + std::vector adjacency_list(const U& vertex) const; + + U load_vertex_data(const V& vertex) const; + }; + + template + static void topological_sort_internal(const V& vertex, + const AdjacencyProvider& f, + std::unordered_map& exploration_status, + std::vector& sorted) + { + ExplorationStatus& status = exploration_status[vertex]; + switch (status) + { + case ExplorationStatus::FULLY_EXPLORED: return; + case ExplorationStatus::PARTIALLY_EXPLORED: Checks::exit_with_message(VCPKG_LINE_INFO, "cycle in graph"); + case ExplorationStatus::NOT_EXPLORED: + { + status = ExplorationStatus::PARTIALLY_EXPLORED; + U vertex_data = f.load_vertex_data(vertex); + for (const V& neighbour : f.adjacency_list(vertex_data)) + topological_sort_internal(neighbour, f, exploration_status, sorted); + + sorted.push_back(std::move(vertex_data)); + status = ExplorationStatus::FULLY_EXPLORED; + return; + } + default: Checks::unreachable(VCPKG_LINE_INFO); + } + } + + template + std::vector topological_sort(const std::vector& starting_vertices, const AdjacencyProvider& f) + { + std::vector sorted; + std::unordered_map exploration_status; + + for (auto& vertex : starting_vertices) + { + topological_sort_internal(vertex, f, exploration_status, sorted); + } + + return sorted; + } + + template + struct GraphAdjacencyProvider final : AdjacencyProvider + { + const std::unordered_map>& vertices; + + GraphAdjacencyProvider(const std::unordered_map>& vertices) : vertices(vertices) {} + + std::vector adjacency_list(const V& vertex) const override + { + const std::unordered_set& as_set = this->vertices.at(vertex); + return std::vector(as_set.cbegin(), as_set.cend()); // TODO: Avoid redundant copy + } + + V load_vertex_data(const V& vertex) const override { return vertex; } + }; + + template + struct Graph + { + public: + void add_vertex(V v) { this->vertices[v]; } + + // TODO: Change with iterators + void add_vertices(const std::vector& vs) + { + for (const V& v : vs) + { + this->vertices[v]; + } + } + + void add_edge(V u, V v) + { + this->vertices[v]; + this->vertices[u].insert(v); + } + + std::vector topological_sort() const + { + GraphAdjacencyProvider adjacency_provider{this->vertices}; + std::unordered_map indegrees = count_indegrees(); + + std::vector sorted; + sorted.reserve(indegrees.size()); + + std::unordered_map exploration_status; + exploration_status.reserve(indegrees.size()); + + for (auto& pair : indegrees) + { + if (pair.second == 0) // Starting from vertices with indegree == 0. Not required. + { + V vertex = pair.first; + topological_sort_internal(vertex, adjacency_provider, exploration_status, sorted); + } + } + + return sorted; + } + + std::unordered_map count_indegrees() const + { + std::unordered_map indegrees; + + for (auto& pair : this->vertices) + { + indegrees[pair.first]; + for (V neighbour : pair.second) + { + ++indegrees[neighbour]; + } + } + + return indegrees; + } + + const std::unordered_map>& adjacency_list() const { return this->vertices; } + std::vector vertex_list() const + { + // why no &? it returns 0 + std::vector vertex_list; + for (const auto& vertex : this->vertices) + { + vertex_list.emplace_back(vertex.first); + } + return vertex_list; + } + + private: + std::unordered_map> vertices; + }; +} diff --git a/toolsrc/include/vcpkg/base/lazy.h b/toolsrc/include/vcpkg/base/lazy.h new file mode 100644 index 000000000..58c11c002 --- /dev/null +++ b/toolsrc/include/vcpkg/base/lazy.h @@ -0,0 +1,26 @@ +#pragma once + +namespace vcpkg +{ + template + class Lazy + { + public: + Lazy() : value(T()), initialized(false) {} + + template + T const& get_lazy(const F& f) const + { + if (!initialized) + { + value = f(); + initialized = true; + } + return value; + } + + private: + mutable T value; + mutable bool initialized; + }; +} diff --git a/toolsrc/include/vcpkg/base/lineinfo.h b/toolsrc/include/vcpkg/base/lineinfo.h new file mode 100644 index 000000000..62973462a --- /dev/null +++ b/toolsrc/include/vcpkg/base/lineinfo.h @@ -0,0 +1,19 @@ +#pragma once + +#include + +namespace vcpkg +{ + struct LineInfo + { + int line_number; + const char* file_name; + + constexpr LineInfo() : line_number(0), file_name(nullptr) {} + constexpr LineInfo(const int lineno, const char* filename) : line_number(lineno), file_name(filename) {} + + std::string to_string() const; + }; +} + +#define VCPKG_LINE_INFO vcpkg::LineInfo(__LINE__, __FILE__) diff --git a/toolsrc/include/vcpkg/base/machinetype.h b/toolsrc/include/vcpkg/base/machinetype.h new file mode 100644 index 000000000..b85cdbb0b --- /dev/null +++ b/toolsrc/include/vcpkg/base/machinetype.h @@ -0,0 +1,37 @@ +#pragma once + +#include + +namespace vcpkg +{ + enum class MachineType : uint16_t + { + UNKNOWN = 0x0, // The contents of this field are assumed to be applicable to any machine type + AM33 = 0x1d3, // Matsushita AM33 + AMD64 = 0x8664, // x64 + ARM = 0x1c0, // ARM little endian + ARM64 = 0xaa64, // ARM64 little endian + ARMNT = 0x1c4, // ARM Thumb-2 little endian + EBC = 0xebc, // EFI byte code + I386 = 0x14c, // Intel 386 or later processors and compatible processors + IA64 = 0x200, // Intel Itanium processor family + M32R = 0x9041, // Mitsubishi M32R little endian + MIPS16 = 0x266, // MIPS16 + MIPSFPU = 0x366, // MIPS with FPU + MIPSFPU16 = 0x466, // MIPS16 with FPU + POWERPC = 0x1f0, // Power PC little endian + POWERPCFP = 0x1f1, // Power PC with floating point support + R4000 = 0x166, // MIPS little endian + RISCV32 = 0x5032, // RISC-V 32-bit address space + RISCV64 = 0x5064, // RISC-V 64-bit address space + RISCV128 = 0x5128, // RISC-V 128-bit address space + SH3 = 0x1a2, // Hitachi SH3 + SH3DSP = 0x1a3, // Hitachi SH3 DSP + SH4 = 0x1a6, // Hitachi SH4 + SH5 = 0x1a8, // Hitachi SH5 + THUMB = 0x1c2, // Thumb + WCEMIPSV2 = 0x169, // MIPS little-endian WCE v2 + }; + + MachineType to_machine_type(const uint16_t value); +} diff --git a/toolsrc/include/vcpkg/base/optional.h b/toolsrc/include/vcpkg/base/optional.h new file mode 100644 index 000000000..ff7a210c7 --- /dev/null +++ b/toolsrc/include/vcpkg/base/optional.h @@ -0,0 +1,99 @@ +#pragma once + +#include + +namespace vcpkg +{ + struct NullOpt + { + explicit constexpr NullOpt(int) {} + }; + + const static constexpr NullOpt nullopt{0}; + + template + class Optional + { + public: + constexpr Optional() : m_is_present(false), m_t() {} + + // Constructors are intentionally implicit + constexpr Optional(NullOpt) : m_is_present(false), m_t() {} + + Optional(const T& t) : m_is_present(true), m_t(t) {} + + Optional(T&& t) : m_is_present(true), m_t(std::move(t)) {} + + T&& value_or_exit(const LineInfo& line_info) && + { + this->exit_if_null(line_info); + return std::move(this->m_t); + } + + const T& value_or_exit(const LineInfo& line_info) const& + { + this->exit_if_null(line_info); + return this->m_t; + } + + constexpr explicit operator bool() const { return this->m_is_present; } + + constexpr bool has_value() const { return m_is_present; } + + template + T value_or(U&& default_value) const& + { + return bool(*this) ? this->m_t : static_cast(std::forward(default_value)); + } + + template + T value_or(U&& default_value) && + { + return bool(*this) ? std::move(this->m_t) : static_cast(std::forward(default_value)); + } + + const T* get() const { return bool(*this) ? &this->m_t : nullptr; } + + T* get() { return bool(*this) ? &this->m_t : nullptr; } + + private: + void exit_if_null(const LineInfo& line_info) const + { + Checks::check_exit(line_info, this->m_is_present, "Value was null"); + } + + bool m_is_present; + T m_t; + }; + + template + Optional> make_optional(U&& u) + { + return Optional>(std::forward(u)); + } + + template + bool operator==(const Optional& o, const T& t) + { + if (auto p = o.get()) return *p == t; + return false; + } + template + bool operator==(const T& t, const Optional& o) + { + if (auto p = o.get()) return t == *p; + return false; + } + template + bool operator!=(const Optional& o, const T& t) + { + if (auto p = o.get()) return *p != t; + return true; + } + template + bool operator!=(const T& t, const Optional& o) + { + if (auto p = o.get()) return t != *p; + return true; + } +} diff --git a/toolsrc/include/vcpkg/base/sortedvector.h b/toolsrc/include/vcpkg/base/sortedvector.h new file mode 100644 index 000000000..62808cc2f --- /dev/null +++ b/toolsrc/include/vcpkg/base/sortedvector.h @@ -0,0 +1,50 @@ +#pragma once + +#include +#include + +// Add more forwarding functions to the m_data std::vector as needed. +namespace vcpkg +{ + template + class SortedVector + { + public: + using size_type = typename std::vector::size_type; + using iterator = typename std::vector::const_iterator; + + SortedVector() : m_data() {} + + explicit SortedVector(std::vector v) : m_data(std::move(v)) + { + if (!std::is_sorted(m_data.begin(), m_data.end())) + { + std::sort(m_data.begin(), m_data.end()); + } + } + + template + SortedVector(std::vector v, Compare comp) : m_data(std::move(v)) + { + if (!std::is_sorted(m_data.cbegin(), m_data.cend(), comp)) + { + std::sort(m_data.begin(), m_data.end(), comp); + } + } + + iterator begin() const { return this->m_data.cbegin(); } + + iterator end() const { return this->m_data.cend(); } + + iterator cbegin() const { return this->m_data.cbegin(); } + + iterator cend() const { return this->m_data.cend(); } + + bool empty() const { return this->m_data.empty(); } + + size_type size() const { return this->m_data.size(); } + + private: + std::vector m_data; + }; +} diff --git a/toolsrc/include/vcpkg/base/span.h b/toolsrc/include/vcpkg/base/span.h new file mode 100644 index 000000000..6be546351 --- /dev/null +++ b/toolsrc/include/vcpkg/base/span.h @@ -0,0 +1,60 @@ +#pragma once + +#include +#include +#include +#include + +namespace vcpkg +{ + template + struct Span + { + public: + using element_type = T; + using pointer = T*; + using reference = T&; + using iterator = T*; + + constexpr Span() noexcept : m_ptr(nullptr), m_count(0) {} + constexpr Span(std::nullptr_t) noexcept : Span() {} + constexpr Span(T* ptr, size_t count) noexcept : m_ptr(ptr), m_count(count) {} + constexpr Span(T* ptr_begin, T* ptr_end) noexcept : m_ptr(ptr_begin), m_count(ptr_end - ptr_begin) {} + constexpr Span(std::initializer_list l) noexcept : m_ptr(l.begin()), m_count(l.size()) {} + + template + constexpr Span(T (&arr)[N]) noexcept : Span(arr, N) + { + } + + template + constexpr Span(const std::array, N>& arr) noexcept : Span(arr.data(), arr.size()) + { + } + + Span(std::vector& v) noexcept : Span(v.data(), v.size()) {} + Span(const std::vector>& v) noexcept : Span(v.data(), v.size()) {} + + constexpr iterator begin() const { return m_ptr; } + constexpr iterator end() const { return m_ptr + m_count; } + + constexpr reference operator[](size_t i) const { return m_ptr[i]; } + constexpr size_t size() const { return m_count; } + + private: + pointer m_ptr; + size_t m_count; + }; + + template + Span make_span(std::vector& v) + { + return {v.data(), v.size()}; + } + + template + Span make_span(const std::vector& v) + { + return {v.data(), v.size()}; + } +} \ No newline at end of file diff --git a/toolsrc/include/vcpkg/base/strings.h b/toolsrc/include/vcpkg/base/strings.h new file mode 100644 index 000000000..59823deb8 --- /dev/null +++ b/toolsrc/include/vcpkg/base/strings.h @@ -0,0 +1,114 @@ +#pragma once + +#include + +#include + +namespace vcpkg::Strings::details +{ + template + auto to_printf_arg(const T& t) -> decltype(t.to_string()) + { + return t.to_string(); + } + + inline const char* to_printf_arg(const std::string& s) { return s.c_str(); } + + inline const char* to_printf_arg(const char* s) { return s; } + + inline int to_printf_arg(const int s) { return s; } + + inline long long to_printf_arg(const long long s) { return s; } + + inline unsigned long to_printf_arg(const unsigned long s) { return s; } + + inline size_t to_printf_arg(const size_t s) { return s; } + + inline double to_printf_arg(const double s) { return s; } + + std::string format_internal(const char* fmtstr, ...); + + inline const wchar_t* to_wprintf_arg(const std::wstring& s) { return s.c_str(); } + + inline const wchar_t* to_wprintf_arg(const wchar_t* s) { return s; } + + std::wstring wformat_internal(const wchar_t* fmtstr, ...); +} + +namespace vcpkg::Strings +{ + static constexpr const char* EMPTY = ""; + static constexpr const wchar_t* WEMPTY = L""; + + template + std::string format(const char* fmtstr, const Args&... args) + { + using vcpkg::Strings::details::to_printf_arg; + return details::format_internal(fmtstr, to_printf_arg(to_printf_arg(args))...); + } + + template + std::wstring wformat(const wchar_t* fmtstr, const Args&... args) + { + using vcpkg::Strings::details::to_wprintf_arg; + return details::wformat_internal(fmtstr, to_wprintf_arg(to_wprintf_arg(args))...); + } + + std::wstring to_utf16(const CStringView s); + + std::string to_utf8(const CWStringView w); + + std::string::const_iterator case_insensitive_ascii_find(const std::string& s, const std::string& pattern); + + bool case_insensitive_ascii_contains(const std::string& s, const std::string& pattern); + + bool case_insensitive_ascii_compare(const CStringView left, const CStringView right); + + std::string ascii_to_lowercase(const std::string& input); + + bool case_insensitive_ascii_starts_with(const std::string& s, const std::string& pattern); + + template + std::basic_string join(const CharType* delimiter, const Container& v, Transformer transformer) + { + const auto begin = v.begin(); + const auto end = v.end(); + + if (begin == end) + { + return std::basic_string(); + } + + std::basic_string output; + output.append(transformer(*begin)); + for (auto it = std::next(begin); it != end; ++it) + { + output.append(delimiter); + output.append(transformer(*it)); + } + + return output; + } + template + std::basic_string join(const CharType* delimiter, const Container& v) + { + using Element = decltype(*v.begin()); + return join(delimiter, v, [](const Element& x) -> const Element& { return x; }); + } + + void trim(std::string* s); + + std::string trimmed(const std::string& s); + + void trim_all_and_remove_whitespace_strings(std::vector* strings); + + std::vector split(const std::string& s, const std::string& delimiter); + + template + std::string serialize(const T& t) + { + std::string ret; + serialize(t, ret); + return ret; + } +} diff --git a/toolsrc/include/vcpkg/base/system.h b/toolsrc/include/vcpkg/base/system.h new file mode 100644 index 000000000..a2e8f3f45 --- /dev/null +++ b/toolsrc/include/vcpkg/base/system.h @@ -0,0 +1,108 @@ +#pragma once + +#include +#include +#include + +#include + +namespace vcpkg::System +{ + tm get_current_date_time(); + + fs::path get_exe_path_of_current_process(); + + struct ExitCodeAndOutput + { + int exit_code; + std::string output; + }; + + int cmd_execute_clean(const CWStringView cmd_line); + + int cmd_execute(const CWStringView cmd_line); + + ExitCodeAndOutput cmd_execute_and_capture_output(const CWStringView cmd_line); + + std::wstring create_powershell_script_cmd(const fs::path& script_path, const CWStringView args = Strings::WEMPTY); + + enum class Color + { + success = 10, + error = 12, + warning = 14, + }; + + void println(); + void print(const CStringView message); + void println(const CStringView message); + void print(const Color c, const CStringView message); + void println(const Color c, const CStringView message); + + template + void print(const char* messageTemplate, const Arg1& messageArg1, const Args&... messageArgs) + { + return System::print(Strings::format(messageTemplate, messageArg1, messageArgs...)); + } + + template + void print(const Color c, const char* messageTemplate, const Arg1& messageArg1, const Args&... messageArgs) + { + return System::print(c, Strings::format(messageTemplate, messageArg1, messageArgs...)); + } + + template + void println(const char* messageTemplate, const Arg1& messageArg1, const Args&... messageArgs) + { + return System::println(Strings::format(messageTemplate, messageArg1, messageArgs...)); + } + + template + void println(const Color c, const char* messageTemplate, const Arg1& messageArg1, const Args&... messageArgs) + { + return System::println(c, Strings::format(messageTemplate, messageArg1, messageArgs...)); + } + + Optional get_environment_variable(const CWStringView varname) noexcept; + + Optional get_registry_string(HKEY base, const CWStringView subkey, const CWStringView valuename); + + enum class CPUArchitecture + { + X86, + X64, + ARM, + ARM64, + }; + + Optional to_cpu_architecture(CStringView arch); + + CPUArchitecture get_host_processor(); + + std::vector get_supported_host_architectures(); + + const fs::path& get_program_files_32_bit(); + + const fs::path& get_program_files_platform_bitness(); +} + +namespace vcpkg::Debug +{ + void println(const CStringView message); + void println(const System::Color c, const CStringView message); + + template + void println(const char* messageTemplate, const Arg1& messageArg1, const Args&... messageArgs) + { + return Debug::println(Strings::format(messageTemplate, messageArg1, messageArgs...)); + } + + template + void println(const System::Color c, + const char* messageTemplate, + const Arg1& messageArg1, + const Args&... messageArgs) + { + return Debug::println(c, Strings::format(messageTemplate, messageArg1, messageArgs...)); + } +} diff --git a/toolsrc/include/vcpkg/base/util.h b/toolsrc/include/vcpkg/base/util.h new file mode 100644 index 000000000..3834580b6 --- /dev/null +++ b/toolsrc/include/vcpkg/base/util.h @@ -0,0 +1,156 @@ +#pragma once + +#include +#include +#include +#include + +namespace vcpkg::Util +{ + template + using FmapOut = decltype(std::declval()(*begin(std::declval()))); + + template> + std::vector fmap(Cont&& xs, Func&& f) + { + std::vector ret; + ret.reserve(xs.size()); + + for (auto&& x : xs) + ret.push_back(f(x)); + + return ret; + } + + template + using FmapFlattenOut = std::decay_t()(*begin(std::declval()))))>; + + template> + std::vector fmap_flatten(Cont&& xs, Func&& f) + { + std::vector ret; + + for (auto&& x : xs) + for (auto&& y : f(x)) + ret.push_back(std::move(y)); + + return ret; + } + + template + void stable_keep_if(Container& cont, Pred pred) + { + cont.erase(std::stable_partition(cont.begin(), cont.end(), pred), cont.end()); + } + + template + void unstable_keep_if(Container& cont, Pred pred) + { + cont.erase(std::partition(cont.begin(), cont.end(), pred), cont.end()); + } + + template + void erase_remove_if(Container& cont, Pred pred) + { + cont.erase(std::remove_if(cont.begin(), cont.end(), pred), cont.end()); + } + + template + auto find(Container&& cont, V&& v) + { + using std::begin; + using std::end; + return std::find(begin(cont), end(cont), v); + } + + template + auto find_if(Container&& cont, Pred pred) + { + using std::begin; + using std::end; + return std::find_if(begin(cont), end(cont), pred); + } + + template + using ElementT = std::remove_reference_t()))>; + + template> + std::vector element_pointers(Container&& cont) + { + return fmap(cont, [](auto&& x) { return &x; }); + } + + template + auto find_if_not(Container&& cont, Pred pred) + { + using std::begin; + using std::end; + return std::find_if_not(begin(cont), end(cont), pred); + } + + template + void group_by(const Container& cont, _Inout_ std::map>* output, Func&& f) + { + for (const V& element : cont) + { + K key = f(element); + (*output)[key].push_back(&element); + } + } + + template())->first)>> + std::vector extract_keys(AssocContainer&& input_map) + { + return fmap(input_map, [](auto&& p) { return p.first; }); + } + + struct MoveOnlyBase + { + MoveOnlyBase() = default; + MoveOnlyBase(const MoveOnlyBase&) = delete; + MoveOnlyBase(MoveOnlyBase&&) = default; + + MoveOnlyBase& operator=(const MoveOnlyBase&) = delete; + MoveOnlyBase& operator=(MoveOnlyBase&&) = default; + }; + + struct ResourceBase + { + ResourceBase() = default; + ResourceBase(const ResourceBase&) = delete; + ResourceBase(ResourceBase&&) = delete; + + ResourceBase& operator=(const ResourceBase&) = delete; + ResourceBase& operator=(ResourceBase&&) = delete; + }; + + template + struct LockGuardPtr; + + template + struct LockGuarded + { + friend struct LockGuardPtr; + + LockGuardPtr lock() { return *this; } + + private: + std::mutex m_mutex; + T m_t; + }; + + template + struct LockGuardPtr + { + T& operator*() { return m_ptr; } + T* operator->() { return &m_ptr; } + + T* get() { return &m_ptr; } + + LockGuardPtr(LockGuarded& sync) : m_lock(sync.m_mutex), m_ptr(sync.m_t) {} + + private: + std::unique_lock m_lock; + T& m_ptr; + }; +} \ No newline at end of file diff --git a/toolsrc/include/vcpkg/binaryparagraph.h b/toolsrc/include/vcpkg/binaryparagraph.h new file mode 100644 index 000000000..7eb50a6d7 --- /dev/null +++ b/toolsrc/include/vcpkg/binaryparagraph.h @@ -0,0 +1,42 @@ +#pragma once + +#include +#include + +#include + +namespace vcpkg +{ + /// + /// Built package metadata + /// + struct BinaryParagraph + { + BinaryParagraph(); + explicit BinaryParagraph(std::unordered_map fields); + BinaryParagraph(const SourceParagraph& spgh, const Triplet& triplet); + BinaryParagraph(const SourceParagraph& spgh, const FeatureParagraph& fpgh, const Triplet& triplet); + + std::string displayname() const; + + std::string fullstem() const; + + std::string dir() const; + + PackageSpec spec; + std::string version; + std::string description; + std::string maintainer; + std::string feature; + std::vector default_features; + std::vector depends; + }; + + struct BinaryControlFile + { + BinaryParagraph core_paragraph; + std::vector features; + }; + + void serialize(const BinaryParagraph& pgh, std::string& out_str); +} \ No newline at end of file diff --git a/toolsrc/include/vcpkg/build.h b/toolsrc/include/vcpkg/build.h new file mode 100644 index 000000000..f146e9951 --- /dev/null +++ b/toolsrc/include/vcpkg/build.h @@ -0,0 +1,205 @@ +#pragma once + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +namespace vcpkg::Build +{ + namespace Command + { + void perform_and_exit(const FullPackageSpec& full_spec, + const fs::path& port_dir, + const std::unordered_set& options, + const VcpkgPaths& paths); + + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet); + } + + enum class UseHeadVersion + { + NO = 0, + YES + }; + + inline UseHeadVersion to_use_head_version(const bool value) + { + return value ? UseHeadVersion::YES : UseHeadVersion::NO; + } + + inline bool to_bool(const UseHeadVersion value) { return value == UseHeadVersion::YES; } + + enum class AllowDownloads + { + NO = 0, + YES + }; + + inline AllowDownloads to_allow_downloads(const bool value) + { + return value ? AllowDownloads::YES : AllowDownloads::NO; + } + + inline bool to_bool(const AllowDownloads value) { return value == AllowDownloads::YES; } + + struct BuildPackageOptions + { + UseHeadVersion use_head_version; + AllowDownloads allow_downloads; + }; + + enum class BuildResult + { + NULLVALUE = 0, + SUCCEEDED, + BUILD_FAILED, + POST_BUILD_CHECKS_FAILED, + FILE_CONFLICTS, + CASCADED_DUE_TO_MISSING_DEPENDENCIES + }; + + static constexpr std::array BUILD_RESULT_VALUES = { + BuildResult::SUCCEEDED, + BuildResult::BUILD_FAILED, + BuildResult::POST_BUILD_CHECKS_FAILED, + BuildResult::FILE_CONFLICTS, + BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES}; + + const std::string& to_string(const BuildResult build_result); + std::string create_error_message(const BuildResult build_result, const PackageSpec& spec); + std::string create_user_troubleshooting_message(const PackageSpec& spec); + + /// + /// Settings from the triplet file which impact the build environment and post-build checks + /// + struct PreBuildInfo + { + /// + /// Runs the triplet file in a "capture" mode to create a PreBuildInfo + /// + static PreBuildInfo from_triplet_file(const VcpkgPaths& paths, const Triplet& triplet); + + std::string target_architecture; + std::string cmake_system_name; + std::string cmake_system_version; + Optional platform_toolset; + Optional visual_studio_path; + }; + + std::wstring make_build_env_cmd(const PreBuildInfo& pre_build_info, const Toolset& toolset); + + struct ExtendedBuildResult + { + BuildResult code; + std::vector unmet_dependencies; + }; + + struct BuildPackageConfig + { + BuildPackageConfig(const SourceParagraph& src, + const Triplet& triplet, + fs::path&& port_dir, + const BuildPackageOptions& build_package_options) + : src(src) + , scf(nullptr) + , triplet(triplet) + , port_dir(std::move(port_dir)) + , build_package_options(build_package_options) + , feature_list(nullptr) + { + } + + BuildPackageConfig(const SourceControlFile& src, + const Triplet& triplet, + fs::path&& port_dir, + const BuildPackageOptions& build_package_options, + const std::unordered_set& feature_list) + : src(*src.core_paragraph) + , scf(&src) + , triplet(triplet) + , port_dir(std::move(port_dir)) + , build_package_options(build_package_options) + , feature_list(&feature_list) + { + } + + const SourceParagraph& src; + const SourceControlFile* scf; + const Triplet& triplet; + fs::path port_dir; + const BuildPackageOptions& build_package_options; + const std::unordered_set* feature_list; + }; + + ExtendedBuildResult build_package(const VcpkgPaths& paths, + const BuildPackageConfig& config, + const StatusParagraphs& status_db); + + enum class BuildPolicy + { + EMPTY_PACKAGE, + DLLS_WITHOUT_LIBS, + ONLY_RELEASE_CRT, + EMPTY_INCLUDE_FOLDER, + ALLOW_OBSOLETE_MSVCRT, + // Must be last + COUNT, + }; + + constexpr std::array G_ALL_POLICIES = { + BuildPolicy::EMPTY_PACKAGE, + BuildPolicy::DLLS_WITHOUT_LIBS, + BuildPolicy::ONLY_RELEASE_CRT, + BuildPolicy::EMPTY_INCLUDE_FOLDER, + BuildPolicy::ALLOW_OBSOLETE_MSVCRT, + }; + + const std::string& to_string(BuildPolicy policy); + CStringView to_cmake_variable(BuildPolicy policy); + + struct BuildPolicies + { + BuildPolicies() = default; + BuildPolicies(std::map&& map) : m_policies(std::move(map)) {} + + bool is_enabled(BuildPolicy policy) const + { + const auto it = m_policies.find(policy); + if (it != m_policies.cend()) return it->second; + return false; + } + + private: + std::map m_policies; + }; + + enum class LinkageType : char + { + DYNAMIC, + STATIC, + }; + + Optional to_linkage_type(const std::string& str); + + struct BuildInfo + { + LinkageType crt_linkage; + LinkageType library_linkage; + + Optional version; + + BuildPolicies policies; + }; + + BuildInfo read_build_info(const Files::Filesystem& fs, const fs::path& filepath); +} diff --git a/toolsrc/include/vcpkg/commands.h b/toolsrc/include/vcpkg/commands.h new file mode 100644 index 000000000..64b2118ce --- /dev/null +++ b/toolsrc/include/vcpkg/commands.h @@ -0,0 +1,134 @@ +#pragma once + +#include +#include +#include +#include +#include + +#include + +namespace vcpkg::Commands +{ + using CommandTypeA = void (*)(const VcpkgCmdArguments& args, + const VcpkgPaths& paths, + const Triplet& default_triplet); + using CommandTypeB = void (*)(const VcpkgCmdArguments& args, const VcpkgPaths& paths); + using CommandTypeC = void (*)(const VcpkgCmdArguments& args); + + namespace BuildExternal + { + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet); + } + + namespace CI + { + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet); + } + + namespace Env + { + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet); + } + + namespace Create + { + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); + } + + namespace Edit + { + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); + } + + namespace DependInfo + { + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); + } + + namespace Search + { + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); + } + + namespace List + { + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); + } + + namespace Owns + { + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); + } + + namespace Cache + { + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); + } + + namespace Import + { + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); + } + + namespace Integrate + { + extern const char* const INTEGRATE_COMMAND_HELPSTRING; + + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); + } + + namespace PortsDiff + { + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); + } + + namespace Autocomplete + { + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); + } + + namespace Version + { + const std::string& version(); + void warn_if_vcpkg_version_mismatch(const VcpkgPaths& paths); + void perform_and_exit(const VcpkgCmdArguments& args); + } + + namespace Contact + { + const std::string& email(); + void perform_and_exit(const VcpkgCmdArguments& args); + } + + namespace Hash + { + void perform_and_exit(const VcpkgCmdArguments& args); + } + + template + struct PackageNameAndFunction + { + std::string name; + T function; + }; + + Span> get_available_commands_type_a(); + Span> get_available_commands_type_b(); + Span> get_available_commands_type_c(); + + template + T find(const std::string& command_name, const std::vector> available_commands) + { + for (const PackageNameAndFunction& cmd : available_commands) + { + if (cmd.name == command_name) + { + return cmd.function; + } + } + + // not found + return nullptr; + } +} diff --git a/toolsrc/include/vcpkg/dependencies.h b/toolsrc/include/vcpkg/dependencies.h new file mode 100644 index 000000000..2301dbc36 --- /dev/null +++ b/toolsrc/include/vcpkg/dependencies.h @@ -0,0 +1,149 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +#include + +namespace vcpkg::Dependencies +{ + enum class RequestType + { + UNKNOWN, + USER_REQUESTED, + AUTO_SELECTED + }; + + std::string to_output_string(RequestType request_type, const CStringView s); + + struct AnyParagraph + { + std::vector dependencies(const Triplet& triplet) const; + + Optional status_paragraph; + Optional binary_control_file; + Optional source_paragraph; + Optional source_control_file; + }; +} + +namespace vcpkg::Dependencies +{ + enum class InstallPlanType + { + UNKNOWN, + BUILD_AND_INSTALL, + INSTALL, + ALREADY_INSTALLED + }; + + struct InstallPlanAction : Util::MoveOnlyBase + { + static bool compare_by_name(const InstallPlanAction* left, const InstallPlanAction* right); + + InstallPlanAction(); + + InstallPlanAction(const PackageSpec& spec, + const std::unordered_set& features, + const RequestType& request_type); + InstallPlanAction(const PackageSpec& spec, const AnyParagraph& any_paragraph, const RequestType& request_type); + InstallPlanAction(const PackageSpec& spec, + const SourceControlFile& any_paragraph, + const std::unordered_set& features, + const RequestType& request_type); + + std::string displayname() const; + + PackageSpec spec; + AnyParagraph any_paragraph; + InstallPlanType plan_type; + RequestType request_type; + std::unordered_set feature_list; + }; + + enum class RemovePlanType + { + UNKNOWN, + NOT_INSTALLED, + REMOVE + }; + + struct RemovePlanAction : Util::MoveOnlyBase + { + static bool compare_by_name(const RemovePlanAction* left, const RemovePlanAction* right); + + RemovePlanAction(); + RemovePlanAction(const PackageSpec& spec, const RemovePlanType& plan_type, const RequestType& request_type); + + PackageSpec spec; + RemovePlanType plan_type; + RequestType request_type; + }; + + struct AnyAction + { + AnyAction(InstallPlanAction&& iplan) : install_plan(std::move(iplan)) {} + AnyAction(RemovePlanAction&& rplan) : remove_plan(std::move(rplan)) {} + + Optional install_plan; + Optional remove_plan; + + const PackageSpec& spec() const; + }; + + enum class ExportPlanType + { + UNKNOWN, + PORT_AVAILABLE_BUT_NOT_BUILT, + ALREADY_BUILT + }; + + struct ExportPlanAction : Util::MoveOnlyBase + { + static bool compare_by_name(const ExportPlanAction* left, const ExportPlanAction* right); + + ExportPlanAction(); + ExportPlanAction(const PackageSpec& spec, const AnyParagraph& any_paragraph, const RequestType& request_type); + + PackageSpec spec; + AnyParagraph any_paragraph; + ExportPlanType plan_type; + RequestType request_type; + }; + + __interface PortFileProvider { virtual const SourceControlFile& get_control_file(const std::string& spec) const; }; + + struct MapPortFile : Util::ResourceBase, PortFileProvider + { + const std::unordered_map& ports; + explicit MapPortFile(const std::unordered_map& map); + const SourceControlFile& get_control_file(const std::string& spec) const override; + }; + + struct PathsPortFile : Util::ResourceBase, PortFileProvider + { + const VcpkgPaths& ports; + mutable std::unordered_map cache; + explicit PathsPortFile(const VcpkgPaths& paths); + const SourceControlFile& get_control_file(const std::string& spec) const override; + }; + + std::vector create_install_plan(const PortFileProvider& port_file_provider, + const std::vector& specs, + const StatusParagraphs& status_db); + + std::vector create_remove_plan(const std::vector& specs, + const StatusParagraphs& status_db); + + std::vector create_export_plan(const VcpkgPaths& paths, + const std::vector& specs, + const StatusParagraphs& status_db); + + std::vector create_feature_install_plan(const std::unordered_map& map, + const std::vector& specs, + const StatusParagraphs& status_db); +} diff --git a/toolsrc/include/vcpkg/export.h b/toolsrc/include/vcpkg/export.h new file mode 100644 index 000000000..f3285e187 --- /dev/null +++ b/toolsrc/include/vcpkg/export.h @@ -0,0 +1,10 @@ +#pragma once + +#include + +namespace vcpkg::Export +{ + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet); + + void export_integration_files(const fs::path& raw_exported_dir_path, const VcpkgPaths& paths); +} diff --git a/toolsrc/include/vcpkg/export.ifw.h b/toolsrc/include/vcpkg/export.ifw.h new file mode 100644 index 000000000..d28a4436d --- /dev/null +++ b/toolsrc/include/vcpkg/export.ifw.h @@ -0,0 +1,26 @@ +#pragma once + +#include +#include + +#include + +#include +#include + +namespace vcpkg::Export::IFW +{ + struct Options + { + Optional maybe_repository_url; + Optional maybe_packages_dir_path; + Optional maybe_repository_dir_path; + Optional maybe_config_file_path; + Optional maybe_installer_file_path; + }; + + void do_export(const std::vector& export_plan, + const std::string& export_id, + const Options& ifw_options, + const VcpkgPaths& paths); +} diff --git a/toolsrc/include/vcpkg/globalstate.h b/toolsrc/include/vcpkg/globalstate.h new file mode 100644 index 000000000..7cea361cf --- /dev/null +++ b/toolsrc/include/vcpkg/globalstate.h @@ -0,0 +1,19 @@ +#pragma once + +#include +#include + +#include + +namespace vcpkg +{ + struct GlobalState + { + static Util::LockGuarded timer; + static std::atomic debugging; + static std::atomic feature_packages; + + static std::atomic g_init_console_cp; + static std::atomic g_init_console_output_cp; + }; +} \ No newline at end of file diff --git a/toolsrc/include/vcpkg/help.h b/toolsrc/include/vcpkg/help.h new file mode 100644 index 000000000..39ad6912d --- /dev/null +++ b/toolsrc/include/vcpkg/help.h @@ -0,0 +1,19 @@ +#pragma once + +#include +#include + +#include + +namespace vcpkg::Help +{ + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); + + void help_topic_valid_triplet(const VcpkgPaths& paths); + + void print_usage(); + + void print_example(const std::string& command_and_arguments); + + std::string create_example_string(const std::string& command_and_arguments); +} diff --git a/toolsrc/include/vcpkg/input.h b/toolsrc/include/vcpkg/input.h new file mode 100644 index 000000000..621139427 --- /dev/null +++ b/toolsrc/include/vcpkg/input.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +namespace vcpkg::Input +{ + PackageSpec check_and_get_package_spec(const std::string& package_spec_as_string, + const Triplet& default_triplet, + CStringView example_text); + FullPackageSpec check_and_get_full_package_spec(const std::string& full_package_spec_as_string, + const Triplet& default_triplet, + CStringView example_text); + + void check_triplet(const Triplet& t, const VcpkgPaths& paths); +} diff --git a/toolsrc/include/vcpkg/install.h b/toolsrc/include/vcpkg/install.h new file mode 100644 index 000000000..02600b7f5 --- /dev/null +++ b/toolsrc/include/vcpkg/install.h @@ -0,0 +1,69 @@ +#pragma once + +#include +#include +#include +#include + +#include + +namespace vcpkg::Install +{ + enum class KeepGoing + { + NO = 0, + YES + }; + + inline KeepGoing to_keep_going(const bool value) { return value ? KeepGoing::YES : KeepGoing::NO; } + + enum class PrintSummary + { + NO = 0, + YES + }; + + inline PrintSummary to_print_summary(const bool value) { return value ? PrintSummary::YES : PrintSummary::NO; } + + struct InstallDir + { + static InstallDir from_destination_root(const fs::path& destination_root, + const std::string& destination_subdirectory, + const fs::path& listfile); + + private: + fs::path m_destination; + std::string m_destination_subdirectory; + fs::path m_listfile; + + public: + const fs::path& destination() const; + const std::string& destination_subdirectory() const; + const fs::path& listfile() const; + }; + + Build::BuildResult perform_install_plan_action(const VcpkgPaths& paths, + const Dependencies::InstallPlanAction& action, + const Build::BuildPackageOptions& install_plan_options, + StatusParagraphs& status_db); + + enum class InstallResult + { + FILE_CONFLICTS, + SUCCESS, + }; + + void install_files_and_write_listfile(Files::Filesystem& fs, const fs::path& source_dir, const InstallDir& dirs); + InstallResult install_package(const VcpkgPaths& paths, + const BinaryControlFile& binary_paragraph, + StatusParagraphs* status_db); + + void perform_and_exit_ex(const std::vector& action_plan, + const Build::BuildPackageOptions& install_plan_options, + const KeepGoing keep_going, + const PrintSummary print_summary, + const VcpkgPaths& paths, + StatusParagraphs& status_db); + + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet); +} diff --git a/toolsrc/include/vcpkg/metrics.h b/toolsrc/include/vcpkg/metrics.h new file mode 100644 index 000000000..41be5002d --- /dev/null +++ b/toolsrc/include/vcpkg/metrics.h @@ -0,0 +1,28 @@ +#pragma once + +#include + +#include + +namespace vcpkg::Metrics +{ + struct Metrics : Util::ResourceBase + { + void set_send_metrics(bool should_send_metrics); + void set_print_metrics(bool should_print_metrics); + void set_user_information(const std::string& user_id, const std::string& first_use_time); + void init_user_information(std::string& user_id, std::string& first_use_time); + + void track_metric(const std::string& name, double value); + void track_property(const std::string& name, const std::string& value); + void track_property(const std::string& name, const std::wstring& value); + + void upload(const std::string& payload); + void flush(); + }; + + extern Util::LockGuarded g_metrics; + + std::wstring get_SQM_user(); + bool get_compiled_metrics_enabled(); +} diff --git a/toolsrc/include/vcpkg/packagespec.h b/toolsrc/include/vcpkg/packagespec.h new file mode 100644 index 000000000..ee34f14a3 --- /dev/null +++ b/toolsrc/include/vcpkg/packagespec.h @@ -0,0 +1,95 @@ +#pragma once + +#include +#include +#include + +namespace vcpkg +{ + struct ParsedSpecifier + { + std::string name; + std::vector features; + std::string triplet; + + static ExpectedT from_string(const std::string& input); + }; + + struct PackageSpec + { + static ExpectedT from_name_and_triplet(const std::string& name, + const Triplet& triplet); + + const std::string& name() const; + + const Triplet& triplet() const; + + std::string dir() const; + + std::string to_string() const; + + private: + std::string m_name; + Triplet m_triplet; + }; + + struct FeatureSpec + { + FeatureSpec(const PackageSpec& spec, const std::string& feature) : m_spec(spec), m_feature(feature) {} + + const std::string& name() const { return m_spec.name(); } + const std::string& feature() const { return m_feature; } + const Triplet& triplet() const { return m_spec.triplet(); } + + const PackageSpec& spec() const { return m_spec; } + + std::string to_string() const; + + static std::vector from_strings_and_triplet(const std::vector& depends, + const Triplet& t); + + private: + PackageSpec m_spec; + std::string m_feature; + }; + + struct FullPackageSpec + { + PackageSpec package_spec; + std::vector features; + + static std::vector to_feature_specs(const std::vector& specs); + + static ExpectedT from_string(const std::string& spec_as_string, + const Triplet& default_triplet); + }; + + struct Features + { + std::string name; + std::vector features; + + static ExpectedT from_string(const std::string& input); + }; + + bool operator==(const PackageSpec& left, const PackageSpec& right); + bool operator!=(const PackageSpec& left, const PackageSpec& right); +} + +template<> +struct std::hash +{ + size_t operator()(const vcpkg::PackageSpec& value) const + { + size_t hash = 17; + hash = hash * 31 + std::hash()(value.name()); + hash = hash * 31 + std::hash()(value.triplet()); + return hash; + } +}; + +template<> +struct std::equal_to +{ + bool operator()(const vcpkg::PackageSpec& left, const vcpkg::PackageSpec& right) const { return left == right; } +}; diff --git a/toolsrc/include/vcpkg/packagespecparseresult.h b/toolsrc/include/vcpkg/packagespecparseresult.h new file mode 100644 index 000000000..8a56574fd --- /dev/null +++ b/toolsrc/include/vcpkg/packagespecparseresult.h @@ -0,0 +1,33 @@ +#pragma once + +#include +#include + +namespace vcpkg +{ + enum class PackageSpecParseResult + { + SUCCESS = 0, + TOO_MANY_COLONS, + INVALID_CHARACTERS + }; + + CStringView to_string(PackageSpecParseResult ev) noexcept; + + template<> + struct ErrorHolder + { + ErrorHolder() : m_err(PackageSpecParseResult::SUCCESS) {} + ErrorHolder(PackageSpecParseResult err) : m_err(err) {} + + constexpr bool has_error() const { return m_err != PackageSpecParseResult::SUCCESS; } + + const PackageSpecParseResult& error() const { return m_err; } + PackageSpecParseResult& error() { return m_err; } + + CStringView to_string() const { return vcpkg::to_string(m_err); } + + private: + PackageSpecParseResult m_err; + }; +} diff --git a/toolsrc/include/vcpkg/paragraphparseresult.h b/toolsrc/include/vcpkg/paragraphparseresult.h new file mode 100644 index 000000000..abdd9eecd --- /dev/null +++ b/toolsrc/include/vcpkg/paragraphparseresult.h @@ -0,0 +1,33 @@ +#pragma once + +#include + +namespace vcpkg +{ + enum class ParagraphParseResult + { + SUCCESS = 0, + EXPECTED_ONE_PARAGRAPH + }; + + struct ParagraphParseResultCategoryImpl final : std::error_category + { + virtual const char* name() const noexcept override; + + virtual std::string message(int ev) const noexcept override; + }; + + const std::error_category& paragraph_parse_result_category(); + + std::error_code make_error_code(ParagraphParseResult e); + + ParagraphParseResult to_paragraph_parse_result(int i); + + ParagraphParseResult to_paragraph_parse_result(std::error_code ec); +} + +// Enable implicit conversion to std::error_code +template<> +struct std::is_error_code_enum : ::std::true_type +{ +}; diff --git a/toolsrc/include/vcpkg/paragraphs.h b/toolsrc/include/vcpkg/paragraphs.h new file mode 100644 index 000000000..c8dbea646 --- /dev/null +++ b/toolsrc/include/vcpkg/paragraphs.h @@ -0,0 +1,38 @@ +#pragma once + +#include +#include +#include +#include + +#include + +#include + +namespace vcpkg::Paragraphs +{ + using RawParagraph = Parse::RawParagraph; + + Expected get_single_paragraph(const Files::Filesystem& fs, const fs::path& control_path); + Expected> get_paragraphs(const Files::Filesystem& fs, const fs::path& control_path); + Expected parse_single_paragraph(const std::string& str); + Expected> parse_paragraphs(const std::string& str); + + Parse::ParseExpected try_load_port(const Files::Filesystem& fs, const fs::path& control_path); + + Expected try_load_cached_control_package(const VcpkgPaths& paths, const PackageSpec& spec); + + struct LoadResults + { + std::vector> paragraphs; + std::vector> errors; + }; + + LoadResults try_load_all_ports(const Files::Filesystem& fs, const fs::path& ports_dir); + + std::vector> load_all_ports(const Files::Filesystem& fs, + const fs::path& ports_dir); + + std::map load_all_port_names_and_versions(const Files::Filesystem& fs, + const fs::path& ports_dir); +} diff --git a/toolsrc/include/vcpkg/parse.h b/toolsrc/include/vcpkg/parse.h new file mode 100644 index 000000000..4b33e302e --- /dev/null +++ b/toolsrc/include/vcpkg/parse.h @@ -0,0 +1,38 @@ +#pragma once + +#include +#include + +#include +#include + +namespace vcpkg::Parse +{ + struct ParseControlErrorInfo + { + std::string name; + std::vector missing_fields; + std::vector extra_fields; + std::error_code error; + }; + + template + using ParseExpected = ExpectedT, std::unique_ptr>; + + using RawParagraph = std::unordered_map; + + struct ParagraphParser + { + ParagraphParser(RawParagraph&& fields) : fields(std::move(fields)) {} + + void required_field(const std::string& fieldname, std::string& out); + std::string optional_field(const std::string& fieldname) const; + std::unique_ptr error_info(const std::string& name) const; + + private: + RawParagraph&& fields; + std::vector missing_fields; + }; + + std::vector parse_comma_list(const std::string& str); +} diff --git a/toolsrc/include/vcpkg/postbuildlint.buildtype.h b/toolsrc/include/vcpkg/postbuildlint.buildtype.h new file mode 100644 index 000000000..ff651fd7a --- /dev/null +++ b/toolsrc/include/vcpkg/postbuildlint.buildtype.h @@ -0,0 +1,68 @@ +#pragma once + +#include +#include + +#include +#include + +namespace vcpkg::PostBuildLint +{ + enum class ConfigurationType + { + DEBUG, + RELEASE, + }; + + struct BuildType + { + enum class BackingEnum + { + DEBUG_STATIC = 1, + DEBUG_DYNAMIC, + RELEASE_STATIC, + RELEASE_DYNAMIC + }; + + static BuildType value_of(const ConfigurationType& config, const Build::LinkageType& linkage); + + BuildType() = delete; + + constexpr BuildType(const BackingEnum backing_enum, + const ConfigurationType config, + const Build::LinkageType linkage) + : backing_enum(backing_enum), m_config(config), m_linkage(linkage) + { + } + + constexpr operator BackingEnum() const { return backing_enum; } + + const ConfigurationType& config() const; + const Build::LinkageType& linkage() const; + const std::regex& crt_regex() const; + const std::string& to_string() const; + + private: + BackingEnum backing_enum; + ConfigurationType m_config; + Build::LinkageType m_linkage; + }; + + namespace BuildTypeC + { + using Build::LinkageType; + using BE = BuildType::BackingEnum; + + static constexpr CStringView ENUM_NAME = "vcpkg::PostBuildLint::BuildType"; + + static constexpr BuildType DEBUG_STATIC = {BE::DEBUG_STATIC, ConfigurationType::DEBUG, LinkageType::STATIC}; + static constexpr BuildType DEBUG_DYNAMIC = {BE::DEBUG_DYNAMIC, ConfigurationType::DEBUG, LinkageType::DYNAMIC}; + static constexpr BuildType RELEASE_STATIC = { + BE::RELEASE_STATIC, ConfigurationType::RELEASE, LinkageType::STATIC}; + static constexpr BuildType RELEASE_DYNAMIC = { + BE::RELEASE_DYNAMIC, ConfigurationType::RELEASE, LinkageType::DYNAMIC}; + + static constexpr std::array VALUES = { + DEBUG_STATIC, DEBUG_DYNAMIC, RELEASE_STATIC, RELEASE_DYNAMIC}; + } +} diff --git a/toolsrc/include/vcpkg/postbuildlint.h b/toolsrc/include/vcpkg/postbuildlint.h new file mode 100644 index 000000000..5dcfeb8df --- /dev/null +++ b/toolsrc/include/vcpkg/postbuildlint.h @@ -0,0 +1,13 @@ +#pragma once + +#include +#include +#include + +namespace vcpkg::PostBuildLint +{ + size_t perform_all_checks(const PackageSpec& spec, + const VcpkgPaths& paths, + const Build::PreBuildInfo& pre_build_info, + const Build::BuildInfo& build_info); +} diff --git a/toolsrc/include/vcpkg/remove.h b/toolsrc/include/vcpkg/remove.h new file mode 100644 index 000000000..f4d381ca3 --- /dev/null +++ b/toolsrc/include/vcpkg/remove.h @@ -0,0 +1,24 @@ +#pragma once + +#include +#include +#include + +namespace vcpkg::Remove +{ + enum class Purge + { + NO = 0, + YES + }; + + inline Purge to_purge(const bool value) { return value ? Purge::YES : Purge::NO; } + + void perform_remove_plan_action(const VcpkgPaths& paths, + const Dependencies::RemovePlanAction& action, + const Purge purge, + StatusParagraphs& status_db); + + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet); + void remove_package(const VcpkgPaths& paths, const PackageSpec& spec, StatusParagraphs* status_db); +} diff --git a/toolsrc/include/vcpkg/sourceparagraph.h b/toolsrc/include/vcpkg/sourceparagraph.h new file mode 100644 index 000000000..0a02e4cda --- /dev/null +++ b/toolsrc/include/vcpkg/sourceparagraph.h @@ -0,0 +1,97 @@ +#pragma once + +#include +#include + +#include +#include +#include + +#include +#include + +namespace vcpkg +{ + struct Dependency + { + Features depend; + std::string qualifier; + + std::string name() const; + static Dependency parse_dependency(std::string name, std::string qualifier); + }; + + std::vector filter_dependencies(const std::vector& deps, const Triplet& t); + std::vector filter_dependencies_to_specs(const std::vector& deps, const Triplet& t); + + // zlib[uwp] becomes Dependency{"zlib", "uwp"} + std::vector expand_qualified_dependencies(const std::vector& depends); + + std::string to_string(const Dependency& dep); + + struct FeatureParagraph + { + std::string name; + std::string description; + std::vector depends; + }; + + /// + /// Port metadata (CONTROL file) + /// + struct SourceParagraph + { + std::string name; + std::string version; + std::string description; + std::string maintainer; + std::vector supports; + std::vector depends; + std::vector default_features; + }; + struct SourceControlFile + { + static Parse::ParseExpected parse_control_file( + std::vector&& control_paragraphs); + + std::unique_ptr core_paragraph; + std::vector> feature_paragraphs; + }; + + void print_error_message(Span> error_info_list); + inline void print_error_message(const std::unique_ptr& error_info_list) + { + return print_error_message({&error_info_list, 1}); + } + + struct Supports + { + static ExpectedT> parse(const std::vector& strs); + + using Architecture = System::CPUArchitecture; + + enum class Platform + { + WINDOWS, + UWP, + }; + enum class Linkage + { + DYNAMIC, + STATIC, + }; + enum class ToolsetVersion + { + V140, + V141, + }; + + bool is_supported(Architecture arch, Platform plat, Linkage crt, ToolsetVersion tools); + + private: + std::vector architectures; + std::vector platforms; + std::vector crt_linkages; + std::vector toolsets; + }; +} diff --git a/toolsrc/include/vcpkg/statusparagraph.h b/toolsrc/include/vcpkg/statusparagraph.h new file mode 100644 index 000000000..ca84b1bb7 --- /dev/null +++ b/toolsrc/include/vcpkg/statusparagraph.h @@ -0,0 +1,45 @@ +#pragma once + +#include + +#include + +namespace vcpkg +{ + enum class InstallState + { + ERROR_STATE, + NOT_INSTALLED, + HALF_INSTALLED, + INSTALLED, + }; + + enum class Want + { + ERROR_STATE, + UNKNOWN, + INSTALL, + HOLD, + DEINSTALL, + PURGE + }; + + /// + /// Installed package metadata + /// + struct StatusParagraph + { + StatusParagraph(); + explicit StatusParagraph(std::unordered_map&& fields); + + BinaryParagraph package; + Want want; + InstallState state; + }; + + void serialize(const StatusParagraph& pgh, std::string& out_str); + + std::string to_string(InstallState f); + + std::string to_string(Want f); +} diff --git a/toolsrc/include/vcpkg/statusparagraphs.h b/toolsrc/include/vcpkg/statusparagraphs.h new file mode 100644 index 000000000..c2f3b7b8e --- /dev/null +++ b/toolsrc/include/vcpkg/statusparagraphs.h @@ -0,0 +1,47 @@ +#pragma once +#include + +#include +#include + +namespace vcpkg +{ + struct StatusParagraphs + { + StatusParagraphs(); + explicit StatusParagraphs(std::vector>&& ps); + + using container = std::vector>; + using iterator = container::reverse_iterator; + using const_iterator = container::const_reverse_iterator; + + const_iterator find(const PackageSpec& spec) const { return find(spec.name(), spec.triplet()); } + const_iterator find(const std::string& name, const Triplet& triplet) const; + iterator find(const std::string& name, const Triplet& triplet); + std::vector*> find_all(const std::string& name, const Triplet& triplet); + iterator find(const std::string& name, const Triplet& triplet, const std::string& feature); + + const_iterator find_installed(const PackageSpec& spec) const + { + return find_installed(spec.name(), spec.triplet()); + } + const_iterator find_installed(const std::string& name, const Triplet& triplet) const; + + iterator insert(std::unique_ptr); + + friend void serialize(const StatusParagraphs& pgh, std::string& out_str); + + iterator end() { return paragraphs.rend(); } + + const_iterator end() const { return paragraphs.rend(); } + + iterator begin() { return paragraphs.rbegin(); } + + const_iterator begin() const { return paragraphs.rbegin(); } + + private: + std::vector> paragraphs; + }; + + void serialize(const StatusParagraphs& pgh, std::string& out_str); +} diff --git a/toolsrc/include/vcpkg/triplet.h b/toolsrc/include/vcpkg/triplet.h new file mode 100644 index 000000000..46a52f8e6 --- /dev/null +++ b/toolsrc/include/vcpkg/triplet.h @@ -0,0 +1,43 @@ +#pragma once + +#include + +namespace vcpkg +{ + struct TripletInstance; + + struct Triplet + { + public: + constexpr Triplet() : m_instance(&DEFAULT_INSTANCE) {} + + static Triplet from_canonical_name(const std::string& triplet_as_string); + + static const Triplet X86_WINDOWS; + static const Triplet X64_WINDOWS; + static const Triplet X86_UWP; + static const Triplet X64_UWP; + static const Triplet ARM_UWP; + + const std::string& canonical_name() const; + const std::string& to_string() const; + size_t hash_code() const; + + bool operator==(const Triplet& other) const; + + private: + static const TripletInstance DEFAULT_INSTANCE; + + constexpr Triplet(const TripletInstance* ptr) : m_instance(ptr) {} + + const TripletInstance* m_instance; + }; + + bool operator!=(const Triplet& left, const Triplet& right); +} + +template<> +struct std::hash +{ + size_t operator()(const vcpkg::Triplet& t) const { return t.hash_code(); } +}; diff --git a/toolsrc/include/vcpkg/update.h b/toolsrc/include/vcpkg/update.h new file mode 100644 index 000000000..e7303d1b0 --- /dev/null +++ b/toolsrc/include/vcpkg/update.h @@ -0,0 +1,21 @@ +#pragma once + +#include +#include +#include +#include +#include + +namespace vcpkg::Update +{ + struct OutdatedPackage + { + static bool compare_by_name(const OutdatedPackage& left, const OutdatedPackage& right); + + PackageSpec spec; + VersionDiff version_diff; + }; + + std::vector find_outdated_packages(const VcpkgPaths& paths, const StatusParagraphs& status_db); + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); +} \ No newline at end of file diff --git a/toolsrc/include/vcpkg/vcpkgcmdarguments.h b/toolsrc/include/vcpkg/vcpkgcmdarguments.h new file mode 100644 index 000000000..6c47b98f6 --- /dev/null +++ b/toolsrc/include/vcpkg/vcpkgcmdarguments.h @@ -0,0 +1,50 @@ +#pragma once + +#include + +#include +#include +#include +#include + +namespace vcpkg +{ + struct ParsedArguments + { + std::unordered_set switches; + std::unordered_map settings; + }; + + struct VcpkgCmdArguments + { + static VcpkgCmdArguments create_from_command_line(const int argc, const wchar_t* const* const argv); + static VcpkgCmdArguments create_from_arg_sequence(const std::string* arg_begin, const std::string* arg_end); + + std::unique_ptr vcpkg_root_dir; + std::unique_ptr triplet; + Optional debug = nullopt; + Optional sendmetrics = nullopt; + Optional printmetrics = nullopt; + + std::string command; + std::vector command_arguments; + std::unordered_set check_and_get_optional_command_arguments( + const std::vector& valid_options) const + { + return std::move(check_and_get_optional_command_arguments(valid_options, {}).switches); + } + + ParsedArguments check_and_get_optional_command_arguments(const std::vector& valid_switches, + const std::vector& valid_settings) const; + + void check_max_arg_count(const size_t expected_arg_count) const; + void check_max_arg_count(const size_t expected_arg_count, const std::string& example_text) const; + void check_min_arg_count(const size_t expected_arg_count) const; + void check_min_arg_count(const size_t expected_arg_count, const std::string& example_text) const; + void check_exact_arg_count(const size_t expected_arg_count) const; + void check_exact_arg_count(const size_t expected_arg_count, const std::string& example_text) const; + + private: + std::unordered_map> optional_command_arguments; + }; +} diff --git a/toolsrc/include/vcpkg/vcpkglib.h b/toolsrc/include/vcpkg/vcpkglib.h new file mode 100644 index 000000000..b2aad8d7b --- /dev/null +++ b/toolsrc/include/vcpkg/vcpkglib.h @@ -0,0 +1,38 @@ +#pragma once + +#include +#include +#include + +namespace vcpkg +{ + StatusParagraphs database_load_check(const VcpkgPaths& paths); + + void write_update(const VcpkgPaths& paths, const StatusParagraph& p); + + struct StatusParagraphAndAssociatedFiles + { + StatusParagraph pgh; + SortedVector files; + }; + + std::vector get_installed_ports(const StatusParagraphs& status_db); + std::vector get_installed_files(const VcpkgPaths& paths, + const StatusParagraphs& status_db); + + struct CMakeVariable + { + CMakeVariable(const CWStringView varname, const wchar_t* varvalue); + CMakeVariable(const CWStringView varname, const std::string& varvalue); + CMakeVariable(const CWStringView varname, const std::wstring& varvalue); + CMakeVariable(const CWStringView varname, const fs::path& path); + + std::wstring s; + }; + + std::wstring make_cmake_cmd(const fs::path& cmake_exe, + const fs::path& cmake_script, + const std::vector& pass_variables); + + std::string shorten_text(const std::string& desc, size_t length); +} // namespace vcpkg diff --git a/toolsrc/include/vcpkg/vcpkgpaths.h b/toolsrc/include/vcpkg/vcpkgpaths.h new file mode 100644 index 000000000..df4adfd83 --- /dev/null +++ b/toolsrc/include/vcpkg/vcpkgpaths.h @@ -0,0 +1,85 @@ +#pragma once + +#include +#include + +#include +#include +#include + +namespace vcpkg +{ + struct ToolsetArchOption + { + CWStringView name; + System::CPUArchitecture host_arch; + System::CPUArchitecture target_arch; + }; + + struct Toolset + { + fs::path visual_studio_root_path; + fs::path dumpbin; + fs::path vcvarsall; + std::vector vcvarsall_options; + CWStringView version; + std::vector supported_architectures; + }; + + struct VcpkgPaths + { + static Expected create(const fs::path& vcpkg_root_dir); + + fs::path package_dir(const PackageSpec& spec) const; + fs::path port_dir(const PackageSpec& spec) const; + fs::path port_dir(const std::string& name) const; + fs::path build_info_file_path(const PackageSpec& spec) const; + fs::path listfile_path(const BinaryParagraph& pgh) const; + + bool is_valid_triplet(const Triplet& t) const; + + fs::path root; + fs::path packages; + fs::path buildtrees; + fs::path downloads; + fs::path ports; + fs::path installed; + fs::path triplets; + fs::path scripts; + + fs::path buildsystems; + fs::path buildsystems_msbuild_targets; + + fs::path vcpkg_dir; + fs::path vcpkg_dir_status_file; + fs::path vcpkg_dir_info; + fs::path vcpkg_dir_updates; + + fs::path ports_cmake; + + const fs::path& get_cmake_exe() const; + const fs::path& get_git_exe() const; + const fs::path& get_nuget_exe() const; + const fs::path& get_ifw_installerbase_exe() const; + const fs::path& get_ifw_binarycreator_exe() const; + const fs::path& get_ifw_repogen_exe() const; + + /// Retrieve a toolset matching a VS version + /// + /// Valid version strings are "v140", "v141", and "". Empty string gets the latest. + /// + const Toolset& VcpkgPaths::get_toolset(const Optional& toolset_version, + const Optional& visual_studio_path) const; + + Files::Filesystem& get_filesystem() const; + + private: + Lazy cmake_exe; + Lazy git_exe; + Lazy nuget_exe; + Lazy ifw_installerbase_exe; + Lazy ifw_binarycreator_exe; + Lazy ifw_repogen_exe; + Lazy> toolsets; + }; +} diff --git a/toolsrc/include/vcpkg/versiont.h b/toolsrc/include/vcpkg/versiont.h new file mode 100644 index 000000000..67efd8da3 --- /dev/null +++ b/toolsrc/include/vcpkg/versiont.h @@ -0,0 +1,29 @@ +#pragma once +#include + +namespace vcpkg +{ + struct VersionT + { + VersionT(); + VersionT(const std::string& value); + + std::string to_string() const; + + std::string value; + }; + + bool operator==(const VersionT& left, const VersionT& right); + bool operator!=(const VersionT& left, const VersionT& right); + + struct VersionDiff + { + VersionT left; + VersionT right; + + VersionDiff(); + VersionDiff(const VersionT& left, const VersionT& right); + + std::string to_string() const; + }; +} diff --git a/toolsrc/include/vcpkg_Build.h b/toolsrc/include/vcpkg_Build.h deleted file mode 100644 index 5ba675757..000000000 --- a/toolsrc/include/vcpkg_Build.h +++ /dev/null @@ -1,192 +0,0 @@ -#pragma once - -#include "CStringView.h" -#include "PackageSpec.h" -#include "StatusParagraphs.h" -#include "VcpkgPaths.h" -#include "vcpkg_Files.h" -#include "vcpkg_optional.h" - -#include -#include -#include - -namespace vcpkg::Build -{ - enum class UseHeadVersion - { - NO = 0, - YES - }; - - inline UseHeadVersion to_use_head_version(const bool value) - { - return value ? UseHeadVersion::YES : UseHeadVersion::NO; - } - - inline bool to_bool(const UseHeadVersion value) { return value == UseHeadVersion::YES; } - - enum class AllowDownloads - { - NO = 0, - YES - }; - - inline AllowDownloads to_allow_downloads(const bool value) - { - return value ? AllowDownloads::YES : AllowDownloads::NO; - } - - inline bool to_bool(const AllowDownloads value) { return value == AllowDownloads::YES; } - - struct BuildPackageOptions - { - UseHeadVersion use_head_version; - AllowDownloads allow_downloads; - }; - - enum class BuildResult - { - NULLVALUE = 0, - SUCCEEDED, - BUILD_FAILED, - POST_BUILD_CHECKS_FAILED, - FILE_CONFLICTS, - CASCADED_DUE_TO_MISSING_DEPENDENCIES - }; - - static constexpr std::array BUILD_RESULT_VALUES = { - BuildResult::SUCCEEDED, - BuildResult::BUILD_FAILED, - BuildResult::POST_BUILD_CHECKS_FAILED, - BuildResult::FILE_CONFLICTS, - BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES}; - - const std::string& to_string(const BuildResult build_result); - std::string create_error_message(const BuildResult build_result, const PackageSpec& spec); - std::string create_user_troubleshooting_message(const PackageSpec& spec); - - /// - /// Settings from the triplet file which impact the build environment and post-build checks - /// - struct PreBuildInfo - { - /// - /// Runs the triplet file in a "capture" mode to create a PreBuildInfo - /// - static PreBuildInfo from_triplet_file(const VcpkgPaths& paths, const Triplet& triplet); - - std::string target_architecture; - std::string cmake_system_name; - std::string cmake_system_version; - Optional platform_toolset; - Optional visual_studio_path; - }; - - std::wstring make_build_env_cmd(const PreBuildInfo& pre_build_info, const Toolset& toolset); - - struct ExtendedBuildResult - { - BuildResult code; - std::vector unmet_dependencies; - }; - - struct BuildPackageConfig - { - BuildPackageConfig(const SourceParagraph& src, - const Triplet& triplet, - fs::path&& port_dir, - const BuildPackageOptions& build_package_options) - : src(src) - , scf(nullptr) - , triplet(triplet) - , port_dir(std::move(port_dir)) - , build_package_options(build_package_options) - , feature_list(nullptr) - { - } - - BuildPackageConfig(const SourceControlFile& src, - const Triplet& triplet, - fs::path&& port_dir, - const BuildPackageOptions& build_package_options, - const std::unordered_set& feature_list) - : src(*src.core_paragraph) - , scf(&src) - , triplet(triplet) - , port_dir(std::move(port_dir)) - , build_package_options(build_package_options) - , feature_list(&feature_list) - { - } - - const SourceParagraph& src; - const SourceControlFile* scf; - const Triplet& triplet; - fs::path port_dir; - const BuildPackageOptions& build_package_options; - const std::unordered_set* feature_list; - }; - - ExtendedBuildResult build_package(const VcpkgPaths& paths, - const BuildPackageConfig& config, - const StatusParagraphs& status_db); - - enum class BuildPolicy - { - EMPTY_PACKAGE, - DLLS_WITHOUT_LIBS, - ONLY_RELEASE_CRT, - EMPTY_INCLUDE_FOLDER, - ALLOW_OBSOLETE_MSVCRT, - // Must be last - COUNT, - }; - - constexpr std::array G_ALL_POLICIES = { - BuildPolicy::EMPTY_PACKAGE, - BuildPolicy::DLLS_WITHOUT_LIBS, - BuildPolicy::ONLY_RELEASE_CRT, - BuildPolicy::EMPTY_INCLUDE_FOLDER, - BuildPolicy::ALLOW_OBSOLETE_MSVCRT, - }; - - const std::string& to_string(BuildPolicy policy); - CStringView to_cmake_variable(BuildPolicy policy); - - struct BuildPolicies - { - BuildPolicies() = default; - BuildPolicies(std::map&& map) : m_policies(std::move(map)) {} - - bool is_enabled(BuildPolicy policy) const - { - const auto it = m_policies.find(policy); - if (it != m_policies.cend()) return it->second; - return false; - } - - private: - std::map m_policies; - }; - - enum class LinkageType : char - { - DYNAMIC, - STATIC, - }; - - Optional to_linkage_type(const std::string& str); - - struct BuildInfo - { - LinkageType crt_linkage; - LinkageType library_linkage; - - Optional version; - - BuildPolicies policies; - }; - - BuildInfo read_build_info(const Files::Filesystem& fs, const fs::path& filepath); -} diff --git a/toolsrc/include/vcpkg_Checks.h b/toolsrc/include/vcpkg_Checks.h deleted file mode 100644 index ce486ac19..000000000 --- a/toolsrc/include/vcpkg_Checks.h +++ /dev/null @@ -1,54 +0,0 @@ -#pragma once - -#include "LineInfo.h" -#include "vcpkg_Strings.h" - -namespace vcpkg::Checks -{ - void register_console_ctrl_handler(); - - // Indicate that an internal error has occurred and exit the tool. This should be used when invariants have been - // broken. - [[noreturn]] void unreachable(const LineInfo& line_info); - - [[noreturn]] void exit_with_code(const LineInfo& line_info, const int exit_code); - - // Exit the tool without an error message. - [[noreturn]] inline void exit_fail(const LineInfo& line_info) { exit_with_code(line_info, EXIT_FAILURE); } - - // Exit the tool successfully. - [[noreturn]] inline void exit_success(const LineInfo& line_info) { exit_with_code(line_info, EXIT_SUCCESS); } - - // Display an error message to the user and exit the tool. - [[noreturn]] void exit_with_message(const LineInfo& line_info, const CStringView error_message); - - template - // Display an error message to the user and exit the tool. - [[noreturn]] void exit_with_message(const LineInfo& line_info, - const char* error_message_template, - const Arg1 error_message_arg1, - const Args&... error_message_args) - { - exit_with_message(line_info, - Strings::format(error_message_template, error_message_arg1, error_message_args...)); - } - - void check_exit(const LineInfo& line_info, bool expression); - - void check_exit(const LineInfo& line_info, bool expression, const CStringView error_message); - - template - void check_exit(const LineInfo& line_info, - Conditional&& expression, - const char* error_message_template, - const Arg1 error_message_arg1, - const Args&... error_message_args) - { - if (!expression) - { - // Only create the string if the expression is false - exit_with_message(line_info, - Strings::format(error_message_template, error_message_arg1, error_message_args...)); - } - } -} diff --git a/toolsrc/include/vcpkg_Chrono.h b/toolsrc/include/vcpkg_Chrono.h deleted file mode 100644 index c14019ff9..000000000 --- a/toolsrc/include/vcpkg_Chrono.h +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once - -#include -#include - -namespace vcpkg -{ - class ElapsedTime - { - public: - static ElapsedTime create_started(); - - constexpr ElapsedTime() : m_start_tick() {} - - template - TimeUnit elapsed() const - { - return std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - this->m_start_tick); - } - - double microseconds() const { return elapsed>().count(); } - - std::string to_string() const; - - private: - std::chrono::high_resolution_clock::time_point m_start_tick; - }; -} diff --git a/toolsrc/include/vcpkg_Commands.h b/toolsrc/include/vcpkg_Commands.h deleted file mode 100644 index 7cfa2760e..000000000 --- a/toolsrc/include/vcpkg_Commands.h +++ /dev/null @@ -1,258 +0,0 @@ -#pragma once - -#include "StatusParagraphs.h" -#include "VcpkgCmdArguments.h" -#include "VcpkgPaths.h" -#include "VersionT.h" -#include "vcpkg_Build.h" -#include "vcpkg_Dependencies.h" -#include - -namespace vcpkg::Commands -{ - using CommandTypeA = void (*)(const VcpkgCmdArguments& args, - const VcpkgPaths& paths, - const Triplet& default_triplet); - using CommandTypeB = void (*)(const VcpkgCmdArguments& args, const VcpkgPaths& paths); - using CommandTypeC = void (*)(const VcpkgCmdArguments& args); - - namespace BuildCommand - { - void perform_and_exit(const FullPackageSpec& full_spec, - const fs::path& port_dir, - const std::unordered_set& options, - const VcpkgPaths& paths); - - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet); - } - - namespace BuildExternal - { - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet); - } - - namespace Install - { - enum class KeepGoing - { - NO = 0, - YES - }; - - inline KeepGoing to_keep_going(const bool value) { return value ? KeepGoing::YES : KeepGoing::NO; } - - enum class PrintSummary - { - NO = 0, - YES - }; - - inline PrintSummary to_print_summary(const bool value) { return value ? PrintSummary::YES : PrintSummary::NO; } - - struct InstallDir - { - static InstallDir from_destination_root(const fs::path& destination_root, - const std::string& destination_subdirectory, - const fs::path& listfile); - - private: - fs::path m_destination; - std::string m_destination_subdirectory; - fs::path m_listfile; - - public: - const fs::path& destination() const; - const std::string& destination_subdirectory() const; - const fs::path& listfile() const; - }; - - Build::BuildResult perform_install_plan_action(const VcpkgPaths& paths, - const Dependencies::InstallPlanAction& action, - const Build::BuildPackageOptions& install_plan_options, - StatusParagraphs& status_db); - - enum class InstallResult - { - FILE_CONFLICTS, - SUCCESS, - }; - - void install_files_and_write_listfile(Files::Filesystem& fs, - const fs::path& source_dir, - const InstallDir& dirs); - InstallResult install_package(const VcpkgPaths& paths, - const BinaryControlFile& binary_paragraph, - StatusParagraphs* status_db); - - void perform_and_exit(const std::vector& action_plan, - const Build::BuildPackageOptions& install_plan_options, - const KeepGoing keep_going, - const PrintSummary print_summary, - const VcpkgPaths& paths, - StatusParagraphs& status_db); - - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet); - } - - namespace Export - { - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet); - } - - namespace CI - { - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet); - } - - namespace Remove - { - enum class Purge - { - NO = 0, - YES - }; - - inline Purge to_purge(const bool value) { return value ? Purge::YES : Purge::NO; } - - void perform_remove_plan_action(const VcpkgPaths& paths, - const Dependencies::RemovePlanAction& action, - const Purge purge, - StatusParagraphs& status_db); - - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet); - void remove_package(const VcpkgPaths& paths, const PackageSpec& spec, StatusParagraphs* status_db); - } - - namespace Update - { - struct OutdatedPackage - { - static bool compare_by_name(const OutdatedPackage& left, const OutdatedPackage& right); - - PackageSpec spec; - VersionDiff version_diff; - }; - - std::vector find_outdated_packages(const VcpkgPaths& paths, const StatusParagraphs& status_db); - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); - } - - namespace Env - { - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet); - } - - namespace Create - { - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); - } - - namespace Edit - { - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); - } - - namespace DependInfo - { - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); - } - - namespace Search - { - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); - } - - namespace List - { - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); - } - - namespace Owns - { - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); - } - - namespace Cache - { - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); - } - - namespace Import - { - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); - } - - namespace Integrate - { - extern const char* const INTEGRATE_COMMAND_HELPSTRING; - - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); - } - - namespace PortsDiff - { - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); - } - - namespace Autocomplete - { - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); - } - - namespace Help - { - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); - - void help_topic_valid_triplet(const VcpkgPaths& paths); - - void print_usage(); - - void print_example(const std::string& command_and_arguments); - - std::string create_example_string(const std::string& command_and_arguments); - } - - namespace Version - { - const std::string& version(); - void warn_if_vcpkg_version_mismatch(const VcpkgPaths& paths); - void perform_and_exit(const VcpkgCmdArguments& args); - } - - namespace Contact - { - const std::string& email(); - void perform_and_exit(const VcpkgCmdArguments& args); - } - - namespace Hash - { - void perform_and_exit(const VcpkgCmdArguments& args); - } - - template - struct PackageNameAndFunction - { - std::string name; - T function; - }; - - const std::vector>& get_available_commands_type_a(); - const std::vector>& get_available_commands_type_b(); - const std::vector>& get_available_commands_type_c(); - - template - T find(const std::string& command_name, const std::vector> available_commands) - { - for (const PackageNameAndFunction& cmd : available_commands) - { - if (cmd.name == command_name) - { - return cmd.function; - } - } - - // not found - return nullptr; - } -} diff --git a/toolsrc/include/vcpkg_Commands_Export.h b/toolsrc/include/vcpkg_Commands_Export.h deleted file mode 100644 index 6e698c1b4..000000000 --- a/toolsrc/include/vcpkg_Commands_Export.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -#include "VcpkgPaths.h" - -namespace vcpkg::Commands::Export -{ - void export_integration_files(const fs::path& raw_exported_dir_path, const VcpkgPaths& paths); -} diff --git a/toolsrc/include/vcpkg_Commands_Export_IFW.h b/toolsrc/include/vcpkg_Commands_Export_IFW.h deleted file mode 100644 index 7bee45eaf..000000000 --- a/toolsrc/include/vcpkg_Commands_Export_IFW.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include "VcpkgPaths.h" -#include "vcpkg_Dependencies.h" -#include "vcpkg_Files.h" - -#include -#include - -namespace vcpkg::Commands::Export::IFW -{ - struct Options - { - Optional maybe_repository_url; - Optional maybe_packages_dir_path; - Optional maybe_repository_dir_path; - Optional maybe_config_file_path; - Optional maybe_installer_file_path; - }; - - void do_export(const std::vector& export_plan, - const std::string& export_id, - const Options& ifw_options, - const VcpkgPaths& paths); -} diff --git a/toolsrc/include/vcpkg_Dependencies.h b/toolsrc/include/vcpkg_Dependencies.h deleted file mode 100644 index d67122e48..000000000 --- a/toolsrc/include/vcpkg_Dependencies.h +++ /dev/null @@ -1,147 +0,0 @@ -#pragma once -#include "PackageSpec.h" -#include "StatusParagraphs.h" -#include "VcpkgPaths.h" -#include "vcpkg_Graphs.h" -#include "vcpkg_Util.h" -#include "vcpkg_optional.h" -#include - -namespace vcpkg::Dependencies -{ - enum class RequestType - { - UNKNOWN, - USER_REQUESTED, - AUTO_SELECTED - }; - - std::string to_output_string(RequestType request_type, const CStringView s); - - struct AnyParagraph - { - std::vector dependencies(const Triplet& triplet) const; - - Optional status_paragraph; - Optional binary_control_file; - Optional source_paragraph; - Optional source_control_file; - }; -} - -namespace vcpkg::Dependencies -{ - enum class InstallPlanType - { - UNKNOWN, - BUILD_AND_INSTALL, - INSTALL, - ALREADY_INSTALLED - }; - - struct InstallPlanAction : Util::MoveOnlyBase - { - static bool compare_by_name(const InstallPlanAction* left, const InstallPlanAction* right); - - InstallPlanAction(); - - InstallPlanAction(const PackageSpec& spec, - const std::unordered_set& features, - const RequestType& request_type); - InstallPlanAction(const PackageSpec& spec, const AnyParagraph& any_paragraph, const RequestType& request_type); - InstallPlanAction(const PackageSpec& spec, - const SourceControlFile& any_paragraph, - const std::unordered_set& features, - const RequestType& request_type); - - std::string displayname() const; - - PackageSpec spec; - AnyParagraph any_paragraph; - InstallPlanType plan_type; - RequestType request_type; - std::unordered_set feature_list; - }; - - enum class RemovePlanType - { - UNKNOWN, - NOT_INSTALLED, - REMOVE - }; - - struct RemovePlanAction : Util::MoveOnlyBase - { - static bool compare_by_name(const RemovePlanAction* left, const RemovePlanAction* right); - - RemovePlanAction(); - RemovePlanAction(const PackageSpec& spec, const RemovePlanType& plan_type, const RequestType& request_type); - - PackageSpec spec; - RemovePlanType plan_type; - RequestType request_type; - }; - - struct AnyAction - { - AnyAction(InstallPlanAction&& iplan) : install_plan(std::move(iplan)) {} - AnyAction(RemovePlanAction&& rplan) : remove_plan(std::move(rplan)) {} - - Optional install_plan; - Optional remove_plan; - - const PackageSpec& spec() const; - }; - - enum class ExportPlanType - { - UNKNOWN, - PORT_AVAILABLE_BUT_NOT_BUILT, - ALREADY_BUILT - }; - - struct ExportPlanAction : Util::MoveOnlyBase - { - static bool compare_by_name(const ExportPlanAction* left, const ExportPlanAction* right); - - ExportPlanAction(); - ExportPlanAction(const PackageSpec& spec, const AnyParagraph& any_paragraph, const RequestType& request_type); - - PackageSpec spec; - AnyParagraph any_paragraph; - ExportPlanType plan_type; - RequestType request_type; - }; - - __interface PortFileProvider { virtual const SourceControlFile& get_control_file(const std::string& spec) const; }; - - struct MapPortFile : Util::ResourceBase, PortFileProvider - { - const std::unordered_map& ports; - explicit MapPortFile(const std::unordered_map& map); - const SourceControlFile& get_control_file(const std::string& spec) const override; - }; - - struct PathsPortFile : Util::ResourceBase, PortFileProvider - { - const VcpkgPaths& ports; - mutable std::unordered_map cache; - explicit PathsPortFile(const VcpkgPaths& paths); - const SourceControlFile& get_control_file(const std::string& spec) const override; - }; - - std::vector create_install_plan(const PortFileProvider& port_file_provider, - const std::vector& specs, - const StatusParagraphs& status_db); - - std::vector create_remove_plan(const std::vector& specs, - const StatusParagraphs& status_db); - - std::vector create_export_plan(const VcpkgPaths& paths, - const std::vector& specs, - const StatusParagraphs& status_db); - - std::vector create_feature_install_plan(const std::unordered_map& map, - const std::vector& specs, - const StatusParagraphs& status_db); -} diff --git a/toolsrc/include/vcpkg_Enums.h b/toolsrc/include/vcpkg_Enums.h deleted file mode 100644 index c75feaa1f..000000000 --- a/toolsrc/include/vcpkg_Enums.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once -#include "LineInfo.h" -#include - -namespace vcpkg::Enums -{ - std::string nullvalue_to_string(const CStringView enum_name); - - [[noreturn]] void nullvalue_used(const LineInfo& line_info, const CStringView enum_name); -} diff --git a/toolsrc/include/vcpkg_Files.h b/toolsrc/include/vcpkg_Files.h deleted file mode 100644 index 855e8ea45..000000000 --- a/toolsrc/include/vcpkg_Files.h +++ /dev/null @@ -1,43 +0,0 @@ -#pragma once - -#include "filesystem_fs.h" -#include "vcpkg_expected.h" - -namespace vcpkg::Files -{ - __interface Filesystem - { - virtual Expected read_contents(const fs::path& file_path) const = 0; - 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; - virtual std::vector get_files_non_recursive(const fs::path& dir) const = 0; - - virtual void write_lines(const fs::path& file_path, const std::vector& lines) = 0; - virtual void write_contents(const fs::path& file_path, const std::string& data) = 0; - virtual void rename(const fs::path& oldpath, const fs::path& newpath) = 0; - virtual bool remove(const fs::path& path) = 0; - virtual bool remove(const fs::path& path, std::error_code& ec) = 0; - virtual std::uintmax_t remove_all(const fs::path& path, std::error_code& ec) = 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 bool create_directories(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 bool copy_file( - const fs::path& oldpath, const fs::path& newpath, fs::copy_options opts, std::error_code& ec) = 0; - virtual fs::file_status status(const fs::path& path, std::error_code& ec) const = 0; - }; - - Filesystem& get_real_filesystem(); - - static const char* FILESYSTEM_INVALID_CHARACTERS = R"(\/:*?"<>|)"; - - bool has_invalid_chars_for_filesystem(const std::string& s); - - void print_paths(const std::vector& paths); - - std::vector find_from_PATH(const std::wstring& name); -} diff --git a/toolsrc/include/vcpkg_GlobalState.h b/toolsrc/include/vcpkg_GlobalState.h deleted file mode 100644 index 6522a25bf..000000000 --- a/toolsrc/include/vcpkg_GlobalState.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include - -#include "vcpkg_Chrono.h" -#include "vcpkg_Util.h" - -namespace vcpkg -{ - struct GlobalState - { - static Util::LockGuarded timer; - static std::atomic debugging; - static std::atomic feature_packages; - - static std::atomic g_init_console_cp; - static std::atomic g_init_console_output_cp; - }; -} \ No newline at end of file diff --git a/toolsrc/include/vcpkg_Graphs.h b/toolsrc/include/vcpkg_Graphs.h deleted file mode 100644 index 13c0a7136..000000000 --- a/toolsrc/include/vcpkg_Graphs.h +++ /dev/null @@ -1,159 +0,0 @@ -#pragma once - -#include -#include - -namespace vcpkg::Graphs -{ - enum class ExplorationStatus - { - // We have not visited this vertex - NOT_EXPLORED, - - // We have visited this vertex but haven't visited all vertices in its subtree - PARTIALLY_EXPLORED, - - // We have visited this vertex and all vertices in its subtree - FULLY_EXPLORED - }; - - template - __interface AdjacencyProvider - { - std::vector adjacency_list(const U& vertex) const; - - U load_vertex_data(const V& vertex) const; - }; - - template - static void topological_sort_internal(const V& vertex, - const AdjacencyProvider& f, - std::unordered_map& exploration_status, - std::vector& sorted) - { - ExplorationStatus& status = exploration_status[vertex]; - switch (status) - { - case ExplorationStatus::FULLY_EXPLORED: return; - case ExplorationStatus::PARTIALLY_EXPLORED: Checks::exit_with_message(VCPKG_LINE_INFO, "cycle in graph"); - case ExplorationStatus::NOT_EXPLORED: - { - status = ExplorationStatus::PARTIALLY_EXPLORED; - U vertex_data = f.load_vertex_data(vertex); - for (const V& neighbour : f.adjacency_list(vertex_data)) - topological_sort_internal(neighbour, f, exploration_status, sorted); - - sorted.push_back(std::move(vertex_data)); - status = ExplorationStatus::FULLY_EXPLORED; - return; - } - default: Checks::unreachable(VCPKG_LINE_INFO); - } - } - - template - std::vector topological_sort(const std::vector& starting_vertices, const AdjacencyProvider& f) - { - std::vector sorted; - std::unordered_map exploration_status; - - for (auto& vertex : starting_vertices) - { - topological_sort_internal(vertex, f, exploration_status, sorted); - } - - return sorted; - } - - template - struct GraphAdjacencyProvider final : AdjacencyProvider - { - const std::unordered_map>& vertices; - - GraphAdjacencyProvider(const std::unordered_map>& vertices) : vertices(vertices) {} - - std::vector adjacency_list(const V& vertex) const override - { - const std::unordered_set& as_set = this->vertices.at(vertex); - return std::vector(as_set.cbegin(), as_set.cend()); // TODO: Avoid redundant copy - } - - V load_vertex_data(const V& vertex) const override { return vertex; } - }; - - template - struct Graph - { - public: - void add_vertex(V v) { this->vertices[v]; } - - // TODO: Change with iterators - void add_vertices(const std::vector& vs) - { - for (const V& v : vs) - { - this->vertices[v]; - } - } - - void add_edge(V u, V v) - { - this->vertices[v]; - this->vertices[u].insert(v); - } - - std::vector topological_sort() const - { - GraphAdjacencyProvider adjacency_provider{this->vertices}; - std::unordered_map indegrees = count_indegrees(); - - std::vector sorted; - sorted.reserve(indegrees.size()); - - std::unordered_map exploration_status; - exploration_status.reserve(indegrees.size()); - - for (auto& pair : indegrees) - { - if (pair.second == 0) // Starting from vertices with indegree == 0. Not required. - { - V vertex = pair.first; - topological_sort_internal(vertex, adjacency_provider, exploration_status, sorted); - } - } - - return sorted; - } - - std::unordered_map count_indegrees() const - { - std::unordered_map indegrees; - - for (auto& pair : this->vertices) - { - indegrees[pair.first]; - for (V neighbour : pair.second) - { - ++indegrees[neighbour]; - } - } - - return indegrees; - } - - const std::unordered_map>& adjacency_list() const { return this->vertices; } - std::vector vertex_list() const - { - // why no &? it returns 0 - std::vector vertex_list; - for (const auto& vertex : this->vertices) - { - vertex_list.emplace_back(vertex.first); - } - return vertex_list; - } - - private: - std::unordered_map> vertices; - }; -} diff --git a/toolsrc/include/vcpkg_Input.h b/toolsrc/include/vcpkg_Input.h deleted file mode 100644 index fa568207a..000000000 --- a/toolsrc/include/vcpkg_Input.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once -#include "PackageSpec.h" - -namespace vcpkg::Input -{ - PackageSpec check_and_get_package_spec(const std::string& package_spec_as_string, - const Triplet& default_triplet, - CStringView example_text); - FullPackageSpec check_and_get_full_package_spec(const std::string& full_package_spec_as_string, - const Triplet& default_triplet, - CStringView example_text); - - void check_triplet(const Triplet& t, const VcpkgPaths& paths); -} diff --git a/toolsrc/include/vcpkg_Maps.h b/toolsrc/include/vcpkg_Maps.h deleted file mode 100644 index aadd81c2b..000000000 --- a/toolsrc/include/vcpkg_Maps.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#include -#include -#include - -namespace vcpkg::Maps -{ - template - std::vector extract_keys(const std::unordered_map& input_map) - { - std::vector key_set; - for (auto const& element : input_map) - { - key_set.push_back(element.first); - } - return key_set; - } - - template - std::vector extract_keys(const std::map& input_map) - { - std::vector key_set; - for (auto const& element : input_map) - { - key_set.push_back(element.first); - } - return key_set; - } -} diff --git a/toolsrc/include/vcpkg_Parse.h b/toolsrc/include/vcpkg_Parse.h deleted file mode 100644 index 2dda033b3..000000000 --- a/toolsrc/include/vcpkg_Parse.h +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once - -#include -#include - -#include "vcpkg_expected.h" -#include "vcpkg_optional.h" - -namespace vcpkg::Parse -{ - struct ParseControlErrorInfo - { - std::string name; - std::vector missing_fields; - std::vector extra_fields; - std::error_code error; - }; - - template - using ParseExpected = ExpectedT, std::unique_ptr>; - - using RawParagraph = std::unordered_map; - - struct ParagraphParser - { - ParagraphParser(RawParagraph&& fields) : fields(std::move(fields)) {} - - void required_field(const std::string& fieldname, std::string& out); - std::string optional_field(const std::string& fieldname) const; - std::unique_ptr error_info(const std::string& name) const; - - private: - RawParagraph&& fields; - std::vector missing_fields; - }; - - std::vector parse_comma_list(const std::string& str); -} diff --git a/toolsrc/include/vcpkg_Strings.h b/toolsrc/include/vcpkg_Strings.h deleted file mode 100644 index c44ce2b99..000000000 --- a/toolsrc/include/vcpkg_Strings.h +++ /dev/null @@ -1,113 +0,0 @@ -#pragma once - -#include "CStringView.h" -#include - -namespace vcpkg::Strings::details -{ - template - auto to_printf_arg(const T& t) -> decltype(t.to_string()) - { - return t.to_string(); - } - - inline const char* to_printf_arg(const std::string& s) { return s.c_str(); } - - inline const char* to_printf_arg(const char* s) { return s; } - - inline int to_printf_arg(const int s) { return s; } - - inline long long to_printf_arg(const long long s) { return s; } - - inline unsigned long to_printf_arg(const unsigned long s) { return s; } - - inline size_t to_printf_arg(const size_t s) { return s; } - - inline double to_printf_arg(const double s) { return s; } - - std::string format_internal(const char* fmtstr, ...); - - inline const wchar_t* to_wprintf_arg(const std::wstring& s) { return s.c_str(); } - - inline const wchar_t* to_wprintf_arg(const wchar_t* s) { return s; } - - std::wstring wformat_internal(const wchar_t* fmtstr, ...); -} - -namespace vcpkg::Strings -{ - static constexpr const char* EMPTY = ""; - static constexpr const wchar_t* WEMPTY = L""; - - template - std::string format(const char* fmtstr, const Args&... args) - { - using vcpkg::Strings::details::to_printf_arg; - return details::format_internal(fmtstr, to_printf_arg(to_printf_arg(args))...); - } - - template - std::wstring wformat(const wchar_t* fmtstr, const Args&... args) - { - using vcpkg::Strings::details::to_wprintf_arg; - return details::wformat_internal(fmtstr, to_wprintf_arg(to_wprintf_arg(args))...); - } - - std::wstring to_utf16(const CStringView s); - - std::string to_utf8(const CWStringView w); - - std::string::const_iterator case_insensitive_ascii_find(const std::string& s, const std::string& pattern); - - bool case_insensitive_ascii_contains(const std::string& s, const std::string& pattern); - - int case_insensitive_ascii_compare(const CStringView left, const CStringView right); - - std::string ascii_to_lowercase(const std::string& input); - - bool case_insensitive_ascii_starts_with(const std::string& s, const std::string& pattern); - - template - std::basic_string join(const CharType* delimiter, const Container& v, Transformer transformer) - { - const auto begin = v.begin(); - const auto end = v.end(); - - if (begin == end) - { - return std::basic_string(); - } - - std::basic_string output; - output.append(transformer(*begin)); - for (auto it = std::next(begin); it != end; ++it) - { - output.append(delimiter); - output.append(transformer(*it)); - } - - return output; - } - template - std::basic_string join(const CharType* delimiter, const Container& v) - { - using Element = decltype(*v.begin()); - return join(delimiter, v, [](const Element& x) -> const Element& { return x; }); - } - - void trim(std::string* s); - - std::string trimmed(const std::string& s); - - void trim_all_and_remove_whitespace_strings(std::vector* strings); - - std::vector split(const std::string& s, const std::string& delimiter); - - template - std::string serialize(const T& t) - { - std::string ret; - serialize(t, ret); - return ret; - } -} diff --git a/toolsrc/include/vcpkg_System.h b/toolsrc/include/vcpkg_System.h deleted file mode 100644 index 65f80ae6d..000000000 --- a/toolsrc/include/vcpkg_System.h +++ /dev/null @@ -1,107 +0,0 @@ -#pragma once - -#include "filesystem_fs.h" -#include "vcpkg_Strings.h" -#include "vcpkg_optional.h" -#include - -namespace vcpkg::System -{ - tm get_current_date_time(); - - fs::path get_exe_path_of_current_process(); - - struct ExitCodeAndOutput - { - int exit_code; - std::string output; - }; - - int cmd_execute_clean(const CWStringView cmd_line); - - int cmd_execute(const CWStringView cmd_line); - - ExitCodeAndOutput cmd_execute_and_capture_output(const CWStringView cmd_line); - - std::wstring create_powershell_script_cmd(const fs::path& script_path, const CWStringView args = Strings::WEMPTY); - - enum class Color - { - success = 10, - error = 12, - warning = 14, - }; - - void println(); - void print(const CStringView message); - void println(const CStringView message); - void print(const Color c, const CStringView message); - void println(const Color c, const CStringView message); - - template - void print(const char* messageTemplate, const Arg1& messageArg1, const Args&... messageArgs) - { - return System::print(Strings::format(messageTemplate, messageArg1, messageArgs...)); - } - - template - void print(const Color c, const char* messageTemplate, const Arg1& messageArg1, const Args&... messageArgs) - { - return System::print(c, Strings::format(messageTemplate, messageArg1, messageArgs...)); - } - - template - void println(const char* messageTemplate, const Arg1& messageArg1, const Args&... messageArgs) - { - return System::println(Strings::format(messageTemplate, messageArg1, messageArgs...)); - } - - template - void println(const Color c, const char* messageTemplate, const Arg1& messageArg1, const Args&... messageArgs) - { - return System::println(c, Strings::format(messageTemplate, messageArg1, messageArgs...)); - } - - Optional get_environment_variable(const CWStringView varname) noexcept; - - Optional get_registry_string(HKEY base, const CWStringView subkey, const CWStringView valuename); - - enum class CPUArchitecture - { - X86, - X64, - ARM, - ARM64, - }; - - Optional to_cpu_architecture(CStringView arch); - - CPUArchitecture get_host_processor(); - - std::vector get_supported_host_architectures(); - - const fs::path& get_program_files_32_bit(); - - const fs::path& get_program_files_platform_bitness(); -} - -namespace vcpkg::Debug -{ - void println(const CStringView message); - void println(const System::Color c, const CStringView message); - - template - void println(const char* messageTemplate, const Arg1& messageArg1, const Args&... messageArgs) - { - return Debug::println(Strings::format(messageTemplate, messageArg1, messageArgs...)); - } - - template - void println(const System::Color c, - const char* messageTemplate, - const Arg1& messageArg1, - const Args&... messageArgs) - { - return Debug::println(c, Strings::format(messageTemplate, messageArg1, messageArgs...)); - } -} diff --git a/toolsrc/include/vcpkg_Util.h b/toolsrc/include/vcpkg_Util.h deleted file mode 100644 index facb7dd26..000000000 --- a/toolsrc/include/vcpkg_Util.h +++ /dev/null @@ -1,144 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -namespace vcpkg::Util -{ - template - using FmapOut = decltype(std::declval()(*begin(std::declval()))); - - template> - std::vector fmap(Cont&& xs, Func&& f) - { - std::vector ret; - ret.reserve(xs.size()); - - for (auto&& x : xs) - ret.push_back(f(x)); - - return ret; - } - - template - using FmapFlattenOut = std::decay_t()(*begin(std::declval()))))>; - - template> - std::vector fmap_flatten(Cont&& xs, Func&& f) - { - std::vector ret; - - for (auto&& x : xs) - for (auto&& y : f(x)) - ret.push_back(std::move(y)); - - return ret; - } - - template - void stable_keep_if(Container& cont, Pred pred) - { - cont.erase(std::stable_partition(cont.begin(), cont.end(), pred), cont.end()); - } - - template - void unstable_keep_if(Container& cont, Pred pred) - { - cont.erase(std::partition(cont.begin(), cont.end(), pred), cont.end()); - } - - template - void erase_remove_if(Container& cont, Pred pred) - { - cont.erase(std::remove_if(cont.begin(), cont.end(), pred), cont.end()); - } - - template - auto find(const Container& cont, V&& v) - { - return std::find(cont.cbegin(), cont.cend(), v); - } - - template - auto find_if(const Container& cont, Pred pred) - { - return std::find_if(cont.cbegin(), cont.cend(), pred); - } - - template - using ElementT = std::remove_reference_t()))>; - - template> - std::vector element_pointers(Container&& cont) - { - return fmap(cont, [](auto&& x) { return &x; }); - } - - template - auto find_if_not(const Container& cont, Pred pred) - { - return std::find_if_not(cont.cbegin(), cont.cend(), pred); - } - - template - void group_by(const Container& cont, std::map>* output, Func f) - { - for (const V& element : cont) - { - K key = f(element); - (*output)[key].push_back(&element); - } - } - - struct MoveOnlyBase - { - MoveOnlyBase() = default; - MoveOnlyBase(const MoveOnlyBase&) = delete; - MoveOnlyBase(MoveOnlyBase&&) = default; - - MoveOnlyBase& operator=(const MoveOnlyBase&) = delete; - MoveOnlyBase& operator=(MoveOnlyBase&&) = default; - }; - - struct ResourceBase - { - ResourceBase() = default; - ResourceBase(const ResourceBase&) = delete; - ResourceBase(ResourceBase&&) = delete; - - ResourceBase& operator=(const ResourceBase&) = delete; - ResourceBase& operator=(ResourceBase&&) = delete; - }; - - template - struct LockGuardPtr; - - template - struct LockGuarded - { - friend struct LockGuardPtr; - - LockGuardPtr lock() { return *this; } - - private: - std::mutex m_mutex; - T m_t; - }; - - template - struct LockGuardPtr - { - T& operator*() { return m_ptr; } - T* operator->() { return &m_ptr; } - - T* get() { return &m_ptr; } - - LockGuardPtr(LockGuarded& sync) : m_lock(sync.m_mutex), m_ptr(sync.m_t) {} - - private: - std::unique_lock m_lock; - T& m_ptr; - }; -} \ No newline at end of file diff --git a/toolsrc/include/vcpkg_expected.h b/toolsrc/include/vcpkg_expected.h deleted file mode 100644 index 9637ec087..000000000 --- a/toolsrc/include/vcpkg_expected.h +++ /dev/null @@ -1,114 +0,0 @@ -#pragma once - -#include "vcpkg_Checks.h" -#include - -namespace vcpkg -{ - template - struct ErrorHolder - { - ErrorHolder() : m_is_error(false) {} - template - ErrorHolder(U&& err) : m_is_error(true), m_err(std::forward(err)) - { - } - - constexpr bool has_error() const { return m_is_error; } - - const Err& error() const { return m_err; } - Err& error() { return m_err; } - - CStringView to_string() const { return "value was error"; } - - private: - bool m_is_error; - Err m_err; - }; - - template<> - struct ErrorHolder - { - ErrorHolder() = default; - ErrorHolder(const std::error_code& err) : m_err(err) {} - - constexpr bool has_error() const { return bool(m_err); } - - const std::error_code& error() const { return m_err; } - std::error_code& error() { return m_err; } - - CStringView to_string() const { return "value was error"; } - - private: - std::error_code m_err; - }; - - template - class ExpectedT - { - public: - constexpr ExpectedT() = default; - - // Constructors are intentionally implicit - - ExpectedT(const S& s) : m_s(s) {} - ExpectedT(S&& s) : m_s(std::move(s)) {} - - ExpectedT(const T& t) : m_t(t) {} - ExpectedT(T&& t) : m_t(std::move(t)) {} - - ExpectedT(const ExpectedT&) = default; - ExpectedT(ExpectedT&&) = default; - ExpectedT& operator=(const ExpectedT&) = default; - ExpectedT& operator=(ExpectedT&&) = default; - - explicit constexpr operator bool() const noexcept { return !m_s.has_error(); } - constexpr bool has_value() const noexcept { return !m_s.has_error(); } - - T&& value_or_exit(const LineInfo& line_info) && - { - exit_if_error(line_info); - return std::move(this->m_t); - } - - const T& value_or_exit(const LineInfo& line_info) const & - { - exit_if_error(line_info); - return this->m_t; - } - - const S& error() const & { return this->m_s.error(); } - - S&& error() && { return std::move(this->m_s.error()); } - - const T* get() const - { - if (!this->has_value()) - { - return nullptr; - } - return &this->m_t; - } - - T* get() - { - if (!this->has_value()) - { - return nullptr; - } - return &this->m_t; - } - - private: - void exit_if_error(const LineInfo& line_info) const - { - Checks::check_exit(line_info, !m_s.has_error(), m_s.to_string()); - } - - ErrorHolder m_s; - T m_t; - }; - - template - using Expected = ExpectedT; -} diff --git a/toolsrc/include/vcpkg_optional.h b/toolsrc/include/vcpkg_optional.h deleted file mode 100644 index 31a2d3e88..000000000 --- a/toolsrc/include/vcpkg_optional.h +++ /dev/null @@ -1,98 +0,0 @@ -#pragma once -#include "vcpkg_Checks.h" - -namespace vcpkg -{ - struct NullOpt - { - explicit constexpr NullOpt(int) {} - }; - - const static constexpr NullOpt nullopt{0}; - - template - class Optional - { - public: - constexpr Optional() : m_is_present(false), m_t() {} - - // Constructors are intentionally implicit - constexpr Optional(NullOpt) : m_is_present(false), m_t() {} - - Optional(const T& t) : m_is_present(true), m_t(t) {} - - Optional(T&& t) : m_is_present(true), m_t(std::move(t)) {} - - T&& value_or_exit(const LineInfo& line_info) && - { - this->exit_if_null(line_info); - return std::move(this->m_t); - } - - const T& value_or_exit(const LineInfo& line_info) const & - { - this->exit_if_null(line_info); - return this->m_t; - } - - constexpr explicit operator bool() const { return this->m_is_present; } - - constexpr bool has_value() const { return m_is_present; } - - template - T value_or(U&& default_value) const & - { - return bool(*this) ? this->m_t : static_cast(std::forward(default_value)); - } - - template - T value_or(U&& default_value) && - { - return bool(*this) ? std::move(this->m_t) : static_cast(std::forward(default_value)); - } - - const T* get() const { return bool(*this) ? &this->m_t : nullptr; } - - T* get() { return bool(*this) ? &this->m_t : nullptr; } - - private: - void exit_if_null(const LineInfo& line_info) const - { - Checks::check_exit(line_info, this->m_is_present, "Value was null"); - } - - bool m_is_present; - T m_t; - }; - - template - Optional> make_optional(U&& u) - { - return Optional>(std::forward(u)); - } - - template - bool operator==(const Optional& o, const T& t) - { - if (auto p = o.get()) return *p == t; - return false; - } - template - bool operator==(const T& t, const Optional& o) - { - if (auto p = o.get()) return t == *p; - return false; - } - template - bool operator!=(const Optional& o, const T& t) - { - if (auto p = o.get()) return *p != t; - return true; - } - template - bool operator!=(const T& t, const Optional& o) - { - if (auto p = o.get()) return t != *p; - return true; - } -} diff --git a/toolsrc/include/vcpkglib.h b/toolsrc/include/vcpkglib.h deleted file mode 100644 index 0bb75f9b5..000000000 --- a/toolsrc/include/vcpkglib.h +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once - -#include "SortedVector.h" -#include "StatusParagraphs.h" -#include "VcpkgPaths.h" - -namespace vcpkg -{ - StatusParagraphs database_load_check(const VcpkgPaths& paths); - - void write_update(const VcpkgPaths& paths, const StatusParagraph& p); - - struct StatusParagraphAndAssociatedFiles - { - StatusParagraph pgh; - SortedVector files; - }; - - std::vector get_installed_ports(const StatusParagraphs& status_db); - std::vector get_installed_files(const VcpkgPaths& paths, - const StatusParagraphs& status_db); - - struct CMakeVariable - { - CMakeVariable(const CWStringView varname, const wchar_t* varvalue); - CMakeVariable(const CWStringView varname, const std::string& varvalue); - CMakeVariable(const CWStringView varname, const std::wstring& varvalue); - CMakeVariable(const CWStringView varname, const fs::path& path); - - std::wstring s; - }; - - std::wstring make_cmake_cmd(const fs::path& cmake_exe, - const fs::path& cmake_script, - const std::vector& pass_variables); - - std::string shorten_text(const std::string& desc, size_t length); -} // namespace vcpkg diff --git a/toolsrc/src/BinaryParagraph.cpp b/toolsrc/src/BinaryParagraph.cpp deleted file mode 100644 index 1504912ab..000000000 --- a/toolsrc/src/BinaryParagraph.cpp +++ /dev/null @@ -1,123 +0,0 @@ -#include "pch.h" - -#include "BinaryParagraph.h" -#include "vcpkg_Checks.h" -#include "vcpkg_Parse.h" - -namespace vcpkg -{ - namespace Fields - { - static const std::string PACKAGE = "Package"; - static const std::string VERSION = "Version"; - static const std::string ARCHITECTURE = "Architecture"; - static const std::string MULTI_ARCH = "Multi-Arch"; - } - - namespace Fields - { - static const std::string FEATURE = "Feature"; - static const std::string DESCRIPTION = "Description"; - static const std::string MAINTAINER = "Maintainer"; - static const std::string DEPENDS = "Depends"; - static const std::string DEFAULTFEATURES = "Default-Features"; - } - - BinaryParagraph::BinaryParagraph() = default; - - BinaryParagraph::BinaryParagraph(std::unordered_map fields) - { - using namespace vcpkg::Parse; - - ParagraphParser parser(std::move(fields)); - - { - std::string name; - parser.required_field(Fields::PACKAGE, name); - std::string architecture; - parser.required_field(Fields::ARCHITECTURE, architecture); - this->spec = PackageSpec::from_name_and_triplet(name, Triplet::from_canonical_name(architecture)) - .value_or_exit(VCPKG_LINE_INFO); - } - - // one or the other - this->version = parser.optional_field(Fields::VERSION); - this->feature = parser.optional_field(Fields::FEATURE); - - this->description = parser.optional_field(Fields::DESCRIPTION); - this->maintainer = parser.optional_field(Fields::MAINTAINER); - - std::string multi_arch; - parser.required_field(Fields::MULTI_ARCH, multi_arch); - - this->depends = parse_comma_list(parser.optional_field(Fields::DEPENDS)); - if (this->feature.empty()) - { - this->default_features = parse_comma_list(parser.optional_field(Fields::DEFAULTFEATURES)); - } - - if (const auto err = parser.error_info(this->spec.to_string())) - { - System::println( - System::Color::error, "Error: while parsing the Binary Paragraph for %s", this->spec.to_string()); - print_error_message(err); - Checks::exit_fail(VCPKG_LINE_INFO); - } - - // prefer failing above when possible because it gives better information - Checks::check_exit(VCPKG_LINE_INFO, multi_arch == "same", "Multi-Arch must be 'same' but was %s", multi_arch); - } - - BinaryParagraph::BinaryParagraph(const SourceParagraph& spgh, const Triplet& triplet) - { - this->spec = PackageSpec::from_name_and_triplet(spgh.name, triplet).value_or_exit(VCPKG_LINE_INFO); - this->version = spgh.version; - this->description = spgh.description; - this->maintainer = spgh.maintainer; - this->depends = filter_dependencies(spgh.depends, triplet); - } - - BinaryParagraph::BinaryParagraph(const SourceParagraph& spgh, const FeatureParagraph& fpgh, const Triplet& triplet) - { - this->spec = PackageSpec::from_name_and_triplet(spgh.name, triplet).value_or_exit(VCPKG_LINE_INFO); - this->version = Strings::EMPTY; - this->feature = fpgh.name; - this->description = fpgh.description; - this->maintainer = Strings::EMPTY; - this->depends = filter_dependencies(fpgh.depends, triplet); - } - - std::string BinaryParagraph::displayname() const - { - const auto f = this->feature.empty() ? "core" : this->feature; - return Strings::format("%s[%s]:%s", this->spec.name(), f, this->spec.triplet()); - } - - std::string BinaryParagraph::dir() const { return this->spec.dir(); } - - std::string BinaryParagraph::fullstem() const - { - return Strings::format("%s_%s_%s", this->spec.name(), this->version, this->spec.triplet()); - } - - void serialize(const BinaryParagraph& pgh, std::string& out_str) - { - out_str.append("Package: ").append(pgh.spec.name()).push_back('\n'); - if (!pgh.version.empty()) - out_str.append("Version: ").append(pgh.version).push_back('\n'); - else if (!pgh.feature.empty()) - out_str.append("Feature: ").append(pgh.feature).push_back('\n'); - if (!pgh.depends.empty()) - { - out_str.append("Depends: "); - out_str.append(Strings::join(", ", pgh.depends)); - out_str.push_back('\n'); - } - - out_str.append("Architecture: ").append(pgh.spec.triplet().to_string()).push_back('\n'); - out_str.append("Multi-Arch: same\n"); - - 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/LineInfo.cpp b/toolsrc/src/LineInfo.cpp deleted file mode 100644 index d1bf9a4b1..000000000 --- a/toolsrc/src/LineInfo.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include "pch.h" - -#include "LineInfo.h" -#include "vcpkg_Strings.h" - -namespace vcpkg -{ - std::string LineInfo::to_string() const { return Strings::format("%s(%d)", this->file_name, this->line_number); } -} diff --git a/toolsrc/src/MachineType.cpp b/toolsrc/src/MachineType.cpp deleted file mode 100644 index af6378c88..000000000 --- a/toolsrc/src/MachineType.cpp +++ /dev/null @@ -1,41 +0,0 @@ -#include "pch.h" - -#include "MachineType.h" -#include "vcpkg_Checks.h" - -namespace vcpkg -{ - MachineType to_machine_type(const uint16_t value) - { - const MachineType t = static_cast(value); - switch (t) - { - case MachineType::UNKNOWN: - case MachineType::AM33: - case MachineType::AMD64: - case MachineType::ARM: - case MachineType::ARM64: - case MachineType::ARMNT: - case MachineType::EBC: - case MachineType::I386: - case MachineType::IA64: - case MachineType::M32R: - case MachineType::MIPS16: - case MachineType::MIPSFPU: - case MachineType::MIPSFPU16: - case MachineType::POWERPC: - case MachineType::POWERPCFP: - case MachineType::R4000: - case MachineType::RISCV32: - case MachineType::RISCV64: - case MachineType::RISCV128: - case MachineType::SH3: - case MachineType::SH3DSP: - case MachineType::SH4: - case MachineType::SH5: - case MachineType::THUMB: - case MachineType::WCEMIPSV2: return t; - default: Checks::exit_with_message(VCPKG_LINE_INFO, "Unknown machine type code 0x%x", value); - } - } -} diff --git a/toolsrc/src/PackageSpec.cpp b/toolsrc/src/PackageSpec.cpp deleted file mode 100644 index 890de8899..000000000 --- a/toolsrc/src/PackageSpec.cpp +++ /dev/null @@ -1,175 +0,0 @@ -#include "pch.h" - -#include "PackageSpec.h" -#include "vcpkg_Parse.h" -#include "vcpkg_Util.h" - -using vcpkg::Parse::parse_comma_list; - -namespace vcpkg -{ - static bool is_valid_package_spec_char(char c) - { - return (c == '-') || isdigit(c) || (isalpha(c) && islower(c)) || (c == '[') || (c == ']'); - } - - std::string FeatureSpec::to_string() const - { - if (feature().empty()) return spec().to_string(); - return Strings::format("%s[%s]:%s", name(), feature(), triplet()); - } - - std::vector FeatureSpec::from_strings_and_triplet(const std::vector& depends, - const Triplet& triplet) - { - std::vector f_specs; - for (auto&& depend : depends) - { - auto maybe_spec = ParsedSpecifier::from_string(depend); - if (auto spec = maybe_spec.get()) - { - Checks::check_exit(VCPKG_LINE_INFO, - spec->triplet.empty(), - "error: triplets cannot currently be specified in this context: %s", - depend); - PackageSpec pspec = - PackageSpec::from_name_and_triplet(spec->name, triplet).value_or_exit(VCPKG_LINE_INFO); - - for (auto&& feature : spec->features) - f_specs.push_back(FeatureSpec{pspec, feature}); - - if (spec->features.empty()) f_specs.push_back(FeatureSpec{pspec, Strings::EMPTY}); - } - else - { - Checks::exit_with_message(VCPKG_LINE_INFO, - "error while parsing feature list: %s: %s", - vcpkg::to_string(maybe_spec.error()), - depend); - } - } - return f_specs; - } - - std::vector FullPackageSpec::to_feature_specs(const std::vector& specs) - { - std::vector ret; - for (auto&& spec : specs) - { - ret.emplace_back(spec.package_spec, Strings::EMPTY); - for (auto&& feature : spec.features) - ret.emplace_back(spec.package_spec, feature); - } - return ret; - } - - ExpectedT FullPackageSpec::from_string(const std::string& spec_as_string, - const Triplet& default_triplet) - { - auto res = ParsedSpecifier::from_string(spec_as_string); - if (auto p = res.get()) - { - FullPackageSpec fspec; - Triplet t = p->triplet.empty() ? default_triplet : Triplet::from_canonical_name(p->triplet); - fspec.package_spec = PackageSpec::from_name_and_triplet(p->name, t).value_or_exit(VCPKG_LINE_INFO); - fspec.features = std::move(p->features); - return fspec; - } - return res.error(); - } - - ExpectedT PackageSpec::from_name_and_triplet(const std::string& name, - const Triplet& triplet) - { - if (Util::find_if_not(name, is_valid_package_spec_char) != name.end()) - { - return PackageSpecParseResult::INVALID_CHARACTERS; - } - - PackageSpec p; - p.m_name = name; - p.m_triplet = triplet; - return p; - } - - const std::string& PackageSpec::name() const { return this->m_name; } - - const Triplet& PackageSpec::triplet() const { return this->m_triplet; } - - std::string PackageSpec::dir() const { return Strings::format("%s_%s", this->m_name, this->m_triplet); } - - std::string PackageSpec::to_string() const { return Strings::format("%s:%s", this->name(), this->triplet()); } - - bool operator==(const PackageSpec& left, const PackageSpec& right) - { - return left.name() == right.name() && left.triplet() == right.triplet(); - } - - bool operator!=(const PackageSpec& left, const PackageSpec& right) { return !(left == right); } - - ExpectedT ParsedSpecifier::from_string(const std::string& input) - { - auto pos = input.find(':'); - auto pos_l_bracket = input.find('['); - auto pos_r_bracket = input.find(']'); - - ParsedSpecifier f; - if (pos == std::string::npos && pos_l_bracket == std::string::npos) - { - f.name = input; - return f; - } - else if (pos == std::string::npos) - { - if (pos_r_bracket == std::string::npos || pos_l_bracket >= pos_r_bracket) - { - return PackageSpecParseResult::INVALID_CHARACTERS; - } - const std::string name = input.substr(0, pos_l_bracket); - f.name = name; - f.features = parse_comma_list(input.substr(pos_l_bracket + 1, pos_r_bracket - pos_l_bracket - 1)); - return f; - } - else if (pos_l_bracket == std::string::npos && pos_r_bracket == std::string::npos) - { - const std::string name = input.substr(0, pos); - f.triplet = input.substr(pos + 1); - f.name = name; - } - else - { - if (pos_r_bracket == std::string::npos || pos_l_bracket >= pos_r_bracket) - { - return PackageSpecParseResult::INVALID_CHARACTERS; - } - const std::string name = input.substr(0, pos_l_bracket); - f.features = parse_comma_list(input.substr(pos_l_bracket + 1, pos_r_bracket - pos_l_bracket - 1)); - f.triplet = input.substr(pos + 1); - f.name = name; - } - - auto pos2 = input.find(':', pos + 1); - if (pos2 != std::string::npos) - { - return PackageSpecParseResult::TOO_MANY_COLONS; - } - return f; - } - - ExpectedT Features::from_string(const std::string& name) - { - auto maybe_spec = ParsedSpecifier::from_string(name); - if (auto spec = maybe_spec.get()) - { - Checks::check_exit( - VCPKG_LINE_INFO, spec->triplet.empty(), "error: triplet not allowed in specifier: %s", name); - - Features f; - f.name = spec->name; - f.features = spec->features; - return f; - } - - return maybe_spec.error(); - } -} diff --git a/toolsrc/src/PackageSpecParseResult.cpp b/toolsrc/src/PackageSpecParseResult.cpp deleted file mode 100644 index 838c788ba..000000000 --- a/toolsrc/src/PackageSpecParseResult.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include "pch.h" - -#include "PackageSpecParseResult.h" -#include "vcpkg_Checks.h" - -namespace vcpkg -{ - CStringView to_string(PackageSpecParseResult ev) noexcept - { - switch (ev) - { - case PackageSpecParseResult::SUCCESS: return "OK"; - case PackageSpecParseResult::TOO_MANY_COLONS: return "Too many colons"; - case PackageSpecParseResult::INVALID_CHARACTERS: - return "Contains invalid characters. Only alphanumeric lowercase ASCII characters and dashes are " - "allowed"; - default: Checks::unreachable(VCPKG_LINE_INFO); - } - } -} diff --git a/toolsrc/src/ParagraphParseResult.cpp b/toolsrc/src/ParagraphParseResult.cpp deleted file mode 100644 index 5c8c1d59d..000000000 --- a/toolsrc/src/ParagraphParseResult.cpp +++ /dev/null @@ -1,34 +0,0 @@ -#include "pch.h" - -#include "ParagraphParseResult.h" -#include "vcpkg_Checks.h" - -namespace vcpkg -{ - const char* ParagraphParseResultCategoryImpl::name() const noexcept { return "ParagraphParseResult"; } - - std::string ParagraphParseResultCategoryImpl::message(int ev) const noexcept - { - switch (static_cast(ev)) - { - case ParagraphParseResult::SUCCESS: return "OK"; - case ParagraphParseResult::EXPECTED_ONE_PARAGRAPH: return "There should be exactly one paragraph"; - default: Checks::unreachable(VCPKG_LINE_INFO); - } - } - - const std::error_category& paragraph_parse_result_category() - { - static ParagraphParseResultCategoryImpl instance; - return instance; - } - - std::error_code make_error_code(ParagraphParseResult e) - { - return std::error_code(static_cast(e), paragraph_parse_result_category()); - } - - ParagraphParseResult to_paragraph_parse_result(int i) { return static_cast(i); } - - ParagraphParseResult to_paragraph_parse_result(std::error_code ec) { return to_paragraph_parse_result(ec.value()); } -} diff --git a/toolsrc/src/Paragraphs.cpp b/toolsrc/src/Paragraphs.cpp deleted file mode 100644 index 6a6f191df..000000000 --- a/toolsrc/src/Paragraphs.cpp +++ /dev/null @@ -1,304 +0,0 @@ -#include "pch.h" - -#include "ParagraphParseResult.h" -#include "Paragraphs.h" -#include "vcpkg_Files.h" -#include "vcpkg_GlobalState.h" -#include "vcpkg_Util.h" - -using namespace vcpkg::Parse; - -namespace vcpkg::Paragraphs -{ - struct Parser - { - Parser(const char* c, const char* e) : cur(c), end(e) {} - - private: - const char* cur; - const char* const end; - - void peek(char& ch) const - { - if (cur == end) - ch = 0; - else - ch = *cur; - } - - void next(char& ch) - { - if (cur == end) - ch = 0; - else - { - ++cur; - peek(ch); - } - } - - void skip_comment(char& ch) - { - while (ch != '\r' && ch != '\n' && ch != '\0') - next(ch); - if (ch == '\r') next(ch); - if (ch == '\n') next(ch); - } - - void skip_spaces(char& ch) - { - while (ch == ' ' || ch == '\t') - next(ch); - } - - static bool is_alphanum(char ch) - { - return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9'); - } - - static bool is_comment(char ch) { return (ch == '#'); } - - static bool is_lineend(char ch) { return ch == '\r' || ch == '\n' || ch == 0; } - - void get_fieldvalue(char& ch, std::string& fieldvalue) - { - fieldvalue.clear(); - - auto beginning_of_line = cur; - do - { - // scan to end of current line (it is part of the field value) - while (!is_lineend(ch)) - next(ch); - - fieldvalue.append(beginning_of_line, cur); - - if (ch == '\r') next(ch); - if (ch == '\n') next(ch); - - if (is_alphanum(ch) || is_comment(ch)) - { - // Line begins a new field. - return; - } - - beginning_of_line = cur; - - // Line may continue the current field with data or terminate the paragraph, - // depending on first nonspace character. - skip_spaces(ch); - - if (is_lineend(ch)) - { - // Line was whitespace or empty. - // This terminates the field and the paragraph. - // We leave the blank line's whitespace consumed, because it doesn't matter. - return; - } - - // First nonspace is not a newline. This continues the current field value. - // We forcibly convert all newlines into single '\n' for ease of text handling later on. - fieldvalue.push_back('\n'); - } while (true); - } - - void get_fieldname(char& ch, std::string& fieldname) - { - auto begin_fieldname = cur; - while (is_alphanum(ch) || ch == '-') - next(ch); - Checks::check_exit(VCPKG_LINE_INFO, ch == ':', "Expected ':'"); - fieldname = std::string(begin_fieldname, cur); - - // skip ': ' - next(ch); - skip_spaces(ch); - } - - void get_paragraph(char& ch, std::unordered_map& fields) - { - fields.clear(); - std::string fieldname; - std::string fieldvalue; - do - { - if (is_comment(ch)) - { - skip_comment(ch); - continue; - } - - get_fieldname(ch, fieldname); - - auto it = fields.find(fieldname); - Checks::check_exit(VCPKG_LINE_INFO, it == fields.end(), "Duplicate field"); - - get_fieldvalue(ch, fieldvalue); - - fields.emplace(fieldname, fieldvalue); - } while (!is_lineend(ch)); - } - - public: - std::vector> get_paragraphs() - { - std::vector> paragraphs; - - char ch; - peek(ch); - - while (ch != 0) - { - if (ch == '\n' || ch == '\r' || ch == ' ' || ch == '\t') - { - next(ch); - continue; - } - - paragraphs.emplace_back(); - get_paragraph(ch, paragraphs.back()); - } - - return paragraphs; - } - }; - - Expected> get_single_paragraph(const Files::Filesystem& fs, - const fs::path& control_path) - { - const Expected contents = fs.read_contents(control_path); - if (auto spgh = contents.get()) - { - return parse_single_paragraph(*spgh); - } - - return contents.error(); - } - - Expected>> get_paragraphs(const Files::Filesystem& fs, - const fs::path& control_path) - { - const Expected contents = fs.read_contents(control_path); - if (auto spgh = contents.get()) - { - return parse_paragraphs(*spgh); - } - - return contents.error(); - } - - Expected> parse_single_paragraph(const std::string& str) - { - const std::vector> p = - Parser(str.c_str(), str.c_str() + str.size()).get_paragraphs(); - - if (p.size() == 1) - { - return p.at(0); - } - - return std::error_code(ParagraphParseResult::EXPECTED_ONE_PARAGRAPH); - } - - Expected>> parse_paragraphs(const std::string& str) - { - return Parser(str.c_str(), str.c_str() + str.size()).get_paragraphs(); - } - - ParseExpected try_load_port(const Files::Filesystem& fs, const fs::path& path) - { - Expected>> pghs = get_paragraphs(fs, path / "CONTROL"); - if (auto vector_pghs = pghs.get()) - { - auto csf = SourceControlFile::parse_control_file(std::move(*vector_pghs)); - if (!GlobalState::feature_packages) - { - if (auto ptr = csf.get()) - { - Checks::check_exit(VCPKG_LINE_INFO, ptr->get() != nullptr); - ptr->get()->core_paragraph->default_features.clear(); - ptr->get()->feature_paragraphs.clear(); - } - } - return csf; - } - auto error_info = std::make_unique(); - error_info->name = path.filename().generic_u8string(); - error_info->error = pghs.error(); - return error_info; - } - - Expected try_load_cached_control_package(const VcpkgPaths& paths, const PackageSpec& spec) - { - Expected>> pghs = - get_paragraphs(paths.get_filesystem(), paths.package_dir(spec) / "CONTROL"); - - if (auto p = pghs.get()) - { - BinaryControlFile bcf; - bcf.core_paragraph = BinaryParagraph(p->front()); - p->erase(p->begin()); - - bcf.features = - Util::fmap(*p, [&](auto&& raw_feature) -> BinaryParagraph { return BinaryParagraph(raw_feature); }); - - return bcf; - } - - return pghs.error(); - } - - LoadResults try_load_all_ports(const Files::Filesystem& fs, const fs::path& ports_dir) - { - LoadResults ret; - for (auto&& path : fs.get_files_non_recursive(ports_dir)) - { - auto maybe_spgh = try_load_port(fs, path); - if (const auto spgh = maybe_spgh.get()) - { - ret.paragraphs.emplace_back(std::move(*spgh)); - } - else - { - ret.errors.emplace_back(std::move(maybe_spgh).error()); - } - } - return ret; - } - - std::vector> load_all_ports(const Files::Filesystem& fs, - const fs::path& ports_dir) - { - auto results = try_load_all_ports(fs, ports_dir); - if (!results.errors.empty()) - { - if (GlobalState::debugging) - { - print_error_message(results.errors); - } - else - { - for (auto&& error : results.errors) - { - System::println( - System::Color::warning, "Warning: an error occurred while parsing '%s'", error->name); - } - System::println(System::Color::warning, - "Use '--debug' to get more information about the parse failures.\n"); - } - } - return std::move(results.paragraphs); - } - - std::map load_all_port_names_and_versions(const Files::Filesystem& fs, - const fs::path& ports_dir) - { - auto all_ports = load_all_ports(fs, ports_dir); - - std::map names_and_versions; - for (auto&& port : all_ports) - names_and_versions.emplace(port->core_paragraph->name, port->core_paragraph->version); - - return names_and_versions; - } -} diff --git a/toolsrc/src/PostBuildLint.cpp b/toolsrc/src/PostBuildLint.cpp deleted file mode 100644 index a0699e15c..000000000 --- a/toolsrc/src/PostBuildLint.cpp +++ /dev/null @@ -1,846 +0,0 @@ -#include "pch.h" - -#include "PackageSpec.h" -#include "PostBuildLint.h" -#include "PostBuildLint_BuildType.h" -#include "VcpkgPaths.h" -#include "coff_file_reader.h" -#include "vcpkg_Build.h" -#include "vcpkg_Files.h" -#include "vcpkg_System.h" -#include "vcpkg_Util.h" - -using vcpkg::Build::BuildInfo; -using vcpkg::Build::BuildPolicy; -using vcpkg::Build::PreBuildInfo; - -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, - ERROR_DETECTED = 1 - }; - - struct OutdatedDynamicCrt - { - std::string name; - std::regex regex; - - OutdatedDynamicCrt(const std::string& name, const std::string& regex_as_string) - : name(name), regex(std::regex(regex_as_string, std::regex_constants::icase)) - { - } - }; - - Span get_outdated_dynamic_crts(CStringView toolset) - { - static const std::vector V_NO_MSVCRT = { - {"msvcp100.dll", R"(msvcp100\.dll)"}, - {"msvcp100d.dll", R"(msvcp100d\.dll)"}, - {"msvcp110.dll", R"(msvcp110\.dll)"}, - {"msvcp110_win.dll", R"(msvcp110_win\.dll)"}, - {"msvcp120.dll", R"(msvcp120\.dll)"}, - {"msvcp120_clr0400.dll", R"(msvcp120_clr0400\.dll)"}, - {"msvcp60.dll", R"(msvcp60\.dll)"}, - {"msvcp60.dll", R"(msvcp60\.dll)"}, - - {"msvcr100.dll", R"(msvcr100\.dll)"}, - {"msvcr100d.dll", R"(msvcr100d\.dll)"}, - {"msvcr100_clr0400.dll", R"(msvcr100_clr0400\.dll)"}, - {"msvcr110.dll", R"(msvcr110\.dll)"}, - {"msvcr120.dll", R"(msvcr120\.dll)"}, - {"msvcr120_clr0400.dll", R"(msvcr120_clr0400\.dll)"}, - {"msvcrt20.dll", R"(msvcrt20\.dll)"}, - {"msvcrt40.dll", R"(msvcrt40\.dll)"}}; - - return V_NO_MSVCRT; - } - - static LintStatus check_for_files_in_include_directory(const Files::Filesystem& fs, - const Build::BuildPolicies& policies, - const fs::path& package_dir) - { - if (policies.is_enabled(BuildPolicy::EMPTY_INCLUDE_FOLDER)) - { - return LintStatus::SUCCESS; - } - - const fs::path include_dir = package_dir / "include"; - 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; - } - - return LintStatus::SUCCESS; - } - - 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 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()) - { - System::println(System::Color::warning, - "Include files should not be duplicated into the /debug/include directory. If this cannot " - "be disabled in the project cmake, use\n" - " file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/debug/include)"); - return LintStatus::ERROR_DETECTED; - } - - return LintStatus::SUCCESS; - } - - 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)) - { - 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)"); - return LintStatus::ERROR_DETECTED; - } - - return LintStatus::SUCCESS; - } - - 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)) - { - 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 Files::Filesystem& fs, - const fs::path& package_dir, - const PackageSpec& spec) - { - std::vector dirs = { - package_dir / "cmake", - package_dir / "debug" / "cmake", - package_dir / "lib" / "cmake", - package_dir / "debug" / "lib" / "cmake", - }; - - std::vector 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()) - { - System::println( - System::Color::warning, - "The following cmake files were found outside /share/%s. Please place cmake files in /share/%s.", - spec.name(), - spec.name()); - Files::print_paths(misplaced_cmake_files); - return LintStatus::ERROR_DETECTED; - } - - return LintStatus::SUCCESS; - } - - 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)) - { - 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_dir(const Files::Filesystem& fs, const fs::path& package_dir) - { - std::vector 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 or /debug/lib. Please move them to /bin or " - "/debug/bin, respectively."); - Files::print_paths(dlls); - return LintStatus::ERROR_DETECTED; - } - - return LintStatus::SUCCESS; - } - - 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)) - { - return LintStatus::SUCCESS; - } - const fs::path current_buildtrees_dir = paths.buildtrees / spec.name(); - const fs::path current_buildtrees_dir_src = current_buildtrees_dir / "src"; - - std::vector potential_copyright_files; - // 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 (!fs.is_directory(src_dir)) continue; - - for (auto&& src_file : fs.get_files_non_recursive(src_dir)) - { - 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()); - 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]; - const fs::path relative_path = found_file.string().erase( - 0, current_buildtrees_dir.string().size() + 1); // The +1 is needed to remove the "/" - 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()); - } - 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); - } - return LintStatus::ERROR_DETECTED; - } - - static LintStatus check_for_exes(const Files::Filesystem& fs, const fs::path& package_dir) - { - std::vector 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 or /debug/bin. EXEs are not valid distribution targets."); - Files::print_paths(exes); - return LintStatus::ERROR_DETECTED; - } - - return LintStatus::SUCCESS; - } - - static LintStatus check_exports_of_dlls(const std::vector& dlls, const fs::path& dumpbin_exe) - { - std::vector dlls_with_no_exports; - for (const fs::path& dll : dlls) - { - const std::wstring cmd_line = - Strings::wformat(LR"("%s" /exports "%s")", dumpbin_exe.native(), dll.native()); - System::ExitCodeAndOutput ec_data = System::cmd_execute_and_capture_output(cmd_line); - Checks::check_exit(VCPKG_LINE_INFO, - ec_data.exit_code == 0, - "Running command:\n %s\n failed", - Strings::to_utf8(cmd_line)); - - if (ec_data.output.find("ordinal hint RVA name") == std::string::npos) - { - dlls_with_no_exports.push_back(dll); - } - } - - if (!dlls_with_no_exports.empty()) - { - System::println(System::Color::warning, "The following DLLs have no exports:"); - Files::print_paths(dlls_with_no_exports); - System::println(System::Color::warning, "DLLs without any exports are likely a bug in the build script."); - return LintStatus::ERROR_DETECTED; - } - - return LintStatus::SUCCESS; - } - - static LintStatus check_uwp_bit_of_dlls(const std::string& expected_system_name, - const std::vector& dlls, - const fs::path dumpbin_exe) - { - if (expected_system_name != "WindowsStore") - { - return LintStatus::SUCCESS; - } - - std::vector dlls_with_improper_uwp_bit; - for (const fs::path& dll : dlls) - { - const std::wstring cmd_line = - Strings::wformat(LR"("%s" /headers "%s")", dumpbin_exe.native(), dll.native()); - System::ExitCodeAndOutput ec_data = System::cmd_execute_and_capture_output(cmd_line); - Checks::check_exit(VCPKG_LINE_INFO, - ec_data.exit_code == 0, - "Running command:\n %s\n failed", - Strings::to_utf8(cmd_line)); - - if (ec_data.output.find("App Container") == std::string::npos) - { - dlls_with_improper_uwp_bit.push_back(dll); - } - } - - if (!dlls_with_improper_uwp_bit.empty()) - { - System::println(System::Color::warning, "The following DLLs do not have the App Container bit set:"); - Files::print_paths(dlls_with_improper_uwp_bit); - System::println(System::Color::warning, "This bit is required for Windows Store apps."); - return LintStatus::ERROR_DETECTED; - } - - return LintStatus::SUCCESS; - } - - struct FileAndArch - { - fs::path file; - std::string actual_arch; - }; - - static std::string get_actual_architecture(const MachineType& machine_type) - { - switch (machine_type) - { - case MachineType::AMD64: - case MachineType::IA64: return "x64"; - case MachineType::I386: return "x86"; - case MachineType::ARM: - case MachineType::ARMNT: return "arm"; - default: return "Machine Type Code = " + std::to_string(static_cast(machine_type)); - } - } - - static void print_invalid_architecture_files(const std::string& expected_architecture, - std::vector binaries_with_invalid_architecture) - { - System::println(System::Color::warning, "The following files were built for an incorrect architecture:"); - System::println(); - for (const FileAndArch& b : binaries_with_invalid_architecture) - { - System::println(" %s", b.file.generic_string()); - System::println("Expected %s, but was: %s", expected_architecture, b.actual_arch); - System::println(); - } - } - - static LintStatus check_dll_architecture(const std::string& expected_architecture, - const std::vector& files) - { - std::vector binaries_with_invalid_architecture; - - for (const fs::path& file : files) - { - Checks::check_exit(VCPKG_LINE_INFO, - file.extension() == ".dll", - "The file extension was not .dll: %s", - file.generic_string()); - const CoffFileReader::DllInfo info = CoffFileReader::read_dll(file); - const std::string actual_architecture = get_actual_architecture(info.machine_type); - - if (expected_architecture != actual_architecture) - { - binaries_with_invalid_architecture.push_back({file, actual_architecture}); - } - } - - if (!binaries_with_invalid_architecture.empty()) - { - print_invalid_architecture_files(expected_architecture, binaries_with_invalid_architecture); - return LintStatus::ERROR_DETECTED; - } - - return LintStatus::SUCCESS; - } - - static LintStatus check_lib_architecture(const std::string& expected_architecture, - const std::vector& files) - { - std::vector binaries_with_invalid_architecture; - - for (const fs::path& file : files) - { - Checks::check_exit(VCPKG_LINE_INFO, - file.extension() == ".lib", - "The file extension was not .lib: %s", - file.generic_string()); - CoffFileReader::LibInfo info = CoffFileReader::read_lib(file); - - // This is zero for folly's debug library - // TODO: Why? - if (info.machine_types.size() == 0) return LintStatus::SUCCESS; - - Checks::check_exit(VCPKG_LINE_INFO, - info.machine_types.size() == 1, - "Found more than 1 architecture in file %s", - file.generic_string()); - - const std::string actual_architecture = get_actual_architecture(info.machine_types.at(0)); - if (expected_architecture != actual_architecture) - { - binaries_with_invalid_architecture.push_back({file, actual_architecture}); - } - } - - if (!binaries_with_invalid_architecture.empty()) - { - print_invalid_architecture_files(expected_architecture, binaries_with_invalid_architecture); - return LintStatus::ERROR_DETECTED; - } - - return LintStatus::SUCCESS; - } - - static LintStatus check_no_dlls_present(const std::vector& dlls) - { - if (dlls.empty()) - { - return LintStatus::SUCCESS; - } - - System::println(System::Color::warning, - "DLLs should not be present in a static build, but the following DLLs were found:"); - Files::print_paths(dlls); - return LintStatus::ERROR_DETECTED; - } - - static LintStatus check_matching_debug_and_release_binaries(const std::vector& debug_binaries, - const std::vector& release_binaries) - { - const size_t debug_count = debug_binaries.size(); - const size_t release_count = release_binaries.size(); - if (debug_count == release_count) - { - return LintStatus::SUCCESS; - } - - System::println(System::Color::warning, - "Mismatching number of debug and release binaries. Found %d for debug but %d for release.", - debug_count, - release_count); - System::println("Debug binaries"); - Files::print_paths(debug_binaries); - - System::println("Release binaries"); - Files::print_paths(release_binaries); - - if (debug_count == 0) - { - System::println(System::Color::warning, "Debug binaries were not found"); - } - if (release_count == 0) - { - System::println(System::Color::warning, "Release binaries were not found"); - } - - System::println(); - - return LintStatus::ERROR_DETECTED; - } - - static LintStatus check_lib_files_are_available_if_dlls_are_available(const Build::BuildPolicies& policies, - const size_t lib_count, - const size_t dll_count, - const fs::path& lib_dir) - { - if (policies.is_enabled(BuildPolicy::DLLS_WITHOUT_LIBS)) return LintStatus::SUCCESS; - - if (lib_count == 0 && dll_count != 0) - { - 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)", - to_cmake_variable(BuildPolicy::DLLS_WITHOUT_LIBS)); - return LintStatus::ERROR_DETECTED; - } - - return LintStatus::SUCCESS; - } - - 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)) - { - return LintStatus::SUCCESS; - } - - 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.u8string()); - } - - 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.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" - "\n" - R"###( if(VCPKG_LIBRARY_LINKAGE STREQUAL static))###" - "\n" - R"###( file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/bin ${CURRENT_PACKAGES_DIR}/debug/bin))###" - "\n" - R"###( endif())###" - "\n"); - - return LintStatus::ERROR_DETECTED; - } - - static LintStatus check_no_empty_folders(const Files::Filesystem& fs, const fs::path& dir) - { - std::vector 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()) - { - System::println(System::Color::warning, "There should be no empty directories in %s", dir.generic_string()); - System::println("The following empty directories were found: "); - Files::print_paths(empty_directories); - System::println( - System::Color::warning, - "If a directory should be populated but is not, this might indicate an error in the portfile.\n" - "If the directories are not needed and their creation cannot be disabled, use something like this in " - "the portfile to remove them:\n" - "\n" - R"###( file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/a/dir ${CURRENT_PACKAGES_DIR}/some/other/dir))###" - "\n" - "\n"); - return LintStatus::ERROR_DETECTED; - } - - return LintStatus::SUCCESS; - } - - struct BuildTypeAndFile - { - fs::path file; - BuildType build_type; - }; - - static LintStatus check_crt_linkage_of_libs(const BuildType& expected_build_type, - const std::vector& libs, - const fs::path dumpbin_exe) - { - std::vector bad_build_types(BuildTypeC::VALUES.cbegin(), BuildTypeC::VALUES.cend()); - bad_build_types.erase(std::remove(bad_build_types.begin(), bad_build_types.end(), expected_build_type), - bad_build_types.end()); - - std::vector libs_with_invalid_crt; - - for (const fs::path& lib : libs) - { - const std::wstring cmd_line = - Strings::wformat(LR"("%s" /directives "%s")", dumpbin_exe.native(), lib.native()); - System::ExitCodeAndOutput ec_data = System::cmd_execute_and_capture_output(cmd_line); - Checks::check_exit(VCPKG_LINE_INFO, - ec_data.exit_code == 0, - "Running command:\n %s\n failed", - Strings::to_utf8(cmd_line)); - - for (const BuildType& bad_build_type : bad_build_types) - { - if (std::regex_search(ec_data.output.cbegin(), ec_data.output.cend(), bad_build_type.crt_regex())) - { - libs_with_invalid_crt.push_back({lib, bad_build_type}); - break; - } - } - } - - if (!libs_with_invalid_crt.empty()) - { - System::println(System::Color::warning, - "Expected %s crt linkage, but the following libs had invalid crt linkage:", - expected_build_type.to_string()); - System::println(); - for (const BuildTypeAndFile btf : libs_with_invalid_crt) - { - System::println(" %s: %s", btf.file.generic_string(), btf.build_type.to_string()); - } - System::println(); - - System::println(System::Color::warning, - "To inspect the lib files, use:\n dumpbin.exe /directives mylibfile.lib"); - return LintStatus::ERROR_DETECTED; - } - - return LintStatus::SUCCESS; - } - - struct OutdatedDynamicCrtAndFile - { - fs::path file; - OutdatedDynamicCrt outdated_crt; - - OutdatedDynamicCrtAndFile() = delete; - }; - - static LintStatus check_outdated_crt_linkage_of_dlls(const std::vector& dlls, - const fs::path dumpbin_exe, - const BuildInfo& build_info) - { - if (build_info.policies.is_enabled(BuildPolicy::ALLOW_OBSOLETE_MSVCRT)) return LintStatus::SUCCESS; - - std::vector dlls_with_outdated_crt; - - for (const fs::path& dll : dlls) - { - const std::wstring cmd_line = - Strings::wformat(LR"("%s" /dependents "%s")", dumpbin_exe.native(), dll.native()); - System::ExitCodeAndOutput ec_data = System::cmd_execute_and_capture_output(cmd_line); - Checks::check_exit(VCPKG_LINE_INFO, - ec_data.exit_code == 0, - "Running command:\n %s\n failed", - Strings::to_utf8(cmd_line)); - - for (const OutdatedDynamicCrt& outdated_crt : get_outdated_dynamic_crts("v141")) - { - if (std::regex_search(ec_data.output.cbegin(), ec_data.output.cend(), outdated_crt.regex)) - { - dlls_with_outdated_crt.push_back({dll, outdated_crt}); - break; - } - } - } - - if (!dlls_with_outdated_crt.empty()) - { - System::println(System::Color::warning, "Detected outdated dynamic CRT in the following files:"); - System::println(); - for (const OutdatedDynamicCrtAndFile btf : dlls_with_outdated_crt) - { - System::println(" %s: %s", btf.file.generic_string(), btf.outdated_crt.name); - } - System::println(); - - System::println(System::Color::warning, - "To inspect the dll files, use:\n dumpbin.exe /dependents mydllfile.dll"); - return LintStatus::ERROR_DETECTED; - } - - return LintStatus::SUCCESS; - } - - static LintStatus check_no_files_in_dir(const Files::Filesystem& fs, const fs::path& dir) - { - std::vector 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 (Strings::case_insensitive_ascii_compare(filename.c_str(), "CONTROL") == 0 || - Strings::case_insensitive_ascii_compare(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: ", dir.u8string()); - Files::print_paths(misplaced_files); - System::println(System::Color::warning, "Files cannot be present in those directories.\n"); - return LintStatus::ERROR_DETECTED; - } - - return LintStatus::SUCCESS; - } - - static void operator+=(size_t& left, const LintStatus& right) { left += static_cast(right); } - - static size_t perform_all_checks_and_return_error_count(const PackageSpec& spec, - const VcpkgPaths& paths, - const PreBuildInfo& pre_build_info, - const BuildInfo& build_info) - { - const auto& fs = paths.get_filesystem(); - - // for dumpbin - const Toolset& toolset = paths.get_toolset(pre_build_info.platform_toolset, pre_build_info.visual_studio_path); - const fs::path package_dir = paths.package_dir(spec); - - size_t error_count = 0; - - if (build_info.policies.is_enabled(BuildPolicy::EMPTY_PACKAGE)) - { - return error_count; - } - - 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"; - - std::vector debug_libs = fs.get_files_recursive(debug_lib_dir); - Util::unstable_keep_if(debug_libs, has_extension_pred(fs, ".lib")); - std::vector 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 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(pre_build_info.target_architecture, libs); - } - - std::vector debug_dlls = fs.get_files_recursive(debug_bin_dir); - Util::unstable_keep_if(debug_dlls, has_extension_pred(fs, ".dll")); - std::vector release_dlls = fs.get_files_recursive(release_bin_dir); - Util::unstable_keep_if(release_dlls, has_extension_pred(fs, ".dll")); - - switch (build_info.library_linkage) - { - case Build::LinkageType::DYNAMIC: - { - error_count += check_matching_debug_and_release_binaries(debug_dlls, release_dlls); - - error_count += check_lib_files_are_available_if_dlls_are_available( - build_info.policies, debug_libs.size(), debug_dlls.size(), debug_lib_dir); - error_count += check_lib_files_are_available_if_dlls_are_available( - build_info.policies, release_libs.size(), release_dlls.size(), release_lib_dir); - - std::vector dlls; - dlls.insert(dlls.cend(), debug_dlls.cbegin(), debug_dlls.cend()); - dlls.insert(dlls.cend(), release_dlls.cbegin(), release_dlls.cend()); - - error_count += check_exports_of_dlls(dlls, toolset.dumpbin); - error_count += check_uwp_bit_of_dlls(pre_build_info.cmake_system_name, dlls, toolset.dumpbin); - error_count += check_dll_architecture(pre_build_info.target_architecture, dlls); - - error_count += check_outdated_crt_linkage_of_dlls(dlls, toolset.dumpbin, build_info); - break; - } - case Build::LinkageType::STATIC: - { - auto dlls = release_dlls; - dlls.insert(dlls.end(), debug_dlls.begin(), debug_dlls.end()); - error_count += check_no_dlls_present(dlls); - - error_count += check_bin_folders_are_not_present_in_static_build(fs, package_dir); - - if (!build_info.policies.is_enabled(BuildPolicy::ONLY_RELEASE_CRT)) - { - error_count += - check_crt_linkage_of_libs(BuildType::value_of(ConfigurationType::DEBUG, build_info.crt_linkage), - debug_libs, - toolset.dumpbin); - } - error_count += - check_crt_linkage_of_libs(BuildType::value_of(ConfigurationType::RELEASE, build_info.crt_linkage), - release_libs, - toolset.dumpbin); - break; - } - default: Checks::unreachable(VCPKG_LINE_INFO); - } - - 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; - } - - size_t perform_all_checks(const PackageSpec& spec, - const VcpkgPaths& paths, - const PreBuildInfo& pre_build_info, - const BuildInfo& build_info) - { - System::println("-- Performing post-build validation"); - const size_t error_count = perform_all_checks_and_return_error_count(spec, paths, pre_build_info, build_info); - - if (error_count != 0) - { - const fs::path portfile = paths.ports / spec.name() / "portfile.cmake"; - System::println(System::Color::error, - "Found %u error(s). Please correct the portfile:\n %s", - error_count, - portfile.string()); - } - - System::println("-- Performing post-build validation done"); - - return error_count; - } -} diff --git a/toolsrc/src/PostBuildLint_BuildType.cpp b/toolsrc/src/PostBuildLint_BuildType.cpp deleted file mode 100644 index 649f0ccca..000000000 --- a/toolsrc/src/PostBuildLint_BuildType.cpp +++ /dev/null @@ -1,70 +0,0 @@ -#include "pch.h" - -#include "PostBuildLint_BuildType.h" -#include "vcpkg_Checks.h" - -namespace vcpkg::PostBuildLint -{ - BuildType BuildType::value_of(const ConfigurationType& config, const Build::LinkageType& linkage) - { - if (config == ConfigurationType::DEBUG && linkage == Build::LinkageType::STATIC) - { - return BuildTypeC::DEBUG_STATIC; - } - - if (config == ConfigurationType::DEBUG && linkage == Build::LinkageType::DYNAMIC) - { - return BuildTypeC::DEBUG_DYNAMIC; - } - - if (config == ConfigurationType::RELEASE && linkage == Build::LinkageType::STATIC) - { - return BuildTypeC::RELEASE_STATIC; - } - - if (config == ConfigurationType::RELEASE && linkage == Build::LinkageType::DYNAMIC) - { - return BuildTypeC::RELEASE_DYNAMIC; - } - - Checks::unreachable(VCPKG_LINE_INFO); - } - - const ConfigurationType& BuildType::config() const { return this->m_config; } - - const Build::LinkageType& BuildType::linkage() const { return this->m_linkage; } - - const std::regex& BuildType::crt_regex() const - { - static const std::regex REGEX_DEBUG_STATIC(R"(/DEFAULTLIB:LIBCMTD)", std::regex_constants::icase); - static const std::regex REGEX_DEBUG_DYNAMIC(R"(/DEFAULTLIB:MSVCRTD)", std::regex_constants::icase); - static const std::regex REGEX_RELEASE_STATIC(R"(/DEFAULTLIB:LIBCMT[^D])", std::regex_constants::icase); - static const std::regex REGEX_RELEASE_DYNAMIC(R"(/DEFAULTLIB:MSVCRT[^D])", std::regex_constants::icase); - - switch (backing_enum) - { - case BuildTypeC::DEBUG_STATIC: return REGEX_DEBUG_STATIC; - case BuildTypeC::DEBUG_DYNAMIC: return REGEX_DEBUG_DYNAMIC; - case BuildTypeC::RELEASE_STATIC: return REGEX_RELEASE_STATIC; - case BuildTypeC::RELEASE_DYNAMIC: return REGEX_RELEASE_DYNAMIC; - default: Checks::unreachable(VCPKG_LINE_INFO); - } - } - - const std::string& BuildType::to_string() const - { - static const std::string NAME_DEBUG_STATIC("Debug,Static"); - static const std::string NAME_DEBUG_DYNAMIC("Debug,Dynamic"); - static const std::string NAME_RELEASE_STATIC("Release,Static"); - static const std::string NAME_RELEASE_DYNAMIC("Release,Dynamic"); - - switch (backing_enum) - { - case BuildTypeC::DEBUG_STATIC: return NAME_DEBUG_STATIC; - case BuildTypeC::DEBUG_DYNAMIC: return NAME_DEBUG_DYNAMIC; - case BuildTypeC::RELEASE_STATIC: return NAME_RELEASE_STATIC; - case BuildTypeC::RELEASE_DYNAMIC: return NAME_RELEASE_DYNAMIC; - default: Checks::unreachable(VCPKG_LINE_INFO); - } - } -} diff --git a/toolsrc/src/SourceParagraph.cpp b/toolsrc/src/SourceParagraph.cpp deleted file mode 100644 index 0f1a38d19..000000000 --- a/toolsrc/src/SourceParagraph.cpp +++ /dev/null @@ -1,262 +0,0 @@ -#include "pch.h" - -#include "PackageSpec.h" -#include "SourceParagraph.h" -#include "Triplet.h" -#include "vcpkg_Checks.h" -#include "vcpkg_Maps.h" -#include "vcpkg_System.h" -#include "vcpkg_Util.h" -#include "vcpkg_expected.h" - -namespace vcpkg -{ - using namespace vcpkg::Parse; - - namespace Fields - { - static const std::string BUILD_DEPENDS = "Build-Depends"; - static const std::string DEFAULTFEATURES = "Default-Features"; - static const std::string DESCRIPTION = "Description"; - static const std::string FEATURE = "Feature"; - static const std::string MAINTAINER = "Maintainer"; - static const std::string SOURCE = "Source"; - static const std::string SUPPORTS = "Supports"; - static const std::string VERSION = "Version"; - } - - static Span get_list_of_valid_fields() - { - static const std::string valid_fields[] = { - Fields::SOURCE, - Fields::VERSION, - Fields::DESCRIPTION, - Fields::MAINTAINER, - Fields::BUILD_DEPENDS, - }; - - return valid_fields; - } - - void print_error_message(Span> error_info_list) - { - Checks::check_exit(VCPKG_LINE_INFO, error_info_list.size() > 0); - - for (auto&& error_info : error_info_list) - { - Checks::check_exit(VCPKG_LINE_INFO, error_info != nullptr); - if (error_info->error) - { - System::println( - System::Color::error, "Error: while loading %s: %s", error_info->name, error_info->error.message()); - } - } - - bool have_remaining_fields = false; - for (auto&& error_info : error_info_list) - { - if (!error_info->extra_fields.empty()) - { - System::println(System::Color::error, - "Error: There are invalid fields in the control file of %s", - error_info->name); - System::println("The following fields were not expected:\n\n %s\n", - Strings::join("\n ", error_info->extra_fields)); - have_remaining_fields = true; - } - } - - if (have_remaining_fields) - { - System::println("This is the list of valid fields (case-sensitive): \n\n %s\n", - Strings::join("\n ", get_list_of_valid_fields())); - System::println("Different source may be available for vcpkg. Use .\\bootstrap-vcpkg.bat to update.\n"); - } - - for (auto&& error_info : error_info_list) - { - if (!error_info->missing_fields.empty()) - { - System::println(System::Color::error, - "Error: There are missing fields in the control file of %s", - error_info->name); - System::println("The following fields were missing:\n\n %s\n", - Strings::join("\n ", error_info->missing_fields)); - } - } - } - - static ParseExpected parse_source_paragraph(RawParagraph&& fields) - { - ParagraphParser parser(std::move(fields)); - - auto spgh = std::make_unique(); - - parser.required_field(Fields::SOURCE, spgh->name); - parser.required_field(Fields::VERSION, spgh->version); - - spgh->description = parser.optional_field(Fields::DESCRIPTION); - spgh->maintainer = parser.optional_field(Fields::MAINTAINER); - spgh->depends = expand_qualified_dependencies(parse_comma_list(parser.optional_field(Fields::BUILD_DEPENDS))); - spgh->supports = parse_comma_list(parser.optional_field(Fields::SUPPORTS)); - spgh->default_features = parse_comma_list(parser.optional_field(Fields::DEFAULTFEATURES)); - - auto err = parser.error_info(spgh->name); - if (err) - return std::move(err); - else - return std::move(spgh); - } - - static ParseExpected parse_feature_paragraph(RawParagraph&& fields) - { - ParagraphParser parser(std::move(fields)); - - auto fpgh = std::make_unique(); - - parser.required_field(Fields::FEATURE, fpgh->name); - parser.required_field(Fields::DESCRIPTION, fpgh->description); - - fpgh->depends = expand_qualified_dependencies(parse_comma_list(parser.optional_field(Fields::BUILD_DEPENDS))); - - auto err = parser.error_info(fpgh->name); - if (err) - return std::move(err); - else - return std::move(fpgh); - } - - ParseExpected SourceControlFile::parse_control_file( - std::vector>&& control_paragraphs) - { - if (control_paragraphs.size() == 0) - { - return std::make_unique(); - } - - auto control_file = std::make_unique(); - - auto maybe_source = parse_source_paragraph(std::move(control_paragraphs.front())); - if (const auto source = maybe_source.get()) - control_file->core_paragraph = std::move(*source); - else - return std::move(maybe_source).error(); - - control_paragraphs.erase(control_paragraphs.begin()); - - for (auto&& feature_pgh : control_paragraphs) - { - auto maybe_feature = parse_feature_paragraph(std::move(feature_pgh)); - if (const auto feature = maybe_feature.get()) - control_file->feature_paragraphs.emplace_back(std::move(*feature)); - else - return std::move(maybe_feature).error(); - } - - return std::move(control_file); - } - - Dependency Dependency::parse_dependency(std::string name, std::string qualifier) - { - Dependency dep; - dep.qualifier = qualifier; - if (auto maybe_features = Features::from_string(name)) - dep.depend = *maybe_features.get(); - else - Checks::exit_with_message( - VCPKG_LINE_INFO, "error while parsing dependency: %s: %s", to_string(maybe_features.error()), name); - return dep; - } - - std::string Dependency::name() const - { - if (this->depend.features.empty()) return this->depend.name; - - const std::string features = Strings::join(",", this->depend.features); - return Strings::format("%s[%s]", this->depend.name, features); - } - - std::vector vcpkg::expand_qualified_dependencies(const std::vector& depends) - { - return Util::fmap(depends, [&](const std::string& depend_string) -> Dependency { - auto pos = depend_string.find(' '); - if (pos == std::string::npos) return Dependency::parse_dependency(depend_string, Strings::EMPTY); - // expect of the form "\w+ \[\w+\]" - Dependency dep; - - dep.depend.name = depend_string.substr(0, pos); - if (depend_string.c_str()[pos + 1] != '(' || depend_string[depend_string.size() - 1] != ')') - { - // Error, but for now just slurp the entire string. - return Dependency::parse_dependency(depend_string, Strings::EMPTY); - } - dep.qualifier = depend_string.substr(pos + 2, depend_string.size() - pos - 3); - return dep; - }); - } - - std::vector filter_dependencies(const std::vector& deps, const Triplet& t) - { - std::vector ret; - for (auto&& dep : deps) - { - if (dep.qualifier.empty() || t.canonical_name().find(dep.qualifier) != std::string::npos) - { - ret.emplace_back(dep.name()); - } - } - return ret; - } - - std::vector filter_dependencies_to_specs(const std::vector& deps, const Triplet& t) - { - return FeatureSpec::from_strings_and_triplet(filter_dependencies(deps, t), t); - } - - std::string to_string(const Dependency& dep) { return dep.name(); } - - ExpectedT> Supports::parse(const std::vector& strs) - { - Supports ret; - std::vector unrecognized; - - for (auto&& str : strs) - { - if (str == "x64") - ret.architectures.push_back(Architecture::X64); - else if (str == "x86") - ret.architectures.push_back(Architecture::X86); - else if (str == "arm") - ret.architectures.push_back(Architecture::ARM); - else if (str == "windows") - ret.platforms.push_back(Platform::WINDOWS); - else if (str == "uwp") - ret.platforms.push_back(Platform::UWP); - else if (str == "v140") - ret.toolsets.push_back(ToolsetVersion::V140); - else if (str == "v141") - ret.toolsets.push_back(ToolsetVersion::V141); - else if (str == "crt-static") - ret.crt_linkages.push_back(Linkage::STATIC); - else if (str == "crt-dynamic") - ret.crt_linkages.push_back(Linkage::DYNAMIC); - else - unrecognized.push_back(str); - } - - if (unrecognized.empty()) - return std::move(ret); - else - return std::move(unrecognized); - } - - bool Supports::is_supported(Architecture arch, Platform plat, Linkage crt, ToolsetVersion tools) - { - const auto is_in_or_empty = [](auto v, auto&& c) -> bool { return c.empty() || c.end() != Util::find(c, v); }; - if (!is_in_or_empty(arch, architectures)) return false; - if (!is_in_or_empty(plat, platforms)) return false; - if (!is_in_or_empty(crt, crt_linkages)) return false; - if (!is_in_or_empty(tools, toolsets)) return false; - return true; - } -} diff --git a/toolsrc/src/StatusParagraph.cpp b/toolsrc/src/StatusParagraph.cpp deleted file mode 100644 index f8ae293c2..000000000 --- a/toolsrc/src/StatusParagraph.cpp +++ /dev/null @@ -1,86 +0,0 @@ -#include "pch.h" - -#include "StatusParagraph.h" - -using namespace vcpkg::Parse; - -namespace vcpkg -{ - namespace BinaryParagraphRequiredField - { - static const std::string STATUS = "Status"; - } - - StatusParagraph::StatusParagraph() : want(Want::ERROR_STATE), state(InstallState::ERROR_STATE) {} - - void serialize(const StatusParagraph& pgh, std::string& out_str) - { - 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(std::unordered_map&& fields) - { - auto status_it = fields.find(BinaryParagraphRequiredField::STATUS); - Checks::check_exit(VCPKG_LINE_INFO, status_it != fields.end(), "Expected 'Status' field in status paragraph"); - std::string status_field = std::move(status_it->second); - fields.erase(status_it); - - this->package = BinaryParagraph(std::move(fields)); - - auto b = status_field.begin(); - const auto mark = b; - const auto e = status_field.end(); - - // Todo: improve error handling - while (b != e && *b != ' ') - ++b; - - want = [](const std::string& text) { - if (text == "unknown") return Want::UNKNOWN; - if (text == "install") return Want::INSTALL; - if (text == "hold") return Want::HOLD; - if (text == "deinstall") return Want::DEINSTALL; - if (text == "purge") return Want::PURGE; - return Want::ERROR_STATE; - }(std::string(mark, b)); - - if (std::distance(b, e) < 4) return; - b += 4; - - state = [](const std::string& text) { - if (text == "not-installed") return InstallState::NOT_INSTALLED; - if (text == "installed") return InstallState::INSTALLED; - if (text == "half-installed") return InstallState::HALF_INSTALLED; - return InstallState::ERROR_STATE; - }(std::string(b, e)); - } - - std::string to_string(InstallState f) - { - switch (f) - { - case InstallState::HALF_INSTALLED: return "half-installed"; - case InstallState::INSTALLED: return "installed"; - case InstallState::NOT_INSTALLED: return "not-installed"; - default: return "error"; - } - } - - std::string to_string(Want f) - { - switch (f) - { - case Want::DEINSTALL: return "deinstall"; - case Want::HOLD: return "hold"; - case Want::INSTALL: return "install"; - case Want::PURGE: return "purge"; - case Want::UNKNOWN: return "unknown"; - default: return "error"; - } - } -} diff --git a/toolsrc/src/StatusParagraphs.cpp b/toolsrc/src/StatusParagraphs.cpp deleted file mode 100644 index aaba95eb9..000000000 --- a/toolsrc/src/StatusParagraphs.cpp +++ /dev/null @@ -1,90 +0,0 @@ -#include "pch.h" - -#include "StatusParagraphs.h" -#include "vcpkg_Checks.h" -#include - -namespace vcpkg -{ - StatusParagraphs::StatusParagraphs() = default; - - StatusParagraphs::StatusParagraphs(std::vector>&& ps) - : paragraphs(std::move(ps)){}; - - StatusParagraphs::const_iterator StatusParagraphs::find(const std::string& name, const Triplet& triplet) const - { - return std::find_if(begin(), end(), [&](const std::unique_ptr& pgh) { - const PackageSpec& spec = pgh->package.spec; - return spec.name() == name && spec.triplet() == triplet; - }); - } - - StatusParagraphs::iterator StatusParagraphs::find(const std::string& name, const Triplet& triplet) - { - return std::find_if(begin(), end(), [&](const std::unique_ptr& pgh) { - const PackageSpec& spec = pgh->package.spec; - return spec.name() == name && spec.triplet() == triplet; - }); - } - - std::vector*> StatusParagraphs::find_all(const std::string& name, - const Triplet& triplet) - { - std::vector*> spghs; - for (auto&& p : *this) - { - if (p->package.spec.name() == name && p->package.spec.triplet() == triplet) - { - spghs.emplace_back(&p); - } - } - return spghs; - } - - StatusParagraphs::iterator StatusParagraphs::find(const std::string& name, - const Triplet& triplet, - const std::string& feature) - { - return std::find_if(begin(), end(), [&](const std::unique_ptr& pgh) { - const PackageSpec& spec = pgh->package.spec; - return spec.name() == name && spec.triplet() == triplet && pgh->package.feature == feature; - }); - } - - StatusParagraphs::const_iterator StatusParagraphs::find_installed(const std::string& name, - const Triplet& triplet) const - { - const const_iterator it = find(name, triplet); - if (it != end() && (*it)->want == Want::INSTALL && (*it)->state == InstallState::INSTALLED) - { - return it; - } - - return end(); - } - - StatusParagraphs::iterator StatusParagraphs::insert(std::unique_ptr pgh) - { - Checks::check_exit(VCPKG_LINE_INFO, pgh != nullptr, "Inserted null paragraph"); - const PackageSpec& spec = pgh->package.spec; - const auto ptr = find(spec.name(), spec.triplet(), pgh->package.feature); - if (ptr == end()) - { - paragraphs.push_back(std::move(pgh)); - return paragraphs.rbegin(); - } - - // consume data from provided pgh. - **ptr = std::move(*pgh); - return ptr; - } - - void serialize(const StatusParagraphs& pghs, std::string& out_str) - { - for (auto& pgh : pghs.paragraphs) - { - serialize(*pgh, out_str); - out_str.push_back('\n'); - } - } -} diff --git a/toolsrc/src/VcpkgCmdArguments.cpp b/toolsrc/src/VcpkgCmdArguments.cpp deleted file mode 100644 index cb261930e..000000000 --- a/toolsrc/src/VcpkgCmdArguments.cpp +++ /dev/null @@ -1,283 +0,0 @@ -#include "pch.h" - -#include "VcpkgCmdArguments.h" -#include "metrics.h" -#include "vcpkg_Commands.h" -#include "vcpkg_GlobalState.h" -#include "vcpkg_System.h" - -namespace vcpkg -{ - static void parse_value(const std::string* arg_begin, - const std::string* arg_end, - const std::string& option_name, - std::unique_ptr& option_field) - { - if (arg_begin == arg_end) - { - System::println(System::Color::error, "Error: expected value after %s", option_name); - Metrics::g_metrics.lock()->track_property("error", "error option name"); - Commands::Help::print_usage(); - Checks::exit_fail(VCPKG_LINE_INFO); - } - - if (option_field != nullptr) - { - System::println(System::Color::error, "Error: %s specified multiple times", option_name); - Metrics::g_metrics.lock()->track_property("error", "error option specified multiple times"); - Commands::Help::print_usage(); - Checks::exit_fail(VCPKG_LINE_INFO); - } - - option_field = std::make_unique(*arg_begin); - } - - static void parse_switch(bool new_setting, const std::string& option_name, Optional& option_field) - { - if (option_field && option_field != new_setting) - { - System::println(System::Color::error, "Error: conflicting values specified for --%s", option_name); - Metrics::g_metrics.lock()->track_property("error", "error conflicting switches"); - Commands::Help::print_usage(); - Checks::exit_fail(VCPKG_LINE_INFO); - } - option_field = new_setting; - } - - VcpkgCmdArguments VcpkgCmdArguments::create_from_command_line(const int argc, const wchar_t* const* const argv) - { - std::vector v; - for (int i = 1; i < argc; ++i) - { - v.push_back(Strings::to_utf8(argv[i])); - } - - return VcpkgCmdArguments::create_from_arg_sequence(v.data(), v.data() + v.size()); - } - - VcpkgCmdArguments VcpkgCmdArguments::create_from_arg_sequence(const std::string* arg_begin, - const std::string* arg_end) - { - VcpkgCmdArguments args; - - for (; arg_begin != arg_end; ++arg_begin) - { - std::string arg = *arg_begin; - - if (arg.empty()) - { - continue; - } - - if (arg[0] == '-' && arg[1] != '-') - { - Metrics::g_metrics.lock()->track_property("error", "error short options are not supported"); - Checks::exit_with_message(VCPKG_LINE_INFO, "Error: short options are not supported: %s", arg); - } - - if (arg[0] == '-' && arg[1] == '-') - { - // make argument case insensitive - auto& f = std::use_facet>(std::locale()); - f.tolower(&arg[0], &arg[0] + arg.size()); - // command switch - if (arg == "--vcpkg-root") - { - ++arg_begin; - parse_value(arg_begin, arg_end, "--vcpkg-root", args.vcpkg_root_dir); - continue; - } - if (arg == "--triplet") - { - ++arg_begin; - parse_value(arg_begin, arg_end, "--triplet", args.triplet); - continue; - } - if (arg == "--debug") - { - parse_switch(true, "debug", args.debug); - continue; - } - if (arg == "--sendmetrics") - { - parse_switch(true, "sendmetrics", args.sendmetrics); - continue; - } - if (arg == "--printmetrics") - { - parse_switch(true, "printmetrics", args.printmetrics); - continue; - } - if (arg == "--no-sendmetrics") - { - parse_switch(false, "sendmetrics", args.sendmetrics); - continue; - } - if (arg == "--no-printmetrics") - { - parse_switch(false, "printmetrics", args.printmetrics); - continue; - } - if (arg == "--featurepackages") - { - GlobalState::feature_packages = true; - continue; - } - - const auto eq_pos = arg.find('='); - if (eq_pos != std::string::npos) - { - args.optional_command_arguments.emplace(arg.substr(0, eq_pos), arg.substr(eq_pos + 1)); - } - else - { - args.optional_command_arguments.emplace(arg, nullopt); - } - continue; - } - - if (args.command.empty()) - { - args.command = arg; - } - else - { - args.command_arguments.push_back(arg); - } - } - - return args; - } - - ParsedArguments VcpkgCmdArguments::check_and_get_optional_command_arguments( - const std::vector& valid_switches, const std::vector& valid_settings) const - { - bool failed = false; - ParsedArguments output; - - auto options_copy = this->optional_command_arguments; - for (const std::string& option : valid_switches) - { - const auto it = options_copy.find(option); - if (it != options_copy.end()) - { - if (it->second.has_value()) - { - // Having a string value indicates it was passed like '--a=xyz' - System::println(System::Color::error, "The option '%s' does not accept an argument.", option); - failed = true; - } - else - { - output.switches.insert(option); - options_copy.erase(it); - } - } - } - - for (const std::string& option : valid_settings) - { - const auto it = options_copy.find(option); - if (it != options_copy.end()) - { - if (!it->second.has_value()) - { - // Not having a string value indicates it was passed like '--a' - System::println(System::Color::error, "The option '%s' must be passed an argument.", option); - failed = true; - } - else - { - output.settings.emplace(option, it->second.value_or_exit(VCPKG_LINE_INFO)); - options_copy.erase(it); - } - } - } - - if (!options_copy.empty()) - { - System::println(System::Color::error, "Unknown option(s) for command '%s':", this->command); - for (auto&& option : options_copy) - { - System::println(" %s", option.first); - } - System::println("\nValid options are:", this->command); - for (auto&& option : valid_switches) - { - System::println(" %s", option); - } - for (auto&& option : valid_settings) - { - System::println(" %s=...", option); - } - System::println(" --triplet "); - System::println(" --vcpkg-root "); - - Checks::exit_fail(VCPKG_LINE_INFO); - } - if (failed) Checks::exit_fail(VCPKG_LINE_INFO); - - return output; - } - - void VcpkgCmdArguments::check_max_arg_count(const size_t expected_arg_count) const - { - return check_max_arg_count(expected_arg_count, Strings::EMPTY); - } - - void VcpkgCmdArguments::check_min_arg_count(const size_t expected_arg_count) const - { - return check_min_arg_count(expected_arg_count, Strings::EMPTY); - } - - void VcpkgCmdArguments::check_exact_arg_count(const size_t expected_arg_count) const - { - return check_exact_arg_count(expected_arg_count, Strings::EMPTY); - } - - void VcpkgCmdArguments::check_max_arg_count(const size_t expected_arg_count, const std::string& example_text) const - { - const size_t actual_arg_count = command_arguments.size(); - if (actual_arg_count > expected_arg_count) - { - System::println(System::Color::error, - "Error: `%s` requires at most %u arguments, but %u were provided", - this->command, - expected_arg_count, - actual_arg_count); - System::print(example_text); - Checks::exit_fail(VCPKG_LINE_INFO); - } - } - - void VcpkgCmdArguments::check_min_arg_count(const size_t expected_arg_count, const std::string& example_text) const - { - const size_t actual_arg_count = command_arguments.size(); - if (actual_arg_count < expected_arg_count) - { - System::println(System::Color::error, - "Error: `%s` requires at least %u arguments, but %u were provided", - this->command, - expected_arg_count, - actual_arg_count); - System::print(example_text); - Checks::exit_fail(VCPKG_LINE_INFO); - } - } - - void VcpkgCmdArguments::check_exact_arg_count(const size_t expected_arg_count, - const std::string& example_text) const - { - const size_t actual_arg_count = command_arguments.size(); - if (actual_arg_count != expected_arg_count) - { - System::println(System::Color::error, - "Error: `%s` requires %u arguments, but %u were provided", - this->command, - expected_arg_count, - actual_arg_count); - System::print(example_text); - Checks::exit_fail(VCPKG_LINE_INFO); - } - } -} diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp deleted file mode 100644 index d14002e47..000000000 --- a/toolsrc/src/VcpkgPaths.cpp +++ /dev/null @@ -1,519 +0,0 @@ -#include "pch.h" - -#include "PackageSpec.h" -#include "VcpkgPaths.h" -#include "metrics.h" -#include "vcpkg_Files.h" -#include "vcpkg_System.h" -#include "vcpkg_Util.h" -#include "vcpkg_expected.h" - -namespace vcpkg -{ - static constexpr CWStringView V_120 = L"v120"; - static constexpr CWStringView V_140 = L"v140"; - static constexpr CWStringView V_141 = L"v141"; - - static bool exists_and_has_equal_or_greater_version(const std::wstring& version_cmd, - const std::array& expected_version) - { - static const std::regex RE(R"###((\d+)\.(\d+)\.(\d+))###"); - - const auto rc = System::cmd_execute_and_capture_output(Strings::wformat(LR"(%s)", version_cmd)); - if (rc.exit_code != 0) - { - return false; - } - - std::match_results match; - const auto found = std::regex_search(rc.output, match, RE); - if (!found) - { - return false; - } - - const int d1 = atoi(match[1].str().c_str()); - const int d2 = atoi(match[2].str().c_str()); - const int d3 = atoi(match[3].str().c_str()); - if (d1 > expected_version[0] || (d1 == expected_version[0] && d2 > expected_version[1]) || - (d1 == expected_version[0] && d2 == expected_version[1] && d3 >= expected_version[2])) - { - // satisfactory version found - return true; - } - - return false; - } - - static Optional find_if_has_equal_or_greater_version(const std::vector& candidate_paths, - const std::wstring& version_check_arguments, - const std::array& expected_version) - { - auto it = Util::find_if(candidate_paths, [&](const fs::path& p) { - const std::wstring cmd = Strings::wformat(LR"("%s" %s)", p.native(), version_check_arguments); - return exists_and_has_equal_or_greater_version(cmd, expected_version); - }); - - if (it != candidate_paths.cend()) - { - return std::move(*it); - } - - return nullopt; - } - - static fs::path fetch_dependency(const fs::path& scripts_folder, - const std::wstring& tool_name, - const fs::path& expected_downloaded_path, - const std::array& version) - { - const std::string tool_name_utf8 = Strings::to_utf8(tool_name); - const std::string version_as_string = Strings::format("%d.%d.%d", version[0], version[1], version[2]); - System::println("A suitable version of %s was not found (required v%s). Downloading portable %s v%s...", - tool_name_utf8, - version_as_string, - tool_name_utf8, - version_as_string); - const fs::path script = scripts_folder / "fetchDependency.ps1"; - const auto install_cmd = - System::create_powershell_script_cmd(script, Strings::wformat(L"-Dependency %s", tool_name)); - const System::ExitCodeAndOutput rc = System::cmd_execute_and_capture_output(install_cmd); - if (rc.exit_code) - { - System::println(System::Color::error, - "Launching powershell failed or was denied when trying to fetch %s version %s.\n" - "(No sufficient installed version was found)", - tool_name_utf8, - version_as_string); - { - auto locked_metrics = Metrics::g_metrics.lock(); - locked_metrics->track_property("error", "powershell install failed"); - locked_metrics->track_property("dependency", tool_name); - } - Checks::exit_with_code(VCPKG_LINE_INFO, rc.exit_code); - } - - const fs::path actual_downloaded_path = Strings::trimmed(rc.output); - std::error_code ec; - const auto eq = fs::stdfs::equivalent(expected_downloaded_path, actual_downloaded_path, ec); - Checks::check_exit(VCPKG_LINE_INFO, - eq && !ec, - "Expected dependency downloaded path to be %s, but was %s", - expected_downloaded_path.u8string(), - actual_downloaded_path.u8string()); - return actual_downloaded_path; - } - - static fs::path get_cmake_path(const fs::path& downloads_folder, const fs::path& scripts_folder) - { - static constexpr std::array EXPECTED_VERSION = {3, 9, 3}; - static const std::wstring VERSION_CHECK_ARGUMENTS = L"--version"; - - const fs::path downloaded_copy = downloads_folder / "cmake-3.9.3-win32-x86" / "bin" / "cmake.exe"; - const std::vector from_path = Files::find_from_PATH(L"cmake"); - - std::vector candidate_paths; - candidate_paths.push_back(downloaded_copy); - candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); - candidate_paths.push_back(System::get_program_files_platform_bitness() / "CMake" / "bin" / "cmake.exe"); - candidate_paths.push_back(System::get_program_files_32_bit() / "CMake" / "bin"); - - const Optional path = - find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, EXPECTED_VERSION); - if (const auto p = path.get()) - { - return *p; - } - - return fetch_dependency(scripts_folder, L"cmake", downloaded_copy, EXPECTED_VERSION); - } - - fs::path get_nuget_path(const fs::path& downloads_folder, const fs::path& scripts_folder) - { - static constexpr std::array EXPECTED_VERSION = {4, 3, 0}; - static const std::wstring VERSION_CHECK_ARGUMENTS = Strings::WEMPTY; - - const fs::path downloaded_copy = downloads_folder / "nuget-4.3.0" / "nuget.exe"; - const std::vector from_path = Files::find_from_PATH(L"nuget"); - - std::vector candidate_paths; - candidate_paths.push_back(downloaded_copy); - candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); - - auto path = find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, EXPECTED_VERSION); - if (const auto p = path.get()) - { - return *p; - } - - return fetch_dependency(scripts_folder, L"nuget", downloaded_copy, EXPECTED_VERSION); - } - - fs::path get_git_path(const fs::path& downloads_folder, const fs::path& scripts_folder) - { - static constexpr std::array EXPECTED_VERSION = {2, 14, 1}; - static const std::wstring VERSION_CHECK_ARGUMENTS = L"--version"; - - const fs::path downloaded_copy = downloads_folder / "MinGit-2.14.1-32-bit" / "cmd" / "git.exe"; - const std::vector from_path = Files::find_from_PATH(L"git"); - - std::vector candidate_paths; - candidate_paths.push_back(downloaded_copy); - candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); - candidate_paths.push_back(System::get_program_files_platform_bitness() / "git" / "cmd" / "git.exe"); - candidate_paths.push_back(System::get_program_files_32_bit() / "git" / "cmd" / "git.exe"); - - const Optional path = - find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, EXPECTED_VERSION); - if (const auto p = path.get()) - { - return *p; - } - - return fetch_dependency(scripts_folder, L"git", downloaded_copy, EXPECTED_VERSION); - } - - static fs::path get_ifw_installerbase_path(const fs::path& downloads_folder, const fs::path& scripts_folder) - { - static constexpr std::array EXPECTED_VERSION = {3, 1, 81}; - static const std::wstring VERSION_CHECK_ARGUMENTS = L"--framework-version"; - - const fs::path downloaded_copy = - downloads_folder / "QtInstallerFramework-win-x86" / "bin" / "installerbase.exe"; - - std::vector candidate_paths; - candidate_paths.push_back(downloaded_copy); - // TODO: Uncomment later - // const std::vector from_path = Files::find_from_PATH(L"installerbase"); - // candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); - // candidate_paths.push_back(fs::path(System::get_environment_variable(L"HOMEDRIVE").value_or("C:")) / "Qt" / - // "Tools" / "QtInstallerFramework" / "3.1" / "bin" / "installerbase.exe"); - // candidate_paths.push_back(fs::path(System::get_environment_variable(L"HOMEDRIVE").value_or("C:")) / "Qt" / - // "QtIFW-3.1.0" / "bin" / "installerbase.exe"); - - const Optional path = - find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, EXPECTED_VERSION); - if (const auto p = path.get()) - { - return *p; - } - - return fetch_dependency(scripts_folder, L"installerbase", downloaded_copy, EXPECTED_VERSION); - } - - Expected VcpkgPaths::create(const fs::path& vcpkg_root_dir) - { - std::error_code ec; - const fs::path canonical_vcpkg_root_dir = fs::stdfs::canonical(vcpkg_root_dir, ec); - if (ec) - { - return ec; - } - - VcpkgPaths paths; - paths.root = canonical_vcpkg_root_dir; - - if (paths.root.empty()) - { - Metrics::g_metrics.lock()->track_property("error", "Invalid vcpkg root directory"); - Checks::exit_with_message(VCPKG_LINE_INFO, "Invalid vcpkg root directory: %s", paths.root.string()); - } - - paths.packages = paths.root / "packages"; - paths.buildtrees = paths.root / "buildtrees"; - paths.downloads = paths.root / "downloads"; - paths.ports = paths.root / "ports"; - paths.installed = paths.root / "installed"; - paths.triplets = paths.root / "triplets"; - paths.scripts = paths.root / "scripts"; - - paths.buildsystems = paths.scripts / "buildsystems"; - paths.buildsystems_msbuild_targets = paths.buildsystems / "msbuild" / "vcpkg.targets"; - - paths.vcpkg_dir = paths.installed / "vcpkg"; - paths.vcpkg_dir_status_file = paths.vcpkg_dir / "status"; - paths.vcpkg_dir_info = paths.vcpkg_dir / "info"; - paths.vcpkg_dir_updates = paths.vcpkg_dir / "updates"; - - paths.ports_cmake = paths.scripts / "ports.cmake"; - - return paths; - } - - fs::path VcpkgPaths::package_dir(const PackageSpec& spec) const { return this->packages / spec.dir(); } - - fs::path VcpkgPaths::port_dir(const PackageSpec& spec) const { return this->ports / spec.name(); } - fs::path VcpkgPaths::port_dir(const std::string& name) const { return this->ports / name; } - - fs::path VcpkgPaths::build_info_file_path(const PackageSpec& spec) const - { - return this->package_dir(spec) / "BUILD_INFO"; - } - - fs::path VcpkgPaths::listfile_path(const BinaryParagraph& pgh) const - { - return this->vcpkg_dir_info / (pgh.fullstem() + ".list"); - } - - bool VcpkgPaths::is_valid_triplet(const Triplet& t) const - { - for (auto&& path : get_filesystem().get_files_non_recursive(this->triplets)) - { - const 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 - return true; - } - } - return false; - } - - const fs::path& VcpkgPaths::get_cmake_exe() const - { - return this->cmake_exe.get_lazy([this]() { return get_cmake_path(this->downloads, this->scripts); }); - } - - const fs::path& VcpkgPaths::get_git_exe() const - { - return this->git_exe.get_lazy([this]() { return get_git_path(this->downloads, this->scripts); }); - } - - const fs::path& VcpkgPaths::get_nuget_exe() const - { - return this->nuget_exe.get_lazy([this]() { return get_nuget_path(this->downloads, this->scripts); }); - } - - const fs::path& VcpkgPaths::get_ifw_installerbase_exe() const - { - return this->ifw_installerbase_exe.get_lazy( - [this]() { return get_ifw_installerbase_path(this->downloads, this->scripts); }); - } - - const fs::path& VcpkgPaths::get_ifw_binarycreator_exe() const - { - return this->ifw_binarycreator_exe.get_lazy( - [this]() { return get_ifw_installerbase_exe().parent_path() / "binarycreator.exe"; }); - } - - const fs::path& VcpkgPaths::get_ifw_repogen_exe() const - { - return this->ifw_repogen_exe.get_lazy( - [this]() { return get_ifw_installerbase_exe().parent_path() / "repogen.exe"; }); - } - - struct VisualStudioInstance - { - fs::path root_path; - std::string version; - std::string release_type; - std::string preference_weight; // Mostly unused, just for verification that order is as intended - - std::string major_version() const { return version.substr(0, 2); } - }; - - static std::vector get_visual_studio_instances(const VcpkgPaths& paths) - { - const fs::path script = paths.scripts / "findVisualStudioInstallationInstances.ps1"; - const std::wstring cmd = System::create_powershell_script_cmd(script); - const System::ExitCodeAndOutput ec_data = System::cmd_execute_and_capture_output(cmd); - Checks::check_exit( - VCPKG_LINE_INFO, ec_data.exit_code == 0, "Could not run script to detect Visual Studio instances"); - - const std::vector instances_as_strings = Strings::split(ec_data.output, "\n"); - std::vector output; - for (const std::string& instance_as_string : instances_as_strings) - { - const std::vector split = Strings::split(instance_as_string, "::"); - output.push_back({split.at(3), split.at(2), split.at(1), split.at(0)}); - } - - return output; - } - - static std::vector find_toolset_instances(const VcpkgPaths& paths) - { - using CPU = System::CPUArchitecture; - - const auto& fs = paths.get_filesystem(); - - // Note: this will contain a mix of vcvarsall.bat locations and dumpbin.exe locations. - std::vector paths_examined; - - std::vector found_toolsets; - - const std::vector vs_instances = get_visual_studio_instances(paths); - const bool v140_is_available = Util::find_if(vs_instances, [&](const VisualStudioInstance& vs_instance) { - return vs_instance.major_version() == "14"; - }) != vs_instances.cend(); - - for (const VisualStudioInstance& vs_instance : vs_instances) - { - const std::string major_version = vs_instance.major_version(); - if (major_version == "15") - { - const fs::path vc_dir = vs_instance.root_path / "VC"; - - // Skip any instances that do not have vcvarsall. - const fs::path vcvarsall_dir = vc_dir / "Auxiliary" / "Build"; - const fs::path vcvarsall_bat = vcvarsall_dir / "vcvarsall.bat"; - paths_examined.push_back(vcvarsall_bat); - if (!fs.exists(vcvarsall_bat)) continue; - - // Get all supported architectures - std::vector supported_architectures; - if (fs.exists(vcvarsall_dir / "vcvars32.bat")) - supported_architectures.push_back({L"x86", CPU::X86, CPU::X86}); - if (fs.exists(vcvarsall_dir / "vcvars64.bat")) - supported_architectures.push_back({L"amd64", CPU::X64, CPU::X64}); - if (fs.exists(vcvarsall_dir / "vcvarsx86_amd64.bat")) - supported_architectures.push_back({L"x86_amd64", CPU::X86, CPU::X64}); - if (fs.exists(vcvarsall_dir / "vcvarsx86_arm.bat")) - supported_architectures.push_back({L"x86_arm", CPU::X86, CPU::ARM}); - if (fs.exists(vcvarsall_dir / "vcvarsamd64_x86.bat")) - supported_architectures.push_back({L"amd64_x86", CPU::X64, CPU::X86}); - if (fs.exists(vcvarsall_dir / "vcvarsamd64_arm.bat")) - supported_architectures.push_back({L"amd64_arm", CPU::X64, CPU::ARM}); - - // Locate the "best" MSVC toolchain version - const fs::path msvc_path = vc_dir / "Tools" / "MSVC"; - std::vector 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) { return left.filename() > right.filename(); }); - - for (const fs::path& subdir : msvc_subdirectories) - { - const fs::path dumpbin_path = subdir / "bin" / "HostX86" / "x86" / "dumpbin.exe"; - paths_examined.push_back(dumpbin_path); - if (fs.exists(dumpbin_path)) - { - found_toolsets.push_back(Toolset{ - vs_instance.root_path, dumpbin_path, vcvarsall_bat, {}, V_141, supported_architectures}); - - if (v140_is_available) - { - found_toolsets.push_back(Toolset{vs_instance.root_path, - dumpbin_path, - vcvarsall_bat, - {L"-vcvars_ver=14.0"}, - V_140, - supported_architectures}); - } - - break; - } - } - - continue; - } - - if (major_version == "14") - { - const fs::path vcvarsall_bat = vs_instance.root_path / "VC" / "vcvarsall.bat"; - - paths_examined.push_back(vcvarsall_bat); - if (fs.exists(vcvarsall_bat)) - { - const fs::path vs2015_dumpbin_exe = vs_instance.root_path / "VC" / "bin" / "dumpbin.exe"; - paths_examined.push_back(vs2015_dumpbin_exe); - - const fs::path vs2015_bin_dir = vcvarsall_bat.parent_path() / "bin"; - std::vector supported_architectures; - if (fs.exists(vs2015_bin_dir / "vcvars32.bat")) - supported_architectures.push_back({L"x86", CPU::X86, CPU::X86}); - if (fs.exists(vs2015_bin_dir / "amd64\\vcvars64.bat")) - supported_architectures.push_back({L"x64", CPU::X64, CPU::X64}); - if (fs.exists(vs2015_bin_dir / "x86_amd64\\vcvarsx86_amd64.bat")) - supported_architectures.push_back({L"x86_amd64", CPU::X86, CPU::X64}); - if (fs.exists(vs2015_bin_dir / "x86_arm\\vcvarsx86_arm.bat")) - supported_architectures.push_back({L"x86_arm", CPU::X86, CPU::ARM}); - if (fs.exists(vs2015_bin_dir / "amd64_x86\\vcvarsamd64_x86.bat")) - supported_architectures.push_back({L"amd64_x86", CPU::X64, CPU::X86}); - if (fs.exists(vs2015_bin_dir / "amd64_arm\\vcvarsamd64_arm.bat")) - supported_architectures.push_back({L"amd64_arm", CPU::X64, CPU::ARM}); - - if (fs.exists(vs2015_dumpbin_exe)) - { - found_toolsets.push_back({vs_instance.root_path, - vs2015_dumpbin_exe, - vcvarsall_bat, - {}, - V_140, - supported_architectures}); - } - } - } - } - - if (found_toolsets.empty()) - { - System::println(System::Color::error, "Could not locate a complete toolset."); - System::println("The following paths were examined:"); - for (const fs::path& path : paths_examined) - { - System::println(" %s", path.u8string()); - } - Checks::exit_fail(VCPKG_LINE_INFO); - } - - return found_toolsets; - } - - const Toolset& VcpkgPaths::get_toolset(const Optional& toolset_version, - const Optional& visual_studio_path) const - { - // Invariant: toolsets are non-empty and sorted with newest at back() - const std::vector& vs_toolsets = - this->toolsets.get_lazy([this]() { return find_toolset_instances(*this); }); - - std::vector candidates = Util::element_pointers(vs_toolsets); - const auto tsv = toolset_version.get(); - const auto vsp = visual_studio_path.get(); - - if (tsv && vsp) - { - const std::wstring w_toolset_version = Strings::to_utf16(*tsv); - const fs::path vs_root_path = *vsp; - Util::stable_keep_if(candidates, [&](const Toolset* t) { - return w_toolset_version == t->version && vs_root_path == t->visual_studio_root_path; - }); - Checks::check_exit(VCPKG_LINE_INFO, - !candidates.empty(), - "Could not find Visual Studio instace at %s with %s toolset.", - vs_root_path.generic_string(), - *tsv); - - Checks::check_exit(VCPKG_LINE_INFO, candidates.size() == 1); - return *candidates.back(); - } - - if (tsv) - { - const std::wstring w_toolset_version = Strings::to_utf16(*tsv); - Util::stable_keep_if(candidates, [&](const Toolset* t) { return w_toolset_version == t->version; }); - Checks::check_exit( - VCPKG_LINE_INFO, !candidates.empty(), "Could not find Visual Studio instace with %s toolset.", *tsv); - } - - if (vsp) - { - const fs::path vs_root_path = *vsp; - Util::stable_keep_if(candidates, - [&](const Toolset* t) { return vs_root_path == t->visual_studio_root_path; }); - Checks::check_exit(VCPKG_LINE_INFO, - !candidates.empty(), - "Could not find Visual Studio instace at %s.", - vs_root_path.generic_string()); - } - - return *candidates.front(); - } - - Files::Filesystem& VcpkgPaths::get_filesystem() const { return Files::get_real_filesystem(); } -} diff --git a/toolsrc/src/VersionT.cpp b/toolsrc/src/VersionT.cpp deleted file mode 100644 index 738d2ce88..000000000 --- a/toolsrc/src/VersionT.cpp +++ /dev/null @@ -1,19 +0,0 @@ -#include "pch.h" - -#include "VersionT.h" -#include "vcpkg_Strings.h" - -namespace vcpkg -{ - VersionT::VersionT() : value("0.0.0") {} - VersionT::VersionT(const std::string& value) : value(value) {} - std::string VersionT::to_string() const { return value; } - bool operator==(const VersionT& left, const VersionT& right) { return left.value == right.value; } - bool operator!=(const VersionT& left, const VersionT& right) { return left.value != right.value; } - std::string to_printf_arg(const VersionT& version) { return version.value; } - - VersionDiff::VersionDiff() : left(), right() {} - VersionDiff::VersionDiff(const VersionT& left, const VersionT& right) : left(left), right(right) {} - - std::string VersionDiff::to_string() const { return Strings::format("%s -> %s", left.value, right.value); } -} diff --git a/toolsrc/src/coff_file_reader.cpp b/toolsrc/src/coff_file_reader.cpp deleted file mode 100644 index bb3a6cefd..000000000 --- a/toolsrc/src/coff_file_reader.cpp +++ /dev/null @@ -1,308 +0,0 @@ -#include "pch.h" - -#include "coff_file_reader.h" -#include "vcpkg_Checks.h" - -using namespace std; - -namespace vcpkg::CoffFileReader -{ - template - static T reinterpret_bytes(const char* data) - { - return (*reinterpret_cast(&data[0])); - } - - template - static T read_value_from_stream(fstream& fs) - { - T data; - fs.read(reinterpret_cast(&data), sizeof data); - return data; - } - - template - static T peek_value_from_stream(fstream& fs) - { - const fpos_t original_pos = fs.tellg().seekpos(); - T data; - fs.read(reinterpret_cast(&data), sizeof data); - fs.seekg(original_pos); - return data; - } - - static void verify_equal_strings( - const LineInfo& line_info, const char* expected, const char* actual, int size, const char* label) - { - Checks::check_exit(line_info, - memcmp(expected, actual, size) == 0, - "Incorrect string (%s) found. Expected: (%s) but found (%s)", - label, - expected, - actual); - } - - static void read_and_verify_PE_signature(fstream& fs) - { - static const size_t OFFSET_TO_PE_SIGNATURE_OFFSET = 0x3c; - - static const char* PE_SIGNATURE = "PE\0\0"; - static const size_t PE_SIGNATURE_SIZE = 4; - - fs.seekg(OFFSET_TO_PE_SIGNATURE_OFFSET, ios_base::beg); - const int32_t offset_to_PE_signature = read_value_from_stream(fs); - - fs.seekg(offset_to_PE_signature); - char signature[PE_SIGNATURE_SIZE]; - fs.read(signature, PE_SIGNATURE_SIZE); - verify_equal_strings(VCPKG_LINE_INFO, PE_SIGNATURE, signature, PE_SIGNATURE_SIZE, "PE_SIGNATURE"); - fs.seekg(offset_to_PE_signature + PE_SIGNATURE_SIZE, ios_base::beg); - } - - static fpos_t align_to_size(const uint64_t unaligned, const uint64_t alignment_size) - { - fpos_t aligned = unaligned - 1; - aligned /= alignment_size; - aligned += 1; - aligned *= alignment_size; - return aligned; - } - - struct CoffFileHeader - { - static const size_t HEADER_SIZE = 20; - - static CoffFileHeader read(fstream& fs) - { - CoffFileHeader ret; - ret.data.resize(HEADER_SIZE); - fs.read(&ret.data[0], HEADER_SIZE); - return ret; - } - - MachineType machine_type() const - { - static const size_t MACHINE_TYPE_OFFSET = 0; - static const size_t MACHINE_TYPE_SIZE = 2; - - std::string machine_field_as_string = data.substr(MACHINE_TYPE_OFFSET, MACHINE_TYPE_SIZE); - const uint16_t machine = reinterpret_bytes(machine_field_as_string.c_str()); - return to_machine_type(machine); - } - - private: - std::string data; - }; - - struct ArchiveMemberHeader - { - static const size_t HEADER_SIZE = 60; - - static ArchiveMemberHeader read(fstream& fs) - { - static const size_t HEADER_END_OFFSET = 58; - static const char* HEADER_END = "`\n"; - static const size_t HEADER_END_SIZE = 2; - - ArchiveMemberHeader ret; - ret.data.resize(HEADER_SIZE); - fs.read(&ret.data[0], HEADER_SIZE); - - if (ret.data[0] != '\0') // Due to freeglut. github issue #223 - { - const std::string header_end = ret.data.substr(HEADER_END_OFFSET, HEADER_END_SIZE); - verify_equal_strings( - VCPKG_LINE_INFO, HEADER_END, header_end.c_str(), HEADER_END_SIZE, "LIB HEADER_END"); - } - - return ret; - } - - std::string name() const - { - static const size_t HEADER_NAME_OFFSET = 0; - static const size_t HEADER_NAME_SIZE = 16; - return data.substr(HEADER_NAME_OFFSET, HEADER_NAME_SIZE); - } - - uint64_t member_size() const - { - static const size_t ALIGNMENT_SIZE = 2; - - static const size_t HEADER_SIZE_OFFSET = 48; - static const size_t HEADER_SIZE_FIELD_SIZE = 10; - const std::string as_string = data.substr(HEADER_SIZE_OFFSET, HEADER_SIZE_FIELD_SIZE); - // This is in ASCII decimal representation - const uint64_t value = std::strtoull(as_string.c_str(), nullptr, 10); - - const uint64_t aligned = align_to_size(value, ALIGNMENT_SIZE); - return aligned; - } - - std::string data; - }; - - struct OffsetsArray - { - static OffsetsArray read(fstream& fs, const uint32_t offset_count) - { - static const size_t OFFSET_WIDTH = 4; - - std::string raw_offsets; - const size_t raw_offset_size = offset_count * OFFSET_WIDTH; - raw_offsets.resize(raw_offset_size); - fs.read(&raw_offsets[0], raw_offset_size); - - OffsetsArray ret; - for (uint32_t i = 0; i < offset_count; ++i) - { - const std::string value_as_string = raw_offsets.substr(OFFSET_WIDTH * i, OFFSET_WIDTH * (i + 1)); - const uint32_t value = reinterpret_bytes(value_as_string.c_str()); - - // Ignore offsets that point to offset 0. See vcpkg github #223 #288 #292 - if (value != 0) - { - ret.data.push_back(value); - } - } - - // Sort the offsets, because it is possible for them to be unsorted. See vcpkg github #292 - std::sort(ret.data.begin(), ret.data.end()); - return ret; - } - - std::vector data; - }; - - struct ImportHeader - { - static const size_t HEADER_SIZE = 20; - - static ImportHeader read(fstream& fs) - { - static const size_t SIG1_OFFSET = 0; - static const uint16_t SIG1 = static_cast(MachineType::UNKNOWN); - static const size_t SIG1_SIZE = 2; - - static const size_t SIG2_OFFSET = 2; - static const uint16_t SIG2 = 0xFFFF; - static const size_t SIG2_SIZE = 2; - - ImportHeader ret; - ret.data.resize(HEADER_SIZE); - fs.read(&ret.data[0], HEADER_SIZE); - - const std::string sig1_as_string = ret.data.substr(SIG1_OFFSET, SIG1_SIZE); - const uint16_t sig1 = reinterpret_bytes(sig1_as_string.c_str()); - Checks::check_exit(VCPKG_LINE_INFO, sig1 == SIG1, "Sig1 was incorrect. Expected %s but got %s", SIG1, sig1); - - const std::string sig2_as_string = ret.data.substr(SIG2_OFFSET, SIG2_SIZE); - const uint16_t sig2 = reinterpret_bytes(sig2_as_string.c_str()); - Checks::check_exit(VCPKG_LINE_INFO, sig2 == SIG2, "Sig2 was incorrect. Expected %s but got %s", SIG2, sig2); - - return ret; - } - - MachineType machine_type() const - { - static const size_t MACHINE_TYPE_OFFSET = 6; - static const size_t MACHINE_TYPE_SIZE = 2; - - std::string machine_field_as_string = data.substr(MACHINE_TYPE_OFFSET, MACHINE_TYPE_SIZE); - const uint16_t machine = reinterpret_bytes(machine_field_as_string.c_str()); - return to_machine_type(machine); - } - - private: - std::string data; - }; - - static void read_and_verify_archive_file_signature(fstream& fs) - { - static const char* FILE_START = "!\n"; - static const size_t FILE_START_SIZE = 8; - - fs.seekg(fs.beg); - - char file_start[FILE_START_SIZE]; - fs.read(file_start, FILE_START_SIZE); - verify_equal_strings(VCPKG_LINE_INFO, FILE_START, file_start, FILE_START_SIZE, "LIB FILE_START"); - } - - DllInfo read_dll(const fs::path& path) - { - std::fstream fs(path, std::ios::in | std::ios::binary | std::ios::ate); - Checks::check_exit(VCPKG_LINE_INFO, fs.is_open(), "Could not open file %s for reading", path.generic_string()); - - read_and_verify_PE_signature(fs); - CoffFileHeader header = CoffFileHeader::read(fs); - const MachineType machine = header.machine_type(); - return {machine}; - } - - struct Marker - { - void set_to_offset(const fpos_t position) { this->m_absolute_position = position; } - - void set_to_current_pos(fstream& fs) { this->m_absolute_position = fs.tellg().seekpos(); } - - void seek_to_marker(fstream& fs) const { fs.seekg(this->m_absolute_position, ios_base::beg); } - - void advance_by(const uint64_t offset) { this->m_absolute_position += offset; } - - private: - fpos_t m_absolute_position = 0; - }; - - LibInfo read_lib(const fs::path& path) - { - std::fstream fs(path, std::ios::in | std::ios::binary | std::ios::ate); - Checks::check_exit(VCPKG_LINE_INFO, fs.is_open(), "Could not open file %s for reading", path.generic_string()); - - read_and_verify_archive_file_signature(fs); - - Marker marker; - marker.set_to_current_pos(fs); - - // First Linker Member - const ArchiveMemberHeader first_linker_member_header = ArchiveMemberHeader::read(fs); - Checks::check_exit(VCPKG_LINE_INFO, - first_linker_member_header.name().substr(0, 2) == "/ ", - "Could not find proper first linker member"); - marker.advance_by(ArchiveMemberHeader::HEADER_SIZE + first_linker_member_header.member_size()); - marker.seek_to_marker(fs); - - const ArchiveMemberHeader second_linker_member_header = ArchiveMemberHeader::read(fs); - Checks::check_exit(VCPKG_LINE_INFO, - second_linker_member_header.name().substr(0, 2) == "/ ", - "Could not find proper second linker member"); - // The first 4 bytes contains the number of archive members - const uint32_t archive_member_count = read_value_from_stream(fs); - const OffsetsArray offsets = OffsetsArray::read(fs, archive_member_count); - marker.advance_by(ArchiveMemberHeader::HEADER_SIZE + second_linker_member_header.member_size()); - marker.seek_to_marker(fs); - - const bool hasLongnameMemberHeader = peek_value_from_stream(fs) == 0x2F2F; - if (hasLongnameMemberHeader) - { - const ArchiveMemberHeader longnames_member_header = ArchiveMemberHeader::read(fs); - marker.advance_by(ArchiveMemberHeader::HEADER_SIZE + longnames_member_header.member_size()); - marker.seek_to_marker(fs); - } - - std::set machine_types; - // Next we have the obj and pseudo-object files - for (const uint32_t offset : offsets.data) - { - marker.set_to_offset(offset + ArchiveMemberHeader::HEADER_SIZE); // Skip the header, no need to read it. - marker.seek_to_marker(fs); - const uint16_t first_two_bytes = peek_value_from_stream(fs); - const bool isImportHeader = to_machine_type(first_two_bytes) == MachineType::UNKNOWN; - const MachineType machine = - isImportHeader ? ImportHeader::read(fs).machine_type() : CoffFileHeader::read(fs).machine_type(); - machine_types.insert(machine); - } - - return {std::vector(machine_types.cbegin(), machine_types.cend())}; - } -} diff --git a/toolsrc/src/commands_autocomplete.cpp b/toolsrc/src/commands_autocomplete.cpp deleted file mode 100644 index 3963f904b..000000000 --- a/toolsrc/src/commands_autocomplete.cpp +++ /dev/null @@ -1,79 +0,0 @@ -#include "pch.h" - -#include "Paragraphs.h" -#include "SortedVector.h" -#include "vcpkg_Commands.h" -#include "vcpkg_Maps.h" -#include "vcpkg_System.h" -#include "vcpkglib.h" - -namespace vcpkg::Commands::Autocomplete -{ - std::vector autocomplete_install( - const std::vector>& source_paragraphs, const std::string& start_with) - { - std::vector results; - const auto& istartswith = Strings::case_insensitive_ascii_starts_with; - - for (const auto& source_control_file : source_paragraphs) - { - auto&& sp = *source_control_file->core_paragraph; - - if (istartswith(sp.name, start_with)) - { - results.push_back(sp.name); - } - } - return results; - } - - std::vector autocomplete_remove(std::vector installed_packages, - const std::string& start_with) - { - std::vector results; - const auto& istartswith = Strings::case_insensitive_ascii_starts_with; - - for (const auto& installed_package : installed_packages) - { - auto sp = installed_package->package.displayname(); - - if (istartswith(sp, start_with)) - { - results.push_back(sp); - } - } - return results; - } - - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) - { - static const std::string EXAMPLE = - Strings::format("The argument should be a command line to autocomplete.\n%s", - Commands::Help::create_example_string("autocomplete install z")); - - args.check_min_arg_count(1, EXAMPLE); - args.check_max_arg_count(2, EXAMPLE); - args.check_and_get_optional_command_arguments({}); - - const std::string requested_command = args.command_arguments.at(0); - const std::string start_with = - args.command_arguments.size() > 1 ? args.command_arguments.at(1) : Strings::EMPTY; - std::vector results; - if (requested_command == "install") - { - auto sources_and_errors = Paragraphs::try_load_all_ports(paths.get_filesystem(), paths.ports); - auto& source_paragraphs = sources_and_errors.paragraphs; - - results = autocomplete_install(source_paragraphs, start_with); - } - else if (requested_command == "remove") - { - const StatusParagraphs status_db = database_load_check(paths); - std::vector installed_packages = get_installed_ports(status_db); - results = autocomplete_remove(installed_packages, start_with); - } - - System::println(Strings::join(" ", results)); - Checks::exit_success(VCPKG_LINE_INFO); - } -} diff --git a/toolsrc/src/commands_available_commands.cpp b/toolsrc/src/commands_available_commands.cpp deleted file mode 100644 index d3280e6d7..000000000 --- a/toolsrc/src/commands_available_commands.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#include "pch.h" - -#include "vcpkg_Commands.h" - -namespace vcpkg::Commands -{ - const std::vector>& get_available_commands_type_a() - { - static std::vector> t = { - {"install", &Install::perform_and_exit}, - {"ci", &CI::perform_and_exit}, - {"remove", &Remove::perform_and_exit}, - {"build", &BuildCommand::perform_and_exit}, - {"env", &Env::perform_and_exit}, - {"build-external", &BuildExternal::perform_and_exit}, - {"export", &Export::perform_and_exit}, - }; - return t; - } - - const std::vector>& get_available_commands_type_b() - { - static std::vector> t = { - {"/?", &Help::perform_and_exit}, - {"help", &Help::perform_and_exit}, - {"search", &Search::perform_and_exit}, - {"list", &List::perform_and_exit}, - {"integrate", &Integrate::perform_and_exit}, - {"owns", &Owns::perform_and_exit}, - {"update", &Update::perform_and_exit}, - {"depend-info", &DependInfo::perform_and_exit}, - {"edit", &Edit::perform_and_exit}, - {"create", &Create::perform_and_exit}, - {"import", &Import::perform_and_exit}, - {"cache", &Cache::perform_and_exit}, - {"portsdiff", &PortsDiff::perform_and_exit}, - {"autocomplete", &Autocomplete::perform_and_exit}}; - return t; - } - - const std::vector>& get_available_commands_type_c() - { - static std::vector> t = { - {"version", &Version::perform_and_exit}, - {"contact", &Contact::perform_and_exit}, - {"hash", &Hash::perform_and_exit}, - }; - return t; - } -} diff --git a/toolsrc/src/commands_build.cpp b/toolsrc/src/commands_build.cpp deleted file mode 100644 index a69958058..000000000 --- a/toolsrc/src/commands_build.cpp +++ /dev/null @@ -1,102 +0,0 @@ -#include "pch.h" - -#include "Paragraphs.h" -#include "PostBuildLint.h" -#include "StatusParagraphs.h" -#include "vcpkg_Commands.h" -#include "vcpkg_Dependencies.h" -#include "vcpkg_Enums.h" -#include "vcpkg_Input.h" -#include "vcpkg_System.h" -#include "vcpkglib.h" - -using vcpkg::Build::BuildResult; -using vcpkg::Parse::ParseControlErrorInfo; -using vcpkg::Parse::ParseExpected; - -namespace vcpkg::Commands::BuildCommand -{ - using Dependencies::InstallPlanAction; - using Dependencies::InstallPlanType; - - static const std::string OPTION_CHECKS_ONLY = "--checks-only"; - - void perform_and_exit(const FullPackageSpec& full_spec, - const fs::path& port_dir, - const std::unordered_set& options, - const VcpkgPaths& paths) - { - const PackageSpec& spec = full_spec.package_spec; - if (options.find(OPTION_CHECKS_ONLY) != options.end()) - { - const auto pre_build_info = Build::PreBuildInfo::from_triplet_file(paths, spec.triplet()); - const auto build_info = Build::read_build_info(paths.get_filesystem(), paths.build_info_file_path(spec)); - const size_t error_count = PostBuildLint::perform_all_checks(spec, paths, pre_build_info, build_info); - Checks::check_exit(VCPKG_LINE_INFO, error_count == 0); - Checks::exit_success(VCPKG_LINE_INFO); - } - - const ParseExpected source_control_file = - Paragraphs::try_load_port(paths.get_filesystem(), port_dir); - - if (!source_control_file.has_value()) - { - print_error_message(source_control_file.error()); - Checks::exit_fail(VCPKG_LINE_INFO); - } - - for (const std::string& str : full_spec.features) - { - System::println("%s \n", str); - } - const auto& scf = source_control_file.value_or_exit(VCPKG_LINE_INFO); - Checks::check_exit(VCPKG_LINE_INFO, - spec.name() == scf->core_paragraph->name, - "The Name: field inside the CONTROL does not match the port directory: '%s' != '%s'", - scf->core_paragraph->name, - spec.name()); - - const StatusParagraphs status_db = database_load_check(paths); - const Build::BuildPackageOptions build_package_options{Build::UseHeadVersion::NO, Build::AllowDownloads::YES}; - - const Build::BuildPackageConfig build_config{ - *scf->core_paragraph, spec.triplet(), paths.port_dir(spec), build_package_options}; - - const auto result = Build::build_package(paths, build_config, status_db); - if (result.code == BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES) - { - System::println(System::Color::error, - "The build command requires all dependencies to be already installed."); - System::println("The following dependencies are missing:"); - System::println(); - for (const auto& p : result.unmet_dependencies) - { - System::println(" %s", p); - } - System::println(); - Checks::exit_fail(VCPKG_LINE_INFO); - } - - if (result.code != BuildResult::SUCCEEDED) - { - System::println(System::Color::error, Build::create_error_message(result.code, spec)); - System::println(Build::create_user_troubleshooting_message(spec)); - Checks::exit_fail(VCPKG_LINE_INFO); - } - - Checks::exit_success(VCPKG_LINE_INFO); - } - - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) - { - static const std::string EXAMPLE = Commands::Help::create_example_string("build zlib:x64-windows"); - // Build only takes a single package and all dependencies must already be installed - args.check_exact_arg_count(1, EXAMPLE); - const std::string command_argument = args.command_arguments.at(0); - const FullPackageSpec spec = Input::check_and_get_full_package_spec(command_argument, default_triplet, EXAMPLE); - Input::check_triplet(spec.package_spec.triplet(), paths); - const std::unordered_set options = - args.check_and_get_optional_command_arguments({OPTION_CHECKS_ONLY}); - perform_and_exit(spec, paths.port_dir(spec.package_spec), options, paths); - } -} diff --git a/toolsrc/src/commands_build_external.cpp b/toolsrc/src/commands_build_external.cpp deleted file mode 100644 index 7e85f2250..000000000 --- a/toolsrc/src/commands_build_external.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include "pch.h" - -#include "vcpkg_Commands.h" -#include "vcpkg_Input.h" - -namespace vcpkg::Commands::BuildExternal -{ - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) - { - static const std::string EXAMPLE = - Commands::Help::create_example_string(R"(build_external zlib2 C:\path\to\dir\with\controlfile\)"); - args.check_exact_arg_count(2, EXAMPLE); - const FullPackageSpec spec = - Input::check_and_get_full_package_spec(args.command_arguments.at(0), default_triplet, EXAMPLE); - Input::check_triplet(spec.package_spec.triplet(), paths); - const std::unordered_set options = args.check_and_get_optional_command_arguments({}); - - const fs::path port_dir = args.command_arguments.at(1); - BuildCommand::perform_and_exit(spec, port_dir, options, paths); - } -} diff --git a/toolsrc/src/commands_cache.cpp b/toolsrc/src/commands_cache.cpp deleted file mode 100644 index 5b65b197f..000000000 --- a/toolsrc/src/commands_cache.cpp +++ /dev/null @@ -1,68 +0,0 @@ -#include "pch.h" - -#include "BinaryParagraph.h" -#include "Paragraphs.h" -#include "vcpkg_Commands.h" -#include "vcpkg_Files.h" -#include "vcpkg_System.h" - -namespace vcpkg::Commands::Cache -{ - static std::vector read_all_binary_paragraphs(const VcpkgPaths& paths) - { - std::vector output; - for (auto&& path : paths.get_filesystem().get_files_non_recursive(paths.packages)) - { - const Expected> pghs = - Paragraphs::get_single_paragraph(paths.get_filesystem(), path / "CONTROL"); - if (const auto p = pghs.get()) - { - const BinaryParagraph binary_paragraph = BinaryParagraph(*p); - output.push_back(binary_paragraph); - } - } - - return output; - } - - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) - { - static const std::string EXAMPLE = Strings::format( - "The argument should be a substring to search for, or no argument to display all cached libraries.\n%s", - Commands::Help::create_example_string("cache png")); - args.check_max_arg_count(1, EXAMPLE); - args.check_and_get_optional_command_arguments({}); - - const std::vector binary_paragraphs = read_all_binary_paragraphs(paths); - if (binary_paragraphs.empty()) - { - System::println("No packages are cached."); - Checks::exit_success(VCPKG_LINE_INFO); - } - - if (args.command_arguments.size() == 0) - { - for (const BinaryParagraph& binary_paragraph : binary_paragraphs) - { - const std::string displayname = binary_paragraph.displayname(); - System::println(displayname); - } - } - else - { - // At this point there is 1 argument - for (const BinaryParagraph& binary_paragraph : binary_paragraphs) - { - const std::string displayname = binary_paragraph.displayname(); - if (Strings::case_insensitive_ascii_find(displayname, args.command_arguments[0]) == displayname.end()) - { - continue; - } - - System::println(displayname); - } - } - - Checks::exit_success(VCPKG_LINE_INFO); - } -} diff --git a/toolsrc/src/commands_ci.cpp b/toolsrc/src/commands_ci.cpp deleted file mode 100644 index 75ff65556..000000000 --- a/toolsrc/src/commands_ci.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include "pch.h" - -#include "Paragraphs.h" -#include "vcpkg_Build.h" -#include "vcpkg_Chrono.h" -#include "vcpkg_Commands.h" -#include "vcpkg_Dependencies.h" -#include "vcpkg_Files.h" -#include "vcpkg_Input.h" -#include "vcpkg_System.h" -#include "vcpkg_Util.h" -#include "vcpkglib.h" - -namespace vcpkg::Commands::CI -{ - using Build::BuildResult; - using Dependencies::InstallPlanAction; - using Dependencies::InstallPlanType; - - static std::vector load_all_package_specs(Files::Filesystem& fs, - const fs::path& ports_directory, - const Triplet& triplet) - { - auto ports = Paragraphs::load_all_ports(fs, ports_directory); - return Util::fmap(ports, [&](auto&& control_file) -> PackageSpec { - return PackageSpec::from_name_and_triplet(control_file->core_paragraph->name, triplet) - .value_or_exit(VCPKG_LINE_INFO); - }); - } - - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) - { - static const std::string EXAMPLE = Commands::Help::create_example_string("ci x64-windows"); - args.check_max_arg_count(1, EXAMPLE); - 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 specs = load_all_package_specs(paths.get_filesystem(), paths.ports, triplet); - - StatusParagraphs status_db = database_load_check(paths); - const auto& paths_port_file = Dependencies::PathsPortFile(paths); - std::vector install_plan = - Dependencies::create_install_plan(paths_port_file, specs, status_db); - Checks::check_exit(VCPKG_LINE_INFO, !install_plan.empty(), "Install plan cannot be empty"); - - const Build::BuildPackageOptions install_plan_options = {Build::UseHeadVersion::NO, Build::AllowDownloads::YES}; - - const std::vector action_plan = - Util::fmap(install_plan, [](InstallPlanAction& install_action) { - return Dependencies::AnyAction(std::move(install_action)); - }); - - Install::perform_and_exit( - action_plan, install_plan_options, Install::KeepGoing::YES, Install::PrintSummary::YES, paths, status_db); - - Checks::exit_success(VCPKG_LINE_INFO); - } -} diff --git a/toolsrc/src/commands_contact.cpp b/toolsrc/src/commands_contact.cpp deleted file mode 100644 index 8374350ee..000000000 --- a/toolsrc/src/commands_contact.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include "pch.h" - -#include "vcpkg_Commands.h" -#include "vcpkg_System.h" - -namespace vcpkg::Commands::Contact -{ - const std::string& email() - { - static const std::string S_EMAIL = R"(vcpkg@microsoft.com)"; - return S_EMAIL; - } - - void perform_and_exit(const VcpkgCmdArguments& args) - { - args.check_exact_arg_count(0); - args.check_and_get_optional_command_arguments({}); - - System::println("Send an email to %s with any feedback.", email()); - Checks::exit_success(VCPKG_LINE_INFO); - } -} diff --git a/toolsrc/src/commands_create.cpp b/toolsrc/src/commands_create.cpp deleted file mode 100644 index 6898f7399..000000000 --- a/toolsrc/src/commands_create.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#include "pch.h" - -#include "vcpkg_Commands.h" -#include "vcpkg_Files.h" -#include "vcpkg_System.h" -#include "vcpkglib.h" - -namespace vcpkg::Commands::Create -{ - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) - { - static const std::string EXAMPLE = Commands::Help::create_example_string( - R"###(create zlib2 http://zlib.net/zlib1211.zip "zlib1211-2.zip")###"); - args.check_max_arg_count(3, EXAMPLE); - args.check_min_arg_count(2, EXAMPLE); - args.check_and_get_optional_command_arguments({}); - const std::string port_name = args.command_arguments.at(0); - const std::string url = args.command_arguments.at(1); - - const fs::path& cmake_exe = paths.get_cmake_exe(); - - std::vector cmake_args{{L"CMD", L"CREATE"}, {L"PORT", port_name}, {L"URL", url}}; - - if (args.command_arguments.size() >= 3) - { - const std::string& zip_file_name = args.command_arguments.at(2); - Checks::check_exit(VCPKG_LINE_INFO, - !Files::has_invalid_chars_for_filesystem(zip_file_name), - R"(Filename cannot contain invalid chars %s, but was %s)", - Files::FILESYSTEM_INVALID_CHARACTERS, - zip_file_name); - cmake_args.push_back({L"FILENAME", zip_file_name}); - } - - const std::wstring cmd_launch_cmake = make_cmake_cmd(cmake_exe, paths.ports_cmake, cmake_args); - Checks::exit_with_code(VCPKG_LINE_INFO, System::cmd_execute_clean(cmd_launch_cmake)); - } -} diff --git a/toolsrc/src/commands_depends.cpp b/toolsrc/src/commands_depends.cpp deleted file mode 100644 index 17cd9c881..000000000 --- a/toolsrc/src/commands_depends.cpp +++ /dev/null @@ -1,55 +0,0 @@ -#include "pch.h" - -#include "Paragraphs.h" -#include "vcpkg_Commands.h" -#include "vcpkg_Strings.h" -#include "vcpkg_System.h" -#include "vcpkg_Util.h" - -namespace vcpkg::Commands::DependInfo -{ - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) - { - static const std::string EXAMPLE = Commands::Help::create_example_string(R"###(depend-info [pat])###"); - args.check_max_arg_count(1, EXAMPLE); - args.check_and_get_optional_command_arguments({}); - - std::vector> source_control_files = - Paragraphs::load_all_ports(paths.get_filesystem(), paths.ports); - - if (args.command_arguments.size() == 1) - { - const std::string filter = args.command_arguments.at(0); - - Util::erase_remove_if(source_control_files, - [&](const std::unique_ptr& source_control_file) { - - const SourceParagraph& source_paragraph = *source_control_file->core_paragraph; - - if (Strings::case_insensitive_ascii_contains(source_paragraph.name, filter)) - { - return false; - } - - for (const Dependency& dependency : source_paragraph.depends) - { - if (Strings::case_insensitive_ascii_contains(dependency.name(), filter)) - { - return false; - } - } - - return true; - }); - } - - for (auto&& source_control_file : source_control_files) - { - const SourceParagraph& source_paragraph = *source_control_file->core_paragraph; - const auto s = Strings::join(", ", source_paragraph.depends, [](const Dependency& d) { return d.name(); }); - System::println("%s: %s", source_paragraph.name, s); - } - - Checks::exit_success(VCPKG_LINE_INFO); - } -} diff --git a/toolsrc/src/commands_edit.cpp b/toolsrc/src/commands_edit.cpp deleted file mode 100644 index 823c87534..000000000 --- a/toolsrc/src/commands_edit.cpp +++ /dev/null @@ -1,86 +0,0 @@ -#include "pch.h" - -#include "vcpkg_Commands.h" -#include "vcpkg_Input.h" -#include "vcpkg_System.h" - -namespace vcpkg::Commands::Edit -{ - static std::vector find_from_registry() - { - static const std::array REGKEYS = { - LR"(SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{C26E74D1-022E-4238-8B9D-1E7564A36CC9}_is1)", - LR"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{1287CAD5-7C8D-410D-88B9-0D1EE4A83FF2}_is1)", - LR"(SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{F8A2A208-72B3-4D61-95FC-8A65D340689B}_is1)", - }; - - std::vector output; - for (auto&& keypath : REGKEYS) - { - const Optional code_installpath = - System::get_registry_string(HKEY_LOCAL_MACHINE, keypath, L"InstallLocation"); - if (const auto c = code_installpath.get()) - { - const fs::path install_path = fs::path(*c); - output.push_back(install_path / "Code - Insiders.exe"); - output.push_back(install_path / "Code.exe"); - } - } - return output; - } - - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) - { - static const std::string OPTION_BUILDTREES = "--buildtrees"; - - static const fs::path VS_CODE_INSIDERS = fs::path{"Microsoft VS Code Insiders"} / "Code - Insiders.exe"; - static const fs::path VS_CODE = fs::path{"Microsoft VS Code"} / "Code.exe"; - - auto& fs = paths.get_filesystem(); - - static const std::string EXAMPLE = Commands::Help::create_example_string("edit zlib"); - args.check_exact_arg_count(1, EXAMPLE); - const std::unordered_set options = - args.check_and_get_optional_command_arguments({OPTION_BUILDTREES}); - 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); - - std::vector candidate_paths; - const std::vector from_path = Files::find_from_PATH(L"EDITOR"); - candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); - candidate_paths.push_back(System::get_program_files_platform_bitness() / VS_CODE_INSIDERS); - candidate_paths.push_back(System::get_program_files_32_bit() / VS_CODE_INSIDERS); - candidate_paths.push_back(System::get_program_files_platform_bitness() / VS_CODE); - candidate_paths.push_back(System::get_program_files_32_bit() / VS_CODE); - - const std::vector from_registry = find_from_registry(); - candidate_paths.insert(candidate_paths.end(), from_registry.cbegin(), from_registry.cend()); - - auto it = Util::find_if(candidate_paths, [&](const fs::path& p) { return fs.exists(p); }); - if (it == candidate_paths.cend()) - { - System::println(System::Color::error, - "Error: Visual Studio Code was not found and the environment variable EDITOR is not set."); - System::println("The following paths were examined:"); - Files::print_paths(candidate_paths); - System::println("You can also set the environmental variable EDITOR to your editor of choice."); - Checks::exit_fail(VCPKG_LINE_INFO); - } - - const fs::path env_editor = *it; - if (options.find(OPTION_BUILDTREES) != options.cend()) - { - const auto buildtrees_current_dir = paths.buildtrees / port_name; - - const std::wstring cmd_line = - Strings::wformat(LR"("%s" "%s" -n)", env_editor, buildtrees_current_dir.native()); - Checks::exit_with_code(VCPKG_LINE_INFO, System::cmd_execute(cmd_line)); - } - - const std::wstring cmd_line = Strings::wformat( - LR"("%s" "%s" "%s" -n)", env_editor, portpath.native(), (portpath / "portfile.cmake").native()); - Checks::exit_with_code(VCPKG_LINE_INFO, System::cmd_execute(cmd_line)); - } -} diff --git a/toolsrc/src/commands_env.cpp b/toolsrc/src/commands_env.cpp deleted file mode 100644 index 6dad3e882..000000000 --- a/toolsrc/src/commands_env.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include "pch.h" - -#include "vcpkg_Build.h" -#include "vcpkg_Commands.h" -#include "vcpkg_System.h" - -namespace vcpkg::Commands::Env -{ - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) - { - static const std::string EXAMPLE = Commands::Help::create_example_string(R"(env --Triplet x64-windows)"); - args.check_exact_arg_count(0, EXAMPLE); - args.check_and_get_optional_command_arguments({}); - - const auto pre_build_info = Build::PreBuildInfo::from_triplet_file(paths, default_triplet); - const Toolset& toolset = paths.get_toolset(pre_build_info.platform_toolset, pre_build_info.visual_studio_path); - System::cmd_execute_clean(Build::make_build_env_cmd(pre_build_info, toolset) + L" && cmd"); - - Checks::exit_success(VCPKG_LINE_INFO); - } -} diff --git a/toolsrc/src/commands_export.cpp b/toolsrc/src/commands_export.cpp deleted file mode 100644 index 20838f5a5..000000000 --- a/toolsrc/src/commands_export.cpp +++ /dev/null @@ -1,526 +0,0 @@ -#include "pch.h" - -#include "Paragraphs.h" -#include "vcpkg_Commands.h" -#include "vcpkg_Commands_Export_IFW.h" -#include "vcpkg_Dependencies.h" -#include "vcpkg_Input.h" -#include "vcpkg_System.h" -#include "vcpkg_Util.h" -#include "vcpkglib.h" -#include - -namespace vcpkg::Commands::Export -{ - using Dependencies::ExportPlanAction; - using Dependencies::ExportPlanType; - using Dependencies::RequestType; - using Install::InstallDir; - - static std::string create_nuspec_file_contents(const std::string& raw_exported_dir, - const std::string& targets_redirect_path, - const std::string& nuget_id, - const std::string& nupkg_version) - { - static constexpr auto CONTENT_TEMPLATE = R"( - - - @NUGET_ID@ - @VERSION@ - vcpkg - - Vcpkg NuGet export - - - - - - - - - -)"; - - std::string nuspec_file_content = std::regex_replace(CONTENT_TEMPLATE, std::regex("@NUGET_ID@"), nuget_id); - nuspec_file_content = std::regex_replace(nuspec_file_content, std::regex("@VERSION@"), nupkg_version); - nuspec_file_content = - std::regex_replace(nuspec_file_content, std::regex("@RAW_EXPORTED_DIR@"), raw_exported_dir); - nuspec_file_content = - std::regex_replace(nuspec_file_content, std::regex("@TARGETS_REDIRECT_PATH@"), targets_redirect_path); - return nuspec_file_content; - } - - static std::string create_targets_redirect(const std::string& target_path) noexcept - { - return Strings::format(R"###( - - - -)###", - target_path, - target_path); - } - - static void print_plan(const std::map>& group_by_plan_type) - { - static constexpr std::array ORDER = {ExportPlanType::ALREADY_BUILT, - ExportPlanType::PORT_AVAILABLE_BUT_NOT_BUILT}; - - for (const ExportPlanType plan_type : ORDER) - { - const auto it = group_by_plan_type.find(plan_type); - if (it == group_by_plan_type.cend()) - { - continue; - } - - std::vector cont = it->second; - std::sort(cont.begin(), cont.end(), &ExportPlanAction::compare_by_name); - const std::string as_string = Strings::join("\n", cont, [](const ExportPlanAction* p) { - return Dependencies::to_output_string(p->request_type, p->spec.to_string()); - }); - - switch (plan_type) - { - case ExportPlanType::ALREADY_BUILT: - System::println("The following packages are already built and will be exported:\n%s", as_string); - continue; - case ExportPlanType::PORT_AVAILABLE_BUT_NOT_BUILT: - System::println("The following packages need to be built:\n%s", as_string); - continue; - default: Checks::unreachable(VCPKG_LINE_INFO); - } - } - } - - static std::string create_export_id() - { - const tm date_time = System::get_current_date_time(); - - // Format is: YYYYmmdd-HHMMSS - // 15 characters + 1 null terminating character will be written for a total of 16 chars - char mbstr[16]; - const size_t bytes_written = std::strftime(mbstr, sizeof(mbstr), "%Y%m%d-%H%M%S", &date_time); - Checks::check_exit(VCPKG_LINE_INFO, - bytes_written == 15, - "Expected 15 bytes to be written, but %u were written", - bytes_written); - const std::string date_time_as_string(mbstr); - return ("vcpkg-export-" + date_time_as_string); - } - - static fs::path do_nuget_export(const VcpkgPaths& paths, - const std::string& nuget_id, - const std::string& nuget_version, - const fs::path& raw_exported_dir, - const fs::path& output_dir) - { - Files::Filesystem& fs = paths.get_filesystem(); - const fs::path& nuget_exe = paths.get_nuget_exe(); - - // This file will be placed in "build\native" in the nuget package. Therefore, go up two dirs. - const std::string targets_redirect_content = - create_targets_redirect("../../scripts/buildsystems/msbuild/vcpkg.targets"); - const fs::path targets_redirect = paths.buildsystems / "tmp" / "vcpkg.export.nuget.targets"; - - std::error_code ec; - fs.create_directories(paths.buildsystems / "tmp", ec); - - fs.write_contents(targets_redirect, targets_redirect_content); - - const std::string nuspec_file_content = - create_nuspec_file_contents(raw_exported_dir.string(), targets_redirect.string(), nuget_id, nuget_version); - const fs::path nuspec_file_path = paths.buildsystems / "tmp" / "vcpkg.export.nuspec"; - fs.write_contents(nuspec_file_path, nuspec_file_content); - - // -NoDefaultExcludes is needed for ".vcpkg-root" - const std::wstring cmd_line = - Strings::wformat(LR"("%s" pack -OutputDirectory "%s" "%s" -NoDefaultExcludes > nul)", - nuget_exe.native(), - output_dir.native(), - nuspec_file_path.native()); - - const int exit_code = System::cmd_execute_clean(cmd_line); - Checks::check_exit(VCPKG_LINE_INFO, exit_code == 0, "Error: NuGet package creation failed"); - - const fs::path output_path = output_dir / (nuget_id + ".nupkg"); - return output_path; - } - - struct ArchiveFormat final - { - enum class BackingEnum - { - ZIP = 1, - SEVEN_ZIP, - }; - - constexpr ArchiveFormat() = delete; - - constexpr ArchiveFormat(BackingEnum backing_enum, const wchar_t* extension, const wchar_t* cmake_option) - : backing_enum(backing_enum), m_extension(extension), m_cmake_option(cmake_option) - { - } - - constexpr operator BackingEnum() const { return backing_enum; } - constexpr CWStringView extension() const { return this->m_extension; } - constexpr CWStringView cmake_option() const { return this->m_cmake_option; } - - private: - BackingEnum backing_enum; - const wchar_t* m_extension; - const wchar_t* m_cmake_option; - }; - - namespace ArchiveFormatC - { - constexpr const ArchiveFormat ZIP(ArchiveFormat::BackingEnum::ZIP, L"zip", L"zip"); - constexpr const ArchiveFormat SEVEN_ZIP(ArchiveFormat::BackingEnum::SEVEN_ZIP, L"7z", L"7zip"); - } - - static fs::path do_archive_export(const VcpkgPaths& paths, - const fs::path& raw_exported_dir, - const fs::path& output_dir, - const ArchiveFormat& format) - { - const fs::path& cmake_exe = paths.get_cmake_exe(); - - const std::wstring exported_dir_filename = raw_exported_dir.filename().native(); - const std::wstring exported_archive_filename = - Strings::wformat(L"%s.%s", exported_dir_filename, format.extension()); - const fs::path exported_archive_path = (output_dir / exported_archive_filename); - - // -NoDefaultExcludes is needed for ".vcpkg-root" - const std::wstring cmd_line = Strings::wformat(LR"("%s" -E tar "cf" "%s" --format=%s -- "%s")", - cmake_exe.native(), - exported_archive_path.native(), - format.cmake_option(), - raw_exported_dir.native()); - - const int exit_code = System::cmd_execute_clean(cmd_line); - Checks::check_exit( - VCPKG_LINE_INFO, exit_code == 0, "Error: %s creation failed", exported_archive_path.generic_string()); - return exported_archive_path; - } - - static Optional maybe_lookup(std::unordered_map const& m, - std::string const& key) - { - const auto it = m.find(key); - if (it != m.end()) return it->second; - return nullopt; - } - - void export_integration_files(const fs::path& raw_exported_dir_path, const VcpkgPaths& paths) - { - const std::vector integration_files_relative_to_root = { - {".vcpkg-root"}, - {fs::path{"scripts"} / "buildsystems" / "msbuild" / "applocal.ps1"}, - {fs::path{"scripts"} / "buildsystems" / "msbuild" / "vcpkg.targets"}, - {fs::path{"scripts"} / "buildsystems" / "vcpkg.cmake"}, - {fs::path{"scripts"} / "cmake" / "vcpkg_get_windows_sdk.cmake"}, - {fs::path{"scripts"} / "getWindowsSDK.ps1"}, - {fs::path{"scripts"} / "getProgramFilesPlatformBitness.ps1"}, - {fs::path{"scripts"} / "getProgramFiles32bit.ps1"}, - }; - - for (const fs::path& file : integration_files_relative_to_root) - { - const fs::path source = paths.root / file; - fs::path destination = raw_exported_dir_path / file; - Files::Filesystem& fs = paths.get_filesystem(); - std::error_code ec; - fs.create_directories(destination.parent_path(), ec); - Checks::check_exit(VCPKG_LINE_INFO, !ec); - fs.copy_file(source, destination, fs::copy_options::overwrite_existing, ec); - Checks::check_exit(VCPKG_LINE_INFO, !ec); - } - } - - struct ExportArguments - { - bool dry_run; - bool raw; - bool nuget; - bool ifw; - bool zip; - bool seven_zip; - - Optional maybe_nuget_id; - Optional maybe_nuget_version; - - IFW::Options ifw_options; - std::vector specs; - }; - - static ExportArguments handle_export_command_arguments(const VcpkgCmdArguments& args, - const Triplet& default_triplet) - { - ExportArguments ret; - - static const std::string OPTION_DRY_RUN = "--dry-run"; - static const std::string OPTION_RAW = "--raw"; - static const std::string OPTION_NUGET = "--nuget"; - static const std::string OPTION_IFW = "--ifw"; - static const std::string OPTION_ZIP = "--zip"; - static const std::string OPTION_SEVEN_ZIP = "--7zip"; - static const std::string OPTION_NUGET_ID = "--nuget-id"; - static const std::string OPTION_NUGET_VERSION = "--nuget-version"; - static const std::string OPTION_IFW_REPOSITORY_URL = "--ifw-repository-url"; - static const std::string OPTION_IFW_PACKAGES_DIR_PATH = "--ifw-packages-directory-path"; - static const std::string OPTION_IFW_REPOSITORY_DIR_PATH = "--ifw-repository-directory-path"; - static const std::string OPTION_IFW_CONFIG_FILE_PATH = "--ifw-configuration-file-path"; - static const std::string OPTION_IFW_INSTALLER_FILE_PATH = "--ifw-installer-file-path"; - - // input sanitization - static const std::string EXAMPLE = - Commands::Help::create_example_string("export zlib zlib:x64-windows boost --nuget"); - args.check_min_arg_count(1, EXAMPLE); - - ret.specs = Util::fmap(args.command_arguments, [&](auto&& arg) { - return Input::check_and_get_package_spec(arg, default_triplet, EXAMPLE); - }); - - const auto options = args.check_and_get_optional_command_arguments( - { - OPTION_DRY_RUN, - OPTION_RAW, - OPTION_NUGET, - OPTION_IFW, - OPTION_ZIP, - OPTION_SEVEN_ZIP, - }, - { - OPTION_NUGET_ID, - OPTION_NUGET_VERSION, - OPTION_IFW_REPOSITORY_URL, - OPTION_IFW_PACKAGES_DIR_PATH, - OPTION_IFW_REPOSITORY_DIR_PATH, - OPTION_IFW_CONFIG_FILE_PATH, - OPTION_IFW_INSTALLER_FILE_PATH, - }); - ret.dry_run = options.switches.find(OPTION_DRY_RUN) != options.switches.cend(); - ret.raw = options.switches.find(OPTION_RAW) != options.switches.cend(); - ret.nuget = options.switches.find(OPTION_NUGET) != options.switches.cend(); - ret.ifw = options.switches.find(OPTION_IFW) != options.switches.cend(); - ret.zip = options.switches.find(OPTION_ZIP) != options.switches.cend(); - ret.seven_zip = options.switches.find(OPTION_SEVEN_ZIP) != options.switches.cend(); - - if (!ret.raw && !ret.nuget && !ret.ifw && !ret.zip && !ret.seven_zip && !ret.dry_run) - { - System::println(System::Color::error, - "Must provide at least one export type: --raw --nuget --ifw --zip --7zip"); - System::print(EXAMPLE); - Checks::exit_fail(VCPKG_LINE_INFO); - } - - struct OptionPair - { - const std::string& name; - Optional& out_opt; - }; - const auto options_implies = - [&](const std::string& main_opt_name, bool main_opt, Span implying_opts) { - if (main_opt) - { - for (auto&& opt : implying_opts) - opt.out_opt = maybe_lookup(options.settings, opt.name); - } - else - { - for (auto&& opt : implying_opts) - Checks::check_exit(VCPKG_LINE_INFO, - !maybe_lookup(options.settings, opt.name), - "%s is only valid with %s", - opt.name, - main_opt_name); - } - }; - - options_implies(OPTION_NUGET, - ret.nuget, - { - {OPTION_NUGET_ID, ret.maybe_nuget_id}, - {OPTION_NUGET_VERSION, ret.maybe_nuget_version}, - }); - - options_implies(OPTION_IFW, - ret.ifw, - { - {OPTION_IFW_REPOSITORY_URL, ret.ifw_options.maybe_repository_url}, - {OPTION_IFW_PACKAGES_DIR_PATH, ret.ifw_options.maybe_packages_dir_path}, - {OPTION_IFW_REPOSITORY_DIR_PATH, ret.ifw_options.maybe_repository_dir_path}, - {OPTION_IFW_CONFIG_FILE_PATH, ret.ifw_options.maybe_config_file_path}, - {OPTION_IFW_INSTALLER_FILE_PATH, ret.ifw_options.maybe_installer_file_path}, - }); - return ret; - } - - static void print_next_step_info(const fs::path& prefix) - { - const fs::path cmake_toolchain = prefix / "scripts" / "buildsystems" / "vcpkg.cmake"; - const CMakeVariable cmake_variable = CMakeVariable(L"CMAKE_TOOLCHAIN_FILE", cmake_toolchain.generic_string()); - System::println("\n" - "To use the exported libraries in CMake projects use:" - "\n" - " %s" - "\n", - Strings::to_utf8(cmake_variable.s)); - }; - - static void handle_raw_based_export(Span export_plan, - const ExportArguments& opts, - const std::string& export_id, - const VcpkgPaths& paths) - { - Files::Filesystem& fs = paths.get_filesystem(); - const fs::path export_to_path = paths.root; - const fs::path raw_exported_dir_path = export_to_path / export_id; - std::error_code ec; - fs.remove_all(raw_exported_dir_path, ec); - fs.create_directory(raw_exported_dir_path, ec); - - // execute the plan - for (const ExportPlanAction& action : export_plan) - { - if (action.plan_type != ExportPlanType::ALREADY_BUILT) - { - Checks::unreachable(VCPKG_LINE_INFO); - } - - const std::string display_name = action.spec.to_string(); - System::println("Exporting package %s... ", display_name); - - const BinaryParagraph& binary_paragraph = - action.any_paragraph.binary_control_file.value_or_exit(VCPKG_LINE_INFO).core_paragraph; - - const InstallDir dirs = InstallDir::from_destination_root( - raw_exported_dir_path / "installed", - 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); - System::println(System::Color::success, "Exporting package %s... done", display_name); - } - - // Copy files needed for integration - export_integration_files(raw_exported_dir_path, paths); - - if (opts.raw) - { - System::println( - System::Color::success, R"(Files exported at: "%s")", raw_exported_dir_path.generic_string()); - print_next_step_info(export_to_path); - } - - if (opts.nuget) - { - System::println("Creating nuget package... "); - - const std::string nuget_id = opts.maybe_nuget_id.value_or(raw_exported_dir_path.filename().string()); - const std::string nuget_version = opts.maybe_nuget_version.value_or("1.0.0"); - const fs::path output_path = - do_nuget_export(paths, nuget_id, nuget_version, raw_exported_dir_path, export_to_path); - System::println(System::Color::success, "Creating nuget package... done"); - System::println(System::Color::success, "NuGet package exported at: %s", output_path.generic_string()); - - System::println(R"( -With a project open, go to Tools->NuGet Package Manager->Package Manager Console and paste: - Install-Package %s -Source "%s" -)" - "\n", - nuget_id, - output_path.parent_path().u8string()); - } - - if (opts.zip) - { - System::println("Creating zip archive... "); - const fs::path output_path = - do_archive_export(paths, raw_exported_dir_path, export_to_path, ArchiveFormatC::ZIP); - System::println(System::Color::success, "Creating zip archive... done"); - System::println(System::Color::success, "Zip archive exported at: %s", output_path.generic_string()); - print_next_step_info("[...]"); - } - - if (opts.seven_zip) - { - System::println("Creating 7zip archive... "); - const fs::path output_path = - do_archive_export(paths, raw_exported_dir_path, export_to_path, ArchiveFormatC::SEVEN_ZIP); - System::println(System::Color::success, "Creating 7zip archive... done"); - System::println(System::Color::success, "7zip archive exported at: %s", output_path.generic_string()); - print_next_step_info("[...]"); - } - - if (!opts.raw) - { - fs.remove_all(raw_exported_dir_path, ec); - } - } - - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) - { - const auto opts = handle_export_command_arguments(args, default_triplet); - for (auto&& spec : opts.specs) - Input::check_triplet(spec.triplet(), paths); - - // create the plan - const StatusParagraphs status_db = database_load_check(paths); - std::vector export_plan = Dependencies::create_export_plan(paths, opts.specs, status_db); - Checks::check_exit(VCPKG_LINE_INFO, !export_plan.empty(), "Export plan cannot be empty"); - - std::map> group_by_plan_type; - Util::group_by(export_plan, &group_by_plan_type, [](const ExportPlanAction& p) { return p.plan_type; }); - print_plan(group_by_plan_type); - - const bool has_non_user_requested_packages = - Util::find_if(export_plan, [](const ExportPlanAction& package) -> bool { - return package.request_type != RequestType::USER_REQUESTED; - }) != export_plan.cend(); - - if (has_non_user_requested_packages) - { - System::println(System::Color::warning, - "Additional packages (*) need to be exported to complete this operation."); - } - - const auto it = group_by_plan_type.find(ExportPlanType::PORT_AVAILABLE_BUT_NOT_BUILT); - if (it != group_by_plan_type.cend() && !it->second.empty()) - { - System::println(System::Color::error, "There are packages that have not been built."); - - // No need to show all of them, just the user-requested ones. Dependency resolution will handle the rest. - std::vector unbuilt = it->second; - Util::erase_remove_if( - unbuilt, [](const ExportPlanAction* a) { return a->request_type != RequestType::USER_REQUESTED; }); - - const auto s = Strings::join(" ", unbuilt, [](const ExportPlanAction* a) { return a->spec.to_string(); }); - System::println("To build them, run:\n" - " vcpkg install %s", - s); - Checks::exit_fail(VCPKG_LINE_INFO); - } - - if (opts.dry_run) - { - Checks::exit_success(VCPKG_LINE_INFO); - } - - std::string export_id = create_export_id(); - - if (opts.raw || opts.nuget || opts.zip || opts.seven_zip) - { - handle_raw_based_export(export_plan, opts, export_id, paths); - } - - if (opts.ifw) - { - IFW::do_export(export_plan, export_id, opts.ifw_options, paths); - - print_next_step_info("@RootDir@/src/vcpkg"); - } - - Checks::exit_success(VCPKG_LINE_INFO); - } -} diff --git a/toolsrc/src/commands_export_ifw.cpp b/toolsrc/src/commands_export_ifw.cpp deleted file mode 100644 index 191dbb763..000000000 --- a/toolsrc/src/commands_export_ifw.cpp +++ /dev/null @@ -1,481 +0,0 @@ -#include "pch.h" - -#include "vcpkg_Commands.h" -#include "vcpkg_Commands_Export.h" -#include "vcpkg_Commands_Export_IFW.h" - -namespace vcpkg::Commands::Export::IFW -{ - using Dependencies::ExportPlanAction; - using Dependencies::ExportPlanType; - using Install::InstallDir; - - static std::string create_release_date() - { - const tm date_time = System::get_current_date_time(); - - // Format is: YYYY-mm-dd - // 10 characters + 1 null terminating character will be written for a total of 11 chars - char mbstr[11]; - const size_t bytes_written = std::strftime(mbstr, sizeof(mbstr), "%Y-%m-%d", &date_time); - Checks::check_exit(VCPKG_LINE_INFO, - bytes_written == 10, - "Expected 10 bytes to be written, but %u were written", - bytes_written); - const std::string date_time_as_string(mbstr); - return date_time_as_string; - } - - fs::path get_packages_dir_path(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths) - { - return ifw_options.maybe_packages_dir_path.has_value() - ? fs::path(ifw_options.maybe_packages_dir_path.value_or_exit(VCPKG_LINE_INFO)) - : paths.root / (export_id + "-ifw-packages"); - } - - fs::path get_repository_dir_path(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths) - { - return ifw_options.maybe_repository_dir_path.has_value() - ? fs::path(ifw_options.maybe_repository_dir_path.value_or_exit(VCPKG_LINE_INFO)) - : paths.root / (export_id + "-ifw-repository"); - } - - fs::path get_config_file_path(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths) - { - return ifw_options.maybe_config_file_path.has_value() - ? fs::path(ifw_options.maybe_config_file_path.value_or_exit(VCPKG_LINE_INFO)) - : paths.root / (export_id + "-ifw-configuration.xml"); - } - - fs::path get_installer_file_path(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths) - { - return ifw_options.maybe_installer_file_path.has_value() - ? fs::path(ifw_options.maybe_installer_file_path.value_or_exit(VCPKG_LINE_INFO)) - : paths.root / (export_id + "-ifw-installer.exe"); - } - - fs::path export_real_package(const fs::path& ifw_packages_dir_path, - const ExportPlanAction& action, - Files::Filesystem& fs) - { - std::error_code ec; - - const BinaryParagraph& binary_paragraph = - action.any_paragraph.binary_control_file.value_or_exit(VCPKG_LINE_INFO).core_paragraph; - - // Prepare meta dir - const fs::path package_xml_file_path = - ifw_packages_dir_path / - Strings::format("packages.%s.%s", action.spec.name(), action.spec.triplet().canonical_name()) / "meta" / - "package.xml"; - const fs::path package_xml_dir_path = package_xml_file_path.parent_path(); - fs.create_directories(package_xml_dir_path, ec); - Checks::check_exit(VCPKG_LINE_INFO, - !ec, - "Could not create directory for package file %s", - package_xml_file_path.generic_string()); - - auto deps = Strings::join( - ",", binary_paragraph.depends, [](const std::string& dep) { return "packages." + dep + ":"; }); - - if (!deps.empty()) deps = "\n " + deps + ""; - - fs.write_contents(package_xml_file_path, - Strings::format( - R"###( - - %s - %s - %s - packages.%s:,triplets.%s:%s - true - -)###", - action.spec.to_string(), - binary_paragraph.version, - create_release_date(), - action.spec.name(), - action.spec.triplet().canonical_name(), - deps)); - - // Return dir path for export package data - return ifw_packages_dir_path / - Strings::format("packages.%s.%s", action.spec.name(), action.spec.triplet().canonical_name()) / "data" / - "installed"; - } - - void export_unique_packages(const fs::path& raw_exported_dir_path, - std::map unique_packages, - Files::Filesystem& fs) - { - std::error_code ec; - - // packages - - fs::path package_xml_file_path = raw_exported_dir_path / "packages" / "meta" / "package.xml"; - fs::path package_xml_dir_path = package_xml_file_path.parent_path(); - fs.create_directories(package_xml_dir_path, ec); - Checks::check_exit(VCPKG_LINE_INFO, - !ec, - "Could not create directory for package file %s", - package_xml_file_path.generic_string()); - fs.write_contents(package_xml_file_path, - Strings::format( - R"###( - - Packages - 1.0.0 - %s - -)###", - create_release_date())); - - for (auto package = unique_packages.begin(); package != unique_packages.end(); ++package) - { - const ExportPlanAction& action = *(package->second); - const BinaryParagraph& binary_paragraph = - action.any_paragraph.binary_control_file.value_or_exit(VCPKG_LINE_INFO).core_paragraph; - - package_xml_file_path = - raw_exported_dir_path / Strings::format("packages.%s", package->first) / "meta" / "package.xml"; - package_xml_dir_path = package_xml_file_path.parent_path(); - fs.create_directories(package_xml_dir_path, ec); - Checks::check_exit(VCPKG_LINE_INFO, - !ec, - "Could not create directory for package file %s", - package_xml_file_path.generic_string()); - - fs.write_contents(package_xml_file_path, - Strings::format( - R"###( - - %s - %s - %s - %s - -)###", - action.spec.name(), - binary_paragraph.description, - binary_paragraph.version, - create_release_date())); - } - } - - void export_unique_triplets(const fs::path& raw_exported_dir_path, - std::set unique_triplets, - Files::Filesystem& fs) - { - std::error_code ec; - - // triplets - - fs::path package_xml_file_path = raw_exported_dir_path / "triplets" / "meta" / "package.xml"; - fs::path package_xml_dir_path = package_xml_file_path.parent_path(); - fs.create_directories(package_xml_dir_path, ec); - Checks::check_exit(VCPKG_LINE_INFO, - !ec, - "Could not create directory for package file %s", - package_xml_file_path.generic_string()); - fs.write_contents(package_xml_file_path, - Strings::format( - R"###( - - Triplets - 1.0.0 - %s - -)###", - create_release_date())); - - for (const std::string& triplet : unique_triplets) - { - package_xml_file_path = - raw_exported_dir_path / Strings::format("triplets.%s", triplet) / "meta" / "package.xml"; - package_xml_dir_path = package_xml_file_path.parent_path(); - fs.create_directories(package_xml_dir_path, ec); - Checks::check_exit(VCPKG_LINE_INFO, - !ec, - "Could not create directory for package file %s", - package_xml_file_path.generic_string()); - fs.write_contents(package_xml_file_path, - Strings::format( - R"###( - - %s - 1.0.0 - %s - -)###", - triplet, - create_release_date())); - } - } - - void export_integration(const fs::path& raw_exported_dir_path, Files::Filesystem& fs) - { - std::error_code ec; - - // integration - fs::path package_xml_file_path = raw_exported_dir_path / "integration" / "meta" / "package.xml"; - fs::path package_xml_dir_path = package_xml_file_path.parent_path(); - fs.create_directories(package_xml_dir_path, ec); - Checks::check_exit(VCPKG_LINE_INFO, - !ec, - "Could not create directory for package file %s", - package_xml_file_path.generic_string()); - - fs.write_contents(package_xml_file_path, - Strings::format( - R"###( - - Integration - 1.0.0 - %s - -)###", - create_release_date())); - } - - void export_config(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths) - { - std::error_code ec; - Files::Filesystem& fs = paths.get_filesystem(); - - const fs::path config_xml_file_path = get_config_file_path(export_id, ifw_options, paths); - - fs::path config_xml_dir_path = config_xml_file_path.parent_path(); - fs.create_directories(config_xml_dir_path, ec); - Checks::check_exit(VCPKG_LINE_INFO, - !ec, - "Could not create directory for configuration file %s", - config_xml_file_path.generic_string()); - - std::string formatted_repo_url; - std::string ifw_repo_url = ifw_options.maybe_repository_url.value_or(""); - if (!ifw_repo_url.empty()) - { - formatted_repo_url = Strings::format(R"###( - - - %s - - )###", - ifw_repo_url); - } - - fs.write_contents(config_xml_file_path, - Strings::format( - R"###( - - vcpkg - 1.0.0 - vcpkg - @RootDir@/src/vcpkg%s - -)###", - formatted_repo_url)); - } - - void export_maintenance_tool(const fs::path& ifw_packages_dir_path, const VcpkgPaths& paths) - { - System::println("Exporting maintenance tool... "); - - std::error_code ec; - Files::Filesystem& fs = paths.get_filesystem(); - - const fs::path& installerbase_exe = paths.get_ifw_installerbase_exe(); - fs::path tempmaintenancetool = ifw_packages_dir_path / "maintenance" / "data" / "tempmaintenancetool.exe"; - fs.create_directories(tempmaintenancetool.parent_path(), ec); - Checks::check_exit(VCPKG_LINE_INFO, - !ec, - "Could not create directory for package file %s", - tempmaintenancetool.generic_string()); - fs.copy_file(installerbase_exe, tempmaintenancetool, fs::copy_options::overwrite_existing, ec); - Checks::check_exit( - VCPKG_LINE_INFO, !ec, "Could not write package file %s", tempmaintenancetool.generic_string()); - - fs::path package_xml_file_path = ifw_packages_dir_path / "maintenance" / "meta" / "package.xml"; - fs::path package_xml_dir_path = package_xml_file_path.parent_path(); - fs.create_directories(package_xml_dir_path, ec); - Checks::check_exit(VCPKG_LINE_INFO, - !ec, - "Could not create directory for package file %s", - package_xml_file_path.generic_string()); - fs.write_contents(package_xml_file_path, - Strings::format( - R"###( - - Maintenance Tool - Maintenance Tool - 1.0.0 - %s - - true - true - true - -)###", - create_release_date())); - const fs::path script_source = paths.root / "scripts" / "ifw" / "maintenance.qs"; - const fs::path script_destination = ifw_packages_dir_path / "maintenance" / "meta" / "maintenance.qs"; - fs.copy_file(script_source, script_destination, fs::copy_options::overwrite_existing, ec); - Checks::check_exit( - VCPKG_LINE_INFO, !ec, "Could not write package file %s", script_destination.generic_string()); - - System::println("Exporting maintenance tool... done"); - } - - void do_repository(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths) - { - const fs::path& repogen_exe = paths.get_ifw_repogen_exe(); - const fs::path packages_dir = get_packages_dir_path(export_id, ifw_options, paths); - const fs::path repository_dir = get_repository_dir_path(export_id, ifw_options, paths); - - System::println("Generating repository %s...", repository_dir.generic_string()); - - std::error_code ec; - Files::Filesystem& fs = paths.get_filesystem(); - - fs.remove_all(repository_dir, ec); - Checks::check_exit( - VCPKG_LINE_INFO, !ec, "Could not remove outdated repository directory %s", repository_dir.generic_string()); - - const std::wstring cmd_line = Strings::wformat(LR"("%s" --packages "%s" "%s" > nul)", - repogen_exe.native(), - packages_dir.native(), - repository_dir.native()); - - const int exit_code = System::cmd_execute_clean(cmd_line); - Checks::check_exit(VCPKG_LINE_INFO, exit_code == 0, "Error: IFW repository generating failed"); - - System::println(System::Color::success, "Generating repository %s... done.", repository_dir.generic_string()); - } - - void do_installer(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths) - { - const fs::path& binarycreator_exe = paths.get_ifw_binarycreator_exe(); - const fs::path config_file = get_config_file_path(export_id, ifw_options, paths); - const fs::path packages_dir = get_packages_dir_path(export_id, ifw_options, paths); - const fs::path repository_dir = get_repository_dir_path(export_id, ifw_options, paths); - const fs::path installer_file = get_installer_file_path(export_id, ifw_options, paths); - - System::println("Generating installer %s...", installer_file.generic_string()); - - std::wstring cmd_line; - - std::string ifw_repo_url = ifw_options.maybe_repository_url.value_or(""); - if (!ifw_repo_url.empty()) - { - cmd_line = Strings::wformat(LR"("%s" --online-only --config "%s" --repository "%s" "%s" > nul)", - binarycreator_exe.native(), - config_file.native(), - repository_dir.native(), - installer_file.native()); - } - else - { - cmd_line = Strings::wformat(LR"("%s" --config "%s" --packages "%s" "%s" > nul)", - binarycreator_exe.native(), - config_file.native(), - packages_dir.native(), - installer_file.native()); - } - - const int exit_code = System::cmd_execute_clean(cmd_line); - Checks::check_exit(VCPKG_LINE_INFO, exit_code == 0, "Error: IFW installer generating failed"); - - System::println(System::Color::success, "Generating installer %s... done.", installer_file.generic_string()); - } - - void do_export(const std::vector& export_plan, - const std::string& export_id, - const Options& ifw_options, - const VcpkgPaths& paths) - { - std::error_code ec; - Files::Filesystem& fs = paths.get_filesystem(); - - // Prepare packages directory - const fs::path ifw_packages_dir_path = get_packages_dir_path(export_id, ifw_options, paths); - - fs.remove_all(ifw_packages_dir_path, ec); - Checks::check_exit(VCPKG_LINE_INFO, - !ec, - "Could not remove outdated packages directory %s", - ifw_packages_dir_path.generic_string()); - - fs.create_directory(ifw_packages_dir_path, ec); - Checks::check_exit( - VCPKG_LINE_INFO, !ec, "Could not create packages directory %s", ifw_packages_dir_path.generic_string()); - - // Export maintenance tool - export_maintenance_tool(ifw_packages_dir_path, paths); - - System::println("Exporting packages %s... ", ifw_packages_dir_path.generic_string()); - - // execute the plan - std::map unique_packages; - std::set unique_triplets; - for (const ExportPlanAction& action : export_plan) - { - if (action.plan_type != ExportPlanType::ALREADY_BUILT) - { - Checks::unreachable(VCPKG_LINE_INFO); - } - - const std::string display_name = action.spec.to_string(); - System::println("Exporting package %s... ", display_name); - - const BinaryParagraph& binary_paragraph = - action.any_paragraph.binary_control_file.value_or_exit(VCPKG_LINE_INFO).core_paragraph; - - unique_packages[action.spec.name()] = &action; - unique_triplets.insert(action.spec.triplet().canonical_name()); - - // Export real package and return data dir for installation - fs::path ifw_package_dir_path = export_real_package(ifw_packages_dir_path, action, fs); - - // Copy package data - const InstallDir dirs = InstallDir::from_destination_root(ifw_package_dir_path, - action.spec.triplet().to_string(), - 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); - System::println("Exporting package %s... done", display_name); - } - - System::println("Exporting packages %s... done", ifw_packages_dir_path.generic_string()); - - const fs::path config_file = get_config_file_path(export_id, ifw_options, paths); - - System::println("Generating configuration %s...", config_file.generic_string()); - - // Unique packages - export_unique_packages(ifw_packages_dir_path, unique_packages, fs); - - // Unique triplets - export_unique_triplets(ifw_packages_dir_path, unique_triplets, fs); - - // Copy files needed for integration - export_integration_files(ifw_packages_dir_path / "integration" / "data", paths); - // Integration - export_integration(ifw_packages_dir_path, fs); - - // Configuration - export_config(export_id, ifw_options, paths); - - System::println("Generating configuration %s... done.", config_file.generic_string()); - - // Do repository (optional) - std::string ifw_repo_url = ifw_options.maybe_repository_url.value_or(""); - if (!ifw_repo_url.empty()) - { - do_repository(export_id, ifw_options, paths); - } - - // Do installer - do_installer(export_id, ifw_options, paths); - } -} diff --git a/toolsrc/src/commands_hash.cpp b/toolsrc/src/commands_hash.cpp deleted file mode 100644 index b3211b9f8..000000000 --- a/toolsrc/src/commands_hash.cpp +++ /dev/null @@ -1,55 +0,0 @@ -#include "pch.h" - -#include "vcpkg_Commands.h" -#include "vcpkg_System.h" -#include "vcpkg_Util.h" - -namespace vcpkg::Commands::Hash -{ - static void do_file_hash(fs::path const& path, std::wstring const& hash_type) - { - const auto cmd_line = Strings::wformat(LR"(CertUtil.exe -hashfile "%s" %s)", path.c_str(), hash_type); - const auto ec_data = System::cmd_execute_and_capture_output(cmd_line); - Checks::check_exit( - VCPKG_LINE_INFO, ec_data.exit_code == 0, "Running command:\n %s\n failed", Strings::to_utf8(cmd_line)); - - std::string const& output = ec_data.output; - - const auto start = output.find_first_of("\r\n"); - Checks::check_exit(VCPKG_LINE_INFO, - start != std::string::npos, - "Unexpected output format from command: %s", - Strings::to_utf8(cmd_line)); - - const auto end = output.find_first_of("\r\n", start + 1); - Checks::check_exit(VCPKG_LINE_INFO, - end != std::string::npos, - "Unexpected output format from command: %s", - Strings::to_utf8(cmd_line)); - - auto hash = output.substr(start, end - start); - Util::erase_remove_if(hash, isspace); - System::println(hash); - } - - void perform_and_exit(const VcpkgCmdArguments& args) - { - static const std::string EXAMPLE = - Strings::format("The argument should be a file path\n%s", - Commands::Help::create_example_string("hash boost_1_62_0.tar.bz2")); - args.check_min_arg_count(1, EXAMPLE); - args.check_max_arg_count(2, EXAMPLE); - args.check_and_get_optional_command_arguments({}); - - if (args.command_arguments.size() == 1) - { - do_file_hash(args.command_arguments[0], L"SHA512"); - } - if (args.command_arguments.size() == 2) - { - do_file_hash(args.command_arguments[0], Strings::to_utf16(args.command_arguments[1])); - } - - Checks::exit_success(VCPKG_LINE_INFO); - } -} diff --git a/toolsrc/src/commands_help.cpp b/toolsrc/src/commands_help.cpp deleted file mode 100644 index a12f9003d..000000000 --- a/toolsrc/src/commands_help.cpp +++ /dev/null @@ -1,131 +0,0 @@ -#include "pch.h" - -#include "vcpkg_Commands.h" -#include "vcpkg_System.h" - -namespace vcpkg::Commands::Help -{ - void help_topics() - { - System::println("Available help topics:\n" - " triplet\n" - " integrate\n" - " export"); - } - - void help_topic_valid_triplet(const VcpkgPaths& paths) - { - System::println("Available architecture triplets:"); - for (auto&& path : paths.get_filesystem().get_files_non_recursive(paths.triplets)) - { - System::println(" %s", path.stem().filename().string()); - } - } - - void help_topic_export() - { - System::println("Summary:\n" - " vcpkg export [options] ...\n" - "\n" - "Options:\n" - " --7zip Export to a 7zip (.7z) file\n" - " --dry-run Do not actually export\n" - " --nuget Export a NuGet package\n" - " --nuget-id= Specify the id for the exported NuGet package\n" - " --nuget-version= Specify the version for the exported NuGet package\n" - " --raw Export to an uncompressed directory\n" - " --zip Export to a zip file"); - } - - void print_usage() - { - System::println( - "Commands:\n" - " vcpkg search [pat] Search for packages available to be built\n" - " vcpkg install ... Install a package\n" - " vcpkg remove ... Uninstall a package\n" - " vcpkg remove --outdated Uninstall all out-of-date packages\n" - " vcpkg list List installed packages\n" - " vcpkg update Display list of packages for updating\n" - " vcpkg hash [alg] Hash a file by specific algorithm, default SHA512\n" - " vcpkg help topics Display the list of help topics\n" - " vcpkg help Display help for a specific topic\n" - "\n" - "%s" // Integration help - "\n" - " vcpkg export ... [opt]... Exports a package\n" - " vcpkg edit Open up a port for editing (uses %%EDITOR%%, default 'code')\n" - " vcpkg import Import a pre-built library\n" - " vcpkg create \n" - " [archivename] Create a new package\n" - " vcpkg owns Search for files in installed packages\n" - " vcpkg cache List cached compiled packages\n" - " vcpkg version Display version information\n" - " vcpkg contact Display contact information to send feedback\n" - "\n" - //"internal commands:\n" - //" --check-build-deps \n" - //" --create-binary-control \n" - //"\n" - "Options:\n" - " --triplet Specify the target architecture triplet.\n" - " (default: %%VCPKG_DEFAULT_TRIPLET%%, see 'vcpkg help triplet')\n" - "\n" - " --vcpkg-root Specify the vcpkg root directory\n" - " (default: %%VCPKG_ROOT%%)\n" - "\n" - "For more help (including examples) see the accompanying README.md.", - Integrate::INTEGRATE_COMMAND_HELPSTRING); - } - - std::string create_example_string(const std::string& command_and_arguments) - { - std::string cs = Strings::format("Example:\n" - " vcpkg %s\n", - command_and_arguments); - return cs; - } - - void print_example(const std::string& command_and_arguments) - { - System::println(create_example_string(command_and_arguments)); - } - - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) - { - args.check_max_arg_count(1); - args.check_and_get_optional_command_arguments({}); - - if (args.command_arguments.empty()) - { - print_usage(); - Checks::exit_success(VCPKG_LINE_INFO); - } - const auto& topic = args.command_arguments[0]; - if (topic == "triplet" || topic == "triplets" || topic == "triple") - { - help_topic_valid_triplet(paths); - } - else if (topic == "export") - { - help_topic_export(); - } - else if (topic == "integrate") - { - System::print("Commands:\n" - "%s", - Integrate::INTEGRATE_COMMAND_HELPSTRING); - } - else if (topic == "topics") - { - help_topics(); - } - else - { - System::println(System::Color::error, "Error: unknown topic %s", topic); - help_topics(); - Checks::exit_fail(VCPKG_LINE_INFO); - } - Checks::exit_success(VCPKG_LINE_INFO); - } -} diff --git a/toolsrc/src/commands_import.cpp b/toolsrc/src/commands_import.cpp deleted file mode 100644 index 412a03d7f..000000000 --- a/toolsrc/src/commands_import.cpp +++ /dev/null @@ -1,119 +0,0 @@ -#include "pch.h" - -#include "Paragraphs.h" -#include "StatusParagraph.h" -#include "vcpkg_Commands.h" -#include "vcpkg_Files.h" - -namespace vcpkg::Commands::Import -{ - struct Binaries - { - std::vector dlls; - std::vector libs; - }; - - 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()); - } - - static Binaries find_binaries_in_dir(const Files::Filesystem& fs, const fs::path& path) - { - auto files = fs.get_files_recursive(path); - - check_is_directory(VCPKG_LINE_INFO, fs, path); - - Binaries binaries; - for (auto&& file : files) - { - if (fs.is_directory(file)) continue; - const 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(Files::Filesystem& fs, - const std::vector& files, - const fs::path& destination_folder) - { - std::error_code ec; - fs.create_directory(destination_folder, ec); - - for (auto const& src_path : files) - { - const fs::path dest_path = destination_folder / src_path.filename(); - fs.copy(src_path, dest_path, fs::copy_options::overwrite_existing); - } - } - - 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, fs, include_directory); - check_is_directory(VCPKG_LINE_INFO, fs, project_directory); - check_is_directory(VCPKG_LINE_INFO, fs, destination_path); - const Binaries debug_binaries = find_binaries_in_dir(fs, project_directory / "Debug"); - const Binaries release_binaries = find_binaries_in_dir(fs, project_directory / "Release"); - - const fs::path destination_include_directory = destination_path / "include"; - fs.copy(include_directory, - destination_include_directory, - fs::copy_options::recursive | fs::copy_options::overwrite_existing); - - copy_files_into_directory(fs, release_binaries.dlls, destination_path / "bin"); - copy_files_into_directory(fs, release_binaries.libs, destination_path / "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(); - const fs::path library_destination_path = paths.package_dir(control_file_data.spec); - 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); - - const fs::path control_file_path = library_destination_path / "CONTROL"; - fs.write_contents(control_file_path, Strings::serialize(control_file_data)); - } - - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) - { - static const std::string EXAMPLE = Commands::Help::create_example_string( - R"(import C:\path\to\CONTROLfile C:\path\to\includedir C:\path\to\projectdir)"); - args.check_exact_arg_count(3, EXAMPLE); - args.check_and_get_optional_command_arguments({}); - - const fs::path control_file_path(args.command_arguments[0]); - const fs::path include_directory(args.command_arguments[1]); - const fs::path project_directory(args.command_arguments[2]); - - const Expected> 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; - spgh.package = BinaryParagraph(*pghs.get()); - auto& control_file_data = spgh.package; - - do_import(paths, include_directory, project_directory, control_file_data); - Checks::exit_success(VCPKG_LINE_INFO); - } -} diff --git a/toolsrc/src/commands_install.cpp b/toolsrc/src/commands_install.cpp deleted file mode 100644 index d815332fe..000000000 --- a/toolsrc/src/commands_install.cpp +++ /dev/null @@ -1,613 +0,0 @@ -#include "pch.h" - -#include "Paragraphs.h" -#include "metrics.h" -#include "vcpkg_Build.h" -#include "vcpkg_Commands.h" -#include "vcpkg_Dependencies.h" -#include "vcpkg_Files.h" -#include "vcpkg_GlobalState.h" -#include "vcpkg_Input.h" -#include "vcpkg_System.h" -#include "vcpkg_Util.h" -#include "vcpkglib.h" - -namespace vcpkg::Commands::Install -{ - using namespace Dependencies; - - InstallDir InstallDir::from_destination_root(const fs::path& destination_root, - const std::string& destination_subdirectory, - const fs::path& listfile) - { - InstallDir dirs; - dirs.m_destination = destination_root / destination_subdirectory; - dirs.m_destination_subdirectory = destination_subdirectory; - dirs.m_listfile = listfile; - return dirs; - } - - const fs::path& InstallDir::destination() const { return this->m_destination; } - - const std::string& InstallDir::destination_subdirectory() const { return this->m_destination_subdirectory; } - - const fs::path& InstallDir::listfile() const { return this->m_listfile; } - - void install_files_and_write_listfile(Files::Filesystem& fs, - const fs::path& source_dir, - const InstallDir& destination_dir) - { - std::vector output; - std::error_code ec; - - const size_t prefix_length = source_dir.native().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()); - 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()); - - 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.status(file, ec); - if (ec) - { - System::println(System::Color::error, "failed: %s: %s", file.u8string(), ec.message()); - continue; - } - - const std::string filename = file.filename().generic_string(); - if (fs::is_regular_file(status) && - (Strings::case_insensitive_ascii_compare(filename.c_str(), "CONTROL") == 0 || - Strings::case_insensitive_ascii_compare(filename.c_str(), "BUILD_INFO") == 0)) - { - // Do not copy the control file - continue; - } - - const std::string suffix = file.generic_u8string().substr(prefix_length + 1); - const fs::path target = destination / suffix; - - if (fs::is_directory(status)) - { - 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/)", destination_subdirectory, suffix)); - continue; - } - - if (fs::is_regular_file(status)) - { - 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(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)", destination_subdirectory, suffix)); - continue; - } - - if (!fs::status_known(status)) - { - System::println(System::Color::error, "failed: %s: unknown status", file.u8string()); - continue; - } - - System::println(System::Color::error, "failed: %s: cannot handle file type", file.u8string()); - } - - std::sort(output.begin(), output.end()); - - fs.write_lines(listfile, output); - } - - static void remove_first_n_chars(std::vector* strings, const size_t n) - { - for (std::string& s : *strings) - { - s.erase(0, n); - } - }; - - static std::vector extract_files_in_triplet( - const std::vector& pgh_and_files, const Triplet& triplet) - { - std::vector output; - for (const StatusParagraphAndAssociatedFiles& t : pgh_and_files) - { - if (t.pgh.package.spec.triplet() != triplet) - { - continue; - } - - output.insert(output.end(), t.files.begin(), t.files.end()); - } - - std::sort(output.begin(), output.end()); - return output; - } - - static SortedVector build_list_of_package_files(const Files::Filesystem& fs, - const fs::path& package_dir) - { - const std::vector package_file_paths = fs.get_files_recursive(package_dir); - const size_t package_remove_char_count = package_dir.generic_string().size() + 1; // +1 for the slash - auto package_files = Util::fmap(package_file_paths, [package_remove_char_count](const fs::path& path) { - std::string as_string = path.generic_string(); - as_string.erase(0, package_remove_char_count); - return std::move(as_string); - }); - - return SortedVector(std::move(package_files)); - } - - static SortedVector build_list_of_installed_files( - const std::vector& pgh_and_files, const Triplet& triplet) - { - std::vector installed_files = extract_files_in_triplet(pgh_and_files, triplet); - const size_t installed_remove_char_count = triplet.canonical_name().size() + 1; // +1 for the slash - remove_first_n_chars(&installed_files, installed_remove_char_count); - - return SortedVector(std::move(installed_files)); - } - - InstallResult install_package(const VcpkgPaths& paths, const BinaryControlFile& bcf, StatusParagraphs* status_db) - { - const fs::path package_dir = paths.package_dir(bcf.core_paragraph.spec); - const Triplet& triplet = bcf.core_paragraph.spec.triplet(); - const std::vector pgh_and_files = get_installed_files(paths, *status_db); - - const SortedVector package_files = - build_list_of_package_files(paths.get_filesystem(), package_dir); - const SortedVector installed_files = build_list_of_installed_files(pgh_and_files, triplet); - - std::vector intersection; - std::set_intersection(package_files.begin(), - package_files.end(), - installed_files.begin(), - installed_files.end(), - std::back_inserter(intersection)); - - if (!intersection.empty()) - { - const fs::path triplet_install_path = paths.installed / triplet.canonical_name(); - System::println(System::Color::error, - "The following files are already installed in %s and are in conflict with %s", - triplet_install_path.generic_string(), - bcf.core_paragraph.spec); - System::print("\n "); - System::println(Strings::join("\n ", intersection)); - System::println(); - return InstallResult::FILE_CONFLICTS; - } - - StatusParagraph source_paragraph; - source_paragraph.package = bcf.core_paragraph; - source_paragraph.want = Want::INSTALL; - source_paragraph.state = InstallState::HALF_INSTALLED; - - write_update(paths, source_paragraph); - status_db->insert(std::make_unique(source_paragraph)); - - std::vector features_spghs; - for (auto&& feature : bcf.features) - { - features_spghs.emplace_back(); - - StatusParagraph& feature_paragraph = features_spghs.back(); - feature_paragraph.package = feature; - feature_paragraph.want = Want::INSTALL; - feature_paragraph.state = InstallState::HALF_INSTALLED; - - write_update(paths, feature_paragraph); - status_db->insert(std::make_unique(feature_paragraph)); - } - - 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); - - source_paragraph.state = InstallState::INSTALLED; - write_update(paths, source_paragraph); - status_db->insert(std::make_unique(source_paragraph)); - - for (auto&& feature_paragraph : features_spghs) - { - feature_paragraph.state = InstallState::INSTALLED; - write_update(paths, feature_paragraph); - status_db->insert(std::make_unique(feature_paragraph)); - } - - return InstallResult::SUCCESS; - } - - using Build::BuildResult; - - BuildResult perform_install_plan_action(const VcpkgPaths& paths, - const InstallPlanAction& action, - const Build::BuildPackageOptions& build_package_options, - StatusParagraphs& status_db) - { - const InstallPlanType& plan_type = action.plan_type; - const std::string display_name = action.spec.to_string(); - const std::string display_name_with_features = - GlobalState::feature_packages ? action.displayname() : display_name; - - const bool is_user_requested = action.request_type == RequestType::USER_REQUESTED; - const bool use_head_version = to_bool(build_package_options.use_head_version); - - if (plan_type == InstallPlanType::ALREADY_INSTALLED) - { - if (use_head_version && is_user_requested) - System::println( - System::Color::warning, "Package %s is already installed -- not building from HEAD", display_name); - else - System::println(System::Color::success, "Package %s is already installed", display_name); - return BuildResult::SUCCEEDED; - } - - if (plan_type == InstallPlanType::BUILD_AND_INSTALL) - { - if (use_head_version) - System::println("Building package %s from HEAD... ", display_name_with_features); - else - System::println("Building package %s... ", display_name_with_features); - - const auto result = [&]() -> Build::ExtendedBuildResult { - if (GlobalState::feature_packages) - { - const Build::BuildPackageConfig build_config{ - *action.any_paragraph.source_control_file.value_or_exit(VCPKG_LINE_INFO), - action.spec.triplet(), - paths.port_dir(action.spec), - build_package_options, - action.feature_list}; - return Build::build_package(paths, build_config, status_db); - } - else - { - const Build::BuildPackageConfig build_config{ - action.any_paragraph.source_paragraph.value_or_exit(VCPKG_LINE_INFO), - action.spec.triplet(), - paths.port_dir(action.spec), - build_package_options}; - return Build::build_package(paths, build_config, status_db); - } - }(); - - if (result.code != Build::BuildResult::SUCCEEDED) - { - System::println(System::Color::error, Build::create_error_message(result.code, action.spec)); - return result.code; - } - - System::println("Building package %s... done", display_name_with_features); - - const BinaryControlFile bcf = - Paragraphs::try_load_cached_control_package(paths, action.spec).value_or_exit(VCPKG_LINE_INFO); - System::println("Installing package %s... ", display_name_with_features); - const auto install_result = install_package(paths, bcf, &status_db); - switch (install_result) - { - case InstallResult::SUCCESS: - System::println(System::Color::success, "Installing package %s... done", display_name); - return BuildResult::SUCCEEDED; - case InstallResult::FILE_CONFLICTS: return BuildResult::FILE_CONFLICTS; - default: Checks::unreachable(VCPKG_LINE_INFO); - } - } - - if (plan_type == InstallPlanType::INSTALL) - { - if (use_head_version && is_user_requested) - { - System::println( - System::Color::warning, "Package %s is already built -- not building from HEAD", display_name); - } - System::println("Installing package %s... ", display_name); - const auto install_result = install_package( - paths, action.any_paragraph.binary_control_file.value_or_exit(VCPKG_LINE_INFO), &status_db); - switch (install_result) - { - case InstallResult::SUCCESS: - System::println(System::Color::success, "Installing package %s... done", display_name); - return BuildResult::SUCCEEDED; - case InstallResult::FILE_CONFLICTS: return BuildResult::FILE_CONFLICTS; - default: Checks::unreachable(VCPKG_LINE_INFO); - } - } - - Checks::unreachable(VCPKG_LINE_INFO); - } - - static void print_plan(const std::vector& action_plan, bool is_recursive) - { - std::vector remove_plans; - std::vector rebuilt_plans; - std::vector only_install_plans; - std::vector new_plans; - std::vector already_installed_plans; - - const bool has_non_user_requested_packages = Util::find_if(action_plan, [](const AnyAction& package) -> bool { - if (auto iplan = package.install_plan.get()) - return iplan->request_type != RequestType::USER_REQUESTED; - else - return false; - }) != action_plan.cend(); - - for (auto&& action : action_plan) - { - if (auto install_action = action.install_plan.get()) - { - // remove plans are guaranteed to come before install plans, so we know the plan will be contained if at - // all. - auto it = Util::find_if( - remove_plans, [&](const RemovePlanAction* plan) { return plan->spec == install_action->spec; }); - if (it != remove_plans.end()) - { - rebuilt_plans.emplace_back(install_action); - } - else - { - switch (install_action->plan_type) - { - case InstallPlanType::INSTALL: only_install_plans.emplace_back(install_action); break; - case InstallPlanType::ALREADY_INSTALLED: - if (install_action->request_type == RequestType::USER_REQUESTED) - already_installed_plans.emplace_back(install_action); - break; - case InstallPlanType::BUILD_AND_INSTALL: new_plans.emplace_back(install_action); break; - default: Checks::unreachable(VCPKG_LINE_INFO); - } - } - } - else if (auto remove_action = action.remove_plan.get()) - { - remove_plans.emplace_back(remove_action); - } - } - - std::sort(remove_plans.begin(), remove_plans.end(), &RemovePlanAction::compare_by_name); - std::sort(rebuilt_plans.begin(), rebuilt_plans.end(), &InstallPlanAction::compare_by_name); - std::sort(only_install_plans.begin(), only_install_plans.end(), &InstallPlanAction::compare_by_name); - std::sort(new_plans.begin(), new_plans.end(), &InstallPlanAction::compare_by_name); - std::sort(already_installed_plans.begin(), already_installed_plans.end(), &InstallPlanAction::compare_by_name); - - if (already_installed_plans.size() > 0) - { - const std::string already_string = - Strings::join("\n", already_installed_plans, [](const InstallPlanAction* p) { - return to_output_string(p->request_type, p->displayname()); - }); - System::println("The following packages are already installed:\n%s", already_string); - } - - if (rebuilt_plans.size() > 0) - { - const std::string rebuilt_string = Strings::join("\n", rebuilt_plans, [](const InstallPlanAction* p) { - return to_output_string(p->request_type, p->displayname()); - }); - System::println("The following packages will be rebuilt:\n%s", rebuilt_string); - } - - if (new_plans.size() > 0) - { - const std::string new_string = Strings::join("\n", new_plans, [](const InstallPlanAction* p) { - return to_output_string(p->request_type, p->displayname()); - }); - System::println("The following packages will be built and installed:\n%s", new_string); - } - - if (only_install_plans.size() > 0) - { - const std::string only_install_string = - Strings::join("\n", only_install_plans, [](const InstallPlanAction* p) { - return to_output_string(p->request_type, p->displayname()); - }); - System::println("The following packages will be directly installed:\n%s", only_install_string); - } - - if (has_non_user_requested_packages) - System::println("Additional packages (*) will be installed to complete this operation."); - - if (remove_plans.size() > 0 && !is_recursive) - { - System::println(System::Color::warning, - "If you are sure you want to rebuild the above packages, run the command with the " - "--recurse option"); - Checks::exit_fail(VCPKG_LINE_INFO); - } - } - - void perform_and_exit(const std::vector& action_plan, - const Build::BuildPackageOptions& install_plan_options, - const KeepGoing keep_going, - const PrintSummary print_summary, - const VcpkgPaths& paths, - StatusParagraphs& status_db) - { - std::vector results; - std::vector timing; - const ElapsedTime timer = ElapsedTime::create_started(); - size_t counter = 0; - const size_t package_count = action_plan.size(); - - for (const auto& action : action_plan) - { - const ElapsedTime build_timer = ElapsedTime::create_started(); - counter++; - - const std::string display_name = action.spec().to_string(); - System::println("Starting package %d/%d: %s", counter, package_count, display_name); - - timing.push_back("0"); - results.push_back(BuildResult::NULLVALUE); - - if (const auto install_action = action.install_plan.get()) - { - const BuildResult result = - perform_install_plan_action(paths, *install_action, install_plan_options, status_db); - if (result != BuildResult::SUCCEEDED && keep_going == KeepGoing::NO) - { - System::println(Build::create_user_troubleshooting_message(install_action->spec)); - Checks::exit_fail(VCPKG_LINE_INFO); - } - - results.back() = result; - } - else if (const auto remove_action = action.remove_plan.get()) - { - Checks::check_exit(VCPKG_LINE_INFO, GlobalState::feature_packages); - Remove::perform_remove_plan_action(paths, *remove_action, Remove::Purge::YES, status_db); - } - else - { - Checks::unreachable(VCPKG_LINE_INFO); - } - - timing.back() = build_timer.to_string(); - System::println("Elapsed time for package %s: %s", display_name, build_timer.to_string()); - } - - System::println("Total time taken: %s", timer.to_string()); - - if (print_summary == PrintSummary::YES) - { - for (size_t i = 0; i < results.size(); i++) - { - System::println("%s: %s: %s", action_plan[i].spec(), Build::to_string(results[i]), timing[i]); - } - - std::map summary; - for (const BuildResult& v : Build::BUILD_RESULT_VALUES) - { - summary[v] = 0; - } - - for (const BuildResult& r : results) - { - summary[r]++; - } - - System::println("\n\nSUMMARY"); - for (const std::pair& entry : summary) - { - System::println(" %s: %d", Build::to_string(entry.first), entry.second); - } - } - - Checks::exit_success(VCPKG_LINE_INFO); - } - - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) - { - static const std::string OPTION_DRY_RUN = "--dry-run"; - static const std::string OPTION_USE_HEAD_VERSION = "--head"; - static const std::string OPTION_NO_DOWNLOADS = "--no-downloads"; - static const std::string OPTION_RECURSE = "--recurse"; - static const std::string OPTION_KEEP_GOING = "--keep-going"; - - // input sanitization - static const std::string EXAMPLE = - Commands::Help::create_example_string("install zlib zlib:x64-windows curl boost"); - args.check_min_arg_count(1, EXAMPLE); - - const std::vector specs = Util::fmap(args.command_arguments, [&](auto&& arg) { - return Input::check_and_get_full_package_spec(arg, default_triplet, EXAMPLE); - }); - - for (auto&& spec : specs) - { - Input::check_triplet(spec.package_spec.triplet(), paths); - if (!spec.features.empty() && !GlobalState::feature_packages) - { - Checks::exit_with_message( - VCPKG_LINE_INFO, "Feature packages are experimentally available under the --featurepackages flag."); - } - } - - const std::unordered_set options = args.check_and_get_optional_command_arguments( - {OPTION_DRY_RUN, OPTION_USE_HEAD_VERSION, OPTION_NO_DOWNLOADS, OPTION_RECURSE, OPTION_KEEP_GOING}); - const bool dry_run = options.find(OPTION_DRY_RUN) != options.cend(); - const bool use_head_version = options.find(OPTION_USE_HEAD_VERSION) != options.cend(); - const bool no_downloads = options.find(OPTION_NO_DOWNLOADS) != options.cend(); - const bool is_recursive = options.find(OPTION_RECURSE) != options.cend(); - const KeepGoing keep_going = to_keep_going(options.find(OPTION_KEEP_GOING) != options.cend()); - - // create the plan - StatusParagraphs status_db = database_load_check(paths); - - const Build::BuildPackageOptions install_plan_options = {Build::to_use_head_version(use_head_version), - Build::to_allow_downloads(!no_downloads)}; - - std::vector action_plan; - - if (GlobalState::feature_packages) - { - std::unordered_map scf_map; - auto all_ports = Paragraphs::load_all_ports(paths.get_filesystem(), paths.ports); - for (auto&& port : all_ports) - { - scf_map[port->core_paragraph->name] = std::move(*port); - } - action_plan = create_feature_install_plan(scf_map, FullPackageSpec::to_feature_specs(specs), status_db); - } - else - { - Dependencies::PathsPortFile paths_port_file(paths); - auto install_plan = Dependencies::create_install_plan( - paths_port_file, Util::fmap(specs, [](auto&& spec) { return spec.package_spec; }), status_db); - - action_plan = Util::fmap( - install_plan, [](InstallPlanAction& install_action) { return AnyAction(std::move(install_action)); }); - } - - // install plan will be empty if it is already installed - need to change this at status paragraph part - Checks::check_exit(VCPKG_LINE_INFO, !action_plan.empty(), "Install plan cannot be empty"); - - // log the plan - const std::string specs_string = Strings::join(",", action_plan, [](const AnyAction& action) { - if (auto iaction = action.install_plan.get()) - return iaction->spec.to_string(); - else if (auto raction = action.remove_plan.get()) - return "R$" + raction->spec.to_string(); - Checks::unreachable(VCPKG_LINE_INFO); - }); - - Metrics::g_metrics.lock()->track_property("installplan", specs_string); - - print_plan(action_plan, is_recursive); - - if (dry_run) - { - Checks::exit_success(VCPKG_LINE_INFO); - } - - perform_and_exit(action_plan, install_plan_options, keep_going, PrintSummary::NO, paths, status_db); - - Checks::exit_success(VCPKG_LINE_INFO); - } -} diff --git a/toolsrc/src/commands_integrate.cpp b/toolsrc/src/commands_integrate.cpp deleted file mode 100644 index fd2f11294..000000000 --- a/toolsrc/src/commands_integrate.cpp +++ /dev/null @@ -1,342 +0,0 @@ -#include "pch.h" - -#include "vcpkg_Checks.h" -#include "vcpkg_Commands.h" -#include "vcpkg_Files.h" -#include "vcpkg_System.h" -#include "vcpkg_Util.h" - -namespace vcpkg::Commands::Integrate -{ - static const std::array OLD_SYSTEM_TARGET_FILES = { - System::get_program_files_32_bit() / "MSBuild/14.0/Microsoft.Common.Targets/ImportBefore/vcpkg.nuget.targets", - System::get_program_files_32_bit() / "MSBuild/14.0/Microsoft.Common.Targets/ImportBefore/vcpkg.system.targets"}; - static const fs::path SYSTEM_WIDE_TARGETS_FILE = - System::get_program_files_32_bit() / "MSBuild/Microsoft.Cpp/v4.0/V140/ImportBefore/Default/vcpkg.system.props"; - - static std::string create_appdata_targets_shortcut(const std::string& target_path) noexcept - { - return Strings::format(R"###( - - - -)###", - target_path, - target_path); - } - - static std::string create_system_targets_shortcut() noexcept - { - return R"###( - - - - $(LOCALAPPDATA)\vcpkg\vcpkg.user - - - -)###"; - } - - static std::string create_nuget_targets_file_contents(const fs::path& msbuild_vcpkg_targets_file) noexcept - { - const std::string as_string = msbuild_vcpkg_targets_file.string(); - - return Strings::format(R"###( - - - - - - -)###", - as_string, - as_string); - } - - static std::string create_nuget_props_file_contents() noexcept - { - return R"###( - - - true - - -)###"; - } - - static std::string get_nuget_id(const fs::path& vcpkg_root_dir) - { - std::string dir_id = vcpkg_root_dir.generic_string(); - std::replace(dir_id.begin(), dir_id.end(), '/', '.'); - dir_id.erase(1, 1); // Erasing the ":" - - // NuGet id cannot have invalid characters. We will only use alphanumeric and dot. - Util::erase_remove_if(dir_id, [](char c) { return !isalnum(c) && (c != '.'); }); - - const std::string nuget_id = "vcpkg." + dir_id; - return nuget_id; - } - - static std::string create_nuspec_file_contents(const fs::path& vcpkg_root_dir, - const std::string& nuget_id, - const std::string& nupkg_version) - { - static constexpr auto CONTENT_TEMPLATE = R"( - - - @NUGET_ID@ - @VERSION@ - vcpkg - - This package imports all libraries currently installed in @VCPKG_DIR@. This package does not contain any libraries and instead refers to the folder directly (like a symlink). - - - - - - - -)"; - - std::string content = std::regex_replace(CONTENT_TEMPLATE, std::regex("@NUGET_ID@"), nuget_id); - content = std::regex_replace(content, std::regex("@VCPKG_DIR@"), vcpkg_root_dir.string()); - content = std::regex_replace(content, std::regex("@VERSION@"), nupkg_version); - return content; - } - - enum class ElevationPromptChoice - { - YES, - NO - }; - - static ElevationPromptChoice elevated_cmd_execute(const std::string& param) - { - SHELLEXECUTEINFOW sh_ex_info = {0}; - sh_ex_info.cbSize = sizeof(sh_ex_info); - sh_ex_info.fMask = SEE_MASK_NOCLOSEPROCESS; - sh_ex_info.hwnd = nullptr; - sh_ex_info.lpVerb = L"runas"; - sh_ex_info.lpFile = L"cmd"; // Application to start - - auto wparam = Strings::to_utf16(param); - sh_ex_info.lpParameters = wparam.c_str(); // Additional parameters - sh_ex_info.lpDirectory = nullptr; - sh_ex_info.nShow = SW_HIDE; - sh_ex_info.hInstApp = nullptr; - - if (!ShellExecuteExW(&sh_ex_info)) - { - return ElevationPromptChoice::NO; - } - if (sh_ex_info.hProcess == nullptr) - { - return ElevationPromptChoice::NO; - } - WaitForSingleObject(sh_ex_info.hProcess, INFINITE); - CloseHandle(sh_ex_info.hProcess); - return ElevationPromptChoice::YES; - } - - static fs::path get_appdata_targets_path() - { - static const fs::path LOCAL_APP_DATA = - fs::path(System::get_environment_variable(L"LOCALAPPDATA").value_or_exit(VCPKG_LINE_INFO)); - return LOCAL_APP_DATA / "vcpkg" / "vcpkg.user.targets"; - } - - 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)) - { - const std::string param = - Strings::format(R"(/c DEL "%s" /Q > nul)", old_system_wide_targets_file.string()); - const ElevationPromptChoice user_choice = elevated_cmd_execute(param); - switch (user_choice) - { - case ElevationPromptChoice::YES: break; - case ElevationPromptChoice::NO: - System::println(System::Color::warning, "Warning: Previous integration file was not removed"); - Checks::exit_fail(VCPKG_LINE_INFO); - default: Checks::unreachable(VCPKG_LINE_INFO); - } - } - } - - std::error_code ec; - const fs::path tmp_dir = paths.buildsystems / "tmp"; - fs.create_directory(paths.buildsystems, ec); - fs.create_directory(tmp_dir, ec); - - bool should_install_system = true; - const Expected system_wide_file_contents = fs.read_contents(SYSTEM_WIDE_TARGETS_FILE); - static const std::regex RE(R"###()###"); - if (const auto contents_data = system_wide_file_contents.get()) - { - std::match_results match; - const auto found = std::regex_search(*contents_data, match, RE); - if (found) - { - const int ver = atoi(match[1].str().c_str()); - if (ver >= 1) should_install_system = false; - } - } - - if (should_install_system) - { - const fs::path sys_src_path = tmp_dir / "vcpkg.system.targets"; - 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()); - const ElevationPromptChoice user_choice = elevated_cmd_execute(param); - switch (user_choice) - { - case ElevationPromptChoice::YES: break; - case ElevationPromptChoice::NO: - System::println(System::Color::warning, "Warning: integration was not applied"); - Checks::exit_fail(VCPKG_LINE_INFO); - default: 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()); - } - - const fs::path appdata_src_path = tmp_dir / "vcpkg.user.targets"; - fs.write_contents(appdata_src_path, - create_appdata_targets_shortcut(paths.buildsystems_msbuild_targets.string())); - auto appdata_dst_path = get_appdata_targets_path(); - - const 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); - } - System::println(System::Color::success, "Applied user-wide integration for this vcpkg root."); - const fs::path cmake_toolchain = paths.buildsystems / "vcpkg.cmake"; - System::println("\n" - "All MSBuild C++ projects can now #include any installed libraries.\n" - "Linking will be handled automatically.\n" - "Installing new libraries will make them instantly available.\n" - "\n" - "CMake projects should use -DCMAKE_TOOLCHAIN_FILE=%s", - cmake_toolchain.generic_string()); - - Checks::exit_success(VCPKG_LINE_INFO); - } - - static void integrate_remove(Files::Filesystem& fs) - { - const fs::path path = get_appdata_targets_path(); - - std::error_code ec; - const bool was_deleted = fs.remove(path, ec); - - Checks::check_exit(VCPKG_LINE_INFO, !ec, "Error: Unable to remove user-wide integration: %d", ec.message()); - - if (was_deleted) - { - System::println(System::Color::success, "User-wide integration was removed"); - } - else - { - System::println(System::Color::success, "User-wide integration is not installed"); - } - - Checks::exit_success(VCPKG_LINE_INFO); - } - - 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"; - 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"; - const fs::path nuspec_file_path = tmp_dir / "vcpkg.nuget.nuspec"; - const std::string nuget_id = get_nuget_id(paths.root); - const std::string nupkg_version = "1.0.0"; - - fs.write_contents(targets_file_path, create_nuget_targets_file_contents(paths.buildsystems_msbuild_targets)); - fs.write_contents(props_file_path, create_nuget_props_file_contents()); - fs.write_contents(nuspec_file_path, create_nuspec_file_contents(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()); - - 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"); - System::println(System::Color::success, "Created nupkg: %s", nuget_package.string()); - - auto source_path = buildsystems_dir.u8string(); - source_path = std::regex_replace(source_path, std::regex("`"), "``"); - - System::println(R"( -With a project open, go to Tools->NuGet Package Manager->Package Manager Console and paste: - Install-Package %s -Source "%s" -)", - nuget_id, - source_path); - - Checks::exit_success(VCPKG_LINE_INFO); - } - - const char* const INTEGRATE_COMMAND_HELPSTRING = - " vcpkg integrate install Make installed packages available user-wide. Requires admin privileges on " - "first use\n" - " vcpkg integrate remove Remove user-wide integration\n" - " vcpkg integrate project Generate a referencing nuget package for individual VS project use\n"; - - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) - { - static const std::string EXAMPLE = Strings::format("Commands:\n" - "%s", - INTEGRATE_COMMAND_HELPSTRING); - args.check_exact_arg_count(1, EXAMPLE); - args.check_and_get_optional_command_arguments({}); - - if (args.command_arguments[0] == "install") - { - return integrate_install(paths); - } - if (args.command_arguments[0] == "remove") - { - return integrate_remove(paths.get_filesystem()); - } - if (args.command_arguments[0] == "project") - { - return integrate_project(paths); - } - - Checks::exit_with_message(VCPKG_LINE_INFO, "Unknown parameter %s for integrate", args.command_arguments[0]); - } -} diff --git a/toolsrc/src/commands_list.cpp b/toolsrc/src/commands_list.cpp deleted file mode 100644 index 640885860..000000000 --- a/toolsrc/src/commands_list.cpp +++ /dev/null @@ -1,74 +0,0 @@ -#include "pch.h" - -#include "vcpkg_Commands.h" -#include "vcpkg_System.h" -#include "vcpkglib.h" - -namespace vcpkg::Commands::List -{ - static const std::string OPTION_FULLDESC = "--x-full-desc"; // TODO: This should find a better home, eventually - - static void do_print(const StatusParagraph& pgh, bool full_desc) - { - if (full_desc) - { - System::println("%-30s %-16s %s", pgh.package.displayname(), pgh.package.version, pgh.package.description); - } - else - { - System::println("%-30s %-16s %s", - vcpkg::shorten_text(pgh.package.displayname(), 30), - vcpkg::shorten_text(pgh.package.version, 16), - vcpkg::shorten_text(pgh.package.description, 71)); - } - } - - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) - { - static const std::string EXAMPLE = Strings::format( - "The argument should be a substring to search for, or no argument to display all installed libraries.\n%s", - Commands::Help::create_example_string("list png")); - args.check_max_arg_count(1, EXAMPLE); - const std::unordered_set options = - args.check_and_get_optional_command_arguments({OPTION_FULLDESC}); - - const StatusParagraphs status_paragraphs = database_load_check(paths); - std::vector installed_packages = get_installed_ports(status_paragraphs); - - if (installed_packages.empty()) - { - System::println("No packages are installed. Did you mean `search`?"); - Checks::exit_success(VCPKG_LINE_INFO); - } - - std::sort(installed_packages.begin(), - installed_packages.end(), - [](const StatusParagraph* lhs, const StatusParagraph* rhs) -> bool { - return lhs->package.displayname() < rhs->package.displayname(); - }); - - if (args.command_arguments.size() == 0) - { - for (const StatusParagraph* status_paragraph : installed_packages) - { - do_print(*status_paragraph, options.find(OPTION_FULLDESC) != options.cend()); - } - } - else - { - // At this point there is 1 argument - for (const StatusParagraph* status_paragraph : installed_packages) - { - const std::string displayname = status_paragraph->package.displayname(); - if (Strings::case_insensitive_ascii_find(displayname, args.command_arguments[0]) == displayname.end()) - { - continue; - } - - do_print(*status_paragraph, options.find(OPTION_FULLDESC) != options.cend()); - } - } - - Checks::exit_success(VCPKG_LINE_INFO); - } -} diff --git a/toolsrc/src/commands_owns.cpp b/toolsrc/src/commands_owns.cpp deleted file mode 100644 index 718a0277f..000000000 --- a/toolsrc/src/commands_owns.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#include "pch.h" - -#include "vcpkg_Commands.h" -#include "vcpkg_System.h" -#include "vcpkglib.h" - -namespace vcpkg::Commands::Owns -{ - static void search_file(const VcpkgPaths& paths, const std::string& file_substr, const StatusParagraphs& status_db) - { - const std::vector installed_files = get_installed_files(paths, status_db); - for (const StatusParagraphAndAssociatedFiles& pgh_and_file : installed_files) - { - const StatusParagraph& pgh = pgh_and_file.pgh; - - for (const std::string& file : pgh_and_file.files) - { - if (file.find(file_substr) != std::string::npos) - { - System::println("%s: %s", pgh.package.displayname(), file); - } - } - } - } - - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) - { - static const std::string EXAMPLE = Strings::format("The argument should be a pattern to search for. %s", - Commands::Help::create_example_string("owns zlib.dll")); - args.check_exact_arg_count(1, EXAMPLE); - args.check_and_get_optional_command_arguments({}); - - StatusParagraphs status_db = database_load_check(paths); - search_file(paths, args.command_arguments[0], status_db); - Checks::exit_success(VCPKG_LINE_INFO); - } -} diff --git a/toolsrc/src/commands_portsdiff.cpp b/toolsrc/src/commands_portsdiff.cpp deleted file mode 100644 index 2334b2270..000000000 --- a/toolsrc/src/commands_portsdiff.cpp +++ /dev/null @@ -1,181 +0,0 @@ -#include "pch.h" - -#include "Paragraphs.h" -#include "SortedVector.h" -#include "vcpkg_Commands.h" -#include "vcpkg_Maps.h" -#include "vcpkg_System.h" - -namespace vcpkg::Commands::PortsDiff -{ - struct UpdatedPort - { - static bool compare_by_name(const UpdatedPort& left, const UpdatedPort& right) - { - return left.port < right.port; - } - - std::string port; - VersionDiff version_diff; - }; - - template - struct SetElementPresence - { - static SetElementPresence create(std::vector left, std::vector right) - { - // TODO: This can be done with one pass instead of three passes - SetElementPresence output; - std::set_difference( - left.cbegin(), left.cend(), right.cbegin(), right.cend(), std::back_inserter(output.only_left)); - std::set_intersection( - left.cbegin(), left.cend(), right.cbegin(), right.cend(), std::back_inserter(output.both)); - std::set_difference( - right.cbegin(), right.cend(), left.cbegin(), left.cend(), std::back_inserter(output.only_right)); - - return output; - } - - std::vector only_left; - std::vector both; - std::vector only_right; - }; - - static std::vector find_updated_ports( - const std::vector& ports, - const std::map& previous_names_and_versions, - const std::map& current_names_and_versions) - { - std::vector output; - for (const std::string& name : ports) - { - const VersionT& previous_version = previous_names_and_versions.at(name); - const VersionT& current_version = current_names_and_versions.at(name); - if (previous_version == current_version) - { - continue; - } - - output.push_back({name, VersionDiff(previous_version, current_version)}); - } - - return output; - } - - static void do_print_name_and_version(const std::vector& ports_to_print, - const std::map& names_and_versions) - { - for (const std::string& name : ports_to_print) - { - const VersionT& version = names_and_versions.at(name); - System::println(" - %-14s %-16s", name, version); - } - } - - static std::map 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, 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)", - git_exe.native(), - dot_git_dir.native(), - temp_checkout_path.native(), - git_commit_id, - checkout_this_dir, - L".vcpkg-root", - git_exe.native()); - System::cmd_execute_clean(cmd); - const std::map names_and_versions = Paragraphs::load_all_port_names_and_versions( - paths.get_filesystem(), temp_checkout_path / ports_dir_name_as_string); - fs.remove_all(temp_checkout_path, ec); - return names_and_versions; - } - - static void check_commit_exists(const fs::path& git_exe, const std::wstring& git_commit_id) - { - static const std::string VALID_COMMIT_OUTPUT = "commit\n"; - - const std::wstring cmd = Strings::wformat(LR"("%s" cat-file -t %s)", git_exe.native(), git_commit_id); - const System::ExitCodeAndOutput output = System::cmd_execute_and_capture_output(cmd); - Checks::check_exit(VCPKG_LINE_INFO, - output.output == VALID_COMMIT_OUTPUT, - "Invalid commit id %s", - Strings::to_utf8(git_commit_id)); - } - - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) - { - static const std::string EXAMPLE = - Strings::format("The argument should be a branch/tag/hash to checkout.\n%s", - Commands::Help::create_example_string("portsdiff mybranchname")); - args.check_min_arg_count(1, EXAMPLE); - args.check_max_arg_count(2, EXAMPLE); - args.check_and_get_optional_command_arguments({}); - - const fs::path& git_exe = paths.get_git_exe(); - - const std::wstring git_commit_id_for_previous_snapshot = Strings::to_utf16(args.command_arguments.at(0)); - const std::wstring git_commit_id_for_current_snapshot = - args.command_arguments.size() < 2 ? L"HEAD" : Strings::to_utf16(args.command_arguments.at(1)); - - check_commit_exists(git_exe, git_commit_id_for_current_snapshot); - check_commit_exists(git_exe, git_commit_id_for_previous_snapshot); - - const std::map current_names_and_versions = - read_ports_from_commit(paths, git_commit_id_for_current_snapshot); - const std::map previous_names_and_versions = - read_ports_from_commit(paths, git_commit_id_for_previous_snapshot); - - // Already sorted, so set_difference can work on std::vector too - const std::vector current_ports = Maps::extract_keys(current_names_and_versions); - const std::vector previous_ports = Maps::extract_keys(previous_names_and_versions); - - const SetElementPresence setp = - SetElementPresence::create(current_ports, previous_ports); - - const std::vector& added_ports = setp.only_left; - if (!added_ports.empty()) - { - System::println("\nThe following %d ports were added:", added_ports.size()); - do_print_name_and_version(added_ports, current_names_and_versions); - } - - const std::vector& removed_ports = setp.only_right; - if (!removed_ports.empty()) - { - System::println("\nThe following %d ports were removed:", removed_ports.size()); - do_print_name_and_version(removed_ports, previous_names_and_versions); - } - - const std::vector& common_ports = setp.both; - const std::vector updated_ports = - find_updated_ports(common_ports, previous_names_and_versions, current_names_and_versions); - - if (!updated_ports.empty()) - { - System::println("\nThe following %d ports were updated:", updated_ports.size()); - for (const UpdatedPort& p : updated_ports) - { - System::println(" - %-14s %-16s", p.port, p.version_diff.to_string()); - } - } - - if (added_ports.empty() && removed_ports.empty() && updated_ports.empty()) - { - System::println("There were no changes in the ports between the two commits."); - } - - Checks::exit_success(VCPKG_LINE_INFO); - } -} diff --git a/toolsrc/src/commands_remove.cpp b/toolsrc/src/commands_remove.cpp deleted file mode 100644 index a9f1b2564..000000000 --- a/toolsrc/src/commands_remove.cpp +++ /dev/null @@ -1,249 +0,0 @@ -#include "pch.h" - -#include "vcpkg_Commands.h" -#include "vcpkg_Dependencies.h" -#include "vcpkg_Input.h" -#include "vcpkg_System.h" -#include "vcpkg_Util.h" -#include "vcpkglib.h" - -namespace vcpkg::Commands::Remove -{ - using Dependencies::RemovePlanAction; - using Dependencies::RemovePlanType; - using Dependencies::RequestType; - using Update::OutdatedPackage; - - void remove_package(const VcpkgPaths& paths, const PackageSpec& spec, StatusParagraphs* status_db) - { - auto& fs = paths.get_filesystem(); - auto spghs = status_db->find_all(spec.name(), spec.triplet()); - const auto core_pkg = **status_db->find(spec.name(), spec.triplet(), Strings::EMPTY); - - for (auto&& spgh : spghs) - { - StatusParagraph& pkg = **spgh; - if (pkg.state != InstallState::INSTALLED) continue; - pkg.want = Want::PURGE; - pkg.state = InstallState::HALF_INSTALLED; - write_update(paths, pkg); - } - - auto maybe_lines = fs.read_lines(paths.listfile_path(core_pkg.package)); - - if (const auto lines = maybe_lines.get()) - { - std::vector dirs_touched; - for (auto&& suffix : *lines) - { - if (!suffix.empty() && suffix.back() == '\r') suffix.pop_back(); - - std::error_code ec; - - auto target = paths.installed / suffix; - - const auto status = fs.status(target, ec); - if (ec) - { - System::println(System::Color::error, "failed: %s", ec.message()); - continue; - } - - if (fs::is_directory(status)) - { - dirs_touched.push_back(target); - } - else if (fs::is_regular_file(status)) - { - fs.remove(target, ec); - if (ec) - { - System::println(System::Color::error, "failed: %s: %s", target.u8string(), ec.message()); - } - } - else if (!fs::status_known(status)) - { - System::println(System::Color::warning, "Warning: unknown status: %s", target.u8string()); - } - else - { - System::println(System::Color::warning, "Warning: %s: cannot handle file type", target.u8string()); - } - } - - auto b = dirs_touched.rbegin(); - const auto e = dirs_touched.rend(); - for (; b != e; ++b) - { - if (fs.is_empty(*b)) - { - std::error_code ec; - fs.remove(*b, ec); - if (ec) - { - System::println(System::Color::error, "failed: %s", ec.message()); - } - } - } - - fs.remove(paths.listfile_path(core_pkg.package)); - } - - for (auto&& spgh : spghs) - { - StatusParagraph& pkg = **spgh; - if (pkg.state != InstallState::HALF_INSTALLED) continue; - pkg.state = InstallState::NOT_INSTALLED; - write_update(paths, pkg); - } - } - - static void print_plan(const std::map>& group_by_plan_type) - { - static constexpr std::array ORDER = {RemovePlanType::NOT_INSTALLED, RemovePlanType::REMOVE}; - - for (const RemovePlanType plan_type : ORDER) - { - const auto it = group_by_plan_type.find(plan_type); - if (it == group_by_plan_type.cend()) - { - continue; - } - - std::vector cont = it->second; - std::sort(cont.begin(), cont.end(), &RemovePlanAction::compare_by_name); - const std::string as_string = Strings::join("\n", cont, [](const RemovePlanAction* p) { - return Dependencies::to_output_string(p->request_type, p->spec.to_string()); - }); - - switch (plan_type) - { - case RemovePlanType::NOT_INSTALLED: - System::println("The following packages are not installed, so not removed:\n%s", as_string); - continue; - case RemovePlanType::REMOVE: - System::println("The following packages will be removed:\n%s", as_string); - continue; - default: Checks::unreachable(VCPKG_LINE_INFO); - } - } - } - - void perform_remove_plan_action(const VcpkgPaths& paths, - const RemovePlanAction& action, - const Purge purge, - StatusParagraphs& status_db) - { - const std::string display_name = action.spec.to_string(); - - switch (action.plan_type) - { - case RemovePlanType::NOT_INSTALLED: - System::println(System::Color::success, "Package %s is not installed", display_name); - break; - case RemovePlanType::REMOVE: - System::println("Removing package %s... ", display_name); - remove_package(paths, action.spec, &status_db); - System::println(System::Color::success, "Removing package %s... done", display_name); - break; - case RemovePlanType::UNKNOWN: - default: Checks::unreachable(VCPKG_LINE_INFO); - } - - if (purge == Purge::YES) - { - System::println("Purging package %s... ", display_name); - Files::Filesystem& fs = paths.get_filesystem(); - std::error_code ec; - fs.remove_all(paths.packages / action.spec.dir(), ec); - System::println(System::Color::success, "Purging package %s... done", display_name); - } - } - - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) - { - static const std::string OPTION_PURGE = "--purge"; - static const std::string OPTION_NO_PURGE = "--no-purge"; - static const std::string OPTION_RECURSE = "--recurse"; - static const std::string OPTION_DRY_RUN = "--dry-run"; - static const std::string OPTION_OUTDATED = "--outdated"; - static const std::string EXAMPLE = - Commands::Help::create_example_string("remove zlib zlib:x64-windows curl boost"); - const std::unordered_set options = args.check_and_get_optional_command_arguments( - {OPTION_PURGE, OPTION_NO_PURGE, OPTION_RECURSE, OPTION_DRY_RUN, OPTION_OUTDATED}); - - StatusParagraphs status_db = database_load_check(paths); - std::vector specs; - if (options.find(OPTION_OUTDATED) != options.cend()) - { - args.check_exact_arg_count(0, EXAMPLE); - specs = Util::fmap(Update::find_outdated_packages(paths, status_db), - [](auto&& outdated) { return outdated.spec; }); - - if (specs.empty()) - { - System::println(System::Color::success, "There are no outdated packages."); - Checks::exit_success(VCPKG_LINE_INFO); - } - } - else - { - args.check_min_arg_count(1, EXAMPLE); - specs = Util::fmap(args.command_arguments, [&](auto&& arg) { - return Input::check_and_get_package_spec(arg, default_triplet, EXAMPLE); - }); - - for (auto&& spec : specs) - Input::check_triplet(spec.triplet(), paths); - } - - const bool no_purge_was_passed = options.find(OPTION_NO_PURGE) != options.end(); - const bool purge_was_passed = options.find(OPTION_PURGE) != options.end(); - if (purge_was_passed && no_purge_was_passed) - { - System::println(System::Color::error, "Error: cannot specify both --no-purge and --purge."); - System::print(EXAMPLE); - Checks::exit_fail(VCPKG_LINE_INFO); - } - const Purge purge = to_purge(purge_was_passed || !no_purge_was_passed); - const bool is_recursive = options.find(OPTION_RECURSE) != options.cend(); - const bool dry_run = options.find(OPTION_DRY_RUN) != options.cend(); - - const std::vector remove_plan = Dependencies::create_remove_plan(specs, status_db); - Checks::check_exit(VCPKG_LINE_INFO, !remove_plan.empty(), "Remove plan cannot be empty"); - - std::map> group_by_plan_type; - Util::group_by(remove_plan, &group_by_plan_type, [](const RemovePlanAction& p) { return p.plan_type; }); - print_plan(group_by_plan_type); - - const bool has_non_user_requested_packages = - Util::find_if(remove_plan, [](const RemovePlanAction& package) -> bool { - return package.request_type != RequestType::USER_REQUESTED; - }) != remove_plan.cend(); - - if (has_non_user_requested_packages) - { - System::println(System::Color::warning, - "Additional packages (*) need to be removed to complete this operation."); - - if (!is_recursive) - { - System::println(System::Color::warning, - "If you are sure you want to remove them, run the command with the --recurse option"); - Checks::exit_fail(VCPKG_LINE_INFO); - } - } - - if (dry_run) - { - Checks::exit_success(VCPKG_LINE_INFO); - } - - for (const RemovePlanAction& action : remove_plan) - { - perform_remove_plan_action(paths, action, purge, status_db); - } - - Checks::exit_success(VCPKG_LINE_INFO); - } -} diff --git a/toolsrc/src/commands_search.cpp b/toolsrc/src/commands_search.cpp deleted file mode 100644 index d35a546c4..000000000 --- a/toolsrc/src/commands_search.cpp +++ /dev/null @@ -1,145 +0,0 @@ -#include "pch.h" - -#include "Paragraphs.h" -#include "SourceParagraph.h" -#include "vcpkg_Commands.h" -#include "vcpkg_GlobalState.h" -#include "vcpkg_System.h" -#include "vcpkglib.h" - -namespace vcpkg::Commands::Search -{ - static const std::string OPTION_GRAPH = "--graph"; // TODO: This should find a better home, eventually - static const std::string OPTION_FULLDESC = "--x-full-desc"; // TODO: This should find a better home, eventually - - static std::string replace_dashes_with_underscore(const std::string& input) - { - std::string output = input; - std::replace(output.begin(), output.end(), '-', '_'); - return output; - } - - static std::string create_graph_as_string( - const std::vector>& source_control_files) - { - int empty_node_count = 0; - - std::string s; - s.append("digraph G{ rankdir=LR; edge [minlen=3]; overlap=false;"); - - for (const auto& source_control_file : source_control_files) - { - const SourceParagraph& source_paragraph = *source_control_file->core_paragraph; - if (source_paragraph.depends.empty()) - { - empty_node_count++; - continue; - } - - const std::string name = replace_dashes_with_underscore(source_paragraph.name); - s.append(Strings::format("%s;", name)); - for (const Dependency& d : source_paragraph.depends) - { - const std::string dependency_name = replace_dashes_with_underscore(d.name()); - s.append(Strings::format("%s -> %s;", name, dependency_name)); - } - } - - s.append(Strings::format("empty [label=\"%d singletons...\"]; }", empty_node_count)); - return s; - } - static void do_print(const SourceParagraph& source_paragraph, bool full_desc) - { - if (full_desc) - { - System::println( - "%-20s %-16s %s", source_paragraph.name, source_paragraph.version, source_paragraph.description); - } - else - { - System::println("%-20s %-16s %s", - vcpkg::shorten_text(source_paragraph.name, 20), - vcpkg::shorten_text(source_paragraph.version, 16), - vcpkg::shorten_text(source_paragraph.description, 81)); - } - } - - static void do_print(const std::string& name, const FeatureParagraph& feature_paragraph, bool full_desc) - { - if (full_desc) - { - System::println("%-37s %s", name + "[" + feature_paragraph.name + "]", feature_paragraph.description); - } - else - { - System::println("%-37s %s", - vcpkg::shorten_text(name + "[" + feature_paragraph.name + "]", 37), - vcpkg::shorten_text(feature_paragraph.description, 81)); - } - } - - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) - { - static const std::string EXAMPLE = Strings::format( - "The argument should be a substring to search for, or no argument to display all libraries.\n%s", - Commands::Help::create_example_string("search png")); - args.check_max_arg_count(1, EXAMPLE); - const std::unordered_set options = - args.check_and_get_optional_command_arguments({OPTION_GRAPH, OPTION_FULLDESC}); - - auto 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); - System::println(graph_as_string); - Checks::exit_success(VCPKG_LINE_INFO); - } - - if (args.command_arguments.empty()) - { - for (const auto& source_control_file : source_paragraphs) - { - do_print(*source_control_file->core_paragraph, options.find(OPTION_FULLDESC) != options.cend()); - for (auto&& feature_paragraph : source_control_file->feature_paragraphs) - { - do_print(source_control_file->core_paragraph->name, - *feature_paragraph, - options.find(OPTION_FULLDESC) != options.cend()); - } - } - } - else - { - const auto& icontains = Strings::case_insensitive_ascii_contains; - - // At this point there is 1 argument - auto&& args_zero = args.command_arguments[0]; - for (const auto& source_control_file : source_paragraphs) - { - auto&& sp = *source_control_file->core_paragraph; - - bool contains_name = icontains(sp.name, args_zero); - if (contains_name || icontains(sp.description, args_zero)) - { - do_print(sp, options.find(OPTION_FULLDESC) != options.cend()); - } - - for (auto&& feature_paragraph : source_control_file->feature_paragraphs) - { - if (contains_name || icontains(feature_paragraph->name, args_zero) || - icontains(feature_paragraph->description, args_zero)) - { - do_print(sp.name, *feature_paragraph, options.find(OPTION_FULLDESC) != options.cend()); - } - } - } - } - - System::println( - "\nIf your library is not listed, please open an issue at and/or consider making a pull request:\n" - " https://github.com/Microsoft/vcpkg/issues"); - - Checks::exit_success(VCPKG_LINE_INFO); - } -} diff --git a/toolsrc/src/commands_update.cpp b/toolsrc/src/commands_update.cpp deleted file mode 100644 index 71ea4b063..000000000 --- a/toolsrc/src/commands_update.cpp +++ /dev/null @@ -1,73 +0,0 @@ -#include "pch.h" - -#include "Paragraphs.h" -#include "vcpkg_Commands.h" -#include "vcpkg_System.h" -#include "vcpkglib.h" - -namespace vcpkg::Commands::Update -{ - bool OutdatedPackage::compare_by_name(const OutdatedPackage& left, const OutdatedPackage& right) - { - return left.spec.name() < right.spec.name(); - } - - std::vector find_outdated_packages(const VcpkgPaths& paths, const StatusParagraphs& status_db) - { - const std::map src_names_to_versions = - Paragraphs::load_all_port_names_and_versions(paths.get_filesystem(), paths.ports); - const std::vector installed_packages = get_installed_ports(status_db); - - std::vector output; - for (const StatusParagraph* pgh : installed_packages) - { - const auto it = src_names_to_versions.find(pgh->package.spec.name()); - if (it == src_names_to_versions.end()) - { - // Package was not installed from portfile - continue; - } - if (it->second != pgh->package.version) - { - output.push_back({pgh->package.spec, VersionDiff(pgh->package.version, it->second)}); - } - } - - return output; - } - - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) - { - args.check_exact_arg_count(0); - args.check_and_get_optional_command_arguments({}); - System::println("Using local portfile versions. To update the local portfiles, use `git pull`."); - - const StatusParagraphs status_db = database_load_check(paths); - - const auto outdated_packages = - SortedVector(find_outdated_packages(paths, status_db), &OutdatedPackage::compare_by_name); - - if (outdated_packages.empty()) - { - System::println("No packages need updating."); - } - else - { - std::string install_line; - System::println("The following packages differ from their port versions:"); - for (auto&& package : outdated_packages) - { - install_line += package.spec.to_string(); - install_line += " "; - System::println(" %-32s %s", package.spec, package.version_diff.to_string()); - } - System::println("\n" - "To update these packages, run\n" - " .\\vcpkg remove --outdated\n" - " .\\vcpkg install " + - install_line); - } - - Checks::exit_success(VCPKG_LINE_INFO); - } -} diff --git a/toolsrc/src/commands_version.cpp b/toolsrc/src/commands_version.cpp deleted file mode 100644 index 5744ea9ef..000000000 --- a/toolsrc/src/commands_version.cpp +++ /dev/null @@ -1,67 +0,0 @@ -#include "pch.h" - -#include "metrics.h" -#include "vcpkg_Commands.h" -#include "vcpkg_System.h" - -#define STRINGIFY(...) #__VA_ARGS__ -#define MACRO_TO_STRING(X) STRINGIFY(X) - -#define VCPKG_VERSION_AS_STRING MACRO_TO_STRING(VCPKG_VERSION) - -namespace vcpkg::Commands::Version -{ - const std::string& version() - { - static const std::string S_VERSION = -#include "../VERSION.txt" - - +std::string(VCPKG_VERSION_AS_STRING) -#ifndef NDEBUG - + std::string("-debug") -#endif - + std::string(Metrics::get_compiled_metrics_enabled() ? Strings::EMPTY : "-external"); - return S_VERSION; - } - - void warn_if_vcpkg_version_mismatch(const VcpkgPaths& paths) - { - auto version_file = paths.get_filesystem().read_contents(paths.root / "toolsrc" / "VERSION.txt"); - if (const auto version_contents = version_file.get()) - { - int maj1, min1, rev1; - const auto num1 = sscanf_s(version_contents->c_str(), "\"%d.%d.%d\"", &maj1, &min1, &rev1); - - int maj2, min2, rev2; - const auto num2 = sscanf_s(Version::version().c_str(), "%d.%d.%d-", &maj2, &min2, &rev2); - - if (num1 == 3 && num2 == 3) - { - if (maj1 != maj2 || min1 != min2 || rev1 != rev2) - { - System::println(System::Color::warning, - "Warning: Different source is available for vcpkg (%d.%d.%d -> %d.%d.%d). Use " - ".\\bootstrap-vcpkg.bat to update.", - maj2, - min2, - rev2, - maj1, - min1, - rev1); - } - } - } - } - - void perform_and_exit(const VcpkgCmdArguments& args) - { - args.check_exact_arg_count(0); - args.check_and_get_optional_command_arguments({}); - - System::println("Vcpkg package management program version %s\n" - "\n" - "See LICENSE.txt for license information.", - version()); - Checks::exit_success(VCPKG_LINE_INFO); - } -} diff --git a/toolsrc/src/metrics.cpp b/toolsrc/src/metrics.cpp deleted file mode 100644 index 8a0050bfc..000000000 --- a/toolsrc/src/metrics.cpp +++ /dev/null @@ -1,395 +0,0 @@ -#include "pch.h" - -#include "filesystem_fs.h" -#include "metrics.h" -#include "vcpkg_Files.h" -#include "vcpkg_Strings.h" -#include "vcpkg_System.h" - -namespace vcpkg::Metrics -{ - Util::LockGuarded g_metrics; - - static std::string get_current_date_time() - { - struct tm newtime; - std::array date; - date.fill(0); - - struct _timeb timebuffer; - - _ftime_s(&timebuffer); - time_t now = timebuffer.time; - const int milli = timebuffer.millitm; - - const errno_t err = gmtime_s(&newtime, &now); - if (err) - { - return Strings::EMPTY; - } - - strftime(&date[0], date.size(), "%Y-%m-%dT%H:%M:%S", &newtime); - return std::string(&date[0]) + "." + std::to_string(milli) + "Z"; - } - - static std::string generate_random_UUID() - { - int part_sizes[] = {8, 4, 4, 4, 12}; - char uuid[37]; - memset(uuid, 0, sizeof(uuid)); - int num; - srand(static_cast(time(nullptr))); - int index = 0; - for (int part = 0; part < 5; part++) - { - if (part > 0) - { - uuid[index] = '-'; - index++; - } - - // Generating UUID format version 4 - // http://en.wikipedia.org/wiki/Universally_unique_identifier - for (int i = 0; i < part_sizes[part]; i++, index++) - { - if (part == 2 && i == 0) - { - num = 4; - } - else if (part == 4 && i == 0) - { - num = (rand() % 4) + 8; - } - else - { - num = rand() % 16; - } - - if (num < 10) - { - uuid[index] = static_cast('0' + num); - } - else - { - uuid[index] = static_cast('a' + (num - 10)); - } - } - } - - return uuid; - } - - static const std::string& get_session_id() - { - static const std::string ID = generate_random_UUID(); - return ID; - } - - static std::string to_json_string(const std::string& str) - { - std::string encoded = "\""; - for (auto&& ch : str) - { - if (ch == '\\') - { - encoded.append("\\\\"); - } - else if (ch == '"') - { - encoded.append("\\\""); - } - else if (ch < 0x20 || ch >= 0x80) - { - // Note: this treats incoming Strings as Latin-1 - static constexpr const char HEX[16] = { - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; - encoded.append("\\u00"); - encoded.push_back(HEX[ch / 16]); - encoded.push_back(HEX[ch % 16]); - } - else - { - encoded.push_back(ch); - } - } - encoded.push_back('"'); - return encoded; - } - - static std::string get_os_version_string() - { - std::wstring path; - path.resize(MAX_PATH); - const auto n = GetSystemDirectoryW(&path[0], static_cast(path.size())); - path.resize(n); - path += L"\\kernel32.dll"; - - const auto versz = GetFileVersionInfoSizeW(path.c_str(), nullptr); - if (versz == 0) return Strings::EMPTY; - - std::vector verbuf; - verbuf.resize(versz); - - if (!GetFileVersionInfoW(path.c_str(), 0, static_cast(verbuf.size()), &verbuf[0])) return Strings::EMPTY; - - void* rootblock; - UINT rootblocksize; - if (!VerQueryValueW(&verbuf[0], L"\\", &rootblock, &rootblocksize)) return Strings::EMPTY; - - auto rootblock_ffi = static_cast(rootblock); - - return Strings::format("%d.%d.%d", - static_cast(HIWORD(rootblock_ffi->dwProductVersionMS)), - static_cast(LOWORD(rootblock_ffi->dwProductVersionMS)), - static_cast(HIWORD(rootblock_ffi->dwProductVersionLS))); - } - - struct MetricMessage - { - std::string user_id = generate_random_UUID(); - std::string user_timestamp; - std::string timestamp = get_current_date_time(); - std::string properties; - std::string measurements; - - void track_property(const std::string& name, const std::string& value) - { - if (properties.size() != 0) properties.push_back(','); - properties.append(to_json_string(name)); - properties.push_back(':'); - properties.append(to_json_string(value)); - } - - void track_metric(const std::string& name, double value) - { - if (measurements.size() != 0) measurements.push_back(','); - measurements.append(to_json_string(name)); - measurements.push_back(':'); - measurements.append(std::to_string(value)); - } - - std::string format_event_data_template() const - { - const std::string& session_id = get_session_id(); - return Strings::format(R"([{ - "ver": 1, - "name": "Microsoft.ApplicationInsights.Event", - "time": "%s", - "sampleRate": 100.000000, - "seq": "0:0", - "iKey": "b4e88960-4393-4dd9-ab8e-97e8fe6d7603", - "flags": 0.000000, - "tags": { - "ai.device.os": "Windows", - "ai.device.osVersion": "%s", - "ai.session.id": "%s", - "ai.user.id": "%s", - "ai.user.accountAcquisitionDate": "%s" - }, - "data": { - "baseType": "EventData", - "baseData": { - "ver": 2, - "name": "commandline_test7", - "properties": { %s }, - "measurements": { %s } - } - } -}])", - timestamp, - get_os_version_string(), - session_id, - user_id, - user_timestamp, - properties, - measurements); - } - }; - - static MetricMessage g_metricmessage; - static bool g_should_send_metrics = -#if defined(NDEBUG) && (DISABLE_METRICS == 0) - true -#else - false -#endif - ; - static bool g_should_print_metrics = false; - - bool get_compiled_metrics_enabled() { return DISABLE_METRICS == 0; } - - std::wstring get_SQM_user() - { - auto hkcu_sqmclient = - System::get_registry_string(HKEY_CURRENT_USER, LR"(Software\Microsoft\SQMClient)", L"UserId"); - return hkcu_sqmclient.value_or(L"{}"); - } - - void Metrics::set_user_information(const std::string& user_id, const std::string& first_use_time) - { - g_metricmessage.user_id = user_id; - g_metricmessage.user_timestamp = first_use_time; - } - - void Metrics::init_user_information(std::string& user_id, std::string& first_use_time) - { - user_id = generate_random_UUID(); - first_use_time = get_current_date_time(); - } - - void Metrics::set_send_metrics(bool should_send_metrics) { g_should_send_metrics = should_send_metrics; } - - void Metrics::set_print_metrics(bool should_print_metrics) { g_should_print_metrics = should_print_metrics; } - - void Metrics::track_metric(const std::string& name, double value) { g_metricmessage.track_metric(name, value); } - - void Metrics::track_property(const std::string& name, const std::wstring& value) - { - // Note: this is not valid UTF-16 -> UTF-8, it just yields a close enough approximation for our purposes. - std::string converted_value; - converted_value.resize(value.size()); - std::transform( - value.begin(), value.end(), converted_value.begin(), [](wchar_t ch) { return static_cast(ch); }); - - g_metricmessage.track_property(name, converted_value); - } - - void Metrics::track_property(const std::string& name, const std::string& value) - { - g_metricmessage.track_property(name, value); - } - - void Metrics::upload(const std::string& payload) - { - HINTERNET connect = nullptr, request = nullptr; - BOOL results = FALSE; - - const HINTERNET session = WinHttpOpen( - L"vcpkg/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); - if (session) connect = WinHttpConnect(session, L"dc.services.visualstudio.com", INTERNET_DEFAULT_HTTPS_PORT, 0); - - if (connect) - request = WinHttpOpenRequest(connect, - L"POST", - L"/v2/track", - nullptr, - WINHTTP_NO_REFERER, - WINHTTP_DEFAULT_ACCEPT_TYPES, - WINHTTP_FLAG_SECURE); - - if (request) - { - if (MAXDWORD <= payload.size()) abort(); - std::wstring hdrs = L"Content-Type: application/json\r\n"; - std::string& p = const_cast(payload); - results = WinHttpSendRequest(request, - hdrs.c_str(), - static_cast(hdrs.size()), - static_cast(&p[0]), - static_cast(payload.size()), - static_cast(payload.size()), - 0); - } - - if (results) - { - results = WinHttpReceiveResponse(request, nullptr); - } - - DWORD http_code = 0, junk = sizeof(DWORD); - - if (results) - { - results = WinHttpQueryHeaders(request, - WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, - nullptr, - &http_code, - &junk, - WINHTTP_NO_HEADER_INDEX); - } - - std::vector response_buffer; - if (results) - { - DWORD available_data = 0, read_data = 0, total_data = 0; - while ((results = WinHttpQueryDataAvailable(request, &available_data)) == TRUE && available_data > 0) - { - response_buffer.resize(response_buffer.size() + available_data); - - results = WinHttpReadData(request, &response_buffer.data()[total_data], available_data, &read_data); - - if (!results) - { - break; - } - - total_data += read_data; - - response_buffer.resize(total_data); - } - } - - if (!results) - { -#ifndef NDEBUG - __debugbreak(); - auto err = GetLastError(); - std::cerr << "[DEBUG] failed to connect to server: " << err << "\n"; -#endif - } - - if (request) WinHttpCloseHandle(request); - if (connect) WinHttpCloseHandle(connect); - if (session) WinHttpCloseHandle(session); - } - - static fs::path get_bindir() - { - wchar_t buf[_MAX_PATH]; - const int bytes = GetModuleFileNameW(nullptr, buf, _MAX_PATH); - if (bytes == 0) std::abort(); - return fs::path(buf, buf + bytes); - } - - void Metrics::flush() - { - const std::string payload = g_metricmessage.format_event_data_template(); - if (g_should_print_metrics) std::cerr << payload << "\n"; - if (!g_should_send_metrics) return; - - // upload(payload); - - wchar_t temp_folder[MAX_PATH]; - GetTempPathW(MAX_PATH, temp_folder); - - 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]() -> fs::path { - auto vcpkgdir = get_bindir().parent_path(); - auto path = vcpkgdir / "vcpkgmetricsuploader.exe"; - if (fs.exists(path)) return path; - - path = vcpkgdir / "scripts" / "vcpkgmetricsuploader.exe"; - if (fs.exists(path)) return path; - - return Strings::WEMPTY; - }(); - - std::error_code 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"); - fs.write_contents(vcpkg_metrics_txt_path, payload); - - const std::wstring cmd_line = - Strings::wformat(L"start %s %s", temp_folder_path_exe.native(), vcpkg_metrics_txt_path.native()); - System::cmd_execute_clean(cmd_line); - } -} diff --git a/toolsrc/src/test_install_plan.cpp b/toolsrc/src/test_install_plan.cpp deleted file mode 100644 index 6c9311264..000000000 --- a/toolsrc/src/test_install_plan.cpp +++ /dev/null @@ -1,486 +0,0 @@ -#include "CppUnitTest.h" -#include "vcpkg_Dependencies.h" -#include "vcpkg_Util.h" - -using namespace Microsoft::VisualStudio::CppUnitTestFramework; - -using namespace vcpkg; - -namespace Microsoft::VisualStudio::CppUnitTestFramework -{ - template<> - inline std::wstring ToString(const vcpkg::Dependencies::InstallPlanType& t) - { - switch (t) - { - case Dependencies::InstallPlanType::ALREADY_INSTALLED: return L"ALREADY_INSTALLED"; - case Dependencies::InstallPlanType::BUILD_AND_INSTALL: return L"BUILD_AND_INSTALL"; - case Dependencies::InstallPlanType::INSTALL: return L"INSTALL"; - case Dependencies::InstallPlanType::UNKNOWN: return L"UNKNOWN"; - default: return ToString((int)t); - } - } - - template<> - inline std::wstring ToString(const vcpkg::Dependencies::RequestType& t) - { - switch (t) - { - case Dependencies::RequestType::AUTO_SELECTED: return L"AUTO_SELECTED"; - case Dependencies::RequestType::USER_REQUESTED: return L"USER_REQUESTED"; - case Dependencies::RequestType::UNKNOWN: return L"UNKNOWN"; - default: return ToString((int)t); - } - } -} - -namespace UnitTest1 -{ - class InstallPlanTests : public TestClass - { - static std::unique_ptr make_control_file( - const char* name, - const char* depends, - const std::vector>& features = {}) - { - using Pgh = std::unordered_map; - std::vector scf_pghs; - scf_pghs.push_back(Pgh{ - {"Source", name}, - {"Version", "0"}, - {"Build-Depends", depends}, - }); - for (auto&& feature : features) - { - scf_pghs.push_back(Pgh{ - {"Feature", feature.first}, - {"Description", "feature"}, - {"Build-Depends", feature.second}, - }); - } - auto m_pgh = vcpkg::SourceControlFile::parse_control_file(std::move(scf_pghs)); - Assert::IsTrue(m_pgh.has_value()); - return std::move(*m_pgh.get()); - } - - static void features_check(Dependencies::AnyAction* install_action, - std::string pkg_name, - std::vector vec, - const Triplet& triplet = Triplet::X86_WINDOWS) - { - const auto& plan = install_action->install_plan.value_or_exit(VCPKG_LINE_INFO); - const auto& feature_list = plan.feature_list; - - Assert::AreEqual(plan.spec.triplet().to_string().c_str(), triplet.to_string().c_str()); - - Assert::AreEqual(pkg_name.c_str(), - (*plan.any_paragraph.source_control_file.get())->core_paragraph->name.c_str()); - Assert::AreEqual(size_t(vec.size()), feature_list.size()); - - for (auto&& feature_name : vec) - { - if (feature_name == "core" || feature_name == "") - { - Assert::IsTrue(Util::find(feature_list, "core") != feature_list.end() || - Util::find(feature_list, "") != feature_list.end()); - continue; - } - Assert::IsTrue(Util::find(feature_list, feature_name) != feature_list.end()); - } - } - - static void remove_plan_check(Dependencies::AnyAction* remove_action, - std::string pkg_name, - const Triplet& triplet = Triplet::X86_WINDOWS) - { - const auto& plan = remove_action->remove_plan.value_or_exit(VCPKG_LINE_INFO); - Assert::AreEqual(plan.spec.triplet().to_string().c_str(), triplet.to_string().c_str()); - Assert::AreEqual(pkg_name.c_str(), plan.spec.name().c_str()); - } - - static std::unique_ptr make_status_pgh(const char* name, const char* depends = "") - { - using Pgh = std::unordered_map; - return std::make_unique(Pgh{{"Package", name}, - {"Version", "1"}, - {"Architecture", "x86-windows"}, - {"Multi-Arch", "same"}, - {"Depends", depends}, - {"Status", "install ok installed"}}); - } - static std::unique_ptr make_status_feature_pgh(const char* name, - const char* feature, - const char* depends = "") - { - using Pgh = std::unordered_map; - return std::make_unique(Pgh{{"Package", name}, - {"Version", "1"}, - {"Feature", feature}, - {"Architecture", "x86-windows"}, - {"Multi-Arch", "same"}, - {"Depends", depends}, - {"Status", "install ok installed"}}); - } - struct PackageSpecMap - { - std::unordered_map map; - Triplet triplet; - PackageSpecMap(const Triplet& t) { triplet = t; } - - PackageSpec emplace(const char* name, - const char* depends = "", - const std::vector>& features = {}) - { - return emplace(std::move(*make_control_file(name, depends, features))); - } - PackageSpec emplace(vcpkg::SourceControlFile&& scf) - { - auto spec = PackageSpec::from_name_and_triplet(scf.core_paragraph->name, triplet); - Assert::IsTrue(spec.has_value()); - map.emplace(scf.core_paragraph->name, std::move(scf)); - return PackageSpec{*spec.get()}; - } - }; - - TEST_METHOD(basic_install_scheme) - { - std::vector> status_paragraphs; - - PackageSpecMap spec_map(Triplet::X86_WINDOWS); - auto spec_a = spec_map.emplace("a", "b"); - auto spec_b = spec_map.emplace("b", "c"); - auto spec_c = spec_map.emplace("c"); - - Dependencies::MapPortFile map_port(spec_map.map); - auto install_plan = - Dependencies::create_install_plan(map_port, {spec_a}, StatusParagraphs(std::move(status_paragraphs))); - - Assert::AreEqual(size_t(3), install_plan.size()); - Assert::AreEqual("c", install_plan[0].spec.name().c_str()); - Assert::AreEqual("b", install_plan[1].spec.name().c_str()); - Assert::AreEqual("a", install_plan[2].spec.name().c_str()); - } - - TEST_METHOD(multiple_install_scheme) - { - std::vector> status_paragraphs; - - PackageSpecMap spec_map(Triplet::X86_WINDOWS); - auto spec_a = spec_map.emplace("a", "d"); - auto spec_b = spec_map.emplace("b", "d, e"); - auto spec_c = spec_map.emplace("c", "e, h"); - auto spec_d = spec_map.emplace("d", "f, g, h"); - auto spec_e = spec_map.emplace("e", "g"); - auto spec_f = spec_map.emplace("f"); - auto spec_g = spec_map.emplace("g"); - auto spec_h = spec_map.emplace("h"); - - Dependencies::MapPortFile map_port(spec_map.map); - auto install_plan = Dependencies::create_install_plan( - map_port, {spec_a, spec_b, spec_c}, StatusParagraphs(std::move(status_paragraphs))); - - auto iterator_pos = [&](const PackageSpec& spec) -> int { - auto it = std::find_if( - install_plan.begin(), install_plan.end(), [&](auto& action) { return action.spec == spec; }); - Assert::IsTrue(it != install_plan.end()); - return (int)(it - install_plan.begin()); - }; - - int a_pos = iterator_pos(spec_a), b_pos = iterator_pos(spec_b), c_pos = iterator_pos(spec_c), - d_pos = iterator_pos(spec_d), e_pos = iterator_pos(spec_e), f_pos = iterator_pos(spec_f), - g_pos = iterator_pos(spec_g), h_pos = iterator_pos(spec_h); - - Assert::IsTrue(a_pos > d_pos); - Assert::IsTrue(b_pos > e_pos); - Assert::IsTrue(b_pos > d_pos); - Assert::IsTrue(c_pos > e_pos); - Assert::IsTrue(c_pos > h_pos); - Assert::IsTrue(d_pos > f_pos); - Assert::IsTrue(d_pos > g_pos); - Assert::IsTrue(d_pos > h_pos); - Assert::IsTrue(e_pos > g_pos); - } - - TEST_METHOD(existing_package_scheme) - { - std::vector> status_paragraphs; - status_paragraphs.push_back(make_status_pgh("a")); - - PackageSpecMap spec_map(Triplet::X86_WINDOWS); - auto spec_a = FullPackageSpec{spec_map.emplace("a")}; - - auto install_plan = - Dependencies::create_feature_install_plan(spec_map.map, - FullPackageSpec::to_feature_specs({spec_a}), - StatusParagraphs(std::move(status_paragraphs))); - - Assert::AreEqual(size_t(1), install_plan.size()); - auto p = install_plan[0].install_plan.get(); - Assert::IsNotNull(p); - Assert::AreEqual("a", p->spec.name().c_str()); - Assert::AreEqual(Dependencies::InstallPlanType::ALREADY_INSTALLED, p->plan_type); - Assert::AreEqual(Dependencies::RequestType::USER_REQUESTED, p->request_type); - } - - TEST_METHOD(user_requested_package_scheme) - { - std::vector> status_paragraphs; - - PackageSpecMap spec_map(Triplet::X86_WINDOWS); - auto spec_a = FullPackageSpec{spec_map.emplace("a", "b")}; - auto spec_b = FullPackageSpec{spec_map.emplace("b")}; - - auto install_plan = - Dependencies::create_feature_install_plan(spec_map.map, - FullPackageSpec::to_feature_specs({spec_a}), - StatusParagraphs(std::move(status_paragraphs))); - - Assert::AreEqual(size_t(2), install_plan.size()); - auto p = install_plan[0].install_plan.get(); - Assert::IsNotNull(p); - Assert::AreEqual("b", p->spec.name().c_str()); - Assert::AreEqual(Dependencies::InstallPlanType::BUILD_AND_INSTALL, p->plan_type); - Assert::AreEqual(Dependencies::RequestType::AUTO_SELECTED, p->request_type); - - auto p2 = install_plan[1].install_plan.get(); - Assert::IsNotNull(p2); - Assert::AreEqual("a", p2->spec.name().c_str()); - Assert::AreEqual(Dependencies::InstallPlanType::BUILD_AND_INSTALL, p2->plan_type); - Assert::AreEqual(Dependencies::RequestType::USER_REQUESTED, p2->request_type); - } - - TEST_METHOD(long_install_scheme) - { - std::vector> status_paragraphs; - status_paragraphs.push_back(make_status_pgh("j", "k")); - status_paragraphs.push_back(make_status_pgh("k")); - - PackageSpecMap spec_map(Triplet::X86_WINDOWS); - - auto spec_a = spec_map.emplace("a", "b, c, d, e, f, g, h, j, k"); - auto spec_b = spec_map.emplace("b", "c, d, e, f, g, h, j, k"); - auto spec_c = spec_map.emplace("c", "d, e, f, g, h, j, k"); - auto spec_d = spec_map.emplace("d", "e, f, g, h, j, k"); - auto spec_e = spec_map.emplace("e", "f, g, h, j, k"); - auto spec_f = spec_map.emplace("f", "g, h, j, k"); - auto spec_g = spec_map.emplace("g", "h, j, k"); - auto spec_h = spec_map.emplace("h", "j, k"); - auto spec_j = spec_map.emplace("j", "k"); - auto spec_k = spec_map.emplace("k"); - - Dependencies::MapPortFile map_port(spec_map.map); - auto install_plan = - Dependencies::create_install_plan(map_port, {spec_a}, StatusParagraphs(std::move(status_paragraphs))); - - Assert::AreEqual(size_t(8), install_plan.size()); - Assert::AreEqual("h", install_plan[0].spec.name().c_str()); - Assert::AreEqual("g", install_plan[1].spec.name().c_str()); - Assert::AreEqual("f", install_plan[2].spec.name().c_str()); - Assert::AreEqual("e", install_plan[3].spec.name().c_str()); - Assert::AreEqual("d", install_plan[4].spec.name().c_str()); - Assert::AreEqual("c", install_plan[5].spec.name().c_str()); - Assert::AreEqual("b", install_plan[6].spec.name().c_str()); - Assert::AreEqual("a", install_plan[7].spec.name().c_str()); - } - - TEST_METHOD(basic_feature_test_1) - { - std::vector> status_paragraphs; - status_paragraphs.push_back(make_status_pgh("a", "b, b[b1]")); - status_paragraphs.push_back(make_status_pgh("b")); - status_paragraphs.push_back(make_status_feature_pgh("b", "b1")); - - PackageSpecMap spec_map(Triplet::X86_WINDOWS); - auto spec_a = FullPackageSpec{spec_map.emplace("a", "b, b[b1]", {{"a1", "b[b2]"}}), {"a1"}}; - auto spec_b = FullPackageSpec{spec_map.emplace("b", "", {{"b1", ""}, {"b2", ""}, {"b3", ""}})}; - - auto install_plan = - Dependencies::create_feature_install_plan(spec_map.map, - FullPackageSpec::to_feature_specs({spec_a}), - StatusParagraphs(std::move(status_paragraphs))); - - Assert::AreEqual(size_t(4), install_plan.size()); - remove_plan_check(&install_plan[0], "a"); - remove_plan_check(&install_plan[1], "b"); - features_check(&install_plan[2], "b", {"b1", "core", "b1"}); - features_check(&install_plan[3], "a", {"a1", "core"}); - } - - TEST_METHOD(basic_feature_test_2) - { - std::vector> status_paragraphs; - - PackageSpecMap spec_map(Triplet::X86_WINDOWS); - - auto spec_a = FullPackageSpec{spec_map.emplace("a", "b[b1]", {{"a1", "b[b2]"}}), {"a1"}}; - auto spec_b = FullPackageSpec{spec_map.emplace("b", "", {{"b1", ""}, {"b2", ""}, {"b3", ""}})}; - - auto install_plan = - Dependencies::create_feature_install_plan(spec_map.map, - FullPackageSpec::to_feature_specs({spec_a}), - StatusParagraphs(std::move(status_paragraphs))); - - Assert::AreEqual(size_t(2), install_plan.size()); - features_check(&install_plan[0], "b", {"b1", "b2", "core"}); - features_check(&install_plan[1], "a", {"a1", "core"}); - } - - TEST_METHOD(basic_feature_test_3) - { - std::vector> status_paragraphs; - status_paragraphs.push_back(make_status_pgh("a")); - - PackageSpecMap spec_map(Triplet::X86_WINDOWS); - - auto spec_a = FullPackageSpec{spec_map.emplace("a", "b", {{"a1", ""}}), {"core"}}; - auto spec_b = FullPackageSpec{spec_map.emplace("b")}; - auto spec_c = FullPackageSpec{spec_map.emplace("c", "a[a1]"), {"core"}}; - - auto install_plan = - Dependencies::create_feature_install_plan(spec_map.map, - FullPackageSpec::to_feature_specs({spec_c, spec_a}), - StatusParagraphs(std::move(status_paragraphs))); - - Assert::AreEqual(size_t(4), install_plan.size()); - remove_plan_check(&install_plan[0], "a"); - features_check(&install_plan[1], "b", {"core"}); - features_check(&install_plan[2], "a", {"a1", "core"}); - features_check(&install_plan[3], "c", {"core"}); - } - - TEST_METHOD(basic_feature_test_4) - { - std::vector> status_paragraphs; - status_paragraphs.push_back(make_status_pgh("a")); - status_paragraphs.push_back(make_status_feature_pgh("a", "a1", "")); - - PackageSpecMap spec_map(Triplet::X86_WINDOWS); - - auto spec_a = FullPackageSpec{spec_map.emplace("a", "b", {{"a1", ""}})}; - auto spec_b = FullPackageSpec{spec_map.emplace("b")}; - auto spec_c = FullPackageSpec{spec_map.emplace("c", "a[a1]"), {"core"}}; - - auto install_plan = - Dependencies::create_feature_install_plan(spec_map.map, - FullPackageSpec::to_feature_specs({spec_c}), - StatusParagraphs(std::move(status_paragraphs))); - - Assert::AreEqual(size_t(1), install_plan.size()); - features_check(&install_plan[0], "c", {"core"}); - } - - TEST_METHOD(basic_feature_test_5) - { - std::vector> status_paragraphs; - - PackageSpecMap spec_map(Triplet::X86_WINDOWS); - - auto spec_a = - FullPackageSpec{spec_map.emplace("a", "", {{"a1", "b[b1]"}, {"a2", "b[b2]"}, {"a3", "a[a2]"}}), {"a3"}}; - auto spec_b = FullPackageSpec{spec_map.emplace("b", "", {{"b1", ""}, {"b2", ""}})}; - - auto install_plan = - Dependencies::create_feature_install_plan(spec_map.map, - FullPackageSpec::to_feature_specs({spec_a}), - StatusParagraphs(std::move(status_paragraphs))); - - Assert::AreEqual(size_t(2), install_plan.size()); - features_check(&install_plan[0], "b", {"core", "b2"}); - features_check(&install_plan[1], "a", {"core", "a3", "a2"}); - } - - TEST_METHOD(basic_feature_test_6) - { - std::vector> status_paragraphs; - status_paragraphs.push_back(make_status_pgh("b")); - - PackageSpecMap spec_map(Triplet::X86_WINDOWS); - auto spec_a = FullPackageSpec{spec_map.emplace("a", "b[core]"), {"core"}}; - auto spec_b = FullPackageSpec{spec_map.emplace("b", "", {{"b1", ""}}), {"b1"}}; - - auto install_plan = - Dependencies::create_feature_install_plan(spec_map.map, - FullPackageSpec::to_feature_specs({spec_a, spec_b}), - StatusParagraphs(std::move(status_paragraphs))); - - Assert::AreEqual(size_t(3), install_plan.size()); - remove_plan_check(&install_plan[0], "b"); - features_check(&install_plan[1], "b", {"core", "b1"}); - features_check(&install_plan[2], "a", {"core"}); - } - - TEST_METHOD(basic_feature_test_7) - { - std::vector> status_paragraphs; - status_paragraphs.push_back(make_status_pgh("x", "b")); - status_paragraphs.push_back(make_status_pgh("b")); - - PackageSpecMap spec_map(Triplet::X86_WINDOWS); - - auto spec_a = FullPackageSpec{spec_map.emplace("a")}; - auto spec_x = FullPackageSpec{spec_map.emplace("x", "a"), {"core"}}; - auto spec_b = FullPackageSpec{spec_map.emplace("b", "", {{"b1", ""}}), {"b1"}}; - - auto install_plan = - Dependencies::create_feature_install_plan(spec_map.map, - FullPackageSpec::to_feature_specs({spec_b}), - StatusParagraphs(std::move(status_paragraphs))); - - Assert::AreEqual(size_t(5), install_plan.size()); - remove_plan_check(&install_plan[0], "x"); - remove_plan_check(&install_plan[1], "b"); - - // TODO: order here may change but A < X, and B anywhere - features_check(&install_plan[2], "b", {"core", "b1"}); - features_check(&install_plan[3], "a", {"core"}); - features_check(&install_plan[4], "x", {"core"}); - } - - TEST_METHOD(basic_feature_test_8) - { - std::vector> status_paragraphs; - status_paragraphs.push_back(make_status_pgh("a")); - status_paragraphs.push_back(make_status_pgh("a")); - status_paragraphs.back()->package.spec = - PackageSpec::from_name_and_triplet("a", Triplet::X64_WINDOWS).value_or_exit(VCPKG_LINE_INFO); - - PackageSpecMap spec_map(Triplet::X64_WINDOWS); - auto spec_a_64 = FullPackageSpec{spec_map.emplace("a", "b", {{"a1", ""}}), {"core"}}; - auto spec_b_64 = FullPackageSpec{spec_map.emplace("b")}; - auto spec_c_64 = FullPackageSpec{spec_map.emplace("c", "a[a1]"), {"core"}}; - - spec_map.triplet = Triplet::X86_WINDOWS; - auto spec_a_86 = FullPackageSpec{spec_map.emplace("a", "b", {{"a1", ""}}), {"core"}}; - auto spec_b_86 = FullPackageSpec{spec_map.emplace("b")}; - auto spec_c_86 = FullPackageSpec{spec_map.emplace("c", "a[a1]"), {"core"}}; - - auto install_plan = Dependencies::create_feature_install_plan( - spec_map.map, - FullPackageSpec::to_feature_specs({spec_c_64, spec_a_86, spec_a_64, spec_c_86}), - StatusParagraphs(std::move(status_paragraphs))); - - /*Assert::AreEqual(size_t(8), install_plan.size()); - auto iterator_pos = [&](const PackageSpec& spec, size_t start) -> int { - auto it = std::find_if(install_plan.begin() + start, install_plan.end(), [&](auto& action) { - return action.spec == spec; - }); - Assert::IsTrue(it != install_plan.end()); - return (int)(it - install_plan.begin()); - }; - int a_64_1 = iterator_pos(spec_a_64.package_spec, 0), a_86_1 = iterator_pos(spec_a_86.package_spec, 0), - b_64 = iterator_pos(spec_b_64.package_spec, 0), b_86 = iterator_pos(spec_b_86.package_spec, 0), - c_64 = iterator_pos(spec_c_64.package_spec, 0), c_86 = iterator_pos(spec_c_86.package_spec, 0), - a_64_2 = iterator_pos(spec_a_64.package_spec, a_64_1 + 1), - a_86_2 = iterator_pos(spec_a_86.package_spec, a_86_1 + 1);*/ - - remove_plan_check(&install_plan[0], "a", Triplet::X64_WINDOWS); - remove_plan_check(&install_plan[1], "a"); - features_check(&install_plan[2], "b", {"core"}, Triplet::X64_WINDOWS); - features_check(&install_plan[3], "a", {"a1", "core"}, Triplet::X64_WINDOWS); - features_check(&install_plan[4], "c", {"core"}, Triplet::X64_WINDOWS); - features_check(&install_plan[5], "b", {"core"}); - features_check(&install_plan[6], "a", {"a1", "core"}); - features_check(&install_plan[7], "c", {"core"}); - } - }; -} \ No newline at end of file diff --git a/toolsrc/src/tests.arguments.cpp b/toolsrc/src/tests.arguments.cpp new file mode 100644 index 000000000..25bf0f085 --- /dev/null +++ b/toolsrc/src/tests.arguments.cpp @@ -0,0 +1,58 @@ +#include +#include + +#pragma comment(lib, "version") +#pragma comment(lib, "winhttp") + +using namespace Microsoft::VisualStudio::CppUnitTestFramework; + +using namespace vcpkg; + +namespace UnitTest1 +{ + class ArgumentTests : public TestClass + { + TEST_METHOD(create_from_arg_sequence_options_lower) + { + std::vector t = {"--vcpkg-root", "C:\\vcpkg", "--debug", "--sendmetrics", "--printmetrics"}; + auto v = VcpkgCmdArguments::create_from_arg_sequence(t.data(), t.data() + t.size()); + Assert::AreEqual("C:\\vcpkg", v.vcpkg_root_dir.get()->c_str()); + Assert::IsTrue(v.debug && *v.debug.get()); + Assert::IsTrue(v.sendmetrics && v.sendmetrics.get()); + Assert::IsTrue(v.printmetrics && *v.printmetrics.get()); + } + + TEST_METHOD(create_from_arg_sequence_options_upper) + { + std::vector t = {"--VCPKG-ROOT", "C:\\vcpkg", "--DEBUG", "--SENDMETRICS", "--PRINTMETRICS"}; + auto v = VcpkgCmdArguments::create_from_arg_sequence(t.data(), t.data() + t.size()); + Assert::AreEqual("C:\\vcpkg", v.vcpkg_root_dir.get()->c_str()); + Assert::IsTrue(v.debug && *v.debug.get()); + Assert::IsTrue(v.sendmetrics && v.sendmetrics.get()); + Assert::IsTrue(v.printmetrics && *v.printmetrics.get()); + } + + TEST_METHOD(create_from_arg_sequence_valued_options) + { + std::vector t = {"--a=b", "command", "argument"}; + auto v = VcpkgCmdArguments::create_from_arg_sequence(t.data(), t.data() + t.size()); + auto opts = v.check_and_get_optional_command_arguments({}, {"--a"}); + Assert::AreEqual("b", opts.settings["--a"].c_str()); + Assert::AreEqual(size_t{1}, v.command_arguments.size()); + Assert::AreEqual("argument", v.command_arguments[0].c_str()); + Assert::AreEqual("command", v.command.c_str()); + } + + TEST_METHOD(create_from_arg_sequence_valued_options2) + { + std::vector t = {"--a", "--b=c"}; + auto v = VcpkgCmdArguments::create_from_arg_sequence(t.data(), t.data() + t.size()); + auto opts = v.check_and_get_optional_command_arguments({"--a", "--c"}, {"--b", "--d"}); + Assert::AreEqual("c", opts.settings["--b"].c_str()); + Assert::IsTrue(opts.settings.find("--d") == opts.settings.end()); + Assert::IsTrue(opts.switches.find("--a") != opts.switches.end()); + Assert::IsTrue(opts.settings.find("--c") == opts.settings.end()); + Assert::AreEqual(size_t{0}, v.command_arguments.size()); + } + }; +} \ No newline at end of file diff --git a/toolsrc/src/tests.dependencies.cpp b/toolsrc/src/tests.dependencies.cpp new file mode 100644 index 000000000..3f6e0dd10 --- /dev/null +++ b/toolsrc/src/tests.dependencies.cpp @@ -0,0 +1,110 @@ +#include +#include +#include + +#pragma comment(lib, "version") +#pragma comment(lib, "winhttp") + +using namespace Microsoft::VisualStudio::CppUnitTestFramework; + +using namespace vcpkg; +using Parse::parse_comma_list; + +namespace UnitTest1 +{ + class DependencyTests : public TestClass + { + TEST_METHOD(parse_depends_one) + { + auto v = expand_qualified_dependencies(parse_comma_list("libA (windows)")); + Assert::AreEqual(size_t(1), v.size()); + Assert::AreEqual("libA", v[0].depend.name.c_str()); + Assert::AreEqual("windows", v[0].qualifier.c_str()); + } + + TEST_METHOD(filter_depends) + { + auto deps = expand_qualified_dependencies(parse_comma_list("libA (windows), libB, libC (uwp)")); + auto v = filter_dependencies(deps, Triplet::X64_WINDOWS); + Assert::AreEqual(size_t(2), v.size()); + Assert::AreEqual("libA", v[0].c_str()); + Assert::AreEqual("libB", v[1].c_str()); + + auto v2 = filter_dependencies(deps, Triplet::ARM_UWP); + Assert::AreEqual(size_t(2), v.size()); + Assert::AreEqual("libB", v2[0].c_str()); + Assert::AreEqual("libC", v2[1].c_str()); + } + }; + + class SupportsTests : public TestClass + { + TEST_METHOD(parse_supports_all) + { + auto v = Supports::parse({ + "x64", + "x86", + "arm", + "windows", + "uwp", + "v140", + "v141", + "crt-static", + "crt-dynamic", + }); + Assert::AreNotEqual(uintptr_t(0), uintptr_t(v.get())); + + Assert::IsTrue(v.get()->is_supported(System::CPUArchitecture::X64, + Supports::Platform::UWP, + Supports::Linkage::DYNAMIC, + Supports::ToolsetVersion::V140)); + Assert::IsTrue(v.get()->is_supported(System::CPUArchitecture::ARM, + Supports::Platform::WINDOWS, + Supports::Linkage::STATIC, + Supports::ToolsetVersion::V141)); + } + + TEST_METHOD(parse_supports_invalid) + { + auto v = Supports::parse({"arm64"}); + Assert::AreEqual(uintptr_t(0), uintptr_t(v.get())); + Assert::AreEqual(size_t(1), v.error().size()); + Assert::AreEqual("arm64", v.error()[0].c_str()); + } + + TEST_METHOD(parse_supports_case_sensitive) + { + auto v = Supports::parse({"Windows"}); + Assert::AreEqual(uintptr_t(0), uintptr_t(v.get())); + Assert::AreEqual(size_t(1), v.error().size()); + Assert::AreEqual("Windows", v.error()[0].c_str()); + } + + TEST_METHOD(parse_supports_some) + { + auto v = Supports::parse({ + "x64", + "x86", + "windows", + }); + Assert::AreNotEqual(uintptr_t(0), uintptr_t(v.get())); + + Assert::IsTrue(v.get()->is_supported(System::CPUArchitecture::X64, + Supports::Platform::WINDOWS, + Supports::Linkage::DYNAMIC, + Supports::ToolsetVersion::V140)); + Assert::IsFalse(v.get()->is_supported(System::CPUArchitecture::ARM, + Supports::Platform::WINDOWS, + Supports::Linkage::DYNAMIC, + Supports::ToolsetVersion::V140)); + Assert::IsFalse(v.get()->is_supported(System::CPUArchitecture::X64, + Supports::Platform::UWP, + Supports::Linkage::DYNAMIC, + Supports::ToolsetVersion::V140)); + Assert::IsTrue(v.get()->is_supported(System::CPUArchitecture::X64, + Supports::Platform::WINDOWS, + Supports::Linkage::STATIC, + Supports::ToolsetVersion::V141)); + } + }; +} diff --git a/toolsrc/src/tests.installplan.cpp b/toolsrc/src/tests.installplan.cpp new file mode 100644 index 000000000..120009db5 --- /dev/null +++ b/toolsrc/src/tests.installplan.cpp @@ -0,0 +1,487 @@ +#include +#include + +#include + +using namespace Microsoft::VisualStudio::CppUnitTestFramework; + +using namespace vcpkg; + +namespace Microsoft::VisualStudio::CppUnitTestFramework +{ + template<> + inline std::wstring ToString(const vcpkg::Dependencies::InstallPlanType& t) + { + switch (t) + { + case Dependencies::InstallPlanType::ALREADY_INSTALLED: return L"ALREADY_INSTALLED"; + case Dependencies::InstallPlanType::BUILD_AND_INSTALL: return L"BUILD_AND_INSTALL"; + case Dependencies::InstallPlanType::INSTALL: return L"INSTALL"; + case Dependencies::InstallPlanType::UNKNOWN: return L"UNKNOWN"; + default: return ToString((int)t); + } + } + + template<> + inline std::wstring ToString(const vcpkg::Dependencies::RequestType& t) + { + switch (t) + { + case Dependencies::RequestType::AUTO_SELECTED: return L"AUTO_SELECTED"; + case Dependencies::RequestType::USER_REQUESTED: return L"USER_REQUESTED"; + case Dependencies::RequestType::UNKNOWN: return L"UNKNOWN"; + default: return ToString((int)t); + } + } +} + +namespace UnitTest1 +{ + class InstallPlanTests : public TestClass + { + static std::unique_ptr make_control_file( + const char* name, + const char* depends, + const std::vector>& features = {}) + { + using Pgh = std::unordered_map; + std::vector scf_pghs; + scf_pghs.push_back(Pgh{ + {"Source", name}, + {"Version", "0"}, + {"Build-Depends", depends}, + }); + for (auto&& feature : features) + { + scf_pghs.push_back(Pgh{ + {"Feature", feature.first}, + {"Description", "feature"}, + {"Build-Depends", feature.second}, + }); + } + auto m_pgh = vcpkg::SourceControlFile::parse_control_file(std::move(scf_pghs)); + Assert::IsTrue(m_pgh.has_value()); + return std::move(*m_pgh.get()); + } + + static void features_check(Dependencies::AnyAction* install_action, + std::string pkg_name, + std::vector vec, + const Triplet& triplet = Triplet::X86_WINDOWS) + { + const auto& plan = install_action->install_plan.value_or_exit(VCPKG_LINE_INFO); + const auto& feature_list = plan.feature_list; + + Assert::AreEqual(plan.spec.triplet().to_string().c_str(), triplet.to_string().c_str()); + + Assert::AreEqual(pkg_name.c_str(), + (*plan.any_paragraph.source_control_file.get())->core_paragraph->name.c_str()); + Assert::AreEqual(size_t(vec.size()), feature_list.size()); + + for (auto&& feature_name : vec) + { + if (feature_name == "core" || feature_name == "") + { + Assert::IsTrue(Util::find(feature_list, "core") != feature_list.end() || + Util::find(feature_list, "") != feature_list.end()); + continue; + } + Assert::IsTrue(Util::find(feature_list, feature_name) != feature_list.end()); + } + } + + static void remove_plan_check(Dependencies::AnyAction* remove_action, + std::string pkg_name, + const Triplet& triplet = Triplet::X86_WINDOWS) + { + const auto& plan = remove_action->remove_plan.value_or_exit(VCPKG_LINE_INFO); + Assert::AreEqual(plan.spec.triplet().to_string().c_str(), triplet.to_string().c_str()); + Assert::AreEqual(pkg_name.c_str(), plan.spec.name().c_str()); + } + + static std::unique_ptr make_status_pgh(const char* name, const char* depends = "") + { + using Pgh = std::unordered_map; + return std::make_unique(Pgh{{"Package", name}, + {"Version", "1"}, + {"Architecture", "x86-windows"}, + {"Multi-Arch", "same"}, + {"Depends", depends}, + {"Status", "install ok installed"}}); + } + static std::unique_ptr make_status_feature_pgh(const char* name, + const char* feature, + const char* depends = "") + { + using Pgh = std::unordered_map; + return std::make_unique(Pgh{{"Package", name}, + {"Version", "1"}, + {"Feature", feature}, + {"Architecture", "x86-windows"}, + {"Multi-Arch", "same"}, + {"Depends", depends}, + {"Status", "install ok installed"}}); + } + struct PackageSpecMap + { + std::unordered_map map; + Triplet triplet; + PackageSpecMap(const Triplet& t) { triplet = t; } + + PackageSpec emplace(const char* name, + const char* depends = "", + const std::vector>& features = {}) + { + return emplace(std::move(*make_control_file(name, depends, features))); + } + PackageSpec emplace(vcpkg::SourceControlFile&& scf) + { + auto spec = PackageSpec::from_name_and_triplet(scf.core_paragraph->name, triplet); + Assert::IsTrue(spec.has_value()); + map.emplace(scf.core_paragraph->name, std::move(scf)); + return PackageSpec{*spec.get()}; + } + }; + + TEST_METHOD(basic_install_scheme) + { + std::vector> status_paragraphs; + + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + auto spec_a = spec_map.emplace("a", "b"); + auto spec_b = spec_map.emplace("b", "c"); + auto spec_c = spec_map.emplace("c"); + + Dependencies::MapPortFile map_port(spec_map.map); + auto install_plan = + Dependencies::create_install_plan(map_port, {spec_a}, StatusParagraphs(std::move(status_paragraphs))); + + Assert::AreEqual(size_t(3), install_plan.size()); + Assert::AreEqual("c", install_plan[0].spec.name().c_str()); + Assert::AreEqual("b", install_plan[1].spec.name().c_str()); + Assert::AreEqual("a", install_plan[2].spec.name().c_str()); + } + + TEST_METHOD(multiple_install_scheme) + { + std::vector> status_paragraphs; + + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + auto spec_a = spec_map.emplace("a", "d"); + auto spec_b = spec_map.emplace("b", "d, e"); + auto spec_c = spec_map.emplace("c", "e, h"); + auto spec_d = spec_map.emplace("d", "f, g, h"); + auto spec_e = spec_map.emplace("e", "g"); + auto spec_f = spec_map.emplace("f"); + auto spec_g = spec_map.emplace("g"); + auto spec_h = spec_map.emplace("h"); + + Dependencies::MapPortFile map_port(spec_map.map); + auto install_plan = Dependencies::create_install_plan( + map_port, {spec_a, spec_b, spec_c}, StatusParagraphs(std::move(status_paragraphs))); + + auto iterator_pos = [&](const PackageSpec& spec) -> int { + auto it = std::find_if( + install_plan.begin(), install_plan.end(), [&](auto& action) { return action.spec == spec; }); + Assert::IsTrue(it != install_plan.end()); + return (int)(it - install_plan.begin()); + }; + + int a_pos = iterator_pos(spec_a), b_pos = iterator_pos(spec_b), c_pos = iterator_pos(spec_c), + d_pos = iterator_pos(spec_d), e_pos = iterator_pos(spec_e), f_pos = iterator_pos(spec_f), + g_pos = iterator_pos(spec_g), h_pos = iterator_pos(spec_h); + + Assert::IsTrue(a_pos > d_pos); + Assert::IsTrue(b_pos > e_pos); + Assert::IsTrue(b_pos > d_pos); + Assert::IsTrue(c_pos > e_pos); + Assert::IsTrue(c_pos > h_pos); + Assert::IsTrue(d_pos > f_pos); + Assert::IsTrue(d_pos > g_pos); + Assert::IsTrue(d_pos > h_pos); + Assert::IsTrue(e_pos > g_pos); + } + + TEST_METHOD(existing_package_scheme) + { + std::vector> status_paragraphs; + status_paragraphs.push_back(make_status_pgh("a")); + + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + auto spec_a = FullPackageSpec{spec_map.emplace("a")}; + + auto install_plan = + Dependencies::create_feature_install_plan(spec_map.map, + FullPackageSpec::to_feature_specs({spec_a}), + StatusParagraphs(std::move(status_paragraphs))); + + Assert::AreEqual(size_t(1), install_plan.size()); + auto p = install_plan[0].install_plan.get(); + Assert::IsNotNull(p); + Assert::AreEqual("a", p->spec.name().c_str()); + Assert::AreEqual(Dependencies::InstallPlanType::ALREADY_INSTALLED, p->plan_type); + Assert::AreEqual(Dependencies::RequestType::USER_REQUESTED, p->request_type); + } + + TEST_METHOD(user_requested_package_scheme) + { + std::vector> status_paragraphs; + + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + auto spec_a = FullPackageSpec{spec_map.emplace("a", "b")}; + auto spec_b = FullPackageSpec{spec_map.emplace("b")}; + + auto install_plan = + Dependencies::create_feature_install_plan(spec_map.map, + FullPackageSpec::to_feature_specs({spec_a}), + StatusParagraphs(std::move(status_paragraphs))); + + Assert::AreEqual(size_t(2), install_plan.size()); + auto p = install_plan[0].install_plan.get(); + Assert::IsNotNull(p); + Assert::AreEqual("b", p->spec.name().c_str()); + Assert::AreEqual(Dependencies::InstallPlanType::BUILD_AND_INSTALL, p->plan_type); + Assert::AreEqual(Dependencies::RequestType::AUTO_SELECTED, p->request_type); + + auto p2 = install_plan[1].install_plan.get(); + Assert::IsNotNull(p2); + Assert::AreEqual("a", p2->spec.name().c_str()); + Assert::AreEqual(Dependencies::InstallPlanType::BUILD_AND_INSTALL, p2->plan_type); + Assert::AreEqual(Dependencies::RequestType::USER_REQUESTED, p2->request_type); + } + + TEST_METHOD(long_install_scheme) + { + std::vector> status_paragraphs; + status_paragraphs.push_back(make_status_pgh("j", "k")); + status_paragraphs.push_back(make_status_pgh("k")); + + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + + auto spec_a = spec_map.emplace("a", "b, c, d, e, f, g, h, j, k"); + auto spec_b = spec_map.emplace("b", "c, d, e, f, g, h, j, k"); + auto spec_c = spec_map.emplace("c", "d, e, f, g, h, j, k"); + auto spec_d = spec_map.emplace("d", "e, f, g, h, j, k"); + auto spec_e = spec_map.emplace("e", "f, g, h, j, k"); + auto spec_f = spec_map.emplace("f", "g, h, j, k"); + auto spec_g = spec_map.emplace("g", "h, j, k"); + auto spec_h = spec_map.emplace("h", "j, k"); + auto spec_j = spec_map.emplace("j", "k"); + auto spec_k = spec_map.emplace("k"); + + Dependencies::MapPortFile map_port(spec_map.map); + auto install_plan = + Dependencies::create_install_plan(map_port, {spec_a}, StatusParagraphs(std::move(status_paragraphs))); + + Assert::AreEqual(size_t(8), install_plan.size()); + Assert::AreEqual("h", install_plan[0].spec.name().c_str()); + Assert::AreEqual("g", install_plan[1].spec.name().c_str()); + Assert::AreEqual("f", install_plan[2].spec.name().c_str()); + Assert::AreEqual("e", install_plan[3].spec.name().c_str()); + Assert::AreEqual("d", install_plan[4].spec.name().c_str()); + Assert::AreEqual("c", install_plan[5].spec.name().c_str()); + Assert::AreEqual("b", install_plan[6].spec.name().c_str()); + Assert::AreEqual("a", install_plan[7].spec.name().c_str()); + } + + TEST_METHOD(basic_feature_test_1) + { + std::vector> status_paragraphs; + status_paragraphs.push_back(make_status_pgh("a", "b, b[b1]")); + status_paragraphs.push_back(make_status_pgh("b")); + status_paragraphs.push_back(make_status_feature_pgh("b", "b1")); + + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + auto spec_a = FullPackageSpec{spec_map.emplace("a", "b, b[b1]", {{"a1", "b[b2]"}}), {"a1"}}; + auto spec_b = FullPackageSpec{spec_map.emplace("b", "", {{"b1", ""}, {"b2", ""}, {"b3", ""}})}; + + auto install_plan = + Dependencies::create_feature_install_plan(spec_map.map, + FullPackageSpec::to_feature_specs({spec_a}), + StatusParagraphs(std::move(status_paragraphs))); + + Assert::AreEqual(size_t(4), install_plan.size()); + remove_plan_check(&install_plan[0], "a"); + remove_plan_check(&install_plan[1], "b"); + features_check(&install_plan[2], "b", {"b1", "core", "b1"}); + features_check(&install_plan[3], "a", {"a1", "core"}); + } + + TEST_METHOD(basic_feature_test_2) + { + std::vector> status_paragraphs; + + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + + auto spec_a = FullPackageSpec{spec_map.emplace("a", "b[b1]", {{"a1", "b[b2]"}}), {"a1"}}; + auto spec_b = FullPackageSpec{spec_map.emplace("b", "", {{"b1", ""}, {"b2", ""}, {"b3", ""}})}; + + auto install_plan = + Dependencies::create_feature_install_plan(spec_map.map, + FullPackageSpec::to_feature_specs({spec_a}), + StatusParagraphs(std::move(status_paragraphs))); + + Assert::AreEqual(size_t(2), install_plan.size()); + features_check(&install_plan[0], "b", {"b1", "b2", "core"}); + features_check(&install_plan[1], "a", {"a1", "core"}); + } + + TEST_METHOD(basic_feature_test_3) + { + std::vector> status_paragraphs; + status_paragraphs.push_back(make_status_pgh("a")); + + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + + auto spec_a = FullPackageSpec{spec_map.emplace("a", "b", {{"a1", ""}}), {"core"}}; + auto spec_b = FullPackageSpec{spec_map.emplace("b")}; + auto spec_c = FullPackageSpec{spec_map.emplace("c", "a[a1]"), {"core"}}; + + auto install_plan = + Dependencies::create_feature_install_plan(spec_map.map, + FullPackageSpec::to_feature_specs({spec_c, spec_a}), + StatusParagraphs(std::move(status_paragraphs))); + + Assert::AreEqual(size_t(4), install_plan.size()); + remove_plan_check(&install_plan[0], "a"); + features_check(&install_plan[1], "b", {"core"}); + features_check(&install_plan[2], "a", {"a1", "core"}); + features_check(&install_plan[3], "c", {"core"}); + } + + TEST_METHOD(basic_feature_test_4) + { + std::vector> status_paragraphs; + status_paragraphs.push_back(make_status_pgh("a")); + status_paragraphs.push_back(make_status_feature_pgh("a", "a1", "")); + + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + + auto spec_a = FullPackageSpec{spec_map.emplace("a", "b", {{"a1", ""}})}; + auto spec_b = FullPackageSpec{spec_map.emplace("b")}; + auto spec_c = FullPackageSpec{spec_map.emplace("c", "a[a1]"), {"core"}}; + + auto install_plan = + Dependencies::create_feature_install_plan(spec_map.map, + FullPackageSpec::to_feature_specs({spec_c}), + StatusParagraphs(std::move(status_paragraphs))); + + Assert::AreEqual(size_t(1), install_plan.size()); + features_check(&install_plan[0], "c", {"core"}); + } + + TEST_METHOD(basic_feature_test_5) + { + std::vector> status_paragraphs; + + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + + auto spec_a = + FullPackageSpec{spec_map.emplace("a", "", {{"a1", "b[b1]"}, {"a2", "b[b2]"}, {"a3", "a[a2]"}}), {"a3"}}; + auto spec_b = FullPackageSpec{spec_map.emplace("b", "", {{"b1", ""}, {"b2", ""}})}; + + auto install_plan = + Dependencies::create_feature_install_plan(spec_map.map, + FullPackageSpec::to_feature_specs({spec_a}), + StatusParagraphs(std::move(status_paragraphs))); + + Assert::AreEqual(size_t(2), install_plan.size()); + features_check(&install_plan[0], "b", {"core", "b2"}); + features_check(&install_plan[1], "a", {"core", "a3", "a2"}); + } + + TEST_METHOD(basic_feature_test_6) + { + std::vector> status_paragraphs; + status_paragraphs.push_back(make_status_pgh("b")); + + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + auto spec_a = FullPackageSpec{spec_map.emplace("a", "b[core]"), {"core"}}; + auto spec_b = FullPackageSpec{spec_map.emplace("b", "", {{"b1", ""}}), {"b1"}}; + + auto install_plan = + Dependencies::create_feature_install_plan(spec_map.map, + FullPackageSpec::to_feature_specs({spec_a, spec_b}), + StatusParagraphs(std::move(status_paragraphs))); + + Assert::AreEqual(size_t(3), install_plan.size()); + remove_plan_check(&install_plan[0], "b"); + features_check(&install_plan[1], "b", {"core", "b1"}); + features_check(&install_plan[2], "a", {"core"}); + } + + TEST_METHOD(basic_feature_test_7) + { + std::vector> status_paragraphs; + status_paragraphs.push_back(make_status_pgh("x", "b")); + status_paragraphs.push_back(make_status_pgh("b")); + + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + + auto spec_a = FullPackageSpec{spec_map.emplace("a")}; + auto spec_x = FullPackageSpec{spec_map.emplace("x", "a"), {"core"}}; + auto spec_b = FullPackageSpec{spec_map.emplace("b", "", {{"b1", ""}}), {"b1"}}; + + auto install_plan = + Dependencies::create_feature_install_plan(spec_map.map, + FullPackageSpec::to_feature_specs({spec_b}), + StatusParagraphs(std::move(status_paragraphs))); + + Assert::AreEqual(size_t(5), install_plan.size()); + remove_plan_check(&install_plan[0], "x"); + remove_plan_check(&install_plan[1], "b"); + + // TODO: order here may change but A < X, and B anywhere + features_check(&install_plan[2], "b", {"core", "b1"}); + features_check(&install_plan[3], "a", {"core"}); + features_check(&install_plan[4], "x", {"core"}); + } + + TEST_METHOD(basic_feature_test_8) + { + std::vector> status_paragraphs; + status_paragraphs.push_back(make_status_pgh("a")); + status_paragraphs.push_back(make_status_pgh("a")); + status_paragraphs.back()->package.spec = + PackageSpec::from_name_and_triplet("a", Triplet::X64_WINDOWS).value_or_exit(VCPKG_LINE_INFO); + + PackageSpecMap spec_map(Triplet::X64_WINDOWS); + auto spec_a_64 = FullPackageSpec{spec_map.emplace("a", "b", {{"a1", ""}}), {"core"}}; + auto spec_b_64 = FullPackageSpec{spec_map.emplace("b")}; + auto spec_c_64 = FullPackageSpec{spec_map.emplace("c", "a[a1]"), {"core"}}; + + spec_map.triplet = Triplet::X86_WINDOWS; + auto spec_a_86 = FullPackageSpec{spec_map.emplace("a", "b", {{"a1", ""}}), {"core"}}; + auto spec_b_86 = FullPackageSpec{spec_map.emplace("b")}; + auto spec_c_86 = FullPackageSpec{spec_map.emplace("c", "a[a1]"), {"core"}}; + + auto install_plan = Dependencies::create_feature_install_plan( + spec_map.map, + FullPackageSpec::to_feature_specs({spec_c_64, spec_a_86, spec_a_64, spec_c_86}), + StatusParagraphs(std::move(status_paragraphs))); + + /*Assert::AreEqual(size_t(8), install_plan.size()); + auto iterator_pos = [&](const PackageSpec& spec, size_t start) -> int { + auto it = std::find_if(install_plan.begin() + start, install_plan.end(), [&](auto& action) { + return action.spec == spec; + }); + Assert::IsTrue(it != install_plan.end()); + return (int)(it - install_plan.begin()); + }; + int a_64_1 = iterator_pos(spec_a_64.package_spec, 0), a_86_1 = iterator_pos(spec_a_86.package_spec, 0), + b_64 = iterator_pos(spec_b_64.package_spec, 0), b_86 = iterator_pos(spec_b_86.package_spec, 0), + c_64 = iterator_pos(spec_c_64.package_spec, 0), c_86 = iterator_pos(spec_c_86.package_spec, 0), + a_64_2 = iterator_pos(spec_a_64.package_spec, a_64_1 + 1), + a_86_2 = iterator_pos(spec_a_86.package_spec, a_86_1 + 1);*/ + + remove_plan_check(&install_plan[0], "a", Triplet::X64_WINDOWS); + remove_plan_check(&install_plan[1], "a"); + features_check(&install_plan[2], "b", {"core"}, Triplet::X64_WINDOWS); + features_check(&install_plan[3], "a", {"a1", "core"}, Triplet::X64_WINDOWS); + features_check(&install_plan[4], "c", {"core"}, Triplet::X64_WINDOWS); + features_check(&install_plan[5], "b", {"core"}); + features_check(&install_plan[6], "a", {"a1", "core"}); + features_check(&install_plan[7], "c", {"core"}); + } + }; +} \ No newline at end of file diff --git a/toolsrc/src/tests.packagespec.cpp b/toolsrc/src/tests.packagespec.cpp new file mode 100644 index 000000000..cb5c41af0 --- /dev/null +++ b/toolsrc/src/tests.packagespec.cpp @@ -0,0 +1,120 @@ +#include +#include +#include + +#include + +#pragma comment(lib, "version") +#pragma comment(lib, "winhttp") + +using namespace Microsoft::VisualStudio::CppUnitTestFramework; + +namespace Microsoft::VisualStudio::CppUnitTestFramework +{ + template<> + inline std::wstring ToString(const vcpkg::PackageSpecParseResult& t) + { + return ToString(static_cast(t)); + } + + template<> + inline std::wstring ToString(const vcpkg::PackageSpec& t) + { + return ToString(t.to_string()); + } +} + +namespace Strings = vcpkg::Strings; + +namespace UnitTest1 +{ + using namespace vcpkg; + + class SpecifierConversion : public TestClass + { + TEST_METHOD(full_package_spec_to_feature_specs) + { + auto a_spec = PackageSpec::from_name_and_triplet("a", Triplet::X64_WINDOWS).value_or_exit(VCPKG_LINE_INFO); + auto b_spec = PackageSpec::from_name_and_triplet("b", Triplet::X64_WINDOWS).value_or_exit(VCPKG_LINE_INFO); + + auto fspecs = FullPackageSpec::to_feature_specs({{a_spec, {"0", "1"}}, {b_spec, {"2", "3"}}}); + + Assert::AreEqual(size_t(6), fspecs.size()); + + std::array features = {"", "0", "1", "", "2", "3"}; + std::array specs = {&a_spec, &a_spec, &a_spec, &b_spec, &b_spec, &b_spec}; + + for (size_t i = 0; i < features.size(); ++i) + { + Assert::AreEqual(features[i], fspecs[i].feature().c_str()); + Assert::AreEqual(*specs[i], fspecs[i].spec()); + } + } + }; + + class SpecifierParsing : public TestClass + { + TEST_METHOD(parsed_specifier_from_string) + { + auto maybe_spec = vcpkg::ParsedSpecifier::from_string("zlib"); + Assert::AreEqual(vcpkg::PackageSpecParseResult::SUCCESS, maybe_spec.error()); + auto spec = maybe_spec.get(); + Assert::AreEqual("zlib", spec->name.c_str()); + Assert::AreEqual(size_t(0), spec->features.size()); + Assert::AreEqual("", spec->triplet.c_str()); + } + + TEST_METHOD(parsed_specifier_from_string_with_triplet) + { + auto maybe_spec = vcpkg::ParsedSpecifier::from_string("zlib:x64-uwp"); + Assert::AreEqual(vcpkg::PackageSpecParseResult::SUCCESS, maybe_spec.error()); + auto spec = maybe_spec.get(); + Assert::AreEqual("zlib", spec->name.c_str()); + Assert::AreEqual("x64-uwp", spec->triplet.c_str()); + } + + TEST_METHOD(parsed_specifier_from_string_with_colons) + { + auto ec = vcpkg::ParsedSpecifier::from_string("zlib:x86-uwp:").error(); + Assert::AreEqual(vcpkg::PackageSpecParseResult::TOO_MANY_COLONS, ec); + } + + TEST_METHOD(parsed_specifier_from_string_with_feature) + { + auto maybe_spec = vcpkg::ParsedSpecifier::from_string("zlib[feature]:x64-uwp"); + Assert::AreEqual(vcpkg::PackageSpecParseResult::SUCCESS, maybe_spec.error()); + auto spec = maybe_spec.get(); + Assert::AreEqual("zlib", spec->name.c_str()); + Assert::IsTrue(spec->features.size() == 1); + Assert::AreEqual("feature", spec->features.front().c_str()); + Assert::AreEqual("x64-uwp", spec->triplet.c_str()); + } + + TEST_METHOD(parsed_specifier_from_string_with_many_features) + { + auto maybe_spec = vcpkg::ParsedSpecifier::from_string("zlib[0, 1,2]"); + Assert::AreEqual(vcpkg::PackageSpecParseResult::SUCCESS, maybe_spec.error()); + auto spec = maybe_spec.get(); + Assert::AreEqual("zlib", spec->name.c_str()); + Assert::IsTrue(spec->features.size() == 3); + Assert::AreEqual("0", spec->features[0].c_str()); + Assert::AreEqual("1", spec->features[1].c_str()); + Assert::AreEqual("2", spec->features[2].c_str()); + Assert::AreEqual("", spec->triplet.c_str()); + } + + TEST_METHOD(utf8_to_utf16) + { + auto str = vcpkg::Strings::to_utf16("abc"); + Assert::AreEqual(L"abc", str.c_str()); + } + + TEST_METHOD(utf8_to_utf16_with_whitespace) + { + auto str = vcpkg::Strings::to_utf16("abc -x86-windows"); + Assert::AreEqual(L"abc -x86-windows", str.c_str()); + } + }; + + TEST_CLASS(Metrics){}; +} diff --git a/toolsrc/src/tests.paragraph.cpp b/toolsrc/src/tests.paragraph.cpp new file mode 100644 index 000000000..d9301abd0 --- /dev/null +++ b/toolsrc/src/tests.paragraph.cpp @@ -0,0 +1,389 @@ +#include +#include +#include + +#include + +#pragma comment(lib, "version") +#pragma comment(lib, "winhttp") + +using namespace Microsoft::VisualStudio::CppUnitTestFramework; + +namespace Microsoft::VisualStudio::CppUnitTestFramework +{ + template<> + inline std::wstring ToString(const vcpkg::PackageSpecParseResult& t) + { + return ToString(static_cast(t)); + } +} + +namespace Strings = vcpkg::Strings; + +namespace UnitTest1 +{ + class ControlParsing : public TestClass + { + TEST_METHOD(SourceParagraph_Construct_Minimum) + { + auto m_pgh = + vcpkg::SourceControlFile::parse_control_file(std::vector>{{ + {"Source", "zlib"}, + {"Version", "1.2.8"}, + }}); + + Assert::IsTrue(m_pgh.has_value()); + auto& pgh = *m_pgh.get(); + + Assert::AreEqual("zlib", pgh->core_paragraph->name.c_str()); + Assert::AreEqual("1.2.8", pgh->core_paragraph->version.c_str()); + Assert::AreEqual("", pgh->core_paragraph->maintainer.c_str()); + Assert::AreEqual("", pgh->core_paragraph->description.c_str()); + Assert::AreEqual(size_t(0), pgh->core_paragraph->depends.size()); + } + + TEST_METHOD(SourceParagraph_Construct_Maximum) + { + auto m_pgh = + vcpkg::SourceControlFile::parse_control_file(std::vector>{{ + {"Source", "s"}, + {"Version", "v"}, + {"Maintainer", "m"}, + {"Description", "d"}, + {"Build-Depends", "bd"}, + {"Supports", "x64"}, + }}); + Assert::IsTrue(m_pgh.has_value()); + auto& pgh = *m_pgh.get(); + + Assert::AreEqual("s", pgh->core_paragraph->name.c_str()); + Assert::AreEqual("v", pgh->core_paragraph->version.c_str()); + Assert::AreEqual("m", pgh->core_paragraph->maintainer.c_str()); + Assert::AreEqual("d", pgh->core_paragraph->description.c_str()); + Assert::AreEqual(size_t(1), pgh->core_paragraph->depends.size()); + Assert::AreEqual("bd", pgh->core_paragraph->depends[0].name().c_str()); + Assert::AreEqual(size_t(1), pgh->core_paragraph->supports.size()); + Assert::AreEqual("x64", pgh->core_paragraph->supports[0].c_str()); + } + + TEST_METHOD(SourceParagraph_Two_Depends) + { + auto m_pgh = + vcpkg::SourceControlFile::parse_control_file(std::vector>{{ + {"Source", "zlib"}, + {"Version", "1.2.8"}, + {"Build-Depends", "z, openssl"}, + }}); + Assert::IsTrue(m_pgh.has_value()); + auto& pgh = *m_pgh.get(); + + Assert::AreEqual(size_t(2), pgh->core_paragraph->depends.size()); + Assert::AreEqual("z", pgh->core_paragraph->depends[0].name().c_str()); + Assert::AreEqual("openssl", pgh->core_paragraph->depends[1].name().c_str()); + } + + TEST_METHOD(SourceParagraph_Three_Depends) + { + auto m_pgh = + vcpkg::SourceControlFile::parse_control_file(std::vector>{{ + {"Source", "zlib"}, + {"Version", "1.2.8"}, + {"Build-Depends", "z, openssl, xyz"}, + }}); + Assert::IsTrue(m_pgh.has_value()); + auto& pgh = *m_pgh.get(); + + Assert::AreEqual(size_t(3), pgh->core_paragraph->depends.size()); + Assert::AreEqual("z", pgh->core_paragraph->depends[0].name().c_str()); + Assert::AreEqual("openssl", pgh->core_paragraph->depends[1].name().c_str()); + Assert::AreEqual("xyz", pgh->core_paragraph->depends[2].name().c_str()); + } + + TEST_METHOD(SourceParagraph_Three_Supports) + { + auto m_pgh = + vcpkg::SourceControlFile::parse_control_file(std::vector>{{ + {"Source", "zlib"}, + {"Version", "1.2.8"}, + {"Supports", "x64, windows, uwp"}, + }}); + Assert::IsTrue(m_pgh.has_value()); + auto& pgh = *m_pgh.get(); + + Assert::AreEqual(size_t(3), pgh->core_paragraph->supports.size()); + Assert::AreEqual("x64", pgh->core_paragraph->supports[0].c_str()); + Assert::AreEqual("windows", pgh->core_paragraph->supports[1].c_str()); + Assert::AreEqual("uwp", pgh->core_paragraph->supports[2].c_str()); + } + + TEST_METHOD(SourceParagraph_Construct_Qualified_Depends) + { + auto m_pgh = + vcpkg::SourceControlFile::parse_control_file(std::vector>{{ + {"Source", "zlib"}, + {"Version", "1.2.8"}, + {"Build-Depends", "libA (windows), libB (uwp)"}, + }}); + Assert::IsTrue(m_pgh.has_value()); + auto& pgh = *m_pgh.get(); + + Assert::AreEqual("zlib", pgh->core_paragraph->name.c_str()); + Assert::AreEqual("1.2.8", pgh->core_paragraph->version.c_str()); + Assert::AreEqual("", pgh->core_paragraph->maintainer.c_str()); + Assert::AreEqual("", pgh->core_paragraph->description.c_str()); + Assert::AreEqual(size_t(2), pgh->core_paragraph->depends.size()); + Assert::AreEqual("libA", pgh->core_paragraph->depends[0].name().c_str()); + Assert::AreEqual("windows", pgh->core_paragraph->depends[0].qualifier.c_str()); + Assert::AreEqual("libB", pgh->core_paragraph->depends[1].name().c_str()); + Assert::AreEqual("uwp", pgh->core_paragraph->depends[1].qualifier.c_str()); + } + + TEST_METHOD(BinaryParagraph_Construct_Minimum) + { + vcpkg::BinaryParagraph pgh({ + {"Package", "zlib"}, + {"Version", "1.2.8"}, + {"Architecture", "x86-windows"}, + {"Multi-Arch", "same"}, + }); + + Assert::AreEqual("zlib", pgh.spec.name().c_str()); + Assert::AreEqual("1.2.8", pgh.version.c_str()); + Assert::AreEqual("", pgh.maintainer.c_str()); + Assert::AreEqual("", pgh.description.c_str()); + Assert::AreEqual("x86-windows", pgh.spec.triplet().canonical_name().c_str()); + Assert::AreEqual(size_t(0), pgh.depends.size()); + } + + TEST_METHOD(BinaryParagraph_Construct_Maximum) + { + vcpkg::BinaryParagraph pgh({ + {"Package", "s"}, + {"Version", "v"}, + {"Architecture", "x86-windows"}, + {"Multi-Arch", "same"}, + {"Maintainer", "m"}, + {"Description", "d"}, + {"Depends", "bd"}, + }); + Assert::AreEqual("s", pgh.spec.name().c_str()); + Assert::AreEqual("v", pgh.version.c_str()); + Assert::AreEqual("m", pgh.maintainer.c_str()); + Assert::AreEqual("d", pgh.description.c_str()); + Assert::AreEqual(size_t(1), pgh.depends.size()); + Assert::AreEqual("bd", pgh.depends[0].c_str()); + } + + TEST_METHOD(BinaryParagraph_Three_Depends) + { + vcpkg::BinaryParagraph pgh({ + {"Package", "zlib"}, + {"Version", "1.2.8"}, + {"Architecture", "x86-windows"}, + {"Multi-Arch", "same"}, + {"Depends", "a, b, c"}, + }); + + Assert::AreEqual(size_t(3), pgh.depends.size()); + Assert::AreEqual("a", pgh.depends[0].c_str()); + Assert::AreEqual("b", pgh.depends[1].c_str()); + Assert::AreEqual("c", pgh.depends[2].c_str()); + } + + TEST_METHOD(parse_paragraphs_empty) + { + const char* str = ""; + auto pghs = vcpkg::Paragraphs::parse_paragraphs(str).value_or_exit(VCPKG_LINE_INFO); + Assert::IsTrue(pghs.empty()); + } + + TEST_METHOD(parse_paragraphs_one_field) + { + const char* str = "f1: v1"; + auto pghs = vcpkg::Paragraphs::parse_paragraphs(str).value_or_exit(VCPKG_LINE_INFO); + Assert::AreEqual(size_t(1), pghs.size()); + Assert::AreEqual(size_t(1), pghs[0].size()); + Assert::AreEqual("v1", pghs[0]["f1"].c_str()); + } + + TEST_METHOD(parse_paragraphs_one_pgh) + { + const char* str = "f1: v1\n" + "f2: v2"; + auto pghs = vcpkg::Paragraphs::parse_paragraphs(str).value_or_exit(VCPKG_LINE_INFO); + Assert::AreEqual(size_t(1), pghs.size()); + Assert::AreEqual(size_t(2), pghs[0].size()); + Assert::AreEqual("v1", pghs[0]["f1"].c_str()); + Assert::AreEqual("v2", pghs[0]["f2"].c_str()); + } + + TEST_METHOD(parse_paragraphs_two_pgh) + { + const char* str = "f1: v1\n" + "f2: v2\n" + "\n" + "f3: v3\n" + "f4: v4"; + auto pghs = vcpkg::Paragraphs::parse_paragraphs(str).value_or_exit(VCPKG_LINE_INFO); + Assert::AreEqual(size_t(2), pghs.size()); + Assert::AreEqual(size_t(2), pghs[0].size()); + Assert::AreEqual("v1", pghs[0]["f1"].c_str()); + Assert::AreEqual("v2", pghs[0]["f2"].c_str()); + Assert::AreEqual(size_t(2), pghs[1].size()); + Assert::AreEqual("v3", pghs[1]["f3"].c_str()); + Assert::AreEqual("v4", pghs[1]["f4"].c_str()); + } + + TEST_METHOD(parse_paragraphs_field_names) + { + const char* str = "1:\n" + "f:\n" + "F:\n" + "0:\n" + "F-2:\n"; + auto pghs = vcpkg::Paragraphs::parse_paragraphs(str).value_or_exit(VCPKG_LINE_INFO); + Assert::AreEqual(size_t(1), pghs.size()); + Assert::AreEqual(size_t(5), pghs[0].size()); + } + + TEST_METHOD(parse_paragraphs_multiple_blank_lines) + { + const char* str = "f1: v1\n" + "f2: v2\n" + "\n" + "\n" + "f3: v3\n" + "f4: v4"; + auto pghs = vcpkg::Paragraphs::parse_paragraphs(str).value_or_exit(VCPKG_LINE_INFO); + Assert::AreEqual(size_t(2), pghs.size()); + } + + TEST_METHOD(parse_paragraphs_empty_fields) + { + const char* str = "f1:\n" + "f2: "; + auto pghs = vcpkg::Paragraphs::parse_paragraphs(str).value_or_exit(VCPKG_LINE_INFO); + Assert::AreEqual(size_t(1), pghs.size()); + Assert::AreEqual(size_t(2), pghs[0].size()); + Assert::AreEqual("", pghs[0]["f1"].c_str()); + Assert::AreEqual("", pghs[0]["f2"].c_str()); + Assert::AreEqual(size_t(2), pghs[0].size()); + } + + TEST_METHOD(parse_paragraphs_multiline_fields) + { + const char* str = "f1: simple\n" + " f1\r\n" + "f2:\r\n" + " f2\r\n" + " continue\r\n"; + auto pghs = vcpkg::Paragraphs::parse_paragraphs(str).value_or_exit(VCPKG_LINE_INFO); + Assert::AreEqual(size_t(1), pghs.size()); + Assert::AreEqual("simple\n f1", pghs[0]["f1"].c_str()); + Assert::AreEqual("\n f2\n continue", pghs[0]["f2"].c_str()); + } + + TEST_METHOD(parse_paragraphs_crlfs) + { + const char* str = "f1: v1\r\n" + "f2: v2\r\n" + "\r\n" + "f3: v3\r\n" + "f4: v4"; + auto pghs = vcpkg::Paragraphs::parse_paragraphs(str).value_or_exit(VCPKG_LINE_INFO); + Assert::AreEqual(size_t(2), pghs.size()); + Assert::AreEqual(size_t(2), pghs[0].size()); + Assert::AreEqual("v1", pghs[0]["f1"].c_str()); + Assert::AreEqual("v2", pghs[0]["f2"].c_str()); + Assert::AreEqual(size_t(2), pghs[1].size()); + Assert::AreEqual("v3", pghs[1]["f3"].c_str()); + Assert::AreEqual("v4", pghs[1]["f4"].c_str()); + } + + TEST_METHOD(parse_paragraphs_comment) + { + const char* str = "f1: v1\r\n" + "#comment\r\n" + "f2: v2\r\n" + "#comment\r\n" + "\r\n" + "#comment\r\n" + "f3: v3\r\n" + "#comment\r\n" + "f4: v4"; + auto pghs = vcpkg::Paragraphs::parse_paragraphs(str).value_or_exit(VCPKG_LINE_INFO); + Assert::AreEqual(size_t(2), pghs.size()); + Assert::AreEqual(size_t(2), pghs[0].size()); + Assert::AreEqual("v1", pghs[0]["f1"].c_str()); + Assert::AreEqual("v2", pghs[0]["f2"].c_str()); + Assert::AreEqual(size_t(2), pghs[1].size()); + Assert::AreEqual("v3", pghs[1]["f3"].c_str()); + 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(BinaryParagraph_serialize_min) + { + vcpkg::BinaryParagraph pgh({ + {"Package", "zlib"}, + {"Version", "1.2.8"}, + {"Architecture", "x86-windows"}, + {"Multi-Arch", "same"}, + }); + 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()); + Assert::AreEqual("1.2.8", pghs[0]["Version"].c_str()); + Assert::AreEqual("x86-windows", pghs[0]["Architecture"].c_str()); + Assert::AreEqual("same", pghs[0]["Multi-Arch"].c_str()); + } + + TEST_METHOD(BinaryParagraph_serialize_max) + { + vcpkg::BinaryParagraph pgh({ + {"Package", "zlib"}, + {"Version", "1.2.8"}, + {"Architecture", "x86-windows"}, + {"Description", "first line\n second line"}, + {"Maintainer", "abc "}, + {"Depends", "dep"}, + {"Multi-Arch", "same"}, + }); + 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()); + Assert::AreEqual("1.2.8", pghs[0]["Version"].c_str()); + Assert::AreEqual("x86-windows", pghs[0]["Architecture"].c_str()); + Assert::AreEqual("same", pghs[0]["Multi-Arch"].c_str()); + Assert::AreEqual("first line\n second line", pghs[0]["Description"].c_str()); + Assert::AreEqual("dep", pghs[0]["Depends"].c_str()); + } + + TEST_METHOD(BinaryParagraph_serialize_multiple_deps) + { + vcpkg::BinaryParagraph pgh({ + {"Package", "zlib"}, + {"Version", "1.2.8"}, + {"Architecture", "x86-windows"}, + {"Multi-Arch", "same"}, + {"Depends", "a, b, c"}, + }); + 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/tests_arguments.cpp b/toolsrc/src/tests_arguments.cpp deleted file mode 100644 index 14b3c3d4f..000000000 --- a/toolsrc/src/tests_arguments.cpp +++ /dev/null @@ -1,58 +0,0 @@ -#include "CppUnitTest.h" -#include "VcpkgCmdArguments.h" - -#pragma comment(lib, "version") -#pragma comment(lib, "winhttp") - -using namespace Microsoft::VisualStudio::CppUnitTestFramework; - -using namespace vcpkg; - -namespace UnitTest1 -{ - class ArgumentTests : public TestClass - { - TEST_METHOD(create_from_arg_sequence_options_lower) - { - std::vector t = {"--vcpkg-root", "C:\\vcpkg", "--debug", "--sendmetrics", "--printmetrics"}; - auto v = VcpkgCmdArguments::create_from_arg_sequence(t.data(), t.data() + t.size()); - Assert::AreEqual("C:\\vcpkg", v.vcpkg_root_dir.get()->c_str()); - Assert::IsTrue(v.debug && *v.debug.get()); - Assert::IsTrue(v.sendmetrics && v.sendmetrics.get()); - Assert::IsTrue(v.printmetrics && *v.printmetrics.get()); - } - - TEST_METHOD(create_from_arg_sequence_options_upper) - { - std::vector t = {"--VCPKG-ROOT", "C:\\vcpkg", "--DEBUG", "--SENDMETRICS", "--PRINTMETRICS"}; - auto v = VcpkgCmdArguments::create_from_arg_sequence(t.data(), t.data() + t.size()); - Assert::AreEqual("C:\\vcpkg", v.vcpkg_root_dir.get()->c_str()); - Assert::IsTrue(v.debug && *v.debug.get()); - Assert::IsTrue(v.sendmetrics && v.sendmetrics.get()); - Assert::IsTrue(v.printmetrics && *v.printmetrics.get()); - } - - TEST_METHOD(create_from_arg_sequence_valued_options) - { - std::vector t = {"--a=b", "command", "argument"}; - auto v = VcpkgCmdArguments::create_from_arg_sequence(t.data(), t.data() + t.size()); - auto opts = v.check_and_get_optional_command_arguments({}, {"--a"}); - Assert::AreEqual("b", opts.settings["--a"].c_str()); - Assert::AreEqual(size_t{1}, v.command_arguments.size()); - Assert::AreEqual("argument", v.command_arguments[0].c_str()); - Assert::AreEqual("command", v.command.c_str()); - } - - TEST_METHOD(create_from_arg_sequence_valued_options2) - { - std::vector t = {"--a", "--b=c"}; - auto v = VcpkgCmdArguments::create_from_arg_sequence(t.data(), t.data() + t.size()); - auto opts = v.check_and_get_optional_command_arguments({"--a", "--c"}, {"--b", "--d"}); - Assert::AreEqual("c", opts.settings["--b"].c_str()); - Assert::IsTrue(opts.settings.find("--d") == opts.settings.end()); - Assert::IsTrue(opts.switches.find("--a") != opts.switches.end()); - Assert::IsTrue(opts.settings.find("--c") == opts.settings.end()); - Assert::AreEqual(size_t{0}, v.command_arguments.size()); - } - }; -} \ No newline at end of file diff --git a/toolsrc/src/tests_dependencies.cpp b/toolsrc/src/tests_dependencies.cpp deleted file mode 100644 index 6a6981d73..000000000 --- a/toolsrc/src/tests_dependencies.cpp +++ /dev/null @@ -1,110 +0,0 @@ -#include "CppUnitTest.h" -#include "SourceParagraph.h" -#include "Triplet.h" - -#pragma comment(lib, "version") -#pragma comment(lib, "winhttp") - -using namespace Microsoft::VisualStudio::CppUnitTestFramework; - -using namespace vcpkg; -using Parse::parse_comma_list; - -namespace UnitTest1 -{ - class DependencyTests : public TestClass - { - TEST_METHOD(parse_depends_one) - { - auto v = expand_qualified_dependencies(parse_comma_list("libA (windows)")); - Assert::AreEqual(size_t(1), v.size()); - Assert::AreEqual("libA", v[0].depend.name.c_str()); - Assert::AreEqual("windows", v[0].qualifier.c_str()); - } - - TEST_METHOD(filter_depends) - { - auto deps = expand_qualified_dependencies(parse_comma_list("libA (windows), libB, libC (uwp)")); - auto v = filter_dependencies(deps, Triplet::X64_WINDOWS); - Assert::AreEqual(size_t(2), v.size()); - Assert::AreEqual("libA", v[0].c_str()); - Assert::AreEqual("libB", v[1].c_str()); - - auto v2 = filter_dependencies(deps, Triplet::ARM_UWP); - Assert::AreEqual(size_t(2), v.size()); - Assert::AreEqual("libB", v2[0].c_str()); - Assert::AreEqual("libC", v2[1].c_str()); - } - }; - - class SupportsTests : public TestClass - { - TEST_METHOD(parse_supports_all) - { - auto v = Supports::parse({ - "x64", - "x86", - "arm", - "windows", - "uwp", - "v140", - "v141", - "crt-static", - "crt-dynamic", - }); - Assert::AreNotEqual(uintptr_t(0), uintptr_t(v.get())); - - Assert::IsTrue(v.get()->is_supported(System::CPUArchitecture::X64, - Supports::Platform::UWP, - Supports::Linkage::DYNAMIC, - Supports::ToolsetVersion::V140)); - Assert::IsTrue(v.get()->is_supported(System::CPUArchitecture::ARM, - Supports::Platform::WINDOWS, - Supports::Linkage::STATIC, - Supports::ToolsetVersion::V141)); - } - - TEST_METHOD(parse_supports_invalid) - { - auto v = Supports::parse({"arm64"}); - Assert::AreEqual(uintptr_t(0), uintptr_t(v.get())); - Assert::AreEqual(size_t(1), v.error().size()); - Assert::AreEqual("arm64", v.error()[0].c_str()); - } - - TEST_METHOD(parse_supports_case_sensitive) - { - auto v = Supports::parse({"Windows"}); - Assert::AreEqual(uintptr_t(0), uintptr_t(v.get())); - Assert::AreEqual(size_t(1), v.error().size()); - Assert::AreEqual("Windows", v.error()[0].c_str()); - } - - TEST_METHOD(parse_supports_some) - { - auto v = Supports::parse({ - "x64", - "x86", - "windows", - }); - Assert::AreNotEqual(uintptr_t(0), uintptr_t(v.get())); - - Assert::IsTrue(v.get()->is_supported(System::CPUArchitecture::X64, - Supports::Platform::WINDOWS, - Supports::Linkage::DYNAMIC, - Supports::ToolsetVersion::V140)); - Assert::IsFalse(v.get()->is_supported(System::CPUArchitecture::ARM, - Supports::Platform::WINDOWS, - Supports::Linkage::DYNAMIC, - Supports::ToolsetVersion::V140)); - Assert::IsFalse(v.get()->is_supported(System::CPUArchitecture::X64, - Supports::Platform::UWP, - Supports::Linkage::DYNAMIC, - Supports::ToolsetVersion::V140)); - Assert::IsTrue(v.get()->is_supported(System::CPUArchitecture::X64, - Supports::Platform::WINDOWS, - Supports::Linkage::STATIC, - Supports::ToolsetVersion::V141)); - } - }; -} diff --git a/toolsrc/src/tests_package_spec.cpp b/toolsrc/src/tests_package_spec.cpp deleted file mode 100644 index a6b9d5b13..000000000 --- a/toolsrc/src/tests_package_spec.cpp +++ /dev/null @@ -1,119 +0,0 @@ -#include "BinaryParagraph.h" -#include "CppUnitTest.h" -#include "Paragraphs.h" -#include "vcpkg_Strings.h" - -#pragma comment(lib, "version") -#pragma comment(lib, "winhttp") - -using namespace Microsoft::VisualStudio::CppUnitTestFramework; - -namespace Microsoft::VisualStudio::CppUnitTestFramework -{ - template<> - inline std::wstring ToString(const vcpkg::PackageSpecParseResult& t) - { - return ToString(static_cast(t)); - } - - template<> - inline std::wstring ToString(const vcpkg::PackageSpec& t) - { - return ToString(t.to_string()); - } -} - -namespace Strings = vcpkg::Strings; - -namespace UnitTest1 -{ - using namespace vcpkg; - - class SpecifierConversion : public TestClass - { - TEST_METHOD(full_package_spec_to_feature_specs) - { - auto a_spec = PackageSpec::from_name_and_triplet("a", Triplet::X64_WINDOWS).value_or_exit(VCPKG_LINE_INFO); - auto b_spec = PackageSpec::from_name_and_triplet("b", Triplet::X64_WINDOWS).value_or_exit(VCPKG_LINE_INFO); - - auto fspecs = FullPackageSpec::to_feature_specs({{a_spec, {"0", "1"}}, {b_spec, {"2", "3"}}}); - - Assert::AreEqual(size_t(6), fspecs.size()); - - std::array features = {"", "0", "1", "", "2", "3"}; - std::array specs = {&a_spec, &a_spec, &a_spec, &b_spec, &b_spec, &b_spec}; - - for (size_t i = 0; i < features.size(); ++i) - { - Assert::AreEqual(features[i], fspecs[i].feature().c_str()); - Assert::AreEqual(*specs[i], fspecs[i].spec()); - } - } - }; - - class SpecifierParsing : public TestClass - { - TEST_METHOD(parsed_specifier_from_string) - { - auto maybe_spec = vcpkg::ParsedSpecifier::from_string("zlib"); - Assert::AreEqual(vcpkg::PackageSpecParseResult::SUCCESS, maybe_spec.error()); - auto spec = maybe_spec.get(); - Assert::AreEqual("zlib", spec->name.c_str()); - Assert::AreEqual(size_t(0), spec->features.size()); - Assert::AreEqual("", spec->triplet.c_str()); - } - - TEST_METHOD(parsed_specifier_from_string_with_triplet) - { - auto maybe_spec = vcpkg::ParsedSpecifier::from_string("zlib:x64-uwp"); - Assert::AreEqual(vcpkg::PackageSpecParseResult::SUCCESS, maybe_spec.error()); - auto spec = maybe_spec.get(); - Assert::AreEqual("zlib", spec->name.c_str()); - Assert::AreEqual("x64-uwp", spec->triplet.c_str()); - } - - TEST_METHOD(parsed_specifier_from_string_with_colons) - { - auto ec = vcpkg::ParsedSpecifier::from_string("zlib:x86-uwp:").error(); - Assert::AreEqual(vcpkg::PackageSpecParseResult::TOO_MANY_COLONS, ec); - } - - TEST_METHOD(parsed_specifier_from_string_with_feature) - { - auto maybe_spec = vcpkg::ParsedSpecifier::from_string("zlib[feature]:x64-uwp"); - Assert::AreEqual(vcpkg::PackageSpecParseResult::SUCCESS, maybe_spec.error()); - auto spec = maybe_spec.get(); - Assert::AreEqual("zlib", spec->name.c_str()); - Assert::IsTrue(spec->features.size() == 1); - Assert::AreEqual("feature", spec->features.front().c_str()); - Assert::AreEqual("x64-uwp", spec->triplet.c_str()); - } - - TEST_METHOD(parsed_specifier_from_string_with_many_features) - { - auto maybe_spec = vcpkg::ParsedSpecifier::from_string("zlib[0, 1,2]"); - Assert::AreEqual(vcpkg::PackageSpecParseResult::SUCCESS, maybe_spec.error()); - auto spec = maybe_spec.get(); - Assert::AreEqual("zlib", spec->name.c_str()); - Assert::IsTrue(spec->features.size() == 3); - Assert::AreEqual("0", spec->features[0].c_str()); - Assert::AreEqual("1", spec->features[1].c_str()); - Assert::AreEqual("2", spec->features[2].c_str()); - Assert::AreEqual("", spec->triplet.c_str()); - } - - TEST_METHOD(utf8_to_utf16) - { - auto str = vcpkg::Strings::to_utf16("abc"); - Assert::AreEqual(L"abc", str.c_str()); - } - - TEST_METHOD(utf8_to_utf16_with_whitespace) - { - auto str = vcpkg::Strings::to_utf16("abc -x86-windows"); - Assert::AreEqual(L"abc -x86-windows", str.c_str()); - } - }; - - TEST_CLASS(Metrics){}; -} diff --git a/toolsrc/src/tests_paragraph.cpp b/toolsrc/src/tests_paragraph.cpp deleted file mode 100644 index 47a07e12d..000000000 --- a/toolsrc/src/tests_paragraph.cpp +++ /dev/null @@ -1,388 +0,0 @@ -#include "BinaryParagraph.h" -#include "CppUnitTest.h" -#include "Paragraphs.h" -#include "vcpkg_Strings.h" - -#pragma comment(lib, "version") -#pragma comment(lib, "winhttp") - -using namespace Microsoft::VisualStudio::CppUnitTestFramework; - -namespace Microsoft::VisualStudio::CppUnitTestFramework -{ - template<> - inline std::wstring ToString(const vcpkg::PackageSpecParseResult& t) - { - return ToString(static_cast(t)); - } -} - -namespace Strings = vcpkg::Strings; - -namespace UnitTest1 -{ - class ControlParsing : public TestClass - { - TEST_METHOD(SourceParagraph_Construct_Minimum) - { - auto m_pgh = - vcpkg::SourceControlFile::parse_control_file(std::vector>{{ - {"Source", "zlib"}, - {"Version", "1.2.8"}, - }}); - - Assert::IsTrue(m_pgh.has_value()); - auto& pgh = *m_pgh.get(); - - Assert::AreEqual("zlib", pgh->core_paragraph->name.c_str()); - Assert::AreEqual("1.2.8", pgh->core_paragraph->version.c_str()); - Assert::AreEqual("", pgh->core_paragraph->maintainer.c_str()); - Assert::AreEqual("", pgh->core_paragraph->description.c_str()); - Assert::AreEqual(size_t(0), pgh->core_paragraph->depends.size()); - } - - TEST_METHOD(SourceParagraph_Construct_Maximum) - { - auto m_pgh = - vcpkg::SourceControlFile::parse_control_file(std::vector>{{ - {"Source", "s"}, - {"Version", "v"}, - {"Maintainer", "m"}, - {"Description", "d"}, - {"Build-Depends", "bd"}, - {"Supports", "x64"}, - }}); - Assert::IsTrue(m_pgh.has_value()); - auto& pgh = *m_pgh.get(); - - Assert::AreEqual("s", pgh->core_paragraph->name.c_str()); - Assert::AreEqual("v", pgh->core_paragraph->version.c_str()); - Assert::AreEqual("m", pgh->core_paragraph->maintainer.c_str()); - Assert::AreEqual("d", pgh->core_paragraph->description.c_str()); - Assert::AreEqual(size_t(1), pgh->core_paragraph->depends.size()); - Assert::AreEqual("bd", pgh->core_paragraph->depends[0].name().c_str()); - Assert::AreEqual(size_t(1), pgh->core_paragraph->supports.size()); - Assert::AreEqual("x64", pgh->core_paragraph->supports[0].c_str()); - } - - TEST_METHOD(SourceParagraph_Two_Depends) - { - auto m_pgh = - vcpkg::SourceControlFile::parse_control_file(std::vector>{{ - {"Source", "zlib"}, - {"Version", "1.2.8"}, - {"Build-Depends", "z, openssl"}, - }}); - Assert::IsTrue(m_pgh.has_value()); - auto& pgh = *m_pgh.get(); - - Assert::AreEqual(size_t(2), pgh->core_paragraph->depends.size()); - Assert::AreEqual("z", pgh->core_paragraph->depends[0].name().c_str()); - Assert::AreEqual("openssl", pgh->core_paragraph->depends[1].name().c_str()); - } - - TEST_METHOD(SourceParagraph_Three_Depends) - { - auto m_pgh = - vcpkg::SourceControlFile::parse_control_file(std::vector>{{ - {"Source", "zlib"}, - {"Version", "1.2.8"}, - {"Build-Depends", "z, openssl, xyz"}, - }}); - Assert::IsTrue(m_pgh.has_value()); - auto& pgh = *m_pgh.get(); - - Assert::AreEqual(size_t(3), pgh->core_paragraph->depends.size()); - Assert::AreEqual("z", pgh->core_paragraph->depends[0].name().c_str()); - Assert::AreEqual("openssl", pgh->core_paragraph->depends[1].name().c_str()); - Assert::AreEqual("xyz", pgh->core_paragraph->depends[2].name().c_str()); - } - - TEST_METHOD(SourceParagraph_Three_Supports) - { - auto m_pgh = - vcpkg::SourceControlFile::parse_control_file(std::vector>{{ - {"Source", "zlib"}, - {"Version", "1.2.8"}, - {"Supports", "x64, windows, uwp"}, - }}); - Assert::IsTrue(m_pgh.has_value()); - auto& pgh = *m_pgh.get(); - - Assert::AreEqual(size_t(3), pgh->core_paragraph->supports.size()); - Assert::AreEqual("x64", pgh->core_paragraph->supports[0].c_str()); - Assert::AreEqual("windows", pgh->core_paragraph->supports[1].c_str()); - Assert::AreEqual("uwp", pgh->core_paragraph->supports[2].c_str()); - } - - TEST_METHOD(SourceParagraph_Construct_Qualified_Depends) - { - auto m_pgh = - vcpkg::SourceControlFile::parse_control_file(std::vector>{{ - {"Source", "zlib"}, - {"Version", "1.2.8"}, - {"Build-Depends", "libA (windows), libB (uwp)"}, - }}); - Assert::IsTrue(m_pgh.has_value()); - auto& pgh = *m_pgh.get(); - - Assert::AreEqual("zlib", pgh->core_paragraph->name.c_str()); - Assert::AreEqual("1.2.8", pgh->core_paragraph->version.c_str()); - Assert::AreEqual("", pgh->core_paragraph->maintainer.c_str()); - Assert::AreEqual("", pgh->core_paragraph->description.c_str()); - Assert::AreEqual(size_t(2), pgh->core_paragraph->depends.size()); - Assert::AreEqual("libA", pgh->core_paragraph->depends[0].name().c_str()); - Assert::AreEqual("windows", pgh->core_paragraph->depends[0].qualifier.c_str()); - Assert::AreEqual("libB", pgh->core_paragraph->depends[1].name().c_str()); - Assert::AreEqual("uwp", pgh->core_paragraph->depends[1].qualifier.c_str()); - } - - TEST_METHOD(BinaryParagraph_Construct_Minimum) - { - vcpkg::BinaryParagraph pgh({ - {"Package", "zlib"}, - {"Version", "1.2.8"}, - {"Architecture", "x86-windows"}, - {"Multi-Arch", "same"}, - }); - - Assert::AreEqual("zlib", pgh.spec.name().c_str()); - Assert::AreEqual("1.2.8", pgh.version.c_str()); - Assert::AreEqual("", pgh.maintainer.c_str()); - Assert::AreEqual("", pgh.description.c_str()); - Assert::AreEqual("x86-windows", pgh.spec.triplet().canonical_name().c_str()); - Assert::AreEqual(size_t(0), pgh.depends.size()); - } - - TEST_METHOD(BinaryParagraph_Construct_Maximum) - { - vcpkg::BinaryParagraph pgh({ - {"Package", "s"}, - {"Version", "v"}, - {"Architecture", "x86-windows"}, - {"Multi-Arch", "same"}, - {"Maintainer", "m"}, - {"Description", "d"}, - {"Depends", "bd"}, - }); - Assert::AreEqual("s", pgh.spec.name().c_str()); - Assert::AreEqual("v", pgh.version.c_str()); - Assert::AreEqual("m", pgh.maintainer.c_str()); - Assert::AreEqual("d", pgh.description.c_str()); - Assert::AreEqual(size_t(1), pgh.depends.size()); - Assert::AreEqual("bd", pgh.depends[0].c_str()); - } - - TEST_METHOD(BinaryParagraph_Three_Depends) - { - vcpkg::BinaryParagraph pgh({ - {"Package", "zlib"}, - {"Version", "1.2.8"}, - {"Architecture", "x86-windows"}, - {"Multi-Arch", "same"}, - {"Depends", "a, b, c"}, - }); - - Assert::AreEqual(size_t(3), pgh.depends.size()); - Assert::AreEqual("a", pgh.depends[0].c_str()); - Assert::AreEqual("b", pgh.depends[1].c_str()); - Assert::AreEqual("c", pgh.depends[2].c_str()); - } - - TEST_METHOD(parse_paragraphs_empty) - { - const char* str = ""; - auto pghs = vcpkg::Paragraphs::parse_paragraphs(str).value_or_exit(VCPKG_LINE_INFO); - Assert::IsTrue(pghs.empty()); - } - - TEST_METHOD(parse_paragraphs_one_field) - { - const char* str = "f1: v1"; - auto pghs = vcpkg::Paragraphs::parse_paragraphs(str).value_or_exit(VCPKG_LINE_INFO); - Assert::AreEqual(size_t(1), pghs.size()); - Assert::AreEqual(size_t(1), pghs[0].size()); - Assert::AreEqual("v1", pghs[0]["f1"].c_str()); - } - - TEST_METHOD(parse_paragraphs_one_pgh) - { - const char* str = "f1: v1\n" - "f2: v2"; - auto pghs = vcpkg::Paragraphs::parse_paragraphs(str).value_or_exit(VCPKG_LINE_INFO); - Assert::AreEqual(size_t(1), pghs.size()); - Assert::AreEqual(size_t(2), pghs[0].size()); - Assert::AreEqual("v1", pghs[0]["f1"].c_str()); - Assert::AreEqual("v2", pghs[0]["f2"].c_str()); - } - - TEST_METHOD(parse_paragraphs_two_pgh) - { - const char* str = "f1: v1\n" - "f2: v2\n" - "\n" - "f3: v3\n" - "f4: v4"; - auto pghs = vcpkg::Paragraphs::parse_paragraphs(str).value_or_exit(VCPKG_LINE_INFO); - Assert::AreEqual(size_t(2), pghs.size()); - Assert::AreEqual(size_t(2), pghs[0].size()); - Assert::AreEqual("v1", pghs[0]["f1"].c_str()); - Assert::AreEqual("v2", pghs[0]["f2"].c_str()); - Assert::AreEqual(size_t(2), pghs[1].size()); - Assert::AreEqual("v3", pghs[1]["f3"].c_str()); - Assert::AreEqual("v4", pghs[1]["f4"].c_str()); - } - - TEST_METHOD(parse_paragraphs_field_names) - { - const char* str = "1:\n" - "f:\n" - "F:\n" - "0:\n" - "F-2:\n"; - auto pghs = vcpkg::Paragraphs::parse_paragraphs(str).value_or_exit(VCPKG_LINE_INFO); - Assert::AreEqual(size_t(1), pghs.size()); - Assert::AreEqual(size_t(5), pghs[0].size()); - } - - TEST_METHOD(parse_paragraphs_multiple_blank_lines) - { - const char* str = "f1: v1\n" - "f2: v2\n" - "\n" - "\n" - "f3: v3\n" - "f4: v4"; - auto pghs = vcpkg::Paragraphs::parse_paragraphs(str).value_or_exit(VCPKG_LINE_INFO); - Assert::AreEqual(size_t(2), pghs.size()); - } - - TEST_METHOD(parse_paragraphs_empty_fields) - { - const char* str = "f1:\n" - "f2: "; - auto pghs = vcpkg::Paragraphs::parse_paragraphs(str).value_or_exit(VCPKG_LINE_INFO); - Assert::AreEqual(size_t(1), pghs.size()); - Assert::AreEqual(size_t(2), pghs[0].size()); - Assert::AreEqual("", pghs[0]["f1"].c_str()); - Assert::AreEqual("", pghs[0]["f2"].c_str()); - Assert::AreEqual(size_t(2), pghs[0].size()); - } - - TEST_METHOD(parse_paragraphs_multiline_fields) - { - const char* str = "f1: simple\n" - " f1\r\n" - "f2:\r\n" - " f2\r\n" - " continue\r\n"; - auto pghs = vcpkg::Paragraphs::parse_paragraphs(str).value_or_exit(VCPKG_LINE_INFO); - Assert::AreEqual(size_t(1), pghs.size()); - Assert::AreEqual("simple\n f1", pghs[0]["f1"].c_str()); - Assert::AreEqual("\n f2\n continue", pghs[0]["f2"].c_str()); - } - - TEST_METHOD(parse_paragraphs_crlfs) - { - const char* str = "f1: v1\r\n" - "f2: v2\r\n" - "\r\n" - "f3: v3\r\n" - "f4: v4"; - auto pghs = vcpkg::Paragraphs::parse_paragraphs(str).value_or_exit(VCPKG_LINE_INFO); - Assert::AreEqual(size_t(2), pghs.size()); - Assert::AreEqual(size_t(2), pghs[0].size()); - Assert::AreEqual("v1", pghs[0]["f1"].c_str()); - Assert::AreEqual("v2", pghs[0]["f2"].c_str()); - Assert::AreEqual(size_t(2), pghs[1].size()); - Assert::AreEqual("v3", pghs[1]["f3"].c_str()); - Assert::AreEqual("v4", pghs[1]["f4"].c_str()); - } - - TEST_METHOD(parse_paragraphs_comment) - { - const char* str = "f1: v1\r\n" - "#comment\r\n" - "f2: v2\r\n" - "#comment\r\n" - "\r\n" - "#comment\r\n" - "f3: v3\r\n" - "#comment\r\n" - "f4: v4"; - auto pghs = vcpkg::Paragraphs::parse_paragraphs(str).value_or_exit(VCPKG_LINE_INFO); - Assert::AreEqual(size_t(2), pghs.size()); - Assert::AreEqual(size_t(2), pghs[0].size()); - Assert::AreEqual("v1", pghs[0]["f1"].c_str()); - Assert::AreEqual("v2", pghs[0]["f2"].c_str()); - Assert::AreEqual(size_t(2), pghs[1].size()); - Assert::AreEqual("v3", pghs[1]["f3"].c_str()); - 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(BinaryParagraph_serialize_min) - { - vcpkg::BinaryParagraph pgh({ - {"Package", "zlib"}, - {"Version", "1.2.8"}, - {"Architecture", "x86-windows"}, - {"Multi-Arch", "same"}, - }); - 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()); - Assert::AreEqual("1.2.8", pghs[0]["Version"].c_str()); - Assert::AreEqual("x86-windows", pghs[0]["Architecture"].c_str()); - Assert::AreEqual("same", pghs[0]["Multi-Arch"].c_str()); - } - - TEST_METHOD(BinaryParagraph_serialize_max) - { - vcpkg::BinaryParagraph pgh({ - {"Package", "zlib"}, - {"Version", "1.2.8"}, - {"Architecture", "x86-windows"}, - {"Description", "first line\n second line"}, - {"Maintainer", "abc "}, - {"Depends", "dep"}, - {"Multi-Arch", "same"}, - }); - 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()); - Assert::AreEqual("1.2.8", pghs[0]["Version"].c_str()); - Assert::AreEqual("x86-windows", pghs[0]["Architecture"].c_str()); - Assert::AreEqual("same", pghs[0]["Multi-Arch"].c_str()); - Assert::AreEqual("first line\n second line", pghs[0]["Description"].c_str()); - Assert::AreEqual("dep", pghs[0]["Depends"].c_str()); - } - - TEST_METHOD(BinaryParagraph_serialize_multiple_deps) - { - vcpkg::BinaryParagraph pgh({ - {"Package", "zlib"}, - {"Version", "1.2.8"}, - {"Architecture", "x86-windows"}, - {"Multi-Arch", "same"}, - {"Depends", "a, b, c"}, - }); - 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/triplet.cpp b/toolsrc/src/triplet.cpp deleted file mode 100644 index 3b56da02a..000000000 --- a/toolsrc/src/triplet.cpp +++ /dev/null @@ -1,55 +0,0 @@ -#include "pch.h" - -#include "Triplet.h" -#include "vcpkg_Checks.h" -#include "vcpkg_Strings.h" - -namespace vcpkg -{ - struct TripletInstance - { - TripletInstance(std::string&& s) : value(std::move(s)), hash(std::hash()(value)) {} - - const std::string value; - const size_t hash = 0; - - bool operator==(const TripletInstance& o) const { return o.value == value; } - }; - const TripletInstance Triplet::DEFAULT_INSTANCE({}); -} - -template<> -struct std::hash -{ - size_t operator()(const vcpkg::TripletInstance& t) const { return t.hash; } -}; - -namespace vcpkg -{ - static std::unordered_set g_triplet_instances; - - const Triplet Triplet::X86_WINDOWS = from_canonical_name("x86-windows"); - const Triplet Triplet::X64_WINDOWS = from_canonical_name("x64-windows"); - const Triplet Triplet::X86_UWP = from_canonical_name("x86-uwp"); - const Triplet Triplet::X64_UWP = from_canonical_name("x64-uwp"); - const Triplet Triplet::ARM_UWP = from_canonical_name("arm-uwp"); - - bool Triplet::operator==(const Triplet& other) const { return this->m_instance == other.m_instance; } - - bool operator!=(const Triplet& left, const Triplet& right) { return !(left == right); } - - Triplet Triplet::from_canonical_name(const std::string& triplet_as_string) - { - std::string s(Strings::ascii_to_lowercase(triplet_as_string)); - const auto it = std::find(s.cbegin(), s.cend(), '-'); - Checks::check_exit(VCPKG_LINE_INFO, it != s.cend(), "Invalid triplet: %s", triplet_as_string); - - const auto p = g_triplet_instances.emplace(std::move(s)); - return &*p.first; - } - - const std::string& Triplet::canonical_name() const { return this->m_instance->value; } - - const std::string& Triplet::to_string() const { return this->canonical_name(); } - size_t Triplet::hash_code() const { return m_instance->hash; } -} diff --git a/toolsrc/src/vcpkg.cpp b/toolsrc/src/vcpkg.cpp index 706c641fb..748b4f0ee 100644 --- a/toolsrc/src/vcpkg.cpp +++ b/toolsrc/src/vcpkg.cpp @@ -1,16 +1,18 @@ #define WIN32_LEAN_AND_MEAN #include -#include "Paragraphs.h" -#include "metrics.h" -#include "vcpkg_Chrono.h" -#include "vcpkg_Commands.h" -#include "vcpkg_Files.h" -#include "vcpkg_GlobalState.h" -#include "vcpkg_Input.h" -#include "vcpkg_Strings.h" -#include "vcpkg_System.h" -#include "vcpkglib.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + #pragma warning(push) #pragma warning(disable : 4768) #include @@ -19,12 +21,15 @@ #include #include +#pragma comment(lib, "ole32") +#pragma comment(lib, "shell32") + using namespace vcpkg; void invalid_command(const std::string& cmd) { System::println(System::Color::error, "invalid command: %s", cmd); - Commands::Help::print_usage(); + Help::print_usage(); Checks::exit_fail(VCPKG_LINE_INFO); } @@ -33,13 +38,26 @@ static void inner(const VcpkgCmdArguments& args) Metrics::g_metrics.lock()->track_property("command", args.command); if (args.command.empty()) { - Commands::Help::print_usage(); + Help::print_usage(); Checks::exit_fail(VCPKG_LINE_INFO); } - if (const auto command_function = Commands::find(args.command, Commands::get_available_commands_type_c())) + static const auto find_command = [&](auto&& commands) { + auto it = Util::find_if(commands, [&](auto&& commandc) { + return Strings::case_insensitive_ascii_compare(commandc.name, args.command); + }); + using std::end; + if (it != end(commands)) + { + return &*it; + } + else + return static_cast(nullptr); + }; + + if (const auto command_function = find_command(Commands::get_available_commands_type_c())) { - return command_function(args); + return command_function->function(args); } fs::path vcpkg_root_dir; @@ -74,9 +92,9 @@ static void inner(const VcpkgCmdArguments& args) Checks::check_exit(VCPKG_LINE_INFO, exit_code == 0, "Changing the working dir failed"); Commands::Version::warn_if_vcpkg_version_mismatch(paths); - if (const auto command_function = Commands::find(args.command, Commands::get_available_commands_type_b())) + if (const auto command_function = find_command(Commands::get_available_commands_type_b())) { - return command_function(args, paths); + return command_function->function(args, paths); } Triplet default_triplet; @@ -100,9 +118,9 @@ static void inner(const VcpkgCmdArguments& args) Input::check_triplet(default_triplet, paths); - if (const auto command_function = Commands::find(args.command, Commands::get_available_commands_type_a())) + if (const auto command_function = find_command(Commands::get_available_commands_type_a())) { - return command_function(args, paths, default_triplet); + return command_function->function(args, paths, default_triplet); } return invalid_command(args.command); @@ -202,7 +220,7 @@ int wmain(const int argc, const wchar_t* const* const argv) SetConsoleCP(65001); SetConsoleOutputCP(65001); - *GlobalState::timer.lock() = ElapsedTime::create_started(); + *GlobalState::timer.lock() = Chrono::ElapsedTime::create_started(); const std::string trimmed_command_line = trim_path_from_command_line(Strings::to_utf8(GetCommandLineW())); diff --git a/toolsrc/src/vcpkg/base/checks.cpp b/toolsrc/src/vcpkg/base/checks.cpp new file mode 100644 index 000000000..73c7b9b1a --- /dev/null +++ b/toolsrc/src/vcpkg/base/checks.cpp @@ -0,0 +1,81 @@ +#include "pch.h" + +#include +#include + +#include +#include + +namespace vcpkg::Checks +{ + [[noreturn]] static void cleanup_and_exit(const int exit_code) + { + const auto elapsed_us = GlobalState::timer.lock()->microseconds(); + + auto metrics = Metrics::g_metrics.lock(); + metrics->track_metric("elapsed_us", elapsed_us); + GlobalState::debugging = false; + metrics->flush(); + + SetConsoleCP(GlobalState::g_init_console_cp); + SetConsoleOutputCP(GlobalState::g_init_console_output_cp); + + fflush(nullptr); + + ::TerminateProcess(::GetCurrentProcess(), exit_code); + } + + static BOOL ctrl_handler(DWORD fdw_ctrl_type) + { + { + auto locked_metrics = Metrics::g_metrics.lock(); + locked_metrics->track_property("CtrlHandler", std::to_string(fdw_ctrl_type)); + locked_metrics->track_property("error", "CtrlHandler was fired."); + } + cleanup_and_exit(EXIT_FAILURE); + } + + void register_console_ctrl_handler() + { + SetConsoleCtrlHandler(reinterpret_cast(ctrl_handler), TRUE); + } + + [[noreturn]] void unreachable(const LineInfo& line_info) + { + System::println(System::Color::error, "Error: Unreachable code was reached"); + System::println(System::Color::error, line_info.to_string()); // Always print line_info here +#ifndef NDEBUG + std::abort(); +#else + cleanup_and_exit(EXIT_FAILURE); +#endif + } + + [[noreturn]] void exit_with_code(const LineInfo& line_info, const int exit_code) + { + Debug::println(System::Color::error, line_info.to_string()); + cleanup_and_exit(exit_code); + } + + [[noreturn]] void exit_with_message(const LineInfo& line_info, const CStringView error_message) + { + System::println(System::Color::error, error_message); + exit_fail(line_info); + } + + void check_exit(const LineInfo& line_info, bool expression) + { + if (!expression) + { + exit_with_message(line_info, Strings::EMPTY); + } + } + + void check_exit(const LineInfo& line_info, bool expression, const CStringView error_message) + { + if (!expression) + { + exit_with_message(line_info, error_message); + } + } +} diff --git a/toolsrc/src/vcpkg/base/chrono.cpp b/toolsrc/src/vcpkg/base/chrono.cpp new file mode 100644 index 000000000..5d28909fc --- /dev/null +++ b/toolsrc/src/vcpkg/base/chrono.cpp @@ -0,0 +1,61 @@ +#include "pch.h" + +#include +#include + +namespace vcpkg::Chrono +{ + static std::string format_time_userfriendly(const std::chrono::nanoseconds& nanos) + { + using std::chrono::duration_cast; + using std::chrono::hours; + using std::chrono::microseconds; + using std::chrono::milliseconds; + using std::chrono::minutes; + using std::chrono::nanoseconds; + using std::chrono::seconds; + + const double nanos_as_double = static_cast(nanos.count()); + + if (duration_cast(nanos) > hours()) + { + const auto t = nanos_as_double / duration_cast(hours(1)).count(); + return Strings::format("%.4g h", t); + } + + if (duration_cast(nanos) > minutes()) + { + const auto t = nanos_as_double / duration_cast(minutes(1)).count(); + return Strings::format("%.4g min", t); + } + + if (duration_cast(nanos) > seconds()) + { + const auto t = nanos_as_double / duration_cast(seconds(1)).count(); + return Strings::format("%.4g s", t); + } + + if (duration_cast(nanos) > milliseconds()) + { + const auto t = nanos_as_double / duration_cast(milliseconds(1)).count(); + return Strings::format("%.4g ms", t); + } + + if (duration_cast(nanos) > microseconds()) + { + const auto t = nanos_as_double / duration_cast(microseconds(1)).count(); + return Strings::format("%.4g us", t); + } + + return Strings::format("%.4g ns", nanos_as_double); + } + + ElapsedTime ElapsedTime::create_started() + { + ElapsedTime t; + t.m_start_tick = std::chrono::high_resolution_clock::now(); + return t; + } + + std::string ElapsedTime::to_string() const { return format_time_userfriendly(elapsed()); } +} diff --git a/toolsrc/src/vcpkg/base/cofffilereader.cpp b/toolsrc/src/vcpkg/base/cofffilereader.cpp new file mode 100644 index 000000000..5e9c86998 --- /dev/null +++ b/toolsrc/src/vcpkg/base/cofffilereader.cpp @@ -0,0 +1,308 @@ +#include "pch.h" + +#include +#include + +using namespace std; + +namespace vcpkg::CoffFileReader +{ + template + static T reinterpret_bytes(const char* data) + { + return (*reinterpret_cast(&data[0])); + } + + template + static T read_value_from_stream(fstream& fs) + { + T data; + fs.read(reinterpret_cast(&data), sizeof data); + return data; + } + + template + static T peek_value_from_stream(fstream& fs) + { + const fpos_t original_pos = fs.tellg().seekpos(); + T data; + fs.read(reinterpret_cast(&data), sizeof data); + fs.seekg(original_pos); + return data; + } + + static void verify_equal_strings( + const LineInfo& line_info, const char* expected, const char* actual, int size, const char* label) + { + Checks::check_exit(line_info, + memcmp(expected, actual, size) == 0, + "Incorrect string (%s) found. Expected: (%s) but found (%s)", + label, + expected, + actual); + } + + static void read_and_verify_PE_signature(fstream& fs) + { + static const size_t OFFSET_TO_PE_SIGNATURE_OFFSET = 0x3c; + + static const char* PE_SIGNATURE = "PE\0\0"; + static const size_t PE_SIGNATURE_SIZE = 4; + + fs.seekg(OFFSET_TO_PE_SIGNATURE_OFFSET, ios_base::beg); + const int32_t offset_to_PE_signature = read_value_from_stream(fs); + + fs.seekg(offset_to_PE_signature); + char signature[PE_SIGNATURE_SIZE]; + fs.read(signature, PE_SIGNATURE_SIZE); + verify_equal_strings(VCPKG_LINE_INFO, PE_SIGNATURE, signature, PE_SIGNATURE_SIZE, "PE_SIGNATURE"); + fs.seekg(offset_to_PE_signature + PE_SIGNATURE_SIZE, ios_base::beg); + } + + static fpos_t align_to_size(const uint64_t unaligned, const uint64_t alignment_size) + { + fpos_t aligned = unaligned - 1; + aligned /= alignment_size; + aligned += 1; + aligned *= alignment_size; + return aligned; + } + + struct CoffFileHeader + { + static const size_t HEADER_SIZE = 20; + + static CoffFileHeader read(fstream& fs) + { + CoffFileHeader ret; + ret.data.resize(HEADER_SIZE); + fs.read(&ret.data[0], HEADER_SIZE); + return ret; + } + + MachineType machine_type() const + { + static const size_t MACHINE_TYPE_OFFSET = 0; + static const size_t MACHINE_TYPE_SIZE = 2; + + std::string machine_field_as_string = data.substr(MACHINE_TYPE_OFFSET, MACHINE_TYPE_SIZE); + const uint16_t machine = reinterpret_bytes(machine_field_as_string.c_str()); + return to_machine_type(machine); + } + + private: + std::string data; + }; + + struct ArchiveMemberHeader + { + static const size_t HEADER_SIZE = 60; + + static ArchiveMemberHeader read(fstream& fs) + { + static const size_t HEADER_END_OFFSET = 58; + static const char* HEADER_END = "`\n"; + static const size_t HEADER_END_SIZE = 2; + + ArchiveMemberHeader ret; + ret.data.resize(HEADER_SIZE); + fs.read(&ret.data[0], HEADER_SIZE); + + if (ret.data[0] != '\0') // Due to freeglut. github issue #223 + { + const std::string header_end = ret.data.substr(HEADER_END_OFFSET, HEADER_END_SIZE); + verify_equal_strings( + VCPKG_LINE_INFO, HEADER_END, header_end.c_str(), HEADER_END_SIZE, "LIB HEADER_END"); + } + + return ret; + } + + std::string name() const + { + static const size_t HEADER_NAME_OFFSET = 0; + static const size_t HEADER_NAME_SIZE = 16; + return data.substr(HEADER_NAME_OFFSET, HEADER_NAME_SIZE); + } + + uint64_t member_size() const + { + static const size_t ALIGNMENT_SIZE = 2; + + static const size_t HEADER_SIZE_OFFSET = 48; + static const size_t HEADER_SIZE_FIELD_SIZE = 10; + const std::string as_string = data.substr(HEADER_SIZE_OFFSET, HEADER_SIZE_FIELD_SIZE); + // This is in ASCII decimal representation + const uint64_t value = std::strtoull(as_string.c_str(), nullptr, 10); + + const uint64_t aligned = align_to_size(value, ALIGNMENT_SIZE); + return aligned; + } + + std::string data; + }; + + struct OffsetsArray + { + static OffsetsArray read(fstream& fs, const uint32_t offset_count) + { + static const size_t OFFSET_WIDTH = 4; + + std::string raw_offsets; + const size_t raw_offset_size = offset_count * OFFSET_WIDTH; + raw_offsets.resize(raw_offset_size); + fs.read(&raw_offsets[0], raw_offset_size); + + OffsetsArray ret; + for (uint32_t i = 0; i < offset_count; ++i) + { + const std::string value_as_string = raw_offsets.substr(OFFSET_WIDTH * i, OFFSET_WIDTH * (i + 1)); + const uint32_t value = reinterpret_bytes(value_as_string.c_str()); + + // Ignore offsets that point to offset 0. See vcpkg github #223 #288 #292 + if (value != 0) + { + ret.data.push_back(value); + } + } + + // Sort the offsets, because it is possible for them to be unsorted. See vcpkg github #292 + std::sort(ret.data.begin(), ret.data.end()); + return ret; + } + + std::vector data; + }; + + struct ImportHeader + { + static const size_t HEADER_SIZE = 20; + + static ImportHeader read(fstream& fs) + { + static const size_t SIG1_OFFSET = 0; + static const uint16_t SIG1 = static_cast(MachineType::UNKNOWN); + static const size_t SIG1_SIZE = 2; + + static const size_t SIG2_OFFSET = 2; + static const uint16_t SIG2 = 0xFFFF; + static const size_t SIG2_SIZE = 2; + + ImportHeader ret; + ret.data.resize(HEADER_SIZE); + fs.read(&ret.data[0], HEADER_SIZE); + + const std::string sig1_as_string = ret.data.substr(SIG1_OFFSET, SIG1_SIZE); + const uint16_t sig1 = reinterpret_bytes(sig1_as_string.c_str()); + Checks::check_exit(VCPKG_LINE_INFO, sig1 == SIG1, "Sig1 was incorrect. Expected %s but got %s", SIG1, sig1); + + const std::string sig2_as_string = ret.data.substr(SIG2_OFFSET, SIG2_SIZE); + const uint16_t sig2 = reinterpret_bytes(sig2_as_string.c_str()); + Checks::check_exit(VCPKG_LINE_INFO, sig2 == SIG2, "Sig2 was incorrect. Expected %s but got %s", SIG2, sig2); + + return ret; + } + + MachineType machine_type() const + { + static const size_t MACHINE_TYPE_OFFSET = 6; + static const size_t MACHINE_TYPE_SIZE = 2; + + std::string machine_field_as_string = data.substr(MACHINE_TYPE_OFFSET, MACHINE_TYPE_SIZE); + const uint16_t machine = reinterpret_bytes(machine_field_as_string.c_str()); + return to_machine_type(machine); + } + + private: + std::string data; + }; + + static void read_and_verify_archive_file_signature(fstream& fs) + { + static const char* FILE_START = "!\n"; + static const size_t FILE_START_SIZE = 8; + + fs.seekg(fs.beg); + + char file_start[FILE_START_SIZE]; + fs.read(file_start, FILE_START_SIZE); + verify_equal_strings(VCPKG_LINE_INFO, FILE_START, file_start, FILE_START_SIZE, "LIB FILE_START"); + } + + DllInfo read_dll(const fs::path& path) + { + std::fstream fs(path, std::ios::in | std::ios::binary | std::ios::ate); + Checks::check_exit(VCPKG_LINE_INFO, fs.is_open(), "Could not open file %s for reading", path.generic_string()); + + read_and_verify_PE_signature(fs); + CoffFileHeader header = CoffFileHeader::read(fs); + const MachineType machine = header.machine_type(); + return {machine}; + } + + struct Marker + { + void set_to_offset(const fpos_t position) { this->m_absolute_position = position; } + + void set_to_current_pos(fstream& fs) { this->m_absolute_position = fs.tellg().seekpos(); } + + void seek_to_marker(fstream& fs) const { fs.seekg(this->m_absolute_position, ios_base::beg); } + + void advance_by(const uint64_t offset) { this->m_absolute_position += offset; } + + private: + fpos_t m_absolute_position = 0; + }; + + LibInfo read_lib(const fs::path& path) + { + std::fstream fs(path, std::ios::in | std::ios::binary | std::ios::ate); + Checks::check_exit(VCPKG_LINE_INFO, fs.is_open(), "Could not open file %s for reading", path.generic_string()); + + read_and_verify_archive_file_signature(fs); + + Marker marker; + marker.set_to_current_pos(fs); + + // First Linker Member + const ArchiveMemberHeader first_linker_member_header = ArchiveMemberHeader::read(fs); + Checks::check_exit(VCPKG_LINE_INFO, + first_linker_member_header.name().substr(0, 2) == "/ ", + "Could not find proper first linker member"); + marker.advance_by(ArchiveMemberHeader::HEADER_SIZE + first_linker_member_header.member_size()); + marker.seek_to_marker(fs); + + const ArchiveMemberHeader second_linker_member_header = ArchiveMemberHeader::read(fs); + Checks::check_exit(VCPKG_LINE_INFO, + second_linker_member_header.name().substr(0, 2) == "/ ", + "Could not find proper second linker member"); + // The first 4 bytes contains the number of archive members + const uint32_t archive_member_count = read_value_from_stream(fs); + const OffsetsArray offsets = OffsetsArray::read(fs, archive_member_count); + marker.advance_by(ArchiveMemberHeader::HEADER_SIZE + second_linker_member_header.member_size()); + marker.seek_to_marker(fs); + + const bool hasLongnameMemberHeader = peek_value_from_stream(fs) == 0x2F2F; + if (hasLongnameMemberHeader) + { + const ArchiveMemberHeader longnames_member_header = ArchiveMemberHeader::read(fs); + marker.advance_by(ArchiveMemberHeader::HEADER_SIZE + longnames_member_header.member_size()); + marker.seek_to_marker(fs); + } + + std::set machine_types; + // Next we have the obj and pseudo-object files + for (const uint32_t offset : offsets.data) + { + marker.set_to_offset(offset + ArchiveMemberHeader::HEADER_SIZE); // Skip the header, no need to read it. + marker.seek_to_marker(fs); + const uint16_t first_two_bytes = peek_value_from_stream(fs); + const bool isImportHeader = to_machine_type(first_two_bytes) == MachineType::UNKNOWN; + const MachineType machine = + isImportHeader ? ImportHeader::read(fs).machine_type() : CoffFileHeader::read(fs).machine_type(); + machine_types.insert(machine); + } + + return {std::vector(machine_types.cbegin(), machine_types.cend())}; + } +} diff --git a/toolsrc/src/vcpkg/base/enums.cpp b/toolsrc/src/vcpkg/base/enums.cpp new file mode 100644 index 000000000..aa124f3aa --- /dev/null +++ b/toolsrc/src/vcpkg/base/enums.cpp @@ -0,0 +1,14 @@ +#include "pch.h" + +#include +#include + +namespace vcpkg::Enums +{ + std::string nullvalue_to_string(const CStringView enum_name) { return Strings::format("%s_NULLVALUE", enum_name); } + + [[noreturn]] void nullvalue_used(const LineInfo& line_info, const CStringView enum_name) + { + Checks::exit_with_message(line_info, "NULLVALUE of enum %s was used", enum_name); + } +} diff --git a/toolsrc/src/vcpkg/base/files.cpp b/toolsrc/src/vcpkg/base/files.cpp new file mode 100644 index 000000000..f8b239eaa --- /dev/null +++ b/toolsrc/src/vcpkg/base/files.cpp @@ -0,0 +1,208 @@ +#include "pch.h" + +#include +#include +#include + +namespace vcpkg::Files +{ + static const std::regex FILESYSTEM_INVALID_CHARACTERS_REGEX = std::regex(R"([\/:*?"<>|])"); + + struct RealFilesystem final : Filesystem + { + virtual Expected 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()) + { + return std::make_error_code(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::make_error_code(std::errc::file_too_large); + } + + std::string output; + output.resize(static_cast(length)); + file_stream.read(&output[0], length); + file_stream.close(); + + return std::move(output); + } + virtual Expected> 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::make_error_code(std::errc::no_such_file_or_directory); + } + + std::vector output; + std::string line; + while (std::getline(file_stream, line)) + { + output.push_back(line); + } + file_stream.close(); + + return std::move(output); + } + virtual fs::path find_file_recursively_up(const fs::path& starting_dir, + const std::string& filename) const override + { + 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; + } + + virtual std::vector get_files_recursive(const fs::path& dir) const override + { + std::vector ret; + + fs::stdfs::recursive_directory_iterator b(dir), e{}; + for (; b != e; ++b) + { + ret.push_back(b->path()); + } + + return ret; + } + + virtual std::vector get_files_non_recursive(const fs::path& dir) const override + { + std::vector ret; + + fs::stdfs::directory_iterator b(dir), e{}; + for (; b != e; ++b) + { + ret.push_back(b->path()); + } + + return ret; + } + + virtual void write_lines(const fs::path& file_path, const std::vector& lines) override + { + 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"; + } + output.close(); + } + + 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 + { + // Working around the currently buggy remove_all() + std::uintmax_t out = fs::stdfs::remove_all(path, ec); + + for (int i = 0; i < 5 && this->exists(path); i++) + { + using namespace std::chrono_literals; + std::this_thread::sleep_for(i * 100ms); + out += fs::stdfs::remove_all(path, ec); + } + + if (this->exists(path)) + { + System::println(System::Color::warning, + "Some files in %s were unable to be removed. Close any editors operating in this " + "directory and retry.", + path.string()); + } + + return out; + } + 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 bool create_directories(const fs::path& path, std::error_code& ec) override + { + return fs::stdfs::create_directories(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); + } + + 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, "Error: Could not open file for writing: %s", file_path.u8string().c_str()); + auto count = fwrite(data.data(), sizeof(data[0]), data.size(), f); + fclose(f); + + Checks::check_exit(VCPKG_LINE_INFO, count == data.size()); + } + }; + + Filesystem& get_real_filesystem() + { + static RealFilesystem real_fs; + return real_fs; + } + + bool has_invalid_chars_for_filesystem(const std::string& s) + { + return std::regex_search(s, FILESYSTEM_INVALID_CHARACTERS_REGEX); + } + + void print_paths(const std::vector& paths) + { + System::println(); + for (const fs::path& p : paths) + { + System::println(" %s", p.generic_string()); + } + System::println(); + } + + std::vector find_from_PATH(const std::wstring& name) + { + const std::wstring cmd = Strings::wformat(L"where.exe %s", name); + auto out = System::cmd_execute_and_capture_output(cmd); + if (out.exit_code != 0) + { + return {}; + } + + return Util::fmap(Strings::split(out.output, "\n"), [](auto&& s) { return fs::path(s); }); + } +} diff --git a/toolsrc/src/vcpkg/base/lineinfo.cpp b/toolsrc/src/vcpkg/base/lineinfo.cpp new file mode 100644 index 000000000..7435ed666 --- /dev/null +++ b/toolsrc/src/vcpkg/base/lineinfo.cpp @@ -0,0 +1,9 @@ +#include "pch.h" + +#include +#include + +namespace vcpkg +{ + std::string LineInfo::to_string() const { return Strings::format("%s(%d)", this->file_name, this->line_number); } +} diff --git a/toolsrc/src/vcpkg/base/machinetype.cpp b/toolsrc/src/vcpkg/base/machinetype.cpp new file mode 100644 index 000000000..2b7bd5e3a --- /dev/null +++ b/toolsrc/src/vcpkg/base/machinetype.cpp @@ -0,0 +1,41 @@ +#include "pch.h" + +#include +#include + +namespace vcpkg +{ + MachineType to_machine_type(const uint16_t value) + { + const MachineType t = static_cast(value); + switch (t) + { + case MachineType::UNKNOWN: + case MachineType::AM33: + case MachineType::AMD64: + case MachineType::ARM: + case MachineType::ARM64: + case MachineType::ARMNT: + case MachineType::EBC: + case MachineType::I386: + case MachineType::IA64: + case MachineType::M32R: + case MachineType::MIPS16: + case MachineType::MIPSFPU: + case MachineType::MIPSFPU16: + case MachineType::POWERPC: + case MachineType::POWERPCFP: + case MachineType::R4000: + case MachineType::RISCV32: + case MachineType::RISCV64: + case MachineType::RISCV128: + case MachineType::SH3: + case MachineType::SH3DSP: + case MachineType::SH4: + case MachineType::SH5: + case MachineType::THUMB: + case MachineType::WCEMIPSV2: return t; + default: Checks::exit_with_message(VCPKG_LINE_INFO, "Unknown machine type code 0x%x", value); + } + } +} diff --git a/toolsrc/src/vcpkg/base/strings.cpp b/toolsrc/src/vcpkg/base/strings.cpp new file mode 100644 index 000000000..2a6d3dff2 --- /dev/null +++ b/toolsrc/src/vcpkg/base/strings.cpp @@ -0,0 +1,174 @@ +#include "pch.h" + +#include +#include +#include + +namespace vcpkg::Strings::details +{ + // To disambiguate between two overloads + static const auto isspace = [](const char c) { return std::isspace(c); }; + + // Avoids C4244 warnings because of char<->int conversion that occur when using std::tolower() + static char tolower_char(const char c) { return static_cast(std::tolower(c)); } + +#if defined(_WIN32) + static _locale_t& c_locale() + { + static _locale_t c_locale_impl = _create_locale(LC_ALL, "C"); + return c_locale_impl; + } +#endif + + std::string format_internal(const char* fmtstr, ...) + { + va_list args; + va_start(args, fmtstr); + +#if defined(_WIN32) + const int sz = _vscprintf_l(fmtstr, c_locale(), args); +#else + const int sz = vsnprintf(nullptr, 0, fmtstr, args); +#endif + Checks::check_exit(VCPKG_LINE_INFO, sz > 0); + + std::string output(sz, '\0'); + +#if defined(_WIN32) + _vsnprintf_s_l(&output.at(0), output.size() + 1, output.size(), fmtstr, c_locale(), args); +#else + vsnprintf(&output.at(0), output.size() + 1, fmtstr, args); +#endif + va_end(args); + + return output; + } + + std::wstring wformat_internal(const wchar_t* fmtstr, ...) + { + va_list args; + va_start(args, fmtstr); + +#if defined(_WIN32) + const int sz = _vscwprintf_l(fmtstr, c_locale(), args); +#else + const int sz = vswprintf(nullptr, 0, fmtstr, args); +#endif + Checks::check_exit(VCPKG_LINE_INFO, sz > 0); + + std::wstring output(sz, L'\0'); + +#if defined(_WIN32) + _vsnwprintf_s_l(&output.at(0), output.size() + 1, output.size(), fmtstr, c_locale(), args); +#else + vswprintf(&output.at(0), output.size() + 1, fmtstr, args); +#endif + va_end(args); + + return output; + } +} + +namespace vcpkg::Strings +{ + std::wstring to_utf16(const CStringView s) + { + const int size = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, nullptr, 0); + std::wstring output; + output.resize(size - 1); + MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, output.data(), size - 1); + return output; + } + + std::string to_utf8(const CWStringView w) + { + const int size = WideCharToMultiByte(CP_UTF8, 0, w.c_str(), -1, nullptr, 0, nullptr, nullptr); + std::string output; + output.resize(size - 1); + WideCharToMultiByte(CP_UTF8, 0, w.c_str(), -1, output.data(), size - 1, nullptr, nullptr); + return output; + } + + std::string::const_iterator case_insensitive_ascii_find(const std::string& s, const std::string& pattern) + { + const std::string pattern_as_lower_case(ascii_to_lowercase(pattern)); + return search(s.begin(), + s.end(), + pattern_as_lower_case.begin(), + pattern_as_lower_case.end(), + [](const char a, const char b) { return details::tolower_char(a) == b; }); + } + + bool case_insensitive_ascii_contains(const std::string& s, const std::string& pattern) + { + return case_insensitive_ascii_find(s, pattern) != s.end(); + } + + bool case_insensitive_ascii_compare(const CStringView left, const CStringView right) + { + return _stricmp(left.c_str(), right.c_str()) == 0; + } + + std::string ascii_to_lowercase(const std::string& input) + { + std::string output(input); + std::transform(output.begin(), output.end(), output.begin(), &details::tolower_char); + return output; + } + + bool case_insensitive_ascii_starts_with(const std::string& s, const std::string& pattern) + { + return _strnicmp(s.c_str(), pattern.c_str(), pattern.size()) == 0; + } + + void trim(std::string* s) + { + s->erase(std::find_if_not(s->rbegin(), s->rend(), details::isspace).base(), s->end()); + s->erase(s->begin(), std::find_if_not(s->begin(), s->end(), details::isspace)); + } + + std::string trimmed(const std::string& s) + { + auto whitespace_back = std::find_if_not(s.rbegin(), s.rend(), details::isspace).base(); + auto whitespace_front = std::find_if_not(s.begin(), whitespace_back, details::isspace); + return std::string(whitespace_front, whitespace_back); + } + + void trim_all_and_remove_whitespace_strings(std::vector* strings) + { + for (std::string& s : *strings) + { + trim(&s); + } + + Util::erase_remove_if(*strings, [](const std::string& s) { return s.empty(); }); + } + + std::vector split(const std::string& s, const std::string& delimiter) + { + std::vector output; + + if (delimiter.empty()) + { + output.push_back(s); + return output; + } + + const size_t delimiter_length = delimiter.length(); + size_t i = 0; + for (size_t pos = s.find(delimiter); pos != std::string::npos; pos = s.find(delimiter, pos)) + { + output.push_back(s.substr(i, pos - i)); + pos += delimiter_length; + i = pos; + } + + // Add the rest of the string after the last delimiter, unless there is nothing after it + if (i != s.length()) + { + output.push_back(s.substr(i, s.length())); + } + + return output; + } +} diff --git a/toolsrc/src/vcpkg/base/system.cpp b/toolsrc/src/vcpkg/base/system.cpp new file mode 100644 index 000000000..716c2a6a6 --- /dev/null +++ b/toolsrc/src/vcpkg/base/system.cpp @@ -0,0 +1,350 @@ +#include "pch.h" + +#include +#include +#include + +#pragma comment(lib, "Advapi32") + +namespace vcpkg::System +{ + tm get_current_date_time() + { + using std::chrono::system_clock; + std::time_t now_time = system_clock::to_time_t(system_clock::now()); + tm parts; + localtime_s(&parts, &now_time); + return parts; + } + + fs::path get_exe_path_of_current_process() + { + wchar_t buf[_MAX_PATH]; + const int bytes = GetModuleFileNameW(nullptr, buf, _MAX_PATH); + if (bytes == 0) std::abort(); + return fs::path(buf, buf + bytes); + } + + Optional to_cpu_architecture(CStringView arch) + { + if (Strings::case_insensitive_ascii_compare(arch, "x86")) return CPUArchitecture::X86; + if (Strings::case_insensitive_ascii_compare(arch, "x64")) return CPUArchitecture::X64; + if (Strings::case_insensitive_ascii_compare(arch, "amd64")) return CPUArchitecture::X64; + if (Strings::case_insensitive_ascii_compare(arch, "arm")) return CPUArchitecture::ARM; + if (Strings::case_insensitive_ascii_compare(arch, "arm64")) return CPUArchitecture::ARM64; + return nullopt; + } + + CPUArchitecture get_host_processor() + { + auto w6432 = get_environment_variable(L"PROCESSOR_ARCHITEW6432"); + if (const auto p = w6432.get()) return to_cpu_architecture(Strings::to_utf8(*p)).value_or_exit(VCPKG_LINE_INFO); + + const auto procarch = get_environment_variable(L"PROCESSOR_ARCHITECTURE").value_or_exit(VCPKG_LINE_INFO); + return to_cpu_architecture(Strings::to_utf8(procarch)).value_or_exit(VCPKG_LINE_INFO); + } + + std::vector get_supported_host_architectures() + { + std::vector supported_architectures; + supported_architectures.push_back(get_host_processor()); + + // AMD64 machines support to run x86 applications + if (supported_architectures.back() == CPUArchitecture::X64) + { + supported_architectures.push_back(CPUArchitecture::X86); + } + + return supported_architectures; + } + + int cmd_execute_clean(const CWStringView cmd_line) + { + static const std::wstring SYSTEM_ROOT = get_environment_variable(L"SystemRoot").value_or_exit(VCPKG_LINE_INFO); + static const std::wstring SYSTEM_32 = SYSTEM_ROOT + LR"(\system32)"; + static const std::wstring NEW_PATH = Strings::wformat( + LR"(Path=%s;%s;%s\Wbem;%s\WindowsPowerShell\v1.0\)", SYSTEM_32, SYSTEM_ROOT, SYSTEM_32, SYSTEM_32); + + std::vector env_wstrings = { + L"ALLUSERSPROFILE", + L"APPDATA", + L"CommonProgramFiles", + L"CommonProgramFiles(x86)", + L"CommonProgramW6432", + L"COMPUTERNAME", + L"ComSpec", + L"HOMEDRIVE", + L"HOMEPATH", + L"LOCALAPPDATA", + L"LOGONSERVER", + L"NUMBER_OF_PROCESSORS", + L"OS", + L"PATHEXT", + L"PROCESSOR_ARCHITECTURE", + L"PROCESSOR_ARCHITEW6432", + L"PROCESSOR_IDENTIFIER", + L"PROCESSOR_LEVEL", + L"PROCESSOR_REVISION", + L"ProgramData", + L"ProgramFiles", + L"ProgramFiles(x86)", + L"ProgramW6432", + L"PROMPT", + L"PSModulePath", + L"PUBLIC", + L"SystemDrive", + L"SystemRoot", + L"TEMP", + L"TMP", + L"USERDNSDOMAIN", + L"USERDOMAIN", + L"USERDOMAIN_ROAMINGPROFILE", + L"USERNAME", + L"USERPROFILE", + L"windir", + // Enables proxy information to be passed to Curl, the underlying download library in cmake.exe + L"HTTP_PROXY", + L"HTTPS_PROXY", + // Enables find_package(CUDA) in CMake + L"CUDA_PATH", + }; + + // Flush stdout before launching external process + fflush(nullptr); + + std::wstring env_cstr; + + for (auto&& env_wstring : env_wstrings) + { + const Optional value = System::get_environment_variable(env_wstring); + const auto v = value.get(); + if (!v || v->empty()) continue; + + env_cstr.append(env_wstring); + env_cstr.push_back(L'='); + env_cstr.append(*v); + env_cstr.push_back(L'\0'); + } + + env_cstr.append(NEW_PATH); + env_cstr.push_back(L'\0'); + + STARTUPINFOW startup_info; + memset(&startup_info, 0, sizeof(STARTUPINFOW)); + startup_info.cb = sizeof(STARTUPINFOW); + + PROCESS_INFORMATION process_info; + memset(&process_info, 0, sizeof(PROCESS_INFORMATION)); + + // Basically we are wrapping it in quotes + std::wstring actual_cmd_line = Strings::wformat(LR"###(cmd.exe /c "%s")###", cmd_line); + Debug::println("CreateProcessW(%s)", Strings::to_utf8(actual_cmd_line)); + bool succeeded = TRUE == CreateProcessW(nullptr, + actual_cmd_line.data(), + nullptr, + nullptr, + FALSE, + BELOW_NORMAL_PRIORITY_CLASS | CREATE_UNICODE_ENVIRONMENT, + env_cstr.data(), + nullptr, + &startup_info, + &process_info); + + Checks::check_exit(VCPKG_LINE_INFO, succeeded, "Process creation failed with error code: %lu", GetLastError()); + + CloseHandle(process_info.hThread); + + const DWORD result = WaitForSingleObject(process_info.hProcess, INFINITE); + Checks::check_exit(VCPKG_LINE_INFO, result != WAIT_FAILED, "WaitForSingleObject failed"); + + DWORD exit_code = 0; + GetExitCodeProcess(process_info.hProcess, &exit_code); + + Debug::println("CreateProcessW() returned %lu", exit_code); + return static_cast(exit_code); + } + + int cmd_execute(const CWStringView cmd_line) + { + // Flush stdout before launching external process + fflush(nullptr); + + // Basically we are wrapping it in quotes + const std::wstring& actual_cmd_line = Strings::wformat(LR"###("%s")###", cmd_line); + Debug::println("_wsystem(%s)", Strings::to_utf8(actual_cmd_line)); + const int exit_code = _wsystem(actual_cmd_line.c_str()); + Debug::println("_wsystem() returned %d", exit_code); + return exit_code; + } + + // On Win7, output from powershell calls contain a byte order mark, so we strip it out if it is present + static void remove_byte_order_marks(std::wstring* s) + { + const wchar_t* a = s->c_str(); + // This is the UTF-8 byte-order mark + while (s->size() >= 3 && a[0] == 0xEF && a[1] == 0xBB && a[2] == 0xBF) + { + s->erase(0, 3); + } + } + + ExitCodeAndOutput cmd_execute_and_capture_output(const CWStringView cmd_line) + { + // Flush stdout before launching external process + fflush(stdout); + + const std::wstring& actual_cmd_line = Strings::wformat(LR"###("%s 2>&1")###", cmd_line); + + Debug::println("_wpopen(%s)", Strings::to_utf8(actual_cmd_line)); + std::wstring output; + wchar_t buf[1024]; + const auto pipe = _wpopen(actual_cmd_line.c_str(), L"r"); + if (pipe == nullptr) + { + return {1, Strings::to_utf8(output)}; + } + while (fgetws(buf, 1024, pipe)) + { + output.append(buf); + } + if (!feof(pipe)) + { + return {1, Strings::to_utf8(output)}; + } + + const auto ec = _pclose(pipe); + Debug::println("_pclose() returned %d", ec); + remove_byte_order_marks(&output); + return {ec, Strings::to_utf8(output)}; + } + + std::wstring create_powershell_script_cmd(const fs::path& script_path, const CWStringView args) + { + // TODO: switch out ExecutionPolicy Bypass with "Remove Mark Of The Web" code and restore RemoteSigned + return Strings::wformat( + LR"(powershell -NoProfile -ExecutionPolicy Bypass -Command "& {& '%s' %s}")", script_path.native(), args); + } + + void println() { println(Strings::EMPTY); } + + void print(const CStringView message) { fputs(message.c_str(), stdout); } + + void println(const CStringView message) + { + print(message); + putchar('\n'); + } + + void print(const Color c, const CStringView message) + { + const HANDLE console_handle = GetStdHandle(STD_OUTPUT_HANDLE); + + CONSOLE_SCREEN_BUFFER_INFO console_screen_buffer_info{}; + GetConsoleScreenBufferInfo(console_handle, &console_screen_buffer_info); + const auto original_color = console_screen_buffer_info.wAttributes; + + SetConsoleTextAttribute(console_handle, static_cast(c) | (original_color & 0xF0)); + print(message); + SetConsoleTextAttribute(console_handle, original_color); + } + + void println(const Color c, const CStringView message) + { + print(c, message); + putchar('\n'); + } + + Optional get_environment_variable(const CWStringView varname) noexcept + { + const auto sz = GetEnvironmentVariableW(varname.c_str(), nullptr, 0); + if (sz == 0) return nullopt; + + std::wstring ret(sz, L'\0'); + + Checks::check_exit(VCPKG_LINE_INFO, MAXDWORD >= ret.size()); + const auto sz2 = GetEnvironmentVariableW(varname.c_str(), ret.data(), static_cast(ret.size())); + Checks::check_exit(VCPKG_LINE_INFO, sz2 + 1 == sz); + ret.pop_back(); + return ret; + } + + static bool is_string_keytype(DWORD hkey_type) + { + return hkey_type == REG_SZ || hkey_type == REG_MULTI_SZ || hkey_type == REG_EXPAND_SZ; + } + + Optional get_registry_string(HKEY base, const CWStringView sub_key, const CWStringView valuename) + { + HKEY k = nullptr; + const LSTATUS ec = RegOpenKeyExW(base, sub_key.c_str(), NULL, KEY_READ, &k); + if (ec != ERROR_SUCCESS) return nullopt; + + DWORD dw_buffer_size = 0; + DWORD dw_type = 0; + auto rc = RegQueryValueExW(k, valuename.c_str(), nullptr, &dw_type, nullptr, &dw_buffer_size); + if (rc != ERROR_SUCCESS || !is_string_keytype(dw_type) || dw_buffer_size == 0 || + dw_buffer_size % sizeof(wchar_t) != 0) + return nullopt; + std::wstring ret; + ret.resize(dw_buffer_size / sizeof(wchar_t)); + + rc = RegQueryValueExW( + k, valuename.c_str(), nullptr, &dw_type, reinterpret_cast(ret.data()), &dw_buffer_size); + if (rc != ERROR_SUCCESS || !is_string_keytype(dw_type) || dw_buffer_size != sizeof(wchar_t) * ret.size()) + return nullopt; + + ret.pop_back(); // remove extra trailing null byte + return ret; + } + + static const fs::path& get_program_files() + { + static const fs::path PATH = System::get_environment_variable(L"PROGRAMFILES").value_or_exit(VCPKG_LINE_INFO); + return PATH; + } + + const fs::path& get_program_files_32_bit() + { + static const fs::path PATH = []() -> fs::path { + auto value = System::get_environment_variable(L"ProgramFiles(x86)"); + if (auto v = value.get()) + { + return std::move(*v); + } + return get_program_files(); + }(); + return PATH; + } + + const fs::path& get_program_files_platform_bitness() + { + static const fs::path PATH = []() -> fs::path { + auto value = System::get_environment_variable(L"ProgramW6432"); + if (auto v = value.get()) + { + return std::move(*v); + } + return get_program_files(); + }(); + return PATH; + } +} + +namespace vcpkg::Debug +{ + void println(const CStringView message) + { + if (GlobalState::debugging) + { + System::println("[DEBUG] %s", message); + } + } + + void println(const System::Color c, const CStringView message) + { + if (GlobalState::debugging) + { + System::println(c, "[DEBUG] %s", message); + } + } +} diff --git a/toolsrc/src/vcpkg/binaryparagraph.cpp b/toolsrc/src/vcpkg/binaryparagraph.cpp new file mode 100644 index 000000000..ef943011f --- /dev/null +++ b/toolsrc/src/vcpkg/binaryparagraph.cpp @@ -0,0 +1,123 @@ +#include "pch.h" + +#include +#include +#include + +namespace vcpkg +{ + namespace Fields + { + static const std::string PACKAGE = "Package"; + static const std::string VERSION = "Version"; + static const std::string ARCHITECTURE = "Architecture"; + static const std::string MULTI_ARCH = "Multi-Arch"; + } + + namespace Fields + { + static const std::string FEATURE = "Feature"; + static const std::string DESCRIPTION = "Description"; + static const std::string MAINTAINER = "Maintainer"; + static const std::string DEPENDS = "Depends"; + static const std::string DEFAULTFEATURES = "Default-Features"; + } + + BinaryParagraph::BinaryParagraph() = default; + + BinaryParagraph::BinaryParagraph(std::unordered_map fields) + { + using namespace vcpkg::Parse; + + ParagraphParser parser(std::move(fields)); + + { + std::string name; + parser.required_field(Fields::PACKAGE, name); + std::string architecture; + parser.required_field(Fields::ARCHITECTURE, architecture); + this->spec = PackageSpec::from_name_and_triplet(name, Triplet::from_canonical_name(architecture)) + .value_or_exit(VCPKG_LINE_INFO); + } + + // one or the other + this->version = parser.optional_field(Fields::VERSION); + this->feature = parser.optional_field(Fields::FEATURE); + + this->description = parser.optional_field(Fields::DESCRIPTION); + this->maintainer = parser.optional_field(Fields::MAINTAINER); + + std::string multi_arch; + parser.required_field(Fields::MULTI_ARCH, multi_arch); + + this->depends = parse_comma_list(parser.optional_field(Fields::DEPENDS)); + if (this->feature.empty()) + { + this->default_features = parse_comma_list(parser.optional_field(Fields::DEFAULTFEATURES)); + } + + if (const auto err = parser.error_info(this->spec.to_string())) + { + System::println( + System::Color::error, "Error: while parsing the Binary Paragraph for %s", this->spec.to_string()); + print_error_message(err); + Checks::exit_fail(VCPKG_LINE_INFO); + } + + // prefer failing above when possible because it gives better information + Checks::check_exit(VCPKG_LINE_INFO, multi_arch == "same", "Multi-Arch must be 'same' but was %s", multi_arch); + } + + BinaryParagraph::BinaryParagraph(const SourceParagraph& spgh, const Triplet& triplet) + { + this->spec = PackageSpec::from_name_and_triplet(spgh.name, triplet).value_or_exit(VCPKG_LINE_INFO); + this->version = spgh.version; + this->description = spgh.description; + this->maintainer = spgh.maintainer; + this->depends = filter_dependencies(spgh.depends, triplet); + } + + BinaryParagraph::BinaryParagraph(const SourceParagraph& spgh, const FeatureParagraph& fpgh, const Triplet& triplet) + { + this->spec = PackageSpec::from_name_and_triplet(spgh.name, triplet).value_or_exit(VCPKG_LINE_INFO); + this->version = Strings::EMPTY; + this->feature = fpgh.name; + this->description = fpgh.description; + this->maintainer = Strings::EMPTY; + this->depends = filter_dependencies(fpgh.depends, triplet); + } + + std::string BinaryParagraph::displayname() const + { + const auto f = this->feature.empty() ? "core" : this->feature; + return Strings::format("%s[%s]:%s", this->spec.name(), f, this->spec.triplet()); + } + + std::string BinaryParagraph::dir() const { return this->spec.dir(); } + + std::string BinaryParagraph::fullstem() const + { + return Strings::format("%s_%s_%s", this->spec.name(), this->version, this->spec.triplet()); + } + + void serialize(const BinaryParagraph& pgh, std::string& out_str) + { + out_str.append("Package: ").append(pgh.spec.name()).push_back('\n'); + if (!pgh.version.empty()) + out_str.append("Version: ").append(pgh.version).push_back('\n'); + else if (!pgh.feature.empty()) + out_str.append("Feature: ").append(pgh.feature).push_back('\n'); + if (!pgh.depends.empty()) + { + out_str.append("Depends: "); + out_str.append(Strings::join(", ", pgh.depends)); + out_str.push_back('\n'); + } + + out_str.append("Architecture: ").append(pgh.spec.triplet().to_string()).push_back('\n'); + out_str.append("Multi-Arch: same\n"); + + 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/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp new file mode 100644 index 000000000..99ec541c1 --- /dev/null +++ b/toolsrc/src/vcpkg/build.cpp @@ -0,0 +1,533 @@ +#include "pch.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using vcpkg::Build::BuildResult; +using vcpkg::Parse::ParseControlErrorInfo; +using vcpkg::Parse::ParseExpected; + +namespace vcpkg::Build::Command +{ + using Dependencies::InstallPlanAction; + using Dependencies::InstallPlanType; + + static const std::string OPTION_CHECKS_ONLY = "--checks-only"; + + void perform_and_exit(const FullPackageSpec& full_spec, + const fs::path& port_dir, + const std::unordered_set& options, + const VcpkgPaths& paths) + { + const PackageSpec& spec = full_spec.package_spec; + if (options.find(OPTION_CHECKS_ONLY) != options.end()) + { + const auto pre_build_info = Build::PreBuildInfo::from_triplet_file(paths, spec.triplet()); + const auto build_info = Build::read_build_info(paths.get_filesystem(), paths.build_info_file_path(spec)); + const size_t error_count = PostBuildLint::perform_all_checks(spec, paths, pre_build_info, build_info); + Checks::check_exit(VCPKG_LINE_INFO, error_count == 0); + Checks::exit_success(VCPKG_LINE_INFO); + } + + const ParseExpected source_control_file = + Paragraphs::try_load_port(paths.get_filesystem(), port_dir); + + if (!source_control_file.has_value()) + { + print_error_message(source_control_file.error()); + Checks::exit_fail(VCPKG_LINE_INFO); + } + + for (const std::string& str : full_spec.features) + { + System::println("%s \n", str); + } + const auto& scf = source_control_file.value_or_exit(VCPKG_LINE_INFO); + Checks::check_exit(VCPKG_LINE_INFO, + spec.name() == scf->core_paragraph->name, + "The Name: field inside the CONTROL does not match the port directory: '%s' != '%s'", + scf->core_paragraph->name, + spec.name()); + + const StatusParagraphs status_db = database_load_check(paths); + const Build::BuildPackageOptions build_package_options{Build::UseHeadVersion::NO, Build::AllowDownloads::YES}; + + const Build::BuildPackageConfig build_config{ + *scf->core_paragraph, spec.triplet(), paths.port_dir(spec), build_package_options}; + + const auto result = Build::build_package(paths, build_config, status_db); + if (result.code == BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES) + { + System::println(System::Color::error, + "The build command requires all dependencies to be already installed."); + System::println("The following dependencies are missing:"); + System::println(); + for (const auto& p : result.unmet_dependencies) + { + System::println(" %s", p); + } + System::println(); + Checks::exit_fail(VCPKG_LINE_INFO); + } + + if (result.code != BuildResult::SUCCEEDED) + { + System::println(System::Color::error, Build::create_error_message(result.code, spec)); + System::println(Build::create_user_troubleshooting_message(spec)); + Checks::exit_fail(VCPKG_LINE_INFO); + } + + Checks::exit_success(VCPKG_LINE_INFO); + } + + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) + { + static const std::string EXAMPLE = Help::create_example_string("build zlib:x64-windows"); + // Build only takes a single package and all dependencies must already be installed + args.check_exact_arg_count(1, EXAMPLE); + const std::string command_argument = args.command_arguments.at(0); + const FullPackageSpec spec = Input::check_and_get_full_package_spec(command_argument, default_triplet, EXAMPLE); + Input::check_triplet(spec.package_spec.triplet(), paths); + const std::unordered_set options = + args.check_and_get_optional_command_arguments({OPTION_CHECKS_ONLY}); + perform_and_exit(spec, paths.port_dir(spec.package_spec), options, paths); + } +} + +namespace vcpkg::Build +{ + static const std::string NAME_EMPTY_PACKAGE = "PolicyEmptyPackage"; + static const std::string NAME_DLLS_WITHOUT_LIBS = "PolicyDLLsWithoutLIBs"; + static const std::string NAME_ONLY_RELEASE_CRT = "PolicyOnlyReleaseCRT"; + static const std::string NAME_EMPTY_INCLUDE_FOLDER = "PolicyEmptyIncludeFolder"; + static const std::string NAME_ALLOW_OBSOLETE_MSVCRT = "PolicyAllowObsoleteMsvcrt"; + + const std::string& to_string(BuildPolicy policy) + { + switch (policy) + { + case BuildPolicy::EMPTY_PACKAGE: return NAME_EMPTY_PACKAGE; + case BuildPolicy::DLLS_WITHOUT_LIBS: return NAME_DLLS_WITHOUT_LIBS; + case BuildPolicy::ONLY_RELEASE_CRT: return NAME_ONLY_RELEASE_CRT; + case BuildPolicy::EMPTY_INCLUDE_FOLDER: return NAME_EMPTY_INCLUDE_FOLDER; + case BuildPolicy::ALLOW_OBSOLETE_MSVCRT: return NAME_ALLOW_OBSOLETE_MSVCRT; + default: Checks::unreachable(VCPKG_LINE_INFO); + } + } + + CStringView to_cmake_variable(BuildPolicy policy) + { + switch (policy) + { + case BuildPolicy::EMPTY_PACKAGE: return "VCPKG_POLICY_EMPTY_PACKAGE"; + case BuildPolicy::DLLS_WITHOUT_LIBS: return "VCPKG_POLICY_DLLS_WITHOUT_LIBS"; + case BuildPolicy::ONLY_RELEASE_CRT: return "VCPKG_POLICY_ONLY_RELEASE_CRT"; + case BuildPolicy::EMPTY_INCLUDE_FOLDER: return "VCPKG_POLICY_EMPTY_INCLUDE_FOLDER"; + case BuildPolicy::ALLOW_OBSOLETE_MSVCRT: return "VCPKG_POLICY_ALLOW_OBSOLETE_MSVCRT"; + default: Checks::unreachable(VCPKG_LINE_INFO); + } + } + + Optional to_linkage_type(const std::string& str) + { + if (str == "dynamic") return LinkageType::DYNAMIC; + if (str == "static") return LinkageType::STATIC; + return nullopt; + } + + namespace BuildInfoRequiredField + { + static const std::string CRT_LINKAGE = "CRTLinkage"; + static const std::string LIBRARY_LINKAGE = "LibraryLinkage"; + } + + CWStringView to_vcvarsall_target(const std::string& cmake_system_name) + { + if (cmake_system_name == Strings::EMPTY) return Strings::WEMPTY; + if (cmake_system_name == "Windows") return Strings::WEMPTY; + if (cmake_system_name == "WindowsStore") return L"store"; + + Checks::exit_with_message(VCPKG_LINE_INFO, "Unsupported vcvarsall target %s", cmake_system_name); + } + + CWStringView to_vcvarsall_toolchain(const std::string& target_architecture, const Toolset& toolset) + { + auto maybe_target_arch = System::to_cpu_architecture(target_architecture); + Checks::check_exit( + VCPKG_LINE_INFO, maybe_target_arch.has_value(), "Invalid architecture string: %s", target_architecture); + auto target_arch = maybe_target_arch.value_or_exit(VCPKG_LINE_INFO); + auto host_architectures = System::get_supported_host_architectures(); + + for (auto&& host : host_architectures) + { + auto it = Util::find_if(toolset.supported_architectures, [&](const ToolsetArchOption& opt) { + return host == opt.host_arch && target_arch == opt.target_arch; + }); + if (it != toolset.supported_architectures.end()) return it->name; + } + + Checks::exit_with_message(VCPKG_LINE_INFO, "Unsupported toolchain combination %s", target_architecture); + } + + std::wstring make_build_env_cmd(const PreBuildInfo& pre_build_info, const Toolset& toolset) + { + const wchar_t* tonull = L" >nul"; + if (GlobalState::debugging) + { + tonull = Strings::WEMPTY; + } + + const auto arch = to_vcvarsall_toolchain(pre_build_info.target_architecture, toolset); + const auto target = to_vcvarsall_target(pre_build_info.cmake_system_name); + + return Strings::wformat(LR"("%s" %s %s %s %s 2>&1)", + toolset.vcvarsall.native(), + Strings::join(L" ", toolset.vcvarsall_options), + arch, + target, + tonull); + } + + static void create_binary_feature_control_file(const SourceParagraph& source_paragraph, + const FeatureParagraph& feature_paragraph, + const Triplet& triplet, + BinaryControlFile& bcf) + { + BinaryParagraph bpgh(source_paragraph, feature_paragraph, triplet); + bcf.features.emplace_back(std::move(bpgh)); + } + + static void create_binary_control_file(const SourceParagraph& source_paragraph, + const Triplet& triplet, + const BuildInfo& build_info, + BinaryControlFile& bcf) + { + BinaryParagraph bpgh(source_paragraph, triplet); + if (const auto p_ver = build_info.version.get()) + { + bpgh.version = *p_ver; + } + bcf.core_paragraph = std::move(bpgh); + } + + static void write_binary_control_file(const VcpkgPaths& paths, BinaryControlFile bcf) + { + std::string start = Strings::serialize(bcf.core_paragraph); + for (auto&& feature : bcf.features) + { + start += "\n" + Strings::serialize(feature); + } + const fs::path binary_control_file = paths.packages / bcf.core_paragraph.dir() / "CONTROL"; + paths.get_filesystem().write_contents(binary_control_file, start); + } + + ExtendedBuildResult build_package(const VcpkgPaths& paths, + const BuildPackageConfig& config, + const StatusParagraphs& status_db) + { + const PackageSpec spec = + PackageSpec::from_name_and_triplet(config.src.name, config.triplet).value_or_exit(VCPKG_LINE_INFO); + + const Triplet& triplet = config.triplet; + { + std::vector missing_specs; + for (auto&& dep : filter_dependencies(config.src.depends, triplet)) + { + if (status_db.find_installed(dep, triplet) == status_db.end()) + { + missing_specs.push_back( + PackageSpec::from_name_and_triplet(dep, triplet).value_or_exit(VCPKG_LINE_INFO)); + } + } + // Fail the build if any dependencies were missing + if (!missing_specs.empty()) + { + return {BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES, std::move(missing_specs)}; + } + } + + const fs::path& cmake_exe_path = paths.get_cmake_exe(); + const fs::path& git_exe_path = paths.get_git_exe(); + + const fs::path ports_cmake_script_path = paths.ports_cmake; + const auto pre_build_info = PreBuildInfo::from_triplet_file(paths, triplet); + const Toolset& toolset = paths.get_toolset(pre_build_info.platform_toolset, pre_build_info.visual_studio_path); + const auto cmd_set_environment = make_build_env_cmd(pre_build_info, toolset); + + std::string features; + if (GlobalState::feature_packages) + { + if (config.feature_list) + { + for (auto&& feature : *config.feature_list) + { + features.append(feature + ";"); + } + if (features.size() > 0) + { + features.pop_back(); + } + } + } + + const std::wstring cmd_launch_cmake = make_cmake_cmd( + cmake_exe_path, + ports_cmake_script_path, + { + {L"CMD", L"BUILD"}, + {L"PORT", config.src.name}, + {L"CURRENT_PORT_DIR", config.port_dir / "/."}, + {L"TARGET_TRIPLET", triplet.canonical_name()}, + {L"VCPKG_PLATFORM_TOOLSET", toolset.version.c_str()}, + {L"VCPKG_USE_HEAD_VERSION", to_bool(config.build_package_options.use_head_version) ? L"1" : L"0"}, + {L"_VCPKG_NO_DOWNLOADS", !to_bool(config.build_package_options.allow_downloads) ? L"1" : L"0"}, + {L"GIT", git_exe_path}, + {L"FEATURES", features}, + }); + + const std::wstring command = Strings::wformat(LR"(%s && %s)", cmd_set_environment, cmd_launch_cmake); + + const auto timer = Chrono::ElapsedTime::create_started(); + + const int return_code = System::cmd_execute_clean(command); + const auto buildtimeus = timer.microseconds(); + const auto spec_string = spec.to_string(); + + { + auto locked_metrics = Metrics::g_metrics.lock(); + locked_metrics->track_metric("buildtimeus-" + spec_string, buildtimeus); + if (return_code != 0) + { + locked_metrics->track_property("error", "build failed"); + locked_metrics->track_property("build_error", spec_string); + return {BuildResult::BUILD_FAILED, {}}; + } + } + + const BuildInfo build_info = read_build_info(paths.get_filesystem(), paths.build_info_file_path(spec)); + const size_t error_count = PostBuildLint::perform_all_checks(spec, paths, pre_build_info, build_info); + + BinaryControlFile bcf; + + create_binary_control_file(config.src, triplet, build_info, bcf); + + if (error_count != 0) + { + return {BuildResult::POST_BUILD_CHECKS_FAILED, {}}; + } + if (GlobalState::feature_packages) + { + if (config.feature_list) + { + for (auto&& feature : *config.feature_list) + { + for (auto&& f_pgh : config.scf->feature_paragraphs) + { + if (f_pgh->name == feature) + create_binary_feature_control_file(*config.scf->core_paragraph, *f_pgh, triplet, bcf); + } + } + } + } + + write_binary_control_file(paths, bcf); + + // const fs::path port_buildtrees_dir = paths.buildtrees / spec.name; + // delete_directory(port_buildtrees_dir); + + return {BuildResult::SUCCEEDED, {}}; + } + + const std::string& to_string(const BuildResult build_result) + { + static const std::string NULLVALUE_STRING = Enums::nullvalue_to_string("vcpkg::Commands::Build::BuildResult"); + static const std::string SUCCEEDED_STRING = "SUCCEEDED"; + static const std::string BUILD_FAILED_STRING = "BUILD_FAILED"; + static const std::string FILE_CONFLICTS_STRING = "FILE_CONFLICTS"; + static const std::string POST_BUILD_CHECKS_FAILED_STRING = "POST_BUILD_CHECKS_FAILED"; + static const std::string CASCADED_DUE_TO_MISSING_DEPENDENCIES_STRING = "CASCADED_DUE_TO_MISSING_DEPENDENCIES"; + + switch (build_result) + { + case BuildResult::NULLVALUE: return NULLVALUE_STRING; + case BuildResult::SUCCEEDED: return SUCCEEDED_STRING; + case BuildResult::BUILD_FAILED: return BUILD_FAILED_STRING; + case BuildResult::POST_BUILD_CHECKS_FAILED: return POST_BUILD_CHECKS_FAILED_STRING; + case BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES: return CASCADED_DUE_TO_MISSING_DEPENDENCIES_STRING; + case BuildResult::FILE_CONFLICTS: return FILE_CONFLICTS_STRING; + default: Checks::unreachable(VCPKG_LINE_INFO); + } + } + + std::string create_error_message(const BuildResult build_result, const PackageSpec& spec) + { + return Strings::format("Error: Building package %s failed with: %s", spec, Build::to_string(build_result)); + } + + std::string create_user_troubleshooting_message(const PackageSpec& spec) + { + return Strings::format("Please ensure you're using the latest portfiles with `.\\vcpkg update`, then\n" + "submit an issue at https://github.com/Microsoft/vcpkg/issues including:\n" + " Package: %s\n" + " Vcpkg version: %s\n" + "\n" + "Additionally, attach any relevant sections from the log files above.", + spec, + Commands::Version::version()); + } + + static BuildInfo inner_create_buildinfo(std::unordered_map pgh) + { + Parse::ParagraphParser parser(std::move(pgh)); + + BuildInfo build_info; + + { + std::string crt_linkage_as_string; + parser.required_field(BuildInfoRequiredField::CRT_LINKAGE, crt_linkage_as_string); + + auto crtlinkage = to_linkage_type(crt_linkage_as_string); + if (const auto p = crtlinkage.get()) + build_info.crt_linkage = *p; + else + Checks::exit_with_message(VCPKG_LINE_INFO, "Invalid crt linkage type: [%s]", crt_linkage_as_string); + } + + { + std::string library_linkage_as_string; + parser.required_field(BuildInfoRequiredField::LIBRARY_LINKAGE, library_linkage_as_string); + auto liblinkage = to_linkage_type(library_linkage_as_string); + if (const auto p = liblinkage.get()) + build_info.library_linkage = *p; + else + Checks::exit_with_message( + VCPKG_LINE_INFO, "Invalid library linkage type: [%s]", library_linkage_as_string); + } + std::string version = parser.optional_field("Version"); + if (!version.empty()) build_info.version = std::move(version); + + std::map policies; + for (auto policy : G_ALL_POLICIES) + { + const auto setting = parser.optional_field(to_string(policy)); + if (setting.empty()) continue; + if (setting == "enabled") + policies.emplace(policy, true); + else if (setting == "disabled") + policies.emplace(policy, false); + else + Checks::exit_with_message( + VCPKG_LINE_INFO, "Unknown setting for policy '%s': %s", to_string(policy), setting); + } + + if (const auto err = parser.error_info("PostBuildInformation")) + { + print_error_message(err); + Checks::exit_fail(VCPKG_LINE_INFO); + } + + build_info.policies = BuildPolicies(std::move(policies)); + + return build_info; + } + + BuildInfo read_build_info(const Files::Filesystem& fs, const fs::path& filepath) + { + const Expected> pghs = + Paragraphs::get_single_paragraph(fs, filepath); + Checks::check_exit(VCPKG_LINE_INFO, pghs.get() != nullptr, "Invalid BUILD_INFO file for package"); + return inner_create_buildinfo(*pghs.get()); + } + + PreBuildInfo PreBuildInfo::from_triplet_file(const VcpkgPaths& paths, const Triplet& triplet) + { + static constexpr CStringView FLAG_GUID = "c35112b6-d1ba-415b-aa5d-81de856ef8eb"; + + const fs::path& cmake_exe_path = paths.get_cmake_exe(); + const fs::path ports_cmake_script_path = paths.scripts / "get_triplet_environment.cmake"; + const fs::path triplet_file_path = paths.triplets / (triplet.canonical_name() + ".cmake"); + + const std::wstring cmd_launch_cmake = make_cmake_cmd(cmake_exe_path, + ports_cmake_script_path, + { + {L"CMAKE_TRIPLET_FILE", triplet_file_path}, + }); + + const std::wstring command = Strings::wformat(LR"(%s)", cmd_launch_cmake); + const auto ec_data = System::cmd_execute_and_capture_output(command); + Checks::check_exit(VCPKG_LINE_INFO, ec_data.exit_code == 0); + + const std::vector lines = Strings::split(ec_data.output, "\n"); + + PreBuildInfo pre_build_info; + + const auto e = lines.cend(); + auto cur = std::find(lines.cbegin(), e, FLAG_GUID); + if (cur != e) ++cur; + + for (; cur != e; ++cur) + { + auto&& line = *cur; + + const std::vector s = Strings::split(line, "="); + Checks::check_exit(VCPKG_LINE_INFO, + s.size() == 1 || s.size() == 2, + "Expected format is [VARIABLE_NAME=VARIABLE_VALUE], but was [%s]", + line); + + const bool variable_with_no_value = s.size() == 1; + const std::string variable_name = s.at(0); + const std::string variable_value = variable_with_no_value ? Strings::EMPTY : s.at(1); + + if (variable_name == "VCPKG_TARGET_ARCHITECTURE") + { + pre_build_info.target_architecture = variable_value; + continue; + } + + if (variable_name == "VCPKG_CMAKE_SYSTEM_NAME") + { + pre_build_info.cmake_system_name = variable_value; + continue; + } + + if (variable_name == "VCPKG_CMAKE_SYSTEM_VERSION") + { + pre_build_info.cmake_system_version = variable_value; + continue; + } + + if (variable_name == "VCPKG_PLATFORM_TOOLSET") + { + pre_build_info.platform_toolset = + variable_value.empty() ? nullopt : Optional{variable_value}; + continue; + } + + if (variable_name == "VCPKG_VISUAL_STUDIO_PATH") + { + pre_build_info.visual_studio_path = + variable_value.empty() ? nullopt : Optional{variable_value}; + continue; + } + + Checks::exit_with_message(VCPKG_LINE_INFO, "Unknown variable name %s", line); + } + + return pre_build_info; + } +} diff --git a/toolsrc/src/vcpkg/commands.autocomplete.cpp b/toolsrc/src/vcpkg/commands.autocomplete.cpp new file mode 100644 index 000000000..ad2a5b227 --- /dev/null +++ b/toolsrc/src/vcpkg/commands.autocomplete.cpp @@ -0,0 +1,78 @@ +#include "pch.h" + +#include +#include +#include +#include +#include +#include + +namespace vcpkg::Commands::Autocomplete +{ + std::vector autocomplete_install( + const std::vector>& source_paragraphs, const std::string& start_with) + { + std::vector results; + const auto& istartswith = Strings::case_insensitive_ascii_starts_with; + + for (const auto& source_control_file : source_paragraphs) + { + auto&& sp = *source_control_file->core_paragraph; + + if (istartswith(sp.name, start_with)) + { + results.push_back(sp.name); + } + } + return results; + } + + std::vector autocomplete_remove(std::vector installed_packages, + const std::string& start_with) + { + std::vector results; + const auto& istartswith = Strings::case_insensitive_ascii_starts_with; + + for (const auto& installed_package : installed_packages) + { + auto sp = installed_package->package.displayname(); + + if (istartswith(sp, start_with)) + { + results.push_back(sp); + } + } + return results; + } + + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) + { + static const std::string EXAMPLE = Strings::format("The argument should be a command line to autocomplete.\n%s", + Help::create_example_string("autocomplete install z")); + + args.check_min_arg_count(1, EXAMPLE); + args.check_max_arg_count(2, EXAMPLE); + args.check_and_get_optional_command_arguments({}); + + const std::string requested_command = args.command_arguments.at(0); + const std::string start_with = + args.command_arguments.size() > 1 ? args.command_arguments.at(1) : Strings::EMPTY; + std::vector results; + if (requested_command == "install") + { + auto sources_and_errors = Paragraphs::try_load_all_ports(paths.get_filesystem(), paths.ports); + auto& source_paragraphs = sources_and_errors.paragraphs; + + results = autocomplete_install(source_paragraphs, start_with); + } + else if (requested_command == "remove") + { + const StatusParagraphs status_db = database_load_check(paths); + std::vector installed_packages = get_installed_ports(status_db); + results = autocomplete_remove(installed_packages, start_with); + } + + System::println(Strings::join(" ", results)); + Checks::exit_success(VCPKG_LINE_INFO); + } +} diff --git a/toolsrc/src/vcpkg/commands.buildexternal.cpp b/toolsrc/src/vcpkg/commands.buildexternal.cpp new file mode 100644 index 000000000..3991beb62 --- /dev/null +++ b/toolsrc/src/vcpkg/commands.buildexternal.cpp @@ -0,0 +1,23 @@ +#include "pch.h" + +#include +#include +#include +#include + +namespace vcpkg::Commands::BuildExternal +{ + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) + { + static const std::string EXAMPLE = + Help::create_example_string(R"(build_external zlib2 C:\path\to\dir\with\controlfile\)"); + args.check_exact_arg_count(2, EXAMPLE); + const FullPackageSpec spec = + Input::check_and_get_full_package_spec(args.command_arguments.at(0), default_triplet, EXAMPLE); + Input::check_triplet(spec.package_spec.triplet(), paths); + const std::unordered_set options = args.check_and_get_optional_command_arguments({}); + + const fs::path port_dir = args.command_arguments.at(1); + Build::Command::perform_and_exit(spec, port_dir, options, paths); + } +} diff --git a/toolsrc/src/vcpkg/commands.cache.cpp b/toolsrc/src/vcpkg/commands.cache.cpp new file mode 100644 index 000000000..77f0a20f6 --- /dev/null +++ b/toolsrc/src/vcpkg/commands.cache.cpp @@ -0,0 +1,69 @@ +#include "pch.h" + +#include +#include +#include +#include +#include +#include + +namespace vcpkg::Commands::Cache +{ + static std::vector read_all_binary_paragraphs(const VcpkgPaths& paths) + { + std::vector output; + for (auto&& path : paths.get_filesystem().get_files_non_recursive(paths.packages)) + { + const Expected> pghs = + Paragraphs::get_single_paragraph(paths.get_filesystem(), path / "CONTROL"); + if (const auto p = pghs.get()) + { + const BinaryParagraph binary_paragraph = BinaryParagraph(*p); + output.push_back(binary_paragraph); + } + } + + return output; + } + + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) + { + static const std::string EXAMPLE = Strings::format( + "The argument should be a substring to search for, or no argument to display all cached libraries.\n%s", + Help::create_example_string("cache png")); + args.check_max_arg_count(1, EXAMPLE); + args.check_and_get_optional_command_arguments({}); + + const std::vector binary_paragraphs = read_all_binary_paragraphs(paths); + if (binary_paragraphs.empty()) + { + System::println("No packages are cached."); + Checks::exit_success(VCPKG_LINE_INFO); + } + + if (args.command_arguments.size() == 0) + { + for (const BinaryParagraph& binary_paragraph : binary_paragraphs) + { + const std::string displayname = binary_paragraph.displayname(); + System::println(displayname); + } + } + else + { + // At this point there is 1 argument + for (const BinaryParagraph& binary_paragraph : binary_paragraphs) + { + const std::string displayname = binary_paragraph.displayname(); + if (Strings::case_insensitive_ascii_find(displayname, args.command_arguments[0]) == displayname.end()) + { + continue; + } + + System::println(displayname); + } + } + + Checks::exit_success(VCPKG_LINE_INFO); + } +} diff --git a/toolsrc/src/vcpkg/commands.ci.cpp b/toolsrc/src/vcpkg/commands.ci.cpp new file mode 100644 index 000000000..1c98d1d83 --- /dev/null +++ b/toolsrc/src/vcpkg/commands.ci.cpp @@ -0,0 +1,62 @@ +#include "pch.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace vcpkg::Commands::CI +{ + using Build::BuildResult; + using Dependencies::InstallPlanAction; + using Dependencies::InstallPlanType; + + static std::vector load_all_package_specs(Files::Filesystem& fs, + const fs::path& ports_directory, + const Triplet& triplet) + { + auto ports = Paragraphs::load_all_ports(fs, ports_directory); + return Util::fmap(ports, [&](auto&& control_file) -> PackageSpec { + return PackageSpec::from_name_and_triplet(control_file->core_paragraph->name, triplet) + .value_or_exit(VCPKG_LINE_INFO); + }); + } + + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) + { + static const std::string EXAMPLE = Help::create_example_string("ci x64-windows"); + args.check_max_arg_count(1, EXAMPLE); + 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 specs = load_all_package_specs(paths.get_filesystem(), paths.ports, triplet); + + StatusParagraphs status_db = database_load_check(paths); + const auto& paths_port_file = Dependencies::PathsPortFile(paths); + std::vector install_plan = + Dependencies::create_install_plan(paths_port_file, specs, status_db); + Checks::check_exit(VCPKG_LINE_INFO, !install_plan.empty(), "Install plan cannot be empty"); + + const Build::BuildPackageOptions install_plan_options = {Build::UseHeadVersion::NO, Build::AllowDownloads::YES}; + + const std::vector action_plan = + Util::fmap(install_plan, [](InstallPlanAction& install_action) { + return Dependencies::AnyAction(std::move(install_action)); + }); + + Install::perform_and_exit_ex( + action_plan, install_plan_options, Install::KeepGoing::YES, Install::PrintSummary::YES, paths, status_db); + + Checks::exit_success(VCPKG_LINE_INFO); + } +} diff --git a/toolsrc/src/vcpkg/commands.contact.cpp b/toolsrc/src/vcpkg/commands.contact.cpp new file mode 100644 index 000000000..421b8a230 --- /dev/null +++ b/toolsrc/src/vcpkg/commands.contact.cpp @@ -0,0 +1,22 @@ +#include "pch.h" + +#include +#include + +namespace vcpkg::Commands::Contact +{ + const std::string& email() + { + static const std::string S_EMAIL = R"(vcpkg@microsoft.com)"; + return S_EMAIL; + } + + void perform_and_exit(const VcpkgCmdArguments& args) + { + args.check_exact_arg_count(0); + args.check_and_get_optional_command_arguments({}); + + System::println("Send an email to %s with any feedback.", email()); + Checks::exit_success(VCPKG_LINE_INFO); + } +} diff --git a/toolsrc/src/vcpkg/commands.cpp b/toolsrc/src/vcpkg/commands.cpp new file mode 100644 index 000000000..9d969ea28 --- /dev/null +++ b/toolsrc/src/vcpkg/commands.cpp @@ -0,0 +1,56 @@ +#include "pch.h" + +#include +#include +#include +#include +#include +#include +#include + +namespace vcpkg::Commands +{ + Span> get_available_commands_type_a() + { + static std::vector> t = { + {"install", &Install::perform_and_exit}, + {"ci", &CI::perform_and_exit}, + {"remove", &Remove::perform_and_exit}, + {"build", &Build::Command::perform_and_exit}, + {"env", &Env::perform_and_exit}, + {"build-external", &BuildExternal::perform_and_exit}, + {"export", &Export::perform_and_exit}, + }; + return t; + } + + Span> get_available_commands_type_b() + { + static std::vector> t = { + {"/?", &Help::perform_and_exit}, + {"help", &Help::perform_and_exit}, + {"search", &Search::perform_and_exit}, + {"list", &List::perform_and_exit}, + {"integrate", &Integrate::perform_and_exit}, + {"owns", &Owns::perform_and_exit}, + {"update", &Update::perform_and_exit}, + {"depend-info", &DependInfo::perform_and_exit}, + {"edit", &Edit::perform_and_exit}, + {"create", &Create::perform_and_exit}, + {"import", &Import::perform_and_exit}, + {"cache", &Cache::perform_and_exit}, + {"portsdiff", &PortsDiff::perform_and_exit}, + {"autocomplete", &Autocomplete::perform_and_exit}}; + return t; + } + + Span> get_available_commands_type_c() + { + static std::vector> t = { + {"version", &Version::perform_and_exit}, + {"contact", &Contact::perform_and_exit}, + {"hash", &Hash::perform_and_exit}, + }; + return t; + } +} diff --git a/toolsrc/src/vcpkg/commands.create.cpp b/toolsrc/src/vcpkg/commands.create.cpp new file mode 100644 index 000000000..d923cf555 --- /dev/null +++ b/toolsrc/src/vcpkg/commands.create.cpp @@ -0,0 +1,39 @@ +#include "pch.h" + +#include +#include +#include +#include +#include + +namespace vcpkg::Commands::Create +{ + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) + { + static const std::string EXAMPLE = Help::create_example_string( + R"###(create zlib2 http://zlib.net/zlib1211.zip "zlib1211-2.zip")###"); + args.check_max_arg_count(3, EXAMPLE); + args.check_min_arg_count(2, EXAMPLE); + args.check_and_get_optional_command_arguments({}); + const std::string port_name = args.command_arguments.at(0); + const std::string url = args.command_arguments.at(1); + + const fs::path& cmake_exe = paths.get_cmake_exe(); + + std::vector cmake_args{{L"CMD", L"CREATE"}, {L"PORT", port_name}, {L"URL", url}}; + + if (args.command_arguments.size() >= 3) + { + const std::string& zip_file_name = args.command_arguments.at(2); + Checks::check_exit(VCPKG_LINE_INFO, + !Files::has_invalid_chars_for_filesystem(zip_file_name), + R"(Filename cannot contain invalid chars %s, but was %s)", + Files::FILESYSTEM_INVALID_CHARACTERS, + zip_file_name); + cmake_args.push_back({L"FILENAME", zip_file_name}); + } + + const std::wstring cmd_launch_cmake = make_cmake_cmd(cmake_exe, paths.ports_cmake, cmake_args); + Checks::exit_with_code(VCPKG_LINE_INFO, System::cmd_execute_clean(cmd_launch_cmake)); + } +} diff --git a/toolsrc/src/vcpkg/commands.dependinfo.cpp b/toolsrc/src/vcpkg/commands.dependinfo.cpp new file mode 100644 index 000000000..89c7e0c7f --- /dev/null +++ b/toolsrc/src/vcpkg/commands.dependinfo.cpp @@ -0,0 +1,56 @@ +#include "pch.h" + +#include +#include +#include +#include +#include +#include + +namespace vcpkg::Commands::DependInfo +{ + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) + { + static const std::string EXAMPLE = Help::create_example_string(R"###(depend-info [pat])###"); + args.check_max_arg_count(1, EXAMPLE); + args.check_and_get_optional_command_arguments({}); + + std::vector> source_control_files = + Paragraphs::load_all_ports(paths.get_filesystem(), paths.ports); + + if (args.command_arguments.size() == 1) + { + const std::string filter = args.command_arguments.at(0); + + Util::erase_remove_if(source_control_files, + [&](const std::unique_ptr& source_control_file) { + + const SourceParagraph& source_paragraph = *source_control_file->core_paragraph; + + if (Strings::case_insensitive_ascii_contains(source_paragraph.name, filter)) + { + return false; + } + + for (const Dependency& dependency : source_paragraph.depends) + { + if (Strings::case_insensitive_ascii_contains(dependency.name(), filter)) + { + return false; + } + } + + return true; + }); + } + + for (auto&& source_control_file : source_control_files) + { + const SourceParagraph& source_paragraph = *source_control_file->core_paragraph; + const auto s = Strings::join(", ", source_paragraph.depends, [](const Dependency& d) { return d.name(); }); + System::println("%s: %s", source_paragraph.name, s); + } + + Checks::exit_success(VCPKG_LINE_INFO); + } +} diff --git a/toolsrc/src/vcpkg/commands.edit.cpp b/toolsrc/src/vcpkg/commands.edit.cpp new file mode 100644 index 000000000..9497bd76e --- /dev/null +++ b/toolsrc/src/vcpkg/commands.edit.cpp @@ -0,0 +1,87 @@ +#include "pch.h" + +#include +#include +#include +#include + +namespace vcpkg::Commands::Edit +{ + static std::vector find_from_registry() + { + static const std::array REGKEYS = { + LR"(SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{C26E74D1-022E-4238-8B9D-1E7564A36CC9}_is1)", + LR"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{1287CAD5-7C8D-410D-88B9-0D1EE4A83FF2}_is1)", + LR"(SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{F8A2A208-72B3-4D61-95FC-8A65D340689B}_is1)", + }; + + std::vector output; + for (auto&& keypath : REGKEYS) + { + const Optional code_installpath = + System::get_registry_string(HKEY_LOCAL_MACHINE, keypath, L"InstallLocation"); + if (const auto c = code_installpath.get()) + { + const fs::path install_path = fs::path(*c); + output.push_back(install_path / "Code - Insiders.exe"); + output.push_back(install_path / "Code.exe"); + } + } + return output; + } + + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) + { + static const std::string OPTION_BUILDTREES = "--buildtrees"; + + static const fs::path VS_CODE_INSIDERS = fs::path{"Microsoft VS Code Insiders"} / "Code - Insiders.exe"; + static const fs::path VS_CODE = fs::path{"Microsoft VS Code"} / "Code.exe"; + + auto& fs = paths.get_filesystem(); + + static const std::string EXAMPLE = Help::create_example_string("edit zlib"); + args.check_exact_arg_count(1, EXAMPLE); + const std::unordered_set options = + args.check_and_get_optional_command_arguments({OPTION_BUILDTREES}); + 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); + + std::vector candidate_paths; + const std::vector from_path = Files::find_from_PATH(L"EDITOR"); + candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); + candidate_paths.push_back(System::get_program_files_platform_bitness() / VS_CODE_INSIDERS); + candidate_paths.push_back(System::get_program_files_32_bit() / VS_CODE_INSIDERS); + candidate_paths.push_back(System::get_program_files_platform_bitness() / VS_CODE); + candidate_paths.push_back(System::get_program_files_32_bit() / VS_CODE); + + const std::vector from_registry = find_from_registry(); + candidate_paths.insert(candidate_paths.end(), from_registry.cbegin(), from_registry.cend()); + + auto it = Util::find_if(candidate_paths, [&](const fs::path& p) { return fs.exists(p); }); + if (it == candidate_paths.cend()) + { + System::println(System::Color::error, + "Error: Visual Studio Code was not found and the environment variable EDITOR is not set."); + System::println("The following paths were examined:"); + Files::print_paths(candidate_paths); + System::println("You can also set the environmental variable EDITOR to your editor of choice."); + Checks::exit_fail(VCPKG_LINE_INFO); + } + + const fs::path env_editor = *it; + if (options.find(OPTION_BUILDTREES) != options.cend()) + { + const auto buildtrees_current_dir = paths.buildtrees / port_name; + + const std::wstring cmd_line = + Strings::wformat(LR"("%s" "%s" -n)", env_editor, buildtrees_current_dir.native()); + Checks::exit_with_code(VCPKG_LINE_INFO, System::cmd_execute(cmd_line)); + } + + const std::wstring cmd_line = Strings::wformat( + LR"("%s" "%s" "%s" -n)", env_editor, portpath.native(), (portpath / "portfile.cmake").native()); + Checks::exit_with_code(VCPKG_LINE_INFO, System::cmd_execute(cmd_line)); + } +} diff --git a/toolsrc/src/vcpkg/commands.env.cpp b/toolsrc/src/vcpkg/commands.env.cpp new file mode 100644 index 000000000..089881588 --- /dev/null +++ b/toolsrc/src/vcpkg/commands.env.cpp @@ -0,0 +1,22 @@ +#include "pch.h" + +#include +#include +#include +#include + +namespace vcpkg::Commands::Env +{ + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) + { + static const std::string EXAMPLE = Help::create_example_string(R"(env --triplet x64-windows)"); + args.check_exact_arg_count(0, EXAMPLE); + args.check_and_get_optional_command_arguments({}); + + const auto pre_build_info = Build::PreBuildInfo::from_triplet_file(paths, default_triplet); + const Toolset& toolset = paths.get_toolset(pre_build_info.platform_toolset, pre_build_info.visual_studio_path); + System::cmd_execute_clean(Build::make_build_env_cmd(pre_build_info, toolset) + L" && cmd"); + + Checks::exit_success(VCPKG_LINE_INFO); + } +} diff --git a/toolsrc/src/vcpkg/commands.exportifw.cpp b/toolsrc/src/vcpkg/commands.exportifw.cpp new file mode 100644 index 000000000..35a3c97a7 --- /dev/null +++ b/toolsrc/src/vcpkg/commands.exportifw.cpp @@ -0,0 +1,482 @@ +#include "pch.h" + +#include +#include +#include +#include + +namespace vcpkg::Export::IFW +{ + using Dependencies::ExportPlanAction; + using Dependencies::ExportPlanType; + using Install::InstallDir; + + static std::string create_release_date() + { + const tm date_time = System::get_current_date_time(); + + // Format is: YYYY-mm-dd + // 10 characters + 1 null terminating character will be written for a total of 11 chars + char mbstr[11]; + const size_t bytes_written = std::strftime(mbstr, sizeof(mbstr), "%Y-%m-%d", &date_time); + Checks::check_exit(VCPKG_LINE_INFO, + bytes_written == 10, + "Expected 10 bytes to be written, but %u were written", + bytes_written); + const std::string date_time_as_string(mbstr); + return date_time_as_string; + } + + fs::path get_packages_dir_path(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths) + { + return ifw_options.maybe_packages_dir_path.has_value() + ? fs::path(ifw_options.maybe_packages_dir_path.value_or_exit(VCPKG_LINE_INFO)) + : paths.root / (export_id + "-ifw-packages"); + } + + fs::path get_repository_dir_path(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths) + { + return ifw_options.maybe_repository_dir_path.has_value() + ? fs::path(ifw_options.maybe_repository_dir_path.value_or_exit(VCPKG_LINE_INFO)) + : paths.root / (export_id + "-ifw-repository"); + } + + fs::path get_config_file_path(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths) + { + return ifw_options.maybe_config_file_path.has_value() + ? fs::path(ifw_options.maybe_config_file_path.value_or_exit(VCPKG_LINE_INFO)) + : paths.root / (export_id + "-ifw-configuration.xml"); + } + + fs::path get_installer_file_path(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths) + { + return ifw_options.maybe_installer_file_path.has_value() + ? fs::path(ifw_options.maybe_installer_file_path.value_or_exit(VCPKG_LINE_INFO)) + : paths.root / (export_id + "-ifw-installer.exe"); + } + + fs::path export_real_package(const fs::path& ifw_packages_dir_path, + const ExportPlanAction& action, + Files::Filesystem& fs) + { + std::error_code ec; + + const BinaryParagraph& binary_paragraph = + action.any_paragraph.binary_control_file.value_or_exit(VCPKG_LINE_INFO).core_paragraph; + + // Prepare meta dir + const fs::path package_xml_file_path = + ifw_packages_dir_path / + Strings::format("packages.%s.%s", action.spec.name(), action.spec.triplet().canonical_name()) / "meta" / + "package.xml"; + const fs::path package_xml_dir_path = package_xml_file_path.parent_path(); + fs.create_directories(package_xml_dir_path, ec); + Checks::check_exit(VCPKG_LINE_INFO, + !ec, + "Could not create directory for package file %s", + package_xml_file_path.generic_string()); + + auto deps = Strings::join( + ",", binary_paragraph.depends, [](const std::string& dep) { return "packages." + dep + ":"; }); + + if (!deps.empty()) deps = "\n " + deps + ""; + + fs.write_contents(package_xml_file_path, + Strings::format( + R"###( + + %s + %s + %s + packages.%s:,triplets.%s:%s + true + +)###", + action.spec.to_string(), + binary_paragraph.version, + create_release_date(), + action.spec.name(), + action.spec.triplet().canonical_name(), + deps)); + + // Return dir path for export package data + return ifw_packages_dir_path / + Strings::format("packages.%s.%s", action.spec.name(), action.spec.triplet().canonical_name()) / "data" / + "installed"; + } + + void export_unique_packages(const fs::path& raw_exported_dir_path, + std::map unique_packages, + Files::Filesystem& fs) + { + std::error_code ec; + + // packages + + fs::path package_xml_file_path = raw_exported_dir_path / "packages" / "meta" / "package.xml"; + fs::path package_xml_dir_path = package_xml_file_path.parent_path(); + fs.create_directories(package_xml_dir_path, ec); + Checks::check_exit(VCPKG_LINE_INFO, + !ec, + "Could not create directory for package file %s", + package_xml_file_path.generic_string()); + fs.write_contents(package_xml_file_path, + Strings::format( + R"###( + + Packages + 1.0.0 + %s + +)###", + create_release_date())); + + for (auto package = unique_packages.begin(); package != unique_packages.end(); ++package) + { + const ExportPlanAction& action = *(package->second); + const BinaryParagraph& binary_paragraph = + action.any_paragraph.binary_control_file.value_or_exit(VCPKG_LINE_INFO).core_paragraph; + + package_xml_file_path = + raw_exported_dir_path / Strings::format("packages.%s", package->first) / "meta" / "package.xml"; + package_xml_dir_path = package_xml_file_path.parent_path(); + fs.create_directories(package_xml_dir_path, ec); + Checks::check_exit(VCPKG_LINE_INFO, + !ec, + "Could not create directory for package file %s", + package_xml_file_path.generic_string()); + + fs.write_contents(package_xml_file_path, + Strings::format( + R"###( + + %s + %s + %s + %s + +)###", + action.spec.name(), + binary_paragraph.description, + binary_paragraph.version, + create_release_date())); + } + } + + void export_unique_triplets(const fs::path& raw_exported_dir_path, + std::set unique_triplets, + Files::Filesystem& fs) + { + std::error_code ec; + + // triplets + + fs::path package_xml_file_path = raw_exported_dir_path / "triplets" / "meta" / "package.xml"; + fs::path package_xml_dir_path = package_xml_file_path.parent_path(); + fs.create_directories(package_xml_dir_path, ec); + Checks::check_exit(VCPKG_LINE_INFO, + !ec, + "Could not create directory for package file %s", + package_xml_file_path.generic_string()); + fs.write_contents(package_xml_file_path, + Strings::format( + R"###( + + Triplets + 1.0.0 + %s + +)###", + create_release_date())); + + for (const std::string& triplet : unique_triplets) + { + package_xml_file_path = + raw_exported_dir_path / Strings::format("triplets.%s", triplet) / "meta" / "package.xml"; + package_xml_dir_path = package_xml_file_path.parent_path(); + fs.create_directories(package_xml_dir_path, ec); + Checks::check_exit(VCPKG_LINE_INFO, + !ec, + "Could not create directory for package file %s", + package_xml_file_path.generic_string()); + fs.write_contents(package_xml_file_path, + Strings::format( + R"###( + + %s + 1.0.0 + %s + +)###", + triplet, + create_release_date())); + } + } + + void export_integration(const fs::path& raw_exported_dir_path, Files::Filesystem& fs) + { + std::error_code ec; + + // integration + fs::path package_xml_file_path = raw_exported_dir_path / "integration" / "meta" / "package.xml"; + fs::path package_xml_dir_path = package_xml_file_path.parent_path(); + fs.create_directories(package_xml_dir_path, ec); + Checks::check_exit(VCPKG_LINE_INFO, + !ec, + "Could not create directory for package file %s", + package_xml_file_path.generic_string()); + + fs.write_contents(package_xml_file_path, + Strings::format( + R"###( + + Integration + 1.0.0 + %s + +)###", + create_release_date())); + } + + void export_config(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths) + { + std::error_code ec; + Files::Filesystem& fs = paths.get_filesystem(); + + const fs::path config_xml_file_path = get_config_file_path(export_id, ifw_options, paths); + + fs::path config_xml_dir_path = config_xml_file_path.parent_path(); + fs.create_directories(config_xml_dir_path, ec); + Checks::check_exit(VCPKG_LINE_INFO, + !ec, + "Could not create directory for configuration file %s", + config_xml_file_path.generic_string()); + + std::string formatted_repo_url; + std::string ifw_repo_url = ifw_options.maybe_repository_url.value_or(""); + if (!ifw_repo_url.empty()) + { + formatted_repo_url = Strings::format(R"###( + + + %s + + )###", + ifw_repo_url); + } + + fs.write_contents(config_xml_file_path, + Strings::format( + R"###( + + vcpkg + 1.0.0 + vcpkg + @RootDir@/src/vcpkg%s + +)###", + formatted_repo_url)); + } + + void export_maintenance_tool(const fs::path& ifw_packages_dir_path, const VcpkgPaths& paths) + { + System::println("Exporting maintenance tool... "); + + std::error_code ec; + Files::Filesystem& fs = paths.get_filesystem(); + + const fs::path& installerbase_exe = paths.get_ifw_installerbase_exe(); + fs::path tempmaintenancetool = ifw_packages_dir_path / "maintenance" / "data" / "tempmaintenancetool.exe"; + fs.create_directories(tempmaintenancetool.parent_path(), ec); + Checks::check_exit(VCPKG_LINE_INFO, + !ec, + "Could not create directory for package file %s", + tempmaintenancetool.generic_string()); + fs.copy_file(installerbase_exe, tempmaintenancetool, fs::copy_options::overwrite_existing, ec); + Checks::check_exit( + VCPKG_LINE_INFO, !ec, "Could not write package file %s", tempmaintenancetool.generic_string()); + + fs::path package_xml_file_path = ifw_packages_dir_path / "maintenance" / "meta" / "package.xml"; + fs::path package_xml_dir_path = package_xml_file_path.parent_path(); + fs.create_directories(package_xml_dir_path, ec); + Checks::check_exit(VCPKG_LINE_INFO, + !ec, + "Could not create directory for package file %s", + package_xml_file_path.generic_string()); + fs.write_contents(package_xml_file_path, + Strings::format( + R"###( + + Maintenance Tool + Maintenance Tool + 1.0.0 + %s + + true + true + true + +)###", + create_release_date())); + const fs::path script_source = paths.root / "scripts" / "ifw" / "maintenance.qs"; + const fs::path script_destination = ifw_packages_dir_path / "maintenance" / "meta" / "maintenance.qs"; + fs.copy_file(script_source, script_destination, fs::copy_options::overwrite_existing, ec); + Checks::check_exit( + VCPKG_LINE_INFO, !ec, "Could not write package file %s", script_destination.generic_string()); + + System::println("Exporting maintenance tool... done"); + } + + void do_repository(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths) + { + const fs::path& repogen_exe = paths.get_ifw_repogen_exe(); + const fs::path packages_dir = get_packages_dir_path(export_id, ifw_options, paths); + const fs::path repository_dir = get_repository_dir_path(export_id, ifw_options, paths); + + System::println("Generating repository %s...", repository_dir.generic_string()); + + std::error_code ec; + Files::Filesystem& fs = paths.get_filesystem(); + + fs.remove_all(repository_dir, ec); + Checks::check_exit( + VCPKG_LINE_INFO, !ec, "Could not remove outdated repository directory %s", repository_dir.generic_string()); + + const std::wstring cmd_line = Strings::wformat(LR"("%s" --packages "%s" "%s" > nul)", + repogen_exe.native(), + packages_dir.native(), + repository_dir.native()); + + const int exit_code = System::cmd_execute_clean(cmd_line); + Checks::check_exit(VCPKG_LINE_INFO, exit_code == 0, "Error: IFW repository generating failed"); + + System::println(System::Color::success, "Generating repository %s... done.", repository_dir.generic_string()); + } + + void do_installer(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths) + { + const fs::path& binarycreator_exe = paths.get_ifw_binarycreator_exe(); + const fs::path config_file = get_config_file_path(export_id, ifw_options, paths); + const fs::path packages_dir = get_packages_dir_path(export_id, ifw_options, paths); + const fs::path repository_dir = get_repository_dir_path(export_id, ifw_options, paths); + const fs::path installer_file = get_installer_file_path(export_id, ifw_options, paths); + + System::println("Generating installer %s...", installer_file.generic_string()); + + std::wstring cmd_line; + + std::string ifw_repo_url = ifw_options.maybe_repository_url.value_or(""); + if (!ifw_repo_url.empty()) + { + cmd_line = Strings::wformat(LR"("%s" --online-only --config "%s" --repository "%s" "%s" > nul)", + binarycreator_exe.native(), + config_file.native(), + repository_dir.native(), + installer_file.native()); + } + else + { + cmd_line = Strings::wformat(LR"("%s" --config "%s" --packages "%s" "%s" > nul)", + binarycreator_exe.native(), + config_file.native(), + packages_dir.native(), + installer_file.native()); + } + + const int exit_code = System::cmd_execute_clean(cmd_line); + Checks::check_exit(VCPKG_LINE_INFO, exit_code == 0, "Error: IFW installer generating failed"); + + System::println(System::Color::success, "Generating installer %s... done.", installer_file.generic_string()); + } + + void do_export(const std::vector& export_plan, + const std::string& export_id, + const Options& ifw_options, + const VcpkgPaths& paths) + { + std::error_code ec; + Files::Filesystem& fs = paths.get_filesystem(); + + // Prepare packages directory + const fs::path ifw_packages_dir_path = get_packages_dir_path(export_id, ifw_options, paths); + + fs.remove_all(ifw_packages_dir_path, ec); + Checks::check_exit(VCPKG_LINE_INFO, + !ec, + "Could not remove outdated packages directory %s", + ifw_packages_dir_path.generic_string()); + + fs.create_directory(ifw_packages_dir_path, ec); + Checks::check_exit( + VCPKG_LINE_INFO, !ec, "Could not create packages directory %s", ifw_packages_dir_path.generic_string()); + + // Export maintenance tool + export_maintenance_tool(ifw_packages_dir_path, paths); + + System::println("Exporting packages %s... ", ifw_packages_dir_path.generic_string()); + + // execute the plan + std::map unique_packages; + std::set unique_triplets; + for (const ExportPlanAction& action : export_plan) + { + if (action.plan_type != ExportPlanType::ALREADY_BUILT) + { + Checks::unreachable(VCPKG_LINE_INFO); + } + + const std::string display_name = action.spec.to_string(); + System::println("Exporting package %s... ", display_name); + + const BinaryParagraph& binary_paragraph = + action.any_paragraph.binary_control_file.value_or_exit(VCPKG_LINE_INFO).core_paragraph; + + unique_packages[action.spec.name()] = &action; + unique_triplets.insert(action.spec.triplet().canonical_name()); + + // Export real package and return data dir for installation + fs::path ifw_package_dir_path = export_real_package(ifw_packages_dir_path, action, fs); + + // Copy package data + const InstallDir dirs = InstallDir::from_destination_root(ifw_package_dir_path, + action.spec.triplet().to_string(), + 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); + System::println("Exporting package %s... done", display_name); + } + + System::println("Exporting packages %s... done", ifw_packages_dir_path.generic_string()); + + const fs::path config_file = get_config_file_path(export_id, ifw_options, paths); + + System::println("Generating configuration %s...", config_file.generic_string()); + + // Unique packages + export_unique_packages(ifw_packages_dir_path, unique_packages, fs); + + // Unique triplets + export_unique_triplets(ifw_packages_dir_path, unique_triplets, fs); + + // Copy files needed for integration + export_integration_files(ifw_packages_dir_path / "integration" / "data", paths); + // Integration + export_integration(ifw_packages_dir_path, fs); + + // Configuration + export_config(export_id, ifw_options, paths); + + System::println("Generating configuration %s... done.", config_file.generic_string()); + + // Do repository (optional) + std::string ifw_repo_url = ifw_options.maybe_repository_url.value_or(""); + if (!ifw_repo_url.empty()) + { + do_repository(export_id, ifw_options, paths); + } + + // Do installer + do_installer(export_id, ifw_options, paths); + } +} diff --git a/toolsrc/src/vcpkg/commands.hash.cpp b/toolsrc/src/vcpkg/commands.hash.cpp new file mode 100644 index 000000000..394a02e23 --- /dev/null +++ b/toolsrc/src/vcpkg/commands.hash.cpp @@ -0,0 +1,55 @@ +#include "pch.h" + +#include +#include +#include +#include + +namespace vcpkg::Commands::Hash +{ + static void do_file_hash(fs::path const& path, std::wstring const& hash_type) + { + const auto cmd_line = Strings::wformat(LR"(CertUtil.exe -hashfile "%s" %s)", path.c_str(), hash_type); + const auto ec_data = System::cmd_execute_and_capture_output(cmd_line); + Checks::check_exit( + VCPKG_LINE_INFO, ec_data.exit_code == 0, "Running command:\n %s\n failed", Strings::to_utf8(cmd_line)); + + std::string const& output = ec_data.output; + + const auto start = output.find_first_of("\r\n"); + Checks::check_exit(VCPKG_LINE_INFO, + start != std::string::npos, + "Unexpected output format from command: %s", + Strings::to_utf8(cmd_line)); + + const auto end = output.find_first_of("\r\n", start + 1); + Checks::check_exit(VCPKG_LINE_INFO, + end != std::string::npos, + "Unexpected output format from command: %s", + Strings::to_utf8(cmd_line)); + + auto hash = output.substr(start, end - start); + Util::erase_remove_if(hash, isspace); + System::println(hash); + } + + void perform_and_exit(const VcpkgCmdArguments& args) + { + static const std::string EXAMPLE = Strings::format("The argument should be a file path\n%s", + Help::create_example_string("hash boost_1_62_0.tar.bz2")); + args.check_min_arg_count(1, EXAMPLE); + args.check_max_arg_count(2, EXAMPLE); + args.check_and_get_optional_command_arguments({}); + + if (args.command_arguments.size() == 1) + { + do_file_hash(args.command_arguments[0], L"SHA512"); + } + if (args.command_arguments.size() == 2) + { + do_file_hash(args.command_arguments[0], Strings::to_utf16(args.command_arguments[1])); + } + + Checks::exit_success(VCPKG_LINE_INFO); + } +} diff --git a/toolsrc/src/vcpkg/commands.import.cpp b/toolsrc/src/vcpkg/commands.import.cpp new file mode 100644 index 000000000..119aee022 --- /dev/null +++ b/toolsrc/src/vcpkg/commands.import.cpp @@ -0,0 +1,120 @@ +#include "pch.h" + +#include +#include +#include +#include +#include + +namespace vcpkg::Commands::Import +{ + struct Binaries + { + std::vector dlls; + std::vector libs; + }; + + 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()); + } + + static Binaries find_binaries_in_dir(const Files::Filesystem& fs, const fs::path& path) + { + auto files = fs.get_files_recursive(path); + + check_is_directory(VCPKG_LINE_INFO, fs, path); + + Binaries binaries; + for (auto&& file : files) + { + if (fs.is_directory(file)) continue; + const 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(Files::Filesystem& fs, + const std::vector& files, + const fs::path& destination_folder) + { + std::error_code ec; + fs.create_directory(destination_folder, ec); + + for (auto const& src_path : files) + { + const fs::path dest_path = destination_folder / src_path.filename(); + fs.copy(src_path, dest_path, fs::copy_options::overwrite_existing); + } + } + + 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, fs, include_directory); + check_is_directory(VCPKG_LINE_INFO, fs, project_directory); + check_is_directory(VCPKG_LINE_INFO, fs, destination_path); + const Binaries debug_binaries = find_binaries_in_dir(fs, project_directory / "Debug"); + const Binaries release_binaries = find_binaries_in_dir(fs, project_directory / "Release"); + + const fs::path destination_include_directory = destination_path / "include"; + fs.copy(include_directory, + destination_include_directory, + fs::copy_options::recursive | fs::copy_options::overwrite_existing); + + copy_files_into_directory(fs, release_binaries.dlls, destination_path / "bin"); + copy_files_into_directory(fs, release_binaries.libs, destination_path / "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(); + const fs::path library_destination_path = paths.package_dir(control_file_data.spec); + 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); + + const fs::path control_file_path = library_destination_path / "CONTROL"; + fs.write_contents(control_file_path, Strings::serialize(control_file_data)); + } + + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) + { + static const std::string EXAMPLE = Help::create_example_string( + R"(import C:\path\to\CONTROLfile C:\path\to\includedir C:\path\to\projectdir)"); + args.check_exact_arg_count(3, EXAMPLE); + args.check_and_get_optional_command_arguments({}); + + const fs::path control_file_path(args.command_arguments[0]); + const fs::path include_directory(args.command_arguments[1]); + const fs::path project_directory(args.command_arguments[2]); + + const Expected> 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; + spgh.package = BinaryParagraph(*pghs.get()); + auto& control_file_data = spgh.package; + + do_import(paths, include_directory, project_directory, control_file_data); + Checks::exit_success(VCPKG_LINE_INFO); + } +} diff --git a/toolsrc/src/vcpkg/commands.integrate.cpp b/toolsrc/src/vcpkg/commands.integrate.cpp new file mode 100644 index 000000000..7f6639222 --- /dev/null +++ b/toolsrc/src/vcpkg/commands.integrate.cpp @@ -0,0 +1,342 @@ +#include "pch.h" + +#include +#include +#include +#include +#include + +namespace vcpkg::Commands::Integrate +{ + static const std::array OLD_SYSTEM_TARGET_FILES = { + System::get_program_files_32_bit() / "MSBuild/14.0/Microsoft.Common.Targets/ImportBefore/vcpkg.nuget.targets", + System::get_program_files_32_bit() / "MSBuild/14.0/Microsoft.Common.Targets/ImportBefore/vcpkg.system.targets"}; + static const fs::path SYSTEM_WIDE_TARGETS_FILE = + System::get_program_files_32_bit() / "MSBuild/Microsoft.Cpp/v4.0/V140/ImportBefore/Default/vcpkg.system.props"; + + static std::string create_appdata_targets_shortcut(const std::string& target_path) noexcept + { + return Strings::format(R"###( + + + +)###", + target_path, + target_path); + } + + static std::string create_system_targets_shortcut() noexcept + { + return R"###( + + + + $(LOCALAPPDATA)\vcpkg\vcpkg.user + + + +)###"; + } + + static std::string create_nuget_targets_file_contents(const fs::path& msbuild_vcpkg_targets_file) noexcept + { + const std::string as_string = msbuild_vcpkg_targets_file.string(); + + return Strings::format(R"###( + + + + + + +)###", + as_string, + as_string); + } + + static std::string create_nuget_props_file_contents() noexcept + { + return R"###( + + + true + + +)###"; + } + + static std::string get_nuget_id(const fs::path& vcpkg_root_dir) + { + std::string dir_id = vcpkg_root_dir.generic_string(); + std::replace(dir_id.begin(), dir_id.end(), '/', '.'); + dir_id.erase(1, 1); // Erasing the ":" + + // NuGet id cannot have invalid characters. We will only use alphanumeric and dot. + Util::erase_remove_if(dir_id, [](char c) { return !isalnum(c) && (c != '.'); }); + + const std::string nuget_id = "vcpkg." + dir_id; + return nuget_id; + } + + static std::string create_nuspec_file_contents(const fs::path& vcpkg_root_dir, + const std::string& nuget_id, + const std::string& nupkg_version) + { + static constexpr auto CONTENT_TEMPLATE = R"( + + + @NUGET_ID@ + @VERSION@ + vcpkg + + This package imports all libraries currently installed in @VCPKG_DIR@. This package does not contain any libraries and instead refers to the folder directly (like a symlink). + + + + + + + +)"; + + std::string content = std::regex_replace(CONTENT_TEMPLATE, std::regex("@NUGET_ID@"), nuget_id); + content = std::regex_replace(content, std::regex("@VCPKG_DIR@"), vcpkg_root_dir.string()); + content = std::regex_replace(content, std::regex("@VERSION@"), nupkg_version); + return content; + } + + enum class ElevationPromptChoice + { + YES, + NO + }; + + static ElevationPromptChoice elevated_cmd_execute(const std::string& param) + { + SHELLEXECUTEINFOW sh_ex_info = {0}; + sh_ex_info.cbSize = sizeof(sh_ex_info); + sh_ex_info.fMask = SEE_MASK_NOCLOSEPROCESS; + sh_ex_info.hwnd = nullptr; + sh_ex_info.lpVerb = L"runas"; + sh_ex_info.lpFile = L"cmd"; // Application to start + + auto wparam = Strings::to_utf16(param); + sh_ex_info.lpParameters = wparam.c_str(); // Additional parameters + sh_ex_info.lpDirectory = nullptr; + sh_ex_info.nShow = SW_HIDE; + sh_ex_info.hInstApp = nullptr; + + if (!ShellExecuteExW(&sh_ex_info)) + { + return ElevationPromptChoice::NO; + } + if (sh_ex_info.hProcess == nullptr) + { + return ElevationPromptChoice::NO; + } + WaitForSingleObject(sh_ex_info.hProcess, INFINITE); + CloseHandle(sh_ex_info.hProcess); + return ElevationPromptChoice::YES; + } + + static fs::path get_appdata_targets_path() + { + static const fs::path LOCAL_APP_DATA = + fs::path(System::get_environment_variable(L"LOCALAPPDATA").value_or_exit(VCPKG_LINE_INFO)); + return LOCAL_APP_DATA / "vcpkg" / "vcpkg.user.targets"; + } + + 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)) + { + const std::string param = + Strings::format(R"(/c DEL "%s" /Q > nul)", old_system_wide_targets_file.string()); + const ElevationPromptChoice user_choice = elevated_cmd_execute(param); + switch (user_choice) + { + case ElevationPromptChoice::YES: break; + case ElevationPromptChoice::NO: + System::println(System::Color::warning, "Warning: Previous integration file was not removed"); + Checks::exit_fail(VCPKG_LINE_INFO); + default: Checks::unreachable(VCPKG_LINE_INFO); + } + } + } + + std::error_code ec; + const fs::path tmp_dir = paths.buildsystems / "tmp"; + fs.create_directory(paths.buildsystems, ec); + fs.create_directory(tmp_dir, ec); + + bool should_install_system = true; + const Expected system_wide_file_contents = fs.read_contents(SYSTEM_WIDE_TARGETS_FILE); + static const std::regex RE(R"###()###"); + if (const auto contents_data = system_wide_file_contents.get()) + { + std::match_results match; + const auto found = std::regex_search(*contents_data, match, RE); + if (found) + { + const int ver = atoi(match[1].str().c_str()); + if (ver >= 1) should_install_system = false; + } + } + + if (should_install_system) + { + const fs::path sys_src_path = tmp_dir / "vcpkg.system.targets"; + 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()); + const ElevationPromptChoice user_choice = elevated_cmd_execute(param); + switch (user_choice) + { + case ElevationPromptChoice::YES: break; + case ElevationPromptChoice::NO: + System::println(System::Color::warning, "Warning: integration was not applied"); + Checks::exit_fail(VCPKG_LINE_INFO); + default: 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()); + } + + const fs::path appdata_src_path = tmp_dir / "vcpkg.user.targets"; + fs.write_contents(appdata_src_path, + create_appdata_targets_shortcut(paths.buildsystems_msbuild_targets.string())); + auto appdata_dst_path = get_appdata_targets_path(); + + const 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); + } + System::println(System::Color::success, "Applied user-wide integration for this vcpkg root."); + const fs::path cmake_toolchain = paths.buildsystems / "vcpkg.cmake"; + System::println("\n" + "All MSBuild C++ projects can now #include any installed libraries.\n" + "Linking will be handled automatically.\n" + "Installing new libraries will make them instantly available.\n" + "\n" + "CMake projects should use -DCMAKE_TOOLCHAIN_FILE=%s", + cmake_toolchain.generic_string()); + + Checks::exit_success(VCPKG_LINE_INFO); + } + + static void integrate_remove(Files::Filesystem& fs) + { + const fs::path path = get_appdata_targets_path(); + + std::error_code ec; + const bool was_deleted = fs.remove(path, ec); + + Checks::check_exit(VCPKG_LINE_INFO, !ec, "Error: Unable to remove user-wide integration: %d", ec.message()); + + if (was_deleted) + { + System::println(System::Color::success, "User-wide integration was removed"); + } + else + { + System::println(System::Color::success, "User-wide integration is not installed"); + } + + Checks::exit_success(VCPKG_LINE_INFO); + } + + 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"; + 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"; + const fs::path nuspec_file_path = tmp_dir / "vcpkg.nuget.nuspec"; + const std::string nuget_id = get_nuget_id(paths.root); + const std::string nupkg_version = "1.0.0"; + + fs.write_contents(targets_file_path, create_nuget_targets_file_contents(paths.buildsystems_msbuild_targets)); + fs.write_contents(props_file_path, create_nuget_props_file_contents()); + fs.write_contents(nuspec_file_path, create_nuspec_file_contents(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()); + + 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"); + System::println(System::Color::success, "Created nupkg: %s", nuget_package.string()); + + auto source_path = buildsystems_dir.u8string(); + source_path = std::regex_replace(source_path, std::regex("`"), "``"); + + System::println(R"( +With a project open, go to Tools->NuGet Package Manager->Package Manager Console and paste: + Install-Package %s -Source "%s" +)", + nuget_id, + source_path); + + Checks::exit_success(VCPKG_LINE_INFO); + } + + const char* const INTEGRATE_COMMAND_HELPSTRING = + " vcpkg integrate install Make installed packages available user-wide. Requires admin privileges on " + "first use\n" + " vcpkg integrate remove Remove user-wide integration\n" + " vcpkg integrate project Generate a referencing nuget package for individual VS project use\n"; + + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) + { + static const std::string EXAMPLE = Strings::format("Commands:\n" + "%s", + INTEGRATE_COMMAND_HELPSTRING); + args.check_exact_arg_count(1, EXAMPLE); + args.check_and_get_optional_command_arguments({}); + + if (args.command_arguments[0] == "install") + { + return integrate_install(paths); + } + if (args.command_arguments[0] == "remove") + { + return integrate_remove(paths.get_filesystem()); + } + if (args.command_arguments[0] == "project") + { + return integrate_project(paths); + } + + Checks::exit_with_message(VCPKG_LINE_INFO, "Unknown parameter %s for integrate", args.command_arguments[0]); + } +} diff --git a/toolsrc/src/vcpkg/commands.list.cpp b/toolsrc/src/vcpkg/commands.list.cpp new file mode 100644 index 000000000..d0e8e00b4 --- /dev/null +++ b/toolsrc/src/vcpkg/commands.list.cpp @@ -0,0 +1,75 @@ +#include "pch.h" + +#include +#include +#include +#include + +namespace vcpkg::Commands::List +{ + static const std::string OPTION_FULLDESC = "--x-full-desc"; // TODO: This should find a better home, eventually + + static void do_print(const StatusParagraph& pgh, bool full_desc) + { + if (full_desc) + { + System::println("%-30s %-16s %s", pgh.package.displayname(), pgh.package.version, pgh.package.description); + } + else + { + System::println("%-30s %-16s %s", + vcpkg::shorten_text(pgh.package.displayname(), 30), + vcpkg::shorten_text(pgh.package.version, 16), + vcpkg::shorten_text(pgh.package.description, 71)); + } + } + + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) + { + static const std::string EXAMPLE = Strings::format( + "The argument should be a substring to search for, or no argument to display all installed libraries.\n%s", + Help::create_example_string("list png")); + args.check_max_arg_count(1, EXAMPLE); + const std::unordered_set options = + args.check_and_get_optional_command_arguments({OPTION_FULLDESC}); + + const StatusParagraphs status_paragraphs = database_load_check(paths); + std::vector installed_packages = get_installed_ports(status_paragraphs); + + if (installed_packages.empty()) + { + System::println("No packages are installed. Did you mean `search`?"); + Checks::exit_success(VCPKG_LINE_INFO); + } + + std::sort(installed_packages.begin(), + installed_packages.end(), + [](const StatusParagraph* lhs, const StatusParagraph* rhs) -> bool { + return lhs->package.displayname() < rhs->package.displayname(); + }); + + if (args.command_arguments.size() == 0) + { + for (const StatusParagraph* status_paragraph : installed_packages) + { + do_print(*status_paragraph, options.find(OPTION_FULLDESC) != options.cend()); + } + } + else + { + // At this point there is 1 argument + for (const StatusParagraph* status_paragraph : installed_packages) + { + const std::string displayname = status_paragraph->package.displayname(); + if (Strings::case_insensitive_ascii_find(displayname, args.command_arguments[0]) == displayname.end()) + { + continue; + } + + do_print(*status_paragraph, options.find(OPTION_FULLDESC) != options.cend()); + } + } + + Checks::exit_success(VCPKG_LINE_INFO); + } +} diff --git a/toolsrc/src/vcpkg/commands.owns.cpp b/toolsrc/src/vcpkg/commands.owns.cpp new file mode 100644 index 000000000..69079e829 --- /dev/null +++ b/toolsrc/src/vcpkg/commands.owns.cpp @@ -0,0 +1,38 @@ +#include "pch.h" + +#include +#include +#include +#include + +namespace vcpkg::Commands::Owns +{ + static void search_file(const VcpkgPaths& paths, const std::string& file_substr, const StatusParagraphs& status_db) + { + const std::vector installed_files = get_installed_files(paths, status_db); + for (const StatusParagraphAndAssociatedFiles& pgh_and_file : installed_files) + { + const StatusParagraph& pgh = pgh_and_file.pgh; + + for (const std::string& file : pgh_and_file.files) + { + if (file.find(file_substr) != std::string::npos) + { + System::println("%s: %s", pgh.package.displayname(), file); + } + } + } + } + + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) + { + static const std::string EXAMPLE = Strings::format("The argument should be a pattern to search for. %s", + Help::create_example_string("owns zlib.dll")); + args.check_exact_arg_count(1, EXAMPLE); + args.check_and_get_optional_command_arguments({}); + + StatusParagraphs status_db = database_load_check(paths); + search_file(paths, args.command_arguments[0], status_db); + Checks::exit_success(VCPKG_LINE_INFO); + } +} diff --git a/toolsrc/src/vcpkg/commands.portsdiff.cpp b/toolsrc/src/vcpkg/commands.portsdiff.cpp new file mode 100644 index 000000000..b70ad2b80 --- /dev/null +++ b/toolsrc/src/vcpkg/commands.portsdiff.cpp @@ -0,0 +1,182 @@ +#include "pch.h" + +#include +#include +#include + +#include +#include +#include + +namespace vcpkg::Commands::PortsDiff +{ + struct UpdatedPort + { + static bool compare_by_name(const UpdatedPort& left, const UpdatedPort& right) + { + return left.port < right.port; + } + + std::string port; + VersionDiff version_diff; + }; + + template + struct SetElementPresence + { + static SetElementPresence create(std::vector left, std::vector right) + { + // TODO: This can be done with one pass instead of three passes + SetElementPresence output; + std::set_difference( + left.cbegin(), left.cend(), right.cbegin(), right.cend(), std::back_inserter(output.only_left)); + std::set_intersection( + left.cbegin(), left.cend(), right.cbegin(), right.cend(), std::back_inserter(output.both)); + std::set_difference( + right.cbegin(), right.cend(), left.cbegin(), left.cend(), std::back_inserter(output.only_right)); + + return output; + } + + std::vector only_left; + std::vector both; + std::vector only_right; + }; + + static std::vector find_updated_ports( + const std::vector& ports, + const std::map& previous_names_and_versions, + const std::map& current_names_and_versions) + { + std::vector output; + for (const std::string& name : ports) + { + const VersionT& previous_version = previous_names_and_versions.at(name); + const VersionT& current_version = current_names_and_versions.at(name); + if (previous_version == current_version) + { + continue; + } + + output.push_back({name, VersionDiff(previous_version, current_version)}); + } + + return output; + } + + static void do_print_name_and_version(const std::vector& ports_to_print, + const std::map& names_and_versions) + { + for (const std::string& name : ports_to_print) + { + const VersionT& version = names_and_versions.at(name); + System::println(" - %-14s %-16s", name, version); + } + } + + static std::map 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, 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)", + git_exe.native(), + dot_git_dir.native(), + temp_checkout_path.native(), + git_commit_id, + checkout_this_dir, + L".vcpkg-root", + git_exe.native()); + System::cmd_execute_clean(cmd); + const std::map names_and_versions = Paragraphs::load_all_port_names_and_versions( + paths.get_filesystem(), temp_checkout_path / ports_dir_name_as_string); + fs.remove_all(temp_checkout_path, ec); + return names_and_versions; + } + + static void check_commit_exists(const fs::path& git_exe, const std::wstring& git_commit_id) + { + static const std::string VALID_COMMIT_OUTPUT = "commit\n"; + + const std::wstring cmd = Strings::wformat(LR"("%s" cat-file -t %s)", git_exe.native(), git_commit_id); + const System::ExitCodeAndOutput output = System::cmd_execute_and_capture_output(cmd); + Checks::check_exit(VCPKG_LINE_INFO, + output.output == VALID_COMMIT_OUTPUT, + "Invalid commit id %s", + Strings::to_utf8(git_commit_id)); + } + + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) + { + static const std::string EXAMPLE = Strings::format("The argument should be a branch/tag/hash to checkout.\n%s", + Help::create_example_string("portsdiff mybranchname")); + args.check_min_arg_count(1, EXAMPLE); + args.check_max_arg_count(2, EXAMPLE); + args.check_and_get_optional_command_arguments({}); + + const fs::path& git_exe = paths.get_git_exe(); + + const std::wstring git_commit_id_for_previous_snapshot = Strings::to_utf16(args.command_arguments.at(0)); + const std::wstring git_commit_id_for_current_snapshot = + args.command_arguments.size() < 2 ? L"HEAD" : Strings::to_utf16(args.command_arguments.at(1)); + + check_commit_exists(git_exe, git_commit_id_for_current_snapshot); + check_commit_exists(git_exe, git_commit_id_for_previous_snapshot); + + const std::map current_names_and_versions = + read_ports_from_commit(paths, git_commit_id_for_current_snapshot); + const std::map previous_names_and_versions = + read_ports_from_commit(paths, git_commit_id_for_previous_snapshot); + + // Already sorted, so set_difference can work on std::vector too + const std::vector current_ports = Util::extract_keys(current_names_and_versions); + const std::vector previous_ports = Util::extract_keys(previous_names_and_versions); + + const SetElementPresence setp = + SetElementPresence::create(current_ports, previous_ports); + + const std::vector& added_ports = setp.only_left; + if (!added_ports.empty()) + { + System::println("\nThe following %d ports were added:", added_ports.size()); + do_print_name_and_version(added_ports, current_names_and_versions); + } + + const std::vector& removed_ports = setp.only_right; + if (!removed_ports.empty()) + { + System::println("\nThe following %d ports were removed:", removed_ports.size()); + do_print_name_and_version(removed_ports, previous_names_and_versions); + } + + const std::vector& common_ports = setp.both; + const std::vector updated_ports = + find_updated_ports(common_ports, previous_names_and_versions, current_names_and_versions); + + if (!updated_ports.empty()) + { + System::println("\nThe following %d ports were updated:", updated_ports.size()); + for (const UpdatedPort& p : updated_ports) + { + System::println(" - %-14s %-16s", p.port, p.version_diff.to_string()); + } + } + + if (added_ports.empty() && removed_ports.empty() && updated_ports.empty()) + { + System::println("There were no changes in the ports between the two commits."); + } + + Checks::exit_success(VCPKG_LINE_INFO); + } +} diff --git a/toolsrc/src/vcpkg/commands.search.cpp b/toolsrc/src/vcpkg/commands.search.cpp new file mode 100644 index 000000000..3ba8707de --- /dev/null +++ b/toolsrc/src/vcpkg/commands.search.cpp @@ -0,0 +1,146 @@ +#include "pch.h" + +#include +#include +#include +#include +#include +#include +#include + +namespace vcpkg::Commands::Search +{ + static const std::string OPTION_GRAPH = "--graph"; // TODO: This should find a better home, eventually + static const std::string OPTION_FULLDESC = "--x-full-desc"; // TODO: This should find a better home, eventually + + static std::string replace_dashes_with_underscore(const std::string& input) + { + std::string output = input; + std::replace(output.begin(), output.end(), '-', '_'); + return output; + } + + static std::string create_graph_as_string( + const std::vector>& source_control_files) + { + int empty_node_count = 0; + + std::string s; + s.append("digraph G{ rankdir=LR; edge [minlen=3]; overlap=false;"); + + for (const auto& source_control_file : source_control_files) + { + const SourceParagraph& source_paragraph = *source_control_file->core_paragraph; + if (source_paragraph.depends.empty()) + { + empty_node_count++; + continue; + } + + const std::string name = replace_dashes_with_underscore(source_paragraph.name); + s.append(Strings::format("%s;", name)); + for (const Dependency& d : source_paragraph.depends) + { + const std::string dependency_name = replace_dashes_with_underscore(d.name()); + s.append(Strings::format("%s -> %s;", name, dependency_name)); + } + } + + s.append(Strings::format("empty [label=\"%d singletons...\"]; }", empty_node_count)); + return s; + } + static void do_print(const SourceParagraph& source_paragraph, bool full_desc) + { + if (full_desc) + { + System::println( + "%-20s %-16s %s", source_paragraph.name, source_paragraph.version, source_paragraph.description); + } + else + { + System::println("%-20s %-16s %s", + vcpkg::shorten_text(source_paragraph.name, 20), + vcpkg::shorten_text(source_paragraph.version, 16), + vcpkg::shorten_text(source_paragraph.description, 81)); + } + } + + static void do_print(const std::string& name, const FeatureParagraph& feature_paragraph, bool full_desc) + { + if (full_desc) + { + System::println("%-37s %s", name + "[" + feature_paragraph.name + "]", feature_paragraph.description); + } + else + { + System::println("%-37s %s", + vcpkg::shorten_text(name + "[" + feature_paragraph.name + "]", 37), + vcpkg::shorten_text(feature_paragraph.description, 81)); + } + } + + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) + { + static const std::string EXAMPLE = Strings::format( + "The argument should be a substring to search for, or no argument to display all libraries.\n%s", + Help::create_example_string("search png")); + args.check_max_arg_count(1, EXAMPLE); + const std::unordered_set options = + args.check_and_get_optional_command_arguments({OPTION_GRAPH, OPTION_FULLDESC}); + + auto 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); + System::println(graph_as_string); + Checks::exit_success(VCPKG_LINE_INFO); + } + + if (args.command_arguments.empty()) + { + for (const auto& source_control_file : source_paragraphs) + { + do_print(*source_control_file->core_paragraph, options.find(OPTION_FULLDESC) != options.cend()); + for (auto&& feature_paragraph : source_control_file->feature_paragraphs) + { + do_print(source_control_file->core_paragraph->name, + *feature_paragraph, + options.find(OPTION_FULLDESC) != options.cend()); + } + } + } + else + { + const auto& icontains = Strings::case_insensitive_ascii_contains; + + // At this point there is 1 argument + auto&& args_zero = args.command_arguments[0]; + for (const auto& source_control_file : source_paragraphs) + { + auto&& sp = *source_control_file->core_paragraph; + + bool contains_name = icontains(sp.name, args_zero); + if (contains_name || icontains(sp.description, args_zero)) + { + do_print(sp, options.find(OPTION_FULLDESC) != options.cend()); + } + + for (auto&& feature_paragraph : source_control_file->feature_paragraphs) + { + if (contains_name || icontains(feature_paragraph->name, args_zero) || + icontains(feature_paragraph->description, args_zero)) + { + do_print(sp.name, *feature_paragraph, options.find(OPTION_FULLDESC) != options.cend()); + } + } + } + } + + System::println( + "\nIf your library is not listed, please open an issue at and/or consider making a pull request:\n" + " https://github.com/Microsoft/vcpkg/issues"); + + Checks::exit_success(VCPKG_LINE_INFO); + } +} diff --git a/toolsrc/src/vcpkg/commands.version.cpp b/toolsrc/src/vcpkg/commands.version.cpp new file mode 100644 index 000000000..c6cc82d1f --- /dev/null +++ b/toolsrc/src/vcpkg/commands.version.cpp @@ -0,0 +1,67 @@ +#include "pch.h" + +#include +#include +#include + +#define STRINGIFY(...) #__VA_ARGS__ +#define MACRO_TO_STRING(X) STRINGIFY(X) + +#define VCPKG_VERSION_AS_STRING MACRO_TO_STRING(VCPKG_VERSION) + +namespace vcpkg::Commands::Version +{ + const std::string& version() + { + static const std::string S_VERSION = +#include "../VERSION.txt" + + +std::string(VCPKG_VERSION_AS_STRING) +#ifndef NDEBUG + + std::string("-debug") +#endif + + std::string(Metrics::get_compiled_metrics_enabled() ? Strings::EMPTY : "-external"); + return S_VERSION; + } + + void warn_if_vcpkg_version_mismatch(const VcpkgPaths& paths) + { + auto version_file = paths.get_filesystem().read_contents(paths.root / "toolsrc" / "VERSION.txt"); + if (const auto version_contents = version_file.get()) + { + int maj1, min1, rev1; + const auto num1 = sscanf_s(version_contents->c_str(), "\"%d.%d.%d\"", &maj1, &min1, &rev1); + + int maj2, min2, rev2; + const auto num2 = sscanf_s(Version::version().c_str(), "%d.%d.%d-", &maj2, &min2, &rev2); + + if (num1 == 3 && num2 == 3) + { + if (maj1 != maj2 || min1 != min2 || rev1 != rev2) + { + System::println(System::Color::warning, + "Warning: Different source is available for vcpkg (%d.%d.%d -> %d.%d.%d). Use " + ".\\bootstrap-vcpkg.bat to update.", + maj2, + min2, + rev2, + maj1, + min1, + rev1); + } + } + } + } + + void perform_and_exit(const VcpkgCmdArguments& args) + { + args.check_exact_arg_count(0); + args.check_and_get_optional_command_arguments({}); + + System::println("Vcpkg package management program version %s\n" + "\n" + "See LICENSE.txt for license information.", + version()); + Checks::exit_success(VCPKG_LINE_INFO); + } +} diff --git a/toolsrc/src/vcpkg/dependencies.cpp b/toolsrc/src/vcpkg/dependencies.cpp new file mode 100644 index 000000000..da8f1e178 --- /dev/null +++ b/toolsrc/src/vcpkg/dependencies.cpp @@ -0,0 +1,669 @@ +#include "pch.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace vcpkg::Dependencies +{ + struct FeatureNodeEdges + { + std::vector remove_edges; + std::vector build_edges; + bool plus = false; + }; + + struct Cluster : Util::MoveOnlyBase + { + std::vector status_paragraphs; + Optional source_control_file; + PackageSpec spec; + std::unordered_map edges; + std::unordered_set to_install_features; + std::unordered_set original_features; + bool will_remove = false; + bool transient_uninstalled = true; + RequestType request_type = RequestType::AUTO_SELECTED; + }; + + struct ClusterPtr + { + Cluster* ptr; + + Cluster* operator->() const { return ptr; } + }; + + bool operator==(const ClusterPtr& l, const ClusterPtr& r) { return l.ptr == r.ptr; } +} + +template<> +struct std::hash +{ + size_t operator()(const vcpkg::Dependencies::ClusterPtr& value) const + { + return std::hash()(value.ptr->spec); + } +}; + +namespace vcpkg::Dependencies +{ + struct GraphPlan + { + Graphs::Graph remove_graph; + Graphs::Graph install_graph; + }; + + struct ClusterGraph : Util::MoveOnlyBase + { + explicit ClusterGraph(std::unordered_map&& ports) + : m_ports(std::move(ports)) + { + } + + Cluster& get(const PackageSpec& spec) + { + auto it = m_graph.find(spec); + if (it == m_graph.end()) + { + // Load on-demand from m_ports + auto it_ports = m_ports.find(spec.name()); + if (it_ports != m_ports.end()) + { + auto& clust = m_graph[spec]; + clust.spec = spec; + cluster_from_scf(*it_ports->second, clust); + return clust; + } + return m_graph[spec]; + } + return it->second; + } + + private: + void cluster_from_scf(const SourceControlFile& scf, Cluster& out_cluster) const + { + FeatureNodeEdges core_dependencies; + core_dependencies.build_edges = + filter_dependencies_to_specs(scf.core_paragraph->depends, out_cluster.spec.triplet()); + out_cluster.edges.emplace("core", std::move(core_dependencies)); + + for (const auto& feature : scf.feature_paragraphs) + { + FeatureNodeEdges added_edges; + added_edges.build_edges = filter_dependencies_to_specs(feature->depends, out_cluster.spec.triplet()); + out_cluster.edges.emplace(feature->name, std::move(added_edges)); + } + out_cluster.source_control_file = &scf; + } + + std::unordered_map m_graph; + std::unordered_map m_ports; + }; + + std::vector AnyParagraph::dependencies(const Triplet& triplet) const + { + auto to_package_specs = [&](const std::vector& dependencies_as_string) { + return Util::fmap(dependencies_as_string, [&](const std::string s) { + return PackageSpec::from_name_and_triplet(s, triplet).value_or_exit(VCPKG_LINE_INFO); + }); + }; + + if (auto p = this->status_paragraph.get()) + { + return to_package_specs(p->package.depends); + } + + if (auto p = this->binary_control_file.get()) + { + auto deps = Util::fmap_flatten(p->features, [](const BinaryParagraph& pgh) { return pgh.depends; }); + deps.insert(deps.end(), p->core_paragraph.depends.begin(), p->core_paragraph.depends.end()); + return to_package_specs(deps); + } + + if (auto p = this->source_paragraph.get()) + { + return to_package_specs(filter_dependencies(p->depends, triplet)); + } + + Checks::exit_with_message(VCPKG_LINE_INFO, + "Cannot get dependencies because there was none of: source/binary/status paragraphs"); + } + + std::string to_output_string(RequestType request_type, const CStringView s) + { + switch (request_type) + { + case RequestType::AUTO_SELECTED: return Strings::format(" * %s", s); + case RequestType::USER_REQUESTED: return Strings::format(" %s", s); + default: Checks::unreachable(VCPKG_LINE_INFO); + } + } + + InstallPlanAction::InstallPlanAction() : plan_type(InstallPlanType::UNKNOWN), request_type(RequestType::UNKNOWN) {} + + InstallPlanAction::InstallPlanAction(const PackageSpec& spec, + const SourceControlFile& any_paragraph, + const std::unordered_set& features, + const RequestType& request_type) + : spec(spec), plan_type(InstallPlanType::BUILD_AND_INSTALL), request_type(request_type), feature_list(features) + { + this->any_paragraph.source_control_file = &any_paragraph; + } + + InstallPlanAction::InstallPlanAction(const PackageSpec& spec, + const std::unordered_set& features, + const RequestType& request_type) + : spec(spec), plan_type(InstallPlanType::ALREADY_INSTALLED), request_type(request_type), feature_list(features) + { + } + + InstallPlanAction::InstallPlanAction(const PackageSpec& spec, + const AnyParagraph& any_paragraph, + const RequestType& request_type) + : spec(spec), any_paragraph(any_paragraph), plan_type(InstallPlanType::UNKNOWN), request_type(request_type) + { + if (auto p = any_paragraph.status_paragraph.get()) + { + this->plan_type = InstallPlanType::ALREADY_INSTALLED; + return; + } + + if (auto p = any_paragraph.binary_control_file.get()) + { + this->plan_type = InstallPlanType::INSTALL; + return; + } + + if (auto p = any_paragraph.source_paragraph.get()) + { + this->plan_type = InstallPlanType::BUILD_AND_INSTALL; + return; + } + } + + std::string InstallPlanAction::displayname() const + { + if (this->feature_list.empty()) + { + return this->spec.to_string(); + } + + const std::string features = Strings::join(",", this->feature_list); + return Strings::format("%s[%s]:%s", this->spec.name(), features, this->spec.triplet()); + } + + bool InstallPlanAction::compare_by_name(const InstallPlanAction* left, const InstallPlanAction* right) + { + return left->spec.name() < right->spec.name(); + } + + RemovePlanAction::RemovePlanAction() : plan_type(RemovePlanType::UNKNOWN), request_type(RequestType::UNKNOWN) {} + + RemovePlanAction::RemovePlanAction(const PackageSpec& spec, + const RemovePlanType& plan_type, + const RequestType& request_type) + : spec(spec), plan_type(plan_type), request_type(request_type) + { + } + + const PackageSpec& AnyAction::spec() const + { + if (const auto p = install_plan.get()) + { + return p->spec; + } + + if (const auto p = remove_plan.get()) + { + return p->spec; + } + + Checks::exit_with_message(VCPKG_LINE_INFO, "Null action"); + } + + bool ExportPlanAction::compare_by_name(const ExportPlanAction* left, const ExportPlanAction* right) + { + return left->spec.name() < right->spec.name(); + } + + ExportPlanAction::ExportPlanAction() : plan_type(ExportPlanType::UNKNOWN), request_type(RequestType::UNKNOWN) {} + + ExportPlanAction::ExportPlanAction(const PackageSpec& spec, + const AnyParagraph& any_paragraph, + const RequestType& request_type) + : spec(spec), any_paragraph(any_paragraph), plan_type(ExportPlanType::UNKNOWN), request_type(request_type) + { + if (auto p = any_paragraph.binary_control_file.get()) + { + this->plan_type = ExportPlanType::ALREADY_BUILT; + return; + } + + if (auto p = any_paragraph.source_paragraph.get()) + { + this->plan_type = ExportPlanType::PORT_AVAILABLE_BUT_NOT_BUILT; + return; + } + } + + bool RemovePlanAction::compare_by_name(const RemovePlanAction* left, const RemovePlanAction* right) + { + return left->spec.name() < right->spec.name(); + } + + MapPortFile::MapPortFile(const std::unordered_map& map) : ports(map) {} + + const SourceControlFile& MapPortFile::get_control_file(const std::string& spec) const + { + auto scf = ports.find(spec); + if (scf == ports.end()) + { + Checks::exit_fail(VCPKG_LINE_INFO); + } + return scf->second; + } + + PathsPortFile::PathsPortFile(const VcpkgPaths& paths) : ports(paths) {} + + const SourceControlFile& PathsPortFile::get_control_file(const std::string& spec) const + { + auto cache_it = cache.find(spec); + if (cache_it != cache.end()) + { + return cache_it->second; + } + Parse::ParseExpected source_control_file = + Paragraphs::try_load_port(ports.get_filesystem(), ports.port_dir(spec)); + + if (auto scf = source_control_file.get()) + { + auto it = cache.emplace(spec, std::move(*scf->get())); + return it.first->second; + } + print_error_message(source_control_file.error()); + Checks::exit_fail(VCPKG_LINE_INFO); + } + + std::vector create_install_plan(const PortFileProvider& port_file_provider, + const std::vector& specs, + const StatusParagraphs& status_db) + { + struct InstallAdjacencyProvider final : Graphs::AdjacencyProvider + { + const PortFileProvider& port_file_provider; + const StatusParagraphs& status_db; + const std::unordered_set& specs_as_set; + + InstallAdjacencyProvider(const PortFileProvider& port_file_provider, + const StatusParagraphs& s, + const std::unordered_set& specs_as_set) + : port_file_provider(port_file_provider), status_db(s), specs_as_set(specs_as_set) + { + } + + std::vector adjacency_list(const InstallPlanAction& plan) const override + { + if (plan.any_paragraph.status_paragraph.get()) return std::vector{}; + return plan.any_paragraph.dependencies(plan.spec.triplet()); + } + + InstallPlanAction load_vertex_data(const PackageSpec& spec) const override + { + const RequestType request_type = specs_as_set.find(spec) != specs_as_set.end() + ? RequestType::USER_REQUESTED + : RequestType::AUTO_SELECTED; + auto it = status_db.find_installed(spec); + if (it != status_db.end()) return InstallPlanAction{spec, {*it->get(), nullopt, nullopt}, request_type}; + return InstallPlanAction{ + spec, + {nullopt, nullopt, *port_file_provider.get_control_file(spec.name()).core_paragraph}, + request_type}; + } + }; + + const std::unordered_set specs_as_set(specs.cbegin(), specs.cend()); + std::vector toposort = + Graphs::topological_sort(specs, InstallAdjacencyProvider{port_file_provider, status_db, specs_as_set}); + Util::erase_remove_if(toposort, [](const InstallPlanAction& plan) { + return plan.request_type == RequestType::AUTO_SELECTED && + plan.plan_type == InstallPlanType::ALREADY_INSTALLED; + }); + + return toposort; + } + + std::vector create_remove_plan(const std::vector& specs, + const StatusParagraphs& status_db) + { + struct RemoveAdjacencyProvider final : Graphs::AdjacencyProvider + { + const StatusParagraphs& status_db; + const std::vector& installed_ports; + const std::unordered_set& specs_as_set; + + RemoveAdjacencyProvider(const StatusParagraphs& status_db, + const std::vector& installed_ports, + const std::unordered_set& specs_as_set) + : status_db(status_db), installed_ports(installed_ports), specs_as_set(specs_as_set) + { + } + + std::vector adjacency_list(const RemovePlanAction& plan) const override + { + if (plan.plan_type == RemovePlanType::NOT_INSTALLED) + { + return {}; + } + + const PackageSpec& spec = plan.spec; + std::vector dependents; + for (const StatusParagraph* an_installed_package : installed_ports) + { + if (an_installed_package->package.spec.triplet() != spec.triplet()) continue; + + const std::vector& deps = an_installed_package->package.depends; + if (std::find(deps.begin(), deps.end(), spec.name()) == deps.end()) continue; + + dependents.push_back(an_installed_package->package.spec); + } + + return dependents; + } + + RemovePlanAction load_vertex_data(const PackageSpec& spec) const override + { + const RequestType request_type = specs_as_set.find(spec) != specs_as_set.end() + ? RequestType::USER_REQUESTED + : RequestType::AUTO_SELECTED; + const StatusParagraphs::const_iterator it = status_db.find_installed(spec); + if (it == status_db.end()) + { + return RemovePlanAction{spec, RemovePlanType::NOT_INSTALLED, request_type}; + } + return RemovePlanAction{spec, RemovePlanType::REMOVE, request_type}; + } + }; + + const std::vector& installed_ports = get_installed_ports(status_db); + const std::unordered_set specs_as_set(specs.cbegin(), specs.cend()); + return Graphs::topological_sort(specs, RemoveAdjacencyProvider{status_db, installed_ports, specs_as_set}); + } + + std::vector create_export_plan(const VcpkgPaths& paths, + const std::vector& specs, + const StatusParagraphs& status_db) + { + struct ExportAdjacencyProvider final : Graphs::AdjacencyProvider + { + const VcpkgPaths& paths; + const StatusParagraphs& status_db; + const std::unordered_set& specs_as_set; + + ExportAdjacencyProvider(const VcpkgPaths& p, + const StatusParagraphs& s, + const std::unordered_set& specs_as_set) + : paths(p), status_db(s), specs_as_set(specs_as_set) + { + } + + std::vector adjacency_list(const ExportPlanAction& plan) const override + { + return plan.any_paragraph.dependencies(plan.spec.triplet()); + } + + ExportPlanAction load_vertex_data(const PackageSpec& spec) const override + { + const RequestType request_type = specs_as_set.find(spec) != specs_as_set.end() + ? RequestType::USER_REQUESTED + : RequestType::AUTO_SELECTED; + + Expected maybe_bpgh = Paragraphs::try_load_cached_control_package(paths, spec); + if (auto bcf = maybe_bpgh.get()) + return ExportPlanAction{spec, AnyParagraph{nullopt, std::move(*bcf), nullopt}, request_type}; + + auto maybe_scf = Paragraphs::try_load_port(paths.get_filesystem(), paths.port_dir(spec)); + if (auto scf = maybe_scf.get()) + return ExportPlanAction{spec, {nullopt, nullopt, *scf->get()->core_paragraph}, request_type}; + else + print_error_message(maybe_scf.error()); + + Checks::exit_with_message(VCPKG_LINE_INFO, "Could not find package %s", spec); + } + }; + + const std::unordered_set specs_as_set(specs.cbegin(), specs.cend()); + std::vector toposort = + Graphs::topological_sort(specs, ExportAdjacencyProvider{paths, status_db, specs_as_set}); + return toposort; + } + + enum class MarkPlusResult + { + FEATURE_NOT_FOUND, + SUCCESS, + }; + + MarkPlusResult mark_plus(const std::string& feature, + Cluster& cluster, + ClusterGraph& pkg_to_cluster, + GraphPlan& graph_plan); + void mark_minus(Cluster& cluster, ClusterGraph& pkg_to_cluster, GraphPlan& graph_plan); + + MarkPlusResult mark_plus(const std::string& feature, Cluster& cluster, ClusterGraph& graph, GraphPlan& graph_plan) + { + if (feature.empty()) + { + // Indicates that core was not specified in the reference + return mark_plus("core", cluster, graph, graph_plan); + } + + auto it = cluster.edges.find(feature); + if (it == cluster.edges.end()) return MarkPlusResult::FEATURE_NOT_FOUND; + + if (cluster.edges[feature].plus) return MarkPlusResult::SUCCESS; + + if (cluster.original_features.find(feature) == cluster.original_features.end()) + { + cluster.transient_uninstalled = true; + } + + if (!cluster.transient_uninstalled) + { + return MarkPlusResult::SUCCESS; + } + cluster.edges[feature].plus = true; + + if (!cluster.original_features.empty()) + { + mark_minus(cluster, graph, graph_plan); + } + + graph_plan.install_graph.add_vertex({&cluster}); + auto& tracked = cluster.to_install_features; + tracked.insert(feature); + + if (feature != "core") + { + // All features implicitly depend on core + auto res = mark_plus("core", cluster, graph, graph_plan); + + // Should be impossible for "core" to not exist + Checks::check_exit(VCPKG_LINE_INFO, res == MarkPlusResult::SUCCESS); + } + + for (auto&& depend : cluster.edges[feature].build_edges) + { + auto& depend_cluster = graph.get(depend.spec()); + auto res = mark_plus(depend.feature(), depend_cluster, graph, graph_plan); + + Checks::check_exit(VCPKG_LINE_INFO, + res == MarkPlusResult::SUCCESS, + "Error: Unable to satisfy dependency %s of %s", + depend, + FeatureSpec(cluster.spec, feature)); + + if (&depend_cluster == &cluster) continue; + graph_plan.install_graph.add_edge({&cluster}, {&depend_cluster}); + } + + return MarkPlusResult::SUCCESS; + } + + void mark_minus(Cluster& cluster, ClusterGraph& graph, GraphPlan& graph_plan) + { + if (cluster.will_remove) return; + cluster.will_remove = true; + + graph_plan.remove_graph.add_vertex({&cluster}); + for (auto&& pair : cluster.edges) + { + auto& remove_edges_edges = pair.second.remove_edges; + for (auto&& depend : remove_edges_edges) + { + auto& depend_cluster = graph.get(depend.spec()); + graph_plan.remove_graph.add_edge({&cluster}, {&depend_cluster}); + mark_minus(depend_cluster, graph, graph_plan); + } + } + + cluster.transient_uninstalled = true; + for (auto&& original_feature : cluster.original_features) + { + auto res = mark_plus(original_feature, cluster, graph, graph_plan); + if (res != MarkPlusResult::SUCCESS) + { + System::println(System::Color::warning, + "Warning: could not reinstall feature %s", + FeatureSpec{cluster.spec, original_feature}); + } + } + } + + static ClusterGraph create_feature_install_graph(const std::unordered_map& map, + const StatusParagraphs& status_db) + { + std::unordered_map ptr_map; + for (auto&& p : map) + ptr_map.emplace(p.first, &p.second); + ClusterGraph graph(std::move(ptr_map)); + + auto installed_ports = get_installed_ports(status_db); + + for (auto&& status_paragraph : installed_ports) + { + Cluster& cluster = graph.get(status_paragraph->package.spec); + + cluster.transient_uninstalled = false; + + cluster.status_paragraphs.emplace_back(status_paragraph); + + auto& status_paragraph_feature = status_paragraph->package.feature; + // In this case, empty string indicates the "core" paragraph for a package. + if (status_paragraph_feature.empty()) + { + cluster.original_features.insert("core"); + } + else + { + cluster.original_features.insert(status_paragraph_feature); + } + } + + for (auto&& status_paragraph : installed_ports) + { + auto& spec = status_paragraph->package.spec; + auto& status_paragraph_feature = status_paragraph->package.feature; + auto reverse_edges = FeatureSpec::from_strings_and_triplet(status_paragraph->package.depends, + status_paragraph->package.spec.triplet()); + + for (auto&& dependency : reverse_edges) + { + auto& dep_cluster = graph.get(dependency.spec()); + + auto depends_name = dependency.feature(); + if (depends_name.empty()) depends_name = "core"; + + auto& target_node = dep_cluster.edges[depends_name]; + target_node.remove_edges.emplace_back(FeatureSpec{spec, status_paragraph_feature}); + } + } + return graph; + } + + std::vector create_feature_install_plan(const std::unordered_map& map, + const std::vector& specs, + const StatusParagraphs& status_db) + { + ClusterGraph graph = create_feature_install_graph(map, status_db); + + GraphPlan graph_plan; + for (auto&& spec : specs) + { + Cluster& spec_cluster = graph.get(spec.spec()); + spec_cluster.request_type = RequestType::USER_REQUESTED; + auto res = mark_plus(spec.feature(), spec_cluster, graph, graph_plan); + + Checks::check_exit( + VCPKG_LINE_INFO, res == MarkPlusResult::SUCCESS, "Error: Unable to locate feature %s", spec); + + graph_plan.install_graph.add_vertex(ClusterPtr{&spec_cluster}); + } + + Graphs::GraphAdjacencyProvider adjacency_remove_graph(graph_plan.remove_graph.adjacency_list()); + auto remove_vertex_list = graph_plan.remove_graph.vertex_list(); + auto remove_toposort = Graphs::topological_sort(remove_vertex_list, adjacency_remove_graph); + + Graphs::GraphAdjacencyProvider adjacency_install_graph(graph_plan.install_graph.adjacency_list()); + auto insert_vertex_list = graph_plan.install_graph.vertex_list(); + auto insert_toposort = Graphs::topological_sort(insert_vertex_list, adjacency_install_graph); + + std::vector plan; + + for (auto&& p_cluster : remove_toposort) + { + auto scf = *p_cluster->source_control_file.get(); + auto spec = PackageSpec::from_name_and_triplet(scf->core_paragraph->name, p_cluster->spec.triplet()) + .value_or_exit(VCPKG_LINE_INFO); + plan.emplace_back(RemovePlanAction{ + std::move(spec), + RemovePlanType::REMOVE, + p_cluster->request_type, + }); + } + + for (auto&& p_cluster : insert_toposort) + { + if (p_cluster->transient_uninstalled) + { + // If it will be transiently uninstalled, we need to issue a full installation command + auto pscf = p_cluster->source_control_file.value_or_exit(VCPKG_LINE_INFO); + Checks::check_exit(VCPKG_LINE_INFO, pscf != nullptr); + plan.emplace_back(InstallPlanAction{ + p_cluster->spec, + *pscf, + p_cluster->to_install_features, + p_cluster->request_type, + }); + } + else + { + // If the package isn't transitively installed, still include it if the user explicitly requested it + if (p_cluster->request_type != RequestType::USER_REQUESTED) continue; + plan.emplace_back(InstallPlanAction{ + p_cluster->spec, + p_cluster->original_features, + p_cluster->request_type, + }); + } + } + + return plan; + } +} diff --git a/toolsrc/src/vcpkg/export.cpp b/toolsrc/src/vcpkg/export.cpp new file mode 100644 index 000000000..de6464c87 --- /dev/null +++ b/toolsrc/src/vcpkg/export.cpp @@ -0,0 +1,528 @@ +#include "pch.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace vcpkg::Export +{ + using Dependencies::ExportPlanAction; + using Dependencies::ExportPlanType; + using Dependencies::RequestType; + using Install::InstallDir; + + static std::string create_nuspec_file_contents(const std::string& raw_exported_dir, + const std::string& targets_redirect_path, + const std::string& nuget_id, + const std::string& nupkg_version) + { + static constexpr auto CONTENT_TEMPLATE = R"( + + + @NUGET_ID@ + @VERSION@ + vcpkg + + Vcpkg NuGet export + + + + + + + + + +)"; + + std::string nuspec_file_content = std::regex_replace(CONTENT_TEMPLATE, std::regex("@NUGET_ID@"), nuget_id); + nuspec_file_content = std::regex_replace(nuspec_file_content, std::regex("@VERSION@"), nupkg_version); + nuspec_file_content = + std::regex_replace(nuspec_file_content, std::regex("@RAW_EXPORTED_DIR@"), raw_exported_dir); + nuspec_file_content = + std::regex_replace(nuspec_file_content, std::regex("@TARGETS_REDIRECT_PATH@"), targets_redirect_path); + return nuspec_file_content; + } + + static std::string create_targets_redirect(const std::string& target_path) noexcept + { + return Strings::format(R"###( + + + +)###", + target_path, + target_path); + } + + static void print_plan(const std::map>& group_by_plan_type) + { + static constexpr std::array ORDER = {ExportPlanType::ALREADY_BUILT, + ExportPlanType::PORT_AVAILABLE_BUT_NOT_BUILT}; + + for (const ExportPlanType plan_type : ORDER) + { + const auto it = group_by_plan_type.find(plan_type); + if (it == group_by_plan_type.cend()) + { + continue; + } + + std::vector cont = it->second; + std::sort(cont.begin(), cont.end(), &ExportPlanAction::compare_by_name); + const std::string as_string = Strings::join("\n", cont, [](const ExportPlanAction* p) { + return Dependencies::to_output_string(p->request_type, p->spec.to_string()); + }); + + switch (plan_type) + { + case ExportPlanType::ALREADY_BUILT: + System::println("The following packages are already built and will be exported:\n%s", as_string); + continue; + case ExportPlanType::PORT_AVAILABLE_BUT_NOT_BUILT: + System::println("The following packages need to be built:\n%s", as_string); + continue; + default: Checks::unreachable(VCPKG_LINE_INFO); + } + } + } + + static std::string create_export_id() + { + const tm date_time = System::get_current_date_time(); + + // Format is: YYYYmmdd-HHMMSS + // 15 characters + 1 null terminating character will be written for a total of 16 chars + char mbstr[16]; + const size_t bytes_written = std::strftime(mbstr, sizeof(mbstr), "%Y%m%d-%H%M%S", &date_time); + Checks::check_exit(VCPKG_LINE_INFO, + bytes_written == 15, + "Expected 15 bytes to be written, but %u were written", + bytes_written); + const std::string date_time_as_string(mbstr); + return ("vcpkg-export-" + date_time_as_string); + } + + static fs::path do_nuget_export(const VcpkgPaths& paths, + const std::string& nuget_id, + const std::string& nuget_version, + const fs::path& raw_exported_dir, + const fs::path& output_dir) + { + Files::Filesystem& fs = paths.get_filesystem(); + const fs::path& nuget_exe = paths.get_nuget_exe(); + + // This file will be placed in "build\native" in the nuget package. Therefore, go up two dirs. + const std::string targets_redirect_content = + create_targets_redirect("../../scripts/buildsystems/msbuild/vcpkg.targets"); + const fs::path targets_redirect = paths.buildsystems / "tmp" / "vcpkg.export.nuget.targets"; + + std::error_code ec; + fs.create_directories(paths.buildsystems / "tmp", ec); + + fs.write_contents(targets_redirect, targets_redirect_content); + + const std::string nuspec_file_content = + create_nuspec_file_contents(raw_exported_dir.string(), targets_redirect.string(), nuget_id, nuget_version); + const fs::path nuspec_file_path = paths.buildsystems / "tmp" / "vcpkg.export.nuspec"; + fs.write_contents(nuspec_file_path, nuspec_file_content); + + // -NoDefaultExcludes is needed for ".vcpkg-root" + const std::wstring cmd_line = + Strings::wformat(LR"("%s" pack -OutputDirectory "%s" "%s" -NoDefaultExcludes > nul)", + nuget_exe.native(), + output_dir.native(), + nuspec_file_path.native()); + + const int exit_code = System::cmd_execute_clean(cmd_line); + Checks::check_exit(VCPKG_LINE_INFO, exit_code == 0, "Error: NuGet package creation failed"); + + const fs::path output_path = output_dir / (nuget_id + ".nupkg"); + return output_path; + } + + struct ArchiveFormat final + { + enum class BackingEnum + { + ZIP = 1, + SEVEN_ZIP, + }; + + constexpr ArchiveFormat() = delete; + + constexpr ArchiveFormat(BackingEnum backing_enum, const wchar_t* extension, const wchar_t* cmake_option) + : backing_enum(backing_enum), m_extension(extension), m_cmake_option(cmake_option) + { + } + + constexpr operator BackingEnum() const { return backing_enum; } + constexpr CWStringView extension() const { return this->m_extension; } + constexpr CWStringView cmake_option() const { return this->m_cmake_option; } + + private: + BackingEnum backing_enum; + const wchar_t* m_extension; + const wchar_t* m_cmake_option; + }; + + namespace ArchiveFormatC + { + constexpr const ArchiveFormat ZIP(ArchiveFormat::BackingEnum::ZIP, L"zip", L"zip"); + constexpr const ArchiveFormat SEVEN_ZIP(ArchiveFormat::BackingEnum::SEVEN_ZIP, L"7z", L"7zip"); + } + + static fs::path do_archive_export(const VcpkgPaths& paths, + const fs::path& raw_exported_dir, + const fs::path& output_dir, + const ArchiveFormat& format) + { + const fs::path& cmake_exe = paths.get_cmake_exe(); + + const std::wstring exported_dir_filename = raw_exported_dir.filename().native(); + const std::wstring exported_archive_filename = + Strings::wformat(L"%s.%s", exported_dir_filename, format.extension()); + const fs::path exported_archive_path = (output_dir / exported_archive_filename); + + // -NoDefaultExcludes is needed for ".vcpkg-root" + const std::wstring cmd_line = Strings::wformat(LR"("%s" -E tar "cf" "%s" --format=%s -- "%s")", + cmake_exe.native(), + exported_archive_path.native(), + format.cmake_option(), + raw_exported_dir.native()); + + const int exit_code = System::cmd_execute_clean(cmd_line); + Checks::check_exit( + VCPKG_LINE_INFO, exit_code == 0, "Error: %s creation failed", exported_archive_path.generic_string()); + return exported_archive_path; + } + + static Optional maybe_lookup(std::unordered_map const& m, + std::string const& key) + { + const auto it = m.find(key); + if (it != m.end()) return it->second; + return nullopt; + } + + void export_integration_files(const fs::path& raw_exported_dir_path, const VcpkgPaths& paths) + { + const std::vector integration_files_relative_to_root = { + {".vcpkg-root"}, + {fs::path{"scripts"} / "buildsystems" / "msbuild" / "applocal.ps1"}, + {fs::path{"scripts"} / "buildsystems" / "msbuild" / "vcpkg.targets"}, + {fs::path{"scripts"} / "buildsystems" / "vcpkg.cmake"}, + {fs::path{"scripts"} / "cmake" / "vcpkg_get_windows_sdk.cmake"}, + {fs::path{"scripts"} / "getWindowsSDK.ps1"}, + {fs::path{"scripts"} / "getProgramFilesPlatformBitness.ps1"}, + {fs::path{"scripts"} / "getProgramFiles32bit.ps1"}, + }; + + for (const fs::path& file : integration_files_relative_to_root) + { + const fs::path source = paths.root / file; + fs::path destination = raw_exported_dir_path / file; + Files::Filesystem& fs = paths.get_filesystem(); + std::error_code ec; + fs.create_directories(destination.parent_path(), ec); + Checks::check_exit(VCPKG_LINE_INFO, !ec); + fs.copy_file(source, destination, fs::copy_options::overwrite_existing, ec); + Checks::check_exit(VCPKG_LINE_INFO, !ec); + } + } + + struct ExportArguments + { + bool dry_run; + bool raw; + bool nuget; + bool ifw; + bool zip; + bool seven_zip; + + Optional maybe_nuget_id; + Optional maybe_nuget_version; + + IFW::Options ifw_options; + std::vector specs; + }; + + static ExportArguments handle_export_command_arguments(const VcpkgCmdArguments& args, + const Triplet& default_triplet) + { + ExportArguments ret; + + static const std::string OPTION_DRY_RUN = "--dry-run"; + static const std::string OPTION_RAW = "--raw"; + static const std::string OPTION_NUGET = "--nuget"; + static const std::string OPTION_IFW = "--ifw"; + static const std::string OPTION_ZIP = "--zip"; + static const std::string OPTION_SEVEN_ZIP = "--7zip"; + static const std::string OPTION_NUGET_ID = "--nuget-id"; + static const std::string OPTION_NUGET_VERSION = "--nuget-version"; + static const std::string OPTION_IFW_REPOSITORY_URL = "--ifw-repository-url"; + static const std::string OPTION_IFW_PACKAGES_DIR_PATH = "--ifw-packages-directory-path"; + static const std::string OPTION_IFW_REPOSITORY_DIR_PATH = "--ifw-repository-directory-path"; + static const std::string OPTION_IFW_CONFIG_FILE_PATH = "--ifw-configuration-file-path"; + static const std::string OPTION_IFW_INSTALLER_FILE_PATH = "--ifw-installer-file-path"; + + // input sanitization + static const std::string EXAMPLE = Help::create_example_string("export zlib zlib:x64-windows boost --nuget"); + args.check_min_arg_count(1, EXAMPLE); + + ret.specs = Util::fmap(args.command_arguments, [&](auto&& arg) { + return Input::check_and_get_package_spec(arg, default_triplet, EXAMPLE); + }); + + const auto options = args.check_and_get_optional_command_arguments( + { + OPTION_DRY_RUN, + OPTION_RAW, + OPTION_NUGET, + OPTION_IFW, + OPTION_ZIP, + OPTION_SEVEN_ZIP, + }, + { + OPTION_NUGET_ID, + OPTION_NUGET_VERSION, + OPTION_IFW_REPOSITORY_URL, + OPTION_IFW_PACKAGES_DIR_PATH, + OPTION_IFW_REPOSITORY_DIR_PATH, + OPTION_IFW_CONFIG_FILE_PATH, + OPTION_IFW_INSTALLER_FILE_PATH, + }); + ret.dry_run = options.switches.find(OPTION_DRY_RUN) != options.switches.cend(); + ret.raw = options.switches.find(OPTION_RAW) != options.switches.cend(); + ret.nuget = options.switches.find(OPTION_NUGET) != options.switches.cend(); + ret.ifw = options.switches.find(OPTION_IFW) != options.switches.cend(); + ret.zip = options.switches.find(OPTION_ZIP) != options.switches.cend(); + ret.seven_zip = options.switches.find(OPTION_SEVEN_ZIP) != options.switches.cend(); + + if (!ret.raw && !ret.nuget && !ret.ifw && !ret.zip && !ret.seven_zip && !ret.dry_run) + { + System::println(System::Color::error, + "Must provide at least one export type: --raw --nuget --ifw --zip --7zip"); + System::print(EXAMPLE); + Checks::exit_fail(VCPKG_LINE_INFO); + } + + struct OptionPair + { + const std::string& name; + Optional& out_opt; + }; + const auto options_implies = + [&](const std::string& main_opt_name, bool main_opt, Span implying_opts) { + if (main_opt) + { + for (auto&& opt : implying_opts) + opt.out_opt = maybe_lookup(options.settings, opt.name); + } + else + { + for (auto&& opt : implying_opts) + Checks::check_exit(VCPKG_LINE_INFO, + !maybe_lookup(options.settings, opt.name), + "%s is only valid with %s", + opt.name, + main_opt_name); + } + }; + + options_implies(OPTION_NUGET, + ret.nuget, + { + {OPTION_NUGET_ID, ret.maybe_nuget_id}, + {OPTION_NUGET_VERSION, ret.maybe_nuget_version}, + }); + + options_implies(OPTION_IFW, + ret.ifw, + { + {OPTION_IFW_REPOSITORY_URL, ret.ifw_options.maybe_repository_url}, + {OPTION_IFW_PACKAGES_DIR_PATH, ret.ifw_options.maybe_packages_dir_path}, + {OPTION_IFW_REPOSITORY_DIR_PATH, ret.ifw_options.maybe_repository_dir_path}, + {OPTION_IFW_CONFIG_FILE_PATH, ret.ifw_options.maybe_config_file_path}, + {OPTION_IFW_INSTALLER_FILE_PATH, ret.ifw_options.maybe_installer_file_path}, + }); + return ret; + } + + static void print_next_step_info(const fs::path& prefix) + { + const fs::path cmake_toolchain = prefix / "scripts" / "buildsystems" / "vcpkg.cmake"; + const CMakeVariable cmake_variable = CMakeVariable(L"CMAKE_TOOLCHAIN_FILE", cmake_toolchain.generic_string()); + System::println("\n" + "To use the exported libraries in CMake projects use:" + "\n" + " %s" + "\n", + Strings::to_utf8(cmake_variable.s)); + }; + + static void handle_raw_based_export(Span export_plan, + const ExportArguments& opts, + const std::string& export_id, + const VcpkgPaths& paths) + { + Files::Filesystem& fs = paths.get_filesystem(); + const fs::path export_to_path = paths.root; + const fs::path raw_exported_dir_path = export_to_path / export_id; + std::error_code ec; + fs.remove_all(raw_exported_dir_path, ec); + fs.create_directory(raw_exported_dir_path, ec); + + // execute the plan + for (const ExportPlanAction& action : export_plan) + { + if (action.plan_type != ExportPlanType::ALREADY_BUILT) + { + Checks::unreachable(VCPKG_LINE_INFO); + } + + const std::string display_name = action.spec.to_string(); + System::println("Exporting package %s... ", display_name); + + const BinaryParagraph& binary_paragraph = + action.any_paragraph.binary_control_file.value_or_exit(VCPKG_LINE_INFO).core_paragraph; + + const InstallDir dirs = InstallDir::from_destination_root( + raw_exported_dir_path / "installed", + 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); + System::println(System::Color::success, "Exporting package %s... done", display_name); + } + + // Copy files needed for integration + export_integration_files(raw_exported_dir_path, paths); + + if (opts.raw) + { + System::println( + System::Color::success, R"(Files exported at: "%s")", raw_exported_dir_path.generic_string()); + print_next_step_info(export_to_path); + } + + if (opts.nuget) + { + System::println("Creating nuget package... "); + + const std::string nuget_id = opts.maybe_nuget_id.value_or(raw_exported_dir_path.filename().string()); + const std::string nuget_version = opts.maybe_nuget_version.value_or("1.0.0"); + const fs::path output_path = + do_nuget_export(paths, nuget_id, nuget_version, raw_exported_dir_path, export_to_path); + System::println(System::Color::success, "Creating nuget package... done"); + System::println(System::Color::success, "NuGet package exported at: %s", output_path.generic_string()); + + System::println(R"( +With a project open, go to Tools->NuGet Package Manager->Package Manager Console and paste: + Install-Package %s -Source "%s" +)" + "\n", + nuget_id, + output_path.parent_path().u8string()); + } + + if (opts.zip) + { + System::println("Creating zip archive... "); + const fs::path output_path = + do_archive_export(paths, raw_exported_dir_path, export_to_path, ArchiveFormatC::ZIP); + System::println(System::Color::success, "Creating zip archive... done"); + System::println(System::Color::success, "Zip archive exported at: %s", output_path.generic_string()); + print_next_step_info("[...]"); + } + + if (opts.seven_zip) + { + System::println("Creating 7zip archive... "); + const fs::path output_path = + do_archive_export(paths, raw_exported_dir_path, export_to_path, ArchiveFormatC::SEVEN_ZIP); + System::println(System::Color::success, "Creating 7zip archive... done"); + System::println(System::Color::success, "7zip archive exported at: %s", output_path.generic_string()); + print_next_step_info("[...]"); + } + + if (!opts.raw) + { + fs.remove_all(raw_exported_dir_path, ec); + } + } + + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) + { + const auto opts = handle_export_command_arguments(args, default_triplet); + for (auto&& spec : opts.specs) + Input::check_triplet(spec.triplet(), paths); + + // create the plan + const StatusParagraphs status_db = database_load_check(paths); + std::vector export_plan = Dependencies::create_export_plan(paths, opts.specs, status_db); + Checks::check_exit(VCPKG_LINE_INFO, !export_plan.empty(), "Export plan cannot be empty"); + + std::map> group_by_plan_type; + Util::group_by(export_plan, &group_by_plan_type, [](const ExportPlanAction& p) { return p.plan_type; }); + print_plan(group_by_plan_type); + + const bool has_non_user_requested_packages = + Util::find_if(export_plan, [](const ExportPlanAction& package) -> bool { + return package.request_type != RequestType::USER_REQUESTED; + }) != export_plan.cend(); + + if (has_non_user_requested_packages) + { + System::println(System::Color::warning, + "Additional packages (*) need to be exported to complete this operation."); + } + + const auto it = group_by_plan_type.find(ExportPlanType::PORT_AVAILABLE_BUT_NOT_BUILT); + if (it != group_by_plan_type.cend() && !it->second.empty()) + { + System::println(System::Color::error, "There are packages that have not been built."); + + // No need to show all of them, just the user-requested ones. Dependency resolution will handle the rest. + std::vector unbuilt = it->second; + Util::erase_remove_if( + unbuilt, [](const ExportPlanAction* a) { return a->request_type != RequestType::USER_REQUESTED; }); + + const auto s = Strings::join(" ", unbuilt, [](const ExportPlanAction* a) { return a->spec.to_string(); }); + System::println("To build them, run:\n" + " vcpkg install %s", + s); + Checks::exit_fail(VCPKG_LINE_INFO); + } + + if (opts.dry_run) + { + Checks::exit_success(VCPKG_LINE_INFO); + } + + std::string export_id = create_export_id(); + + if (opts.raw || opts.nuget || opts.zip || opts.seven_zip) + { + handle_raw_based_export(export_plan, opts, export_id, paths); + } + + if (opts.ifw) + { + IFW::do_export(export_plan, export_id, opts.ifw_options, paths); + + print_next_step_info("@RootDir@/src/vcpkg"); + } + + Checks::exit_success(VCPKG_LINE_INFO); + } +} diff --git a/toolsrc/src/vcpkg/globalstate.cpp b/toolsrc/src/vcpkg/globalstate.cpp new file mode 100644 index 000000000..de564d357 --- /dev/null +++ b/toolsrc/src/vcpkg/globalstate.cpp @@ -0,0 +1,13 @@ +#include "pch.h" + +#include + +namespace vcpkg +{ + Util::LockGuarded GlobalState::timer; + std::atomic GlobalState::debugging = false; + std::atomic GlobalState::feature_packages = false; + + std::atomic GlobalState::g_init_console_cp = 0; + std::atomic GlobalState::g_init_console_output_cp = 0; +} diff --git a/toolsrc/src/vcpkg/help.cpp b/toolsrc/src/vcpkg/help.cpp new file mode 100644 index 000000000..7867f71d2 --- /dev/null +++ b/toolsrc/src/vcpkg/help.cpp @@ -0,0 +1,131 @@ +#include "pch.h" + +#include +#include + +namespace vcpkg::Help +{ + void help_topics() + { + System::println("Available help topics:\n" + " triplet\n" + " integrate\n" + " export"); + } + + void help_topic_valid_triplet(const VcpkgPaths& paths) + { + System::println("Available architecture triplets:"); + for (auto&& path : paths.get_filesystem().get_files_non_recursive(paths.triplets)) + { + System::println(" %s", path.stem().filename().string()); + } + } + + void help_topic_export() + { + System::println("Summary:\n" + " vcpkg export [options] ...\n" + "\n" + "Options:\n" + " --7zip Export to a 7zip (.7z) file\n" + " --dry-run Do not actually export\n" + " --nuget Export a NuGet package\n" + " --nuget-id= Specify the id for the exported NuGet package\n" + " --nuget-version= Specify the version for the exported NuGet package\n" + " --raw Export to an uncompressed directory\n" + " --zip Export to a zip file"); + } + + void print_usage() + { + System::println( + "Commands:\n" + " vcpkg search [pat] Search for packages available to be built\n" + " vcpkg install ... Install a package\n" + " vcpkg remove ... Uninstall a package\n" + " vcpkg remove --outdated Uninstall all out-of-date packages\n" + " vcpkg list List installed packages\n" + " vcpkg update Display list of packages for updating\n" + " vcpkg hash [alg] Hash a file by specific algorithm, default SHA512\n" + " vcpkg help topics Display the list of help topics\n" + " vcpkg help Display help for a specific topic\n" + "\n" + "%s" // Integration help + "\n" + " vcpkg export ... [opt]... Exports a package\n" + " vcpkg edit Open up a port for editing (uses %%EDITOR%%, default 'code')\n" + " vcpkg import Import a pre-built library\n" + " vcpkg create \n" + " [archivename] Create a new package\n" + " vcpkg owns Search for files in installed packages\n" + " vcpkg cache List cached compiled packages\n" + " vcpkg version Display version information\n" + " vcpkg contact Display contact information to send feedback\n" + "\n" + //"internal commands:\n" + //" --check-build-deps \n" + //" --create-binary-control \n" + //"\n" + "Options:\n" + " --triplet Specify the target architecture triplet.\n" + " (default: %%VCPKG_DEFAULT_TRIPLET%%, see 'vcpkg help triplet')\n" + "\n" + " --vcpkg-root Specify the vcpkg root directory\n" + " (default: %%VCPKG_ROOT%%)\n" + "\n" + "For more help (including examples) see the accompanying README.md.", + Commands::Integrate::INTEGRATE_COMMAND_HELPSTRING); + } + + std::string create_example_string(const std::string& command_and_arguments) + { + std::string cs = Strings::format("Example:\n" + " vcpkg %s\n", + command_and_arguments); + return cs; + } + + void print_example(const std::string& command_and_arguments) + { + System::println(create_example_string(command_and_arguments)); + } + + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) + { + args.check_max_arg_count(1); + args.check_and_get_optional_command_arguments({}); + + if (args.command_arguments.empty()) + { + print_usage(); + Checks::exit_success(VCPKG_LINE_INFO); + } + const auto& topic = args.command_arguments[0]; + if (topic == "triplet" || topic == "triplets" || topic == "triple") + { + help_topic_valid_triplet(paths); + } + else if (topic == "export") + { + help_topic_export(); + } + else if (topic == "integrate") + { + System::print("Commands:\n" + "%s", + Commands::Integrate::INTEGRATE_COMMAND_HELPSTRING); + } + else if (topic == "topics") + { + help_topics(); + } + else + { + System::println(System::Color::error, "Error: unknown topic %s", topic); + help_topics(); + Checks::exit_fail(VCPKG_LINE_INFO); + } + Checks::exit_success(VCPKG_LINE_INFO); + } +} diff --git a/toolsrc/src/vcpkg/input.cpp b/toolsrc/src/vcpkg/input.cpp new file mode 100644 index 000000000..aee0fac7f --- /dev/null +++ b/toolsrc/src/vcpkg/input.cpp @@ -0,0 +1,55 @@ +#include "pch.h" + +#include +#include +#include +#include +#include + +namespace vcpkg::Input +{ + PackageSpec check_and_get_package_spec(const std::string& package_spec_as_string, + const Triplet& default_triplet, + CStringView example_text) + { + const std::string as_lowercase = Strings::ascii_to_lowercase(package_spec_as_string); + auto expected_spec = FullPackageSpec::from_string(as_lowercase, default_triplet); + if (const auto spec = expected_spec.get()) + { + return PackageSpec{spec->package_spec}; + } + + // Intentionally show the lowercased string + System::println(System::Color::error, "Error: %s: %s", vcpkg::to_string(expected_spec.error()), as_lowercase); + System::print(example_text); + Checks::exit_fail(VCPKG_LINE_INFO); + } + + void check_triplet(const Triplet& t, const VcpkgPaths& paths) + { + if (!paths.is_valid_triplet(t)) + { + System::println(System::Color::error, "Error: invalid triplet: %s", t); + Metrics::g_metrics.lock()->track_property("error", "invalid triplet: " + t.to_string()); + Help::help_topic_valid_triplet(paths); + Checks::exit_fail(VCPKG_LINE_INFO); + } + } + + FullPackageSpec check_and_get_full_package_spec(const std::string& full_package_spec_as_string, + const Triplet& default_triplet, + CStringView example_text) + { + const std::string as_lowercase = Strings::ascii_to_lowercase(full_package_spec_as_string); + auto expected_spec = FullPackageSpec::from_string(as_lowercase, default_triplet); + if (const auto spec = expected_spec.get()) + { + return *spec; + } + + // Intentionally show the lowercased string + System::println(System::Color::error, "Error: %s: %s", vcpkg::to_string(expected_spec.error()), as_lowercase); + System::print(example_text); + Checks::exit_fail(VCPKG_LINE_INFO); + } +} diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp new file mode 100644 index 000000000..74bea0d5f --- /dev/null +++ b/toolsrc/src/vcpkg/install.cpp @@ -0,0 +1,615 @@ +#include "pch.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace vcpkg::Install +{ + using namespace Dependencies; + + InstallDir InstallDir::from_destination_root(const fs::path& destination_root, + const std::string& destination_subdirectory, + const fs::path& listfile) + { + InstallDir dirs; + dirs.m_destination = destination_root / destination_subdirectory; + dirs.m_destination_subdirectory = destination_subdirectory; + dirs.m_listfile = listfile; + return dirs; + } + + const fs::path& InstallDir::destination() const { return this->m_destination; } + + const std::string& InstallDir::destination_subdirectory() const { return this->m_destination_subdirectory; } + + const fs::path& InstallDir::listfile() const { return this->m_listfile; } + + void install_files_and_write_listfile(Files::Filesystem& fs, + const fs::path& source_dir, + const InstallDir& destination_dir) + { + std::vector output; + std::error_code ec; + + const size_t prefix_length = source_dir.native().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()); + 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()); + + 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.status(file, ec); + if (ec) + { + System::println(System::Color::error, "failed: %s: %s", file.u8string(), ec.message()); + continue; + } + + const std::string filename = file.filename().generic_string(); + if (fs::is_regular_file(status) && + (Strings::case_insensitive_ascii_compare(filename.c_str(), "CONTROL") || + Strings::case_insensitive_ascii_compare(filename.c_str(), "BUILD_INFO"))) + { + // Do not copy the control file + continue; + } + + const std::string suffix = file.generic_u8string().substr(prefix_length + 1); + const fs::path target = destination / suffix; + + if (fs::is_directory(status)) + { + 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/)", destination_subdirectory, suffix)); + continue; + } + + if (fs::is_regular_file(status)) + { + 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(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)", destination_subdirectory, suffix)); + continue; + } + + if (!fs::status_known(status)) + { + System::println(System::Color::error, "failed: %s: unknown status", file.u8string()); + continue; + } + + System::println(System::Color::error, "failed: %s: cannot handle file type", file.u8string()); + } + + std::sort(output.begin(), output.end()); + + fs.write_lines(listfile, output); + } + + static void remove_first_n_chars(std::vector* strings, const size_t n) + { + for (std::string& s : *strings) + { + s.erase(0, n); + } + }; + + static std::vector extract_files_in_triplet( + const std::vector& pgh_and_files, const Triplet& triplet) + { + std::vector output; + for (const StatusParagraphAndAssociatedFiles& t : pgh_and_files) + { + if (t.pgh.package.spec.triplet() != triplet) + { + continue; + } + + output.insert(output.end(), t.files.begin(), t.files.end()); + } + + std::sort(output.begin(), output.end()); + return output; + } + + static SortedVector build_list_of_package_files(const Files::Filesystem& fs, + const fs::path& package_dir) + { + const std::vector package_file_paths = fs.get_files_recursive(package_dir); + const size_t package_remove_char_count = package_dir.generic_string().size() + 1; // +1 for the slash + auto package_files = Util::fmap(package_file_paths, [package_remove_char_count](const fs::path& path) { + std::string as_string = path.generic_string(); + as_string.erase(0, package_remove_char_count); + return std::move(as_string); + }); + + return SortedVector(std::move(package_files)); + } + + static SortedVector build_list_of_installed_files( + const std::vector& pgh_and_files, const Triplet& triplet) + { + std::vector installed_files = extract_files_in_triplet(pgh_and_files, triplet); + const size_t installed_remove_char_count = triplet.canonical_name().size() + 1; // +1 for the slash + remove_first_n_chars(&installed_files, installed_remove_char_count); + + return SortedVector(std::move(installed_files)); + } + + InstallResult install_package(const VcpkgPaths& paths, const BinaryControlFile& bcf, StatusParagraphs* status_db) + { + const fs::path package_dir = paths.package_dir(bcf.core_paragraph.spec); + const Triplet& triplet = bcf.core_paragraph.spec.triplet(); + const std::vector pgh_and_files = get_installed_files(paths, *status_db); + + const SortedVector package_files = + build_list_of_package_files(paths.get_filesystem(), package_dir); + const SortedVector installed_files = build_list_of_installed_files(pgh_and_files, triplet); + + std::vector intersection; + std::set_intersection(package_files.begin(), + package_files.end(), + installed_files.begin(), + installed_files.end(), + std::back_inserter(intersection)); + + if (!intersection.empty()) + { + const fs::path triplet_install_path = paths.installed / triplet.canonical_name(); + System::println(System::Color::error, + "The following files are already installed in %s and are in conflict with %s", + triplet_install_path.generic_string(), + bcf.core_paragraph.spec); + System::print("\n "); + System::println(Strings::join("\n ", intersection)); + System::println(); + return InstallResult::FILE_CONFLICTS; + } + + StatusParagraph source_paragraph; + source_paragraph.package = bcf.core_paragraph; + source_paragraph.want = Want::INSTALL; + source_paragraph.state = InstallState::HALF_INSTALLED; + + write_update(paths, source_paragraph); + status_db->insert(std::make_unique(source_paragraph)); + + std::vector features_spghs; + for (auto&& feature : bcf.features) + { + features_spghs.emplace_back(); + + StatusParagraph& feature_paragraph = features_spghs.back(); + feature_paragraph.package = feature; + feature_paragraph.want = Want::INSTALL; + feature_paragraph.state = InstallState::HALF_INSTALLED; + + write_update(paths, feature_paragraph); + status_db->insert(std::make_unique(feature_paragraph)); + } + + 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); + + source_paragraph.state = InstallState::INSTALLED; + write_update(paths, source_paragraph); + status_db->insert(std::make_unique(source_paragraph)); + + for (auto&& feature_paragraph : features_spghs) + { + feature_paragraph.state = InstallState::INSTALLED; + write_update(paths, feature_paragraph); + status_db->insert(std::make_unique(feature_paragraph)); + } + + return InstallResult::SUCCESS; + } + + using Build::BuildResult; + + BuildResult perform_install_plan_action(const VcpkgPaths& paths, + const InstallPlanAction& action, + const Build::BuildPackageOptions& build_package_options, + StatusParagraphs& status_db) + { + const InstallPlanType& plan_type = action.plan_type; + const std::string display_name = action.spec.to_string(); + const std::string display_name_with_features = + GlobalState::feature_packages ? action.displayname() : display_name; + + const bool is_user_requested = action.request_type == RequestType::USER_REQUESTED; + const bool use_head_version = to_bool(build_package_options.use_head_version); + + if (plan_type == InstallPlanType::ALREADY_INSTALLED) + { + if (use_head_version && is_user_requested) + System::println( + System::Color::warning, "Package %s is already installed -- not building from HEAD", display_name); + else + System::println(System::Color::success, "Package %s is already installed", display_name); + return BuildResult::SUCCEEDED; + } + + if (plan_type == InstallPlanType::BUILD_AND_INSTALL) + { + if (use_head_version) + System::println("Building package %s from HEAD... ", display_name_with_features); + else + System::println("Building package %s... ", display_name_with_features); + + const auto result = [&]() -> Build::ExtendedBuildResult { + if (GlobalState::feature_packages) + { + const Build::BuildPackageConfig build_config{ + *action.any_paragraph.source_control_file.value_or_exit(VCPKG_LINE_INFO), + action.spec.triplet(), + paths.port_dir(action.spec), + build_package_options, + action.feature_list}; + return Build::build_package(paths, build_config, status_db); + } + else + { + const Build::BuildPackageConfig build_config{ + action.any_paragraph.source_paragraph.value_or_exit(VCPKG_LINE_INFO), + action.spec.triplet(), + paths.port_dir(action.spec), + build_package_options}; + return Build::build_package(paths, build_config, status_db); + } + }(); + + if (result.code != Build::BuildResult::SUCCEEDED) + { + System::println(System::Color::error, Build::create_error_message(result.code, action.spec)); + return result.code; + } + + System::println("Building package %s... done", display_name_with_features); + + const BinaryControlFile bcf = + Paragraphs::try_load_cached_control_package(paths, action.spec).value_or_exit(VCPKG_LINE_INFO); + System::println("Installing package %s... ", display_name_with_features); + const auto install_result = install_package(paths, bcf, &status_db); + switch (install_result) + { + case InstallResult::SUCCESS: + System::println(System::Color::success, "Installing package %s... done", display_name); + return BuildResult::SUCCEEDED; + case InstallResult::FILE_CONFLICTS: return BuildResult::FILE_CONFLICTS; + default: Checks::unreachable(VCPKG_LINE_INFO); + } + } + + if (plan_type == InstallPlanType::INSTALL) + { + if (use_head_version && is_user_requested) + { + System::println( + System::Color::warning, "Package %s is already built -- not building from HEAD", display_name); + } + System::println("Installing package %s... ", display_name); + const auto install_result = install_package( + paths, action.any_paragraph.binary_control_file.value_or_exit(VCPKG_LINE_INFO), &status_db); + switch (install_result) + { + case InstallResult::SUCCESS: + System::println(System::Color::success, "Installing package %s... done", display_name); + return BuildResult::SUCCEEDED; + case InstallResult::FILE_CONFLICTS: return BuildResult::FILE_CONFLICTS; + default: Checks::unreachable(VCPKG_LINE_INFO); + } + } + + Checks::unreachable(VCPKG_LINE_INFO); + } + + static void print_plan(const std::vector& action_plan, bool is_recursive) + { + std::vector remove_plans; + std::vector rebuilt_plans; + std::vector only_install_plans; + std::vector new_plans; + std::vector already_installed_plans; + + const bool has_non_user_requested_packages = Util::find_if(action_plan, [](const AnyAction& package) -> bool { + if (auto iplan = package.install_plan.get()) + return iplan->request_type != RequestType::USER_REQUESTED; + else + return false; + }) != action_plan.cend(); + + for (auto&& action : action_plan) + { + if (auto install_action = action.install_plan.get()) + { + // remove plans are guaranteed to come before install plans, so we know the plan will be contained if at + // all. + auto it = Util::find_if( + remove_plans, [&](const RemovePlanAction* plan) { return plan->spec == install_action->spec; }); + if (it != remove_plans.end()) + { + rebuilt_plans.emplace_back(install_action); + } + else + { + switch (install_action->plan_type) + { + case InstallPlanType::INSTALL: only_install_plans.emplace_back(install_action); break; + case InstallPlanType::ALREADY_INSTALLED: + if (install_action->request_type == RequestType::USER_REQUESTED) + already_installed_plans.emplace_back(install_action); + break; + case InstallPlanType::BUILD_AND_INSTALL: new_plans.emplace_back(install_action); break; + default: Checks::unreachable(VCPKG_LINE_INFO); + } + } + } + else if (auto remove_action = action.remove_plan.get()) + { + remove_plans.emplace_back(remove_action); + } + } + + std::sort(remove_plans.begin(), remove_plans.end(), &RemovePlanAction::compare_by_name); + std::sort(rebuilt_plans.begin(), rebuilt_plans.end(), &InstallPlanAction::compare_by_name); + std::sort(only_install_plans.begin(), only_install_plans.end(), &InstallPlanAction::compare_by_name); + std::sort(new_plans.begin(), new_plans.end(), &InstallPlanAction::compare_by_name); + std::sort(already_installed_plans.begin(), already_installed_plans.end(), &InstallPlanAction::compare_by_name); + + if (already_installed_plans.size() > 0) + { + const std::string already_string = + Strings::join("\n", already_installed_plans, [](const InstallPlanAction* p) { + return to_output_string(p->request_type, p->displayname()); + }); + System::println("The following packages are already installed:\n%s", already_string); + } + + if (rebuilt_plans.size() > 0) + { + const std::string rebuilt_string = Strings::join("\n", rebuilt_plans, [](const InstallPlanAction* p) { + return to_output_string(p->request_type, p->displayname()); + }); + System::println("The following packages will be rebuilt:\n%s", rebuilt_string); + } + + if (new_plans.size() > 0) + { + const std::string new_string = Strings::join("\n", new_plans, [](const InstallPlanAction* p) { + return to_output_string(p->request_type, p->displayname()); + }); + System::println("The following packages will be built and installed:\n%s", new_string); + } + + if (only_install_plans.size() > 0) + { + const std::string only_install_string = + Strings::join("\n", only_install_plans, [](const InstallPlanAction* p) { + return to_output_string(p->request_type, p->displayname()); + }); + System::println("The following packages will be directly installed:\n%s", only_install_string); + } + + if (has_non_user_requested_packages) + System::println("Additional packages (*) will be installed to complete this operation."); + + if (remove_plans.size() > 0 && !is_recursive) + { + System::println(System::Color::warning, + "If you are sure you want to rebuild the above packages, run the command with the " + "--recurse option"); + Checks::exit_fail(VCPKG_LINE_INFO); + } + } + + void perform_and_exit_ex(const std::vector& action_plan, + const Build::BuildPackageOptions& install_plan_options, + const KeepGoing keep_going, + const PrintSummary print_summary, + const VcpkgPaths& paths, + StatusParagraphs& status_db) + { + std::vector results; + std::vector timing; + const auto timer = Chrono::ElapsedTime::create_started(); + size_t counter = 0; + const size_t package_count = action_plan.size(); + + for (const auto& action : action_plan) + { + const auto build_timer = Chrono::ElapsedTime::create_started(); + counter++; + + const std::string display_name = action.spec().to_string(); + System::println("Starting package %d/%d: %s", counter, package_count, display_name); + + timing.push_back("0"); + results.push_back(BuildResult::NULLVALUE); + + if (const auto install_action = action.install_plan.get()) + { + const BuildResult result = + perform_install_plan_action(paths, *install_action, install_plan_options, status_db); + if (result != BuildResult::SUCCEEDED && keep_going == KeepGoing::NO) + { + System::println(Build::create_user_troubleshooting_message(install_action->spec)); + Checks::exit_fail(VCPKG_LINE_INFO); + } + + results.back() = result; + } + else if (const auto remove_action = action.remove_plan.get()) + { + Checks::check_exit(VCPKG_LINE_INFO, GlobalState::feature_packages); + Remove::perform_remove_plan_action(paths, *remove_action, Remove::Purge::YES, status_db); + } + else + { + Checks::unreachable(VCPKG_LINE_INFO); + } + + timing.back() = build_timer.to_string(); + System::println("Elapsed time for package %s: %s", display_name, build_timer.to_string()); + } + + System::println("Total time taken: %s", timer.to_string()); + + if (print_summary == PrintSummary::YES) + { + for (size_t i = 0; i < results.size(); i++) + { + System::println("%s: %s: %s", action_plan[i].spec(), Build::to_string(results[i]), timing[i]); + } + + std::map summary; + for (const BuildResult& v : Build::BUILD_RESULT_VALUES) + { + summary[v] = 0; + } + + for (const BuildResult& r : results) + { + summary[r]++; + } + + System::println("\n\nSUMMARY"); + for (const std::pair& entry : summary) + { + System::println(" %s: %d", Build::to_string(entry.first), entry.second); + } + } + + Checks::exit_success(VCPKG_LINE_INFO); + } + + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) + { + static const std::string OPTION_DRY_RUN = "--dry-run"; + static const std::string OPTION_USE_HEAD_VERSION = "--head"; + static const std::string OPTION_NO_DOWNLOADS = "--no-downloads"; + static const std::string OPTION_RECURSE = "--recurse"; + static const std::string OPTION_KEEP_GOING = "--keep-going"; + + // input sanitization + static const std::string EXAMPLE = Help::create_example_string("install zlib zlib:x64-windows curl boost"); + args.check_min_arg_count(1, EXAMPLE); + + const std::vector specs = Util::fmap(args.command_arguments, [&](auto&& arg) { + return Input::check_and_get_full_package_spec(arg, default_triplet, EXAMPLE); + }); + + for (auto&& spec : specs) + { + Input::check_triplet(spec.package_spec.triplet(), paths); + if (!spec.features.empty() && !GlobalState::feature_packages) + { + Checks::exit_with_message( + VCPKG_LINE_INFO, "Feature packages are experimentally available under the --featurepackages flag."); + } + } + + const std::unordered_set options = args.check_and_get_optional_command_arguments( + {OPTION_DRY_RUN, OPTION_USE_HEAD_VERSION, OPTION_NO_DOWNLOADS, OPTION_RECURSE, OPTION_KEEP_GOING}); + const bool dry_run = options.find(OPTION_DRY_RUN) != options.cend(); + const bool use_head_version = options.find(OPTION_USE_HEAD_VERSION) != options.cend(); + const bool no_downloads = options.find(OPTION_NO_DOWNLOADS) != options.cend(); + const bool is_recursive = options.find(OPTION_RECURSE) != options.cend(); + const KeepGoing keep_going = to_keep_going(options.find(OPTION_KEEP_GOING) != options.cend()); + + // create the plan + StatusParagraphs status_db = database_load_check(paths); + + const Build::BuildPackageOptions install_plan_options = {Build::to_use_head_version(use_head_version), + Build::to_allow_downloads(!no_downloads)}; + + std::vector action_plan; + + if (GlobalState::feature_packages) + { + std::unordered_map scf_map; + auto all_ports = Paragraphs::load_all_ports(paths.get_filesystem(), paths.ports); + for (auto&& port : all_ports) + { + scf_map[port->core_paragraph->name] = std::move(*port); + } + action_plan = create_feature_install_plan(scf_map, FullPackageSpec::to_feature_specs(specs), status_db); + } + else + { + Dependencies::PathsPortFile paths_port_file(paths); + auto install_plan = Dependencies::create_install_plan( + paths_port_file, Util::fmap(specs, [](auto&& spec) { return spec.package_spec; }), status_db); + + action_plan = Util::fmap( + install_plan, [](InstallPlanAction& install_action) { return AnyAction(std::move(install_action)); }); + } + + // install plan will be empty if it is already installed - need to change this at status paragraph part + Checks::check_exit(VCPKG_LINE_INFO, !action_plan.empty(), "Install plan cannot be empty"); + + // log the plan + const std::string specs_string = Strings::join(",", action_plan, [](const AnyAction& action) { + if (auto iaction = action.install_plan.get()) + return iaction->spec.to_string(); + else if (auto raction = action.remove_plan.get()) + return "R$" + raction->spec.to_string(); + Checks::unreachable(VCPKG_LINE_INFO); + }); + + Metrics::g_metrics.lock()->track_property("installplan", specs_string); + + print_plan(action_plan, is_recursive); + + if (dry_run) + { + Checks::exit_success(VCPKG_LINE_INFO); + } + + perform_and_exit_ex(action_plan, install_plan_options, keep_going, PrintSummary::NO, paths, status_db); + + Checks::exit_success(VCPKG_LINE_INFO); + } +} diff --git a/toolsrc/src/vcpkg/metrics.cpp b/toolsrc/src/vcpkg/metrics.cpp new file mode 100644 index 000000000..84c1ee208 --- /dev/null +++ b/toolsrc/src/vcpkg/metrics.cpp @@ -0,0 +1,398 @@ +#include "pch.h" + +#include + +#include +#include +#include + +#pragma comment(lib, "version") +#pragma comment(lib, "winhttp") + +namespace vcpkg::Metrics +{ + Util::LockGuarded g_metrics; + + static std::string get_current_date_time() + { + struct tm newtime; + std::array date; + date.fill(0); + + struct _timeb timebuffer; + + _ftime_s(&timebuffer); + time_t now = timebuffer.time; + const int milli = timebuffer.millitm; + + const errno_t err = gmtime_s(&newtime, &now); + if (err) + { + return Strings::EMPTY; + } + + strftime(&date[0], date.size(), "%Y-%m-%dT%H:%M:%S", &newtime); + return std::string(&date[0]) + "." + std::to_string(milli) + "Z"; + } + + static std::string generate_random_UUID() + { + int part_sizes[] = {8, 4, 4, 4, 12}; + char uuid[37]; + memset(uuid, 0, sizeof(uuid)); + int num; + srand(static_cast(time(nullptr))); + int index = 0; + for (int part = 0; part < 5; part++) + { + if (part > 0) + { + uuid[index] = '-'; + index++; + } + + // Generating UUID format version 4 + // http://en.wikipedia.org/wiki/Universally_unique_identifier + for (int i = 0; i < part_sizes[part]; i++, index++) + { + if (part == 2 && i == 0) + { + num = 4; + } + else if (part == 4 && i == 0) + { + num = (rand() % 4) + 8; + } + else + { + num = rand() % 16; + } + + if (num < 10) + { + uuid[index] = static_cast('0' + num); + } + else + { + uuid[index] = static_cast('a' + (num - 10)); + } + } + } + + return uuid; + } + + static const std::string& get_session_id() + { + static const std::string ID = generate_random_UUID(); + return ID; + } + + static std::string to_json_string(const std::string& str) + { + std::string encoded = "\""; + for (auto&& ch : str) + { + if (ch == '\\') + { + encoded.append("\\\\"); + } + else if (ch == '"') + { + encoded.append("\\\""); + } + else if (ch < 0x20 || ch >= 0x80) + { + // Note: this treats incoming Strings as Latin-1 + static constexpr const char HEX[16] = { + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; + encoded.append("\\u00"); + encoded.push_back(HEX[ch / 16]); + encoded.push_back(HEX[ch % 16]); + } + else + { + encoded.push_back(ch); + } + } + encoded.push_back('"'); + return encoded; + } + + static std::string get_os_version_string() + { + std::wstring path; + path.resize(MAX_PATH); + const auto n = GetSystemDirectoryW(&path[0], static_cast(path.size())); + path.resize(n); + path += L"\\kernel32.dll"; + + const auto versz = GetFileVersionInfoSizeW(path.c_str(), nullptr); + if (versz == 0) return Strings::EMPTY; + + std::vector verbuf; + verbuf.resize(versz); + + if (!GetFileVersionInfoW(path.c_str(), 0, static_cast(verbuf.size()), &verbuf[0])) return Strings::EMPTY; + + void* rootblock; + UINT rootblocksize; + if (!VerQueryValueW(&verbuf[0], L"\\", &rootblock, &rootblocksize)) return Strings::EMPTY; + + auto rootblock_ffi = static_cast(rootblock); + + return Strings::format("%d.%d.%d", + static_cast(HIWORD(rootblock_ffi->dwProductVersionMS)), + static_cast(LOWORD(rootblock_ffi->dwProductVersionMS)), + static_cast(HIWORD(rootblock_ffi->dwProductVersionLS))); + } + + struct MetricMessage + { + std::string user_id = generate_random_UUID(); + std::string user_timestamp; + std::string timestamp = get_current_date_time(); + std::string properties; + std::string measurements; + + void track_property(const std::string& name, const std::string& value) + { + if (properties.size() != 0) properties.push_back(','); + properties.append(to_json_string(name)); + properties.push_back(':'); + properties.append(to_json_string(value)); + } + + void track_metric(const std::string& name, double value) + { + if (measurements.size() != 0) measurements.push_back(','); + measurements.append(to_json_string(name)); + measurements.push_back(':'); + measurements.append(std::to_string(value)); + } + + std::string format_event_data_template() const + { + const std::string& session_id = get_session_id(); + return Strings::format(R"([{ + "ver": 1, + "name": "Microsoft.ApplicationInsights.Event", + "time": "%s", + "sampleRate": 100.000000, + "seq": "0:0", + "iKey": "b4e88960-4393-4dd9-ab8e-97e8fe6d7603", + "flags": 0.000000, + "tags": { + "ai.device.os": "Windows", + "ai.device.osVersion": "%s", + "ai.session.id": "%s", + "ai.user.id": "%s", + "ai.user.accountAcquisitionDate": "%s" + }, + "data": { + "baseType": "EventData", + "baseData": { + "ver": 2, + "name": "commandline_test7", + "properties": { %s }, + "measurements": { %s } + } + } +}])", + timestamp, + get_os_version_string(), + session_id, + user_id, + user_timestamp, + properties, + measurements); + } + }; + + static MetricMessage g_metricmessage; + static bool g_should_send_metrics = +#if defined(NDEBUG) && (DISABLE_METRICS == 0) + true +#else + false +#endif + ; + static bool g_should_print_metrics = false; + + bool get_compiled_metrics_enabled() { return DISABLE_METRICS == 0; } + + std::wstring get_SQM_user() + { + auto hkcu_sqmclient = + System::get_registry_string(HKEY_CURRENT_USER, LR"(Software\Microsoft\SQMClient)", L"UserId"); + return hkcu_sqmclient.value_or(L"{}"); + } + + void Metrics::set_user_information(const std::string& user_id, const std::string& first_use_time) + { + g_metricmessage.user_id = user_id; + g_metricmessage.user_timestamp = first_use_time; + } + + void Metrics::init_user_information(std::string& user_id, std::string& first_use_time) + { + user_id = generate_random_UUID(); + first_use_time = get_current_date_time(); + } + + void Metrics::set_send_metrics(bool should_send_metrics) { g_should_send_metrics = should_send_metrics; } + + void Metrics::set_print_metrics(bool should_print_metrics) { g_should_print_metrics = should_print_metrics; } + + void Metrics::track_metric(const std::string& name, double value) { g_metricmessage.track_metric(name, value); } + + void Metrics::track_property(const std::string& name, const std::wstring& value) + { + // Note: this is not valid UTF-16 -> UTF-8, it just yields a close enough approximation for our purposes. + std::string converted_value; + converted_value.resize(value.size()); + std::transform( + value.begin(), value.end(), converted_value.begin(), [](wchar_t ch) { return static_cast(ch); }); + + g_metricmessage.track_property(name, converted_value); + } + + void Metrics::track_property(const std::string& name, const std::string& value) + { + g_metricmessage.track_property(name, value); + } + + void Metrics::upload(const std::string& payload) + { + HINTERNET connect = nullptr, request = nullptr; + BOOL results = FALSE; + + const HINTERNET session = WinHttpOpen( + L"vcpkg/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); + if (session) connect = WinHttpConnect(session, L"dc.services.visualstudio.com", INTERNET_DEFAULT_HTTPS_PORT, 0); + + if (connect) + request = WinHttpOpenRequest(connect, + L"POST", + L"/v2/track", + nullptr, + WINHTTP_NO_REFERER, + WINHTTP_DEFAULT_ACCEPT_TYPES, + WINHTTP_FLAG_SECURE); + + if (request) + { + if (MAXDWORD <= payload.size()) abort(); + std::wstring hdrs = L"Content-Type: application/json\r\n"; + std::string& p = const_cast(payload); + results = WinHttpSendRequest(request, + hdrs.c_str(), + static_cast(hdrs.size()), + static_cast(&p[0]), + static_cast(payload.size()), + static_cast(payload.size()), + 0); + } + + if (results) + { + results = WinHttpReceiveResponse(request, nullptr); + } + + DWORD http_code = 0, junk = sizeof(DWORD); + + if (results) + { + results = WinHttpQueryHeaders(request, + WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, + nullptr, + &http_code, + &junk, + WINHTTP_NO_HEADER_INDEX); + } + + std::vector response_buffer; + if (results) + { + DWORD available_data = 0, read_data = 0, total_data = 0; + while ((results = WinHttpQueryDataAvailable(request, &available_data)) == TRUE && available_data > 0) + { + response_buffer.resize(response_buffer.size() + available_data); + + results = WinHttpReadData(request, &response_buffer.data()[total_data], available_data, &read_data); + + if (!results) + { + break; + } + + total_data += read_data; + + response_buffer.resize(total_data); + } + } + + if (!results) + { +#ifndef NDEBUG + __debugbreak(); + auto err = GetLastError(); + std::cerr << "[DEBUG] failed to connect to server: " << err << "\n"; +#endif + } + + if (request) WinHttpCloseHandle(request); + if (connect) WinHttpCloseHandle(connect); + if (session) WinHttpCloseHandle(session); + } + + static fs::path get_bindir() + { + wchar_t buf[_MAX_PATH]; + const int bytes = GetModuleFileNameW(nullptr, buf, _MAX_PATH); + if (bytes == 0) std::abort(); + return fs::path(buf, buf + bytes); + } + + void Metrics::flush() + { + const std::string payload = g_metricmessage.format_event_data_template(); + if (g_should_print_metrics) std::cerr << payload << "\n"; + if (!g_should_send_metrics) return; + + // upload(payload); + + wchar_t temp_folder[MAX_PATH]; + GetTempPathW(MAX_PATH, temp_folder); + + 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]() -> fs::path { + auto vcpkgdir = get_bindir().parent_path(); + auto path = vcpkgdir / "vcpkgmetricsuploader.exe"; + if (fs.exists(path)) return path; + + path = vcpkgdir / "scripts" / "vcpkgmetricsuploader.exe"; + if (fs.exists(path)) return path; + + return Strings::WEMPTY; + }(); + + std::error_code 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"); + fs.write_contents(vcpkg_metrics_txt_path, payload); + + const std::wstring cmd_line = + Strings::wformat(L"start %s %s", temp_folder_path_exe.native(), vcpkg_metrics_txt_path.native()); + System::cmd_execute_clean(cmd_line); + } +} diff --git a/toolsrc/src/vcpkg/packagespec.cpp b/toolsrc/src/vcpkg/packagespec.cpp new file mode 100644 index 000000000..01a09618d --- /dev/null +++ b/toolsrc/src/vcpkg/packagespec.cpp @@ -0,0 +1,175 @@ +#include "pch.h" + +#include +#include +#include + +using vcpkg::Parse::parse_comma_list; + +namespace vcpkg +{ + static bool is_valid_package_spec_char(char c) + { + return (c == '-') || isdigit(c) || (isalpha(c) && islower(c)) || (c == '[') || (c == ']'); + } + + std::string FeatureSpec::to_string() const + { + if (feature().empty()) return spec().to_string(); + return Strings::format("%s[%s]:%s", name(), feature(), triplet()); + } + + std::vector FeatureSpec::from_strings_and_triplet(const std::vector& depends, + const Triplet& triplet) + { + std::vector f_specs; + for (auto&& depend : depends) + { + auto maybe_spec = ParsedSpecifier::from_string(depend); + if (auto spec = maybe_spec.get()) + { + Checks::check_exit(VCPKG_LINE_INFO, + spec->triplet.empty(), + "error: triplets cannot currently be specified in this context: %s", + depend); + PackageSpec pspec = + PackageSpec::from_name_and_triplet(spec->name, triplet).value_or_exit(VCPKG_LINE_INFO); + + for (auto&& feature : spec->features) + f_specs.push_back(FeatureSpec{pspec, feature}); + + if (spec->features.empty()) f_specs.push_back(FeatureSpec{pspec, Strings::EMPTY}); + } + else + { + Checks::exit_with_message(VCPKG_LINE_INFO, + "error while parsing feature list: %s: %s", + vcpkg::to_string(maybe_spec.error()), + depend); + } + } + return f_specs; + } + + std::vector FullPackageSpec::to_feature_specs(const std::vector& specs) + { + std::vector ret; + for (auto&& spec : specs) + { + ret.emplace_back(spec.package_spec, Strings::EMPTY); + for (auto&& feature : spec.features) + ret.emplace_back(spec.package_spec, feature); + } + return ret; + } + + ExpectedT FullPackageSpec::from_string(const std::string& spec_as_string, + const Triplet& default_triplet) + { + auto res = ParsedSpecifier::from_string(spec_as_string); + if (auto p = res.get()) + { + FullPackageSpec fspec; + Triplet t = p->triplet.empty() ? default_triplet : Triplet::from_canonical_name(p->triplet); + fspec.package_spec = PackageSpec::from_name_and_triplet(p->name, t).value_or_exit(VCPKG_LINE_INFO); + fspec.features = std::move(p->features); + return fspec; + } + return res.error(); + } + + ExpectedT PackageSpec::from_name_and_triplet(const std::string& name, + const Triplet& triplet) + { + if (Util::find_if_not(name, is_valid_package_spec_char) != name.end()) + { + return PackageSpecParseResult::INVALID_CHARACTERS; + } + + PackageSpec p; + p.m_name = name; + p.m_triplet = triplet; + return p; + } + + const std::string& PackageSpec::name() const { return this->m_name; } + + const Triplet& PackageSpec::triplet() const { return this->m_triplet; } + + std::string PackageSpec::dir() const { return Strings::format("%s_%s", this->m_name, this->m_triplet); } + + std::string PackageSpec::to_string() const { return Strings::format("%s:%s", this->name(), this->triplet()); } + + bool operator==(const PackageSpec& left, const PackageSpec& right) + { + return left.name() == right.name() && left.triplet() == right.triplet(); + } + + bool operator!=(const PackageSpec& left, const PackageSpec& right) { return !(left == right); } + + ExpectedT ParsedSpecifier::from_string(const std::string& input) + { + auto pos = input.find(':'); + auto pos_l_bracket = input.find('['); + auto pos_r_bracket = input.find(']'); + + ParsedSpecifier f; + if (pos == std::string::npos && pos_l_bracket == std::string::npos) + { + f.name = input; + return f; + } + else if (pos == std::string::npos) + { + if (pos_r_bracket == std::string::npos || pos_l_bracket >= pos_r_bracket) + { + return PackageSpecParseResult::INVALID_CHARACTERS; + } + const std::string name = input.substr(0, pos_l_bracket); + f.name = name; + f.features = parse_comma_list(input.substr(pos_l_bracket + 1, pos_r_bracket - pos_l_bracket - 1)); + return f; + } + else if (pos_l_bracket == std::string::npos && pos_r_bracket == std::string::npos) + { + const std::string name = input.substr(0, pos); + f.triplet = input.substr(pos + 1); + f.name = name; + } + else + { + if (pos_r_bracket == std::string::npos || pos_l_bracket >= pos_r_bracket) + { + return PackageSpecParseResult::INVALID_CHARACTERS; + } + const std::string name = input.substr(0, pos_l_bracket); + f.features = parse_comma_list(input.substr(pos_l_bracket + 1, pos_r_bracket - pos_l_bracket - 1)); + f.triplet = input.substr(pos + 1); + f.name = name; + } + + auto pos2 = input.find(':', pos + 1); + if (pos2 != std::string::npos) + { + return PackageSpecParseResult::TOO_MANY_COLONS; + } + return f; + } + + ExpectedT Features::from_string(const std::string& name) + { + auto maybe_spec = ParsedSpecifier::from_string(name); + if (auto spec = maybe_spec.get()) + { + Checks::check_exit( + VCPKG_LINE_INFO, spec->triplet.empty(), "error: triplet not allowed in specifier: %s", name); + + Features f; + f.name = spec->name; + f.features = spec->features; + return f; + } + + return maybe_spec.error(); + } +} diff --git a/toolsrc/src/vcpkg/packagespecparseresult.cpp b/toolsrc/src/vcpkg/packagespecparseresult.cpp new file mode 100644 index 000000000..b12bd12d0 --- /dev/null +++ b/toolsrc/src/vcpkg/packagespecparseresult.cpp @@ -0,0 +1,21 @@ +#include "pch.h" + +#include + +#include + +namespace vcpkg +{ + CStringView to_string(PackageSpecParseResult ev) noexcept + { + switch (ev) + { + case PackageSpecParseResult::SUCCESS: return "OK"; + case PackageSpecParseResult::TOO_MANY_COLONS: return "Too many colons"; + case PackageSpecParseResult::INVALID_CHARACTERS: + return "Contains invalid characters. Only alphanumeric lowercase ASCII characters and dashes are " + "allowed"; + default: Checks::unreachable(VCPKG_LINE_INFO); + } + } +} diff --git a/toolsrc/src/vcpkg/paragraphparseresult.cpp b/toolsrc/src/vcpkg/paragraphparseresult.cpp new file mode 100644 index 000000000..920a4b16b --- /dev/null +++ b/toolsrc/src/vcpkg/paragraphparseresult.cpp @@ -0,0 +1,34 @@ +#include "pch.h" + +#include +#include + +namespace vcpkg +{ + const char* ParagraphParseResultCategoryImpl::name() const noexcept { return "ParagraphParseResult"; } + + std::string ParagraphParseResultCategoryImpl::message(int ev) const noexcept + { + switch (static_cast(ev)) + { + case ParagraphParseResult::SUCCESS: return "OK"; + case ParagraphParseResult::EXPECTED_ONE_PARAGRAPH: return "There should be exactly one paragraph"; + default: Checks::unreachable(VCPKG_LINE_INFO); + } + } + + const std::error_category& paragraph_parse_result_category() + { + static ParagraphParseResultCategoryImpl instance; + return instance; + } + + std::error_code make_error_code(ParagraphParseResult e) + { + return std::error_code(static_cast(e), paragraph_parse_result_category()); + } + + ParagraphParseResult to_paragraph_parse_result(int i) { return static_cast(i); } + + ParagraphParseResult to_paragraph_parse_result(std::error_code ec) { return to_paragraph_parse_result(ec.value()); } +} diff --git a/toolsrc/src/vcpkg/paragraphs.cpp b/toolsrc/src/vcpkg/paragraphs.cpp new file mode 100644 index 000000000..b93de190c --- /dev/null +++ b/toolsrc/src/vcpkg/paragraphs.cpp @@ -0,0 +1,304 @@ +#include "pch.h" + +#include +#include +#include +#include +#include + +using namespace vcpkg::Parse; + +namespace vcpkg::Paragraphs +{ + struct Parser + { + Parser(const char* c, const char* e) : cur(c), end(e) {} + + private: + const char* cur; + const char* const end; + + void peek(char& ch) const + { + if (cur == end) + ch = 0; + else + ch = *cur; + } + + void next(char& ch) + { + if (cur == end) + ch = 0; + else + { + ++cur; + peek(ch); + } + } + + void skip_comment(char& ch) + { + while (ch != '\r' && ch != '\n' && ch != '\0') + next(ch); + if (ch == '\r') next(ch); + if (ch == '\n') next(ch); + } + + void skip_spaces(char& ch) + { + while (ch == ' ' || ch == '\t') + next(ch); + } + + static bool is_alphanum(char ch) + { + return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9'); + } + + static bool is_comment(char ch) { return (ch == '#'); } + + static bool is_lineend(char ch) { return ch == '\r' || ch == '\n' || ch == 0; } + + void get_fieldvalue(char& ch, std::string& fieldvalue) + { + fieldvalue.clear(); + + auto beginning_of_line = cur; + do + { + // scan to end of current line (it is part of the field value) + while (!is_lineend(ch)) + next(ch); + + fieldvalue.append(beginning_of_line, cur); + + if (ch == '\r') next(ch); + if (ch == '\n') next(ch); + + if (is_alphanum(ch) || is_comment(ch)) + { + // Line begins a new field. + return; + } + + beginning_of_line = cur; + + // Line may continue the current field with data or terminate the paragraph, + // depending on first nonspace character. + skip_spaces(ch); + + if (is_lineend(ch)) + { + // Line was whitespace or empty. + // This terminates the field and the paragraph. + // We leave the blank line's whitespace consumed, because it doesn't matter. + return; + } + + // First nonspace is not a newline. This continues the current field value. + // We forcibly convert all newlines into single '\n' for ease of text handling later on. + fieldvalue.push_back('\n'); + } while (true); + } + + void get_fieldname(char& ch, std::string& fieldname) + { + auto begin_fieldname = cur; + while (is_alphanum(ch) || ch == '-') + next(ch); + Checks::check_exit(VCPKG_LINE_INFO, ch == ':', "Expected ':'"); + fieldname = std::string(begin_fieldname, cur); + + // skip ': ' + next(ch); + skip_spaces(ch); + } + + void get_paragraph(char& ch, std::unordered_map& fields) + { + fields.clear(); + std::string fieldname; + std::string fieldvalue; + do + { + if (is_comment(ch)) + { + skip_comment(ch); + continue; + } + + get_fieldname(ch, fieldname); + + auto it = fields.find(fieldname); + Checks::check_exit(VCPKG_LINE_INFO, it == fields.end(), "Duplicate field"); + + get_fieldvalue(ch, fieldvalue); + + fields.emplace(fieldname, fieldvalue); + } while (!is_lineend(ch)); + } + + public: + std::vector> get_paragraphs() + { + std::vector> paragraphs; + + char ch; + peek(ch); + + while (ch != 0) + { + if (ch == '\n' || ch == '\r' || ch == ' ' || ch == '\t') + { + next(ch); + continue; + } + + paragraphs.emplace_back(); + get_paragraph(ch, paragraphs.back()); + } + + return paragraphs; + } + }; + + Expected> get_single_paragraph(const Files::Filesystem& fs, + const fs::path& control_path) + { + const Expected contents = fs.read_contents(control_path); + if (auto spgh = contents.get()) + { + return parse_single_paragraph(*spgh); + } + + return contents.error(); + } + + Expected>> get_paragraphs(const Files::Filesystem& fs, + const fs::path& control_path) + { + const Expected contents = fs.read_contents(control_path); + if (auto spgh = contents.get()) + { + return parse_paragraphs(*spgh); + } + + return contents.error(); + } + + Expected> parse_single_paragraph(const std::string& str) + { + const std::vector> p = + Parser(str.c_str(), str.c_str() + str.size()).get_paragraphs(); + + if (p.size() == 1) + { + return p.at(0); + } + + return std::error_code(ParagraphParseResult::EXPECTED_ONE_PARAGRAPH); + } + + Expected>> parse_paragraphs(const std::string& str) + { + return Parser(str.c_str(), str.c_str() + str.size()).get_paragraphs(); + } + + ParseExpected try_load_port(const Files::Filesystem& fs, const fs::path& path) + { + Expected>> pghs = get_paragraphs(fs, path / "CONTROL"); + if (auto vector_pghs = pghs.get()) + { + auto csf = SourceControlFile::parse_control_file(std::move(*vector_pghs)); + if (!GlobalState::feature_packages) + { + if (auto ptr = csf.get()) + { + Checks::check_exit(VCPKG_LINE_INFO, ptr->get() != nullptr); + ptr->get()->core_paragraph->default_features.clear(); + ptr->get()->feature_paragraphs.clear(); + } + } + return csf; + } + auto error_info = std::make_unique(); + error_info->name = path.filename().generic_u8string(); + error_info->error = pghs.error(); + return error_info; + } + + Expected try_load_cached_control_package(const VcpkgPaths& paths, const PackageSpec& spec) + { + Expected>> pghs = + get_paragraphs(paths.get_filesystem(), paths.package_dir(spec) / "CONTROL"); + + if (auto p = pghs.get()) + { + BinaryControlFile bcf; + bcf.core_paragraph = BinaryParagraph(p->front()); + p->erase(p->begin()); + + bcf.features = + Util::fmap(*p, [&](auto&& raw_feature) -> BinaryParagraph { return BinaryParagraph(raw_feature); }); + + return bcf; + } + + return pghs.error(); + } + + LoadResults try_load_all_ports(const Files::Filesystem& fs, const fs::path& ports_dir) + { + LoadResults ret; + for (auto&& path : fs.get_files_non_recursive(ports_dir)) + { + auto maybe_spgh = try_load_port(fs, path); + if (const auto spgh = maybe_spgh.get()) + { + ret.paragraphs.emplace_back(std::move(*spgh)); + } + else + { + ret.errors.emplace_back(std::move(maybe_spgh).error()); + } + } + return ret; + } + + std::vector> load_all_ports(const Files::Filesystem& fs, + const fs::path& ports_dir) + { + auto results = try_load_all_ports(fs, ports_dir); + if (!results.errors.empty()) + { + if (GlobalState::debugging) + { + print_error_message(results.errors); + } + else + { + for (auto&& error : results.errors) + { + System::println( + System::Color::warning, "Warning: an error occurred while parsing '%s'", error->name); + } + System::println(System::Color::warning, + "Use '--debug' to get more information about the parse failures.\n"); + } + } + return std::move(results.paragraphs); + } + + std::map load_all_port_names_and_versions(const Files::Filesystem& fs, + const fs::path& ports_dir) + { + auto all_ports = load_all_ports(fs, ports_dir); + + std::map names_and_versions; + for (auto&& port : all_ports) + names_and_versions.emplace(port->core_paragraph->name, port->core_paragraph->version); + + return names_and_versions; + } +} diff --git a/toolsrc/src/vcpkg/parse.cpp b/toolsrc/src/vcpkg/parse.cpp new file mode 100644 index 000000000..116a7f5c8 --- /dev/null +++ b/toolsrc/src/vcpkg/parse.cpp @@ -0,0 +1,81 @@ +#include "pch.h" + +#include + +#include +#include + +namespace vcpkg::Parse +{ + static Optional remove_field(std::unordered_map* fields, + const std::string& fieldname) + { + auto it = fields->find(fieldname); + if (it == fields->end()) + { + return nullopt; + } + + const std::string value = std::move(it->second); + fields->erase(it); + return value; + } + + void ParagraphParser::required_field(const std::string& fieldname, std::string& out) + { + auto maybe_field = remove_field(&fields, fieldname); + if (const auto field = maybe_field.get()) + out = std::move(*field); + else + missing_fields.push_back(fieldname); + } + std::string ParagraphParser::optional_field(const std::string& fieldname) const + { + return remove_field(&fields, fieldname).value_or(Strings::EMPTY); + } + std::unique_ptr ParagraphParser::error_info(const std::string& name) const + { + if (!fields.empty() || !missing_fields.empty()) + { + auto err = std::make_unique(); + err->name = name; + err->extra_fields = Util::extract_keys(fields); + err->missing_fields = std::move(missing_fields); + return err; + } + return nullptr; + } + + std::vector parse_comma_list(const std::string& str) + { + if (str.empty()) + { + return {}; + } + + std::vector out; + + size_t cur = 0; + do + { + auto pos = str.find(',', cur); + if (pos == std::string::npos) + { + out.push_back(str.substr(cur)); + break; + } + out.push_back(str.substr(cur, pos - cur)); + + // skip comma and space + ++pos; + if (str[pos] == ' ') + { + ++pos; + } + + cur = pos; + } while (cur != std::string::npos); + + return out; + } +} diff --git a/toolsrc/src/vcpkg/postbuildlint.buildtype.cpp b/toolsrc/src/vcpkg/postbuildlint.buildtype.cpp new file mode 100644 index 000000000..2baaddb5e --- /dev/null +++ b/toolsrc/src/vcpkg/postbuildlint.buildtype.cpp @@ -0,0 +1,70 @@ +#include "pch.h" + +#include +#include + +namespace vcpkg::PostBuildLint +{ + BuildType BuildType::value_of(const ConfigurationType& config, const Build::LinkageType& linkage) + { + if (config == ConfigurationType::DEBUG && linkage == Build::LinkageType::STATIC) + { + return BuildTypeC::DEBUG_STATIC; + } + + if (config == ConfigurationType::DEBUG && linkage == Build::LinkageType::DYNAMIC) + { + return BuildTypeC::DEBUG_DYNAMIC; + } + + if (config == ConfigurationType::RELEASE && linkage == Build::LinkageType::STATIC) + { + return BuildTypeC::RELEASE_STATIC; + } + + if (config == ConfigurationType::RELEASE && linkage == Build::LinkageType::DYNAMIC) + { + return BuildTypeC::RELEASE_DYNAMIC; + } + + Checks::unreachable(VCPKG_LINE_INFO); + } + + const ConfigurationType& BuildType::config() const { return this->m_config; } + + const Build::LinkageType& BuildType::linkage() const { return this->m_linkage; } + + const std::regex& BuildType::crt_regex() const + { + static const std::regex REGEX_DEBUG_STATIC(R"(/DEFAULTLIB:LIBCMTD)", std::regex_constants::icase); + static const std::regex REGEX_DEBUG_DYNAMIC(R"(/DEFAULTLIB:MSVCRTD)", std::regex_constants::icase); + static const std::regex REGEX_RELEASE_STATIC(R"(/DEFAULTLIB:LIBCMT[^D])", std::regex_constants::icase); + static const std::regex REGEX_RELEASE_DYNAMIC(R"(/DEFAULTLIB:MSVCRT[^D])", std::regex_constants::icase); + + switch (backing_enum) + { + case BuildTypeC::DEBUG_STATIC: return REGEX_DEBUG_STATIC; + case BuildTypeC::DEBUG_DYNAMIC: return REGEX_DEBUG_DYNAMIC; + case BuildTypeC::RELEASE_STATIC: return REGEX_RELEASE_STATIC; + case BuildTypeC::RELEASE_DYNAMIC: return REGEX_RELEASE_DYNAMIC; + default: Checks::unreachable(VCPKG_LINE_INFO); + } + } + + const std::string& BuildType::to_string() const + { + static const std::string NAME_DEBUG_STATIC("Debug,Static"); + static const std::string NAME_DEBUG_DYNAMIC("Debug,Dynamic"); + static const std::string NAME_RELEASE_STATIC("Release,Static"); + static const std::string NAME_RELEASE_DYNAMIC("Release,Dynamic"); + + switch (backing_enum) + { + case BuildTypeC::DEBUG_STATIC: return NAME_DEBUG_STATIC; + case BuildTypeC::DEBUG_DYNAMIC: return NAME_DEBUG_DYNAMIC; + case BuildTypeC::RELEASE_STATIC: return NAME_RELEASE_STATIC; + case BuildTypeC::RELEASE_DYNAMIC: return NAME_RELEASE_DYNAMIC; + default: Checks::unreachable(VCPKG_LINE_INFO); + } + } +} diff --git a/toolsrc/src/vcpkg/postbuildlint.cpp b/toolsrc/src/vcpkg/postbuildlint.cpp new file mode 100644 index 000000000..5f55249df --- /dev/null +++ b/toolsrc/src/vcpkg/postbuildlint.cpp @@ -0,0 +1,846 @@ +#include "pch.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using vcpkg::Build::BuildInfo; +using vcpkg::Build::BuildPolicy; +using vcpkg::Build::PreBuildInfo; + +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, + ERROR_DETECTED = 1 + }; + + struct OutdatedDynamicCrt + { + std::string name; + std::regex regex; + + OutdatedDynamicCrt(const std::string& name, const std::string& regex_as_string) + : name(name), regex(std::regex(regex_as_string, std::regex_constants::icase)) + { + } + }; + + Span get_outdated_dynamic_crts(CStringView toolset) + { + static const std::vector V_NO_MSVCRT = { + {"msvcp100.dll", R"(msvcp100\.dll)"}, + {"msvcp100d.dll", R"(msvcp100d\.dll)"}, + {"msvcp110.dll", R"(msvcp110\.dll)"}, + {"msvcp110_win.dll", R"(msvcp110_win\.dll)"}, + {"msvcp120.dll", R"(msvcp120\.dll)"}, + {"msvcp120_clr0400.dll", R"(msvcp120_clr0400\.dll)"}, + {"msvcp60.dll", R"(msvcp60\.dll)"}, + {"msvcp60.dll", R"(msvcp60\.dll)"}, + + {"msvcr100.dll", R"(msvcr100\.dll)"}, + {"msvcr100d.dll", R"(msvcr100d\.dll)"}, + {"msvcr100_clr0400.dll", R"(msvcr100_clr0400\.dll)"}, + {"msvcr110.dll", R"(msvcr110\.dll)"}, + {"msvcr120.dll", R"(msvcr120\.dll)"}, + {"msvcr120_clr0400.dll", R"(msvcr120_clr0400\.dll)"}, + {"msvcrt20.dll", R"(msvcrt20\.dll)"}, + {"msvcrt40.dll", R"(msvcrt40\.dll)"}}; + + return V_NO_MSVCRT; + } + + static LintStatus check_for_files_in_include_directory(const Files::Filesystem& fs, + const Build::BuildPolicies& policies, + const fs::path& package_dir) + { + if (policies.is_enabled(BuildPolicy::EMPTY_INCLUDE_FOLDER)) + { + return LintStatus::SUCCESS; + } + + const fs::path include_dir = package_dir / "include"; + 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; + } + + return LintStatus::SUCCESS; + } + + 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 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()) + { + System::println(System::Color::warning, + "Include files should not be duplicated into the /debug/include directory. If this cannot " + "be disabled in the project cmake, use\n" + " file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/debug/include)"); + return LintStatus::ERROR_DETECTED; + } + + return LintStatus::SUCCESS; + } + + 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)) + { + 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)"); + return LintStatus::ERROR_DETECTED; + } + + return LintStatus::SUCCESS; + } + + 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)) + { + 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 Files::Filesystem& fs, + const fs::path& package_dir, + const PackageSpec& spec) + { + std::vector dirs = { + package_dir / "cmake", + package_dir / "debug" / "cmake", + package_dir / "lib" / "cmake", + package_dir / "debug" / "lib" / "cmake", + }; + + std::vector 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()) + { + System::println( + System::Color::warning, + "The following cmake files were found outside /share/%s. Please place cmake files in /share/%s.", + spec.name(), + spec.name()); + Files::print_paths(misplaced_cmake_files); + return LintStatus::ERROR_DETECTED; + } + + return LintStatus::SUCCESS; + } + + 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)) + { + 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_dir(const Files::Filesystem& fs, const fs::path& package_dir) + { + std::vector 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 or /debug/lib. Please move them to /bin or " + "/debug/bin, respectively."); + Files::print_paths(dlls); + return LintStatus::ERROR_DETECTED; + } + + return LintStatus::SUCCESS; + } + + 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)) + { + return LintStatus::SUCCESS; + } + const fs::path current_buildtrees_dir = paths.buildtrees / spec.name(); + const fs::path current_buildtrees_dir_src = current_buildtrees_dir / "src"; + + std::vector potential_copyright_files; + // 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 (!fs.is_directory(src_dir)) continue; + + for (auto&& src_file : fs.get_files_non_recursive(src_dir)) + { + 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()); + 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]; + const fs::path relative_path = found_file.string().erase( + 0, current_buildtrees_dir.string().size() + 1); // The +1 is needed to remove the "/" + 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()); + } + 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); + } + return LintStatus::ERROR_DETECTED; + } + + static LintStatus check_for_exes(const Files::Filesystem& fs, const fs::path& package_dir) + { + std::vector 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 or /debug/bin. EXEs are not valid distribution targets."); + Files::print_paths(exes); + return LintStatus::ERROR_DETECTED; + } + + return LintStatus::SUCCESS; + } + + static LintStatus check_exports_of_dlls(const std::vector& dlls, const fs::path& dumpbin_exe) + { + std::vector dlls_with_no_exports; + for (const fs::path& dll : dlls) + { + const std::wstring cmd_line = + Strings::wformat(LR"("%s" /exports "%s")", dumpbin_exe.native(), dll.native()); + System::ExitCodeAndOutput ec_data = System::cmd_execute_and_capture_output(cmd_line); + Checks::check_exit(VCPKG_LINE_INFO, + ec_data.exit_code == 0, + "Running command:\n %s\n failed", + Strings::to_utf8(cmd_line)); + + if (ec_data.output.find("ordinal hint RVA name") == std::string::npos) + { + dlls_with_no_exports.push_back(dll); + } + } + + if (!dlls_with_no_exports.empty()) + { + System::println(System::Color::warning, "The following DLLs have no exports:"); + Files::print_paths(dlls_with_no_exports); + System::println(System::Color::warning, "DLLs without any exports are likely a bug in the build script."); + return LintStatus::ERROR_DETECTED; + } + + return LintStatus::SUCCESS; + } + + static LintStatus check_uwp_bit_of_dlls(const std::string& expected_system_name, + const std::vector& dlls, + const fs::path dumpbin_exe) + { + if (expected_system_name != "WindowsStore") + { + return LintStatus::SUCCESS; + } + + std::vector dlls_with_improper_uwp_bit; + for (const fs::path& dll : dlls) + { + const std::wstring cmd_line = + Strings::wformat(LR"("%s" /headers "%s")", dumpbin_exe.native(), dll.native()); + System::ExitCodeAndOutput ec_data = System::cmd_execute_and_capture_output(cmd_line); + Checks::check_exit(VCPKG_LINE_INFO, + ec_data.exit_code == 0, + "Running command:\n %s\n failed", + Strings::to_utf8(cmd_line)); + + if (ec_data.output.find("App Container") == std::string::npos) + { + dlls_with_improper_uwp_bit.push_back(dll); + } + } + + if (!dlls_with_improper_uwp_bit.empty()) + { + System::println(System::Color::warning, "The following DLLs do not have the App Container bit set:"); + Files::print_paths(dlls_with_improper_uwp_bit); + System::println(System::Color::warning, "This bit is required for Windows Store apps."); + return LintStatus::ERROR_DETECTED; + } + + return LintStatus::SUCCESS; + } + + struct FileAndArch + { + fs::path file; + std::string actual_arch; + }; + + static std::string get_actual_architecture(const MachineType& machine_type) + { + switch (machine_type) + { + case MachineType::AMD64: + case MachineType::IA64: return "x64"; + case MachineType::I386: return "x86"; + case MachineType::ARM: + case MachineType::ARMNT: return "arm"; + default: return "Machine Type Code = " + std::to_string(static_cast(machine_type)); + } + } + + static void print_invalid_architecture_files(const std::string& expected_architecture, + std::vector binaries_with_invalid_architecture) + { + System::println(System::Color::warning, "The following files were built for an incorrect architecture:"); + System::println(); + for (const FileAndArch& b : binaries_with_invalid_architecture) + { + System::println(" %s", b.file.generic_string()); + System::println("Expected %s, but was: %s", expected_architecture, b.actual_arch); + System::println(); + } + } + + static LintStatus check_dll_architecture(const std::string& expected_architecture, + const std::vector& files) + { + std::vector binaries_with_invalid_architecture; + + for (const fs::path& file : files) + { + Checks::check_exit(VCPKG_LINE_INFO, + file.extension() == ".dll", + "The file extension was not .dll: %s", + file.generic_string()); + const CoffFileReader::DllInfo info = CoffFileReader::read_dll(file); + const std::string actual_architecture = get_actual_architecture(info.machine_type); + + if (expected_architecture != actual_architecture) + { + binaries_with_invalid_architecture.push_back({file, actual_architecture}); + } + } + + if (!binaries_with_invalid_architecture.empty()) + { + print_invalid_architecture_files(expected_architecture, binaries_with_invalid_architecture); + return LintStatus::ERROR_DETECTED; + } + + return LintStatus::SUCCESS; + } + + static LintStatus check_lib_architecture(const std::string& expected_architecture, + const std::vector& files) + { + std::vector binaries_with_invalid_architecture; + + for (const fs::path& file : files) + { + Checks::check_exit(VCPKG_LINE_INFO, + file.extension() == ".lib", + "The file extension was not .lib: %s", + file.generic_string()); + CoffFileReader::LibInfo info = CoffFileReader::read_lib(file); + + // This is zero for folly's debug library + // TODO: Why? + if (info.machine_types.size() == 0) return LintStatus::SUCCESS; + + Checks::check_exit(VCPKG_LINE_INFO, + info.machine_types.size() == 1, + "Found more than 1 architecture in file %s", + file.generic_string()); + + const std::string actual_architecture = get_actual_architecture(info.machine_types.at(0)); + if (expected_architecture != actual_architecture) + { + binaries_with_invalid_architecture.push_back({file, actual_architecture}); + } + } + + if (!binaries_with_invalid_architecture.empty()) + { + print_invalid_architecture_files(expected_architecture, binaries_with_invalid_architecture); + return LintStatus::ERROR_DETECTED; + } + + return LintStatus::SUCCESS; + } + + static LintStatus check_no_dlls_present(const std::vector& dlls) + { + if (dlls.empty()) + { + return LintStatus::SUCCESS; + } + + System::println(System::Color::warning, + "DLLs should not be present in a static build, but the following DLLs were found:"); + Files::print_paths(dlls); + return LintStatus::ERROR_DETECTED; + } + + static LintStatus check_matching_debug_and_release_binaries(const std::vector& debug_binaries, + const std::vector& release_binaries) + { + const size_t debug_count = debug_binaries.size(); + const size_t release_count = release_binaries.size(); + if (debug_count == release_count) + { + return LintStatus::SUCCESS; + } + + System::println(System::Color::warning, + "Mismatching number of debug and release binaries. Found %d for debug but %d for release.", + debug_count, + release_count); + System::println("Debug binaries"); + Files::print_paths(debug_binaries); + + System::println("Release binaries"); + Files::print_paths(release_binaries); + + if (debug_count == 0) + { + System::println(System::Color::warning, "Debug binaries were not found"); + } + if (release_count == 0) + { + System::println(System::Color::warning, "Release binaries were not found"); + } + + System::println(); + + return LintStatus::ERROR_DETECTED; + } + + static LintStatus check_lib_files_are_available_if_dlls_are_available(const Build::BuildPolicies& policies, + const size_t lib_count, + const size_t dll_count, + const fs::path& lib_dir) + { + if (policies.is_enabled(BuildPolicy::DLLS_WITHOUT_LIBS)) return LintStatus::SUCCESS; + + if (lib_count == 0 && dll_count != 0) + { + 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)", + to_cmake_variable(BuildPolicy::DLLS_WITHOUT_LIBS)); + return LintStatus::ERROR_DETECTED; + } + + return LintStatus::SUCCESS; + } + + 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)) + { + return LintStatus::SUCCESS; + } + + 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.u8string()); + } + + 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.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" + "\n" + R"###( if(VCPKG_LIBRARY_LINKAGE STREQUAL static))###" + "\n" + R"###( file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/bin ${CURRENT_PACKAGES_DIR}/debug/bin))###" + "\n" + R"###( endif())###" + "\n"); + + return LintStatus::ERROR_DETECTED; + } + + static LintStatus check_no_empty_folders(const Files::Filesystem& fs, const fs::path& dir) + { + std::vector 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()) + { + System::println(System::Color::warning, "There should be no empty directories in %s", dir.generic_string()); + System::println("The following empty directories were found: "); + Files::print_paths(empty_directories); + System::println( + System::Color::warning, + "If a directory should be populated but is not, this might indicate an error in the portfile.\n" + "If the directories are not needed and their creation cannot be disabled, use something like this in " + "the portfile to remove them:\n" + "\n" + R"###( file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/a/dir ${CURRENT_PACKAGES_DIR}/some/other/dir))###" + "\n" + "\n"); + return LintStatus::ERROR_DETECTED; + } + + return LintStatus::SUCCESS; + } + + struct BuildTypeAndFile + { + fs::path file; + BuildType build_type; + }; + + static LintStatus check_crt_linkage_of_libs(const BuildType& expected_build_type, + const std::vector& libs, + const fs::path dumpbin_exe) + { + std::vector bad_build_types(BuildTypeC::VALUES.cbegin(), BuildTypeC::VALUES.cend()); + bad_build_types.erase(std::remove(bad_build_types.begin(), bad_build_types.end(), expected_build_type), + bad_build_types.end()); + + std::vector libs_with_invalid_crt; + + for (const fs::path& lib : libs) + { + const std::wstring cmd_line = + Strings::wformat(LR"("%s" /directives "%s")", dumpbin_exe.native(), lib.native()); + System::ExitCodeAndOutput ec_data = System::cmd_execute_and_capture_output(cmd_line); + Checks::check_exit(VCPKG_LINE_INFO, + ec_data.exit_code == 0, + "Running command:\n %s\n failed", + Strings::to_utf8(cmd_line)); + + for (const BuildType& bad_build_type : bad_build_types) + { + if (std::regex_search(ec_data.output.cbegin(), ec_data.output.cend(), bad_build_type.crt_regex())) + { + libs_with_invalid_crt.push_back({lib, bad_build_type}); + break; + } + } + } + + if (!libs_with_invalid_crt.empty()) + { + System::println(System::Color::warning, + "Expected %s crt linkage, but the following libs had invalid crt linkage:", + expected_build_type.to_string()); + System::println(); + for (const BuildTypeAndFile btf : libs_with_invalid_crt) + { + System::println(" %s: %s", btf.file.generic_string(), btf.build_type.to_string()); + } + System::println(); + + System::println(System::Color::warning, + "To inspect the lib files, use:\n dumpbin.exe /directives mylibfile.lib"); + return LintStatus::ERROR_DETECTED; + } + + return LintStatus::SUCCESS; + } + + struct OutdatedDynamicCrtAndFile + { + fs::path file; + OutdatedDynamicCrt outdated_crt; + + OutdatedDynamicCrtAndFile() = delete; + }; + + static LintStatus check_outdated_crt_linkage_of_dlls(const std::vector& dlls, + const fs::path dumpbin_exe, + const BuildInfo& build_info) + { + if (build_info.policies.is_enabled(BuildPolicy::ALLOW_OBSOLETE_MSVCRT)) return LintStatus::SUCCESS; + + std::vector dlls_with_outdated_crt; + + for (const fs::path& dll : dlls) + { + const std::wstring cmd_line = + Strings::wformat(LR"("%s" /dependents "%s")", dumpbin_exe.native(), dll.native()); + System::ExitCodeAndOutput ec_data = System::cmd_execute_and_capture_output(cmd_line); + Checks::check_exit(VCPKG_LINE_INFO, + ec_data.exit_code == 0, + "Running command:\n %s\n failed", + Strings::to_utf8(cmd_line)); + + for (const OutdatedDynamicCrt& outdated_crt : get_outdated_dynamic_crts("v141")) + { + if (std::regex_search(ec_data.output.cbegin(), ec_data.output.cend(), outdated_crt.regex)) + { + dlls_with_outdated_crt.push_back({dll, outdated_crt}); + break; + } + } + } + + if (!dlls_with_outdated_crt.empty()) + { + System::println(System::Color::warning, "Detected outdated dynamic CRT in the following files:"); + System::println(); + for (const OutdatedDynamicCrtAndFile btf : dlls_with_outdated_crt) + { + System::println(" %s: %s", btf.file.generic_string(), btf.outdated_crt.name); + } + System::println(); + + System::println(System::Color::warning, + "To inspect the dll files, use:\n dumpbin.exe /dependents mydllfile.dll"); + return LintStatus::ERROR_DETECTED; + } + + return LintStatus::SUCCESS; + } + + static LintStatus check_no_files_in_dir(const Files::Filesystem& fs, const fs::path& dir) + { + std::vector 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 (Strings::case_insensitive_ascii_compare(filename.c_str(), "CONTROL") || + Strings::case_insensitive_ascii_compare(filename.c_str(), "BUILD_INFO")) + return false; + return !fs.is_directory(path); + }); + + if (!misplaced_files.empty()) + { + 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; + } + + return LintStatus::SUCCESS; + } + + static void operator+=(size_t& left, const LintStatus& right) { left += static_cast(right); } + + static size_t perform_all_checks_and_return_error_count(const PackageSpec& spec, + const VcpkgPaths& paths, + const PreBuildInfo& pre_build_info, + const BuildInfo& build_info) + { + const auto& fs = paths.get_filesystem(); + + // for dumpbin + const Toolset& toolset = paths.get_toolset(pre_build_info.platform_toolset, pre_build_info.visual_studio_path); + const fs::path package_dir = paths.package_dir(spec); + + size_t error_count = 0; + + if (build_info.policies.is_enabled(BuildPolicy::EMPTY_PACKAGE)) + { + return error_count; + } + + 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"; + + std::vector debug_libs = fs.get_files_recursive(debug_lib_dir); + Util::unstable_keep_if(debug_libs, has_extension_pred(fs, ".lib")); + std::vector 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 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(pre_build_info.target_architecture, libs); + } + + std::vector debug_dlls = fs.get_files_recursive(debug_bin_dir); + Util::unstable_keep_if(debug_dlls, has_extension_pred(fs, ".dll")); + std::vector release_dlls = fs.get_files_recursive(release_bin_dir); + Util::unstable_keep_if(release_dlls, has_extension_pred(fs, ".dll")); + + switch (build_info.library_linkage) + { + case Build::LinkageType::DYNAMIC: + { + error_count += check_matching_debug_and_release_binaries(debug_dlls, release_dlls); + + error_count += check_lib_files_are_available_if_dlls_are_available( + build_info.policies, debug_libs.size(), debug_dlls.size(), debug_lib_dir); + error_count += check_lib_files_are_available_if_dlls_are_available( + build_info.policies, release_libs.size(), release_dlls.size(), release_lib_dir); + + std::vector dlls; + dlls.insert(dlls.cend(), debug_dlls.cbegin(), debug_dlls.cend()); + dlls.insert(dlls.cend(), release_dlls.cbegin(), release_dlls.cend()); + + error_count += check_exports_of_dlls(dlls, toolset.dumpbin); + error_count += check_uwp_bit_of_dlls(pre_build_info.cmake_system_name, dlls, toolset.dumpbin); + error_count += check_dll_architecture(pre_build_info.target_architecture, dlls); + + error_count += check_outdated_crt_linkage_of_dlls(dlls, toolset.dumpbin, build_info); + break; + } + case Build::LinkageType::STATIC: + { + auto dlls = release_dlls; + dlls.insert(dlls.end(), debug_dlls.begin(), debug_dlls.end()); + error_count += check_no_dlls_present(dlls); + + error_count += check_bin_folders_are_not_present_in_static_build(fs, package_dir); + + if (!build_info.policies.is_enabled(BuildPolicy::ONLY_RELEASE_CRT)) + { + error_count += + check_crt_linkage_of_libs(BuildType::value_of(ConfigurationType::DEBUG, build_info.crt_linkage), + debug_libs, + toolset.dumpbin); + } + error_count += + check_crt_linkage_of_libs(BuildType::value_of(ConfigurationType::RELEASE, build_info.crt_linkage), + release_libs, + toolset.dumpbin); + break; + } + default: Checks::unreachable(VCPKG_LINE_INFO); + } + + 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; + } + + size_t perform_all_checks(const PackageSpec& spec, + const VcpkgPaths& paths, + const PreBuildInfo& pre_build_info, + const BuildInfo& build_info) + { + System::println("-- Performing post-build validation"); + const size_t error_count = perform_all_checks_and_return_error_count(spec, paths, pre_build_info, build_info); + + if (error_count != 0) + { + const fs::path portfile = paths.ports / spec.name() / "portfile.cmake"; + System::println(System::Color::error, + "Found %u error(s). Please correct the portfile:\n %s", + error_count, + portfile.string()); + } + + System::println("-- Performing post-build validation done"); + + return error_count; + } +} diff --git a/toolsrc/src/vcpkg/remove.cpp b/toolsrc/src/vcpkg/remove.cpp new file mode 100644 index 000000000..3751566f7 --- /dev/null +++ b/toolsrc/src/vcpkg/remove.cpp @@ -0,0 +1,251 @@ +#include "pch.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace vcpkg::Remove +{ + using Dependencies::RemovePlanAction; + using Dependencies::RemovePlanType; + using Dependencies::RequestType; + using Update::OutdatedPackage; + + void remove_package(const VcpkgPaths& paths, const PackageSpec& spec, StatusParagraphs* status_db) + { + auto& fs = paths.get_filesystem(); + auto spghs = status_db->find_all(spec.name(), spec.triplet()); + const auto core_pkg = **status_db->find(spec.name(), spec.triplet(), Strings::EMPTY); + + for (auto&& spgh : spghs) + { + StatusParagraph& pkg = **spgh; + if (pkg.state != InstallState::INSTALLED) continue; + pkg.want = Want::PURGE; + pkg.state = InstallState::HALF_INSTALLED; + write_update(paths, pkg); + } + + auto maybe_lines = fs.read_lines(paths.listfile_path(core_pkg.package)); + + if (const auto lines = maybe_lines.get()) + { + std::vector dirs_touched; + for (auto&& suffix : *lines) + { + if (!suffix.empty() && suffix.back() == '\r') suffix.pop_back(); + + std::error_code ec; + + auto target = paths.installed / suffix; + + const auto status = fs.status(target, ec); + if (ec) + { + System::println(System::Color::error, "failed: %s", ec.message()); + continue; + } + + if (fs::is_directory(status)) + { + dirs_touched.push_back(target); + } + else if (fs::is_regular_file(status)) + { + fs.remove(target, ec); + if (ec) + { + System::println(System::Color::error, "failed: %s: %s", target.u8string(), ec.message()); + } + } + else if (!fs::status_known(status)) + { + System::println(System::Color::warning, "Warning: unknown status: %s", target.u8string()); + } + else + { + System::println(System::Color::warning, "Warning: %s: cannot handle file type", target.u8string()); + } + } + + auto b = dirs_touched.rbegin(); + const auto e = dirs_touched.rend(); + for (; b != e; ++b) + { + if (fs.is_empty(*b)) + { + std::error_code ec; + fs.remove(*b, ec); + if (ec) + { + System::println(System::Color::error, "failed: %s", ec.message()); + } + } + } + + fs.remove(paths.listfile_path(core_pkg.package)); + } + + for (auto&& spgh : spghs) + { + StatusParagraph& pkg = **spgh; + if (pkg.state != InstallState::HALF_INSTALLED) continue; + pkg.state = InstallState::NOT_INSTALLED; + write_update(paths, pkg); + } + } + + static void print_plan(const std::map>& group_by_plan_type) + { + static constexpr std::array ORDER = {RemovePlanType::NOT_INSTALLED, RemovePlanType::REMOVE}; + + for (const RemovePlanType plan_type : ORDER) + { + const auto it = group_by_plan_type.find(plan_type); + if (it == group_by_plan_type.cend()) + { + continue; + } + + std::vector cont = it->second; + std::sort(cont.begin(), cont.end(), &RemovePlanAction::compare_by_name); + const std::string as_string = Strings::join("\n", cont, [](const RemovePlanAction* p) { + return Dependencies::to_output_string(p->request_type, p->spec.to_string()); + }); + + switch (plan_type) + { + case RemovePlanType::NOT_INSTALLED: + System::println("The following packages are not installed, so not removed:\n%s", as_string); + continue; + case RemovePlanType::REMOVE: + System::println("The following packages will be removed:\n%s", as_string); + continue; + default: Checks::unreachable(VCPKG_LINE_INFO); + } + } + } + + void perform_remove_plan_action(const VcpkgPaths& paths, + const RemovePlanAction& action, + const Purge purge, + StatusParagraphs& status_db) + { + const std::string display_name = action.spec.to_string(); + + switch (action.plan_type) + { + case RemovePlanType::NOT_INSTALLED: + System::println(System::Color::success, "Package %s is not installed", display_name); + break; + case RemovePlanType::REMOVE: + System::println("Removing package %s... ", display_name); + remove_package(paths, action.spec, &status_db); + System::println(System::Color::success, "Removing package %s... done", display_name); + break; + case RemovePlanType::UNKNOWN: + default: Checks::unreachable(VCPKG_LINE_INFO); + } + + if (purge == Purge::YES) + { + System::println("Purging package %s... ", display_name); + Files::Filesystem& fs = paths.get_filesystem(); + std::error_code ec; + fs.remove_all(paths.packages / action.spec.dir(), ec); + System::println(System::Color::success, "Purging package %s... done", display_name); + } + } + + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) + { + static const std::string OPTION_PURGE = "--purge"; + static const std::string OPTION_NO_PURGE = "--no-purge"; + static const std::string OPTION_RECURSE = "--recurse"; + static const std::string OPTION_DRY_RUN = "--dry-run"; + static const std::string OPTION_OUTDATED = "--outdated"; + static const std::string EXAMPLE = Help::create_example_string("remove zlib zlib:x64-windows curl boost"); + const std::unordered_set options = args.check_and_get_optional_command_arguments( + {OPTION_PURGE, OPTION_NO_PURGE, OPTION_RECURSE, OPTION_DRY_RUN, OPTION_OUTDATED}); + + StatusParagraphs status_db = database_load_check(paths); + std::vector specs; + if (options.find(OPTION_OUTDATED) != options.cend()) + { + args.check_exact_arg_count(0, EXAMPLE); + specs = Util::fmap(Update::find_outdated_packages(paths, status_db), + [](auto&& outdated) { return outdated.spec; }); + + if (specs.empty()) + { + System::println(System::Color::success, "There are no outdated packages."); + Checks::exit_success(VCPKG_LINE_INFO); + } + } + else + { + args.check_min_arg_count(1, EXAMPLE); + specs = Util::fmap(args.command_arguments, [&](auto&& arg) { + return Input::check_and_get_package_spec(arg, default_triplet, EXAMPLE); + }); + + for (auto&& spec : specs) + Input::check_triplet(spec.triplet(), paths); + } + + const bool no_purge_was_passed = options.find(OPTION_NO_PURGE) != options.end(); + const bool purge_was_passed = options.find(OPTION_PURGE) != options.end(); + if (purge_was_passed && no_purge_was_passed) + { + System::println(System::Color::error, "Error: cannot specify both --no-purge and --purge."); + System::print(EXAMPLE); + Checks::exit_fail(VCPKG_LINE_INFO); + } + const Purge purge = to_purge(purge_was_passed || !no_purge_was_passed); + const bool is_recursive = options.find(OPTION_RECURSE) != options.cend(); + const bool dry_run = options.find(OPTION_DRY_RUN) != options.cend(); + + const std::vector remove_plan = Dependencies::create_remove_plan(specs, status_db); + Checks::check_exit(VCPKG_LINE_INFO, !remove_plan.empty(), "Remove plan cannot be empty"); + + std::map> group_by_plan_type; + Util::group_by(remove_plan, &group_by_plan_type, [](const RemovePlanAction& p) { return p.plan_type; }); + print_plan(group_by_plan_type); + + const bool has_non_user_requested_packages = + Util::find_if(remove_plan, [](const RemovePlanAction& package) -> bool { + return package.request_type != RequestType::USER_REQUESTED; + }) != remove_plan.cend(); + + if (has_non_user_requested_packages) + { + System::println(System::Color::warning, + "Additional packages (*) need to be removed to complete this operation."); + + if (!is_recursive) + { + System::println(System::Color::warning, + "If you are sure you want to remove them, run the command with the --recurse option"); + Checks::exit_fail(VCPKG_LINE_INFO); + } + } + + if (dry_run) + { + Checks::exit_success(VCPKG_LINE_INFO); + } + + for (const RemovePlanAction& action : remove_plan) + { + perform_remove_plan_action(paths, action, purge, status_db); + } + + Checks::exit_success(VCPKG_LINE_INFO); + } +} diff --git a/toolsrc/src/vcpkg/sourceparagraph.cpp b/toolsrc/src/vcpkg/sourceparagraph.cpp new file mode 100644 index 000000000..d766dcb72 --- /dev/null +++ b/toolsrc/src/vcpkg/sourceparagraph.cpp @@ -0,0 +1,264 @@ +#include "pch.h" + +#include +#include +#include + +#include +#include +#include +#include + +namespace vcpkg +{ + using namespace vcpkg::Parse; + + namespace SourceParagraphFields + { + static const std::string BUILD_DEPENDS = "Build-Depends"; + static const std::string DEFAULTFEATURES = "Default-Features"; + static const std::string DESCRIPTION = "Description"; + static const std::string FEATURE = "Feature"; + static const std::string MAINTAINER = "Maintainer"; + static const std::string SOURCE = "Source"; + static const std::string SUPPORTS = "Supports"; + static const std::string VERSION = "Version"; + } + + static Span get_list_of_valid_fields() + { + static const std::string valid_fields[] = { + SourceParagraphFields::SOURCE, + SourceParagraphFields::VERSION, + SourceParagraphFields::DESCRIPTION, + SourceParagraphFields::MAINTAINER, + SourceParagraphFields::BUILD_DEPENDS, + }; + + return valid_fields; + } + + void print_error_message(Span> error_info_list) + { + Checks::check_exit(VCPKG_LINE_INFO, error_info_list.size() > 0); + + for (auto&& error_info : error_info_list) + { + Checks::check_exit(VCPKG_LINE_INFO, error_info != nullptr); + if (error_info->error) + { + System::println( + System::Color::error, "Error: while loading %s: %s", error_info->name, error_info->error.message()); + } + } + + bool have_remaining_fields = false; + for (auto&& error_info : error_info_list) + { + if (!error_info->extra_fields.empty()) + { + System::println(System::Color::error, + "Error: There are invalid fields in the control file of %s", + error_info->name); + System::println("The following fields were not expected:\n\n %s\n", + Strings::join("\n ", error_info->extra_fields)); + have_remaining_fields = true; + } + } + + if (have_remaining_fields) + { + System::println("This is the list of valid fields (case-sensitive): \n\n %s\n", + Strings::join("\n ", get_list_of_valid_fields())); + System::println("Different source may be available for vcpkg. Use .\\bootstrap-vcpkg.bat to update.\n"); + } + + for (auto&& error_info : error_info_list) + { + if (!error_info->missing_fields.empty()) + { + System::println(System::Color::error, + "Error: There are missing fields in the control file of %s", + error_info->name); + System::println("The following fields were missing:\n\n %s\n", + Strings::join("\n ", error_info->missing_fields)); + } + } + } + + static ParseExpected parse_source_paragraph(RawParagraph&& fields) + { + ParagraphParser parser(std::move(fields)); + + auto spgh = std::make_unique(); + + parser.required_field(SourceParagraphFields::SOURCE, spgh->name); + parser.required_field(SourceParagraphFields::VERSION, spgh->version); + + spgh->description = parser.optional_field(SourceParagraphFields::DESCRIPTION); + spgh->maintainer = parser.optional_field(SourceParagraphFields::MAINTAINER); + spgh->depends = expand_qualified_dependencies( + parse_comma_list(parser.optional_field(SourceParagraphFields::BUILD_DEPENDS))); + spgh->supports = parse_comma_list(parser.optional_field(SourceParagraphFields::SUPPORTS)); + spgh->default_features = parse_comma_list(parser.optional_field(SourceParagraphFields::DEFAULTFEATURES)); + + auto err = parser.error_info(spgh->name); + if (err) + return std::move(err); + else + return std::move(spgh); + } + + static ParseExpected parse_feature_paragraph(RawParagraph&& fields) + { + ParagraphParser parser(std::move(fields)); + + auto fpgh = std::make_unique(); + + parser.required_field(SourceParagraphFields::FEATURE, fpgh->name); + parser.required_field(SourceParagraphFields::DESCRIPTION, fpgh->description); + + fpgh->depends = expand_qualified_dependencies( + parse_comma_list(parser.optional_field(SourceParagraphFields::BUILD_DEPENDS))); + + auto err = parser.error_info(fpgh->name); + if (err) + return std::move(err); + else + return std::move(fpgh); + } + + ParseExpected SourceControlFile::parse_control_file( + std::vector>&& control_paragraphs) + { + if (control_paragraphs.size() == 0) + { + return std::make_unique(); + } + + auto control_file = std::make_unique(); + + auto maybe_source = parse_source_paragraph(std::move(control_paragraphs.front())); + if (const auto source = maybe_source.get()) + control_file->core_paragraph = std::move(*source); + else + return std::move(maybe_source).error(); + + control_paragraphs.erase(control_paragraphs.begin()); + + for (auto&& feature_pgh : control_paragraphs) + { + auto maybe_feature = parse_feature_paragraph(std::move(feature_pgh)); + if (const auto feature = maybe_feature.get()) + control_file->feature_paragraphs.emplace_back(std::move(*feature)); + else + return std::move(maybe_feature).error(); + } + + return std::move(control_file); + } + + Dependency Dependency::parse_dependency(std::string name, std::string qualifier) + { + Dependency dep; + dep.qualifier = qualifier; + if (auto maybe_features = Features::from_string(name)) + dep.depend = *maybe_features.get(); + else + Checks::exit_with_message( + VCPKG_LINE_INFO, "error while parsing dependency: %s: %s", to_string(maybe_features.error()), name); + return dep; + } + + std::string Dependency::name() const + { + if (this->depend.features.empty()) return this->depend.name; + + const std::string features = Strings::join(",", this->depend.features); + return Strings::format("%s[%s]", this->depend.name, features); + } + + std::vector vcpkg::expand_qualified_dependencies(const std::vector& depends) + { + return Util::fmap(depends, [&](const std::string& depend_string) -> Dependency { + auto pos = depend_string.find(' '); + if (pos == std::string::npos) return Dependency::parse_dependency(depend_string, Strings::EMPTY); + // expect of the form "\w+ \[\w+\]" + Dependency dep; + + dep.depend.name = depend_string.substr(0, pos); + if (depend_string.c_str()[pos + 1] != '(' || depend_string[depend_string.size() - 1] != ')') + { + // Error, but for now just slurp the entire string. + return Dependency::parse_dependency(depend_string, Strings::EMPTY); + } + dep.qualifier = depend_string.substr(pos + 2, depend_string.size() - pos - 3); + return dep; + }); + } + + std::vector filter_dependencies(const std::vector& deps, const Triplet& t) + { + std::vector ret; + for (auto&& dep : deps) + { + if (dep.qualifier.empty() || t.canonical_name().find(dep.qualifier) != std::string::npos) + { + ret.emplace_back(dep.name()); + } + } + return ret; + } + + std::vector filter_dependencies_to_specs(const std::vector& deps, const Triplet& t) + { + return FeatureSpec::from_strings_and_triplet(filter_dependencies(deps, t), t); + } + + std::string to_string(const Dependency& dep) { return dep.name(); } + + ExpectedT> Supports::parse(const std::vector& strs) + { + Supports ret; + std::vector unrecognized; + + for (auto&& str : strs) + { + if (str == "x64") + ret.architectures.push_back(Architecture::X64); + else if (str == "x86") + ret.architectures.push_back(Architecture::X86); + else if (str == "arm") + ret.architectures.push_back(Architecture::ARM); + else if (str == "windows") + ret.platforms.push_back(Platform::WINDOWS); + else if (str == "uwp") + ret.platforms.push_back(Platform::UWP); + else if (str == "v140") + ret.toolsets.push_back(ToolsetVersion::V140); + else if (str == "v141") + ret.toolsets.push_back(ToolsetVersion::V141); + else if (str == "crt-static") + ret.crt_linkages.push_back(Linkage::STATIC); + else if (str == "crt-dynamic") + ret.crt_linkages.push_back(Linkage::DYNAMIC); + else + unrecognized.push_back(str); + } + + if (unrecognized.empty()) + return std::move(ret); + else + return std::move(unrecognized); + } + + bool Supports::is_supported(Architecture arch, Platform plat, Linkage crt, ToolsetVersion tools) + { + const auto is_in_or_empty = [](auto v, auto&& c) -> bool { return c.empty() || c.end() != Util::find(c, v); }; + if (!is_in_or_empty(arch, architectures)) return false; + if (!is_in_or_empty(plat, platforms)) return false; + if (!is_in_or_empty(crt, crt_linkages)) return false; + if (!is_in_or_empty(tools, toolsets)) return false; + return true; + } +} diff --git a/toolsrc/src/vcpkg/statusparagraph.cpp b/toolsrc/src/vcpkg/statusparagraph.cpp new file mode 100644 index 000000000..5f00825e1 --- /dev/null +++ b/toolsrc/src/vcpkg/statusparagraph.cpp @@ -0,0 +1,86 @@ +#include "pch.h" + +#include + +using namespace vcpkg::Parse; + +namespace vcpkg +{ + namespace BinaryParagraphRequiredField + { + static const std::string STATUS = "Status"; + } + + StatusParagraph::StatusParagraph() : want(Want::ERROR_STATE), state(InstallState::ERROR_STATE) {} + + void serialize(const StatusParagraph& pgh, std::string& out_str) + { + 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(std::unordered_map&& fields) + { + auto status_it = fields.find(BinaryParagraphRequiredField::STATUS); + Checks::check_exit(VCPKG_LINE_INFO, status_it != fields.end(), "Expected 'Status' field in status paragraph"); + std::string status_field = std::move(status_it->second); + fields.erase(status_it); + + this->package = BinaryParagraph(std::move(fields)); + + auto b = status_field.begin(); + const auto mark = b; + const auto e = status_field.end(); + + // Todo: improve error handling + while (b != e && *b != ' ') + ++b; + + want = [](const std::string& text) { + if (text == "unknown") return Want::UNKNOWN; + if (text == "install") return Want::INSTALL; + if (text == "hold") return Want::HOLD; + if (text == "deinstall") return Want::DEINSTALL; + if (text == "purge") return Want::PURGE; + return Want::ERROR_STATE; + }(std::string(mark, b)); + + if (std::distance(b, e) < 4) return; + b += 4; + + state = [](const std::string& text) { + if (text == "not-installed") return InstallState::NOT_INSTALLED; + if (text == "installed") return InstallState::INSTALLED; + if (text == "half-installed") return InstallState::HALF_INSTALLED; + return InstallState::ERROR_STATE; + }(std::string(b, e)); + } + + std::string to_string(InstallState f) + { + switch (f) + { + case InstallState::HALF_INSTALLED: return "half-installed"; + case InstallState::INSTALLED: return "installed"; + case InstallState::NOT_INSTALLED: return "not-installed"; + default: return "error"; + } + } + + std::string to_string(Want f) + { + switch (f) + { + case Want::DEINSTALL: return "deinstall"; + case Want::HOLD: return "hold"; + case Want::INSTALL: return "install"; + case Want::PURGE: return "purge"; + case Want::UNKNOWN: return "unknown"; + default: return "error"; + } + } +} diff --git a/toolsrc/src/vcpkg/statusparagraphs.cpp b/toolsrc/src/vcpkg/statusparagraphs.cpp new file mode 100644 index 000000000..647ed6d3f --- /dev/null +++ b/toolsrc/src/vcpkg/statusparagraphs.cpp @@ -0,0 +1,89 @@ +#include "pch.h" + +#include +#include + +namespace vcpkg +{ + StatusParagraphs::StatusParagraphs() = default; + + StatusParagraphs::StatusParagraphs(std::vector>&& ps) + : paragraphs(std::move(ps)){}; + + StatusParagraphs::const_iterator StatusParagraphs::find(const std::string& name, const Triplet& triplet) const + { + return std::find_if(begin(), end(), [&](const std::unique_ptr& pgh) { + const PackageSpec& spec = pgh->package.spec; + return spec.name() == name && spec.triplet() == triplet; + }); + } + + StatusParagraphs::iterator StatusParagraphs::find(const std::string& name, const Triplet& triplet) + { + return std::find_if(begin(), end(), [&](const std::unique_ptr& pgh) { + const PackageSpec& spec = pgh->package.spec; + return spec.name() == name && spec.triplet() == triplet; + }); + } + + std::vector*> StatusParagraphs::find_all(const std::string& name, + const Triplet& triplet) + { + std::vector*> spghs; + for (auto&& p : *this) + { + if (p->package.spec.name() == name && p->package.spec.triplet() == triplet) + { + spghs.emplace_back(&p); + } + } + return spghs; + } + + StatusParagraphs::iterator StatusParagraphs::find(const std::string& name, + const Triplet& triplet, + const std::string& feature) + { + return std::find_if(begin(), end(), [&](const std::unique_ptr& pgh) { + const PackageSpec& spec = pgh->package.spec; + return spec.name() == name && spec.triplet() == triplet && pgh->package.feature == feature; + }); + } + + StatusParagraphs::const_iterator StatusParagraphs::find_installed(const std::string& name, + const Triplet& triplet) const + { + const const_iterator it = find(name, triplet); + if (it != end() && (*it)->want == Want::INSTALL && (*it)->state == InstallState::INSTALLED) + { + return it; + } + + return end(); + } + + StatusParagraphs::iterator StatusParagraphs::insert(std::unique_ptr pgh) + { + Checks::check_exit(VCPKG_LINE_INFO, pgh != nullptr, "Inserted null paragraph"); + const PackageSpec& spec = pgh->package.spec; + const auto ptr = find(spec.name(), spec.triplet(), pgh->package.feature); + if (ptr == end()) + { + paragraphs.push_back(std::move(pgh)); + return paragraphs.rbegin(); + } + + // consume data from provided pgh. + **ptr = std::move(*pgh); + return ptr; + } + + void serialize(const StatusParagraphs& pghs, std::string& out_str) + { + for (auto& pgh : pghs.paragraphs) + { + serialize(*pgh, out_str); + out_str.push_back('\n'); + } + } +} diff --git a/toolsrc/src/vcpkg/triplet.cpp b/toolsrc/src/vcpkg/triplet.cpp new file mode 100644 index 000000000..8a84ee2b2 --- /dev/null +++ b/toolsrc/src/vcpkg/triplet.cpp @@ -0,0 +1,55 @@ +#include "pch.h" + +#include +#include +#include + +namespace vcpkg +{ + struct TripletInstance + { + TripletInstance(std::string&& s) : value(std::move(s)), hash(std::hash()(value)) {} + + const std::string value; + const size_t hash = 0; + + bool operator==(const TripletInstance& o) const { return o.value == value; } + }; + const TripletInstance Triplet::DEFAULT_INSTANCE({}); +} + +template<> +struct std::hash +{ + size_t operator()(const vcpkg::TripletInstance& t) const { return t.hash; } +}; + +namespace vcpkg +{ + static std::unordered_set g_triplet_instances; + + const Triplet Triplet::X86_WINDOWS = from_canonical_name("x86-windows"); + const Triplet Triplet::X64_WINDOWS = from_canonical_name("x64-windows"); + const Triplet Triplet::X86_UWP = from_canonical_name("x86-uwp"); + const Triplet Triplet::X64_UWP = from_canonical_name("x64-uwp"); + const Triplet Triplet::ARM_UWP = from_canonical_name("arm-uwp"); + + bool Triplet::operator==(const Triplet& other) const { return this->m_instance == other.m_instance; } + + bool operator!=(const Triplet& left, const Triplet& right) { return !(left == right); } + + Triplet Triplet::from_canonical_name(const std::string& triplet_as_string) + { + std::string s(Strings::ascii_to_lowercase(triplet_as_string)); + const auto it = std::find(s.cbegin(), s.cend(), '-'); + Checks::check_exit(VCPKG_LINE_INFO, it != s.cend(), "Invalid triplet: %s", triplet_as_string); + + const auto p = g_triplet_instances.emplace(std::move(s)); + return &*p.first; + } + + const std::string& Triplet::canonical_name() const { return this->m_instance->value; } + + const std::string& Triplet::to_string() const { return this->canonical_name(); } + size_t Triplet::hash_code() const { return m_instance->hash; } +} diff --git a/toolsrc/src/vcpkg/update.cpp b/toolsrc/src/vcpkg/update.cpp new file mode 100644 index 000000000..168949bc1 --- /dev/null +++ b/toolsrc/src/vcpkg/update.cpp @@ -0,0 +1,75 @@ +#include "pch.h" + +#include +#include +#include +#include +#include +#include + +namespace vcpkg::Update +{ + bool OutdatedPackage::compare_by_name(const OutdatedPackage& left, const OutdatedPackage& right) + { + return left.spec.name() < right.spec.name(); + } + + std::vector find_outdated_packages(const VcpkgPaths& paths, const StatusParagraphs& status_db) + { + const std::map src_names_to_versions = + Paragraphs::load_all_port_names_and_versions(paths.get_filesystem(), paths.ports); + const std::vector installed_packages = get_installed_ports(status_db); + + std::vector output; + for (const StatusParagraph* pgh : installed_packages) + { + const auto it = src_names_to_versions.find(pgh->package.spec.name()); + if (it == src_names_to_versions.end()) + { + // Package was not installed from portfile + continue; + } + if (it->second != pgh->package.version) + { + output.push_back({pgh->package.spec, VersionDiff(pgh->package.version, it->second)}); + } + } + + return output; + } + + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) + { + args.check_exact_arg_count(0); + args.check_and_get_optional_command_arguments({}); + System::println("Using local portfile versions. To update the local portfiles, use `git pull`."); + + const StatusParagraphs status_db = database_load_check(paths); + + const auto outdated_packages = + SortedVector(find_outdated_packages(paths, status_db), &OutdatedPackage::compare_by_name); + + if (outdated_packages.empty()) + { + System::println("No packages need updating."); + } + else + { + std::string install_line; + System::println("The following packages differ from their port versions:"); + for (auto&& package : outdated_packages) + { + install_line += package.spec.to_string(); + install_line += " "; + System::println(" %-32s %s", package.spec, package.version_diff.to_string()); + } + System::println("\n" + "To update these packages, run\n" + " .\\vcpkg remove --outdated\n" + " .\\vcpkg install " + + install_line); + } + + Checks::exit_success(VCPKG_LINE_INFO); + } +} diff --git a/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp b/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp new file mode 100644 index 000000000..522961693 --- /dev/null +++ b/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp @@ -0,0 +1,284 @@ +#include "pch.h" + +#include +#include +#include +#include +#include +#include + +namespace vcpkg +{ + static void parse_value(const std::string* arg_begin, + const std::string* arg_end, + const std::string& option_name, + std::unique_ptr& option_field) + { + if (arg_begin == arg_end) + { + System::println(System::Color::error, "Error: expected value after %s", option_name); + Metrics::g_metrics.lock()->track_property("error", "error option name"); + Help::print_usage(); + Checks::exit_fail(VCPKG_LINE_INFO); + } + + if (option_field != nullptr) + { + System::println(System::Color::error, "Error: %s specified multiple times", option_name); + Metrics::g_metrics.lock()->track_property("error", "error option specified multiple times"); + Help::print_usage(); + Checks::exit_fail(VCPKG_LINE_INFO); + } + + option_field = std::make_unique(*arg_begin); + } + + static void parse_switch(bool new_setting, const std::string& option_name, Optional& option_field) + { + if (option_field && option_field != new_setting) + { + System::println(System::Color::error, "Error: conflicting values specified for --%s", option_name); + Metrics::g_metrics.lock()->track_property("error", "error conflicting switches"); + Help::print_usage(); + Checks::exit_fail(VCPKG_LINE_INFO); + } + option_field = new_setting; + } + + VcpkgCmdArguments VcpkgCmdArguments::create_from_command_line(const int argc, const wchar_t* const* const argv) + { + std::vector v; + for (int i = 1; i < argc; ++i) + { + v.push_back(Strings::to_utf8(argv[i])); + } + + return VcpkgCmdArguments::create_from_arg_sequence(v.data(), v.data() + v.size()); + } + + VcpkgCmdArguments VcpkgCmdArguments::create_from_arg_sequence(const std::string* arg_begin, + const std::string* arg_end) + { + VcpkgCmdArguments args; + + for (; arg_begin != arg_end; ++arg_begin) + { + std::string arg = *arg_begin; + + if (arg.empty()) + { + continue; + } + + if (arg[0] == '-' && arg[1] != '-') + { + Metrics::g_metrics.lock()->track_property("error", "error short options are not supported"); + Checks::exit_with_message(VCPKG_LINE_INFO, "Error: short options are not supported: %s", arg); + } + + if (arg[0] == '-' && arg[1] == '-') + { + // make argument case insensitive + auto& f = std::use_facet>(std::locale()); + f.tolower(&arg[0], &arg[0] + arg.size()); + // command switch + if (arg == "--vcpkg-root") + { + ++arg_begin; + parse_value(arg_begin, arg_end, "--vcpkg-root", args.vcpkg_root_dir); + continue; + } + if (arg == "--triplet") + { + ++arg_begin; + parse_value(arg_begin, arg_end, "--triplet", args.triplet); + continue; + } + if (arg == "--debug") + { + parse_switch(true, "debug", args.debug); + continue; + } + if (arg == "--sendmetrics") + { + parse_switch(true, "sendmetrics", args.sendmetrics); + continue; + } + if (arg == "--printmetrics") + { + parse_switch(true, "printmetrics", args.printmetrics); + continue; + } + if (arg == "--no-sendmetrics") + { + parse_switch(false, "sendmetrics", args.sendmetrics); + continue; + } + if (arg == "--no-printmetrics") + { + parse_switch(false, "printmetrics", args.printmetrics); + continue; + } + if (arg == "--featurepackages") + { + GlobalState::feature_packages = true; + continue; + } + + const auto eq_pos = arg.find('='); + if (eq_pos != std::string::npos) + { + args.optional_command_arguments.emplace(arg.substr(0, eq_pos), arg.substr(eq_pos + 1)); + } + else + { + args.optional_command_arguments.emplace(arg, nullopt); + } + continue; + } + + if (args.command.empty()) + { + args.command = arg; + } + else + { + args.command_arguments.push_back(arg); + } + } + + return args; + } + + ParsedArguments VcpkgCmdArguments::check_and_get_optional_command_arguments( + const std::vector& valid_switches, const std::vector& valid_settings) const + { + bool failed = false; + ParsedArguments output; + + auto options_copy = this->optional_command_arguments; + for (const std::string& option : valid_switches) + { + const auto it = options_copy.find(option); + if (it != options_copy.end()) + { + if (it->second.has_value()) + { + // Having a string value indicates it was passed like '--a=xyz' + System::println(System::Color::error, "The option '%s' does not accept an argument.", option); + failed = true; + } + else + { + output.switches.insert(option); + options_copy.erase(it); + } + } + } + + for (const std::string& option : valid_settings) + { + const auto it = options_copy.find(option); + if (it != options_copy.end()) + { + if (!it->second.has_value()) + { + // Not having a string value indicates it was passed like '--a' + System::println(System::Color::error, "The option '%s' must be passed an argument.", option); + failed = true; + } + else + { + output.settings.emplace(option, it->second.value_or_exit(VCPKG_LINE_INFO)); + options_copy.erase(it); + } + } + } + + if (!options_copy.empty()) + { + System::println(System::Color::error, "Unknown option(s) for command '%s':", this->command); + for (auto&& option : options_copy) + { + System::println(" %s", option.first); + } + System::println("\nValid options are:", this->command); + for (auto&& option : valid_switches) + { + System::println(" %s", option); + } + for (auto&& option : valid_settings) + { + System::println(" %s=...", option); + } + System::println(" --triplet "); + System::println(" --vcpkg-root "); + + Checks::exit_fail(VCPKG_LINE_INFO); + } + if (failed) Checks::exit_fail(VCPKG_LINE_INFO); + + return output; + } + + void VcpkgCmdArguments::check_max_arg_count(const size_t expected_arg_count) const + { + return check_max_arg_count(expected_arg_count, Strings::EMPTY); + } + + void VcpkgCmdArguments::check_min_arg_count(const size_t expected_arg_count) const + { + return check_min_arg_count(expected_arg_count, Strings::EMPTY); + } + + void VcpkgCmdArguments::check_exact_arg_count(const size_t expected_arg_count) const + { + return check_exact_arg_count(expected_arg_count, Strings::EMPTY); + } + + void VcpkgCmdArguments::check_max_arg_count(const size_t expected_arg_count, const std::string& example_text) const + { + const size_t actual_arg_count = command_arguments.size(); + if (actual_arg_count > expected_arg_count) + { + System::println(System::Color::error, + "Error: `%s` requires at most %u arguments, but %u were provided", + this->command, + expected_arg_count, + actual_arg_count); + System::print(example_text); + Checks::exit_fail(VCPKG_LINE_INFO); + } + } + + void VcpkgCmdArguments::check_min_arg_count(const size_t expected_arg_count, const std::string& example_text) const + { + const size_t actual_arg_count = command_arguments.size(); + if (actual_arg_count < expected_arg_count) + { + System::println(System::Color::error, + "Error: `%s` requires at least %u arguments, but %u were provided", + this->command, + expected_arg_count, + actual_arg_count); + System::print(example_text); + Checks::exit_fail(VCPKG_LINE_INFO); + } + } + + void VcpkgCmdArguments::check_exact_arg_count(const size_t expected_arg_count, + const std::string& example_text) const + { + const size_t actual_arg_count = command_arguments.size(); + if (actual_arg_count != expected_arg_count) + { + System::println(System::Color::error, + "Error: `%s` requires %u arguments, but %u were provided", + this->command, + expected_arg_count, + actual_arg_count); + System::print(example_text); + Checks::exit_fail(VCPKG_LINE_INFO); + } + } +} diff --git a/toolsrc/src/vcpkg/vcpkglib.cpp b/toolsrc/src/vcpkg/vcpkglib.cpp new file mode 100644 index 000000000..23c774210 --- /dev/null +++ b/toolsrc/src/vcpkg/vcpkglib.cpp @@ -0,0 +1,247 @@ +#include "pch.h" + +#include +#include +#include +#include +#include +#include + +namespace vcpkg +{ + 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_old)) + { + // no status file, use empty db + return StatusParagraphs(); + } + + fs.rename(vcpkg_dir_status_file_old, vcpkg_dir_status_file); + } + + auto pghs = Paragraphs::get_paragraphs(fs, vcpkg_dir_status_file).value_or_exit(VCPKG_LINE_INFO); + + std::vector> status_pghs; + for (auto&& p : pghs) + { + status_pghs.push_back(std::make_unique(std::move(p))); + } + + return StatusParagraphs(std::move(status_pghs)); + } + + StatusParagraphs database_load_check(const VcpkgPaths& paths) + { + auto& fs = paths.get_filesystem(); + + const 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); + + 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(fs, status_file, status_file_old); + + 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 (auto&& file : update_files) + { + if (!fs.is_regular_file(file)) continue; + if (file.filename() == "incomplete") continue; + + auto pghs = Paragraphs::get_paragraphs(fs, file).value_or_exit(VCPKG_LINE_INFO); + for (auto&& p : pghs) + { + current_status_db.insert(std::make_unique(std::move(p))); + } + } + + fs.write_contents(status_file_new, Strings::serialize(current_status_db)); + + fs.rename(status_file_new, status_file); + + for (auto&& file : update_files) + { + if (!fs.is_regular_file(file)) continue; + + fs.remove(file); + } + + return current_status_db; + } + + void write_update(const VcpkgPaths& paths, const StatusParagraph& p) + { + static int update_id = 0; + auto& fs = paths.get_filesystem(); + + const auto my_update_id = update_id++; + const auto tmp_update_filename = paths.vcpkg_dir_updates / "incomplete"; + const auto update_filename = paths.vcpkg_dir_updates / std::to_string(my_update_id); + + fs.write_contents(tmp_update_filename, Strings::serialize(p)); + fs.rename(tmp_update_filename, update_filename); + } + + static void upgrade_to_slash_terminated_sorted_format(Files::Filesystem& fs, + std::vector* lines, + const fs::path& listfile_path) + { + static bool was_tracked = false; + + if (lines->empty()) + { + return; + } + + if (lines->at(0).back() == '/') + { + return; // File already in the new format + } + + if (!was_tracked) + { + was_tracked = true; + Metrics::g_metrics.lock()->track_property("listfile", "update to new format"); + } + + // The files are sorted such that directories are placed just before the files they contain + // (They are not necessarily sorted alphabetically, e.g. libflac) + // Therefore we can detect the entries that represent directories by comparing every element with the next one + // and checking if the next has a slash immediately after the current one's length + for (size_t i = 0; i < lines->size() - 1; i++) + { + std::string& current_string = lines->at(i); + const std::string& next_string = lines->at(i + 1); + + const size_t potential_slash_char_index = current_string.length(); + // Make sure the index exists first + if (next_string.size() > potential_slash_char_index && next_string.at(potential_slash_char_index) == '/') + { + current_string += '/'; // Mark as a directory + } + } + + // After suffixing the directories with a slash, we can now sort. + // We cannot sort before adding the suffixes because the following (actual example): + /* + x86-windows/include/FLAC <<<<<< This would be separated from its group due to sorting + x86-windows/include/FLAC/all.h + x86-windows/include/FLAC/assert.h + x86-windows/include/FLAC/callback.h + x86-windows/include/FLAC++ + x86-windows/include/FLAC++/all.h + x86-windows/include/FLAC++/decoder.h + x86-windows/include/FLAC++/encoder.h + * + x86-windows/include/FLAC/ <<<<<< This will now be kept with its group when sorting + x86-windows/include/FLAC/all.h + x86-windows/include/FLAC/assert.h + x86-windows/include/FLAC/callback.h + x86-windows/include/FLAC++/ + x86-windows/include/FLAC++/all.h + x86-windows/include/FLAC++/decoder.h + x86-windows/include/FLAC++/encoder.h + */ + // Note that after sorting, the FLAC++/ group will be placed before the FLAC/ group + // The new format is lexicographically sorted + std::sort(lines->begin(), lines->end()); + + // Replace the listfile on disk + const fs::path updated_listfile_path = listfile_path.generic_string() + "_updated"; + fs.write_lines(updated_listfile_path, *lines); + fs.rename(updated_listfile_path, listfile_path); + } + + std::vector get_installed_ports(const StatusParagraphs& status_db) + { + std::vector installed_packages; + for (auto&& pgh : status_db) + { + if (pgh->state != InstallState::INSTALLED || pgh->want != Want::INSTALL) continue; + installed_packages.push_back(pgh.get()); + } + + return installed_packages; + } + + std::vector get_installed_files(const VcpkgPaths& paths, + const StatusParagraphs& status_db) + { + auto& fs = paths.get_filesystem(); + + std::vector installed_files; + + for (const std::unique_ptr& pgh : status_db) + { + if (pgh->state != InstallState::INSTALLED || !pgh->package.feature.empty()) + { + continue; + } + + const fs::path listfile_path = paths.listfile_path(pgh->package); + std::vector 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(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() == '/'; }); + + StatusParagraphAndAssociatedFiles pgh_and_files = { + *pgh, SortedVector(std::move(installed_files_of_current_pgh))}; + installed_files.push_back(std::move(pgh_and_files)); + } + + return installed_files; + } + + CMakeVariable::CMakeVariable(const CWStringView varname, const wchar_t* varvalue) + : s(Strings::wformat(LR"("-D%s=%s")", varname, varvalue)) + { + } + CMakeVariable::CMakeVariable(const CWStringView varname, const std::string& varvalue) + : CMakeVariable(varname, Strings::to_utf16(varvalue).c_str()) + { + } + CMakeVariable::CMakeVariable(const CWStringView varname, const std::wstring& varvalue) + : CMakeVariable(varname, varvalue.c_str()) + { + } + CMakeVariable::CMakeVariable(const CWStringView varname, const fs::path& path) + : CMakeVariable(varname, path.generic_wstring()) + { + } + + std::wstring make_cmake_cmd(const fs::path& cmake_exe, + const fs::path& cmake_script, + const std::vector& pass_variables) + { + const std::wstring cmd_cmake_pass_variables = Strings::join(L" ", pass_variables, [](auto&& v) { return v.s; }); + return Strings::wformat( + LR"("%s" %s -P "%s")", cmake_exe.native(), cmd_cmake_pass_variables, cmake_script.generic_wstring()); + } + + std::string shorten_text(const std::string& desc, size_t length) + { + Checks::check_exit(VCPKG_LINE_INFO, length >= 3); + auto simple_desc = std::regex_replace(desc, std::regex("\\s+"), " "); + return simple_desc.size() <= length ? simple_desc : simple_desc.substr(0, length - 3) + "..."; + } +} diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp new file mode 100644 index 000000000..e1a4acd69 --- /dev/null +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -0,0 +1,519 @@ +#include "pch.h" + +#include +#include +#include +#include +#include +#include +#include + +namespace vcpkg +{ + static constexpr CWStringView V_120 = L"v120"; + static constexpr CWStringView V_140 = L"v140"; + static constexpr CWStringView V_141 = L"v141"; + + static bool exists_and_has_equal_or_greater_version(const std::wstring& version_cmd, + const std::array& expected_version) + { + static const std::regex RE(R"###((\d+)\.(\d+)\.(\d+))###"); + + const auto rc = System::cmd_execute_and_capture_output(Strings::wformat(LR"(%s)", version_cmd)); + if (rc.exit_code != 0) + { + return false; + } + + std::match_results match; + const auto found = std::regex_search(rc.output, match, RE); + if (!found) + { + return false; + } + + const int d1 = atoi(match[1].str().c_str()); + const int d2 = atoi(match[2].str().c_str()); + const int d3 = atoi(match[3].str().c_str()); + if (d1 > expected_version[0] || (d1 == expected_version[0] && d2 > expected_version[1]) || + (d1 == expected_version[0] && d2 == expected_version[1] && d3 >= expected_version[2])) + { + // satisfactory version found + return true; + } + + return false; + } + + static Optional find_if_has_equal_or_greater_version(const std::vector& candidate_paths, + const std::wstring& version_check_arguments, + const std::array& expected_version) + { + auto it = Util::find_if(candidate_paths, [&](const fs::path& p) { + const std::wstring cmd = Strings::wformat(LR"("%s" %s)", p.native(), version_check_arguments); + return exists_and_has_equal_or_greater_version(cmd, expected_version); + }); + + if (it != candidate_paths.cend()) + { + return std::move(*it); + } + + return nullopt; + } + + static fs::path fetch_dependency(const fs::path& scripts_folder, + const std::wstring& tool_name, + const fs::path& expected_downloaded_path, + const std::array& version) + { + const std::string tool_name_utf8 = Strings::to_utf8(tool_name); + const std::string version_as_string = Strings::format("%d.%d.%d", version[0], version[1], version[2]); + System::println("A suitable version of %s was not found (required v%s). Downloading portable %s v%s...", + tool_name_utf8, + version_as_string, + tool_name_utf8, + version_as_string); + const fs::path script = scripts_folder / "fetchDependency.ps1"; + const auto install_cmd = + System::create_powershell_script_cmd(script, Strings::wformat(L"-Dependency %s", tool_name)); + const System::ExitCodeAndOutput rc = System::cmd_execute_and_capture_output(install_cmd); + if (rc.exit_code) + { + System::println(System::Color::error, + "Launching powershell failed or was denied when trying to fetch %s version %s.\n" + "(No sufficient installed version was found)", + tool_name_utf8, + version_as_string); + { + auto locked_metrics = Metrics::g_metrics.lock(); + locked_metrics->track_property("error", "powershell install failed"); + locked_metrics->track_property("dependency", tool_name); + } + Checks::exit_with_code(VCPKG_LINE_INFO, rc.exit_code); + } + + const fs::path actual_downloaded_path = Strings::trimmed(rc.output); + std::error_code ec; + const auto eq = fs::stdfs::equivalent(expected_downloaded_path, actual_downloaded_path, ec); + Checks::check_exit(VCPKG_LINE_INFO, + eq && !ec, + "Expected dependency downloaded path to be %s, but was %s", + expected_downloaded_path.u8string(), + actual_downloaded_path.u8string()); + return actual_downloaded_path; + } + + static fs::path get_cmake_path(const fs::path& downloads_folder, const fs::path& scripts_folder) + { + static constexpr std::array EXPECTED_VERSION = {3, 9, 3}; + static const std::wstring VERSION_CHECK_ARGUMENTS = L"--version"; + + const fs::path downloaded_copy = downloads_folder / "cmake-3.9.3-win32-x86" / "bin" / "cmake.exe"; + const std::vector from_path = Files::find_from_PATH(L"cmake"); + + std::vector candidate_paths; + candidate_paths.push_back(downloaded_copy); + candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); + candidate_paths.push_back(System::get_program_files_platform_bitness() / "CMake" / "bin" / "cmake.exe"); + candidate_paths.push_back(System::get_program_files_32_bit() / "CMake" / "bin"); + + const Optional path = + find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, EXPECTED_VERSION); + if (const auto p = path.get()) + { + return *p; + } + + return fetch_dependency(scripts_folder, L"cmake", downloaded_copy, EXPECTED_VERSION); + } + + fs::path get_nuget_path(const fs::path& downloads_folder, const fs::path& scripts_folder) + { + static constexpr std::array EXPECTED_VERSION = {4, 3, 0}; + static const std::wstring VERSION_CHECK_ARGUMENTS = Strings::WEMPTY; + + const fs::path downloaded_copy = downloads_folder / "nuget-4.3.0" / "nuget.exe"; + const std::vector from_path = Files::find_from_PATH(L"nuget"); + + std::vector candidate_paths; + candidate_paths.push_back(downloaded_copy); + candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); + + auto path = find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, EXPECTED_VERSION); + if (const auto p = path.get()) + { + return *p; + } + + return fetch_dependency(scripts_folder, L"nuget", downloaded_copy, EXPECTED_VERSION); + } + + fs::path get_git_path(const fs::path& downloads_folder, const fs::path& scripts_folder) + { + static constexpr std::array EXPECTED_VERSION = {2, 14, 1}; + static const std::wstring VERSION_CHECK_ARGUMENTS = L"--version"; + + const fs::path downloaded_copy = downloads_folder / "MinGit-2.14.1-32-bit" / "cmd" / "git.exe"; + const std::vector from_path = Files::find_from_PATH(L"git"); + + std::vector candidate_paths; + candidate_paths.push_back(downloaded_copy); + candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); + candidate_paths.push_back(System::get_program_files_platform_bitness() / "git" / "cmd" / "git.exe"); + candidate_paths.push_back(System::get_program_files_32_bit() / "git" / "cmd" / "git.exe"); + + const Optional path = + find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, EXPECTED_VERSION); + if (const auto p = path.get()) + { + return *p; + } + + return fetch_dependency(scripts_folder, L"git", downloaded_copy, EXPECTED_VERSION); + } + + static fs::path get_ifw_installerbase_path(const fs::path& downloads_folder, const fs::path& scripts_folder) + { + static constexpr std::array EXPECTED_VERSION = {3, 1, 81}; + static const std::wstring VERSION_CHECK_ARGUMENTS = L"--framework-version"; + + const fs::path downloaded_copy = + downloads_folder / "QtInstallerFramework-win-x86" / "bin" / "installerbase.exe"; + + std::vector candidate_paths; + candidate_paths.push_back(downloaded_copy); + // TODO: Uncomment later + // const std::vector from_path = Files::find_from_PATH(L"installerbase"); + // candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); + // candidate_paths.push_back(fs::path(System::get_environment_variable(L"HOMEDRIVE").value_or("C:")) / "Qt" / + // "Tools" / "QtInstallerFramework" / "3.1" / "bin" / "installerbase.exe"); + // candidate_paths.push_back(fs::path(System::get_environment_variable(L"HOMEDRIVE").value_or("C:")) / "Qt" / + // "QtIFW-3.1.0" / "bin" / "installerbase.exe"); + + const Optional path = + find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, EXPECTED_VERSION); + if (const auto p = path.get()) + { + return *p; + } + + return fetch_dependency(scripts_folder, L"installerbase", downloaded_copy, EXPECTED_VERSION); + } + + Expected VcpkgPaths::create(const fs::path& vcpkg_root_dir) + { + std::error_code ec; + const fs::path canonical_vcpkg_root_dir = fs::stdfs::canonical(vcpkg_root_dir, ec); + if (ec) + { + return ec; + } + + VcpkgPaths paths; + paths.root = canonical_vcpkg_root_dir; + + if (paths.root.empty()) + { + Metrics::g_metrics.lock()->track_property("error", "Invalid vcpkg root directory"); + Checks::exit_with_message(VCPKG_LINE_INFO, "Invalid vcpkg root directory: %s", paths.root.string()); + } + + paths.packages = paths.root / "packages"; + paths.buildtrees = paths.root / "buildtrees"; + paths.downloads = paths.root / "downloads"; + paths.ports = paths.root / "ports"; + paths.installed = paths.root / "installed"; + paths.triplets = paths.root / "triplets"; + paths.scripts = paths.root / "scripts"; + + paths.buildsystems = paths.scripts / "buildsystems"; + paths.buildsystems_msbuild_targets = paths.buildsystems / "msbuild" / "vcpkg.targets"; + + paths.vcpkg_dir = paths.installed / "vcpkg"; + paths.vcpkg_dir_status_file = paths.vcpkg_dir / "status"; + paths.vcpkg_dir_info = paths.vcpkg_dir / "info"; + paths.vcpkg_dir_updates = paths.vcpkg_dir / "updates"; + + paths.ports_cmake = paths.scripts / "ports.cmake"; + + return paths; + } + + fs::path VcpkgPaths::package_dir(const PackageSpec& spec) const { return this->packages / spec.dir(); } + + fs::path VcpkgPaths::port_dir(const PackageSpec& spec) const { return this->ports / spec.name(); } + fs::path VcpkgPaths::port_dir(const std::string& name) const { return this->ports / name; } + + fs::path VcpkgPaths::build_info_file_path(const PackageSpec& spec) const + { + return this->package_dir(spec) / "BUILD_INFO"; + } + + fs::path VcpkgPaths::listfile_path(const BinaryParagraph& pgh) const + { + return this->vcpkg_dir_info / (pgh.fullstem() + ".list"); + } + + bool VcpkgPaths::is_valid_triplet(const Triplet& t) const + { + for (auto&& path : get_filesystem().get_files_non_recursive(this->triplets)) + { + const 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 + return true; + } + } + return false; + } + + const fs::path& VcpkgPaths::get_cmake_exe() const + { + return this->cmake_exe.get_lazy([this]() { return get_cmake_path(this->downloads, this->scripts); }); + } + + const fs::path& VcpkgPaths::get_git_exe() const + { + return this->git_exe.get_lazy([this]() { return get_git_path(this->downloads, this->scripts); }); + } + + const fs::path& VcpkgPaths::get_nuget_exe() const + { + return this->nuget_exe.get_lazy([this]() { return get_nuget_path(this->downloads, this->scripts); }); + } + + const fs::path& VcpkgPaths::get_ifw_installerbase_exe() const + { + return this->ifw_installerbase_exe.get_lazy( + [this]() { return get_ifw_installerbase_path(this->downloads, this->scripts); }); + } + + const fs::path& VcpkgPaths::get_ifw_binarycreator_exe() const + { + return this->ifw_binarycreator_exe.get_lazy( + [this]() { return get_ifw_installerbase_exe().parent_path() / "binarycreator.exe"; }); + } + + const fs::path& VcpkgPaths::get_ifw_repogen_exe() const + { + return this->ifw_repogen_exe.get_lazy( + [this]() { return get_ifw_installerbase_exe().parent_path() / "repogen.exe"; }); + } + + struct VisualStudioInstance + { + fs::path root_path; + std::string version; + std::string release_type; + std::string preference_weight; // Mostly unused, just for verification that order is as intended + + std::string major_version() const { return version.substr(0, 2); } + }; + + static std::vector get_visual_studio_instances(const VcpkgPaths& paths) + { + const fs::path script = paths.scripts / "findVisualStudioInstallationInstances.ps1"; + const std::wstring cmd = System::create_powershell_script_cmd(script); + const System::ExitCodeAndOutput ec_data = System::cmd_execute_and_capture_output(cmd); + Checks::check_exit( + VCPKG_LINE_INFO, ec_data.exit_code == 0, "Could not run script to detect Visual Studio instances"); + + const std::vector instances_as_strings = Strings::split(ec_data.output, "\n"); + std::vector output; + for (const std::string& instance_as_string : instances_as_strings) + { + const std::vector split = Strings::split(instance_as_string, "::"); + output.push_back({split.at(3), split.at(2), split.at(1), split.at(0)}); + } + + return output; + } + + static std::vector find_toolset_instances(const VcpkgPaths& paths) + { + using CPU = System::CPUArchitecture; + + const auto& fs = paths.get_filesystem(); + + // Note: this will contain a mix of vcvarsall.bat locations and dumpbin.exe locations. + std::vector paths_examined; + + std::vector found_toolsets; + + const std::vector vs_instances = get_visual_studio_instances(paths); + const bool v140_is_available = Util::find_if(vs_instances, [&](const VisualStudioInstance& vs_instance) { + return vs_instance.major_version() == "14"; + }) != vs_instances.cend(); + + for (const VisualStudioInstance& vs_instance : vs_instances) + { + const std::string major_version = vs_instance.major_version(); + if (major_version == "15") + { + const fs::path vc_dir = vs_instance.root_path / "VC"; + + // Skip any instances that do not have vcvarsall. + const fs::path vcvarsall_dir = vc_dir / "Auxiliary" / "Build"; + const fs::path vcvarsall_bat = vcvarsall_dir / "vcvarsall.bat"; + paths_examined.push_back(vcvarsall_bat); + if (!fs.exists(vcvarsall_bat)) continue; + + // Get all supported architectures + std::vector supported_architectures; + if (fs.exists(vcvarsall_dir / "vcvars32.bat")) + supported_architectures.push_back({L"x86", CPU::X86, CPU::X86}); + if (fs.exists(vcvarsall_dir / "vcvars64.bat")) + supported_architectures.push_back({L"amd64", CPU::X64, CPU::X64}); + if (fs.exists(vcvarsall_dir / "vcvarsx86_amd64.bat")) + supported_architectures.push_back({L"x86_amd64", CPU::X86, CPU::X64}); + if (fs.exists(vcvarsall_dir / "vcvarsx86_arm.bat")) + supported_architectures.push_back({L"x86_arm", CPU::X86, CPU::ARM}); + if (fs.exists(vcvarsall_dir / "vcvarsamd64_x86.bat")) + supported_architectures.push_back({L"amd64_x86", CPU::X64, CPU::X86}); + if (fs.exists(vcvarsall_dir / "vcvarsamd64_arm.bat")) + supported_architectures.push_back({L"amd64_arm", CPU::X64, CPU::ARM}); + + // Locate the "best" MSVC toolchain version + const fs::path msvc_path = vc_dir / "Tools" / "MSVC"; + std::vector 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) { return left.filename() > right.filename(); }); + + for (const fs::path& subdir : msvc_subdirectories) + { + const fs::path dumpbin_path = subdir / "bin" / "HostX86" / "x86" / "dumpbin.exe"; + paths_examined.push_back(dumpbin_path); + if (fs.exists(dumpbin_path)) + { + found_toolsets.push_back(Toolset{ + vs_instance.root_path, dumpbin_path, vcvarsall_bat, {}, V_141, supported_architectures}); + + if (v140_is_available) + { + found_toolsets.push_back(Toolset{vs_instance.root_path, + dumpbin_path, + vcvarsall_bat, + {L"-vcvars_ver=14.0"}, + V_140, + supported_architectures}); + } + + break; + } + } + + continue; + } + + if (major_version == "14") + { + const fs::path vcvarsall_bat = vs_instance.root_path / "VC" / "vcvarsall.bat"; + + paths_examined.push_back(vcvarsall_bat); + if (fs.exists(vcvarsall_bat)) + { + const fs::path vs2015_dumpbin_exe = vs_instance.root_path / "VC" / "bin" / "dumpbin.exe"; + paths_examined.push_back(vs2015_dumpbin_exe); + + const fs::path vs2015_bin_dir = vcvarsall_bat.parent_path() / "bin"; + std::vector supported_architectures; + if (fs.exists(vs2015_bin_dir / "vcvars32.bat")) + supported_architectures.push_back({L"x86", CPU::X86, CPU::X86}); + if (fs.exists(vs2015_bin_dir / "amd64\\vcvars64.bat")) + supported_architectures.push_back({L"x64", CPU::X64, CPU::X64}); + if (fs.exists(vs2015_bin_dir / "x86_amd64\\vcvarsx86_amd64.bat")) + supported_architectures.push_back({L"x86_amd64", CPU::X86, CPU::X64}); + if (fs.exists(vs2015_bin_dir / "x86_arm\\vcvarsx86_arm.bat")) + supported_architectures.push_back({L"x86_arm", CPU::X86, CPU::ARM}); + if (fs.exists(vs2015_bin_dir / "amd64_x86\\vcvarsamd64_x86.bat")) + supported_architectures.push_back({L"amd64_x86", CPU::X64, CPU::X86}); + if (fs.exists(vs2015_bin_dir / "amd64_arm\\vcvarsamd64_arm.bat")) + supported_architectures.push_back({L"amd64_arm", CPU::X64, CPU::ARM}); + + if (fs.exists(vs2015_dumpbin_exe)) + { + found_toolsets.push_back({vs_instance.root_path, + vs2015_dumpbin_exe, + vcvarsall_bat, + {}, + V_140, + supported_architectures}); + } + } + } + } + + if (found_toolsets.empty()) + { + System::println(System::Color::error, "Could not locate a complete toolset."); + System::println("The following paths were examined:"); + for (const fs::path& path : paths_examined) + { + System::println(" %s", path.u8string()); + } + Checks::exit_fail(VCPKG_LINE_INFO); + } + + return found_toolsets; + } + + const Toolset& VcpkgPaths::get_toolset(const Optional& toolset_version, + const Optional& visual_studio_path) const + { + // Invariant: toolsets are non-empty and sorted with newest at back() + const std::vector& vs_toolsets = + this->toolsets.get_lazy([this]() { return find_toolset_instances(*this); }); + + std::vector candidates = Util::element_pointers(vs_toolsets); + const auto tsv = toolset_version.get(); + const auto vsp = visual_studio_path.get(); + + if (tsv && vsp) + { + const std::wstring w_toolset_version = Strings::to_utf16(*tsv); + const fs::path vs_root_path = *vsp; + Util::stable_keep_if(candidates, [&](const Toolset* t) { + return w_toolset_version == t->version && vs_root_path == t->visual_studio_root_path; + }); + Checks::check_exit(VCPKG_LINE_INFO, + !candidates.empty(), + "Could not find Visual Studio instace at %s with %s toolset.", + vs_root_path.generic_string(), + *tsv); + + Checks::check_exit(VCPKG_LINE_INFO, candidates.size() == 1); + return *candidates.back(); + } + + if (tsv) + { + const std::wstring w_toolset_version = Strings::to_utf16(*tsv); + Util::stable_keep_if(candidates, [&](const Toolset* t) { return w_toolset_version == t->version; }); + Checks::check_exit( + VCPKG_LINE_INFO, !candidates.empty(), "Could not find Visual Studio instace with %s toolset.", *tsv); + } + + if (vsp) + { + const fs::path vs_root_path = *vsp; + Util::stable_keep_if(candidates, + [&](const Toolset* t) { return vs_root_path == t->visual_studio_root_path; }); + Checks::check_exit(VCPKG_LINE_INFO, + !candidates.empty(), + "Could not find Visual Studio instace at %s.", + vs_root_path.generic_string()); + } + + return *candidates.front(); + } + + Files::Filesystem& VcpkgPaths::get_filesystem() const { return Files::get_real_filesystem(); } +} diff --git a/toolsrc/src/vcpkg/versiont.cpp b/toolsrc/src/vcpkg/versiont.cpp new file mode 100644 index 000000000..1c52d674a --- /dev/null +++ b/toolsrc/src/vcpkg/versiont.cpp @@ -0,0 +1,19 @@ +#include "pch.h" + +#include +#include + +namespace vcpkg +{ + VersionT::VersionT() : value("0.0.0") {} + VersionT::VersionT(const std::string& value) : value(value) {} + std::string VersionT::to_string() const { return value; } + bool operator==(const VersionT& left, const VersionT& right) { return left.value == right.value; } + bool operator!=(const VersionT& left, const VersionT& right) { return left.value != right.value; } + std::string to_printf_arg(const VersionT& version) { return version.value; } + + VersionDiff::VersionDiff() : left(), right() {} + VersionDiff::VersionDiff(const VersionT& left, const VersionT& right) : left(left), right(right) {} + + std::string VersionDiff::to_string() const { return Strings::format("%s -> %s", left.value, right.value); } +} diff --git a/toolsrc/src/vcpkg_Build.cpp b/toolsrc/src/vcpkg_Build.cpp deleted file mode 100644 index 9be20629d..000000000 --- a/toolsrc/src/vcpkg_Build.cpp +++ /dev/null @@ -1,406 +0,0 @@ -#include "pch.h" - -#include "Paragraphs.h" -#include "PostBuildLint.h" -#include "metrics.h" -#include "vcpkg_Build.h" -#include "vcpkg_Checks.h" -#include "vcpkg_Chrono.h" -#include "vcpkg_Commands.h" -#include "vcpkg_Enums.h" -#include "vcpkg_GlobalState.h" -#include "vcpkg_System.h" -#include "vcpkg_optional.h" -#include "vcpkglib.h" - -namespace vcpkg::Build -{ - Optional to_linkage_type(const std::string& str) - { - if (str == "dynamic") return LinkageType::DYNAMIC; - if (str == "static") return LinkageType::STATIC; - return nullopt; - } - - namespace BuildInfoRequiredField - { - static const std::string CRT_LINKAGE = "CRTLinkage"; - static const std::string LIBRARY_LINKAGE = "LibraryLinkage"; - } - - CWStringView to_vcvarsall_target(const std::string& cmake_system_name) - { - if (cmake_system_name == Strings::EMPTY) return Strings::WEMPTY; - if (cmake_system_name == "Windows") return Strings::WEMPTY; - if (cmake_system_name == "WindowsStore") return L"store"; - - Checks::exit_with_message(VCPKG_LINE_INFO, "Unsupported vcvarsall target %s", cmake_system_name); - } - - CWStringView to_vcvarsall_toolchain(const std::string& target_architecture, const Toolset& toolset) - { - auto maybe_target_arch = System::to_cpu_architecture(target_architecture); - Checks::check_exit( - VCPKG_LINE_INFO, maybe_target_arch.has_value(), "Invalid architecture string: %s", target_architecture); - auto target_arch = maybe_target_arch.value_or_exit(VCPKG_LINE_INFO); - auto host_architectures = System::get_supported_host_architectures(); - - for (auto&& host : host_architectures) - { - auto it = Util::find_if(toolset.supported_architectures, [&](const ToolsetArchOption& opt) { - return host == opt.host_arch && target_arch == opt.target_arch; - }); - if (it != toolset.supported_architectures.end()) return it->name; - } - - Checks::exit_with_message(VCPKG_LINE_INFO, "Unsupported toolchain combination %s", target_architecture); - } - - std::wstring make_build_env_cmd(const PreBuildInfo& pre_build_info, const Toolset& toolset) - { - const wchar_t* tonull = L" >nul"; - if (GlobalState::debugging) - { - tonull = Strings::WEMPTY; - } - - const auto arch = to_vcvarsall_toolchain(pre_build_info.target_architecture, toolset); - const auto target = to_vcvarsall_target(pre_build_info.cmake_system_name); - - return Strings::wformat(LR"("%s" %s %s %s %s 2>&1)", - toolset.vcvarsall.native(), - Strings::join(L" ", toolset.vcvarsall_options), - arch, - target, - tonull); - } - - static void create_binary_feature_control_file(const SourceParagraph& source_paragraph, - const FeatureParagraph& feature_paragraph, - const Triplet& triplet, - BinaryControlFile& bcf) - { - BinaryParagraph bpgh(source_paragraph, feature_paragraph, triplet); - bcf.features.emplace_back(std::move(bpgh)); - } - - static void create_binary_control_file(const SourceParagraph& source_paragraph, - const Triplet& triplet, - const BuildInfo& build_info, - BinaryControlFile& bcf) - { - BinaryParagraph bpgh(source_paragraph, triplet); - if (const auto p_ver = build_info.version.get()) - { - bpgh.version = *p_ver; - } - bcf.core_paragraph = std::move(bpgh); - } - - static void write_binary_control_file(const VcpkgPaths& paths, BinaryControlFile bcf) - { - std::string start = Strings::serialize(bcf.core_paragraph); - for (auto&& feature : bcf.features) - { - start += "\n" + Strings::serialize(feature); - } - const fs::path binary_control_file = paths.packages / bcf.core_paragraph.dir() / "CONTROL"; - paths.get_filesystem().write_contents(binary_control_file, start); - } - - ExtendedBuildResult build_package(const VcpkgPaths& paths, - const BuildPackageConfig& config, - const StatusParagraphs& status_db) - { - const PackageSpec spec = - PackageSpec::from_name_and_triplet(config.src.name, config.triplet).value_or_exit(VCPKG_LINE_INFO); - - const Triplet& triplet = config.triplet; - { - std::vector missing_specs; - for (auto&& dep : filter_dependencies(config.src.depends, triplet)) - { - if (status_db.find_installed(dep, triplet) == status_db.end()) - { - missing_specs.push_back( - PackageSpec::from_name_and_triplet(dep, triplet).value_or_exit(VCPKG_LINE_INFO)); - } - } - // Fail the build if any dependencies were missing - if (!missing_specs.empty()) - { - return {BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES, std::move(missing_specs)}; - } - } - - const fs::path& cmake_exe_path = paths.get_cmake_exe(); - const fs::path& git_exe_path = paths.get_git_exe(); - - const fs::path ports_cmake_script_path = paths.ports_cmake; - const auto pre_build_info = PreBuildInfo::from_triplet_file(paths, triplet); - const Toolset& toolset = paths.get_toolset(pre_build_info.platform_toolset, pre_build_info.visual_studio_path); - const auto cmd_set_environment = make_build_env_cmd(pre_build_info, toolset); - - std::string features; - if (GlobalState::feature_packages) - { - if (config.feature_list) - { - for (auto&& feature : *config.feature_list) - { - features.append(feature + ";"); - } - if (features.size() > 0) - { - features.pop_back(); - } - } - } - - const std::wstring cmd_launch_cmake = make_cmake_cmd( - cmake_exe_path, - ports_cmake_script_path, - { - {L"CMD", L"BUILD"}, - {L"PORT", config.src.name}, - {L"CURRENT_PORT_DIR", config.port_dir / "/."}, - {L"TARGET_TRIPLET", triplet.canonical_name()}, - {L"VCPKG_PLATFORM_TOOLSET", toolset.version.c_str()}, - {L"VCPKG_USE_HEAD_VERSION", to_bool(config.build_package_options.use_head_version) ? L"1" : L"0"}, - {L"_VCPKG_NO_DOWNLOADS", !to_bool(config.build_package_options.allow_downloads) ? L"1" : L"0"}, - {L"GIT", git_exe_path}, - {L"FEATURES", features}, - }); - - const std::wstring command = Strings::wformat(LR"(%s && %s)", cmd_set_environment, cmd_launch_cmake); - - const ElapsedTime timer = ElapsedTime::create_started(); - - const int return_code = System::cmd_execute_clean(command); - const auto buildtimeus = timer.microseconds(); - const auto spec_string = spec.to_string(); - - { - auto locked_metrics = Metrics::g_metrics.lock(); - locked_metrics->track_metric("buildtimeus-" + spec_string, buildtimeus); - if (return_code != 0) - { - locked_metrics->track_property("error", "build failed"); - locked_metrics->track_property("build_error", spec_string); - return {BuildResult::BUILD_FAILED, {}}; - } - } - - const BuildInfo build_info = read_build_info(paths.get_filesystem(), paths.build_info_file_path(spec)); - const size_t error_count = PostBuildLint::perform_all_checks(spec, paths, pre_build_info, build_info); - - BinaryControlFile bcf; - - create_binary_control_file(config.src, triplet, build_info, bcf); - - if (error_count != 0) - { - return {BuildResult::POST_BUILD_CHECKS_FAILED, {}}; - } - if (GlobalState::feature_packages) - { - if (config.feature_list) - { - for (auto&& feature : *config.feature_list) - { - for (auto&& f_pgh : config.scf->feature_paragraphs) - { - if (f_pgh->name == feature) - create_binary_feature_control_file(*config.scf->core_paragraph, *f_pgh, triplet, bcf); - } - } - } - } - - write_binary_control_file(paths, bcf); - - // const fs::path port_buildtrees_dir = paths.buildtrees / spec.name; - // delete_directory(port_buildtrees_dir); - - return {BuildResult::SUCCEEDED, {}}; - } - - const std::string& to_string(const BuildResult build_result) - { - static const std::string NULLVALUE_STRING = Enums::nullvalue_to_string("vcpkg::Commands::Build::BuildResult"); - static const std::string SUCCEEDED_STRING = "SUCCEEDED"; - static const std::string BUILD_FAILED_STRING = "BUILD_FAILED"; - static const std::string FILE_CONFLICTS_STRING = "FILE_CONFLICTS"; - static const std::string POST_BUILD_CHECKS_FAILED_STRING = "POST_BUILD_CHECKS_FAILED"; - static const std::string CASCADED_DUE_TO_MISSING_DEPENDENCIES_STRING = "CASCADED_DUE_TO_MISSING_DEPENDENCIES"; - - switch (build_result) - { - case BuildResult::NULLVALUE: return NULLVALUE_STRING; - case BuildResult::SUCCEEDED: return SUCCEEDED_STRING; - case BuildResult::BUILD_FAILED: return BUILD_FAILED_STRING; - case BuildResult::POST_BUILD_CHECKS_FAILED: return POST_BUILD_CHECKS_FAILED_STRING; - case BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES: return CASCADED_DUE_TO_MISSING_DEPENDENCIES_STRING; - case BuildResult::FILE_CONFLICTS: return FILE_CONFLICTS_STRING; - default: Checks::unreachable(VCPKG_LINE_INFO); - } - } - - std::string create_error_message(const BuildResult build_result, const PackageSpec& spec) - { - return Strings::format("Error: Building package %s failed with: %s", spec, Build::to_string(build_result)); - } - - std::string create_user_troubleshooting_message(const PackageSpec& spec) - { - return Strings::format("Please ensure you're using the latest portfiles with `.\\vcpkg update`, then\n" - "submit an issue at https://github.com/Microsoft/vcpkg/issues including:\n" - " Package: %s\n" - " Vcpkg version: %s\n" - "\n" - "Additionally, attach any relevant sections from the log files above.", - spec, - Commands::Version::version()); - } - - static BuildInfo inner_create_buildinfo(std::unordered_map pgh) - { - Parse::ParagraphParser parser(std::move(pgh)); - - BuildInfo build_info; - - { - std::string crt_linkage_as_string; - parser.required_field(BuildInfoRequiredField::CRT_LINKAGE, crt_linkage_as_string); - - auto crtlinkage = to_linkage_type(crt_linkage_as_string); - if (const auto p = crtlinkage.get()) - build_info.crt_linkage = *p; - else - Checks::exit_with_message(VCPKG_LINE_INFO, "Invalid crt linkage type: [%s]", crt_linkage_as_string); - } - - { - std::string library_linkage_as_string; - parser.required_field(BuildInfoRequiredField::LIBRARY_LINKAGE, library_linkage_as_string); - auto liblinkage = to_linkage_type(library_linkage_as_string); - if (const auto p = liblinkage.get()) - build_info.library_linkage = *p; - else - Checks::exit_with_message( - VCPKG_LINE_INFO, "Invalid library linkage type: [%s]", library_linkage_as_string); - } - std::string version = parser.optional_field("Version"); - if (!version.empty()) build_info.version = std::move(version); - - std::map policies; - for (auto policy : G_ALL_POLICIES) - { - const auto setting = parser.optional_field(to_string(policy)); - if (setting.empty()) continue; - if (setting == "enabled") - policies.emplace(policy, true); - else if (setting == "disabled") - policies.emplace(policy, false); - else - Checks::exit_with_message( - VCPKG_LINE_INFO, "Unknown setting for policy '%s': %s", to_string(policy), setting); - } - - if (const auto err = parser.error_info("PostBuildInformation")) - { - print_error_message(err); - Checks::exit_fail(VCPKG_LINE_INFO); - } - - build_info.policies = BuildPolicies(std::move(policies)); - - return build_info; - } - - BuildInfo read_build_info(const Files::Filesystem& fs, const fs::path& filepath) - { - const Expected> pghs = - Paragraphs::get_single_paragraph(fs, filepath); - Checks::check_exit(VCPKG_LINE_INFO, pghs.get() != nullptr, "Invalid BUILD_INFO file for package"); - return inner_create_buildinfo(*pghs.get()); - } - - PreBuildInfo PreBuildInfo::from_triplet_file(const VcpkgPaths& paths, const Triplet& triplet) - { - static constexpr CStringView FLAG_GUID = "c35112b6-d1ba-415b-aa5d-81de856ef8eb"; - - const fs::path& cmake_exe_path = paths.get_cmake_exe(); - const fs::path ports_cmake_script_path = paths.scripts / "get_triplet_environment.cmake"; - const fs::path triplet_file_path = paths.triplets / (triplet.canonical_name() + ".cmake"); - - const std::wstring cmd_launch_cmake = make_cmake_cmd(cmake_exe_path, - ports_cmake_script_path, - { - {L"CMAKE_TRIPLET_FILE", triplet_file_path}, - }); - - const std::wstring command = Strings::wformat(LR"(%s)", cmd_launch_cmake); - const auto ec_data = System::cmd_execute_and_capture_output(command); - Checks::check_exit(VCPKG_LINE_INFO, ec_data.exit_code == 0); - - const std::vector lines = Strings::split(ec_data.output, "\n"); - - PreBuildInfo pre_build_info; - - const auto e = lines.cend(); - auto cur = std::find(lines.cbegin(), e, FLAG_GUID); - if (cur != e) ++cur; - - for (; cur != e; ++cur) - { - auto&& line = *cur; - - const std::vector s = Strings::split(line, "="); - Checks::check_exit(VCPKG_LINE_INFO, - s.size() == 1 || s.size() == 2, - "Expected format is [VARIABLE_NAME=VARIABLE_VALUE], but was [%s]", - line); - - const bool variable_with_no_value = s.size() == 1; - const std::string variable_name = s.at(0); - const std::string variable_value = variable_with_no_value ? Strings::EMPTY : s.at(1); - - if (variable_name == "VCPKG_TARGET_ARCHITECTURE") - { - pre_build_info.target_architecture = variable_value; - continue; - } - - if (variable_name == "VCPKG_CMAKE_SYSTEM_NAME") - { - pre_build_info.cmake_system_name = variable_value; - continue; - } - - if (variable_name == "VCPKG_CMAKE_SYSTEM_VERSION") - { - pre_build_info.cmake_system_version = variable_value; - continue; - } - - if (variable_name == "VCPKG_PLATFORM_TOOLSET") - { - pre_build_info.platform_toolset = - variable_value.empty() ? nullopt : Optional{variable_value}; - continue; - } - - if (variable_name == "VCPKG_VISUAL_STUDIO_PATH") - { - pre_build_info.visual_studio_path = - variable_value.empty() ? nullopt : Optional{variable_value}; - continue; - } - - Checks::exit_with_message(VCPKG_LINE_INFO, "Unknown variable name %s", line); - } - - return pre_build_info; - } -} diff --git a/toolsrc/src/vcpkg_Build_BuildPolicy.cpp b/toolsrc/src/vcpkg_Build_BuildPolicy.cpp deleted file mode 100644 index b3bb778dc..000000000 --- a/toolsrc/src/vcpkg_Build_BuildPolicy.cpp +++ /dev/null @@ -1,40 +0,0 @@ -#include "pch.h" - -#include "vcpkg_Build.h" -#include "vcpkg_Checks.h" -#include "vcpkg_Enums.h" - -namespace vcpkg::Build -{ - static const std::string NAME_EMPTY_PACKAGE = "PolicyEmptyPackage"; - static const std::string NAME_DLLS_WITHOUT_LIBS = "PolicyDLLsWithoutLIBs"; - static const std::string NAME_ONLY_RELEASE_CRT = "PolicyOnlyReleaseCRT"; - static const std::string NAME_EMPTY_INCLUDE_FOLDER = "PolicyEmptyIncludeFolder"; - static const std::string NAME_ALLOW_OBSOLETE_MSVCRT = "PolicyAllowObsoleteMsvcrt"; - - const std::string& to_string(BuildPolicy policy) - { - switch (policy) - { - case BuildPolicy::EMPTY_PACKAGE: return NAME_EMPTY_PACKAGE; - case BuildPolicy::DLLS_WITHOUT_LIBS: return NAME_DLLS_WITHOUT_LIBS; - case BuildPolicy::ONLY_RELEASE_CRT: return NAME_ONLY_RELEASE_CRT; - case BuildPolicy::EMPTY_INCLUDE_FOLDER: return NAME_EMPTY_INCLUDE_FOLDER; - case BuildPolicy::ALLOW_OBSOLETE_MSVCRT: return NAME_ALLOW_OBSOLETE_MSVCRT; - default: Checks::unreachable(VCPKG_LINE_INFO); - } - } - - CStringView to_cmake_variable(BuildPolicy policy) - { - switch (policy) - { - case BuildPolicy::EMPTY_PACKAGE: return "VCPKG_POLICY_EMPTY_PACKAGE"; - case BuildPolicy::DLLS_WITHOUT_LIBS: return "VCPKG_POLICY_DLLS_WITHOUT_LIBS"; - case BuildPolicy::ONLY_RELEASE_CRT: return "VCPKG_POLICY_ONLY_RELEASE_CRT"; - case BuildPolicy::EMPTY_INCLUDE_FOLDER: return "VCPKG_POLICY_EMPTY_INCLUDE_FOLDER"; - case BuildPolicy::ALLOW_OBSOLETE_MSVCRT: return "VCPKG_POLICY_ALLOW_OBSOLETE_MSVCRT"; - default: Checks::unreachable(VCPKG_LINE_INFO); - } - } -} diff --git a/toolsrc/src/vcpkg_Checks.cpp b/toolsrc/src/vcpkg_Checks.cpp deleted file mode 100644 index e7c9046a4..000000000 --- a/toolsrc/src/vcpkg_Checks.cpp +++ /dev/null @@ -1,81 +0,0 @@ -#include "pch.h" - -#include "metrics.h" -#include "vcpkg_Checks.h" -#include "vcpkg_GlobalState.h" -#include "vcpkg_System.h" -#include "vcpkglib.h" - -namespace vcpkg::Checks -{ - [[noreturn]] static void cleanup_and_exit(const int exit_code) - { - const auto elapsed_us = GlobalState::timer.lock()->microseconds(); - - auto metrics = Metrics::g_metrics.lock(); - metrics->track_metric("elapsed_us", elapsed_us); - GlobalState::debugging = false; - metrics->flush(); - - SetConsoleCP(GlobalState::g_init_console_cp); - SetConsoleOutputCP(GlobalState::g_init_console_output_cp); - - fflush(nullptr); - - ::TerminateProcess(::GetCurrentProcess(), exit_code); - } - - static BOOL ctrl_handler(DWORD fdw_ctrl_type) - { - { - auto locked_metrics = Metrics::g_metrics.lock(); - locked_metrics->track_property("CtrlHandler", std::to_string(fdw_ctrl_type)); - locked_metrics->track_property("error", "CtrlHandler was fired."); - } - cleanup_and_exit(EXIT_FAILURE); - } - - void register_console_ctrl_handler() - { - SetConsoleCtrlHandler(reinterpret_cast(ctrl_handler), TRUE); - } - - [[noreturn]] void unreachable(const LineInfo& line_info) - { - System::println(System::Color::error, "Error: Unreachable code was reached"); - System::println(System::Color::error, line_info.to_string()); // Always print line_info here -#ifndef NDEBUG - std::abort(); -#else - cleanup_and_exit(EXIT_FAILURE); -#endif - } - - [[noreturn]] void exit_with_code(const LineInfo& line_info, const int exit_code) - { - Debug::println(System::Color::error, line_info.to_string()); - cleanup_and_exit(exit_code); - } - - [[noreturn]] void exit_with_message(const LineInfo& line_info, const CStringView error_message) - { - System::println(System::Color::error, error_message); - exit_fail(line_info); - } - - void check_exit(const LineInfo& line_info, bool expression) - { - if (!expression) - { - exit_with_message(line_info, Strings::EMPTY); - } - } - - void check_exit(const LineInfo& line_info, bool expression, const CStringView error_message) - { - if (!expression) - { - exit_with_message(line_info, error_message); - } - } -} diff --git a/toolsrc/src/vcpkg_Chrono.cpp b/toolsrc/src/vcpkg_Chrono.cpp deleted file mode 100644 index d96f30987..000000000 --- a/toolsrc/src/vcpkg_Chrono.cpp +++ /dev/null @@ -1,61 +0,0 @@ -#include "pch.h" - -#include "vcpkg_Checks.h" -#include "vcpkg_Chrono.h" - -namespace vcpkg -{ - static std::string format_time_userfriendly(const std::chrono::nanoseconds& nanos) - { - using std::chrono::duration_cast; - using std::chrono::hours; - using std::chrono::microseconds; - using std::chrono::milliseconds; - using std::chrono::minutes; - using std::chrono::nanoseconds; - using std::chrono::seconds; - - const double nanos_as_double = static_cast(nanos.count()); - - if (duration_cast(nanos) > hours()) - { - const auto t = nanos_as_double / duration_cast(hours(1)).count(); - return Strings::format("%.4g h", t); - } - - if (duration_cast(nanos) > minutes()) - { - const auto t = nanos_as_double / duration_cast(minutes(1)).count(); - return Strings::format("%.4g min", t); - } - - if (duration_cast(nanos) > seconds()) - { - const auto t = nanos_as_double / duration_cast(seconds(1)).count(); - return Strings::format("%.4g s", t); - } - - if (duration_cast(nanos) > milliseconds()) - { - const auto t = nanos_as_double / duration_cast(milliseconds(1)).count(); - return Strings::format("%.4g ms", t); - } - - if (duration_cast(nanos) > microseconds()) - { - const auto t = nanos_as_double / duration_cast(microseconds(1)).count(); - return Strings::format("%.4g us", t); - } - - return Strings::format("%.4g ns", nanos_as_double); - } - - ElapsedTime ElapsedTime::create_started() - { - ElapsedTime t; - t.m_start_tick = std::chrono::high_resolution_clock::now(); - return t; - } - - std::string ElapsedTime::to_string() const { return format_time_userfriendly(elapsed()); } -} diff --git a/toolsrc/src/vcpkg_Dependencies.cpp b/toolsrc/src/vcpkg_Dependencies.cpp deleted file mode 100644 index 8dd60a2eb..000000000 --- a/toolsrc/src/vcpkg_Dependencies.cpp +++ /dev/null @@ -1,669 +0,0 @@ -#include "pch.h" - -#include "PackageSpec.h" -#include "Paragraphs.h" -#include "StatusParagraphs.h" -#include "VcpkgPaths.h" -#include "vcpkg_Dependencies.h" -#include "vcpkg_Files.h" -#include "vcpkg_Graphs.h" -#include "vcpkg_Strings.h" -#include "vcpkg_Util.h" -#include "vcpkglib.h" - -namespace vcpkg::Dependencies -{ - struct FeatureNodeEdges - { - std::vector remove_edges; - std::vector build_edges; - bool plus = false; - }; - - struct Cluster : Util::MoveOnlyBase - { - std::vector status_paragraphs; - Optional source_control_file; - PackageSpec spec; - std::unordered_map edges; - std::unordered_set to_install_features; - std::unordered_set original_features; - bool will_remove = false; - bool transient_uninstalled = true; - RequestType request_type = RequestType::AUTO_SELECTED; - }; - - struct ClusterPtr - { - Cluster* ptr; - - Cluster* operator->() const { return ptr; } - }; - - bool operator==(const ClusterPtr& l, const ClusterPtr& r) { return l.ptr == r.ptr; } -} - -template<> -struct std::hash -{ - size_t operator()(const vcpkg::Dependencies::ClusterPtr& value) const - { - return std::hash()(value.ptr->spec); - } -}; - -namespace vcpkg::Dependencies -{ - struct GraphPlan - { - Graphs::Graph remove_graph; - Graphs::Graph install_graph; - }; - - struct ClusterGraph : Util::MoveOnlyBase - { - explicit ClusterGraph(std::unordered_map&& ports) - : m_ports(std::move(ports)) - { - } - - Cluster& get(const PackageSpec& spec) - { - auto it = m_graph.find(spec); - if (it == m_graph.end()) - { - // Load on-demand from m_ports - auto it_ports = m_ports.find(spec.name()); - if (it_ports != m_ports.end()) - { - auto& clust = m_graph[spec]; - clust.spec = spec; - cluster_from_scf(*it_ports->second, clust); - return clust; - } - return m_graph[spec]; - } - return it->second; - } - - private: - void cluster_from_scf(const SourceControlFile& scf, Cluster& out_cluster) const - { - FeatureNodeEdges core_dependencies; - core_dependencies.build_edges = - filter_dependencies_to_specs(scf.core_paragraph->depends, out_cluster.spec.triplet()); - out_cluster.edges.emplace("core", std::move(core_dependencies)); - - for (const auto& feature : scf.feature_paragraphs) - { - FeatureNodeEdges added_edges; - added_edges.build_edges = filter_dependencies_to_specs(feature->depends, out_cluster.spec.triplet()); - out_cluster.edges.emplace(feature->name, std::move(added_edges)); - } - out_cluster.source_control_file = &scf; - } - - std::unordered_map m_graph; - std::unordered_map m_ports; - }; - - std::vector AnyParagraph::dependencies(const Triplet& triplet) const - { - auto to_package_specs = [&](const std::vector& dependencies_as_string) { - return Util::fmap(dependencies_as_string, [&](const std::string s) { - return PackageSpec::from_name_and_triplet(s, triplet).value_or_exit(VCPKG_LINE_INFO); - }); - }; - - if (auto p = this->status_paragraph.get()) - { - return to_package_specs(p->package.depends); - } - - if (auto p = this->binary_control_file.get()) - { - auto deps = Util::fmap_flatten(p->features, [](const BinaryParagraph& pgh) { return pgh.depends; }); - deps.insert(deps.end(), p->core_paragraph.depends.begin(), p->core_paragraph.depends.end()); - return to_package_specs(deps); - } - - if (auto p = this->source_paragraph.get()) - { - return to_package_specs(filter_dependencies(p->depends, triplet)); - } - - Checks::exit_with_message(VCPKG_LINE_INFO, - "Cannot get dependencies because there was none of: source/binary/status paragraphs"); - } - - std::string to_output_string(RequestType request_type, const CStringView s) - { - switch (request_type) - { - case RequestType::AUTO_SELECTED: return Strings::format(" * %s", s); - case RequestType::USER_REQUESTED: return Strings::format(" %s", s); - default: Checks::unreachable(VCPKG_LINE_INFO); - } - } - - InstallPlanAction::InstallPlanAction() : plan_type(InstallPlanType::UNKNOWN), request_type(RequestType::UNKNOWN) {} - - InstallPlanAction::InstallPlanAction(const PackageSpec& spec, - const SourceControlFile& any_paragraph, - const std::unordered_set& features, - const RequestType& request_type) - : spec(spec), plan_type(InstallPlanType::BUILD_AND_INSTALL), request_type(request_type), feature_list(features) - { - this->any_paragraph.source_control_file = &any_paragraph; - } - - InstallPlanAction::InstallPlanAction(const PackageSpec& spec, - const std::unordered_set& features, - const RequestType& request_type) - : spec(spec), plan_type(InstallPlanType::ALREADY_INSTALLED), request_type(request_type), feature_list(features) - { - } - - InstallPlanAction::InstallPlanAction(const PackageSpec& spec, - const AnyParagraph& any_paragraph, - const RequestType& request_type) - : spec(spec), any_paragraph(any_paragraph), plan_type(InstallPlanType::UNKNOWN), request_type(request_type) - { - if (auto p = any_paragraph.status_paragraph.get()) - { - this->plan_type = InstallPlanType::ALREADY_INSTALLED; - return; - } - - if (auto p = any_paragraph.binary_control_file.get()) - { - this->plan_type = InstallPlanType::INSTALL; - return; - } - - if (auto p = any_paragraph.source_paragraph.get()) - { - this->plan_type = InstallPlanType::BUILD_AND_INSTALL; - return; - } - } - - std::string InstallPlanAction::displayname() const - { - if (this->feature_list.empty()) - { - return this->spec.to_string(); - } - - const std::string features = Strings::join(",", this->feature_list); - return Strings::format("%s[%s]:%s", this->spec.name(), features, this->spec.triplet()); - } - - bool InstallPlanAction::compare_by_name(const InstallPlanAction* left, const InstallPlanAction* right) - { - return left->spec.name() < right->spec.name(); - } - - RemovePlanAction::RemovePlanAction() : plan_type(RemovePlanType::UNKNOWN), request_type(RequestType::UNKNOWN) {} - - RemovePlanAction::RemovePlanAction(const PackageSpec& spec, - const RemovePlanType& plan_type, - const RequestType& request_type) - : spec(spec), plan_type(plan_type), request_type(request_type) - { - } - - const PackageSpec& AnyAction::spec() const - { - if (const auto p = install_plan.get()) - { - return p->spec; - } - - if (const auto p = remove_plan.get()) - { - return p->spec; - } - - Checks::exit_with_message(VCPKG_LINE_INFO, "Null action"); - } - - bool ExportPlanAction::compare_by_name(const ExportPlanAction* left, const ExportPlanAction* right) - { - return left->spec.name() < right->spec.name(); - } - - ExportPlanAction::ExportPlanAction() : plan_type(ExportPlanType::UNKNOWN), request_type(RequestType::UNKNOWN) {} - - ExportPlanAction::ExportPlanAction(const PackageSpec& spec, - const AnyParagraph& any_paragraph, - const RequestType& request_type) - : spec(spec), any_paragraph(any_paragraph), plan_type(ExportPlanType::UNKNOWN), request_type(request_type) - { - if (auto p = any_paragraph.binary_control_file.get()) - { - this->plan_type = ExportPlanType::ALREADY_BUILT; - return; - } - - if (auto p = any_paragraph.source_paragraph.get()) - { - this->plan_type = ExportPlanType::PORT_AVAILABLE_BUT_NOT_BUILT; - return; - } - } - - bool RemovePlanAction::compare_by_name(const RemovePlanAction* left, const RemovePlanAction* right) - { - return left->spec.name() < right->spec.name(); - } - - MapPortFile::MapPortFile(const std::unordered_map& map) : ports(map) {} - - const SourceControlFile& MapPortFile::get_control_file(const std::string& spec) const - { - auto scf = ports.find(spec); - if (scf == ports.end()) - { - Checks::exit_fail(VCPKG_LINE_INFO); - } - return scf->second; - } - - PathsPortFile::PathsPortFile(const VcpkgPaths& paths) : ports(paths) {} - - const SourceControlFile& PathsPortFile::get_control_file(const std::string& spec) const - { - auto cache_it = cache.find(spec); - if (cache_it != cache.end()) - { - return cache_it->second; - } - Parse::ParseExpected source_control_file = - Paragraphs::try_load_port(ports.get_filesystem(), ports.port_dir(spec)); - - if (auto scf = source_control_file.get()) - { - auto it = cache.emplace(spec, std::move(*scf->get())); - return it.first->second; - } - print_error_message(source_control_file.error()); - Checks::exit_fail(VCPKG_LINE_INFO); - } - - std::vector create_install_plan(const PortFileProvider& port_file_provider, - const std::vector& specs, - const StatusParagraphs& status_db) - { - struct InstallAdjacencyProvider final : Graphs::AdjacencyProvider - { - const PortFileProvider& port_file_provider; - const StatusParagraphs& status_db; - const std::unordered_set& specs_as_set; - - InstallAdjacencyProvider(const PortFileProvider& port_file_provider, - const StatusParagraphs& s, - const std::unordered_set& specs_as_set) - : port_file_provider(port_file_provider), status_db(s), specs_as_set(specs_as_set) - { - } - - std::vector adjacency_list(const InstallPlanAction& plan) const override - { - if (plan.any_paragraph.status_paragraph.get()) return std::vector{}; - return plan.any_paragraph.dependencies(plan.spec.triplet()); - } - - InstallPlanAction load_vertex_data(const PackageSpec& spec) const override - { - const RequestType request_type = specs_as_set.find(spec) != specs_as_set.end() - ? RequestType::USER_REQUESTED - : RequestType::AUTO_SELECTED; - auto it = status_db.find_installed(spec); - if (it != status_db.end()) return InstallPlanAction{spec, {*it->get(), nullopt, nullopt}, request_type}; - return InstallPlanAction{ - spec, - {nullopt, nullopt, *port_file_provider.get_control_file(spec.name()).core_paragraph}, - request_type}; - } - }; - - const std::unordered_set specs_as_set(specs.cbegin(), specs.cend()); - std::vector toposort = - Graphs::topological_sort(specs, InstallAdjacencyProvider{port_file_provider, status_db, specs_as_set}); - Util::erase_remove_if(toposort, [](const InstallPlanAction& plan) { - return plan.request_type == RequestType::AUTO_SELECTED && - plan.plan_type == InstallPlanType::ALREADY_INSTALLED; - }); - - return toposort; - } - - std::vector create_remove_plan(const std::vector& specs, - const StatusParagraphs& status_db) - { - struct RemoveAdjacencyProvider final : Graphs::AdjacencyProvider - { - const StatusParagraphs& status_db; - const std::vector& installed_ports; - const std::unordered_set& specs_as_set; - - RemoveAdjacencyProvider(const StatusParagraphs& status_db, - const std::vector& installed_ports, - const std::unordered_set& specs_as_set) - : status_db(status_db), installed_ports(installed_ports), specs_as_set(specs_as_set) - { - } - - std::vector adjacency_list(const RemovePlanAction& plan) const override - { - if (plan.plan_type == RemovePlanType::NOT_INSTALLED) - { - return {}; - } - - const PackageSpec& spec = plan.spec; - std::vector dependents; - for (const StatusParagraph* an_installed_package : installed_ports) - { - if (an_installed_package->package.spec.triplet() != spec.triplet()) continue; - - const std::vector& deps = an_installed_package->package.depends; - if (std::find(deps.begin(), deps.end(), spec.name()) == deps.end()) continue; - - dependents.push_back(an_installed_package->package.spec); - } - - return dependents; - } - - RemovePlanAction load_vertex_data(const PackageSpec& spec) const override - { - const RequestType request_type = specs_as_set.find(spec) != specs_as_set.end() - ? RequestType::USER_REQUESTED - : RequestType::AUTO_SELECTED; - const StatusParagraphs::const_iterator it = status_db.find_installed(spec); - if (it == status_db.end()) - { - return RemovePlanAction{spec, RemovePlanType::NOT_INSTALLED, request_type}; - } - return RemovePlanAction{spec, RemovePlanType::REMOVE, request_type}; - } - }; - - const std::vector& installed_ports = get_installed_ports(status_db); - const std::unordered_set specs_as_set(specs.cbegin(), specs.cend()); - return Graphs::topological_sort(specs, RemoveAdjacencyProvider{status_db, installed_ports, specs_as_set}); - } - - std::vector create_export_plan(const VcpkgPaths& paths, - const std::vector& specs, - const StatusParagraphs& status_db) - { - struct ExportAdjacencyProvider final : Graphs::AdjacencyProvider - { - const VcpkgPaths& paths; - const StatusParagraphs& status_db; - const std::unordered_set& specs_as_set; - - ExportAdjacencyProvider(const VcpkgPaths& p, - const StatusParagraphs& s, - const std::unordered_set& specs_as_set) - : paths(p), status_db(s), specs_as_set(specs_as_set) - { - } - - std::vector adjacency_list(const ExportPlanAction& plan) const override - { - return plan.any_paragraph.dependencies(plan.spec.triplet()); - } - - ExportPlanAction load_vertex_data(const PackageSpec& spec) const override - { - const RequestType request_type = specs_as_set.find(spec) != specs_as_set.end() - ? RequestType::USER_REQUESTED - : RequestType::AUTO_SELECTED; - - Expected maybe_bpgh = Paragraphs::try_load_cached_control_package(paths, spec); - if (auto bcf = maybe_bpgh.get()) - return ExportPlanAction{spec, AnyParagraph{nullopt, std::move(*bcf), nullopt}, request_type}; - - auto maybe_scf = Paragraphs::try_load_port(paths.get_filesystem(), paths.port_dir(spec)); - if (auto scf = maybe_scf.get()) - return ExportPlanAction{spec, {nullopt, nullopt, *scf->get()->core_paragraph}, request_type}; - else - print_error_message(maybe_scf.error()); - - Checks::exit_with_message(VCPKG_LINE_INFO, "Could not find package %s", spec); - } - }; - - const std::unordered_set specs_as_set(specs.cbegin(), specs.cend()); - std::vector toposort = - Graphs::topological_sort(specs, ExportAdjacencyProvider{paths, status_db, specs_as_set}); - return toposort; - } - - enum class MarkPlusResult - { - FEATURE_NOT_FOUND, - SUCCESS, - }; - - MarkPlusResult mark_plus(const std::string& feature, - Cluster& cluster, - ClusterGraph& pkg_to_cluster, - GraphPlan& graph_plan); - void mark_minus(Cluster& cluster, ClusterGraph& pkg_to_cluster, GraphPlan& graph_plan); - - MarkPlusResult mark_plus(const std::string& feature, Cluster& cluster, ClusterGraph& graph, GraphPlan& graph_plan) - { - if (feature.empty()) - { - // Indicates that core was not specified in the reference - return mark_plus("core", cluster, graph, graph_plan); - } - - auto it = cluster.edges.find(feature); - if (it == cluster.edges.end()) return MarkPlusResult::FEATURE_NOT_FOUND; - - if (cluster.edges[feature].plus) return MarkPlusResult::SUCCESS; - - if (cluster.original_features.find(feature) == cluster.original_features.end()) - { - cluster.transient_uninstalled = true; - } - - if (!cluster.transient_uninstalled) - { - return MarkPlusResult::SUCCESS; - } - cluster.edges[feature].plus = true; - - if (!cluster.original_features.empty()) - { - mark_minus(cluster, graph, graph_plan); - } - - graph_plan.install_graph.add_vertex({&cluster}); - auto& tracked = cluster.to_install_features; - tracked.insert(feature); - - if (feature != "core") - { - // All features implicitly depend on core - auto res = mark_plus("core", cluster, graph, graph_plan); - - // Should be impossible for "core" to not exist - Checks::check_exit(VCPKG_LINE_INFO, res == MarkPlusResult::SUCCESS); - } - - for (auto&& depend : cluster.edges[feature].build_edges) - { - auto& depend_cluster = graph.get(depend.spec()); - auto res = mark_plus(depend.feature(), depend_cluster, graph, graph_plan); - - Checks::check_exit(VCPKG_LINE_INFO, - res == MarkPlusResult::SUCCESS, - "Error: Unable to satisfy dependency %s of %s", - depend, - FeatureSpec(cluster.spec, feature)); - - if (&depend_cluster == &cluster) continue; - graph_plan.install_graph.add_edge({&cluster}, {&depend_cluster}); - } - - return MarkPlusResult::SUCCESS; - } - - void mark_minus(Cluster& cluster, ClusterGraph& graph, GraphPlan& graph_plan) - { - if (cluster.will_remove) return; - cluster.will_remove = true; - - graph_plan.remove_graph.add_vertex({&cluster}); - for (auto&& pair : cluster.edges) - { - auto& remove_edges_edges = pair.second.remove_edges; - for (auto&& depend : remove_edges_edges) - { - auto& depend_cluster = graph.get(depend.spec()); - graph_plan.remove_graph.add_edge({&cluster}, {&depend_cluster}); - mark_minus(depend_cluster, graph, graph_plan); - } - } - - cluster.transient_uninstalled = true; - for (auto&& original_feature : cluster.original_features) - { - auto res = mark_plus(original_feature, cluster, graph, graph_plan); - if (res != MarkPlusResult::SUCCESS) - { - System::println(System::Color::warning, - "Warning: could not reinstall feature %s", - FeatureSpec{cluster.spec, original_feature}); - } - } - } - - static ClusterGraph create_feature_install_graph(const std::unordered_map& map, - const StatusParagraphs& status_db) - { - std::unordered_map ptr_map; - for (auto&& p : map) - ptr_map.emplace(p.first, &p.second); - ClusterGraph graph(std::move(ptr_map)); - - auto installed_ports = get_installed_ports(status_db); - - for (auto&& status_paragraph : installed_ports) - { - Cluster& cluster = graph.get(status_paragraph->package.spec); - - cluster.transient_uninstalled = false; - - cluster.status_paragraphs.emplace_back(status_paragraph); - - auto& status_paragraph_feature = status_paragraph->package.feature; - // In this case, empty string indicates the "core" paragraph for a package. - if (status_paragraph_feature.empty()) - { - cluster.original_features.insert("core"); - } - else - { - cluster.original_features.insert(status_paragraph_feature); - } - } - - for (auto&& status_paragraph : installed_ports) - { - auto& spec = status_paragraph->package.spec; - auto& status_paragraph_feature = status_paragraph->package.feature; - auto reverse_edges = FeatureSpec::from_strings_and_triplet(status_paragraph->package.depends, - status_paragraph->package.spec.triplet()); - - for (auto&& dependency : reverse_edges) - { - auto& dep_cluster = graph.get(dependency.spec()); - - auto depends_name = dependency.feature(); - if (depends_name.empty()) depends_name = "core"; - - auto& target_node = dep_cluster.edges[depends_name]; - target_node.remove_edges.emplace_back(FeatureSpec{spec, status_paragraph_feature}); - } - } - return graph; - } - - std::vector create_feature_install_plan(const std::unordered_map& map, - const std::vector& specs, - const StatusParagraphs& status_db) - { - ClusterGraph graph = create_feature_install_graph(map, status_db); - - GraphPlan graph_plan; - for (auto&& spec : specs) - { - Cluster& spec_cluster = graph.get(spec.spec()); - spec_cluster.request_type = RequestType::USER_REQUESTED; - auto res = mark_plus(spec.feature(), spec_cluster, graph, graph_plan); - - Checks::check_exit( - VCPKG_LINE_INFO, res == MarkPlusResult::SUCCESS, "Error: Unable to locate feature %s", spec); - - graph_plan.install_graph.add_vertex(ClusterPtr{&spec_cluster}); - } - - Graphs::GraphAdjacencyProvider adjacency_remove_graph(graph_plan.remove_graph.adjacency_list()); - auto remove_vertex_list = graph_plan.remove_graph.vertex_list(); - auto remove_toposort = Graphs::topological_sort(remove_vertex_list, adjacency_remove_graph); - - Graphs::GraphAdjacencyProvider adjacency_install_graph(graph_plan.install_graph.adjacency_list()); - auto insert_vertex_list = graph_plan.install_graph.vertex_list(); - auto insert_toposort = Graphs::topological_sort(insert_vertex_list, adjacency_install_graph); - - std::vector plan; - - for (auto&& p_cluster : remove_toposort) - { - auto scf = *p_cluster->source_control_file.get(); - auto spec = PackageSpec::from_name_and_triplet(scf->core_paragraph->name, p_cluster->spec.triplet()) - .value_or_exit(VCPKG_LINE_INFO); - plan.emplace_back(RemovePlanAction{ - std::move(spec), - RemovePlanType::REMOVE, - p_cluster->request_type, - }); - } - - for (auto&& p_cluster : insert_toposort) - { - if (p_cluster->transient_uninstalled) - { - // If it will be transiently uninstalled, we need to issue a full installation command - auto pscf = p_cluster->source_control_file.value_or_exit(VCPKG_LINE_INFO); - Checks::check_exit(VCPKG_LINE_INFO, pscf != nullptr); - plan.emplace_back(InstallPlanAction{ - p_cluster->spec, - *pscf, - p_cluster->to_install_features, - p_cluster->request_type, - }); - } - else - { - // If the package isn't transitively installed, still include it if the user explicitly requested it - if (p_cluster->request_type != RequestType::USER_REQUESTED) continue; - plan.emplace_back(InstallPlanAction{ - p_cluster->spec, - p_cluster->original_features, - p_cluster->request_type, - }); - } - } - - return plan; - } -} diff --git a/toolsrc/src/vcpkg_Enums.cpp b/toolsrc/src/vcpkg_Enums.cpp deleted file mode 100644 index 51ba9d5dc..000000000 --- a/toolsrc/src/vcpkg_Enums.cpp +++ /dev/null @@ -1,14 +0,0 @@ -#include "pch.h" - -#include "vcpkg_Checks.h" -#include "vcpkg_Enums.h" - -namespace vcpkg::Enums -{ - std::string nullvalue_to_string(const CStringView enum_name) { return Strings::format("%s_NULLVALUE", enum_name); } - - [[noreturn]] void nullvalue_used(const LineInfo& line_info, const CStringView enum_name) - { - Checks::exit_with_message(line_info, "NULLVALUE of enum %s was used", enum_name); - } -} diff --git a/toolsrc/src/vcpkg_Files.cpp b/toolsrc/src/vcpkg_Files.cpp deleted file mode 100644 index ad1fcebc6..000000000 --- a/toolsrc/src/vcpkg_Files.cpp +++ /dev/null @@ -1,209 +0,0 @@ -#include "pch.h" - -#include "vcpkg_Files.h" -#include "vcpkg_System.h" -#include "vcpkg_Util.h" -#include - -namespace vcpkg::Files -{ - static const std::regex FILESYSTEM_INVALID_CHARACTERS_REGEX = std::regex(R"([\/:*?"<>|])"); - - struct RealFilesystem final : Filesystem - { - virtual Expected 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()) - { - return std::make_error_code(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::make_error_code(std::errc::file_too_large); - } - - std::string output; - output.resize(static_cast(length)); - file_stream.read(&output[0], length); - file_stream.close(); - - return std::move(output); - } - virtual Expected> 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::make_error_code(std::errc::no_such_file_or_directory); - } - - std::vector output; - std::string line; - while (std::getline(file_stream, line)) - { - output.push_back(line); - } - file_stream.close(); - - return std::move(output); - } - virtual fs::path find_file_recursively_up(const fs::path& starting_dir, - const std::string& filename) const override - { - 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; - } - - virtual std::vector get_files_recursive(const fs::path& dir) const override - { - std::vector ret; - - fs::stdfs::recursive_directory_iterator b(dir), e{}; - for (; b != e; ++b) - { - ret.push_back(b->path()); - } - - return ret; - } - - virtual std::vector get_files_non_recursive(const fs::path& dir) const override - { - std::vector ret; - - fs::stdfs::directory_iterator b(dir), e{}; - for (; b != e; ++b) - { - ret.push_back(b->path()); - } - - return ret; - } - - virtual void write_lines(const fs::path& file_path, const std::vector& lines) override - { - 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"; - } - output.close(); - } - - 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 - { - // Working around the currently buggy remove_all() - std::uintmax_t out = fs::stdfs::remove_all(path, ec); - - for (int i = 0; i < 5 && this->exists(path); i++) - { - using namespace std::chrono_literals; - std::this_thread::sleep_for(i * 100ms); - out += fs::stdfs::remove_all(path, ec); - } - - if (this->exists(path)) - { - System::println(System::Color::warning, - "Some files in %s were unable to be removed. Close any editors operating in this " - "directory and retry.", - path.string()); - } - - return out; - } - 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 bool create_directories(const fs::path& path, std::error_code& ec) override - { - return fs::stdfs::create_directories(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); - } - - 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, "Error: Could not open file for writing: %s", file_path.u8string().c_str()); - auto count = fwrite(data.data(), sizeof(data[0]), data.size(), f); - fclose(f); - - Checks::check_exit(VCPKG_LINE_INFO, count == data.size()); - } - }; - - Filesystem& get_real_filesystem() - { - static RealFilesystem real_fs; - return real_fs; - } - - bool has_invalid_chars_for_filesystem(const std::string& s) - { - return std::regex_search(s, FILESYSTEM_INVALID_CHARACTERS_REGEX); - } - - void print_paths(const std::vector& paths) - { - System::println(); - for (const fs::path& p : paths) - { - System::println(" %s", p.generic_string()); - } - System::println(); - } - - std::vector find_from_PATH(const std::wstring& name) - { - const std::wstring cmd = Strings::wformat(L"where.exe %s", name); - auto out = System::cmd_execute_and_capture_output(cmd); - if (out.exit_code != 0) - { - return {}; - } - - return Util::fmap(Strings::split(out.output, "\n"), [](auto&& s) { return fs::path(s); }); - } -} diff --git a/toolsrc/src/vcpkg_GlobalState.cpp b/toolsrc/src/vcpkg_GlobalState.cpp deleted file mode 100644 index 2221222c0..000000000 --- a/toolsrc/src/vcpkg_GlobalState.cpp +++ /dev/null @@ -1,13 +0,0 @@ -#include "pch.h" - -#include "vcpkg_GlobalState.h" - -namespace vcpkg -{ - Util::LockGuarded GlobalState::timer; - std::atomic GlobalState::debugging = false; - std::atomic GlobalState::feature_packages = false; - - std::atomic GlobalState::g_init_console_cp = 0; - std::atomic GlobalState::g_init_console_output_cp = 0; -} diff --git a/toolsrc/src/vcpkg_Input.cpp b/toolsrc/src/vcpkg_Input.cpp deleted file mode 100644 index f1cac9632..000000000 --- a/toolsrc/src/vcpkg_Input.cpp +++ /dev/null @@ -1,54 +0,0 @@ -#include "pch.h" - -#include "metrics.h" -#include "vcpkg_Commands.h" -#include "vcpkg_Input.h" -#include "vcpkg_System.h" - -namespace vcpkg::Input -{ - PackageSpec check_and_get_package_spec(const std::string& package_spec_as_string, - const Triplet& default_triplet, - CStringView example_text) - { - const std::string as_lowercase = Strings::ascii_to_lowercase(package_spec_as_string); - auto expected_spec = FullPackageSpec::from_string(as_lowercase, default_triplet); - if (const auto spec = expected_spec.get()) - { - return PackageSpec{spec->package_spec}; - } - - // Intentionally show the lowercased string - System::println(System::Color::error, "Error: %s: %s", vcpkg::to_string(expected_spec.error()), as_lowercase); - System::print(example_text); - Checks::exit_fail(VCPKG_LINE_INFO); - } - - void check_triplet(const Triplet& t, const VcpkgPaths& paths) - { - if (!paths.is_valid_triplet(t)) - { - System::println(System::Color::error, "Error: invalid triplet: %s", t); - Metrics::g_metrics.lock()->track_property("error", "invalid triplet: " + t.to_string()); - Commands::Help::help_topic_valid_triplet(paths); - Checks::exit_fail(VCPKG_LINE_INFO); - } - } - - FullPackageSpec check_and_get_full_package_spec(const std::string& full_package_spec_as_string, - const Triplet& default_triplet, - CStringView example_text) - { - const std::string as_lowercase = Strings::ascii_to_lowercase(full_package_spec_as_string); - auto expected_spec = FullPackageSpec::from_string(as_lowercase, default_triplet); - if (const auto spec = expected_spec.get()) - { - return *spec; - } - - // Intentionally show the lowercased string - System::println(System::Color::error, "Error: %s: %s", vcpkg::to_string(expected_spec.error()), as_lowercase); - System::print(example_text); - Checks::exit_fail(VCPKG_LINE_INFO); - } -} diff --git a/toolsrc/src/vcpkg_Parse.cpp b/toolsrc/src/vcpkg_Parse.cpp deleted file mode 100644 index e671a1a05..000000000 --- a/toolsrc/src/vcpkg_Parse.cpp +++ /dev/null @@ -1,80 +0,0 @@ -#include "pch.h" - -#include "vcpkg_Checks.h" -#include "vcpkg_Maps.h" -#include "vcpkg_Parse.h" - -namespace vcpkg::Parse -{ - static Optional remove_field(std::unordered_map* fields, - const std::string& fieldname) - { - auto it = fields->find(fieldname); - if (it == fields->end()) - { - return nullopt; - } - - const std::string value = std::move(it->second); - fields->erase(it); - return value; - } - - void ParagraphParser::required_field(const std::string& fieldname, std::string& out) - { - auto maybe_field = remove_field(&fields, fieldname); - if (const auto field = maybe_field.get()) - out = std::move(*field); - else - missing_fields.push_back(fieldname); - } - std::string ParagraphParser::optional_field(const std::string& fieldname) const - { - return remove_field(&fields, fieldname).value_or(Strings::EMPTY); - } - std::unique_ptr ParagraphParser::error_info(const std::string& name) const - { - if (!fields.empty() || !missing_fields.empty()) - { - auto err = std::make_unique(); - err->name = name; - err->extra_fields = Maps::extract_keys(fields); - err->missing_fields = std::move(missing_fields); - return err; - } - return nullptr; - } - - std::vector parse_comma_list(const std::string& str) - { - if (str.empty()) - { - return {}; - } - - std::vector out; - - size_t cur = 0; - do - { - auto pos = str.find(',', cur); - if (pos == std::string::npos) - { - out.push_back(str.substr(cur)); - break; - } - out.push_back(str.substr(cur, pos - cur)); - - // skip comma and space - ++pos; - if (str[pos] == ' ') - { - ++pos; - } - - cur = pos; - } while (cur != std::string::npos); - - return out; - } -} diff --git a/toolsrc/src/vcpkg_Strings.cpp b/toolsrc/src/vcpkg_Strings.cpp deleted file mode 100644 index bbe6b29cd..000000000 --- a/toolsrc/src/vcpkg_Strings.cpp +++ /dev/null @@ -1,174 +0,0 @@ -#include "pch.h" - -#include "vcpkg_Checks.h" -#include "vcpkg_Strings.h" -#include "vcpkg_Util.h" - -namespace vcpkg::Strings::details -{ - // To disambiguate between two overloads - static const auto isspace = [](const char c) { return std::isspace(c); }; - - // Avoids C4244 warnings because of char<->int conversion that occur when using std::tolower() - static char tolower_char(const char c) { return static_cast(std::tolower(c)); } - -#if defined(_WIN32) - static _locale_t& c_locale() - { - static _locale_t c_locale_impl = _create_locale(LC_ALL, "C"); - return c_locale_impl; - } -#endif - - std::string format_internal(const char* fmtstr, ...) - { - va_list args; - va_start(args, fmtstr); - -#if defined(_WIN32) - const int sz = _vscprintf_l(fmtstr, c_locale(), args); -#else - const int sz = vsnprintf(nullptr, 0, fmtstr, args); -#endif - Checks::check_exit(VCPKG_LINE_INFO, sz > 0); - - std::string output(sz, '\0'); - -#if defined(_WIN32) - _vsnprintf_s_l(&output.at(0), output.size() + 1, output.size(), fmtstr, c_locale(), args); -#else - vsnprintf(&output.at(0), output.size() + 1, fmtstr, args); -#endif - va_end(args); - - return output; - } - - std::wstring wformat_internal(const wchar_t* fmtstr, ...) - { - va_list args; - va_start(args, fmtstr); - -#if defined(_WIN32) - const int sz = _vscwprintf_l(fmtstr, c_locale(), args); -#else - const int sz = vswprintf(nullptr, 0, fmtstr, args); -#endif - Checks::check_exit(VCPKG_LINE_INFO, sz > 0); - - std::wstring output(sz, L'\0'); - -#if defined(_WIN32) - _vsnwprintf_s_l(&output.at(0), output.size() + 1, output.size(), fmtstr, c_locale(), args); -#else - vswprintf(&output.at(0), output.size() + 1, fmtstr, args); -#endif - va_end(args); - - return output; - } -} - -namespace vcpkg::Strings -{ - std::wstring to_utf16(const CStringView s) - { - const int size = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, nullptr, 0); - std::wstring output; - output.resize(size - 1); - MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, output.data(), size - 1); - return output; - } - - std::string to_utf8(const CWStringView w) - { - const int size = WideCharToMultiByte(CP_UTF8, 0, w.c_str(), -1, nullptr, 0, nullptr, nullptr); - std::string output; - output.resize(size - 1); - WideCharToMultiByte(CP_UTF8, 0, w.c_str(), -1, output.data(), size - 1, nullptr, nullptr); - return output; - } - - std::string::const_iterator case_insensitive_ascii_find(const std::string& s, const std::string& pattern) - { - const std::string pattern_as_lower_case(ascii_to_lowercase(pattern)); - return search(s.begin(), - s.end(), - pattern_as_lower_case.begin(), - pattern_as_lower_case.end(), - [](const char a, const char b) { return details::tolower_char(a) == b; }); - } - - bool case_insensitive_ascii_contains(const std::string& s, const std::string& pattern) - { - return case_insensitive_ascii_find(s, pattern) != s.end(); - } - - int case_insensitive_ascii_compare(const CStringView left, const CStringView right) - { - return _stricmp(left.c_str(), right.c_str()); - } - - std::string ascii_to_lowercase(const std::string& input) - { - std::string output(input); - std::transform(output.begin(), output.end(), output.begin(), &details::tolower_char); - return output; - } - - bool case_insensitive_ascii_starts_with(const std::string& s, const std::string& pattern) - { - return _strnicmp(s.c_str(), pattern.c_str(), pattern.size()) == 0; - } - - void trim(std::string* s) - { - s->erase(std::find_if_not(s->rbegin(), s->rend(), details::isspace).base(), s->end()); - s->erase(s->begin(), std::find_if_not(s->begin(), s->end(), details::isspace)); - } - - std::string trimmed(const std::string& s) - { - auto whitespace_back = std::find_if_not(s.rbegin(), s.rend(), details::isspace).base(); - auto whitespace_front = std::find_if_not(s.begin(), whitespace_back, details::isspace); - return std::string(whitespace_front, whitespace_back); - } - - void trim_all_and_remove_whitespace_strings(std::vector* strings) - { - for (std::string& s : *strings) - { - trim(&s); - } - - Util::erase_remove_if(*strings, [](const std::string& s) { return s.empty(); }); - } - - std::vector split(const std::string& s, const std::string& delimiter) - { - std::vector output; - - if (delimiter.empty()) - { - output.push_back(s); - return output; - } - - const size_t delimiter_length = delimiter.length(); - size_t i = 0; - for (size_t pos = s.find(delimiter); pos != std::string::npos; pos = s.find(delimiter, pos)) - { - output.push_back(s.substr(i, pos - i)); - pos += delimiter_length; - i = pos; - } - - // Add the rest of the string after the last delimiter, unless there is nothing after it - if (i != s.length()) - { - output.push_back(s.substr(i, s.length())); - } - - return output; - } -} diff --git a/toolsrc/src/vcpkg_System.cpp b/toolsrc/src/vcpkg_System.cpp deleted file mode 100644 index 3b4c440d8..000000000 --- a/toolsrc/src/vcpkg_System.cpp +++ /dev/null @@ -1,349 +0,0 @@ -#include "pch.h" - -#include "vcpkg_Checks.h" -#include "vcpkg_GlobalState.h" -#include "vcpkg_System.h" -#include "vcpkglib.h" - -namespace vcpkg::System -{ - tm get_current_date_time() - { - using std::chrono::system_clock; - std::time_t now_time = system_clock::to_time_t(system_clock::now()); - tm parts; - localtime_s(&parts, &now_time); - return parts; - } - - fs::path get_exe_path_of_current_process() - { - wchar_t buf[_MAX_PATH]; - const int bytes = GetModuleFileNameW(nullptr, buf, _MAX_PATH); - if (bytes == 0) std::abort(); - return fs::path(buf, buf + bytes); - } - - Optional to_cpu_architecture(CStringView arch) - { - if (Strings::case_insensitive_ascii_compare(arch, "x86") == 0) return CPUArchitecture::X86; - if (Strings::case_insensitive_ascii_compare(arch, "x64") == 0) return CPUArchitecture::X64; - if (Strings::case_insensitive_ascii_compare(arch, "amd64") == 0) return CPUArchitecture::X64; - if (Strings::case_insensitive_ascii_compare(arch, "arm") == 0) return CPUArchitecture::ARM; - if (Strings::case_insensitive_ascii_compare(arch, "arm64") == 0) return CPUArchitecture::ARM64; - return nullopt; - } - - CPUArchitecture get_host_processor() - { - auto w6432 = get_environment_variable(L"PROCESSOR_ARCHITEW6432"); - if (const auto p = w6432.get()) return to_cpu_architecture(Strings::to_utf8(*p)).value_or_exit(VCPKG_LINE_INFO); - - const auto procarch = get_environment_variable(L"PROCESSOR_ARCHITECTURE").value_or_exit(VCPKG_LINE_INFO); - return to_cpu_architecture(Strings::to_utf8(procarch)).value_or_exit(VCPKG_LINE_INFO); - } - - std::vector get_supported_host_architectures() - { - std::vector supported_architectures; - supported_architectures.push_back(get_host_processor()); - - // AMD64 machines support to run x86 applications - if (supported_architectures.back() == CPUArchitecture::X64) - { - supported_architectures.push_back(CPUArchitecture::X86); - } - - return supported_architectures; - } - - int cmd_execute_clean(const CWStringView cmd_line) - { - static const std::wstring SYSTEM_ROOT = get_environment_variable(L"SystemRoot").value_or_exit(VCPKG_LINE_INFO); - static const std::wstring SYSTEM_32 = SYSTEM_ROOT + LR"(\system32)"; - static const std::wstring NEW_PATH = Strings::wformat( - LR"(Path=%s;%s;%s\Wbem;%s\WindowsPowerShell\v1.0\)", SYSTEM_32, SYSTEM_ROOT, SYSTEM_32, SYSTEM_32); - - std::vector env_wstrings = { - L"ALLUSERSPROFILE", - L"APPDATA", - L"CommonProgramFiles", - L"CommonProgramFiles(x86)", - L"CommonProgramW6432", - L"COMPUTERNAME", - L"ComSpec", - L"HOMEDRIVE", - L"HOMEPATH", - L"LOCALAPPDATA", - L"LOGONSERVER", - L"NUMBER_OF_PROCESSORS", - L"OS", - L"PATHEXT", - L"PROCESSOR_ARCHITECTURE", - L"PROCESSOR_ARCHITEW6432", - L"PROCESSOR_IDENTIFIER", - L"PROCESSOR_LEVEL", - L"PROCESSOR_REVISION", - L"ProgramData", - L"ProgramFiles", - L"ProgramFiles(x86)", - L"ProgramW6432", - L"PROMPT", - L"PSModulePath", - L"PUBLIC", - L"SystemDrive", - L"SystemRoot", - L"TEMP", - L"TMP", - L"USERDNSDOMAIN", - L"USERDOMAIN", - L"USERDOMAIN_ROAMINGPROFILE", - L"USERNAME", - L"USERPROFILE", - L"windir", - // Enables proxy information to be passed to Curl, the underlying download library in cmake.exe - L"HTTP_PROXY", - L"HTTPS_PROXY", - // Enables find_package(CUDA) in CMake - L"CUDA_PATH", - }; - - // Flush stdout before launching external process - fflush(nullptr); - - std::wstring env_cstr; - - for (auto&& env_wstring : env_wstrings) - { - const Optional value = System::get_environment_variable(env_wstring); - const auto v = value.get(); - if (!v || v->empty()) continue; - - env_cstr.append(env_wstring); - env_cstr.push_back(L'='); - env_cstr.append(*v); - env_cstr.push_back(L'\0'); - } - - env_cstr.append(NEW_PATH); - env_cstr.push_back(L'\0'); - - STARTUPINFOW startup_info; - memset(&startup_info, 0, sizeof(STARTUPINFOW)); - startup_info.cb = sizeof(STARTUPINFOW); - - PROCESS_INFORMATION process_info; - memset(&process_info, 0, sizeof(PROCESS_INFORMATION)); - - // Basically we are wrapping it in quotes - std::wstring actual_cmd_line = Strings::wformat(LR"###(cmd.exe /c "%s")###", cmd_line); - Debug::println("CreateProcessW(%s)", Strings::to_utf8(actual_cmd_line)); - bool succeeded = TRUE == CreateProcessW(nullptr, - actual_cmd_line.data(), - nullptr, - nullptr, - FALSE, - BELOW_NORMAL_PRIORITY_CLASS | CREATE_UNICODE_ENVIRONMENT, - env_cstr.data(), - nullptr, - &startup_info, - &process_info); - - Checks::check_exit(VCPKG_LINE_INFO, succeeded, "Process creation failed with error code: %lu", GetLastError()); - - CloseHandle(process_info.hThread); - - const DWORD result = WaitForSingleObject(process_info.hProcess, INFINITE); - Checks::check_exit(VCPKG_LINE_INFO, result != WAIT_FAILED, "WaitForSingleObject failed"); - - DWORD exit_code = 0; - GetExitCodeProcess(process_info.hProcess, &exit_code); - - Debug::println("CreateProcessW() returned %lu", exit_code); - return static_cast(exit_code); - } - - int cmd_execute(const CWStringView cmd_line) - { - // Flush stdout before launching external process - fflush(nullptr); - - // Basically we are wrapping it in quotes - const std::wstring& actual_cmd_line = Strings::wformat(LR"###("%s")###", cmd_line); - Debug::println("_wsystem(%s)", Strings::to_utf8(actual_cmd_line)); - const int exit_code = _wsystem(actual_cmd_line.c_str()); - Debug::println("_wsystem() returned %d", exit_code); - return exit_code; - } - - // On Win7, output from powershell calls contain a byte order mark, so we strip it out if it is present - static void remove_byte_order_marks(std::wstring* s) - { - const wchar_t* a = s->c_str(); - // This is the UTF-8 byte-order mark - while (s->size() >= 3 && a[0] == 0xEF && a[1] == 0xBB && a[2] == 0xBF) - { - s->erase(0, 3); - } - } - - ExitCodeAndOutput cmd_execute_and_capture_output(const CWStringView cmd_line) - { - // Flush stdout before launching external process - fflush(stdout); - - const std::wstring& actual_cmd_line = Strings::wformat(LR"###("%s 2>&1")###", cmd_line); - - Debug::println("_wpopen(%s)", Strings::to_utf8(actual_cmd_line)); - std::wstring output; - wchar_t buf[1024]; - const auto pipe = _wpopen(actual_cmd_line.c_str(), L"r"); - if (pipe == nullptr) - { - return {1, Strings::to_utf8(output)}; - } - while (fgetws(buf, 1024, pipe)) - { - output.append(buf); - } - if (!feof(pipe)) - { - return {1, Strings::to_utf8(output)}; - } - - const auto ec = _pclose(pipe); - Debug::println("_pclose() returned %d", ec); - remove_byte_order_marks(&output); - return {ec, Strings::to_utf8(output)}; - } - - std::wstring create_powershell_script_cmd(const fs::path& script_path, const CWStringView args) - { - // TODO: switch out ExecutionPolicy Bypass with "Remove Mark Of The Web" code and restore RemoteSigned - return Strings::wformat( - LR"(powershell -NoProfile -ExecutionPolicy Bypass -Command "& {& '%s' %s}")", script_path.native(), args); - } - - void println() { println(Strings::EMPTY); } - - void print(const CStringView message) { fputs(message.c_str(), stdout); } - - void println(const CStringView message) - { - print(message); - putchar('\n'); - } - - void print(const Color c, const CStringView message) - { - const HANDLE console_handle = GetStdHandle(STD_OUTPUT_HANDLE); - - CONSOLE_SCREEN_BUFFER_INFO console_screen_buffer_info{}; - GetConsoleScreenBufferInfo(console_handle, &console_screen_buffer_info); - const auto original_color = console_screen_buffer_info.wAttributes; - - SetConsoleTextAttribute(console_handle, static_cast(c) | (original_color & 0xF0)); - print(message); - SetConsoleTextAttribute(console_handle, original_color); - } - - void println(const Color c, const CStringView message) - { - print(c, message); - putchar('\n'); - } - - Optional get_environment_variable(const CWStringView varname) noexcept - { - const auto sz = GetEnvironmentVariableW(varname.c_str(), nullptr, 0); - if (sz == 0) return nullopt; - - std::wstring ret(sz, L'\0'); - - Checks::check_exit(VCPKG_LINE_INFO, MAXDWORD >= ret.size()); - const auto sz2 = GetEnvironmentVariableW(varname.c_str(), ret.data(), static_cast(ret.size())); - Checks::check_exit(VCPKG_LINE_INFO, sz2 + 1 == sz); - ret.pop_back(); - return ret; - } - - static bool is_string_keytype(DWORD hkey_type) - { - return hkey_type == REG_SZ || hkey_type == REG_MULTI_SZ || hkey_type == REG_EXPAND_SZ; - } - - Optional get_registry_string(HKEY base, const CWStringView sub_key, const CWStringView valuename) - { - HKEY k = nullptr; - const LSTATUS ec = RegOpenKeyExW(base, sub_key.c_str(), NULL, KEY_READ, &k); - if (ec != ERROR_SUCCESS) return nullopt; - - DWORD dw_buffer_size = 0; - DWORD dw_type = 0; - auto rc = RegQueryValueExW(k, valuename.c_str(), nullptr, &dw_type, nullptr, &dw_buffer_size); - if (rc != ERROR_SUCCESS || !is_string_keytype(dw_type) || dw_buffer_size == 0 || - dw_buffer_size % sizeof(wchar_t) != 0) - return nullopt; - std::wstring ret; - ret.resize(dw_buffer_size / sizeof(wchar_t)); - - rc = RegQueryValueExW( - k, valuename.c_str(), nullptr, &dw_type, reinterpret_cast(ret.data()), &dw_buffer_size); - if (rc != ERROR_SUCCESS || !is_string_keytype(dw_type) || dw_buffer_size != sizeof(wchar_t) * ret.size()) - return nullopt; - - ret.pop_back(); // remove extra trailing null byte - return ret; - } - - static const fs::path& get_program_files() - { - static const fs::path PATH = System::get_environment_variable(L"PROGRAMFILES").value_or_exit(VCPKG_LINE_INFO); - return PATH; - } - - const fs::path& get_program_files_32_bit() - { - static const fs::path PATH = []() -> fs::path { - auto value = System::get_environment_variable(L"ProgramFiles(x86)"); - if (auto v = value.get()) - { - return std::move(*v); - } - return get_program_files(); - }(); - return PATH; - } - - const fs::path& get_program_files_platform_bitness() - { - static const fs::path PATH = []() -> fs::path { - auto value = System::get_environment_variable(L"ProgramW6432"); - if (auto v = value.get()) - { - return std::move(*v); - } - return get_program_files(); - }(); - return PATH; - } -} - -namespace vcpkg::Debug -{ - void println(const CStringView message) - { - if (GlobalState::debugging) - { - System::println("[DEBUG] %s", message); - } - } - - void println(const System::Color c, const CStringView message) - { - if (GlobalState::debugging) - { - System::println(c, "[DEBUG] %s", message); - } - } -} diff --git a/toolsrc/src/vcpkg_metrics_uploader.cpp b/toolsrc/src/vcpkg_metrics_uploader.cpp deleted file mode 100644 index cef4f4756..000000000 --- a/toolsrc/src/vcpkg_metrics_uploader.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include "metrics.h" -#include "vcpkg_Checks.h" -#include "vcpkg_Files.h" -#include - -using namespace vcpkg; - -int WINAPI WinMain(_In_ HINSTANCE, _In_opt_ HINSTANCE, _In_ LPSTR, _In_ int) -{ - int argCount; - LPWSTR* szArgList = CommandLineToArgvW(GetCommandLineW(), &argCount); - - Checks::check_exit(VCPKG_LINE_INFO, argCount == 2, "Requires exactly one argument, the path to the payload file"); - auto v = Files::get_real_filesystem().read_contents(szArgList[1]).value_or_exit(VCPKG_LINE_INFO); - Metrics::g_metrics.lock()->upload(v); - LocalFree(szArgList); - return 0; -} diff --git a/toolsrc/src/vcpkglib.cpp b/toolsrc/src/vcpkglib.cpp deleted file mode 100644 index 5cdafdbc8..000000000 --- a/toolsrc/src/vcpkglib.cpp +++ /dev/null @@ -1,247 +0,0 @@ -#include "pch.h" - -#include "Paragraphs.h" -#include "metrics.h" -#include "vcpkg_Files.h" -#include "vcpkg_Strings.h" -#include "vcpkg_Util.h" -#include "vcpkglib.h" - -namespace vcpkg -{ - 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_old)) - { - // no status file, use empty db - return StatusParagraphs(); - } - - fs.rename(vcpkg_dir_status_file_old, vcpkg_dir_status_file); - } - - auto pghs = Paragraphs::get_paragraphs(fs, vcpkg_dir_status_file).value_or_exit(VCPKG_LINE_INFO); - - std::vector> status_pghs; - for (auto&& p : pghs) - { - status_pghs.push_back(std::make_unique(std::move(p))); - } - - return StatusParagraphs(std::move(status_pghs)); - } - - StatusParagraphs database_load_check(const VcpkgPaths& paths) - { - auto& fs = paths.get_filesystem(); - - const 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); - - 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(fs, status_file, status_file_old); - - 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 (auto&& file : update_files) - { - if (!fs.is_regular_file(file)) continue; - if (file.filename() == "incomplete") continue; - - auto pghs = Paragraphs::get_paragraphs(fs, file).value_or_exit(VCPKG_LINE_INFO); - for (auto&& p : pghs) - { - current_status_db.insert(std::make_unique(std::move(p))); - } - } - - fs.write_contents(status_file_new, Strings::serialize(current_status_db)); - - fs.rename(status_file_new, status_file); - - for (auto&& file : update_files) - { - if (!fs.is_regular_file(file)) continue; - - fs.remove(file); - } - - return current_status_db; - } - - void write_update(const VcpkgPaths& paths, const StatusParagraph& p) - { - static int update_id = 0; - auto& fs = paths.get_filesystem(); - - const auto my_update_id = update_id++; - const auto tmp_update_filename = paths.vcpkg_dir_updates / "incomplete"; - const auto update_filename = paths.vcpkg_dir_updates / std::to_string(my_update_id); - - fs.write_contents(tmp_update_filename, Strings::serialize(p)); - fs.rename(tmp_update_filename, update_filename); - } - - static void upgrade_to_slash_terminated_sorted_format(Files::Filesystem& fs, - std::vector* lines, - const fs::path& listfile_path) - { - static bool was_tracked = false; - - if (lines->empty()) - { - return; - } - - if (lines->at(0).back() == '/') - { - return; // File already in the new format - } - - if (!was_tracked) - { - was_tracked = true; - Metrics::g_metrics.lock()->track_property("listfile", "update to new format"); - } - - // The files are sorted such that directories are placed just before the files they contain - // (They are not necessarily sorted alphabetically, e.g. libflac) - // Therefore we can detect the entries that represent directories by comparing every element with the next one - // and checking if the next has a slash immediately after the current one's length - for (size_t i = 0; i < lines->size() - 1; i++) - { - std::string& current_string = lines->at(i); - const std::string& next_string = lines->at(i + 1); - - const size_t potential_slash_char_index = current_string.length(); - // Make sure the index exists first - if (next_string.size() > potential_slash_char_index && next_string.at(potential_slash_char_index) == '/') - { - current_string += '/'; // Mark as a directory - } - } - - // After suffixing the directories with a slash, we can now sort. - // We cannot sort before adding the suffixes because the following (actual example): - /* - x86-windows/include/FLAC <<<<<< This would be separated from its group due to sorting - x86-windows/include/FLAC/all.h - x86-windows/include/FLAC/assert.h - x86-windows/include/FLAC/callback.h - x86-windows/include/FLAC++ - x86-windows/include/FLAC++/all.h - x86-windows/include/FLAC++/decoder.h - x86-windows/include/FLAC++/encoder.h - * - x86-windows/include/FLAC/ <<<<<< This will now be kept with its group when sorting - x86-windows/include/FLAC/all.h - x86-windows/include/FLAC/assert.h - x86-windows/include/FLAC/callback.h - x86-windows/include/FLAC++/ - x86-windows/include/FLAC++/all.h - x86-windows/include/FLAC++/decoder.h - x86-windows/include/FLAC++/encoder.h - */ - // Note that after sorting, the FLAC++/ group will be placed before the FLAC/ group - // The new format is lexicographically sorted - std::sort(lines->begin(), lines->end()); - - // Replace the listfile on disk - const fs::path updated_listfile_path = listfile_path.generic_string() + "_updated"; - fs.write_lines(updated_listfile_path, *lines); - fs.rename(updated_listfile_path, listfile_path); - } - - std::vector get_installed_ports(const StatusParagraphs& status_db) - { - std::vector installed_packages; - for (auto&& pgh : status_db) - { - if (pgh->state != InstallState::INSTALLED || pgh->want != Want::INSTALL) continue; - installed_packages.push_back(pgh.get()); - } - - return installed_packages; - } - - std::vector get_installed_files(const VcpkgPaths& paths, - const StatusParagraphs& status_db) - { - auto& fs = paths.get_filesystem(); - - std::vector installed_files; - - for (const std::unique_ptr& pgh : status_db) - { - if (pgh->state != InstallState::INSTALLED || !pgh->package.feature.empty()) - { - continue; - } - - const fs::path listfile_path = paths.listfile_path(pgh->package); - std::vector 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(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() == '/'; }); - - StatusParagraphAndAssociatedFiles pgh_and_files = { - *pgh, SortedVector(std::move(installed_files_of_current_pgh))}; - installed_files.push_back(std::move(pgh_and_files)); - } - - return installed_files; - } - - CMakeVariable::CMakeVariable(const CWStringView varname, const wchar_t* varvalue) - : s(Strings::wformat(LR"("-D%s=%s")", varname, varvalue)) - { - } - CMakeVariable::CMakeVariable(const CWStringView varname, const std::string& varvalue) - : CMakeVariable(varname, Strings::to_utf16(varvalue).c_str()) - { - } - CMakeVariable::CMakeVariable(const CWStringView varname, const std::wstring& varvalue) - : CMakeVariable(varname, varvalue.c_str()) - { - } - CMakeVariable::CMakeVariable(const CWStringView varname, const fs::path& path) - : CMakeVariable(varname, path.generic_wstring()) - { - } - - std::wstring make_cmake_cmd(const fs::path& cmake_exe, - const fs::path& cmake_script, - const std::vector& pass_variables) - { - const std::wstring cmd_cmake_pass_variables = Strings::join(L" ", pass_variables, [](auto&& v) { return v.s; }); - return Strings::wformat( - LR"("%s" %s -P "%s")", cmake_exe.native(), cmd_cmake_pass_variables, cmake_script.generic_wstring()); - } - - std::string shorten_text(const std::string& desc, size_t length) - { - Checks::check_exit(VCPKG_LINE_INFO, length >= 3); - auto simple_desc = std::regex_replace(desc, std::regex("\\s+"), " "); - return simple_desc.size() <= length ? simple_desc : simple_desc.substr(0, length - 3) + "..."; - } -} diff --git a/toolsrc/src/vcpkgmetricsuploader.cpp b/toolsrc/src/vcpkgmetricsuploader.cpp new file mode 100644 index 000000000..2239fe750 --- /dev/null +++ b/toolsrc/src/vcpkgmetricsuploader.cpp @@ -0,0 +1,20 @@ +#include + +#include +#include + +#include + +using namespace vcpkg; + +int WINAPI WinMain(_In_ HINSTANCE, _In_opt_ HINSTANCE, _In_ LPSTR, _In_ int) +{ + int argCount; + LPWSTR* szArgList = CommandLineToArgvW(GetCommandLineW(), &argCount); + + Checks::check_exit(VCPKG_LINE_INFO, argCount == 2, "Requires exactly one argument, the path to the payload file"); + auto v = Files::get_real_filesystem().read_contents(szArgList[1]).value_or_exit(VCPKG_LINE_INFO); + Metrics::g_metrics.lock()->upload(v); + LocalFree(szArgList); + return 0; +} diff --git a/toolsrc/vcpkglib/vcpkglib.vcxproj b/toolsrc/vcpkglib/vcpkglib.vcxproj index 3bb945e85..ae332e015 100644 --- a/toolsrc/vcpkglib/vcpkglib.vcxproj +++ b/toolsrc/vcpkglib/vcpkglib.vcxproj @@ -136,114 +136,114 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create Create Create Create - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/toolsrc/vcpkglib/vcpkglib.vcxproj.filters b/toolsrc/vcpkglib/vcpkglib.vcxproj.filters index 918f83b0a..e902bffbb 100644 --- a/toolsrc/vcpkglib/vcpkglib.vcxproj.filters +++ b/toolsrc/vcpkglib/vcpkglib.vcxproj.filters @@ -13,312 +13,324 @@ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + {69f6b6e6-5ac4-4419-a256-b8a6b0392720} + + + {4a229410-0d09-4dab-953b-f434d6483f96} + + + {75592043-ab63-4905-beee-568a6ab8bf93} + + + {fa1f10e7-58d2-4f7c-ac26-a979baa70061} + - + Source Files - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg\base - - Source Files + + Source Files\vcpkg\base - - Source Files + + Source Files\vcpkg\base - - Source Files + + Source Files\vcpkg\base - - Source Files + + Source Files\vcpkg\base - - Source Files - - - Source Files + + Source Files\vcpkg\base - - Source Files + + Source Files\vcpkg\base - - Source Files - - - Source Files + + Source Files\vcpkg\base - - Source Files + + Source Files\vcpkg\base - + Header Files - - Header Files + + Header Files\vcpkg\base - - Header Files + + Header Files\vcpkg\base - - Header Files + + Header Files\vcpkg\base - - Header Files + + Header Files\vcpkg\base - - Header Files + + Header Files\vcpkg\base - - Header Files + + Header Files\vcpkg\base - - Header Files + + Header Files\vcpkg\base - - Header Files + + Header Files\vcpkg\base - - Header Files + + Header Files\vcpkg\base - - Header Files + + Header Files\vcpkg\base - - Header Files + + Header Files\vcpkg\base - - Header Files + + Header Files\vcpkg\base - - Header Files + + Header Files\vcpkg\base - - Header Files + + Header Files\vcpkg\base - - Header Files + + Header Files\vcpkg\base - - Header Files + + Header Files\vcpkg\base - - Header Files + + Header Files\vcpkg\base - - Header Files + + Header Files\vcpkg - - Header Files + + Header Files\vcpkg - - Header Files + + Header Files\vcpkg - - Header Files + + Header Files\vcpkg - - Header Files + + Header Files\vcpkg - - Header Files + + Header Files\vcpkg - - Header Files + + Header Files\vcpkg - - Header Files + + Header Files\vcpkg - - Header Files + + Header Files\vcpkg - - Header Files + + Header Files\vcpkg - - Header Files + + Header Files\vcpkg - - Header Files + + Header Files\vcpkg - - Header Files + + Header Files\vcpkg - - Header Files + + Header Files\vcpkg - - Header Files + + Header Files\vcpkg - - Header Files + + Header Files\vcpkg - - Header Files + + Header Files\vcpkg - - Header Files + + Header Files\vcpkg - - Header Files + + Header Files\vcpkg - - Header Files + + Header Files\vcpkg - - Header Files + + Header Files\vcpkg - - Header Files + + Header Files\vcpkg - - Header Files + + Header Files\vcpkg - - Header Files + + Header Files\vcpkg - - Header Files + + Header Files\vcpkg - - Header Files + + Header Files\vcpkg + + + Header Files\vcpkg + + + Header Files\vcpkg \ No newline at end of file diff --git a/toolsrc/vcpkgmetricsuploader/vcpkgmetricsuploader.vcxproj b/toolsrc/vcpkgmetricsuploader/vcpkgmetricsuploader.vcxproj index 472d74e30..4b59c5ace 100644 --- a/toolsrc/vcpkgmetricsuploader/vcpkgmetricsuploader.vcxproj +++ b/toolsrc/vcpkgmetricsuploader/vcpkgmetricsuploader.vcxproj @@ -131,7 +131,7 @@ - + diff --git a/toolsrc/vcpkgmetricsuploader/vcpkgmetricsuploader.vcxproj.filters b/toolsrc/vcpkgmetricsuploader/vcpkgmetricsuploader.vcxproj.filters index a50df7250..847921000 100644 --- a/toolsrc/vcpkgmetricsuploader/vcpkgmetricsuploader.vcxproj.filters +++ b/toolsrc/vcpkgmetricsuploader/vcpkgmetricsuploader.vcxproj.filters @@ -15,7 +15,7 @@ - + Source Files diff --git a/toolsrc/vcpkgtest/vcpkgtest.vcxproj b/toolsrc/vcpkgtest/vcpkgtest.vcxproj index 041e74d31..d25748124 100644 --- a/toolsrc/vcpkgtest/vcpkgtest.vcxproj +++ b/toolsrc/vcpkgtest/vcpkgtest.vcxproj @@ -19,11 +19,11 @@ - - - - - + + + + + diff --git a/toolsrc/vcpkgtest/vcpkgtest.vcxproj.filters b/toolsrc/vcpkgtest/vcpkgtest.vcxproj.filters index b31dbd951..42691c614 100644 --- a/toolsrc/vcpkgtest/vcpkgtest.vcxproj.filters +++ b/toolsrc/vcpkgtest/vcpkgtest.vcxproj.filters @@ -15,19 +15,19 @@ - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files -- cgit v1.2.3 From bea4c2ff4936f22b4024c2afef5e403533c7b291 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Fri, 13 Oct 2017 20:58:00 -0700 Subject: [vcpkg] Begin refactor to use CommandStructure to represent command parsing --- toolsrc/include/vcpkg/install.h | 2 + toolsrc/include/vcpkg/remove.h | 2 + toolsrc/include/vcpkg/vcpkgcmdarguments.h | 17 +++++++ toolsrc/src/vcpkg/commands.autocomplete.cpp | 77 ++++++++++++++++++----------- toolsrc/src/vcpkg/install.cpp | 38 +++++++++++--- toolsrc/src/vcpkg/remove.cpp | 37 ++++++++++++-- 6 files changed, 133 insertions(+), 40 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/install.h b/toolsrc/include/vcpkg/install.h index 02600b7f5..72643ff37 100644 --- a/toolsrc/include/vcpkg/install.h +++ b/toolsrc/include/vcpkg/install.h @@ -65,5 +65,7 @@ namespace vcpkg::Install const VcpkgPaths& paths, StatusParagraphs& status_db); + extern const CommandStructure INSTALL_COMMAND_STRUCTURE; + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet); } diff --git a/toolsrc/include/vcpkg/remove.h b/toolsrc/include/vcpkg/remove.h index f4d381ca3..04f2461be 100644 --- a/toolsrc/include/vcpkg/remove.h +++ b/toolsrc/include/vcpkg/remove.h @@ -19,6 +19,8 @@ namespace vcpkg::Remove const Purge purge, StatusParagraphs& status_db); + extern const CommandStructure REMOVE_COMMAND_STRUCTURE; + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet); void remove_package(const VcpkgPaths& paths, const PackageSpec& spec, StatusParagraphs* status_db); } diff --git a/toolsrc/include/vcpkg/vcpkgcmdarguments.h b/toolsrc/include/vcpkg/vcpkgcmdarguments.h index 6c47b98f6..8b1d766b6 100644 --- a/toolsrc/include/vcpkg/vcpkgcmdarguments.h +++ b/toolsrc/include/vcpkg/vcpkgcmdarguments.h @@ -1,6 +1,8 @@ #pragma once +#include #include +#include #include #include @@ -47,4 +49,19 @@ namespace vcpkg private: std::unordered_map> optional_command_arguments; }; + + struct VcpkgPaths; + + struct CommandStructure + { + CStringView example_text; + + size_t minimum_arity; + size_t maximum_arity; + + Span switches; + Span settings; + + std::vector (*valid_arguments)(const VcpkgPaths& paths); + }; } diff --git a/toolsrc/src/vcpkg/commands.autocomplete.cpp b/toolsrc/src/vcpkg/commands.autocomplete.cpp index b8c633142..2e191b428 100644 --- a/toolsrc/src/vcpkg/commands.autocomplete.cpp +++ b/toolsrc/src/vcpkg/commands.autocomplete.cpp @@ -2,8 +2,10 @@ #include #include +#include #include #include +#include #include namespace vcpkg::Commands::Autocomplete @@ -47,6 +49,7 @@ namespace vcpkg::Commands::Autocomplete { const SortedVector sorted_results(results); System::println(Strings::join("\n", sorted_results)); + Checks::exit_success(line_info); } @@ -63,21 +66,23 @@ namespace vcpkg::Commands::Autocomplete { const std::string requested_command = match[1].str(); - std::vector valid_commands = {"install", - "search", - "remove", - "list", - "update", - "hash", - "help", - "integrate", - "export", - "edit", - "create", - "owns", - "cache", - "version", - "contact"}; + std::vector valid_commands = { + "install", + "search", + "remove", + "list", + "update", + "hash", + "help", + "integrate", + "export", + "edit", + "create", + "owns", + "cache", + "version", + "contact", + }; Util::unstable_keep_if(valid_commands, [&](const std::string& s) { return Strings::case_insensitive_ascii_starts_with(s, requested_command); @@ -86,22 +91,36 @@ namespace vcpkg::Commands::Autocomplete output_sorted_results_and_exit(VCPKG_LINE_INFO, std::move(valid_commands)); } - // Handles vcpkg install - if (std::regex_match(to_autocomplete, match, std::regex{R"###(^install.* (\S*)$)###"})) + struct CommandEntry { - const std::string start_with = match[1].str(); - auto sources_and_errors = Paragraphs::try_load_all_ports(paths.get_filesystem(), paths.ports); - auto& source_paragraphs = sources_and_errors.paragraphs; - output_sorted_results_and_exit(VCPKG_LINE_INFO, autocomplete_install(source_paragraphs, start_with)); - } - - // Handles vcpkg remove - if (std::regex_match(to_autocomplete, match, std::regex{R"###(^remove.* (\S*)$)###"})) + CStringView regex; + const CommandStructure& structure; + }; + static constexpr CommandEntry commands[] = { + {R"###(^install\s(.*\s|)(\S*)$)###", Install::INSTALL_COMMAND_STRUCTURE}, + {R"###(^remove\s(.*\s|)(\S*)$)###", Remove::REMOVE_COMMAND_STRUCTURE}, + }; + + for (auto&& command : commands) { - const std::string start_with = match[1].str(); - const StatusParagraphs status_db = database_load_check(paths); - const std::vector installed_packages = get_installed_ports(status_db); - output_sorted_results_and_exit(VCPKG_LINE_INFO, autocomplete_remove(installed_packages, start_with)); + if (std::regex_match(to_autocomplete, match, std::regex{command.regex.c_str()})) + { + auto prefix = match[2].str(); + std::vector v; + if (Strings::case_insensitive_ascii_starts_with(prefix, "-")) + { + v = Util::fmap(command.structure.switches, [](auto&& s) -> std::string { return s; }); + } + else + { + v = command.structure.valid_arguments(paths); + } + + Util::unstable_keep_if( + v, [&](const std::string& s) { return Strings::case_insensitive_ascii_starts_with(s, prefix); }); + + output_sorted_results_and_exit(VCPKG_LINE_INFO, std::move(v)); + } } Checks::exit_success(VCPKG_LINE_INFO); diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp index 28d6d1cc6..6a564b00c 100644 --- a/toolsrc/src/vcpkg/install.cpp +++ b/toolsrc/src/vcpkg/install.cpp @@ -525,14 +525,40 @@ namespace vcpkg::Install Checks::exit_success(VCPKG_LINE_INFO); } - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) + static const std::string OPTION_DRY_RUN = "--dry-run"; + static const std::string OPTION_USE_HEAD_VERSION = "--head"; + static const std::string OPTION_NO_DOWNLOADS = "--no-downloads"; + static const std::string OPTION_RECURSE = "--recurse"; + static const std::string OPTION_KEEP_GOING = "--keep-going"; + + static const std::array INSTALL_SWITCHES = { + OPTION_DRY_RUN, + OPTION_USE_HEAD_VERSION, + OPTION_NO_DOWNLOADS, + OPTION_RECURSE, + OPTION_KEEP_GOING, + }; + static const std::array INSTALL_SETTINGS; + + static std::vector valid_arguments(const VcpkgPaths& paths) { - static const std::string OPTION_DRY_RUN = "--dry-run"; - static const std::string OPTION_USE_HEAD_VERSION = "--head"; - static const std::string OPTION_NO_DOWNLOADS = "--no-downloads"; - static const std::string OPTION_RECURSE = "--recurse"; - static const std::string OPTION_KEEP_GOING = "--keep-going"; + auto sources_and_errors = Paragraphs::try_load_all_ports(paths.get_filesystem(), paths.ports); + + return Util::fmap(sources_and_errors.paragraphs, + [](auto&& pgh) -> std::string { return pgh->core_paragraph->name; }); + } + const CommandStructure INSTALL_COMMAND_STRUCTURE = { + "install zlib zlib:x64-windows curl boost", + 1, + SIZE_MAX, + INSTALL_SWITCHES, + INSTALL_SETTINGS, + &valid_arguments, + }; + + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) + { // input sanitization static const std::string EXAMPLE = Help::create_example_string("install zlib zlib:x64-windows curl boost"); args.check_min_arg_count(1, EXAMPLE); diff --git a/toolsrc/src/vcpkg/remove.cpp b/toolsrc/src/vcpkg/remove.cpp index 3751566f7..30b3d6cd8 100644 --- a/toolsrc/src/vcpkg/remove.cpp +++ b/toolsrc/src/vcpkg/remove.cpp @@ -163,13 +163,40 @@ namespace vcpkg::Remove } } + static const std::string OPTION_PURGE = "--purge"; + static const std::string OPTION_NO_PURGE = "--no-purge"; + static const std::string OPTION_RECURSE = "--recurse"; + static const std::string OPTION_DRY_RUN = "--dry-run"; + static const std::string OPTION_OUTDATED = "--outdated"; + + static const std::array REMOVE_SWITCHES = { + OPTION_PURGE, + OPTION_NO_PURGE, + OPTION_RECURSE, + OPTION_DRY_RUN, + OPTION_OUTDATED, + }; + static const std::array REMOVE_SETTINGS; + + static std::vector valid_arguments(const VcpkgPaths& paths) + { + const StatusParagraphs status_db = database_load_check(paths); + const std::vector installed_packages = get_installed_ports(status_db); + + return Util::fmap(installed_packages, [](auto&& pgh) -> std::string { return pgh->package.spec.to_string(); }); + } + + const CommandStructure REMOVE_COMMAND_STRUCTURE = { + "remove zlib zlib:x64-windows curl boost", + 1, + SIZE_MAX, + REMOVE_SWITCHES, + REMOVE_SETTINGS, + &valid_arguments, + }; + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) { - static const std::string OPTION_PURGE = "--purge"; - static const std::string OPTION_NO_PURGE = "--no-purge"; - static const std::string OPTION_RECURSE = "--recurse"; - static const std::string OPTION_DRY_RUN = "--dry-run"; - static const std::string OPTION_OUTDATED = "--outdated"; static const std::string EXAMPLE = Help::create_example_string("remove zlib zlib:x64-windows curl boost"); const std::unordered_set options = args.check_and_get_optional_command_arguments( {OPTION_PURGE, OPTION_NO_PURGE, OPTION_RECURSE, OPTION_DRY_RUN, OPTION_OUTDATED}); -- cgit v1.2.3 From bf41a93b9de45f5d407fd03a36096f2cd37902b4 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Sat, 14 Oct 2017 02:07:42 -0700 Subject: [vcpkg] Prefer the current vcpkg directory over the one the vcpkg.exe is located in --- toolsrc/src/vcpkg.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg.cpp b/toolsrc/src/vcpkg.cpp index 748b4f0ee..f1a86ae22 100644 --- a/toolsrc/src/vcpkg.cpp +++ b/toolsrc/src/vcpkg.cpp @@ -74,8 +74,14 @@ static void inner(const VcpkgCmdArguments& args) } else { - vcpkg_root_dir = Files::get_real_filesystem().find_file_recursively_up( - fs::stdfs::absolute(System::get_exe_path_of_current_process()), ".vcpkg-root"); + const fs::path current_path = fs::stdfs::current_path(); + vcpkg_root_dir = Files::get_real_filesystem().find_file_recursively_up(current_path, ".vcpkg-root"); + + if (vcpkg_root_dir.empty()) + { + vcpkg_root_dir = Files::get_real_filesystem().find_file_recursively_up( + fs::stdfs::absolute(System::get_exe_path_of_current_process()), ".vcpkg-root"); + } } } @@ -88,6 +94,7 @@ static void inner(const VcpkgCmdArguments& args) vcpkg_root_dir.string(), expected_paths.error().message()); const VcpkgPaths paths = expected_paths.value_or_exit(VCPKG_LINE_INFO); + const int exit_code = _wchdir(paths.root.c_str()); Checks::check_exit(VCPKG_LINE_INFO, exit_code == 0, "Changing the working dir failed"); Commands::Version::warn_if_vcpkg_version_mismatch(paths); -- cgit v1.2.3 From b73327558ba79354769961a8c3f68e61fe9b673e Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Sat, 14 Oct 2017 02:07:56 -0700 Subject: `integrate` Fix quotes in command (in case of space in the path) --- toolsrc/src/vcpkg/commands.integrate.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/commands.integrate.cpp b/toolsrc/src/vcpkg/commands.integrate.cpp index 7f6639222..85b567adb 100644 --- a/toolsrc/src/vcpkg/commands.integrate.cpp +++ b/toolsrc/src/vcpkg/commands.integrate.cpp @@ -230,13 +230,14 @@ namespace vcpkg::Commands::Integrate } System::println(System::Color::success, "Applied user-wide integration for this vcpkg root."); const fs::path cmake_toolchain = paths.buildsystems / "vcpkg.cmake"; - System::println("\n" - "All MSBuild C++ projects can now #include any installed libraries.\n" - "Linking will be handled automatically.\n" - "Installing new libraries will make them instantly available.\n" - "\n" - "CMake projects should use -DCMAKE_TOOLCHAIN_FILE=%s", - cmake_toolchain.generic_string()); + System::println( + R"( +All MSBuild C++ projects can now #include any installed libraries. +Linking will be handled automatically. +Installing new libraries will make them instantly available. + +CMake projects should use: "-DCMAKE_TOOLCHAIN_FILE=%s")", + cmake_toolchain.generic_string()); Checks::exit_success(VCPKG_LINE_INFO); } -- cgit v1.2.3 From 58fd38c8200ce4c96ebe1aae3f85b324456b0ff7 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Sat, 14 Oct 2017 02:16:55 -0700 Subject: [vcpkg-autocomplete] Add edit completion --- toolsrc/include/vcpkg/commands.h | 1 + toolsrc/include/vcpkg/install.h | 2 +- toolsrc/include/vcpkg/remove.h | 2 +- toolsrc/src/vcpkg/commands.autocomplete.cpp | 5 +++-- toolsrc/src/vcpkg/commands.edit.cpp | 27 +++++++++++++++++++++++++-- toolsrc/src/vcpkg/install.cpp | 2 +- toolsrc/src/vcpkg/remove.cpp | 2 +- 7 files changed, 33 insertions(+), 8 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/commands.h b/toolsrc/include/vcpkg/commands.h index 64b2118ce..e00812c98 100644 --- a/toolsrc/include/vcpkg/commands.h +++ b/toolsrc/include/vcpkg/commands.h @@ -38,6 +38,7 @@ namespace vcpkg::Commands namespace Edit { + extern const CommandStructure COMMAND_STRUCTURE; void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); } diff --git a/toolsrc/include/vcpkg/install.h b/toolsrc/include/vcpkg/install.h index 72643ff37..db6055f4f 100644 --- a/toolsrc/include/vcpkg/install.h +++ b/toolsrc/include/vcpkg/install.h @@ -65,7 +65,7 @@ namespace vcpkg::Install const VcpkgPaths& paths, StatusParagraphs& status_db); - extern const CommandStructure INSTALL_COMMAND_STRUCTURE; + extern const CommandStructure COMMAND_STRUCTURE; void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet); } diff --git a/toolsrc/include/vcpkg/remove.h b/toolsrc/include/vcpkg/remove.h index 04f2461be..6d8a3ebe9 100644 --- a/toolsrc/include/vcpkg/remove.h +++ b/toolsrc/include/vcpkg/remove.h @@ -19,7 +19,7 @@ namespace vcpkg::Remove const Purge purge, StatusParagraphs& status_db); - extern const CommandStructure REMOVE_COMMAND_STRUCTURE; + extern const CommandStructure COMMAND_STRUCTURE; void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet); void remove_package(const VcpkgPaths& paths, const PackageSpec& spec, StatusParagraphs* status_db); diff --git a/toolsrc/src/vcpkg/commands.autocomplete.cpp b/toolsrc/src/vcpkg/commands.autocomplete.cpp index 2e191b428..23c2c2f7e 100644 --- a/toolsrc/src/vcpkg/commands.autocomplete.cpp +++ b/toolsrc/src/vcpkg/commands.autocomplete.cpp @@ -97,8 +97,9 @@ namespace vcpkg::Commands::Autocomplete const CommandStructure& structure; }; static constexpr CommandEntry commands[] = { - {R"###(^install\s(.*\s|)(\S*)$)###", Install::INSTALL_COMMAND_STRUCTURE}, - {R"###(^remove\s(.*\s|)(\S*)$)###", Remove::REMOVE_COMMAND_STRUCTURE}, + {R"###(^install\s(.*\s|)(\S*)$)###", Install::COMMAND_STRUCTURE}, + {R"###(^edit\s(.*\s|)(\S*)$)###", Edit::COMMAND_STRUCTURE}, + {R"###(^remove\s(.*\s|)(\S*)$)###", Remove::COMMAND_STRUCTURE}, }; for (auto&& command : commands) diff --git a/toolsrc/src/vcpkg/commands.edit.cpp b/toolsrc/src/vcpkg/commands.edit.cpp index 9497bd76e..a90ae1bc3 100644 --- a/toolsrc/src/vcpkg/commands.edit.cpp +++ b/toolsrc/src/vcpkg/commands.edit.cpp @@ -4,6 +4,7 @@ #include #include #include +#include namespace vcpkg::Commands::Edit { @@ -30,10 +31,32 @@ namespace vcpkg::Commands::Edit return output; } - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) + static const std::string OPTION_BUILDTREES = "--buildtrees"; + + static const std::array SWITCHES = { + OPTION_BUILDTREES, + }; + static const std::array SETTINGS; + + static std::vector valid_arguments(const VcpkgPaths& paths) { - static const std::string OPTION_BUILDTREES = "--buildtrees"; + auto sources_and_errors = Paragraphs::try_load_all_ports(paths.get_filesystem(), paths.ports); + + return Util::fmap(sources_and_errors.paragraphs, + [](auto&& pgh) -> std::string { return pgh->core_paragraph->name; }); + } + + const CommandStructure COMMAND_STRUCTURE = { + "edit zlib", + 1, + 1, + SWITCHES, + SETTINGS, + &valid_arguments, + }; + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) + { static const fs::path VS_CODE_INSIDERS = fs::path{"Microsoft VS Code Insiders"} / "Code - Insiders.exe"; static const fs::path VS_CODE = fs::path{"Microsoft VS Code"} / "Code.exe"; diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp index 6a564b00c..26f729a57 100644 --- a/toolsrc/src/vcpkg/install.cpp +++ b/toolsrc/src/vcpkg/install.cpp @@ -548,7 +548,7 @@ namespace vcpkg::Install [](auto&& pgh) -> std::string { return pgh->core_paragraph->name; }); } - const CommandStructure INSTALL_COMMAND_STRUCTURE = { + const CommandStructure COMMAND_STRUCTURE = { "install zlib zlib:x64-windows curl boost", 1, SIZE_MAX, diff --git a/toolsrc/src/vcpkg/remove.cpp b/toolsrc/src/vcpkg/remove.cpp index 30b3d6cd8..04ddba1e4 100644 --- a/toolsrc/src/vcpkg/remove.cpp +++ b/toolsrc/src/vcpkg/remove.cpp @@ -186,7 +186,7 @@ namespace vcpkg::Remove return Util::fmap(installed_packages, [](auto&& pgh) -> std::string { return pgh->package.spec.to_string(); }); } - const CommandStructure REMOVE_COMMAND_STRUCTURE = { + const CommandStructure COMMAND_STRUCTURE = { "remove zlib zlib:x64-windows curl boost", 1, SIZE_MAX, -- cgit v1.2.3 From 630bcd84b8325217c440def11681e375f5ef4652 Mon Sep 17 00:00:00 2001 From: martin-s Date: Sat, 14 Oct 2017 18:31:53 +0200 Subject: - Updated naming of msvcrt vector. --- toolsrc/src/PostBuildLint.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/PostBuildLint.cpp b/toolsrc/src/PostBuildLint.cpp index 58d6f987b..5de1078cd 100644 --- a/toolsrc/src/PostBuildLint.cpp +++ b/toolsrc/src/PostBuildLint.cpp @@ -57,7 +57,7 @@ namespace vcpkg::PostBuildLint {"msvcrt40.dll", R"(msvcrt40\.dll)"}, }; - static const std::vector V = [&]() { + static const std::vector V_NO_MSVCRT = [&]() { auto ret = V_NO_120; ret.push_back({"msvcp120.dll", R"(msvcp120\.dll)"}); ret.push_back({"msvcp120_clr0400.dll", R"(msvcp120_clr0400\.dll)"}); @@ -69,7 +69,7 @@ namespace vcpkg::PostBuildLint if (toolset == "v120") return V_NO_120; else - return V; + return V_NO_MSVCRT; } static LintStatus check_for_files_in_include_directory(const Files::Filesystem& fs, -- cgit v1.2.3 From c6d69fac625706c52fc8e48615bc0c6d7b8dad25 Mon Sep 17 00:00:00 2001 From: martin-s Date: Sun, 15 Oct 2017 02:13:36 +0200 Subject: - Fixed formatting. --- toolsrc/src/vcpkg/postbuildlint.cpp | 16 ++++++++-------- toolsrc/src/vcpkg/vcpkgpaths.cpp | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/postbuildlint.cpp b/toolsrc/src/vcpkg/postbuildlint.cpp index b2422b4b2..548093c6f 100644 --- a/toolsrc/src/vcpkg/postbuildlint.cpp +++ b/toolsrc/src/vcpkg/postbuildlint.cpp @@ -66,14 +66,14 @@ namespace vcpkg::PostBuildLint return ret; }(); - const auto tsv = toolset_version.get(); - if (tsv && (*tsv) == "v120") - { - return V_NO_120; - } - - // Default case for all version >= VS 2015. - return V_NO_MSVCRT; + const auto tsv = toolset_version.get(); + if (tsv && (*tsv) == "v120") + { + return V_NO_120; + } + + // Default case for all version >= VS 2015. + return V_NO_MSVCRT; } static LintStatus check_for_files_in_include_directory(const Files::Filesystem& fs, diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index f0e02db8a..b6ec2cb52 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -448,7 +448,7 @@ namespace vcpkg vs_dumpbin_exe, vcvarsall_bat, {}, - major_version == "14" ? V_140 : V_120, + major_version == "14" ? V_140 : V_120, supported_architectures}); } } -- cgit v1.2.3 From 93497f5eab0c1628cc5b1a3a9a671c069c8f8533 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Sun, 15 Oct 2017 22:16:46 -0700 Subject: Casing and specification correctness --- toolsrc/src/vcpkg/commands.autocomplete.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/commands.autocomplete.cpp b/toolsrc/src/vcpkg/commands.autocomplete.cpp index 23c2c2f7e..3901566d9 100644 --- a/toolsrc/src/vcpkg/commands.autocomplete.cpp +++ b/toolsrc/src/vcpkg/commands.autocomplete.cpp @@ -93,16 +93,21 @@ namespace vcpkg::Commands::Autocomplete struct CommandEntry { + constexpr CommandEntry(const CStringView& regex, const CommandStructure& structure) + : regex(regex), structure(structure) + { + } + CStringView regex; const CommandStructure& structure; }; - static constexpr CommandEntry commands[] = { - {R"###(^install\s(.*\s|)(\S*)$)###", Install::COMMAND_STRUCTURE}, - {R"###(^edit\s(.*\s|)(\S*)$)###", Edit::COMMAND_STRUCTURE}, - {R"###(^remove\s(.*\s|)(\S*)$)###", Remove::COMMAND_STRUCTURE}, + static constexpr CommandEntry COMMANDS[] = { + CommandEntry{R"###(^install\s(.*\s|)(\S*)$)###", Install::COMMAND_STRUCTURE}, + CommandEntry{R"###(^edit\s(.*\s|)(\S*)$)###", Edit::COMMAND_STRUCTURE}, + CommandEntry{R"###(^remove\s(.*\s|)(\S*)$)###", Remove::COMMAND_STRUCTURE}, }; - for (auto&& command : commands) + for (auto&& command : COMMANDS) { if (std::regex_match(to_autocomplete, match, std::regex{command.regex.c_str()})) { -- cgit v1.2.3 From 6942c00a453c9fa4f9fbde7ba821974110b43d57 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Sun, 15 Oct 2017 23:23:39 -0700 Subject: [triplet] Remove obsolete check about dash in the name Triplets haven't required that for a while now --- toolsrc/src/vcpkg/triplet.cpp | 3 --- 1 file changed, 3 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/triplet.cpp b/toolsrc/src/vcpkg/triplet.cpp index 8a84ee2b2..4ebb97a9b 100644 --- a/toolsrc/src/vcpkg/triplet.cpp +++ b/toolsrc/src/vcpkg/triplet.cpp @@ -41,9 +41,6 @@ namespace vcpkg Triplet Triplet::from_canonical_name(const std::string& triplet_as_string) { std::string s(Strings::ascii_to_lowercase(triplet_as_string)); - const auto it = std::find(s.cbegin(), s.cend(), '-'); - Checks::check_exit(VCPKG_LINE_INFO, it != s.cend(), "Invalid triplet: %s", triplet_as_string); - const auto p = g_triplet_instances.emplace(std::move(s)); return &*p.first; } -- cgit v1.2.3 From b486be5eb3b12c0a6fa0a81992768340317ec5c2 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Sun, 15 Oct 2017 23:24:34 -0700 Subject: Introduce VcpkgPaths::get_available_triplets() --- toolsrc/include/vcpkg/vcpkgpaths.h | 2 ++ toolsrc/src/vcpkg/help.cpp | 4 ++-- toolsrc/src/vcpkg/vcpkgpaths.cpp | 25 ++++++++++++++++--------- 3 files changed, 20 insertions(+), 11 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/vcpkgpaths.h b/toolsrc/include/vcpkg/vcpkgpaths.h index fb9285a84..32dd2e833 100644 --- a/toolsrc/include/vcpkg/vcpkgpaths.h +++ b/toolsrc/include/vcpkg/vcpkgpaths.h @@ -36,6 +36,7 @@ namespace vcpkg fs::path build_info_file_path(const PackageSpec& spec) const; fs::path listfile_path(const BinaryParagraph& pgh) const; + const std::vector& get_available_triplets() const; bool is_valid_triplet(const Triplet& t) const; fs::path root; @@ -74,6 +75,7 @@ namespace vcpkg Files::Filesystem& get_filesystem() const; private: + Lazy> available_triplets; Lazy cmake_exe; Lazy git_exe; Lazy nuget_exe; diff --git a/toolsrc/src/vcpkg/help.cpp b/toolsrc/src/vcpkg/help.cpp index 7867f71d2..2a0578211 100644 --- a/toolsrc/src/vcpkg/help.cpp +++ b/toolsrc/src/vcpkg/help.cpp @@ -16,9 +16,9 @@ namespace vcpkg::Help void help_topic_valid_triplet(const VcpkgPaths& paths) { System::println("Available architecture triplets:"); - for (auto&& path : paths.get_filesystem().get_files_non_recursive(paths.triplets)) + for (auto&& triplet : paths.get_available_triplets()) { - System::println(" %s", path.stem().filename().string()); + System::println(" %s", triplet); } } diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index 07ce5c961..c57077eaa 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -255,18 +255,25 @@ namespace vcpkg return this->vcpkg_dir_info / (pgh.fullstem() + ".list"); } - bool VcpkgPaths::is_valid_triplet(const Triplet& t) const + const std::vector& VcpkgPaths::get_available_triplets() const { - for (auto&& path : get_filesystem().get_files_non_recursive(this->triplets)) - { - const std::string triplet_file_name = path.stem().generic_u8string(); - if (t.canonical_name() == triplet_file_name) // TODO: fuzzy compare + return this->available_triplets.get_lazy([this]() -> std::vector { + + std::vector output; + for (auto&& path : this->get_filesystem().get_files_non_recursive(this->triplets)) { - // t.value = triplet_file_name; // NOTE: uncomment when implementing fuzzy compare - return true; + output.push_back(path.stem().filename().string()); } - } - return false; + + return output; + }); + } + + bool VcpkgPaths::is_valid_triplet(const Triplet& t) const + { + auto it = Util::find_if(this->get_available_triplets(), + [&](auto&& available_triplet) { return t.canonical_name() == available_triplet; }); + return it != this->get_available_triplets().cend(); } const fs::path& VcpkgPaths::get_cmake_exe() const -- cgit v1.2.3 From e46ec5369318f84f359af9f88cb3d517329bf088 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Sun, 15 Oct 2017 23:33:52 -0700 Subject: Remove unused functions --- toolsrc/src/vcpkg/commands.autocomplete.cpp | 34 ----------------------------- 1 file changed, 34 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/commands.autocomplete.cpp b/toolsrc/src/vcpkg/commands.autocomplete.cpp index 3901566d9..feca75dcd 100644 --- a/toolsrc/src/vcpkg/commands.autocomplete.cpp +++ b/toolsrc/src/vcpkg/commands.autocomplete.cpp @@ -10,40 +10,6 @@ namespace vcpkg::Commands::Autocomplete { - std::vector autocomplete_install( - const std::vector>& source_paragraphs, const std::string& start_with) - { - std::vector results; - - for (const auto& source_control_file : source_paragraphs) - { - auto&& sp = *source_control_file->core_paragraph; - - if (Strings::case_insensitive_ascii_starts_with(sp.name, start_with)) - { - results.push_back(sp.name); - } - } - return results; - } - - std::vector autocomplete_remove(std::vector installed_packages, - const std::string& start_with) - { - std::vector results; - - for (const auto& installed_package : installed_packages) - { - const auto sp = installed_package->package.displayname(); - - if (Strings::case_insensitive_ascii_starts_with(sp, start_with)) - { - results.push_back(sp); - } - } - return results; - } - [[noreturn]] static void output_sorted_results_and_exit(const LineInfo& line_info, std::vector&& results) { -- cgit v1.2.3 From 798f8a91e43bfdeda8113639ff262f42e5ab6f84 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Sun, 15 Oct 2017 23:53:35 -0700 Subject: Introduce Vectors::concatenate() --- toolsrc/include/vcpkg/base/util.h | 17 +++++++++++++---- toolsrc/src/vcpkg/install.cpp | 2 +- 2 files changed, 14 insertions(+), 5 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/base/util.h b/toolsrc/include/vcpkg/base/util.h index 3834580b6..4f06a8231 100644 --- a/toolsrc/include/vcpkg/base/util.h +++ b/toolsrc/include/vcpkg/base/util.h @@ -7,6 +7,18 @@ namespace vcpkg::Util { + template + using ElementT = std::remove_reference_t()))>; + + namespace Vectors + { + template> + void concatenate(std::vector* augend, const Container& addend) + { + augend->insert(augend->end(), addend.begin(), addend.end()); + } + } + template using FmapOut = decltype(std::declval()(*begin(std::declval()))); @@ -71,9 +83,6 @@ namespace vcpkg::Util return std::find_if(begin(cont), end(cont), pred); } - template - using ElementT = std::remove_reference_t()))>; - template> std::vector element_pointers(Container&& cont) { @@ -153,4 +162,4 @@ namespace vcpkg::Util std::unique_lock m_lock; T& m_ptr; }; -} \ No newline at end of file +} diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp index 26f729a57..4a1e5537b 100644 --- a/toolsrc/src/vcpkg/install.cpp +++ b/toolsrc/src/vcpkg/install.cpp @@ -145,7 +145,7 @@ namespace vcpkg::Install continue; } - output.insert(output.end(), t.files.begin(), t.files.end()); + Util::Vectors::concatenate(&output, t.files); } std::sort(output.begin(), output.end()); -- cgit v1.2.3 From 01f47f5823b0c0db4a7e3e5b690dbc809429da56 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 16 Oct 2017 01:14:04 -0700 Subject: [autocomplete] Add triplet completion for `vcpkg install` --- toolsrc/src/vcpkg/commands.autocomplete.cpp | 65 +++++++++++++++++++++++------ 1 file changed, 53 insertions(+), 12 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/commands.autocomplete.cpp b/toolsrc/src/vcpkg/commands.autocomplete.cpp index feca75dcd..addb9edaf 100644 --- a/toolsrc/src/vcpkg/commands.autocomplete.cpp +++ b/toolsrc/src/vcpkg/commands.autocomplete.cpp @@ -19,6 +19,13 @@ namespace vcpkg::Commands::Autocomplete Checks::exit_success(line_info); } + std::vector combine_port_with_triplets(const std::string& port, + const std::vector& triplets) + { + return Util::fmap(triplets, + [&](const std::string& triplet) { return Strings::format("%s:%s", port, triplet); }); + } + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { Metrics::g_metrics.lock()->set_send_metrics(false); @@ -57,41 +64,75 @@ namespace vcpkg::Commands::Autocomplete output_sorted_results_and_exit(VCPKG_LINE_INFO, std::move(valid_commands)); } + // Handles vcpkg install package: + if (std::regex_match(to_autocomplete, match, std::regex{R"###(^install(.*|)\s([^:]+):(\S*)$)###"})) + { + const auto port_name = match[2].str(); + const auto triplet_prefix = match[3].str(); + + auto maybe_port = Paragraphs::try_load_port(paths.get_filesystem(), paths.port_dir(port_name)); + if (maybe_port.error()) + { + Checks::exit_success(VCPKG_LINE_INFO); + } + + std::vector triplets = paths.get_available_triplets(); + Util::unstable_keep_if(triplets, [&](const std::string& s) { + return Strings::case_insensitive_ascii_starts_with(s, triplet_prefix); + }); + + auto result = combine_port_with_triplets(port_name, triplets); + + output_sorted_results_and_exit(VCPKG_LINE_INFO, std::move(result)); + } + struct CommandEntry { - constexpr CommandEntry(const CStringView& regex, const CommandStructure& structure) - : regex(regex), structure(structure) + constexpr CommandEntry(const CStringView& name, const CStringView& regex, const CommandStructure& structure) + : name(name), regex(regex), structure(structure) { } + CStringView name; CStringView regex; const CommandStructure& structure; }; + static constexpr CommandEntry COMMANDS[] = { - CommandEntry{R"###(^install\s(.*\s|)(\S*)$)###", Install::COMMAND_STRUCTURE}, - CommandEntry{R"###(^edit\s(.*\s|)(\S*)$)###", Edit::COMMAND_STRUCTURE}, - CommandEntry{R"###(^remove\s(.*\s|)(\S*)$)###", Remove::COMMAND_STRUCTURE}, + CommandEntry{"install", R"###(^install\s(.*\s|)(\S*)$)###", Install::COMMAND_STRUCTURE}, + CommandEntry{"install", R"###(^install\s(.*\s|)(\S*)$)###", Install::COMMAND_STRUCTURE}, + CommandEntry{"edit", R"###(^edit\s(.*\s|)(\S*)$)###", Edit::COMMAND_STRUCTURE}, + CommandEntry{"remove", R"###(^remove\s(.*\s|)(\S*)$)###", Remove::COMMAND_STRUCTURE}, }; for (auto&& command : COMMANDS) { if (std::regex_match(to_autocomplete, match, std::regex{command.regex.c_str()})) { - auto prefix = match[2].str(); - std::vector v; + const auto prefix = match[2].str(); + std::vector results; + if (Strings::case_insensitive_ascii_starts_with(prefix, "-")) { - v = Util::fmap(command.structure.switches, [](auto&& s) -> std::string { return s; }); + results = Util::fmap(command.structure.switches, [](auto&& s) -> std::string { return s; }); } else { - v = command.structure.valid_arguments(paths); + results = command.structure.valid_arguments(paths); } - Util::unstable_keep_if( - v, [&](const std::string& s) { return Strings::case_insensitive_ascii_starts_with(s, prefix); }); + Util::unstable_keep_if(results, [&](const std::string& s) { + return Strings::case_insensitive_ascii_starts_with(s, prefix); + }); + + if (command.name == "install" && results.size() == 1) + { + const auto port_at_each_triplet = + combine_port_with_triplets(results[0], paths.get_available_triplets()); + Util::Vectors::concatenate(&results, port_at_each_triplet); + } - output_sorted_results_and_exit(VCPKG_LINE_INFO, std::move(v)); + output_sorted_results_and_exit(VCPKG_LINE_INFO, std::move(results)); } } -- cgit v1.2.3 From 7214c3583bdf569bc873305908ec109a6c8716cc Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Mon, 16 Oct 2017 11:44:04 -0700 Subject: [vcpkg] Push use of UTF-16 to only around Win32 call boundaries. --- toolsrc/include/pch.h | 18 ++- toolsrc/include/vcpkg/base/cstringview.h | 1 + toolsrc/include/vcpkg/base/expected.h | 2 +- toolsrc/include/vcpkg/base/files.h | 14 ++- toolsrc/include/vcpkg/base/graphs.h | 6 +- toolsrc/include/vcpkg/base/strings.h | 19 +-- toolsrc/include/vcpkg/base/system.h | 15 +-- toolsrc/include/vcpkg/base/util.h | 3 +- toolsrc/include/vcpkg/build.h | 2 +- toolsrc/include/vcpkg/dependencies.h | 5 +- toolsrc/include/vcpkg/packagespec.h | 33 +++--- toolsrc/include/vcpkg/packagespecparseresult.h | 2 +- toolsrc/include/vcpkg/paragraphparseresult.h | 11 +- toolsrc/include/vcpkg/sourceparagraph.h | 2 +- toolsrc/include/vcpkg/triplet.h | 11 +- toolsrc/include/vcpkg/vcpkgcmdarguments.h | 4 + toolsrc/include/vcpkg/vcpkglib.h | 15 ++- toolsrc/include/vcpkg/vcpkgpaths.h | 8 +- toolsrc/src/vcpkg.cpp | 46 ++++++-- toolsrc/src/vcpkg/base/checks.cpp | 12 +- toolsrc/src/vcpkg/base/cofffilereader.cpp | 7 +- toolsrc/src/vcpkg/base/files.cpp | 13 +- toolsrc/src/vcpkg/base/strings.cpp | 21 +++- toolsrc/src/vcpkg/base/system.cpp | 157 ++++++++++++++++++------- toolsrc/src/vcpkg/binaryparagraph.cpp | 4 +- toolsrc/src/vcpkg/build.cpp | 72 ++++++------ toolsrc/src/vcpkg/commands.create.cpp | 6 +- toolsrc/src/vcpkg/commands.edit.cpp | 15 ++- toolsrc/src/vcpkg/commands.env.cpp | 2 +- toolsrc/src/vcpkg/commands.exportifw.cpp | 32 ++--- toolsrc/src/vcpkg/commands.hash.cpp | 23 ++-- toolsrc/src/vcpkg/commands.integrate.cpp | 33 ++++-- toolsrc/src/vcpkg/commands.portsdiff.cpp | 46 ++++---- toolsrc/src/vcpkg/commands.version.cpp | 15 ++- toolsrc/src/vcpkg/dependencies.cpp | 15 ++- toolsrc/src/vcpkg/export.cpp | 43 ++++--- toolsrc/src/vcpkg/globalstate.cpp | 8 +- toolsrc/src/vcpkg/install.cpp | 5 +- toolsrc/src/vcpkg/metrics.cpp | 44 ++++--- toolsrc/src/vcpkg/packagespec.cpp | 4 +- toolsrc/src/vcpkg/parse.cpp | 2 +- toolsrc/src/vcpkg/postbuildlint.cpp | 39 ++---- toolsrc/src/vcpkg/remove.cpp | 2 +- toolsrc/src/vcpkg/sourceparagraph.cpp | 6 +- toolsrc/src/vcpkg/triplet.cpp | 11 +- toolsrc/src/vcpkg/vcpkgcmdarguments.cpp | 14 ++- toolsrc/src/vcpkg/vcpkglib.cpp | 26 ++-- toolsrc/src/vcpkg/vcpkgpaths.cpp | 102 ++++++++-------- 48 files changed, 592 insertions(+), 404 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/pch.h b/toolsrc/include/pch.h index 8333eb927..5c31fbbd1 100644 --- a/toolsrc/include/pch.h +++ b/toolsrc/include/pch.h @@ -1,5 +1,6 @@ #pragma once +#if defined(_WIN32) #define NOMINMAX #define WIN32_LEAN_AND_MEAN @@ -9,6 +10,13 @@ #pragma warning(suppress : 4768) #include +#include +#include +#include +#else +#include +#endif + #include #include #include @@ -19,7 +27,12 @@ #include #include #include +#if defined(_WIN32) #include +#else +#include +#endif +#include #include #include #include @@ -28,18 +41,17 @@ #include #include #include -#include #include #include -#include #include #include #include +#include #include +#include #include #include #include #include #include #include -#include diff --git a/toolsrc/include/vcpkg/base/cstringview.h b/toolsrc/include/vcpkg/base/cstringview.h index 341830f05..eac204f97 100644 --- a/toolsrc/include/vcpkg/base/cstringview.h +++ b/toolsrc/include/vcpkg/base/cstringview.h @@ -1,5 +1,6 @@ #pragma once +#include #include namespace vcpkg diff --git a/toolsrc/include/vcpkg/base/expected.h b/toolsrc/include/vcpkg/base/expected.h index a946c442e..b3b81ae81 100644 --- a/toolsrc/include/vcpkg/base/expected.h +++ b/toolsrc/include/vcpkg/base/expected.h @@ -33,7 +33,7 @@ namespace vcpkg ErrorHolder() = default; ErrorHolder(const std::error_code& err) : m_err(err) {} - constexpr bool has_error() const { return bool(m_err); } + bool has_error() const { return bool(m_err); } const std::error_code& error() const { return m_err; } std::error_code& error() { return m_err; } diff --git a/toolsrc/include/vcpkg/base/files.h b/toolsrc/include/vcpkg/base/files.h index f4bcf742c..63cf3c6fd 100644 --- a/toolsrc/include/vcpkg/base/files.h +++ b/toolsrc/include/vcpkg/base/files.h @@ -2,7 +2,11 @@ #include +#if defined(_WIN32) #include +#else +#include +#endif namespace fs { @@ -19,7 +23,7 @@ namespace fs namespace vcpkg::Files { - __interface Filesystem + struct Filesystem { virtual Expected read_contents(const fs::path& file_path) const = 0; virtual Expected> read_lines(const fs::path& file_path) const = 0; @@ -40,8 +44,10 @@ namespace vcpkg::Files virtual bool create_directory(const fs::path& path, std::error_code& ec) = 0; virtual bool create_directories(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 bool copy_file( - const fs::path& oldpath, const fs::path& newpath, fs::copy_options opts, std::error_code& ec) = 0; + virtual bool copy_file(const fs::path& oldpath, + const fs::path& newpath, + fs::copy_options opts, + std::error_code& ec) = 0; virtual fs::file_status status(const fs::path& path, std::error_code& ec) const = 0; }; @@ -53,5 +59,5 @@ namespace vcpkg::Files void print_paths(const std::vector& paths); - std::vector find_from_PATH(const std::wstring& name); + std::vector find_from_PATH(const std::string& name); } diff --git a/toolsrc/include/vcpkg/base/graphs.h b/toolsrc/include/vcpkg/base/graphs.h index ff56cb298..b585d2bb9 100644 --- a/toolsrc/include/vcpkg/base/graphs.h +++ b/toolsrc/include/vcpkg/base/graphs.h @@ -20,11 +20,11 @@ namespace vcpkg::Graphs }; template - __interface AdjacencyProvider + struct AdjacencyProvider { - std::vector adjacency_list(const U& vertex) const; + virtual std::vector adjacency_list(const U& vertex) const = 0; - U load_vertex_data(const V& vertex) const; + virtual U load_vertex_data(const V& vertex) const = 0; }; template diff --git a/toolsrc/include/vcpkg/base/strings.h b/toolsrc/include/vcpkg/base/strings.h index 59823deb8..93b36a29d 100644 --- a/toolsrc/include/vcpkg/base/strings.h +++ b/toolsrc/include/vcpkg/base/strings.h @@ -16,15 +16,11 @@ namespace vcpkg::Strings::details inline const char* to_printf_arg(const char* s) { return s; } - inline int to_printf_arg(const int s) { return s; } - - inline long long to_printf_arg(const long long s) { return s; } - - inline unsigned long to_printf_arg(const unsigned long s) { return s; } - - inline size_t to_printf_arg(const size_t s) { return s; } - - inline double to_printf_arg(const double s) { return s; } + template::value>> + inline T to_printf_arg(T s) + { + return s; + } std::string format_internal(const char* fmtstr, ...); @@ -37,9 +33,6 @@ namespace vcpkg::Strings::details namespace vcpkg::Strings { - static constexpr const char* EMPTY = ""; - static constexpr const wchar_t* WEMPTY = L""; - template std::string format(const char* fmtstr, const Args&... args) { @@ -62,7 +55,7 @@ namespace vcpkg::Strings bool case_insensitive_ascii_contains(const std::string& s, const std::string& pattern); - bool case_insensitive_ascii_compare(const CStringView left, const CStringView right); + bool case_insensitive_ascii_equals(const CStringView left, const CStringView right); std::string ascii_to_lowercase(const std::string& input); diff --git a/toolsrc/include/vcpkg/base/system.h b/toolsrc/include/vcpkg/base/system.h index a2e8f3f45..f2344c919 100644 --- a/toolsrc/include/vcpkg/base/system.h +++ b/toolsrc/include/vcpkg/base/system.h @@ -4,7 +4,6 @@ #include #include -#include namespace vcpkg::System { @@ -18,13 +17,13 @@ namespace vcpkg::System std::string output; }; - int cmd_execute_clean(const CWStringView cmd_line); + int cmd_execute_clean(const CStringView cmd_line); - int cmd_execute(const CWStringView cmd_line); + int cmd_execute(const CStringView cmd_line); - ExitCodeAndOutput cmd_execute_and_capture_output(const CWStringView cmd_line); + ExitCodeAndOutput cmd_execute_and_capture_output(const CStringView cmd_line); - std::wstring create_powershell_script_cmd(const fs::path& script_path, const CWStringView args = Strings::WEMPTY); + std::string create_powershell_script_cmd(const fs::path& script_path, const CStringView args = ""); enum class Color { @@ -63,9 +62,11 @@ namespace vcpkg::System return System::println(c, Strings::format(messageTemplate, messageArg1, messageArgs...)); } - Optional get_environment_variable(const CWStringView varname) noexcept; + Optional get_environment_variable(const CStringView varname) noexcept; - Optional get_registry_string(HKEY base, const CWStringView subkey, const CWStringView valuename); + Optional get_registry_string(void* base_hkey, + const CWStringView subkey, + const CWStringView valuename); enum class CPUArchitecture { diff --git a/toolsrc/include/vcpkg/base/util.h b/toolsrc/include/vcpkg/base/util.h index 4f06a8231..d5db6b6ee 100644 --- a/toolsrc/include/vcpkg/base/util.h +++ b/toolsrc/include/vcpkg/base/util.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -98,7 +99,7 @@ namespace vcpkg::Util } template - void group_by(const Container& cont, _Inout_ std::map>* output, Func&& f) + void group_by(const Container& cont, std::map>* output, Func&& f) { for (const V& element : cont) { diff --git a/toolsrc/include/vcpkg/build.h b/toolsrc/include/vcpkg/build.h index f146e9951..774e25922 100644 --- a/toolsrc/include/vcpkg/build.h +++ b/toolsrc/include/vcpkg/build.h @@ -96,7 +96,7 @@ namespace vcpkg::Build Optional visual_studio_path; }; - std::wstring make_build_env_cmd(const PreBuildInfo& pre_build_info, const Toolset& toolset); + std::string make_build_env_cmd(const PreBuildInfo& pre_build_info, const Toolset& toolset); struct ExtendedBuildResult { diff --git a/toolsrc/include/vcpkg/dependencies.h b/toolsrc/include/vcpkg/dependencies.h index 2301dbc36..585338ae2 100644 --- a/toolsrc/include/vcpkg/dependencies.h +++ b/toolsrc/include/vcpkg/dependencies.h @@ -115,7 +115,10 @@ namespace vcpkg::Dependencies RequestType request_type; }; - __interface PortFileProvider { virtual const SourceControlFile& get_control_file(const std::string& spec) const; }; + struct PortFileProvider + { + virtual const SourceControlFile& get_control_file(const std::string& spec) const = 0; + }; struct MapPortFile : Util::ResourceBase, PortFileProvider { diff --git a/toolsrc/include/vcpkg/packagespec.h b/toolsrc/include/vcpkg/packagespec.h index ee34f14a3..60c99782e 100644 --- a/toolsrc/include/vcpkg/packagespec.h +++ b/toolsrc/include/vcpkg/packagespec.h @@ -76,20 +76,23 @@ namespace vcpkg bool operator!=(const PackageSpec& left, const PackageSpec& right); } -template<> -struct std::hash +namespace std { - size_t operator()(const vcpkg::PackageSpec& value) const + template<> + struct hash { - size_t hash = 17; - hash = hash * 31 + std::hash()(value.name()); - hash = hash * 31 + std::hash()(value.triplet()); - return hash; - } -}; - -template<> -struct std::equal_to -{ - bool operator()(const vcpkg::PackageSpec& left, const vcpkg::PackageSpec& right) const { return left == right; } -}; + size_t operator()(const vcpkg::PackageSpec& value) const + { + size_t hash = 17; + hash = hash * 31 + std::hash()(value.name()); + hash = hash * 31 + std::hash()(value.triplet()); + return hash; + } + }; + + template<> + struct equal_to + { + bool operator()(const vcpkg::PackageSpec& left, const vcpkg::PackageSpec& right) const { return left == right; } + }; +} diff --git a/toolsrc/include/vcpkg/packagespecparseresult.h b/toolsrc/include/vcpkg/packagespecparseresult.h index 8a56574fd..dd91c9a67 100644 --- a/toolsrc/include/vcpkg/packagespecparseresult.h +++ b/toolsrc/include/vcpkg/packagespecparseresult.h @@ -20,7 +20,7 @@ namespace vcpkg ErrorHolder() : m_err(PackageSpecParseResult::SUCCESS) {} ErrorHolder(PackageSpecParseResult err) : m_err(err) {} - constexpr bool has_error() const { return m_err != PackageSpecParseResult::SUCCESS; } + bool has_error() const { return m_err != PackageSpecParseResult::SUCCESS; } const PackageSpecParseResult& error() const { return m_err; } PackageSpecParseResult& error() { return m_err; } diff --git a/toolsrc/include/vcpkg/paragraphparseresult.h b/toolsrc/include/vcpkg/paragraphparseresult.h index abdd9eecd..558715bbc 100644 --- a/toolsrc/include/vcpkg/paragraphparseresult.h +++ b/toolsrc/include/vcpkg/paragraphparseresult.h @@ -26,8 +26,11 @@ namespace vcpkg ParagraphParseResult to_paragraph_parse_result(std::error_code ec); } -// Enable implicit conversion to std::error_code -template<> -struct std::is_error_code_enum : ::std::true_type +namespace std { -}; + // Enable implicit conversion to std::error_code + template<> + struct is_error_code_enum : ::std::true_type + { + }; +} \ No newline at end of file diff --git a/toolsrc/include/vcpkg/sourceparagraph.h b/toolsrc/include/vcpkg/sourceparagraph.h index 0a02e4cda..dcbbc1c3b 100644 --- a/toolsrc/include/vcpkg/sourceparagraph.h +++ b/toolsrc/include/vcpkg/sourceparagraph.h @@ -3,8 +3,8 @@ #include #include -#include #include +#include #include #include diff --git a/toolsrc/include/vcpkg/triplet.h b/toolsrc/include/vcpkg/triplet.h index 46a52f8e6..50d731593 100644 --- a/toolsrc/include/vcpkg/triplet.h +++ b/toolsrc/include/vcpkg/triplet.h @@ -36,8 +36,11 @@ namespace vcpkg bool operator!=(const Triplet& left, const Triplet& right); } -template<> -struct std::hash +namespace std { - size_t operator()(const vcpkg::Triplet& t) const { return t.hash_code(); } -}; + template<> + struct hash + { + size_t operator()(const vcpkg::Triplet& t) const { return t.hash_code(); } + }; +} \ No newline at end of file diff --git a/toolsrc/include/vcpkg/vcpkgcmdarguments.h b/toolsrc/include/vcpkg/vcpkgcmdarguments.h index 8b1d766b6..d9895f4b8 100644 --- a/toolsrc/include/vcpkg/vcpkgcmdarguments.h +++ b/toolsrc/include/vcpkg/vcpkgcmdarguments.h @@ -19,7 +19,11 @@ namespace vcpkg struct VcpkgCmdArguments { +#if defined(_WIN32) static VcpkgCmdArguments create_from_command_line(const int argc, const wchar_t* const* const argv); +#else + static VcpkgCmdArguments create_from_command_line(const int argc, const char* const* const argv); +#endif static VcpkgCmdArguments create_from_arg_sequence(const std::string* arg_begin, const std::string* arg_end); std::unique_ptr vcpkg_root_dir; diff --git a/toolsrc/include/vcpkg/vcpkglib.h b/toolsrc/include/vcpkg/vcpkglib.h index b2aad8d7b..9a7fdb861 100644 --- a/toolsrc/include/vcpkg/vcpkglib.h +++ b/toolsrc/include/vcpkg/vcpkglib.h @@ -22,17 +22,16 @@ namespace vcpkg struct CMakeVariable { - CMakeVariable(const CWStringView varname, const wchar_t* varvalue); - CMakeVariable(const CWStringView varname, const std::string& varvalue); - CMakeVariable(const CWStringView varname, const std::wstring& varvalue); - CMakeVariable(const CWStringView varname, const fs::path& path); + CMakeVariable(const CStringView varname, const char* varvalue); + CMakeVariable(const CStringView varname, const std::string& varvalue); + CMakeVariable(const CStringView varname, const fs::path& path); - std::wstring s; + std::string s; }; - std::wstring make_cmake_cmd(const fs::path& cmake_exe, - const fs::path& cmake_script, - const std::vector& pass_variables); + std::string make_cmake_cmd(const fs::path& cmake_exe, + const fs::path& cmake_script, + const std::vector& pass_variables); std::string shorten_text(const std::string& desc, size_t length); } // namespace vcpkg diff --git a/toolsrc/include/vcpkg/vcpkgpaths.h b/toolsrc/include/vcpkg/vcpkgpaths.h index 32dd2e833..781dabd1a 100644 --- a/toolsrc/include/vcpkg/vcpkgpaths.h +++ b/toolsrc/include/vcpkg/vcpkgpaths.h @@ -3,15 +3,15 @@ #include #include -#include #include #include +#include namespace vcpkg { struct ToolsetArchOption { - CWStringView name; + CStringView name; System::CPUArchitecture host_arch; System::CPUArchitecture target_arch; }; @@ -21,8 +21,8 @@ namespace vcpkg fs::path visual_studio_root_path; fs::path dumpbin; fs::path vcvarsall; - std::vector vcvarsall_options; - CWStringView version; + std::vector vcvarsall_options; + CStringView version; std::vector supported_architectures; }; diff --git a/toolsrc/src/vcpkg.cpp b/toolsrc/src/vcpkg.cpp index f1a86ae22..e1e2240e7 100644 --- a/toolsrc/src/vcpkg.cpp +++ b/toolsrc/src/vcpkg.cpp @@ -1,6 +1,15 @@ +#if defined(_WIN32) #define WIN32_LEAN_AND_MEAN #include +#pragma warning(push) +#pragma warning(disable : 4768) +#include +#pragma warning(pop) +#else +#include +#endif + #include #include #include @@ -13,10 +22,6 @@ #include #include -#pragma warning(push) -#pragma warning(disable : 4768) -#include -#pragma warning(pop) #include #include #include @@ -44,7 +49,7 @@ static void inner(const VcpkgCmdArguments& args) static const auto find_command = [&](auto&& commands) { auto it = Util::find_if(commands, [&](auto&& commandc) { - return Strings::case_insensitive_ascii_compare(commandc.name, args.command); + return Strings::case_insensitive_ascii_equals(commandc.name, args.command); }); using std::end; if (it != end(commands)) @@ -67,7 +72,7 @@ static void inner(const VcpkgCmdArguments& args) } else { - const Optional vcpkg_root_dir_env = System::get_environment_variable(L"VCPKG_ROOT"); + const auto vcpkg_root_dir_env = System::get_environment_variable("VCPKG_ROOT"); if (const auto v = vcpkg_root_dir_env.get()) { vcpkg_root_dir = fs::stdfs::absolute(*v); @@ -95,7 +100,11 @@ static void inner(const VcpkgCmdArguments& args) expected_paths.error().message()); const VcpkgPaths paths = expected_paths.value_or_exit(VCPKG_LINE_INFO); +#if defined(_WIN32) const int exit_code = _wchdir(paths.root.c_str()); +#else + const int exit_code = chdir(paths.root.c_str()); +#endif Checks::check_exit(VCPKG_LINE_INFO, exit_code == 0, "Changing the working dir failed"); Commands::Version::warn_if_vcpkg_version_mismatch(paths); @@ -111,11 +120,10 @@ static void inner(const VcpkgCmdArguments& args) } else { - const Optional vcpkg_default_triplet_env = - System::get_environment_variable(L"VCPKG_DEFAULT_TRIPLET"); + const auto vcpkg_default_triplet_env = System::get_environment_variable("VCPKG_DEFAULT_TRIPLET"); if (const auto v = vcpkg_default_triplet_env.get()) { - default_triplet = Triplet::from_canonical_name(Strings::to_utf8(*v)); + default_triplet = Triplet::from_canonical_name(*v); } else { @@ -135,6 +143,7 @@ static void inner(const VcpkgCmdArguments& args) static void load_config() { +#if defined(_WIN32) fs::path localappdata; { // Config path in AppDataLocal @@ -194,6 +203,7 @@ static void load_config() catch (...) { } +#endif } static std::string trim_path_from_command_line(const std::string& full_command_line) @@ -217,24 +227,32 @@ static std::string trim_path_from_command_line(const std::string& full_command_l return std::string(it, full_command_line.cend()); } +#if defined(_WIN32) int wmain(const int argc, const wchar_t* const* const argv) +#else +int main(const int argc, const char* const* const argv) +#endif { if (argc == 0) std::abort(); + *GlobalState::timer.lock() = Chrono::ElapsedTime::create_started(); + +#if defined(_WIN32) GlobalState::g_init_console_cp = GetConsoleCP(); GlobalState::g_init_console_output_cp = GetConsoleOutputCP(); SetConsoleCP(65001); SetConsoleOutputCP(65001); - *GlobalState::timer.lock() = Chrono::ElapsedTime::create_started(); - const std::string trimmed_command_line = trim_path_from_command_line(Strings::to_utf8(GetCommandLineW())); +#endif { auto locked_metrics = Metrics::g_metrics.lock(); locked_metrics->track_property("version", Commands::Version::version()); +#if defined(_WIN32) locked_metrics->track_property("cmdline", trimmed_command_line); +#endif } load_config(); Metrics::g_metrics.lock()->track_property("sqmuser", Metrics::get_SQM_user()); @@ -283,6 +301,12 @@ int wmain(const int argc, const wchar_t* const* const argv) exc_msg); fflush(stdout); for (int x = 0; x < argc; ++x) + { +#if defined(_WIN32) System::println("%s|", Strings::to_utf8(argv[x])); +#else + System::println("%s|", argv[x]); +#endif + } fflush(stdout); } diff --git a/toolsrc/src/vcpkg/base/checks.cpp b/toolsrc/src/vcpkg/base/checks.cpp index 73c7b9b1a..ed28d6e2b 100644 --- a/toolsrc/src/vcpkg/base/checks.cpp +++ b/toolsrc/src/vcpkg/base/checks.cpp @@ -17,14 +17,21 @@ namespace vcpkg::Checks GlobalState::debugging = false; metrics->flush(); +#if defined(_WIN32) SetConsoleCP(GlobalState::g_init_console_cp); SetConsoleOutputCP(GlobalState::g_init_console_output_cp); +#endif fflush(nullptr); +#if defined(_WIN32) ::TerminateProcess(::GetCurrentProcess(), exit_code); +#else + ::exit(exit_code); +#endif } +#if defined(_WIN32) static BOOL ctrl_handler(DWORD fdw_ctrl_type) { { @@ -39,6 +46,9 @@ namespace vcpkg::Checks { SetConsoleCtrlHandler(reinterpret_cast(ctrl_handler), TRUE); } +#else + void register_console_ctrl_handler() {} +#endif [[noreturn]] void unreachable(const LineInfo& line_info) { @@ -67,7 +77,7 @@ namespace vcpkg::Checks { if (!expression) { - exit_with_message(line_info, Strings::EMPTY); + exit_with_message(line_info, ""); } } diff --git a/toolsrc/src/vcpkg/base/cofffilereader.cpp b/toolsrc/src/vcpkg/base/cofffilereader.cpp index 5e9c86998..1927e0b5e 100644 --- a/toolsrc/src/vcpkg/base/cofffilereader.cpp +++ b/toolsrc/src/vcpkg/base/cofffilereader.cpp @@ -7,6 +7,7 @@ using namespace std; namespace vcpkg::CoffFileReader { +#if defined(_WIN32) template static T reinterpret_bytes(const char* data) { @@ -24,7 +25,7 @@ namespace vcpkg::CoffFileReader template static T peek_value_from_stream(fstream& fs) { - const fpos_t original_pos = fs.tellg().seekpos(); + const std::streampos original_pos = fs.tellg(); T data; fs.read(reinterpret_cast(&data), sizeof data); fs.seekg(original_pos); @@ -305,4 +306,8 @@ namespace vcpkg::CoffFileReader return {std::vector(machine_types.cbegin(), machine_types.cend())}; } +#else + DllInfo read_dll(const fs::path& path) { exit(-1); } + LibInfo read_lib(const fs::path& path) { exit(-1); } +#endif } diff --git a/toolsrc/src/vcpkg/base/files.cpp b/toolsrc/src/vcpkg/base/files.cpp index f8b239eaa..6e43debb1 100644 --- a/toolsrc/src/vcpkg/base/files.cpp +++ b/toolsrc/src/vcpkg/base/files.cpp @@ -163,7 +163,12 @@ namespace vcpkg::Files virtual void write_contents(const fs::path& file_path, const std::string& data) override { FILE* f = nullptr; +#if defined(_WIN32) auto ec = _wfopen_s(&f, file_path.native().c_str(), L"wb"); +#else + f = fopen(file_path.native().c_str(), "wb"); + int ec = f != nullptr ? 0 : 1; +#endif Checks::check_exit( VCPKG_LINE_INFO, ec == 0, "Error: Could not open file for writing: %s", file_path.u8string().c_str()); auto count = fwrite(data.data(), sizeof(data[0]), data.size(), f); @@ -194,9 +199,13 @@ namespace vcpkg::Files System::println(); } - std::vector find_from_PATH(const std::wstring& name) + std::vector find_from_PATH(const std::string& name) { - const std::wstring cmd = Strings::wformat(L"where.exe %s", name); +#if defined(_WIN32) + const std::string cmd = Strings::format("where.exe %s", name); +#else + const std::string cmd = Strings::format("which %s", name); +#endif auto out = System::cmd_execute_and_capture_output(cmd); if (out.exit_code != 0) { diff --git a/toolsrc/src/vcpkg/base/strings.cpp b/toolsrc/src/vcpkg/base/strings.cpp index 2a6d3dff2..fa04279b9 100644 --- a/toolsrc/src/vcpkg/base/strings.cpp +++ b/toolsrc/src/vcpkg/base/strings.cpp @@ -37,7 +37,8 @@ namespace vcpkg::Strings::details #if defined(_WIN32) _vsnprintf_s_l(&output.at(0), output.size() + 1, output.size(), fmtstr, c_locale(), args); #else - vsnprintf(&output.at(0), output.size() + 1, fmtstr, args); + va_start(args, fmtstr); + auto res = vsnprintf(&output.at(0), output.size() + 1, fmtstr, args); #endif va_end(args); @@ -73,20 +74,28 @@ namespace vcpkg::Strings { std::wstring to_utf16(const CStringView s) { +#if defined(_WIN32) const int size = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, nullptr, 0); std::wstring output; output.resize(size - 1); MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, output.data(), size - 1); return output; +#else + Checks::unreachable(VCPKG_LINE_INFO); +#endif } std::string to_utf8(const CWStringView w) { +#if defined(_WIN32) const int size = WideCharToMultiByte(CP_UTF8, 0, w.c_str(), -1, nullptr, 0, nullptr, nullptr); std::string output; output.resize(size - 1); WideCharToMultiByte(CP_UTF8, 0, w.c_str(), -1, output.data(), size - 1, nullptr, nullptr); return output; +#else + Checks::unreachable(VCPKG_LINE_INFO); +#endif } std::string::const_iterator case_insensitive_ascii_find(const std::string& s, const std::string& pattern) @@ -104,9 +113,13 @@ namespace vcpkg::Strings return case_insensitive_ascii_find(s, pattern) != s.end(); } - bool case_insensitive_ascii_compare(const CStringView left, const CStringView right) + bool case_insensitive_ascii_equals(const CStringView left, const CStringView right) { +#if defined(_WIN32) return _stricmp(left.c_str(), right.c_str()) == 0; +#else + return strcasecmp(left.c_str(), right.c_str()) == 0; +#endif } std::string ascii_to_lowercase(const std::string& input) @@ -118,7 +131,11 @@ namespace vcpkg::Strings bool case_insensitive_ascii_starts_with(const std::string& s, const std::string& pattern) { +#if defined(_WIN32) return _strnicmp(s.c_str(), pattern.c_str(), pattern.size()) == 0; +#else + return strncasecmp(s.c_str(), pattern.c_str(), pattern.size()) == 0; +#endif } void trim(std::string* s) diff --git a/toolsrc/src/vcpkg/base/system.cpp b/toolsrc/src/vcpkg/base/system.cpp index d5d39461c..e92d06f6e 100644 --- a/toolsrc/src/vcpkg/base/system.cpp +++ b/toolsrc/src/vcpkg/base/system.cpp @@ -4,6 +4,8 @@ #include #include +#include + #pragma comment(lib, "Advapi32") namespace vcpkg::System @@ -13,35 +15,46 @@ namespace vcpkg::System using std::chrono::system_clock; std::time_t now_time = system_clock::to_time_t(system_clock::now()); tm parts; +#if defined(_WIN32) localtime_s(&parts, &now_time); +#else + parts = *localtime(&now_time); +#endif return parts; } fs::path get_exe_path_of_current_process() { +#if defined(_WIN32) wchar_t buf[_MAX_PATH]; const int bytes = GetModuleFileNameW(nullptr, buf, _MAX_PATH); if (bytes == 0) std::abort(); return fs::path(buf, buf + bytes); +#else + std::array buf; + auto written = readlink("/proc/self/exe", buf.data(), buf.size()); + Checks::check_exit(VCPKG_LINE_INFO, written != -1, "Could not determine current executable path."); + return fs::path(buf.data(), buf.data() + written); +#endif } Optional to_cpu_architecture(CStringView arch) { - if (Strings::case_insensitive_ascii_compare(arch, "x86")) return CPUArchitecture::X86; - if (Strings::case_insensitive_ascii_compare(arch, "x64")) return CPUArchitecture::X64; - if (Strings::case_insensitive_ascii_compare(arch, "amd64")) return CPUArchitecture::X64; - if (Strings::case_insensitive_ascii_compare(arch, "arm")) return CPUArchitecture::ARM; - if (Strings::case_insensitive_ascii_compare(arch, "arm64")) return CPUArchitecture::ARM64; + if (Strings::case_insensitive_ascii_equals(arch, "x86")) return CPUArchitecture::X86; + if (Strings::case_insensitive_ascii_equals(arch, "x64")) return CPUArchitecture::X64; + if (Strings::case_insensitive_ascii_equals(arch, "amd64")) return CPUArchitecture::X64; + if (Strings::case_insensitive_ascii_equals(arch, "arm")) return CPUArchitecture::ARM; + if (Strings::case_insensitive_ascii_equals(arch, "arm64")) return CPUArchitecture::ARM64; return nullopt; } CPUArchitecture get_host_processor() { - auto w6432 = get_environment_variable(L"PROCESSOR_ARCHITEW6432"); - if (const auto p = w6432.get()) return to_cpu_architecture(Strings::to_utf8(*p)).value_or_exit(VCPKG_LINE_INFO); + auto w6432 = get_environment_variable("PROCESSOR_ARCHITEW6432"); + if (const auto p = w6432.get()) return to_cpu_architecture(*p).value_or_exit(VCPKG_LINE_INFO); - const auto procarch = get_environment_variable(L"PROCESSOR_ARCHITECTURE").value_or_exit(VCPKG_LINE_INFO); - return to_cpu_architecture(Strings::to_utf8(procarch)).value_or_exit(VCPKG_LINE_INFO); + const auto procarch = get_environment_variable("PROCESSOR_ARCHITECTURE").value_or_exit(VCPKG_LINE_INFO); + return to_cpu_architecture(procarch).value_or_exit(VCPKG_LINE_INFO); } std::vector get_supported_host_architectures() @@ -58,12 +71,13 @@ namespace vcpkg::System return supported_architectures; } - int cmd_execute_clean(const CWStringView cmd_line) + int cmd_execute_clean(const CStringView cmd_line) { - static const std::wstring SYSTEM_ROOT = get_environment_variable(L"SystemRoot").value_or_exit(VCPKG_LINE_INFO); - static const std::wstring SYSTEM_32 = SYSTEM_ROOT + LR"(\system32)"; - static const std::wstring NEW_PATH = Strings::wformat( - LR"(Path=%s;%s;%s\Wbem;%s\WindowsPowerShell\v1.0\)", SYSTEM_32, SYSTEM_ROOT, SYSTEM_32, SYSTEM_32); +#if defined(_WIN32) + static const std::string SYSTEM_ROOT = get_environment_variable("SystemRoot").value_or_exit(VCPKG_LINE_INFO); + static const std::string SYSTEM_32 = SYSTEM_ROOT + R"(\system32)"; + static const std::string NEW_PATH = Strings::format( + R"(Path=%s;%s;%s\Wbem;%s\WindowsPowerShell\v1.0\)", SYSTEM_32, SYSTEM_ROOT, SYSTEM_32, SYSTEM_32); std::vector env_wstrings = { L"ALLUSERSPROFILE", @@ -118,17 +132,17 @@ namespace vcpkg::System for (auto&& env_wstring : env_wstrings) { - const Optional value = System::get_environment_variable(env_wstring); + const Optional value = System::get_environment_variable(Strings::to_utf8(env_wstring)); const auto v = value.get(); if (!v || v->empty()) continue; env_cstr.append(env_wstring); env_cstr.push_back(L'='); - env_cstr.append(*v); + env_cstr.append(Strings::to_utf16(*v)); env_cstr.push_back(L'\0'); } - env_cstr.append(NEW_PATH); + env_cstr.append(Strings::to_utf16(NEW_PATH)); env_cstr.push_back(L'\0'); STARTUPINFOW startup_info; @@ -139,10 +153,10 @@ namespace vcpkg::System memset(&process_info, 0, sizeof(PROCESS_INFORMATION)); // Basically we are wrapping it in quotes - std::wstring actual_cmd_line = Strings::wformat(LR"###(cmd.exe /c "%s")###", cmd_line); - Debug::println("CreateProcessW(%s)", Strings::to_utf8(actual_cmd_line)); + std::string actual_cmd_line = Strings::format(R"###(cmd.exe /c "%s")###", cmd_line); + Debug::println("CreateProcessW(%s)", actual_cmd_line); bool succeeded = TRUE == CreateProcessW(nullptr, - actual_cmd_line.data(), + Strings::to_utf16(actual_cmd_line).data(), nullptr, nullptr, FALSE, @@ -164,18 +178,28 @@ namespace vcpkg::System Debug::println("CreateProcessW() returned %lu", exit_code); return static_cast(exit_code); +#else + fflush(nullptr); + return system(cmd_line.c_str()); +#endif } - int cmd_execute(const CWStringView cmd_line) + int cmd_execute(const CStringView cmd_line) { // Flush stdout before launching external process fflush(nullptr); // Basically we are wrapping it in quotes - const std::wstring& actual_cmd_line = Strings::wformat(LR"###("%s")###", cmd_line); - Debug::println("_wsystem(%s)", Strings::to_utf8(actual_cmd_line)); - const int exit_code = _wsystem(actual_cmd_line.c_str()); + const std::string& actual_cmd_line = Strings::format(R"###("%s")###", cmd_line); +#if defined(_WIN32) + Debug::println("_wsystem(%s)", actual_cmd_line); + const int exit_code = _wsystem(Strings::to_utf16(actual_cmd_line).c_str()); Debug::println("_wsystem() returned %d", exit_code); +#else + Debug::println("_system(%s)", actual_cmd_line); + const int exit_code = system(actual_cmd_line.c_str()); + Debug::println("_system() returned %d", exit_code); +#endif return exit_code; } @@ -190,17 +214,18 @@ namespace vcpkg::System } } - ExitCodeAndOutput cmd_execute_and_capture_output(const CWStringView cmd_line) + ExitCodeAndOutput cmd_execute_and_capture_output(const CStringView cmd_line) { // Flush stdout before launching external process fflush(stdout); - const std::wstring& actual_cmd_line = Strings::wformat(LR"###("%s 2>&1")###", cmd_line); +#if defined(_WIN32) + const auto actual_cmd_line = Strings::format(R"###("%s 2>&1")###", cmd_line); - Debug::println("_wpopen(%s)", Strings::to_utf8(actual_cmd_line)); + Debug::println("_wpopen(%s)", actual_cmd_line); std::wstring output; wchar_t buf[1024]; - const auto pipe = _wpopen(actual_cmd_line.c_str(), L"r"); + const auto pipe = _wpopen(Strings::to_utf16(actual_cmd_line).c_str(), L"r"); if (pipe == nullptr) { return {1, Strings::to_utf8(output)}; @@ -218,27 +243,52 @@ namespace vcpkg::System Debug::println("_pclose() returned %d", ec); remove_byte_order_marks(&output); return {ec, Strings::to_utf8(output)}; +#else + const auto actual_cmd_line = Strings::format(R"###(%s 2>&1)###", cmd_line); + + Debug::println("popen(%s)", actual_cmd_line); + std::string output; + char buf[1024]; + const auto pipe = popen(actual_cmd_line.c_str(), "r"); + if (pipe == nullptr) + { + return {1, output}; + } + while (fgets(buf, 1024, pipe)) + { + output.append(buf); + } + if (!feof(pipe)) + { + return {1, output}; + } + + const auto ec = pclose(pipe); + Debug::println("pclose() returned %d", ec); + return {ec, output}; +#endif } - std::wstring create_powershell_script_cmd(const fs::path& script_path, const CWStringView args) + std::string create_powershell_script_cmd(const fs::path& script_path, const CStringView args) { // TODO: switch out ExecutionPolicy Bypass with "Remove Mark Of The Web" code and restore RemoteSigned - return Strings::wformat( - LR"(powershell -NoProfile -ExecutionPolicy Bypass -Command "& {& '%s' %s}")", script_path.native(), args); + return Strings::format( + R"(powershell -NoProfile -ExecutionPolicy Bypass -Command "& {& '%s' %s}")", script_path.u8string(), args); } - void println() { println(Strings::EMPTY); } + void println() { putchar('\n'); } void print(const CStringView message) { fputs(message.c_str(), stdout); } void println(const CStringView message) { print(message); - putchar('\n'); + println(); } void print(const Color c, const CStringView message) { +#if defined(_WIN32) const HANDLE console_handle = GetStdHandle(STD_OUTPUT_HANDLE); CONSOLE_SCREEN_BUFFER_INFO console_screen_buffer_info{}; @@ -248,37 +298,50 @@ namespace vcpkg::System SetConsoleTextAttribute(console_handle, static_cast(c) | (original_color & 0xF0)); print(message); SetConsoleTextAttribute(console_handle, original_color); +#else + print(message); +#endif } void println(const Color c, const CStringView message) { print(c, message); - putchar('\n'); + println(); } - Optional get_environment_variable(const CWStringView varname) noexcept + Optional get_environment_variable(const CStringView varname) noexcept { - const auto sz = GetEnvironmentVariableW(varname.c_str(), nullptr, 0); +#if defined(_WIN32) + const auto w_varname = Strings::to_utf16(varname); + const auto sz = GetEnvironmentVariableW(w_varname.c_str(), nullptr, 0); if (sz == 0) return nullopt; std::wstring ret(sz, L'\0'); Checks::check_exit(VCPKG_LINE_INFO, MAXDWORD >= ret.size()); - const auto sz2 = GetEnvironmentVariableW(varname.c_str(), ret.data(), static_cast(ret.size())); + const auto sz2 = GetEnvironmentVariableW(w_varname.c_str(), ret.data(), static_cast(ret.size())); Checks::check_exit(VCPKG_LINE_INFO, sz2 + 1 == sz); ret.pop_back(); - return ret; + return Strings::to_utf8(ret); +#else + auto v = getenv(varname.c_str()); + if (!v) return nullopt; + return std::string(v); +#endif } +#if defined(_WIN32) static bool is_string_keytype(DWORD hkey_type) { return hkey_type == REG_SZ || hkey_type == REG_MULTI_SZ || hkey_type == REG_EXPAND_SZ; } - Optional get_registry_string(HKEY base, const CWStringView sub_key, const CWStringView valuename) + Optional get_registry_string(void* base_hkey, + const CWStringView sub_key, + const CWStringView valuename) { HKEY k = nullptr; - const LSTATUS ec = RegOpenKeyExW(base, sub_key.c_str(), NULL, KEY_READ, &k); + const LSTATUS ec = RegOpenKeyExW(reinterpret_cast(base_hkey), sub_key.c_str(), NULL, KEY_READ, &k); if (ec != ERROR_SUCCESS) return nullopt; DWORD dw_buffer_size = 0; @@ -298,17 +361,25 @@ namespace vcpkg::System ret.pop_back(); // remove extra trailing null byte return ret; } +#else + Optional get_registry_string(void* base_hkey, + const CWStringView sub_key, + const CWStringView valuename) + { + return nullopt; + } +#endif static const fs::path& get_program_files() { - static const fs::path PATH = System::get_environment_variable(L"PROGRAMFILES").value_or_exit(VCPKG_LINE_INFO); + static const fs::path PATH = System::get_environment_variable("PROGRAMFILES").value_or_exit(VCPKG_LINE_INFO); return PATH; } const fs::path& get_program_files_32_bit() { static const fs::path PATH = []() -> fs::path { - auto value = System::get_environment_variable(L"ProgramFiles(x86)"); + auto value = System::get_environment_variable("ProgramFiles(x86)"); if (auto v = value.get()) { return std::move(*v); @@ -321,7 +392,7 @@ namespace vcpkg::System const fs::path& get_program_files_platform_bitness() { static const fs::path PATH = []() -> fs::path { - auto value = System::get_environment_variable(L"ProgramW6432"); + auto value = System::get_environment_variable("ProgramW6432"); if (auto v = value.get()) { return std::move(*v); diff --git a/toolsrc/src/vcpkg/binaryparagraph.cpp b/toolsrc/src/vcpkg/binaryparagraph.cpp index ef943011f..3a493eb4c 100644 --- a/toolsrc/src/vcpkg/binaryparagraph.cpp +++ b/toolsrc/src/vcpkg/binaryparagraph.cpp @@ -80,10 +80,10 @@ namespace vcpkg BinaryParagraph::BinaryParagraph(const SourceParagraph& spgh, const FeatureParagraph& fpgh, const Triplet& triplet) { this->spec = PackageSpec::from_name_and_triplet(spgh.name, triplet).value_or_exit(VCPKG_LINE_INFO); - this->version = Strings::EMPTY; + this->version = ""; this->feature = fpgh.name; this->description = fpgh.description; - this->maintainer = Strings::EMPTY; + this->maintainer = ""; this->depends = filter_dependencies(fpgh.depends, triplet); } diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index 99ec541c1..3d3bcb5fe 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -155,16 +155,16 @@ namespace vcpkg::Build static const std::string LIBRARY_LINKAGE = "LibraryLinkage"; } - CWStringView to_vcvarsall_target(const std::string& cmake_system_name) + CStringView to_vcvarsall_target(const std::string& cmake_system_name) { - if (cmake_system_name == Strings::EMPTY) return Strings::WEMPTY; - if (cmake_system_name == "Windows") return Strings::WEMPTY; - if (cmake_system_name == "WindowsStore") return L"store"; + if (cmake_system_name.empty()) return ""; + if (cmake_system_name == "Windows") return ""; + if (cmake_system_name == "WindowsStore") return "store"; Checks::exit_with_message(VCPKG_LINE_INFO, "Unsupported vcvarsall target %s", cmake_system_name); } - CWStringView to_vcvarsall_toolchain(const std::string& target_architecture, const Toolset& toolset) + CStringView to_vcvarsall_toolchain(const std::string& target_architecture, const Toolset& toolset) { auto maybe_target_arch = System::to_cpu_architecture(target_architecture); Checks::check_exit( @@ -183,23 +183,23 @@ namespace vcpkg::Build Checks::exit_with_message(VCPKG_LINE_INFO, "Unsupported toolchain combination %s", target_architecture); } - std::wstring make_build_env_cmd(const PreBuildInfo& pre_build_info, const Toolset& toolset) + std::string make_build_env_cmd(const PreBuildInfo& pre_build_info, const Toolset& toolset) { - const wchar_t* tonull = L" >nul"; + const char* tonull = " >nul"; if (GlobalState::debugging) { - tonull = Strings::WEMPTY; + tonull = ""; } const auto arch = to_vcvarsall_toolchain(pre_build_info.target_architecture, toolset); const auto target = to_vcvarsall_target(pre_build_info.cmake_system_name); - return Strings::wformat(LR"("%s" %s %s %s %s 2>&1)", - toolset.vcvarsall.native(), - Strings::join(L" ", toolset.vcvarsall_options), - arch, - target, - tonull); + return Strings::format(R"("%s" %s %s %s %s 2>&1)", + toolset.vcvarsall.u8string(), + Strings::join(" ", toolset.vcvarsall_options), + arch, + target, + tonull); } static void create_binary_feature_control_file(const SourceParagraph& source_paragraph, @@ -265,8 +265,6 @@ namespace vcpkg::Build const fs::path ports_cmake_script_path = paths.ports_cmake; const auto pre_build_info = PreBuildInfo::from_triplet_file(paths, triplet); - const Toolset& toolset = paths.get_toolset(pre_build_info.platform_toolset, pre_build_info.visual_studio_path); - const auto cmd_set_environment = make_build_env_cmd(pre_build_info, toolset); std::string features; if (GlobalState::feature_packages) @@ -284,22 +282,26 @@ namespace vcpkg::Build } } - const std::wstring cmd_launch_cmake = make_cmake_cmd( + const Toolset& toolset = paths.get_toolset(pre_build_info.platform_toolset, pre_build_info.visual_studio_path); + + const std::string cmd_launch_cmake = make_cmake_cmd( cmake_exe_path, ports_cmake_script_path, { - {L"CMD", L"BUILD"}, - {L"PORT", config.src.name}, - {L"CURRENT_PORT_DIR", config.port_dir / "/."}, - {L"TARGET_TRIPLET", triplet.canonical_name()}, - {L"VCPKG_PLATFORM_TOOLSET", toolset.version.c_str()}, - {L"VCPKG_USE_HEAD_VERSION", to_bool(config.build_package_options.use_head_version) ? L"1" : L"0"}, - {L"_VCPKG_NO_DOWNLOADS", !to_bool(config.build_package_options.allow_downloads) ? L"1" : L"0"}, - {L"GIT", git_exe_path}, - {L"FEATURES", features}, + {"CMD", "BUILD"}, + {"PORT", config.src.name}, + {"CURRENT_PORT_DIR", config.port_dir / "/."}, + {"TARGET_TRIPLET", triplet.canonical_name()}, + {"VCPKG_PLATFORM_TOOLSET", toolset.version.c_str()}, + {"VCPKG_USE_HEAD_VERSION", to_bool(config.build_package_options.use_head_version) ? "1" : "0"}, + {"_VCPKG_NO_DOWNLOADS", !to_bool(config.build_package_options.allow_downloads) ? "1" : "0"}, + {"GIT", git_exe_path}, + {"FEATURES", features}, }); - const std::wstring command = Strings::wformat(LR"(%s && %s)", cmd_set_environment, cmd_launch_cmake); + std::string command; + const auto cmd_set_environment = make_build_env_cmd(pre_build_info, toolset); + command = Strings::format(R"(%s && %s)", cmd_set_environment, cmd_launch_cmake); const auto timer = Chrono::ElapsedTime::create_started(); @@ -461,14 +463,12 @@ namespace vcpkg::Build const fs::path ports_cmake_script_path = paths.scripts / "get_triplet_environment.cmake"; const fs::path triplet_file_path = paths.triplets / (triplet.canonical_name() + ".cmake"); - const std::wstring cmd_launch_cmake = make_cmake_cmd(cmake_exe_path, - ports_cmake_script_path, - { - {L"CMAKE_TRIPLET_FILE", triplet_file_path}, - }); - - const std::wstring command = Strings::wformat(LR"(%s)", cmd_launch_cmake); - const auto ec_data = System::cmd_execute_and_capture_output(command); + const auto cmd_launch_cmake = make_cmake_cmd(cmake_exe_path, + ports_cmake_script_path, + { + {"CMAKE_TRIPLET_FILE", triplet_file_path}, + }); + const auto ec_data = System::cmd_execute_and_capture_output(cmd_launch_cmake); Checks::check_exit(VCPKG_LINE_INFO, ec_data.exit_code == 0); const std::vector lines = Strings::split(ec_data.output, "\n"); @@ -491,7 +491,7 @@ namespace vcpkg::Build const bool variable_with_no_value = s.size() == 1; const std::string variable_name = s.at(0); - const std::string variable_value = variable_with_no_value ? Strings::EMPTY : s.at(1); + const std::string variable_value = variable_with_no_value ? "" : s.at(1); if (variable_name == "VCPKG_TARGET_ARCHITECTURE") { diff --git a/toolsrc/src/vcpkg/commands.create.cpp b/toolsrc/src/vcpkg/commands.create.cpp index d923cf555..85763f25e 100644 --- a/toolsrc/src/vcpkg/commands.create.cpp +++ b/toolsrc/src/vcpkg/commands.create.cpp @@ -20,7 +20,7 @@ namespace vcpkg::Commands::Create const fs::path& cmake_exe = paths.get_cmake_exe(); - std::vector cmake_args{{L"CMD", L"CREATE"}, {L"PORT", port_name}, {L"URL", url}}; + std::vector cmake_args{{"CMD", "CREATE"}, {"PORT", port_name}, {"URL", url}}; if (args.command_arguments.size() >= 3) { @@ -30,10 +30,10 @@ namespace vcpkg::Commands::Create R"(Filename cannot contain invalid chars %s, but was %s)", Files::FILESYSTEM_INVALID_CHARACTERS, zip_file_name); - cmake_args.push_back({L"FILENAME", zip_file_name}); + cmake_args.push_back({"FILENAME", zip_file_name}); } - const std::wstring cmd_launch_cmake = make_cmake_cmd(cmake_exe, paths.ports_cmake, cmake_args); + const std::string cmd_launch_cmake = make_cmake_cmd(cmake_exe, paths.ports_cmake, cmake_args); Checks::exit_with_code(VCPKG_LINE_INFO, System::cmd_execute_clean(cmd_launch_cmake)); } } diff --git a/toolsrc/src/vcpkg/commands.edit.cpp b/toolsrc/src/vcpkg/commands.edit.cpp index a90ae1bc3..fe6f76bd2 100644 --- a/toolsrc/src/vcpkg/commands.edit.cpp +++ b/toolsrc/src/vcpkg/commands.edit.cpp @@ -17,6 +17,7 @@ namespace vcpkg::Commands::Edit }; std::vector output; +#if defined(_WIN32) for (auto&& keypath : REGKEYS) { const Optional code_installpath = @@ -28,6 +29,7 @@ namespace vcpkg::Commands::Edit output.push_back(install_path / "Code.exe"); } } +#endif return output; } @@ -72,7 +74,7 @@ namespace vcpkg::Commands::Edit Checks::check_exit(VCPKG_LINE_INFO, fs.is_directory(portpath), R"(Could not find port named "%s")", port_name); std::vector candidate_paths; - const std::vector from_path = Files::find_from_PATH(L"EDITOR"); + const std::vector from_path = Files::find_from_PATH("EDITOR"); candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); candidate_paths.push_back(System::get_program_files_platform_bitness() / VS_CODE_INSIDERS); candidate_paths.push_back(System::get_program_files_32_bit() / VS_CODE_INSIDERS); @@ -98,13 +100,16 @@ namespace vcpkg::Commands::Edit { const auto buildtrees_current_dir = paths.buildtrees / port_name; - const std::wstring cmd_line = - Strings::wformat(LR"("%s" "%s" -n)", env_editor, buildtrees_current_dir.native()); + const auto cmd_line = + Strings::format(R"("%s" "%s" -n)", env_editor.u8string(), buildtrees_current_dir.u8string()); Checks::exit_with_code(VCPKG_LINE_INFO, System::cmd_execute(cmd_line)); } - const std::wstring cmd_line = Strings::wformat( - LR"("%s" "%s" "%s" -n)", env_editor, portpath.native(), (portpath / "portfile.cmake").native()); + const auto cmd_line = Strings::format( + R"("%s" "%s" "%s" -n)", + env_editor.u8string(), + portpath.u8string(), + (portpath / "portfile.cmake").u8string()); Checks::exit_with_code(VCPKG_LINE_INFO, System::cmd_execute(cmd_line)); } } diff --git a/toolsrc/src/vcpkg/commands.env.cpp b/toolsrc/src/vcpkg/commands.env.cpp index 089881588..9f8ae5207 100644 --- a/toolsrc/src/vcpkg/commands.env.cpp +++ b/toolsrc/src/vcpkg/commands.env.cpp @@ -15,7 +15,7 @@ namespace vcpkg::Commands::Env const auto pre_build_info = Build::PreBuildInfo::from_triplet_file(paths, default_triplet); const Toolset& toolset = paths.get_toolset(pre_build_info.platform_toolset, pre_build_info.visual_studio_path); - System::cmd_execute_clean(Build::make_build_env_cmd(pre_build_info, toolset) + L" && cmd"); + System::cmd_execute_clean(Build::make_build_env_cmd(pre_build_info, toolset) + " && cmd"); Checks::exit_success(VCPKG_LINE_INFO); } diff --git a/toolsrc/src/vcpkg/commands.exportifw.cpp b/toolsrc/src/vcpkg/commands.exportifw.cpp index fbf3beb8c..682267acb 100644 --- a/toolsrc/src/vcpkg/commands.exportifw.cpp +++ b/toolsrc/src/vcpkg/commands.exportifw.cpp @@ -29,7 +29,7 @@ namespace vcpkg::Export::IFW std::string safe_rich_from_plain_text(const std::string& text) { - // match standalone ampersand, no HTML number or name + // match standalone ampersand, no HTML number or name std::regex standalone_ampersand(R"###(&(?!(#[0-9]+|\w+);))###"); return std::regex_replace(text, standalone_ampersand, "&"); @@ -350,10 +350,10 @@ namespace vcpkg::Export::IFW Checks::check_exit( VCPKG_LINE_INFO, !ec, "Could not remove outdated repository directory %s", repository_dir.generic_string()); - const std::wstring cmd_line = Strings::wformat(LR"("%s" --packages "%s" "%s" > nul)", - repogen_exe.native(), - packages_dir.native(), - repository_dir.native()); + const auto cmd_line = Strings::format(R"("%s" --packages "%s" "%s" > nul)", + repogen_exe.u8string(), + packages_dir.u8string(), + repository_dir.u8string()); const int exit_code = System::cmd_execute_clean(cmd_line); Checks::check_exit(VCPKG_LINE_INFO, exit_code == 0, "Error: IFW repository generating failed"); @@ -371,24 +371,24 @@ namespace vcpkg::Export::IFW System::println("Generating installer %s...", installer_file.generic_string()); - std::wstring cmd_line; + std::string cmd_line; std::string ifw_repo_url = ifw_options.maybe_repository_url.value_or(""); if (!ifw_repo_url.empty()) { - cmd_line = Strings::wformat(LR"("%s" --online-only --config "%s" --repository "%s" "%s" > nul)", - binarycreator_exe.native(), - config_file.native(), - repository_dir.native(), - installer_file.native()); + cmd_line = Strings::format(R"("%s" --online-only --config "%s" --repository "%s" "%s" > nul)", + binarycreator_exe.u8string(), + config_file.u8string(), + repository_dir.u8string(), + installer_file.u8string()); } else { - cmd_line = Strings::wformat(LR"("%s" --config "%s" --packages "%s" "%s" > nul)", - binarycreator_exe.native(), - config_file.native(), - packages_dir.native(), - installer_file.native()); + cmd_line = Strings::format(R"("%s" --config "%s" --packages "%s" "%s" > nul)", + binarycreator_exe.u8string(), + config_file.u8string(), + packages_dir.u8string(), + installer_file.u8string()); } const int exit_code = System::cmd_execute_clean(cmd_line); diff --git a/toolsrc/src/vcpkg/commands.hash.cpp b/toolsrc/src/vcpkg/commands.hash.cpp index 394a02e23..4bc58b509 100644 --- a/toolsrc/src/vcpkg/commands.hash.cpp +++ b/toolsrc/src/vcpkg/commands.hash.cpp @@ -7,26 +7,21 @@ namespace vcpkg::Commands::Hash { - static void do_file_hash(fs::path const& path, std::wstring const& hash_type) + static void do_file_hash(fs::path const& path, std::string const& hash_type) { - const auto cmd_line = Strings::wformat(LR"(CertUtil.exe -hashfile "%s" %s)", path.c_str(), hash_type); + const auto cmd_line = Strings::format(R"(CertUtil.exe -hashfile "%s" %s)", path.u8string().c_str(), hash_type); const auto ec_data = System::cmd_execute_and_capture_output(cmd_line); - Checks::check_exit( - VCPKG_LINE_INFO, ec_data.exit_code == 0, "Running command:\n %s\n failed", Strings::to_utf8(cmd_line)); + Checks::check_exit(VCPKG_LINE_INFO, ec_data.exit_code == 0, "Running command:\n %s\n failed", cmd_line); std::string const& output = ec_data.output; const auto start = output.find_first_of("\r\n"); - Checks::check_exit(VCPKG_LINE_INFO, - start != std::string::npos, - "Unexpected output format from command: %s", - Strings::to_utf8(cmd_line)); + Checks::check_exit( + VCPKG_LINE_INFO, start != std::string::npos, "Unexpected output format from command: %s", cmd_line); const auto end = output.find_first_of("\r\n", start + 1); - Checks::check_exit(VCPKG_LINE_INFO, - end != std::string::npos, - "Unexpected output format from command: %s", - Strings::to_utf8(cmd_line)); + Checks::check_exit( + VCPKG_LINE_INFO, end != std::string::npos, "Unexpected output format from command: %s", cmd_line); auto hash = output.substr(start, end - start); Util::erase_remove_if(hash, isspace); @@ -43,11 +38,11 @@ namespace vcpkg::Commands::Hash if (args.command_arguments.size() == 1) { - do_file_hash(args.command_arguments[0], L"SHA512"); + do_file_hash(args.command_arguments[0], "SHA512"); } if (args.command_arguments.size() == 2) { - do_file_hash(args.command_arguments[0], Strings::to_utf16(args.command_arguments[1])); + do_file_hash(args.command_arguments[0], args.command_arguments[1]); } Checks::exit_success(VCPKG_LINE_INFO); diff --git a/toolsrc/src/vcpkg/commands.integrate.cpp b/toolsrc/src/vcpkg/commands.integrate.cpp index 85b567adb..0d185476e 100644 --- a/toolsrc/src/vcpkg/commands.integrate.cpp +++ b/toolsrc/src/vcpkg/commands.integrate.cpp @@ -8,12 +8,6 @@ namespace vcpkg::Commands::Integrate { - static const std::array OLD_SYSTEM_TARGET_FILES = { - System::get_program_files_32_bit() / "MSBuild/14.0/Microsoft.Common.Targets/ImportBefore/vcpkg.nuget.targets", - System::get_program_files_32_bit() / "MSBuild/14.0/Microsoft.Common.Targets/ImportBefore/vcpkg.system.targets"}; - static const fs::path SYSTEM_WIDE_TARGETS_FILE = - System::get_program_files_32_bit() / "MSBuild/Microsoft.Cpp/v4.0/V140/ImportBefore/Default/vcpkg.system.props"; - static std::string create_appdata_targets_shortcut(const std::string& target_path) noexcept { return Strings::format(R"###( @@ -111,6 +105,7 @@ namespace vcpkg::Commands::Integrate NO }; +#if defined(_WIN32) static ElevationPromptChoice elevated_cmd_execute(const std::string& param) { SHELLEXECUTEINFOW sh_ex_info = {0}; @@ -138,16 +133,29 @@ namespace vcpkg::Commands::Integrate CloseHandle(sh_ex_info.hProcess); return ElevationPromptChoice::YES; } +#endif +#if defined(_WIN32) static fs::path get_appdata_targets_path() { static const fs::path LOCAL_APP_DATA = - fs::path(System::get_environment_variable(L"LOCALAPPDATA").value_or_exit(VCPKG_LINE_INFO)); + fs::path(System::get_environment_variable("LOCALAPPDATA").value_or_exit(VCPKG_LINE_INFO)); return LOCAL_APP_DATA / "vcpkg" / "vcpkg.user.targets"; } +#endif +#if defined(_WIN32) static void integrate_install(const VcpkgPaths& paths) { + static const std::array OLD_SYSTEM_TARGET_FILES = { + System::get_program_files_32_bit() / + "MSBuild/14.0/Microsoft.Common.Targets/ImportBefore/vcpkg.nuget.targets", + System::get_program_files_32_bit() / + "MSBuild/14.0/Microsoft.Common.Targets/ImportBefore/vcpkg.system.targets"}; + static const fs::path SYSTEM_WIDE_TARGETS_FILE = + System::get_program_files_32_bit() / + "MSBuild/Microsoft.Cpp/v4.0/V140/ImportBefore/Default/vcpkg.system.props"; + auto& fs = paths.get_filesystem(); // TODO: This block of code should eventually be removed @@ -262,6 +270,7 @@ CMake projects should use: "-DCMAKE_TOOLCHAIN_FILE=%s")", Checks::exit_success(VCPKG_LINE_INFO); } +#endif static void integrate_project(const VcpkgPaths& paths) { @@ -286,10 +295,10 @@ CMake projects should use: "-DCMAKE_TOOLCHAIN_FILE=%s")", fs.write_contents(nuspec_file_path, create_nuspec_file_contents(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()); + const std::string cmd_line = Strings::format(R"("%s" pack -OutputDirectory "%s" "%s" > nul)", + nuget_exe.u8string(), + buildsystems_dir.u8string(), + nuspec_file_path.u8string()); const int exit_code = System::cmd_execute_clean(cmd_line); @@ -325,6 +334,7 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console args.check_exact_arg_count(1, EXAMPLE); args.check_and_get_optional_command_arguments({}); +#if defined(_WIN32) if (args.command_arguments[0] == "install") { return integrate_install(paths); @@ -337,6 +347,7 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console { return integrate_project(paths); } +#endif Checks::exit_with_message(VCPKG_LINE_INFO, "Unknown parameter %s for integrate", args.command_arguments[0]); } diff --git a/toolsrc/src/vcpkg/commands.portsdiff.cpp b/toolsrc/src/vcpkg/commands.portsdiff.cpp index b70ad2b80..a8c043751 100644 --- a/toolsrc/src/vcpkg/commands.portsdiff.cpp +++ b/toolsrc/src/vcpkg/commands.portsdiff.cpp @@ -75,28 +75,28 @@ namespace vcpkg::Commands::PortsDiff } static std::map read_ports_from_commit(const VcpkgPaths& paths, - const std::wstring& git_commit_id) + const std::string& 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 std::string ports_dir_name_as_string = paths.ports.filename().u8string(); const fs::path temp_checkout_path = - paths.root / Strings::wformat(L"%s-%s", ports_dir_name_as_string, git_commit_id); + paths.root / Strings::format("%s-%s", ports_dir_name_as_string, git_commit_id); 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)", - git_exe.native(), - dot_git_dir.native(), - temp_checkout_path.native(), - git_commit_id, - checkout_this_dir, - L".vcpkg-root", - git_exe.native()); + const auto checkout_this_dir = + Strings::format(R"(.\%s)", ports_dir_name_as_string); // Must be relative to the root of the repository + + const std::string cmd = + Strings::format(R"("%s" --git-dir="%s" --work-tree="%s" checkout %s -f -q -- %s %s & "%s" reset >NUL)", + git_exe.u8string(), + dot_git_dir.u8string(), + temp_checkout_path.u8string(), + git_commit_id, + checkout_this_dir, + ".vcpkg-root", + git_exe.u8string()); System::cmd_execute_clean(cmd); const std::map names_and_versions = Paragraphs::load_all_port_names_and_versions( paths.get_filesystem(), temp_checkout_path / ports_dir_name_as_string); @@ -104,16 +104,14 @@ namespace vcpkg::Commands::PortsDiff return names_and_versions; } - static void check_commit_exists(const fs::path& git_exe, const std::wstring& git_commit_id) + static void check_commit_exists(const fs::path& git_exe, const std::string& git_commit_id) { static const std::string VALID_COMMIT_OUTPUT = "commit\n"; - const std::wstring cmd = Strings::wformat(LR"("%s" cat-file -t %s)", git_exe.native(), git_commit_id); + const auto cmd = Strings::format(R"("%s" cat-file -t %s)", git_exe.u8string(), git_commit_id); const System::ExitCodeAndOutput output = System::cmd_execute_and_capture_output(cmd); - Checks::check_exit(VCPKG_LINE_INFO, - output.output == VALID_COMMIT_OUTPUT, - "Invalid commit id %s", - Strings::to_utf8(git_commit_id)); + Checks::check_exit( + VCPKG_LINE_INFO, output.output == VALID_COMMIT_OUTPUT, "Invalid commit id %s", git_commit_id); } void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) @@ -126,9 +124,9 @@ namespace vcpkg::Commands::PortsDiff const fs::path& git_exe = paths.get_git_exe(); - const std::wstring git_commit_id_for_previous_snapshot = Strings::to_utf16(args.command_arguments.at(0)); - const std::wstring git_commit_id_for_current_snapshot = - args.command_arguments.size() < 2 ? L"HEAD" : Strings::to_utf16(args.command_arguments.at(1)); + const std::string git_commit_id_for_previous_snapshot = args.command_arguments.at(0); + const std::string git_commit_id_for_current_snapshot = + args.command_arguments.size() < 2 ? "HEAD" : args.command_arguments.at(1); check_commit_exists(git_exe, git_commit_id_for_current_snapshot); check_commit_exists(git_exe, git_commit_id_for_previous_snapshot); diff --git a/toolsrc/src/vcpkg/commands.version.cpp b/toolsrc/src/vcpkg/commands.version.cpp index c6cc82d1f..403c355b5 100644 --- a/toolsrc/src/vcpkg/commands.version.cpp +++ b/toolsrc/src/vcpkg/commands.version.cpp @@ -20,20 +20,29 @@ namespace vcpkg::Commands::Version #ifndef NDEBUG + std::string("-debug") #endif - + std::string(Metrics::get_compiled_metrics_enabled() ? Strings::EMPTY : "-external"); + + std::string(Metrics::get_compiled_metrics_enabled() ? "" : "-external"); return S_VERSION; } + static int scan3(const char* input, const char* pattern, int* a, int* b, int* c) + { +#if defined(_WIN32) + return sscanf_s(input, pattern, a, b, c); +#else + return sscanf(input, pattern, a, b, c); +#endif + } + void warn_if_vcpkg_version_mismatch(const VcpkgPaths& paths) { auto version_file = paths.get_filesystem().read_contents(paths.root / "toolsrc" / "VERSION.txt"); if (const auto version_contents = version_file.get()) { int maj1, min1, rev1; - const auto num1 = sscanf_s(version_contents->c_str(), "\"%d.%d.%d\"", &maj1, &min1, &rev1); + const auto num1 = scan3(version_contents->c_str(), "\"%d.%d.%d\"", &maj1, &min1, &rev1); int maj2, min2, rev2; - const auto num2 = sscanf_s(Version::version().c_str(), "%d.%d.%d-", &maj2, &min2, &rev2); + const auto num2 = scan3(Version::version().c_str(), "%d.%d.%d-", &maj2, &min2, &rev2); if (num1 == 3 && num2 == 3) { diff --git a/toolsrc/src/vcpkg/dependencies.cpp b/toolsrc/src/vcpkg/dependencies.cpp index da8f1e178..02b2ec785 100644 --- a/toolsrc/src/vcpkg/dependencies.cpp +++ b/toolsrc/src/vcpkg/dependencies.cpp @@ -43,14 +43,17 @@ namespace vcpkg::Dependencies bool operator==(const ClusterPtr& l, const ClusterPtr& r) { return l.ptr == r.ptr; } } -template<> -struct std::hash +namespace std { - size_t operator()(const vcpkg::Dependencies::ClusterPtr& value) const + template<> + struct hash { - return std::hash()(value.ptr->spec); - } -}; + size_t operator()(const vcpkg::Dependencies::ClusterPtr& value) const + { + return std::hash()(value.ptr->spec); + } + }; +} namespace vcpkg::Dependencies { diff --git a/toolsrc/src/vcpkg/export.cpp b/toolsrc/src/vcpkg/export.cpp index de6464c87..5e27d4126 100644 --- a/toolsrc/src/vcpkg/export.cpp +++ b/toolsrc/src/vcpkg/export.cpp @@ -137,11 +137,10 @@ namespace vcpkg::Export fs.write_contents(nuspec_file_path, nuspec_file_content); // -NoDefaultExcludes is needed for ".vcpkg-root" - const std::wstring cmd_line = - Strings::wformat(LR"("%s" pack -OutputDirectory "%s" "%s" -NoDefaultExcludes > nul)", - nuget_exe.native(), - output_dir.native(), - nuspec_file_path.native()); + const auto cmd_line = Strings::format(R"("%s" pack -OutputDirectory "%s" "%s" -NoDefaultExcludes > nul)", + nuget_exe.u8string(), + output_dir.u8string(), + nuspec_file_path.u8string()); const int exit_code = System::cmd_execute_clean(cmd_line); Checks::check_exit(VCPKG_LINE_INFO, exit_code == 0, "Error: NuGet package creation failed"); @@ -160,25 +159,25 @@ namespace vcpkg::Export constexpr ArchiveFormat() = delete; - constexpr ArchiveFormat(BackingEnum backing_enum, const wchar_t* extension, const wchar_t* cmake_option) + constexpr ArchiveFormat(BackingEnum backing_enum, const char* extension, const char* cmake_option) : backing_enum(backing_enum), m_extension(extension), m_cmake_option(cmake_option) { } constexpr operator BackingEnum() const { return backing_enum; } - constexpr CWStringView extension() const { return this->m_extension; } - constexpr CWStringView cmake_option() const { return this->m_cmake_option; } + constexpr CStringView extension() const { return this->m_extension; } + constexpr CStringView cmake_option() const { return this->m_cmake_option; } private: BackingEnum backing_enum; - const wchar_t* m_extension; - const wchar_t* m_cmake_option; + const char* m_extension; + const char* m_cmake_option; }; namespace ArchiveFormatC { - constexpr const ArchiveFormat ZIP(ArchiveFormat::BackingEnum::ZIP, L"zip", L"zip"); - constexpr const ArchiveFormat SEVEN_ZIP(ArchiveFormat::BackingEnum::SEVEN_ZIP, L"7z", L"7zip"); + constexpr const ArchiveFormat ZIP(ArchiveFormat::BackingEnum::ZIP, "zip", "zip"); + constexpr const ArchiveFormat SEVEN_ZIP(ArchiveFormat::BackingEnum::SEVEN_ZIP, "7z", "7zip"); } static fs::path do_archive_export(const VcpkgPaths& paths, @@ -188,17 +187,17 @@ namespace vcpkg::Export { const fs::path& cmake_exe = paths.get_cmake_exe(); - const std::wstring exported_dir_filename = raw_exported_dir.filename().native(); - const std::wstring exported_archive_filename = - Strings::wformat(L"%s.%s", exported_dir_filename, format.extension()); + const std::string exported_dir_filename = raw_exported_dir.filename().u8string(); + const std::string exported_archive_filename = + Strings::format("%s.%s", exported_dir_filename, format.extension()); const fs::path exported_archive_path = (output_dir / exported_archive_filename); // -NoDefaultExcludes is needed for ".vcpkg-root" - const std::wstring cmd_line = Strings::wformat(LR"("%s" -E tar "cf" "%s" --format=%s -- "%s")", - cmake_exe.native(), - exported_archive_path.native(), - format.cmake_option(), - raw_exported_dir.native()); + const auto cmd_line = Strings::format(R"("%s" -E tar "cf" "%s" --format=%s -- "%s")", + cmake_exe.u8string(), + exported_archive_path.u8string(), + format.cmake_option(), + raw_exported_dir.u8string()); const int exit_code = System::cmd_execute_clean(cmd_line); Checks::check_exit( @@ -361,13 +360,13 @@ namespace vcpkg::Export static void print_next_step_info(const fs::path& prefix) { const fs::path cmake_toolchain = prefix / "scripts" / "buildsystems" / "vcpkg.cmake"; - const CMakeVariable cmake_variable = CMakeVariable(L"CMAKE_TOOLCHAIN_FILE", cmake_toolchain.generic_string()); + const CMakeVariable cmake_variable = CMakeVariable("CMAKE_TOOLCHAIN_FILE", cmake_toolchain.generic_string()); System::println("\n" "To use the exported libraries in CMake projects use:" "\n" " %s" "\n", - Strings::to_utf8(cmake_variable.s)); + cmake_variable.s); }; static void handle_raw_based_export(Span export_plan, diff --git a/toolsrc/src/vcpkg/globalstate.cpp b/toolsrc/src/vcpkg/globalstate.cpp index de564d357..43230fa4b 100644 --- a/toolsrc/src/vcpkg/globalstate.cpp +++ b/toolsrc/src/vcpkg/globalstate.cpp @@ -5,9 +5,9 @@ namespace vcpkg { Util::LockGuarded GlobalState::timer; - std::atomic GlobalState::debugging = false; - std::atomic GlobalState::feature_packages = false; + std::atomic GlobalState::debugging(false); + std::atomic GlobalState::feature_packages(false); - std::atomic GlobalState::g_init_console_cp = 0; - std::atomic GlobalState::g_init_console_output_cp = 0; + std::atomic GlobalState::g_init_console_cp(0); + std::atomic GlobalState::g_init_console_output_cp(0); } diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp index 4a1e5537b..adbd8c943 100644 --- a/toolsrc/src/vcpkg/install.cpp +++ b/toolsrc/src/vcpkg/install.cpp @@ -70,9 +70,8 @@ namespace vcpkg::Install } const std::string filename = file.filename().generic_string(); - if (fs::is_regular_file(status) && - (Strings::case_insensitive_ascii_compare(filename.c_str(), "CONTROL") || - Strings::case_insensitive_ascii_compare(filename.c_str(), "BUILD_INFO"))) + if (fs::is_regular_file(status) && (Strings::case_insensitive_ascii_equals(filename.c_str(), "CONTROL") || + Strings::case_insensitive_ascii_equals(filename.c_str(), "BUILD_INFO"))) { // Do not copy the control file continue; diff --git a/toolsrc/src/vcpkg/metrics.cpp b/toolsrc/src/vcpkg/metrics.cpp index 84c1ee208..854baa0ca 100644 --- a/toolsrc/src/vcpkg/metrics.cpp +++ b/toolsrc/src/vcpkg/metrics.cpp @@ -19,6 +19,7 @@ namespace vcpkg::Metrics std::array date; date.fill(0); +#if defined(_WIN32) struct _timeb timebuffer; _ftime_s(&timebuffer); @@ -26,10 +27,17 @@ namespace vcpkg::Metrics const int milli = timebuffer.millitm; const errno_t err = gmtime_s(&newtime, &now); + if (err) { - return Strings::EMPTY; + return ""; } +#else + time_t now; + time(&now); + gmtime_r(&now, &newtime); + const int milli = 0; +#endif strftime(&date[0], date.size(), "%Y-%m-%dT%H:%M:%S", &newtime); return std::string(&date[0]) + "." + std::to_string(milli) + "Z"; @@ -121,6 +129,7 @@ namespace vcpkg::Metrics static std::string get_os_version_string() { +#if defined(_WIN32) std::wstring path; path.resize(MAX_PATH); const auto n = GetSystemDirectoryW(&path[0], static_cast(path.size())); @@ -128,16 +137,16 @@ namespace vcpkg::Metrics path += L"\\kernel32.dll"; const auto versz = GetFileVersionInfoSizeW(path.c_str(), nullptr); - if (versz == 0) return Strings::EMPTY; + if (versz == 0) return ""; std::vector verbuf; verbuf.resize(versz); - if (!GetFileVersionInfoW(path.c_str(), 0, static_cast(verbuf.size()), &verbuf[0])) return Strings::EMPTY; + if (!GetFileVersionInfoW(path.c_str(), 0, static_cast(verbuf.size()), &verbuf[0])) return ""; void* rootblock; UINT rootblocksize; - if (!VerQueryValueW(&verbuf[0], L"\\", &rootblock, &rootblocksize)) return Strings::EMPTY; + if (!VerQueryValueW(&verbuf[0], L"\\", &rootblock, &rootblocksize)) return ""; auto rootblock_ffi = static_cast(rootblock); @@ -145,6 +154,9 @@ namespace vcpkg::Metrics static_cast(HIWORD(rootblock_ffi->dwProductVersionMS)), static_cast(LOWORD(rootblock_ffi->dwProductVersionMS)), static_cast(HIWORD(rootblock_ffi->dwProductVersionLS))); +#else + return "unknown"; +#endif } struct MetricMessage @@ -223,9 +235,13 @@ namespace vcpkg::Metrics std::wstring get_SQM_user() { +#if defined(_WIN32) auto hkcu_sqmclient = System::get_registry_string(HKEY_CURRENT_USER, LR"(Software\Microsoft\SQMClient)", L"UserId"); return hkcu_sqmclient.value_or(L"{}"); +#else + return L"{}"; +#endif } void Metrics::set_user_information(const std::string& user_id, const std::string& first_use_time) @@ -264,6 +280,7 @@ namespace vcpkg::Metrics void Metrics::upload(const std::string& payload) { +#if defined(_WIN32) HINTERNET connect = nullptr, request = nullptr; BOOL results = FALSE; @@ -344,18 +361,12 @@ namespace vcpkg::Metrics if (request) WinHttpCloseHandle(request); if (connect) WinHttpCloseHandle(connect); if (session) WinHttpCloseHandle(session); - } - - static fs::path get_bindir() - { - wchar_t buf[_MAX_PATH]; - const int bytes = GetModuleFileNameW(nullptr, buf, _MAX_PATH); - if (bytes == 0) std::abort(); - return fs::path(buf, buf + bytes); +#endif } void Metrics::flush() { +#if defined(_WIN32) const std::string payload = g_metricmessage.format_event_data_template(); if (g_should_print_metrics) std::cerr << payload << "\n"; if (!g_should_send_metrics) return; @@ -373,14 +384,14 @@ namespace vcpkg::Metrics if (true) { const fs::path exe_path = [&fs]() -> fs::path { - auto vcpkgdir = get_bindir().parent_path(); + auto vcpkgdir = System::get_exe_path_of_current_process().parent_path(); auto path = vcpkgdir / "vcpkgmetricsuploader.exe"; if (fs.exists(path)) return path; path = vcpkgdir / "scripts" / "vcpkgmetricsuploader.exe"; if (fs.exists(path)) return path; - return Strings::WEMPTY; + return ""; }(); std::error_code ec; @@ -391,8 +402,9 @@ namespace vcpkg::Metrics const fs::path vcpkg_metrics_txt_path = temp_folder_path / ("vcpkg" + generate_random_UUID() + ".txt"); fs.write_contents(vcpkg_metrics_txt_path, payload); - const std::wstring cmd_line = - Strings::wformat(L"start %s %s", temp_folder_path_exe.native(), vcpkg_metrics_txt_path.native()); + const std::string cmd_line = + Strings::format("start %s %s", temp_folder_path_exe.u8string(), vcpkg_metrics_txt_path.u8string()); System::cmd_execute_clean(cmd_line); +#endif } } diff --git a/toolsrc/src/vcpkg/packagespec.cpp b/toolsrc/src/vcpkg/packagespec.cpp index 01a09618d..6e40d70f5 100644 --- a/toolsrc/src/vcpkg/packagespec.cpp +++ b/toolsrc/src/vcpkg/packagespec.cpp @@ -38,7 +38,7 @@ namespace vcpkg for (auto&& feature : spec->features) f_specs.push_back(FeatureSpec{pspec, feature}); - if (spec->features.empty()) f_specs.push_back(FeatureSpec{pspec, Strings::EMPTY}); + if (spec->features.empty()) f_specs.push_back(FeatureSpec{pspec, ""}); } else { @@ -56,7 +56,7 @@ namespace vcpkg std::vector ret; for (auto&& spec : specs) { - ret.emplace_back(spec.package_spec, Strings::EMPTY); + ret.emplace_back(spec.package_spec, ""); for (auto&& feature : spec.features) ret.emplace_back(spec.package_spec, feature); } diff --git a/toolsrc/src/vcpkg/parse.cpp b/toolsrc/src/vcpkg/parse.cpp index 116a7f5c8..c2670f561 100644 --- a/toolsrc/src/vcpkg/parse.cpp +++ b/toolsrc/src/vcpkg/parse.cpp @@ -31,7 +31,7 @@ namespace vcpkg::Parse } std::string ParagraphParser::optional_field(const std::string& fieldname) const { - return remove_field(&fields, fieldname).value_or(Strings::EMPTY); + return remove_field(&fields, fieldname).value_or(""); } std::unique_ptr ParagraphParser::error_info(const std::string& name) const { diff --git a/toolsrc/src/vcpkg/postbuildlint.cpp b/toolsrc/src/vcpkg/postbuildlint.cpp index 22cf67e86..0063f8d98 100644 --- a/toolsrc/src/vcpkg/postbuildlint.cpp +++ b/toolsrc/src/vcpkg/postbuildlint.cpp @@ -284,13 +284,10 @@ namespace vcpkg::PostBuildLint std::vector dlls_with_no_exports; for (const fs::path& dll : dlls) { - const std::wstring cmd_line = - Strings::wformat(LR"("%s" /exports "%s")", dumpbin_exe.native(), dll.native()); + const std::string cmd_line = + Strings::format(R"("%s" /exports "%s")", dumpbin_exe.u8string(), dll.u8string()); System::ExitCodeAndOutput ec_data = System::cmd_execute_and_capture_output(cmd_line); - Checks::check_exit(VCPKG_LINE_INFO, - ec_data.exit_code == 0, - "Running command:\n %s\n failed", - Strings::to_utf8(cmd_line)); + Checks::check_exit(VCPKG_LINE_INFO, ec_data.exit_code == 0, "Running command:\n %s\n failed", cmd_line); if (ec_data.output.find("ordinal hint RVA name") == std::string::npos) { @@ -321,13 +318,10 @@ namespace vcpkg::PostBuildLint std::vector dlls_with_improper_uwp_bit; for (const fs::path& dll : dlls) { - const std::wstring cmd_line = - Strings::wformat(LR"("%s" /headers "%s")", dumpbin_exe.native(), dll.native()); + const std::string cmd_line = + Strings::format(R"("%s" /headers "%s")", dumpbin_exe.u8string(), dll.u8string()); System::ExitCodeAndOutput ec_data = System::cmd_execute_and_capture_output(cmd_line); - Checks::check_exit(VCPKG_LINE_INFO, - ec_data.exit_code == 0, - "Running command:\n %s\n failed", - Strings::to_utf8(cmd_line)); + Checks::check_exit(VCPKG_LINE_INFO, ec_data.exit_code == 0, "Running command:\n %s\n failed", cmd_line); if (ec_data.output.find("App Container") == std::string::npos) { @@ -599,13 +593,10 @@ namespace vcpkg::PostBuildLint for (const fs::path& lib : libs) { - const std::wstring cmd_line = - Strings::wformat(LR"("%s" /directives "%s")", dumpbin_exe.native(), lib.native()); + const std::string cmd_line = + Strings::format(R"("%s" /directives "%s")", dumpbin_exe.u8string(), lib.u8string()); System::ExitCodeAndOutput ec_data = System::cmd_execute_and_capture_output(cmd_line); - Checks::check_exit(VCPKG_LINE_INFO, - ec_data.exit_code == 0, - "Running command:\n %s\n failed", - Strings::to_utf8(cmd_line)); + Checks::check_exit(VCPKG_LINE_INFO, ec_data.exit_code == 0, "Running command:\n %s\n failed", cmd_line); for (const BuildType& bad_build_type : bad_build_types) { @@ -655,13 +646,9 @@ namespace vcpkg::PostBuildLint for (const fs::path& dll : dlls) { - const std::wstring cmd_line = - Strings::wformat(LR"("%s" /dependents "%s")", dumpbin_exe.native(), dll.native()); + const auto cmd_line = Strings::format(R"("%s" /dependents "%s")", dumpbin_exe.u8string(), dll.u8string()); System::ExitCodeAndOutput ec_data = System::cmd_execute_and_capture_output(cmd_line); - Checks::check_exit(VCPKG_LINE_INFO, - ec_data.exit_code == 0, - "Running command:\n %s\n failed", - Strings::to_utf8(cmd_line)); + Checks::check_exit(VCPKG_LINE_INFO, ec_data.exit_code == 0, "Running command:\n %s\n failed", cmd_line); for (const OutdatedDynamicCrt& outdated_crt : get_outdated_dynamic_crts("v141")) { @@ -696,8 +683,8 @@ namespace vcpkg::PostBuildLint std::vector 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 (Strings::case_insensitive_ascii_compare(filename.c_str(), "CONTROL") || - Strings::case_insensitive_ascii_compare(filename.c_str(), "BUILD_INFO")) + if (Strings::case_insensitive_ascii_equals(filename.c_str(), "CONTROL") || + Strings::case_insensitive_ascii_equals(filename.c_str(), "BUILD_INFO")) return false; return !fs.is_directory(path); }); diff --git a/toolsrc/src/vcpkg/remove.cpp b/toolsrc/src/vcpkg/remove.cpp index 04ddba1e4..2ec32855a 100644 --- a/toolsrc/src/vcpkg/remove.cpp +++ b/toolsrc/src/vcpkg/remove.cpp @@ -21,7 +21,7 @@ namespace vcpkg::Remove { auto& fs = paths.get_filesystem(); auto spghs = status_db->find_all(spec.name(), spec.triplet()); - const auto core_pkg = **status_db->find(spec.name(), spec.triplet(), Strings::EMPTY); + const auto core_pkg = **status_db->find(spec.name(), spec.triplet(), ""); for (auto&& spgh : spghs) { diff --git a/toolsrc/src/vcpkg/sourceparagraph.cpp b/toolsrc/src/vcpkg/sourceparagraph.cpp index d766dcb72..2a9480538 100644 --- a/toolsrc/src/vcpkg/sourceparagraph.cpp +++ b/toolsrc/src/vcpkg/sourceparagraph.cpp @@ -178,11 +178,11 @@ namespace vcpkg return Strings::format("%s[%s]", this->depend.name, features); } - std::vector vcpkg::expand_qualified_dependencies(const std::vector& depends) + std::vector expand_qualified_dependencies(const std::vector& depends) { return Util::fmap(depends, [&](const std::string& depend_string) -> Dependency { auto pos = depend_string.find(' '); - if (pos == std::string::npos) return Dependency::parse_dependency(depend_string, Strings::EMPTY); + if (pos == std::string::npos) return Dependency::parse_dependency(depend_string, ""); // expect of the form "\w+ \[\w+\]" Dependency dep; @@ -190,7 +190,7 @@ namespace vcpkg if (depend_string.c_str()[pos + 1] != '(' || depend_string[depend_string.size() - 1] != ')') { // Error, but for now just slurp the entire string. - return Dependency::parse_dependency(depend_string, Strings::EMPTY); + return Dependency::parse_dependency(depend_string, ""); } dep.qualifier = depend_string.substr(pos + 2, depend_string.size() - pos - 3); return dep; diff --git a/toolsrc/src/vcpkg/triplet.cpp b/toolsrc/src/vcpkg/triplet.cpp index 4ebb97a9b..4cba1523d 100644 --- a/toolsrc/src/vcpkg/triplet.cpp +++ b/toolsrc/src/vcpkg/triplet.cpp @@ -18,11 +18,14 @@ namespace vcpkg const TripletInstance Triplet::DEFAULT_INSTANCE({}); } -template<> -struct std::hash +namespace std { - size_t operator()(const vcpkg::TripletInstance& t) const { return t.hash; } -}; + template<> + struct hash + { + size_t operator()(const vcpkg::TripletInstance& t) const { return t.hash; } + }; +} namespace vcpkg { diff --git a/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp b/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp index 522961693..209f6a3f2 100644 --- a/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp +++ b/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp @@ -45,12 +45,20 @@ namespace vcpkg option_field = new_setting; } +#if defined(_WIN32) VcpkgCmdArguments VcpkgCmdArguments::create_from_command_line(const int argc, const wchar_t* const* const argv) +#else + VcpkgCmdArguments VcpkgCmdArguments::create_from_command_line(const int argc, const char* const* const argv) +#endif { std::vector v; for (int i = 1; i < argc; ++i) { +#if defined(_WIN32) v.push_back(Strings::to_utf8(argv[i])); +#else + v.push_back(argv[i]); +#endif } return VcpkgCmdArguments::create_from_arg_sequence(v.data(), v.data() + v.size()); @@ -223,17 +231,17 @@ namespace vcpkg void VcpkgCmdArguments::check_max_arg_count(const size_t expected_arg_count) const { - return check_max_arg_count(expected_arg_count, Strings::EMPTY); + return check_max_arg_count(expected_arg_count, ""); } void VcpkgCmdArguments::check_min_arg_count(const size_t expected_arg_count) const { - return check_min_arg_count(expected_arg_count, Strings::EMPTY); + return check_min_arg_count(expected_arg_count, ""); } void VcpkgCmdArguments::check_exact_arg_count(const size_t expected_arg_count) const { - return check_exact_arg_count(expected_arg_count, Strings::EMPTY); + return check_exact_arg_count(expected_arg_count, ""); } void VcpkgCmdArguments::check_max_arg_count(const size_t expected_arg_count, const std::string& example_text) const diff --git a/toolsrc/src/vcpkg/vcpkglib.cpp b/toolsrc/src/vcpkg/vcpkglib.cpp index 23c774210..38b130f6f 100644 --- a/toolsrc/src/vcpkg/vcpkglib.cpp +++ b/toolsrc/src/vcpkg/vcpkglib.cpp @@ -212,30 +212,26 @@ namespace vcpkg return installed_files; } - CMakeVariable::CMakeVariable(const CWStringView varname, const wchar_t* varvalue) - : s(Strings::wformat(LR"("-D%s=%s")", varname, varvalue)) + CMakeVariable::CMakeVariable(const CStringView varname, const char* varvalue) + : s(Strings::format(R"("-D%s=%s")", varname, varvalue)) { } - CMakeVariable::CMakeVariable(const CWStringView varname, const std::string& varvalue) - : CMakeVariable(varname, Strings::to_utf16(varvalue).c_str()) - { - } - CMakeVariable::CMakeVariable(const CWStringView varname, const std::wstring& varvalue) + CMakeVariable::CMakeVariable(const CStringView varname, const std::string& varvalue) : CMakeVariable(varname, varvalue.c_str()) { } - CMakeVariable::CMakeVariable(const CWStringView varname, const fs::path& path) - : CMakeVariable(varname, path.generic_wstring()) + CMakeVariable::CMakeVariable(const CStringView varname, const fs::path& path) + : CMakeVariable(varname, path.generic_u8string()) { } - std::wstring make_cmake_cmd(const fs::path& cmake_exe, - const fs::path& cmake_script, - const std::vector& pass_variables) + std::string make_cmake_cmd(const fs::path& cmake_exe, + const fs::path& cmake_script, + const std::vector& pass_variables) { - const std::wstring cmd_cmake_pass_variables = Strings::join(L" ", pass_variables, [](auto&& v) { return v.s; }); - return Strings::wformat( - LR"("%s" %s -P "%s")", cmake_exe.native(), cmd_cmake_pass_variables, cmake_script.generic_wstring()); + const std::string cmd_cmake_pass_variables = Strings::join(" ", pass_variables, [](auto&& v) { return v.s; }); + return Strings::format( + R"("%s" %s -P "%s")", cmake_exe.u8string(), cmd_cmake_pass_variables, cmake_script.generic_u8string()); } std::string shorten_text(const std::string& desc, size_t length) diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index c57077eaa..90f9cb00b 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -10,16 +10,16 @@ namespace vcpkg { - static constexpr CWStringView V_120 = L"v120"; - static constexpr CWStringView V_140 = L"v140"; - static constexpr CWStringView V_141 = L"v141"; + static constexpr CStringView V_120 = "v120"; + static constexpr CStringView V_140 = "v140"; + static constexpr CStringView V_141 = "v141"; - static bool exists_and_has_equal_or_greater_version(const std::wstring& version_cmd, + static bool exists_and_has_equal_or_greater_version(const std::string& version_cmd, const std::array& expected_version) { static const std::regex RE(R"###((\d+)\.(\d+)\.(\d+))###"); - const auto rc = System::cmd_execute_and_capture_output(Strings::wformat(LR"(%s)", version_cmd)); + const auto rc = System::cmd_execute_and_capture_output(Strings::format(R"(%s)", version_cmd)); if (rc.exit_code != 0) { return false; @@ -46,11 +46,11 @@ namespace vcpkg } static Optional find_if_has_equal_or_greater_version(const std::vector& candidate_paths, - const std::wstring& version_check_arguments, + const std::string& version_check_arguments, const std::array& expected_version) { auto it = Util::find_if(candidate_paths, [&](const fs::path& p) { - const std::wstring cmd = Strings::wformat(LR"("%s" %s)", p.native(), version_check_arguments); + const std::string cmd = Strings::format(R"("%s" %s)", p.u8string(), version_check_arguments); return exists_and_has_equal_or_greater_version(cmd, expected_version); }); @@ -63,27 +63,26 @@ namespace vcpkg } static fs::path fetch_dependency(const fs::path& scripts_folder, - const std::wstring& tool_name, + const std::string& tool_name, const fs::path& expected_downloaded_path, const std::array& version) { - const std::string tool_name_utf8 = Strings::to_utf8(tool_name); const std::string version_as_string = Strings::format("%d.%d.%d", version[0], version[1], version[2]); System::println("A suitable version of %s was not found (required v%s). Downloading portable %s v%s...", - tool_name_utf8, + tool_name, version_as_string, - tool_name_utf8, + tool_name, version_as_string); const fs::path script = scripts_folder / "fetchDependency.ps1"; const auto install_cmd = - System::create_powershell_script_cmd(script, Strings::wformat(L"-Dependency %s", tool_name)); + System::create_powershell_script_cmd(script, Strings::format("-Dependency %s", tool_name)); const System::ExitCodeAndOutput rc = System::cmd_execute_and_capture_output(install_cmd); if (rc.exit_code) { System::println(System::Color::error, "Launching powershell failed or was denied when trying to fetch %s version %s.\n" "(No sufficient installed version was found)", - tool_name_utf8, + tool_name, version_as_string); { auto locked_metrics = Metrics::g_metrics.lock(); @@ -107,16 +106,18 @@ namespace vcpkg static fs::path get_cmake_path(const fs::path& downloads_folder, const fs::path& scripts_folder) { static constexpr std::array EXPECTED_VERSION = {3, 9, 3}; - static const std::wstring VERSION_CHECK_ARGUMENTS = L"--version"; + static const std::string VERSION_CHECK_ARGUMENTS = "--version"; const fs::path downloaded_copy = downloads_folder / "cmake-3.9.3-win32-x86" / "bin" / "cmake.exe"; - const std::vector from_path = Files::find_from_PATH(L"cmake"); + const std::vector from_path = Files::find_from_PATH("cmake"); std::vector candidate_paths; candidate_paths.push_back(downloaded_copy); candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); +#if defined(_WIN32) candidate_paths.push_back(System::get_program_files_platform_bitness() / "CMake" / "bin" / "cmake.exe"); candidate_paths.push_back(System::get_program_files_32_bit() / "CMake" / "bin"); +#endif const Optional path = find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, EXPECTED_VERSION); @@ -125,43 +126,44 @@ namespace vcpkg return *p; } - return fetch_dependency(scripts_folder, L"cmake", downloaded_copy, EXPECTED_VERSION); + return fetch_dependency(scripts_folder, "cmake", downloaded_copy, EXPECTED_VERSION); } fs::path get_nuget_path(const fs::path& downloads_folder, const fs::path& scripts_folder) { static constexpr std::array EXPECTED_VERSION = {4, 3, 0}; - static const std::wstring VERSION_CHECK_ARGUMENTS = Strings::WEMPTY; const fs::path downloaded_copy = downloads_folder / "nuget-4.3.0" / "nuget.exe"; - const std::vector from_path = Files::find_from_PATH(L"nuget"); + const std::vector from_path = Files::find_from_PATH("nuget"); std::vector candidate_paths; candidate_paths.push_back(downloaded_copy); candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); - auto path = find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, EXPECTED_VERSION); + auto path = find_if_has_equal_or_greater_version(candidate_paths, "", EXPECTED_VERSION); if (const auto p = path.get()) { return *p; } - return fetch_dependency(scripts_folder, L"nuget", downloaded_copy, EXPECTED_VERSION); + return fetch_dependency(scripts_folder, "nuget", downloaded_copy, EXPECTED_VERSION); } fs::path get_git_path(const fs::path& downloads_folder, const fs::path& scripts_folder) { static constexpr std::array EXPECTED_VERSION = {2, 14, 1}; - static const std::wstring VERSION_CHECK_ARGUMENTS = L"--version"; + static const std::string VERSION_CHECK_ARGUMENTS = "--version"; const fs::path downloaded_copy = downloads_folder / "MinGit-2.14.1-32-bit" / "cmd" / "git.exe"; - const std::vector from_path = Files::find_from_PATH(L"git"); + const std::vector from_path = Files::find_from_PATH("git"); std::vector candidate_paths; candidate_paths.push_back(downloaded_copy); candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); +#if defined(_WIN32) candidate_paths.push_back(System::get_program_files_platform_bitness() / "git" / "cmd" / "git.exe"); candidate_paths.push_back(System::get_program_files_32_bit() / "git" / "cmd" / "git.exe"); +#endif const Optional path = find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, EXPECTED_VERSION); @@ -170,13 +172,13 @@ namespace vcpkg return *p; } - return fetch_dependency(scripts_folder, L"git", downloaded_copy, EXPECTED_VERSION); + return fetch_dependency(scripts_folder, "git", downloaded_copy, EXPECTED_VERSION); } static fs::path get_ifw_installerbase_path(const fs::path& downloads_folder, const fs::path& scripts_folder) { static constexpr std::array EXPECTED_VERSION = {3, 1, 81}; - static const std::wstring VERSION_CHECK_ARGUMENTS = L"--framework-version"; + static const std::string VERSION_CHECK_ARGUMENTS = "--framework-version"; const fs::path downloaded_copy = downloads_folder / "QtInstallerFramework-win-x86" / "bin" / "installerbase.exe"; @@ -184,11 +186,11 @@ namespace vcpkg std::vector candidate_paths; candidate_paths.push_back(downloaded_copy); // TODO: Uncomment later - // const std::vector from_path = Files::find_from_PATH(L"installerbase"); + // const std::vector from_path = Files::find_from_PATH("installerbase"); // candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); - // candidate_paths.push_back(fs::path(System::get_environment_variable(L"HOMEDRIVE").value_or("C:")) / "Qt" / + // candidate_paths.push_back(fs::path(System::get_environment_variable("HOMEDRIVE").value_or("C:")) / "Qt" / // "Tools" / "QtInstallerFramework" / "3.1" / "bin" / "installerbase.exe"); - // candidate_paths.push_back(fs::path(System::get_environment_variable(L"HOMEDRIVE").value_or("C:")) / "Qt" / + // candidate_paths.push_back(fs::path(System::get_environment_variable("HOMEDRIVE").value_or("C:")) / "Qt" / // "QtIFW-3.1.0" / "bin" / "installerbase.exe"); const Optional path = @@ -198,7 +200,7 @@ namespace vcpkg return *p; } - return fetch_dependency(scripts_folder, L"installerbase", downloaded_copy, EXPECTED_VERSION); + return fetch_dependency(scripts_folder, "installerbase", downloaded_copy, EXPECTED_VERSION); } Expected VcpkgPaths::create(const fs::path& vcpkg_root_dir) @@ -322,7 +324,7 @@ namespace vcpkg static std::vector get_visual_studio_instances(const VcpkgPaths& paths) { const fs::path script = paths.scripts / "findVisualStudioInstallationInstances.ps1"; - const std::wstring cmd = System::create_powershell_script_cmd(script); + const std::string cmd = System::create_powershell_script_cmd(script); const System::ExitCodeAndOutput ec_data = System::cmd_execute_and_capture_output(cmd); Checks::check_exit( VCPKG_LINE_INFO, ec_data.exit_code == 0, "Could not run script to detect Visual Studio instances"); @@ -370,21 +372,21 @@ namespace vcpkg // Get all supported architectures std::vector supported_architectures; if (fs.exists(vcvarsall_dir / "vcvars32.bat")) - supported_architectures.push_back({L"x86", CPU::X86, CPU::X86}); + supported_architectures.push_back({"x86", CPU::X86, CPU::X86}); if (fs.exists(vcvarsall_dir / "vcvars64.bat")) - supported_architectures.push_back({L"amd64", CPU::X64, CPU::X64}); + supported_architectures.push_back({"amd64", CPU::X64, CPU::X64}); if (fs.exists(vcvarsall_dir / "vcvarsx86_amd64.bat")) - supported_architectures.push_back({L"x86_amd64", CPU::X86, CPU::X64}); + supported_architectures.push_back({"x86_amd64", CPU::X86, CPU::X64}); if (fs.exists(vcvarsall_dir / "vcvarsx86_arm.bat")) - supported_architectures.push_back({L"x86_arm", CPU::X86, CPU::ARM}); + supported_architectures.push_back({"x86_arm", CPU::X86, CPU::ARM}); if (fs.exists(vcvarsall_dir / "vcvarsx86_arm64.bat")) - supported_architectures.push_back({L"x86_arm64", CPU::X86, CPU::ARM64}); + supported_architectures.push_back({"x86_arm64", CPU::X86, CPU::ARM64}); if (fs.exists(vcvarsall_dir / "vcvarsamd64_x86.bat")) - supported_architectures.push_back({L"amd64_x86", CPU::X64, CPU::X86}); + supported_architectures.push_back({"amd64_x86", CPU::X64, CPU::X86}); if (fs.exists(vcvarsall_dir / "vcvarsamd64_arm.bat")) - supported_architectures.push_back({L"amd64_arm", CPU::X64, CPU::ARM}); + supported_architectures.push_back({"amd64_arm", CPU::X64, CPU::ARM}); if (fs.exists(vcvarsall_dir / "vcvarsamd64_arm64.bat")) - supported_architectures.push_back({L"amd64_arm64", CPU::X64, CPU::ARM64}); + supported_architectures.push_back({"amd64_arm64", CPU::X64, CPU::ARM64}); // Locate the "best" MSVC toolchain version const fs::path msvc_path = vc_dir / "Tools" / "MSVC"; @@ -412,7 +414,7 @@ namespace vcpkg found_toolsets.push_back(Toolset{vs_instance.root_path, dumpbin_path, vcvarsall_bat, - {L"-vcvars_ver=14.0"}, + {"-vcvars_ver=14.0"}, V_140, supported_architectures}); } @@ -437,17 +439,17 @@ namespace vcpkg const fs::path vs2015_bin_dir = vcvarsall_bat.parent_path() / "bin"; std::vector supported_architectures; if (fs.exists(vs2015_bin_dir / "vcvars32.bat")) - supported_architectures.push_back({L"x86", CPU::X86, CPU::X86}); + supported_architectures.push_back({"x86", CPU::X86, CPU::X86}); if (fs.exists(vs2015_bin_dir / "amd64\\vcvars64.bat")) - supported_architectures.push_back({L"x64", CPU::X64, CPU::X64}); + supported_architectures.push_back({"x64", CPU::X64, CPU::X64}); if (fs.exists(vs2015_bin_dir / "x86_amd64\\vcvarsx86_amd64.bat")) - supported_architectures.push_back({L"x86_amd64", CPU::X86, CPU::X64}); + supported_architectures.push_back({"x86_amd64", CPU::X86, CPU::X64}); if (fs.exists(vs2015_bin_dir / "x86_arm\\vcvarsx86_arm.bat")) - supported_architectures.push_back({L"x86_arm", CPU::X86, CPU::ARM}); + supported_architectures.push_back({"x86_arm", CPU::X86, CPU::ARM}); if (fs.exists(vs2015_bin_dir / "amd64_x86\\vcvarsamd64_x86.bat")) - supported_architectures.push_back({L"amd64_x86", CPU::X64, CPU::X86}); + supported_architectures.push_back({"amd64_x86", CPU::X64, CPU::X86}); if (fs.exists(vs2015_bin_dir / "amd64_arm\\vcvarsamd64_arm.bat")) - supported_architectures.push_back({L"amd64_arm", CPU::X64, CPU::ARM}); + supported_architectures.push_back({"amd64_arm", CPU::X64, CPU::ARM}); if (fs.exists(vs2015_dumpbin_exe)) { @@ -489,15 +491,12 @@ namespace vcpkg if (tsv && vsp) { - const std::wstring w_toolset_version = Strings::to_utf16(*tsv); - const fs::path vs_root_path = *vsp; - Util::stable_keep_if(candidates, [&](const Toolset* t) { - return w_toolset_version == t->version && vs_root_path == t->visual_studio_root_path; - }); + Util::stable_keep_if( + candidates, [&](const Toolset* t) { return *tsv == t->version && *vsp == t->visual_studio_root_path; }); Checks::check_exit(VCPKG_LINE_INFO, !candidates.empty(), "Could not find Visual Studio instace at %s with %s toolset.", - vs_root_path.generic_string(), + vsp->u8string(), *tsv); Checks::check_exit(VCPKG_LINE_INFO, candidates.size() == 1); @@ -506,8 +505,7 @@ namespace vcpkg if (tsv) { - const std::wstring w_toolset_version = Strings::to_utf16(*tsv); - Util::stable_keep_if(candidates, [&](const Toolset* t) { return w_toolset_version == t->version; }); + Util::stable_keep_if(candidates, [&](const Toolset* t) { return *tsv == t->version; }); Checks::check_exit( VCPKG_LINE_INFO, !candidates.empty(), "Could not find Visual Studio instace with %s toolset.", *tsv); } -- cgit v1.2.3 From ced047ad78734aed239669a0fd9eca9e81718966 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 16 Oct 2017 13:50:28 -0700 Subject: Remove usages of CWStringView, except in Strings::to_utf8() --- toolsrc/include/vcpkg/base/cstringview.h | 89 +++++++++++--------------------- toolsrc/include/vcpkg/base/strings.h | 4 +- toolsrc/include/vcpkg/base/system.h | 7 +-- toolsrc/include/vcpkg/metrics.h | 2 +- toolsrc/src/vcpkg/base/strings.cpp | 4 +- toolsrc/src/vcpkg/base/system.cpp | 26 ++++++---- toolsrc/src/vcpkg/commands.edit.cpp | 13 +++-- toolsrc/src/vcpkg/metrics.cpp | 8 +-- 8 files changed, 62 insertions(+), 91 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/base/cstringview.h b/toolsrc/include/vcpkg/base/cstringview.h index eac204f97..342455402 100644 --- a/toolsrc/include/vcpkg/base/cstringview.h +++ b/toolsrc/include/vcpkg/base/cstringview.h @@ -5,94 +5,65 @@ namespace vcpkg { - template - struct BasicCStringView + struct CStringView { - constexpr BasicCStringView() : cstr(nullptr) {} - constexpr BasicCStringView(const CharType* cstr) : cstr(cstr) {} - constexpr BasicCStringView(const BasicCStringView&) = default; - BasicCStringView(const std::basic_string& str) : cstr(str.c_str()) {} + constexpr CStringView() : cstr(nullptr) {} + constexpr CStringView(const char* cstr) : cstr(cstr) {} + constexpr CStringView(const CStringView&) = default; + CStringView(const std::string& str) : cstr(str.c_str()) {} - constexpr const CharType* c_str() const { return cstr; } + constexpr const char* c_str() const { return cstr; } private: - const CharType* cstr; + const char* cstr; + }; + + struct CWStringView + { + constexpr CWStringView() : cstr(nullptr) {} + constexpr CWStringView(const wchar_t* cstr) : cstr(cstr) {} + constexpr CWStringView(const CWStringView&) = default; + CWStringView(const std::wstring& str) : cstr(str.c_str()) {} + + constexpr const wchar_t* c_str() const { return cstr; } + + private: + const wchar_t* cstr; }; namespace details { inline bool vcpkg_strcmp(const char* l, const char* r) { return strcmp(l, r) == 0; } - inline bool vcpkg_strcmp(const wchar_t* l, const wchar_t* r) { return wcscmp(l, r) == 0; } } - template - bool operator==(const BasicCStringView& l, const BasicCStringView& r) + inline bool operator==(const CStringView& l, const CStringView& r) { return details::vcpkg_strcmp(l.c_str(), r.c_str()); } - template - bool operator==(const CharType* l, const BasicCStringView& r) - { - return details::vcpkg_strcmp(l, r.c_str()); - } + inline bool operator==(const char* l, const CStringView& r) { return details::vcpkg_strcmp(l, r.c_str()); } - template - bool operator==(const BasicCStringView& r, const CharType* l) - { - return details::vcpkg_strcmp(l, r.c_str()); - } + inline bool operator==(const CStringView& r, const char* l) { return details::vcpkg_strcmp(l, r.c_str()); } - template - bool operator==(const std::basic_string& l, const BasicCStringView& r) - { - return l == r.c_str(); - } + inline bool operator==(const std::string& l, const CStringView& r) { return l == r.c_str(); } - template - bool operator==(const BasicCStringView& r, const std::basic_string& l) - { - return l == r.c_str(); - } + inline bool operator==(const CStringView& r, const std::string& l) { return l == r.c_str(); } // notequals - template - bool operator!=(const BasicCStringView& l, const BasicCStringView& r) + inline bool operator!=(const CStringView& l, const CStringView& r) { return !details::vcpkg_strcmp(l.c_str(), r.c_str()); } - template - bool operator!=(const CharType* l, const BasicCStringView& r) - { - return !details::vcpkg_strcmp(l, r.c_str()); - } - - template - bool operator!=(const BasicCStringView& r, const CharType* l) - { - return !details::vcpkg_strcmp(l, r.c_str()); - } + inline bool operator!=(const char* l, const CStringView& r) { return !details::vcpkg_strcmp(l, r.c_str()); } - template - bool operator!=(const BasicCStringView& r, const std::basic_string& l) - { - return l != r.c_str(); - } + inline bool operator!=(const CStringView& r, const char* l) { return !details::vcpkg_strcmp(l, r.c_str()); } - template - bool operator!=(const std::basic_string& l, const BasicCStringView& r) - { - return l != r.c_str(); - } + inline bool operator!=(const CStringView& r, const std::string& l) { return l != r.c_str(); } - using CStringView = BasicCStringView; - using CWStringView = BasicCStringView; + inline bool operator!=(const std::string& l, const CStringView& r) { return l != r.c_str(); } inline const char* to_printf_arg(const CStringView string_view) { return string_view.c_str(); } - inline const wchar_t* to_wprintf_arg(const CWStringView string_view) { return string_view.c_str(); } - static_assert(sizeof(CStringView) == sizeof(void*), "CStringView must be a simple wrapper around char*"); - static_assert(sizeof(CWStringView) == sizeof(void*), "CWStringView must be a simple wrapper around wchar_t*"); } diff --git a/toolsrc/include/vcpkg/base/strings.h b/toolsrc/include/vcpkg/base/strings.h index 93b36a29d..4adcadb0d 100644 --- a/toolsrc/include/vcpkg/base/strings.h +++ b/toolsrc/include/vcpkg/base/strings.h @@ -47,9 +47,9 @@ namespace vcpkg::Strings return details::wformat_internal(fmtstr, to_wprintf_arg(to_wprintf_arg(args))...); } - std::wstring to_utf16(const CStringView s); + std::wstring to_utf16(const CStringView& s); - std::string to_utf8(const CWStringView w); + std::string to_utf8(const CWStringView& w); std::string::const_iterator case_insensitive_ascii_find(const std::string& s, const std::string& pattern); diff --git a/toolsrc/include/vcpkg/base/system.h b/toolsrc/include/vcpkg/base/system.h index f2344c919..b396ef293 100644 --- a/toolsrc/include/vcpkg/base/system.h +++ b/toolsrc/include/vcpkg/base/system.h @@ -4,7 +4,6 @@ #include #include - namespace vcpkg::System { tm get_current_date_time(); @@ -64,9 +63,7 @@ namespace vcpkg::System Optional get_environment_variable(const CStringView varname) noexcept; - Optional get_registry_string(void* base_hkey, - const CWStringView subkey, - const CWStringView valuename); + Optional get_registry_string(void* base_hkey, const CStringView subkey, const CStringView valuename); enum class CPUArchitecture { @@ -76,7 +73,7 @@ namespace vcpkg::System ARM64, }; - Optional to_cpu_architecture(CStringView arch); + Optional to_cpu_architecture(const CStringView& arch); CPUArchitecture get_host_processor(); diff --git a/toolsrc/include/vcpkg/metrics.h b/toolsrc/include/vcpkg/metrics.h index 41be5002d..d570624eb 100644 --- a/toolsrc/include/vcpkg/metrics.h +++ b/toolsrc/include/vcpkg/metrics.h @@ -23,6 +23,6 @@ namespace vcpkg::Metrics extern Util::LockGuarded g_metrics; - std::wstring get_SQM_user(); + std::string get_SQM_user(); bool get_compiled_metrics_enabled(); } diff --git a/toolsrc/src/vcpkg/base/strings.cpp b/toolsrc/src/vcpkg/base/strings.cpp index fa04279b9..160aa98e9 100644 --- a/toolsrc/src/vcpkg/base/strings.cpp +++ b/toolsrc/src/vcpkg/base/strings.cpp @@ -72,7 +72,7 @@ namespace vcpkg::Strings::details namespace vcpkg::Strings { - std::wstring to_utf16(const CStringView s) + std::wstring to_utf16(const CStringView& s) { #if defined(_WIN32) const int size = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, nullptr, 0); @@ -85,7 +85,7 @@ namespace vcpkg::Strings #endif } - std::string to_utf8(const CWStringView w) + std::string to_utf8(const CWStringView& w) { #if defined(_WIN32) const int size = WideCharToMultiByte(CP_UTF8, 0, w.c_str(), -1, nullptr, 0, nullptr, nullptr); diff --git a/toolsrc/src/vcpkg/base/system.cpp b/toolsrc/src/vcpkg/base/system.cpp index e92d06f6e..730b22c43 100644 --- a/toolsrc/src/vcpkg/base/system.cpp +++ b/toolsrc/src/vcpkg/base/system.cpp @@ -38,7 +38,7 @@ namespace vcpkg::System #endif } - Optional to_cpu_architecture(CStringView arch) + Optional to_cpu_architecture(const CStringView& arch) { if (Strings::case_insensitive_ascii_equals(arch, "x86")) return CPUArchitecture::X86; if (Strings::case_insensitive_ascii_equals(arch, "x64")) return CPUArchitecture::X64; @@ -153,7 +153,7 @@ namespace vcpkg::System memset(&process_info, 0, sizeof(PROCESS_INFORMATION)); // Basically we are wrapping it in quotes - std::string actual_cmd_line = Strings::format(R"###(cmd.exe /c "%s")###", cmd_line); + const std::string actual_cmd_line = Strings::format(R"###(cmd.exe /c "%s")###", cmd_line); Debug::println("CreateProcessW(%s)", actual_cmd_line); bool succeeded = TRUE == CreateProcessW(nullptr, Strings::to_utf16(actual_cmd_line).data(), @@ -331,35 +331,39 @@ namespace vcpkg::System } #if defined(_WIN32) - static bool is_string_keytype(DWORD hkey_type) + static bool is_string_keytype(const DWORD hkey_type) { return hkey_type == REG_SZ || hkey_type == REG_MULTI_SZ || hkey_type == REG_EXPAND_SZ; } - Optional get_registry_string(void* base_hkey, - const CWStringView sub_key, - const CWStringView valuename) + Optional get_registry_string(void* base_hkey, const CStringView sub_key, const CStringView valuename) { HKEY k = nullptr; - const LSTATUS ec = RegOpenKeyExW(reinterpret_cast(base_hkey), sub_key.c_str(), NULL, KEY_READ, &k); + const LSTATUS ec = + RegOpenKeyExW(reinterpret_cast(base_hkey), Strings::to_utf16(sub_key).c_str(), NULL, KEY_READ, &k); if (ec != ERROR_SUCCESS) return nullopt; DWORD dw_buffer_size = 0; DWORD dw_type = 0; - auto rc = RegQueryValueExW(k, valuename.c_str(), nullptr, &dw_type, nullptr, &dw_buffer_size); + auto rc = + RegQueryValueExW(k, Strings::to_utf16(valuename).c_str(), nullptr, &dw_type, nullptr, &dw_buffer_size); if (rc != ERROR_SUCCESS || !is_string_keytype(dw_type) || dw_buffer_size == 0 || dw_buffer_size % sizeof(wchar_t) != 0) return nullopt; std::wstring ret; ret.resize(dw_buffer_size / sizeof(wchar_t)); - rc = RegQueryValueExW( - k, valuename.c_str(), nullptr, &dw_type, reinterpret_cast(ret.data()), &dw_buffer_size); + rc = RegQueryValueExW(k, + Strings::to_utf16(valuename).c_str(), + nullptr, + &dw_type, + reinterpret_cast(ret.data()), + &dw_buffer_size); if (rc != ERROR_SUCCESS || !is_string_keytype(dw_type) || dw_buffer_size != sizeof(wchar_t) * ret.size()) return nullopt; ret.pop_back(); // remove extra trailing null byte - return ret; + return Strings::to_utf8(ret); } #else Optional get_registry_string(void* base_hkey, diff --git a/toolsrc/src/vcpkg/commands.edit.cpp b/toolsrc/src/vcpkg/commands.edit.cpp index fe6f76bd2..668ec9b1a 100644 --- a/toolsrc/src/vcpkg/commands.edit.cpp +++ b/toolsrc/src/vcpkg/commands.edit.cpp @@ -3,25 +3,24 @@ #include #include #include -#include #include namespace vcpkg::Commands::Edit { static std::vector find_from_registry() { - static const std::array REGKEYS = { - LR"(SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{C26E74D1-022E-4238-8B9D-1E7564A36CC9}_is1)", - LR"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{1287CAD5-7C8D-410D-88B9-0D1EE4A83FF2}_is1)", - LR"(SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{F8A2A208-72B3-4D61-95FC-8A65D340689B}_is1)", + static const std::array REGKEYS = { + R"(SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{C26E74D1-022E-4238-8B9D-1E7564A36CC9}_is1)", + R"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{1287CAD5-7C8D-410D-88B9-0D1EE4A83FF2}_is1)", + R"(SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{F8A2A208-72B3-4D61-95FC-8A65D340689B}_is1)", }; std::vector output; #if defined(_WIN32) for (auto&& keypath : REGKEYS) { - const Optional code_installpath = - System::get_registry_string(HKEY_LOCAL_MACHINE, keypath, L"InstallLocation"); + const Optional code_installpath = + System::get_registry_string(HKEY_LOCAL_MACHINE, keypath, "InstallLocation"); if (const auto c = code_installpath.get()) { const fs::path install_path = fs::path(*c); diff --git a/toolsrc/src/vcpkg/metrics.cpp b/toolsrc/src/vcpkg/metrics.cpp index 854baa0ca..c93d47d6e 100644 --- a/toolsrc/src/vcpkg/metrics.cpp +++ b/toolsrc/src/vcpkg/metrics.cpp @@ -233,14 +233,14 @@ namespace vcpkg::Metrics bool get_compiled_metrics_enabled() { return DISABLE_METRICS == 0; } - std::wstring get_SQM_user() + std::string get_SQM_user() { #if defined(_WIN32) auto hkcu_sqmclient = - System::get_registry_string(HKEY_CURRENT_USER, LR"(Software\Microsoft\SQMClient)", L"UserId"); - return hkcu_sqmclient.value_or(L"{}"); + System::get_registry_string(HKEY_CURRENT_USER, R"(Software\Microsoft\SQMClient)", "UserId"); + return hkcu_sqmclient.value_or("{}"); #else - return L"{}"; + return "{}"; #endif } -- cgit v1.2.3 From c797ab4794b022f9f2a53f9a80bd6a451bd6d1ee Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 16 Oct 2017 13:52:35 -0700 Subject: Remove Strings::wformat() --- toolsrc/include/vcpkg/base/strings.h | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/base/strings.h b/toolsrc/include/vcpkg/base/strings.h index 4adcadb0d..6a4d4ef08 100644 --- a/toolsrc/include/vcpkg/base/strings.h +++ b/toolsrc/include/vcpkg/base/strings.h @@ -17,18 +17,12 @@ namespace vcpkg::Strings::details inline const char* to_printf_arg(const char* s) { return s; } template::value>> - inline T to_printf_arg(T s) + T to_printf_arg(T s) { return s; } std::string format_internal(const char* fmtstr, ...); - - inline const wchar_t* to_wprintf_arg(const std::wstring& s) { return s.c_str(); } - - inline const wchar_t* to_wprintf_arg(const wchar_t* s) { return s; } - - std::wstring wformat_internal(const wchar_t* fmtstr, ...); } namespace vcpkg::Strings @@ -40,13 +34,6 @@ namespace vcpkg::Strings return details::format_internal(fmtstr, to_printf_arg(to_printf_arg(args))...); } - template - std::wstring wformat(const wchar_t* fmtstr, const Args&... args) - { - using vcpkg::Strings::details::to_wprintf_arg; - return details::wformat_internal(fmtstr, to_wprintf_arg(to_wprintf_arg(args))...); - } - std::wstring to_utf16(const CStringView& s); std::string to_utf8(const CWStringView& w); -- cgit v1.2.3 From 61777425db2c5f59eb3a44f4439b734c27932cba Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 16 Oct 2017 13:54:38 -0700 Subject: Remove CharType template paramter from Strings::join() --- toolsrc/include/vcpkg/base/strings.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/base/strings.h b/toolsrc/include/vcpkg/base/strings.h index 6a4d4ef08..d263e3b6b 100644 --- a/toolsrc/include/vcpkg/base/strings.h +++ b/toolsrc/include/vcpkg/base/strings.h @@ -48,18 +48,18 @@ namespace vcpkg::Strings bool case_insensitive_ascii_starts_with(const std::string& s, const std::string& pattern); - template - std::basic_string join(const CharType* delimiter, const Container& v, Transformer transformer) + template + std::string join(const char* delimiter, const Container& v, Transformer transformer) { const auto begin = v.begin(); const auto end = v.end(); if (begin == end) { - return std::basic_string(); + return std::string(); } - std::basic_string output; + std::string output; output.append(transformer(*begin)); for (auto it = std::next(begin); it != end; ++it) { @@ -69,8 +69,8 @@ namespace vcpkg::Strings return output; } - template - std::basic_string join(const CharType* delimiter, const Container& v) + template + std::string join(const char* delimiter, const Container& v) { using Element = decltype(*v.begin()); return join(delimiter, v, [](const Element& x) -> const Element& { return x; }); -- cgit v1.2.3 From 70b458f5d97d5c189379b3d6b8913b27a2878661 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 16 Oct 2017 13:56:05 -0700 Subject: Remove Metrics::track_property(std::wstring) --- toolsrc/include/vcpkg/metrics.h | 1 - toolsrc/src/vcpkg/metrics.cpp | 11 ----------- 2 files changed, 12 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/metrics.h b/toolsrc/include/vcpkg/metrics.h index d570624eb..f73c636cf 100644 --- a/toolsrc/include/vcpkg/metrics.h +++ b/toolsrc/include/vcpkg/metrics.h @@ -15,7 +15,6 @@ namespace vcpkg::Metrics void track_metric(const std::string& name, double value); void track_property(const std::string& name, const std::string& value); - void track_property(const std::string& name, const std::wstring& value); void upload(const std::string& payload); void flush(); diff --git a/toolsrc/src/vcpkg/metrics.cpp b/toolsrc/src/vcpkg/metrics.cpp index c93d47d6e..8f2575886 100644 --- a/toolsrc/src/vcpkg/metrics.cpp +++ b/toolsrc/src/vcpkg/metrics.cpp @@ -262,17 +262,6 @@ namespace vcpkg::Metrics void Metrics::track_metric(const std::string& name, double value) { g_metricmessage.track_metric(name, value); } - void Metrics::track_property(const std::string& name, const std::wstring& value) - { - // Note: this is not valid UTF-16 -> UTF-8, it just yields a close enough approximation for our purposes. - std::string converted_value; - converted_value.resize(value.size()); - std::transform( - value.begin(), value.end(), converted_value.begin(), [](wchar_t ch) { return static_cast(ch); }); - - g_metricmessage.track_property(name, converted_value); - } - void Metrics::track_property(const std::string& name, const std::string& value) { g_metricmessage.track_property(name, value); -- cgit v1.2.3 From fdc6b1ea1a59910df19962e0161b593c948abe98 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 16 Oct 2017 13:57:07 -0700 Subject: Remove wformat_internal() --- toolsrc/src/vcpkg/base/strings.cpp | 24 ------------------------ 1 file changed, 24 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/base/strings.cpp b/toolsrc/src/vcpkg/base/strings.cpp index 160aa98e9..af41eed9a 100644 --- a/toolsrc/src/vcpkg/base/strings.cpp +++ b/toolsrc/src/vcpkg/base/strings.cpp @@ -44,30 +44,6 @@ namespace vcpkg::Strings::details return output; } - - std::wstring wformat_internal(const wchar_t* fmtstr, ...) - { - va_list args; - va_start(args, fmtstr); - -#if defined(_WIN32) - const int sz = _vscwprintf_l(fmtstr, c_locale(), args); -#else - const int sz = vswprintf(nullptr, 0, fmtstr, args); -#endif - Checks::check_exit(VCPKG_LINE_INFO, sz > 0); - - std::wstring output(sz, L'\0'); - -#if defined(_WIN32) - _vsnwprintf_s_l(&output.at(0), output.size() + 1, output.size(), fmtstr, c_locale(), args); -#else - vswprintf(&output.at(0), output.size() + 1, fmtstr, args); -#endif - va_end(args); - - return output; - } } namespace vcpkg::Strings -- cgit v1.2.3 From dfe1f880d4e2a7f23d3b43d42a5d6ac2d68dc135 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 16 Oct 2017 14:22:20 -0700 Subject: [system.cpp] Remove usage of std::wstring. Convert at the last step --- toolsrc/src/vcpkg/base/system.cpp | 102 +++++++++++++++++++------------------- 1 file changed, 50 insertions(+), 52 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/base/system.cpp b/toolsrc/src/vcpkg/base/system.cpp index 730b22c43..ac527f9fc 100644 --- a/toolsrc/src/vcpkg/base/system.cpp +++ b/toolsrc/src/vcpkg/base/system.cpp @@ -79,71 +79,71 @@ namespace vcpkg::System static const std::string NEW_PATH = Strings::format( R"(Path=%s;%s;%s\Wbem;%s\WindowsPowerShell\v1.0\)", SYSTEM_32, SYSTEM_ROOT, SYSTEM_32, SYSTEM_32); - std::vector env_wstrings = { - L"ALLUSERSPROFILE", - L"APPDATA", - L"CommonProgramFiles", - L"CommonProgramFiles(x86)", - L"CommonProgramW6432", - L"COMPUTERNAME", - L"ComSpec", - L"HOMEDRIVE", - L"HOMEPATH", - L"LOCALAPPDATA", - L"LOGONSERVER", - L"NUMBER_OF_PROCESSORS", - L"OS", - L"PATHEXT", - L"PROCESSOR_ARCHITECTURE", - L"PROCESSOR_ARCHITEW6432", - L"PROCESSOR_IDENTIFIER", - L"PROCESSOR_LEVEL", - L"PROCESSOR_REVISION", - L"ProgramData", - L"ProgramFiles", - L"ProgramFiles(x86)", - L"ProgramW6432", - L"PROMPT", - L"PSModulePath", - L"PUBLIC", - L"SystemDrive", - L"SystemRoot", - L"TEMP", - L"TMP", - L"USERDNSDOMAIN", - L"USERDOMAIN", - L"USERDOMAIN_ROAMINGPROFILE", - L"USERNAME", - L"USERPROFILE", - L"windir", + std::vector env_wstrings = { + "ALLUSERSPROFILE", + "APPDATA", + "CommonProgramFiles", + "CommonProgramFiles(x86)", + "CommonProgramW6432", + "COMPUTERNAME", + "ComSpec", + "HOMEDRIVE", + "HOMEPATH", + "LOCALAPPDATA", + "LOGONSERVER", + "NUMBER_OF_PROCESSORS", + "OS", + "PATHEXT", + "PROCESSOR_ARCHITECTURE", + "PROCESSOR_ARCHITEW6432", + "PROCESSOR_IDENTIFIER", + "PROCESSOR_LEVEL", + "PROCESSOR_REVISION", + "ProgramData", + "ProgramFiles", + "ProgramFiles(x86)", + "ProgramW6432", + "PROMPT", + "PSModulePath", + "PUBLIC", + "SystemDrive", + "SystemRoot", + "TEMP", + "TMP", + "USERDNSDOMAIN", + "USERDOMAIN", + "USERDOMAIN_ROAMINGPROFILE", + "USERNAME", + "USERPROFILE", + "windir", // Enables proxy information to be passed to Curl, the underlying download library in cmake.exe - L"HTTP_PROXY", - L"HTTPS_PROXY", + "HTTP_PROXY", + "HTTPS_PROXY", // Enables find_package(CUDA) in CMake - L"CUDA_PATH", + "CUDA_PATH", // Environmental variable generated automatically by CUDA after installation - L"NVCUDASAMPLES_ROOT", + "NVCUDASAMPLES_ROOT", }; // Flush stdout before launching external process fflush(nullptr); - std::wstring env_cstr; + std::string env_cstr; for (auto&& env_wstring : env_wstrings) { - const Optional value = System::get_environment_variable(Strings::to_utf8(env_wstring)); + const Optional value = System::get_environment_variable(env_wstring); const auto v = value.get(); if (!v || v->empty()) continue; env_cstr.append(env_wstring); - env_cstr.push_back(L'='); - env_cstr.append(Strings::to_utf16(*v)); - env_cstr.push_back(L'\0'); + env_cstr.push_back('='); + env_cstr.append(*v); + env_cstr.push_back('\0'); } - env_cstr.append(Strings::to_utf16(NEW_PATH)); - env_cstr.push_back(L'\0'); + env_cstr.append(NEW_PATH); + env_cstr.push_back('\0'); STARTUPINFOW startup_info; memset(&startup_info, 0, sizeof(STARTUPINFOW)); @@ -161,7 +161,7 @@ namespace vcpkg::System nullptr, FALSE, BELOW_NORMAL_PRIORITY_CLASS | CREATE_UNICODE_ENVIRONMENT, - env_cstr.data(), + Strings::to_utf16(env_cstr).data(), nullptr, &startup_info, &process_info); @@ -366,9 +366,7 @@ namespace vcpkg::System return Strings::to_utf8(ret); } #else - Optional get_registry_string(void* base_hkey, - const CWStringView sub_key, - const CWStringView valuename) + Optional get_registry_string(void* base_hkey, const CStringView sub_key, const CStringView valuename) { return nullopt; } -- cgit v1.2.3 From 558dcb32ca4ef43c35570794bf4cc4fc46f4af6c Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 16 Oct 2017 15:09:02 -0700 Subject: Revert "[system.cpp] Remove usage of std::wstring. Convert at the last step" This reverts commit dfe1f880d4e2a7f23d3b43d42a5d6ac2d68dc135. --- toolsrc/src/vcpkg/base/system.cpp | 102 +++++++++++++++++++------------------- 1 file changed, 52 insertions(+), 50 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/base/system.cpp b/toolsrc/src/vcpkg/base/system.cpp index ac527f9fc..730b22c43 100644 --- a/toolsrc/src/vcpkg/base/system.cpp +++ b/toolsrc/src/vcpkg/base/system.cpp @@ -79,71 +79,71 @@ namespace vcpkg::System static const std::string NEW_PATH = Strings::format( R"(Path=%s;%s;%s\Wbem;%s\WindowsPowerShell\v1.0\)", SYSTEM_32, SYSTEM_ROOT, SYSTEM_32, SYSTEM_32); - std::vector env_wstrings = { - "ALLUSERSPROFILE", - "APPDATA", - "CommonProgramFiles", - "CommonProgramFiles(x86)", - "CommonProgramW6432", - "COMPUTERNAME", - "ComSpec", - "HOMEDRIVE", - "HOMEPATH", - "LOCALAPPDATA", - "LOGONSERVER", - "NUMBER_OF_PROCESSORS", - "OS", - "PATHEXT", - "PROCESSOR_ARCHITECTURE", - "PROCESSOR_ARCHITEW6432", - "PROCESSOR_IDENTIFIER", - "PROCESSOR_LEVEL", - "PROCESSOR_REVISION", - "ProgramData", - "ProgramFiles", - "ProgramFiles(x86)", - "ProgramW6432", - "PROMPT", - "PSModulePath", - "PUBLIC", - "SystemDrive", - "SystemRoot", - "TEMP", - "TMP", - "USERDNSDOMAIN", - "USERDOMAIN", - "USERDOMAIN_ROAMINGPROFILE", - "USERNAME", - "USERPROFILE", - "windir", + std::vector env_wstrings = { + L"ALLUSERSPROFILE", + L"APPDATA", + L"CommonProgramFiles", + L"CommonProgramFiles(x86)", + L"CommonProgramW6432", + L"COMPUTERNAME", + L"ComSpec", + L"HOMEDRIVE", + L"HOMEPATH", + L"LOCALAPPDATA", + L"LOGONSERVER", + L"NUMBER_OF_PROCESSORS", + L"OS", + L"PATHEXT", + L"PROCESSOR_ARCHITECTURE", + L"PROCESSOR_ARCHITEW6432", + L"PROCESSOR_IDENTIFIER", + L"PROCESSOR_LEVEL", + L"PROCESSOR_REVISION", + L"ProgramData", + L"ProgramFiles", + L"ProgramFiles(x86)", + L"ProgramW6432", + L"PROMPT", + L"PSModulePath", + L"PUBLIC", + L"SystemDrive", + L"SystemRoot", + L"TEMP", + L"TMP", + L"USERDNSDOMAIN", + L"USERDOMAIN", + L"USERDOMAIN_ROAMINGPROFILE", + L"USERNAME", + L"USERPROFILE", + L"windir", // Enables proxy information to be passed to Curl, the underlying download library in cmake.exe - "HTTP_PROXY", - "HTTPS_PROXY", + L"HTTP_PROXY", + L"HTTPS_PROXY", // Enables find_package(CUDA) in CMake - "CUDA_PATH", + L"CUDA_PATH", // Environmental variable generated automatically by CUDA after installation - "NVCUDASAMPLES_ROOT", + L"NVCUDASAMPLES_ROOT", }; // Flush stdout before launching external process fflush(nullptr); - std::string env_cstr; + std::wstring env_cstr; for (auto&& env_wstring : env_wstrings) { - const Optional value = System::get_environment_variable(env_wstring); + const Optional value = System::get_environment_variable(Strings::to_utf8(env_wstring)); const auto v = value.get(); if (!v || v->empty()) continue; env_cstr.append(env_wstring); - env_cstr.push_back('='); - env_cstr.append(*v); - env_cstr.push_back('\0'); + env_cstr.push_back(L'='); + env_cstr.append(Strings::to_utf16(*v)); + env_cstr.push_back(L'\0'); } - env_cstr.append(NEW_PATH); - env_cstr.push_back('\0'); + env_cstr.append(Strings::to_utf16(NEW_PATH)); + env_cstr.push_back(L'\0'); STARTUPINFOW startup_info; memset(&startup_info, 0, sizeof(STARTUPINFOW)); @@ -161,7 +161,7 @@ namespace vcpkg::System nullptr, FALSE, BELOW_NORMAL_PRIORITY_CLASS | CREATE_UNICODE_ENVIRONMENT, - Strings::to_utf16(env_cstr).data(), + env_cstr.data(), nullptr, &startup_info, &process_info); @@ -366,7 +366,9 @@ namespace vcpkg::System return Strings::to_utf8(ret); } #else - Optional get_registry_string(void* base_hkey, const CStringView sub_key, const CStringView valuename) + Optional get_registry_string(void* base_hkey, + const CWStringView sub_key, + const CWStringView valuename) { return nullopt; } -- cgit v1.2.3 From e5867d1d63606cef5c53a764e31ce05385f36497 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 16 Oct 2017 15:26:28 -0700 Subject: CWStringView->CStringView, std::wstring->std::string --- toolsrc/src/vcpkg/base/system.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/base/system.cpp b/toolsrc/src/vcpkg/base/system.cpp index 730b22c43..b04f79414 100644 --- a/toolsrc/src/vcpkg/base/system.cpp +++ b/toolsrc/src/vcpkg/base/system.cpp @@ -366,9 +366,7 @@ namespace vcpkg::System return Strings::to_utf8(ret); } #else - Optional get_registry_string(void* base_hkey, - const CWStringView sub_key, - const CWStringView valuename) + Optional get_registry_string(void* base_hkey, const CStringView sub_key, const CStringView valuename) { return nullopt; } -- cgit v1.2.3 From fb1f5f87fb0cbb666882586271581d57c5e0ef76 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 16 Oct 2017 15:37:14 -0700 Subject: Add timer to `vcpkg build` --- toolsrc/src/vcpkg/build.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index 3d3bcb5fe..cf16c8f9c 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -69,7 +69,10 @@ namespace vcpkg::Build::Command const Build::BuildPackageConfig build_config{ *scf->core_paragraph, spec.triplet(), paths.port_dir(spec), build_package_options}; + const auto build_timer = Chrono::ElapsedTime::create_started(); const auto result = Build::build_package(paths, build_config, status_db); + System::println("Elapsed time for package %s: %s", spec.to_string(), build_timer.to_string()); + if (result.code == BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES) { System::println(System::Color::error, -- cgit v1.2.3 From 7ed8d4f75e903fdad4c02b4e784f2f4bcb30a3b0 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 16 Oct 2017 17:24:17 -0700 Subject: Don't warn for outdated vcpkg if command is autocomplete --- toolsrc/src/vcpkg.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg.cpp b/toolsrc/src/vcpkg.cpp index e1e2240e7..b4c2d0fe2 100644 --- a/toolsrc/src/vcpkg.cpp +++ b/toolsrc/src/vcpkg.cpp @@ -106,7 +106,11 @@ static void inner(const VcpkgCmdArguments& args) const int exit_code = chdir(paths.root.c_str()); #endif Checks::check_exit(VCPKG_LINE_INFO, exit_code == 0, "Changing the working dir failed"); - Commands::Version::warn_if_vcpkg_version_mismatch(paths); + + if (args.command != "autocomplete") + { + Commands::Version::warn_if_vcpkg_version_mismatch(paths); + } if (const auto command_function = find_command(Commands::get_available_commands_type_b())) { -- cgit v1.2.3 From 947c6cac332cabb58452178d563a2a0c26def35e Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 17 Oct 2017 02:30:27 -0700 Subject: `autocomplete` Consider private commands if no public commands match --- toolsrc/src/vcpkg/commands.autocomplete.cpp | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/commands.autocomplete.cpp b/toolsrc/src/vcpkg/commands.autocomplete.cpp index addb9edaf..fcbe73835 100644 --- a/toolsrc/src/vcpkg/commands.autocomplete.cpp +++ b/toolsrc/src/vcpkg/commands.autocomplete.cpp @@ -39,7 +39,8 @@ namespace vcpkg::Commands::Autocomplete { const std::string requested_command = match[1].str(); - std::vector valid_commands = { + // First try public commands + std::vector public_commands = { "install", "search", "remove", @@ -57,11 +58,31 @@ namespace vcpkg::Commands::Autocomplete "contact", }; - Util::unstable_keep_if(valid_commands, [&](const std::string& s) { + Util::unstable_keep_if(public_commands, [&](const std::string& s) { return Strings::case_insensitive_ascii_starts_with(s, requested_command); }); - output_sorted_results_and_exit(VCPKG_LINE_INFO, std::move(valid_commands)); + if (!public_commands.empty()) + { + output_sorted_results_and_exit(VCPKG_LINE_INFO, std::move(public_commands)); + } + + // If no public commands match, try private commands + std::vector private_commands = { + "build", + "buildexternal", + "ci", + "depend-info", + "env", + "import", + "portsdiff", + }; + + Util::unstable_keep_if(private_commands, [&](const std::string& s) { + return Strings::case_insensitive_ascii_starts_with(s, requested_command); + }); + + output_sorted_results_and_exit(VCPKG_LINE_INFO, std::move(private_commands)); } // Handles vcpkg install package: -- cgit v1.2.3 From 3c4f620dbc7ef0005c694ab758c6c7d5e42dbe93 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 17 Oct 2017 02:59:55 -0700 Subject: `autocomplete` Add autocompletion for `vcpkg integrate` --- toolsrc/include/vcpkg/commands.h | 1 + toolsrc/src/vcpkg/commands.autocomplete.cpp | 1 + toolsrc/src/vcpkg/commands.integrate.cpp | 33 ++++++++++++++++++++++++++--- 3 files changed, 32 insertions(+), 3 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/commands.h b/toolsrc/include/vcpkg/commands.h index e00812c98..d9ebad2c4 100644 --- a/toolsrc/include/vcpkg/commands.h +++ b/toolsrc/include/vcpkg/commands.h @@ -75,6 +75,7 @@ namespace vcpkg::Commands namespace Integrate { extern const char* const INTEGRATE_COMMAND_HELPSTRING; + extern const CommandStructure COMMAND_STRUCTURE; void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); } diff --git a/toolsrc/src/vcpkg/commands.autocomplete.cpp b/toolsrc/src/vcpkg/commands.autocomplete.cpp index fcbe73835..e36bf8430 100644 --- a/toolsrc/src/vcpkg/commands.autocomplete.cpp +++ b/toolsrc/src/vcpkg/commands.autocomplete.cpp @@ -124,6 +124,7 @@ namespace vcpkg::Commands::Autocomplete CommandEntry{"install", R"###(^install\s(.*\s|)(\S*)$)###", Install::COMMAND_STRUCTURE}, CommandEntry{"edit", R"###(^edit\s(.*\s|)(\S*)$)###", Edit::COMMAND_STRUCTURE}, CommandEntry{"remove", R"###(^remove\s(.*\s|)(\S*)$)###", Remove::COMMAND_STRUCTURE}, + CommandEntry{"integrate", R"###(^integrate(\s+)(\S*)$)###", Integrate::COMMAND_STRUCTURE}, }; for (auto&& command : COMMANDS) diff --git a/toolsrc/src/vcpkg/commands.integrate.cpp b/toolsrc/src/vcpkg/commands.integrate.cpp index 0d185476e..c8fa275ab 100644 --- a/toolsrc/src/vcpkg/commands.integrate.cpp +++ b/toolsrc/src/vcpkg/commands.integrate.cpp @@ -326,6 +326,33 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console " vcpkg integrate remove Remove user-wide integration\n" " vcpkg integrate project Generate a referencing nuget package for individual VS project use\n"; + namespace Subcommand + { + static const std::string INSTALL = "install"; + static const std::string REMOVE = "remove"; + static const std::string PROJECT = "project"; + } + + static const std::array INSTALL_SWITCHES; + + static const std::array INSTALL_SETTINGS; + + static std::vector valid_arguments(const VcpkgPaths&) + { + return {Subcommand::INSTALL, Subcommand::REMOVE, Subcommand::PROJECT}; + } + + const CommandStructure COMMAND_STRUCTURE = { + Strings::format("Commands:\n" + "%s", + INTEGRATE_COMMAND_HELPSTRING), + 1, + 1, + INSTALL_SWITCHES, + INSTALL_SETTINGS, + &valid_arguments, + }; + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { static const std::string EXAMPLE = Strings::format("Commands:\n" @@ -335,15 +362,15 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console args.check_and_get_optional_command_arguments({}); #if defined(_WIN32) - if (args.command_arguments[0] == "install") + if (args.command_arguments[0] == Subcommand::INSTALL) { return integrate_install(paths); } - if (args.command_arguments[0] == "remove") + if (args.command_arguments[0] == Subcommand::REMOVE) { return integrate_remove(paths.get_filesystem()); } - if (args.command_arguments[0] == "project") + if (args.command_arguments[0] == Subcommand::PROJECT) { return integrate_project(paths); } -- cgit v1.2.3 From a536a4630261684370cd1b43b88e8121fe50f9ad Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 17 Oct 2017 03:07:39 -0700 Subject: `remove`: Consistency renames --- toolsrc/src/vcpkg/remove.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/remove.cpp b/toolsrc/src/vcpkg/remove.cpp index 2ec32855a..6f555b9b8 100644 --- a/toolsrc/src/vcpkg/remove.cpp +++ b/toolsrc/src/vcpkg/remove.cpp @@ -169,14 +169,14 @@ namespace vcpkg::Remove static const std::string OPTION_DRY_RUN = "--dry-run"; static const std::string OPTION_OUTDATED = "--outdated"; - static const std::array REMOVE_SWITCHES = { + static const std::array SWITCHES = { OPTION_PURGE, OPTION_NO_PURGE, OPTION_RECURSE, OPTION_DRY_RUN, OPTION_OUTDATED, }; - static const std::array REMOVE_SETTINGS; + static const std::array SETTINGS; static std::vector valid_arguments(const VcpkgPaths& paths) { @@ -190,8 +190,8 @@ namespace vcpkg::Remove "remove zlib zlib:x64-windows curl boost", 1, SIZE_MAX, - REMOVE_SWITCHES, - REMOVE_SETTINGS, + SWITCHES, + SETTINGS, &valid_arguments, }; -- cgit v1.2.3 From 87296823ac9cc939c233caf7c02585b5fe6d3df7 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 17 Oct 2017 12:41:34 -0700 Subject: [cmake] Update to 3.9.4 (was 3.9.3) --- toolsrc/src/vcpkg/vcpkgpaths.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index 90f9cb00b..486fff40e 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -105,10 +105,10 @@ namespace vcpkg static fs::path get_cmake_path(const fs::path& downloads_folder, const fs::path& scripts_folder) { - static constexpr std::array EXPECTED_VERSION = {3, 9, 3}; + static constexpr std::array EXPECTED_VERSION = {3, 9, 4}; static const std::string VERSION_CHECK_ARGUMENTS = "--version"; - const fs::path downloaded_copy = downloads_folder / "cmake-3.9.3-win32-x86" / "bin" / "cmake.exe"; + const fs::path downloaded_copy = downloads_folder / "cmake-3.9.4-win32-x86" / "bin" / "cmake.exe"; const std::vector from_path = Files::find_from_PATH("cmake"); std::vector candidate_paths; -- cgit v1.2.3 From fa4e54a37356ad0200ce6387541ef78997b8a87e Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 17 Oct 2017 14:05:55 -0700 Subject: [git] Update to 2.14.2.3 (was 2.14.1) --- toolsrc/src/vcpkg/vcpkgpaths.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index 486fff40e..8da718e87 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -151,10 +151,10 @@ namespace vcpkg fs::path get_git_path(const fs::path& downloads_folder, const fs::path& scripts_folder) { - static constexpr std::array EXPECTED_VERSION = {2, 14, 1}; + static constexpr std::array EXPECTED_VERSION = {2, 14, 2}; static const std::string VERSION_CHECK_ARGUMENTS = "--version"; - const fs::path downloaded_copy = downloads_folder / "MinGit-2.14.1-32-bit" / "cmd" / "git.exe"; + const fs::path downloaded_copy = downloads_folder / "MinGit-2.14.2.3-32-bit" / "cmd" / "git.exe"; const std::vector from_path = Files::find_from_PATH("git"); std::vector candidate_paths; -- cgit v1.2.3 From e9ba8b0ecbe5c49cda2710acaae0983dfe2552f9 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 17 Oct 2017 14:19:48 -0700 Subject: [nuget] Update to 4.4.0 (was 4.3.0) --- toolsrc/src/vcpkg/vcpkgpaths.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index 8da718e87..34c661afd 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -131,9 +131,9 @@ namespace vcpkg fs::path get_nuget_path(const fs::path& downloads_folder, const fs::path& scripts_folder) { - static constexpr std::array EXPECTED_VERSION = {4, 3, 0}; + static constexpr std::array EXPECTED_VERSION = {4, 4, 0}; - const fs::path downloaded_copy = downloads_folder / "nuget-4.3.0" / "nuget.exe"; + const fs::path downloaded_copy = downloads_folder / "nuget-4.4.0" / "nuget.exe"; const std::vector from_path = Files::find_from_PATH("nuget"); std::vector candidate_paths; -- cgit v1.2.3 From ae3fe7cd16c82b794d5074104cf078afc1a12c7d Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Tue, 17 Oct 2017 14:42:05 -0700 Subject: [boost] Add feature packages for regex-icu, locale-icu, and python --- toolsrc/src/vcpkg/install.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp index adbd8c943..70757ff38 100644 --- a/toolsrc/src/vcpkg/install.cpp +++ b/toolsrc/src/vcpkg/install.cpp @@ -591,11 +591,12 @@ namespace vcpkg::Install const Build::BuildPackageOptions install_plan_options = {Build::to_use_head_version(use_head_version), Build::to_allow_downloads(!no_downloads)}; + // Note: action_plan will hold raw pointers to SourceControlFiles from this map + std::unordered_map scf_map; std::vector action_plan; if (GlobalState::feature_packages) { - std::unordered_map scf_map; auto all_ports = Paragraphs::load_all_ports(paths.get_filesystem(), paths.ports); for (auto&& port : all_ports) { -- cgit v1.2.3 From d7f6a7e4a8e09ce54c18f16dea9f6d3fe9d0ac77 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 17 Oct 2017 16:12:35 -0700 Subject: Update CHANGELOG and bump version to v0.0.92 --- toolsrc/VERSION.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/VERSION.txt b/toolsrc/VERSION.txt index 04ab0d2c9..af0276f0b 100644 --- a/toolsrc/VERSION.txt +++ b/toolsrc/VERSION.txt @@ -1 +1 @@ -"0.0.91" \ No newline at end of file +"0.0.92" \ No newline at end of file -- cgit v1.2.3 From 7a4023f1dcb3686d7d8deaf9e40cc0283e508b08 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 18 Oct 2017 14:47:04 -0700 Subject: [autocomplete] Don't try to autocomplete triplets to --options --- toolsrc/src/vcpkg/commands.autocomplete.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/commands.autocomplete.cpp b/toolsrc/src/vcpkg/commands.autocomplete.cpp index e36bf8430..410bfcd0d 100644 --- a/toolsrc/src/vcpkg/commands.autocomplete.cpp +++ b/toolsrc/src/vcpkg/commands.autocomplete.cpp @@ -134,7 +134,8 @@ namespace vcpkg::Commands::Autocomplete const auto prefix = match[2].str(); std::vector results; - if (Strings::case_insensitive_ascii_starts_with(prefix, "-")) + const bool is_option = Strings::case_insensitive_ascii_starts_with(prefix, "-"); + if (is_option) { results = Util::fmap(command.structure.switches, [](auto&& s) -> std::string { return s; }); } @@ -147,7 +148,7 @@ namespace vcpkg::Commands::Autocomplete return Strings::case_insensitive_ascii_starts_with(s, prefix); }); - if (command.name == "install" && results.size() == 1) + if (command.name == "install" && results.size() == 1 && !is_option) { const auto port_at_each_triplet = combine_port_with_triplets(results[0], paths.get_available_triplets()); -- cgit v1.2.3 From ecdfd3c8e3a4b924bfad5b70f6557dd9f337bd1c Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 18 Oct 2017 19:04:14 -0700 Subject: ci now accepts multiple triplets. Refactoring to accomodate --- toolsrc/include/vcpkg/install.h | 28 +++++++----- toolsrc/src/vcpkg/commands.ci.cpp | 49 +++++++++++++++++---- toolsrc/src/vcpkg/install.cpp | 93 +++++++++++++++++++++------------------ 3 files changed, 108 insertions(+), 62 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/install.h b/toolsrc/include/vcpkg/install.h index db6055f4f..809befb16 100644 --- a/toolsrc/include/vcpkg/install.h +++ b/toolsrc/include/vcpkg/install.h @@ -17,13 +17,22 @@ namespace vcpkg::Install inline KeepGoing to_keep_going(const bool value) { return value ? KeepGoing::YES : KeepGoing::NO; } - enum class PrintSummary + struct SpecSummary { - NO = 0, - YES + explicit SpecSummary(const PackageSpec& spec); + + PackageSpec spec; + Build::BuildResult result; + std::string timing; }; - inline PrintSummary to_print_summary(const bool value) { return value ? PrintSummary::YES : PrintSummary::NO; } + struct InstallSummary + { + std::vector results; + std::string total_elapsed_time; + + void print() const; + }; struct InstallDir { @@ -58,12 +67,11 @@ namespace vcpkg::Install const BinaryControlFile& binary_paragraph, StatusParagraphs* status_db); - void perform_and_exit_ex(const std::vector& action_plan, - const Build::BuildPackageOptions& install_plan_options, - const KeepGoing keep_going, - const PrintSummary print_summary, - const VcpkgPaths& paths, - StatusParagraphs& status_db); + InstallSummary perform(const std::vector& action_plan, + const Build::BuildPackageOptions& install_plan_options, + const KeepGoing keep_going, + const VcpkgPaths& paths, + StatusParagraphs& status_db); extern const CommandStructure COMMAND_STRUCTURE; diff --git a/toolsrc/src/vcpkg/commands.ci.cpp b/toolsrc/src/vcpkg/commands.ci.cpp index 1c98d1d83..ffeaad790 100644 --- a/toolsrc/src/vcpkg/commands.ci.cpp +++ b/toolsrc/src/vcpkg/commands.ci.cpp @@ -30,15 +30,10 @@ namespace vcpkg::Commands::CI }); } - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) + static Install::InstallSummary run_ci_on_triplet(const Triplet& triplet, const VcpkgPaths& paths) { - static const std::string EXAMPLE = Help::create_example_string("ci x64-windows"); - args.check_max_arg_count(1, EXAMPLE); - 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 specs = load_all_package_specs(paths.get_filesystem(), paths.ports, triplet); StatusParagraphs status_db = database_load_check(paths); @@ -54,8 +49,44 @@ namespace vcpkg::Commands::CI return Dependencies::AnyAction(std::move(install_action)); }); - Install::perform_and_exit_ex( - action_plan, install_plan_options, Install::KeepGoing::YES, Install::PrintSummary::YES, paths, status_db); + return Install::perform(action_plan, install_plan_options, Install::KeepGoing::YES, paths, status_db); + } + + struct TripletAndSummary + { + Triplet triplet; + Install::InstallSummary summary; + }; + + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) + { + static const std::string EXAMPLE = Help::create_example_string("ci x64-windows"); + args.check_and_get_optional_command_arguments({}); + + std::vector triplets; + for (const std::string& triplet : args.command_arguments) + { + triplets.push_back(Triplet::from_canonical_name(triplet)); + } + + if (triplets.empty()) + { + triplets.push_back(default_triplet); + } + + std::vector results; + for (const Triplet& triplet : triplets) + { + Install::InstallSummary summary = run_ci_on_triplet(triplet, paths); + results.push_back({triplet, std::move(summary)}); + } + + for (auto&& result : results) + { + System::println("\nTriplet: %s", result.triplet); + System::println("Total elapsed time: %s", result.summary.total_elapsed_time); + result.summary.print(); + } Checks::exit_success(VCPKG_LINE_INFO); } diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp index 70757ff38..bd924fcba 100644 --- a/toolsrc/src/vcpkg/install.cpp +++ b/toolsrc/src/vcpkg/install.cpp @@ -444,15 +444,41 @@ namespace vcpkg::Install } } - void perform_and_exit_ex(const std::vector& action_plan, - const Build::BuildPackageOptions& install_plan_options, - const KeepGoing keep_going, - const PrintSummary print_summary, - const VcpkgPaths& paths, - StatusParagraphs& status_db) + void InstallSummary::print() const { - std::vector results; - std::vector timing; + System::println("RESULTS"); + + for (const SpecSummary& result : this->results) + { + System::println(" %s: %s: %s", result.spec, Build::to_string(result.result), result.timing); + } + + std::map summary; + for (const BuildResult& v : Build::BUILD_RESULT_VALUES) + { + summary[v] = 0; + } + + for (const SpecSummary& r : this->results) + { + summary[r.result]++; + } + + System::println("\nSUMMARY"); + for (const std::pair& entry : summary) + { + System::println(" %s: %d", Build::to_string(entry.first), entry.second); + } + } + + InstallSummary perform(const std::vector& action_plan, + const Build::BuildPackageOptions& install_plan_options, + const KeepGoing keep_going, + const VcpkgPaths& paths, + StatusParagraphs& status_db) + { + std::vector results; + const auto timer = Chrono::ElapsedTime::create_started(); size_t counter = 0; const size_t package_count = action_plan.size(); @@ -462,11 +488,11 @@ namespace vcpkg::Install const auto build_timer = Chrono::ElapsedTime::create_started(); counter++; - const std::string display_name = action.spec().to_string(); + const PackageSpec& spec = action.spec(); + const std::string display_name = spec.to_string(); System::println("Starting package %d/%d: %s", counter, package_count, display_name); - timing.push_back("0"); - results.push_back(BuildResult::NULLVALUE); + results.push_back(SpecSummary{spec}); if (const auto install_action = action.install_plan.get()) { @@ -478,7 +504,7 @@ namespace vcpkg::Install Checks::exit_fail(VCPKG_LINE_INFO); } - results.back() = result; + results.back().result = result; } else if (const auto remove_action = action.remove_plan.get()) { @@ -490,38 +516,11 @@ namespace vcpkg::Install Checks::unreachable(VCPKG_LINE_INFO); } - timing.back() = build_timer.to_string(); + results.back().timing = build_timer.to_string(); System::println("Elapsed time for package %s: %s", display_name, build_timer.to_string()); } - System::println("Total time taken: %s", timer.to_string()); - - if (print_summary == PrintSummary::YES) - { - for (size_t i = 0; i < results.size(); i++) - { - System::println("%s: %s: %s", action_plan[i].spec(), Build::to_string(results[i]), timing[i]); - } - - std::map summary; - for (const BuildResult& v : Build::BUILD_RESULT_VALUES) - { - summary[v] = 0; - } - - for (const BuildResult& r : results) - { - summary[r]++; - } - - System::println("\n\nSUMMARY"); - for (const std::pair& entry : summary) - { - System::println(" %s: %d", Build::to_string(entry.first), entry.second); - } - } - - Checks::exit_success(VCPKG_LINE_INFO); + return InstallSummary{results, timer.to_string()}; } static const std::string OPTION_DRY_RUN = "--dry-run"; @@ -583,7 +582,6 @@ namespace vcpkg::Install const bool no_downloads = options.find(OPTION_NO_DOWNLOADS) != options.cend(); const bool is_recursive = options.find(OPTION_RECURSE) != options.cend(); const KeepGoing keep_going = to_keep_going(options.find(OPTION_KEEP_GOING) != options.cend()); - const PrintSummary print_summary = to_print_summary(keep_going == KeepGoing::YES); // create the plan StatusParagraphs status_db = database_load_check(paths); @@ -635,8 +633,17 @@ namespace vcpkg::Install Checks::exit_success(VCPKG_LINE_INFO); } - perform_and_exit_ex(action_plan, install_plan_options, keep_going, print_summary, paths, status_db); + const InstallSummary summary = perform(action_plan, install_plan_options, keep_going, paths, status_db); + + System::println("\nTotal elapsed time: %s", summary.total_elapsed_time); + + if (keep_going == KeepGoing::YES) + { + summary.print(); + } Checks::exit_success(VCPKG_LINE_INFO); } + + SpecSummary::SpecSummary(const PackageSpec& spec) : spec(spec), result(BuildResult::NULLVALUE), timing("0") {} } -- cgit v1.2.3 From 9964d84b53442ef4f555cfe090ed22503b90d213 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 18 Oct 2017 19:20:11 -0700 Subject: Add extra checks on the return Visual Studio instances --- toolsrc/src/vcpkg/vcpkgpaths.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index 34c661afd..2f2dd877e 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -330,10 +330,19 @@ namespace vcpkg VCPKG_LINE_INFO, ec_data.exit_code == 0, "Could not run script to detect Visual Studio instances"); const std::vector instances_as_strings = Strings::split(ec_data.output, "\n"); + Checks::check_exit( + VCPKG_LINE_INFO, !instances_as_strings.empty(), "Could not detect any Visual Studio instances"); + std::vector output; for (const std::string& instance_as_string : instances_as_strings) { const std::vector split = Strings::split(instance_as_string, "::"); + Checks::check_exit(VCPKG_LINE_INFO, + split.size() == 4, + "Invalid Visual Studio instance format.\n" + "Expected: PreferenceWeight::ReleaseType::Version::PathToVisualStudio\n" + "Actual : %s", + instance_as_string); output.push_back({split.at(3), split.at(2), split.at(1), split.at(0)}); } -- cgit v1.2.3 From b1d5d8e8baf4bd5132de4415a0168432600ce998 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 19 Oct 2017 19:38:23 -0700 Subject: Introduce Strings::replace_all() --- toolsrc/include/vcpkg/base/strings.h | 2 ++ toolsrc/src/vcpkg/base/strings.cpp | 11 +++++++++++ 2 files changed, 13 insertions(+) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/base/strings.h b/toolsrc/include/vcpkg/base/strings.h index d263e3b6b..5b03286de 100644 --- a/toolsrc/include/vcpkg/base/strings.h +++ b/toolsrc/include/vcpkg/base/strings.h @@ -76,6 +76,8 @@ namespace vcpkg::Strings return join(delimiter, v, [](const Element& x) -> const Element& { return x; }); } + std::string replace_all(std::string&& s, const std::string& search, const std::string& rep); + void trim(std::string* s); std::string trimmed(const std::string& s); diff --git a/toolsrc/src/vcpkg/base/strings.cpp b/toolsrc/src/vcpkg/base/strings.cpp index af41eed9a..36efc3adc 100644 --- a/toolsrc/src/vcpkg/base/strings.cpp +++ b/toolsrc/src/vcpkg/base/strings.cpp @@ -114,6 +114,17 @@ namespace vcpkg::Strings #endif } + std::string replace_all(std::string&& s, const std::string& search, const std::string& rep) + { + size_t pos = 0; + while ((pos = s.find(search, pos)) != std::string::npos) + { + s.replace(pos, search.size(), rep); + pos += rep.size(); + } + return std::move(s); + } + void trim(std::string* s) { s->erase(std::find_if_not(s->rbegin(), s->rend(), details::isspace).base(), s->end()); -- cgit v1.2.3 From 8cefb25bcb7edaedd20d8aa170b2e1b945fd1762 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 19 Oct 2017 19:48:46 -0700 Subject: Use Strings::replace_all() instead of std::regex_replace() --- toolsrc/src/vcpkg/commands.integrate.cpp | 8 ++++---- toolsrc/src/vcpkg/export.cpp | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/commands.integrate.cpp b/toolsrc/src/vcpkg/commands.integrate.cpp index c8fa275ab..27e563cfa 100644 --- a/toolsrc/src/vcpkg/commands.integrate.cpp +++ b/toolsrc/src/vcpkg/commands.integrate.cpp @@ -93,9 +93,9 @@ namespace vcpkg::Commands::Integrate )"; - std::string content = std::regex_replace(CONTENT_TEMPLATE, std::regex("@NUGET_ID@"), nuget_id); - content = std::regex_replace(content, std::regex("@VCPKG_DIR@"), vcpkg_root_dir.string()); - content = std::regex_replace(content, std::regex("@VERSION@"), nupkg_version); + std::string content = Strings::replace_all(CONTENT_TEMPLATE, "@NUGET_ID@", nuget_id); + content = Strings::replace_all(std::move(content), "@VCPKG_DIR@", vcpkg_root_dir.string()); + content = Strings::replace_all(std::move(content), "@VERSION@", nupkg_version); return content; } @@ -308,7 +308,7 @@ CMake projects should use: "-DCMAKE_TOOLCHAIN_FILE=%s")", System::println(System::Color::success, "Created nupkg: %s", nuget_package.string()); auto source_path = buildsystems_dir.u8string(); - source_path = std::regex_replace(source_path, std::regex("`"), "``"); + source_path = Strings::replace_all(std::move(source_path), "`", "``"); System::println(R"( With a project open, go to Tools->NuGet Package Manager->Package Manager Console and paste: diff --git a/toolsrc/src/vcpkg/export.cpp b/toolsrc/src/vcpkg/export.cpp index 5e27d4126..f0a3b23d0 100644 --- a/toolsrc/src/vcpkg/export.cpp +++ b/toolsrc/src/vcpkg/export.cpp @@ -44,12 +44,12 @@ namespace vcpkg::Export )"; - std::string nuspec_file_content = std::regex_replace(CONTENT_TEMPLATE, std::regex("@NUGET_ID@"), nuget_id); - nuspec_file_content = std::regex_replace(nuspec_file_content, std::regex("@VERSION@"), nupkg_version); + std::string nuspec_file_content = Strings::replace_all(CONTENT_TEMPLATE, "@NUGET_ID@", nuget_id); + nuspec_file_content = Strings::replace_all(std::move(nuspec_file_content), "@VERSION@", nupkg_version); nuspec_file_content = - std::regex_replace(nuspec_file_content, std::regex("@RAW_EXPORTED_DIR@"), raw_exported_dir); + Strings::replace_all(std::move(nuspec_file_content), "@RAW_EXPORTED_DIR@", raw_exported_dir); nuspec_file_content = - std::regex_replace(nuspec_file_content, std::regex("@TARGETS_REDIRECT_PATH@"), targets_redirect_path); + Strings::replace_all(std::move(nuspec_file_content), "@TARGETS_REDIRECT_PATH@", targets_redirect_path); return nuspec_file_content; } -- cgit v1.2.3 From 50ae9eec872a0802d2450b4ae2d640475d0d7889 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 19 Oct 2017 19:50:23 -0700 Subject: Do not depend on newlines when getting output from powershell --- toolsrc/include/vcpkg/base/system.h | 2 +- toolsrc/src/vcpkg/base/system.cpp | 16 ++++++++++++++-- toolsrc/src/vcpkg/vcpkgpaths.cpp | 14 ++++++-------- 3 files changed, 21 insertions(+), 11 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/base/system.h b/toolsrc/include/vcpkg/base/system.h index b396ef293..e0d3264e2 100644 --- a/toolsrc/include/vcpkg/base/system.h +++ b/toolsrc/include/vcpkg/base/system.h @@ -22,7 +22,7 @@ namespace vcpkg::System ExitCodeAndOutput cmd_execute_and_capture_output(const CStringView cmd_line); - std::string create_powershell_script_cmd(const fs::path& script_path, const CStringView args = ""); + ExitCodeAndOutput powershell_execute_and_capture_output(const fs::path& script_path, const CStringView args = ""); enum class Color { diff --git a/toolsrc/src/vcpkg/base/system.cpp b/toolsrc/src/vcpkg/base/system.cpp index b04f79414..a1bc9daf6 100644 --- a/toolsrc/src/vcpkg/base/system.cpp +++ b/toolsrc/src/vcpkg/base/system.cpp @@ -269,11 +269,23 @@ namespace vcpkg::System #endif } - std::string create_powershell_script_cmd(const fs::path& script_path, const CStringView args) + ExitCodeAndOutput powershell_execute_and_capture_output(const fs::path& script_path, const CStringView args) { // TODO: switch out ExecutionPolicy Bypass with "Remove Mark Of The Web" code and restore RemoteSigned - return Strings::format( + const std::string cmd = Strings::format( R"(powershell -NoProfile -ExecutionPolicy Bypass -Command "& {& '%s' %s}")", script_path.u8string(), args); + + auto rc = System::cmd_execute_and_capture_output(cmd); + + // Remove newline from all output. + // Powershell returns newlines when it hits the column count of the console. + // For example, this is 80 in cmd on Windows 7. If the expected output is longer than 80 lines, we get + // newlines in-between the data. + // To solve this, we design our interaction with powershell to not depend on newlines, + // and then strip all newlines here. + rc.output = Strings::replace_all(std::move(rc.output), "\n", ""); + + return rc; } void println() { putchar('\n'); } diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index 2f2dd877e..ef9e383bc 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -74,9 +74,8 @@ namespace vcpkg tool_name, version_as_string); const fs::path script = scripts_folder / "fetchDependency.ps1"; - const auto install_cmd = - System::create_powershell_script_cmd(script, Strings::format("-Dependency %s", tool_name)); - const System::ExitCodeAndOutput rc = System::cmd_execute_and_capture_output(install_cmd); + const System::ExitCodeAndOutput rc = + System::powershell_execute_and_capture_output(script, Strings::format("-Dependency %s", tool_name)); if (rc.exit_code) { System::println(System::Color::error, @@ -324,14 +323,13 @@ namespace vcpkg static std::vector get_visual_studio_instances(const VcpkgPaths& paths) { const fs::path script = paths.scripts / "findVisualStudioInstallationInstances.ps1"; - const std::string cmd = System::create_powershell_script_cmd(script); - const System::ExitCodeAndOutput ec_data = System::cmd_execute_and_capture_output(cmd); + const System::ExitCodeAndOutput ec_data = System::powershell_execute_and_capture_output(script); Checks::check_exit( VCPKG_LINE_INFO, ec_data.exit_code == 0, "Could not run script to detect Visual Studio instances"); - const std::vector instances_as_strings = Strings::split(ec_data.output, "\n"); + const std::vector instances_as_strings = Strings::split(ec_data.output, "::"); Checks::check_exit( - VCPKG_LINE_INFO, !instances_as_strings.empty(), "Could not detect any Visual Studio instances"); + VCPKG_LINE_INFO, !instances_as_strings.empty(), "Could not detect any Visual Studio instances.\n"); std::vector output; for (const std::string& instance_as_string : instances_as_strings) @@ -341,7 +339,7 @@ namespace vcpkg split.size() == 4, "Invalid Visual Studio instance format.\n" "Expected: PreferenceWeight::ReleaseType::Version::PathToVisualStudio\n" - "Actual : %s", + "Actual : %s\n", instance_as_string); output.push_back({split.at(3), split.at(2), split.at(1), split.at(0)}); } -- cgit v1.2.3 From 7c0b541cfd892dd0264273dbdfea8bda48bddcd1 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 19 Oct 2017 21:30:12 -0700 Subject: Update CHANGELOG and bump version to v0.0.93 --- toolsrc/VERSION.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/VERSION.txt b/toolsrc/VERSION.txt index af0276f0b..f439c6467 100644 --- a/toolsrc/VERSION.txt +++ b/toolsrc/VERSION.txt @@ -1 +1 @@ -"0.0.92" \ No newline at end of file +"0.0.93" \ No newline at end of file -- cgit v1.2.3 From 7fb0342b8a16b43ce9887fcc879a2321954646be Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 19 Oct 2017 21:34:58 -0700 Subject: [system.h] Naming scheme fixes --- toolsrc/include/vcpkg/base/system.h | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/base/system.h b/toolsrc/include/vcpkg/base/system.h index e0d3264e2..a696bf3ae 100644 --- a/toolsrc/include/vcpkg/base/system.h +++ b/toolsrc/include/vcpkg/base/system.h @@ -38,27 +38,27 @@ namespace vcpkg::System void println(const Color c, const CStringView message); template - void print(const char* messageTemplate, const Arg1& messageArg1, const Args&... messageArgs) + void print(const char* message_template, const Arg1& message_arg1, const Args&... message_args) { - return System::print(Strings::format(messageTemplate, messageArg1, messageArgs...)); + return System::print(Strings::format(message_template, message_arg1, message_args...)); } template - void print(const Color c, const char* messageTemplate, const Arg1& messageArg1, const Args&... messageArgs) + void print(const Color c, const char* message_template, const Arg1& message_arg1, const Args&... message_args) { - return System::print(c, Strings::format(messageTemplate, messageArg1, messageArgs...)); + return System::print(c, Strings::format(message_template, message_arg1, message_args...)); } template - void println(const char* messageTemplate, const Arg1& messageArg1, const Args&... messageArgs) + void println(const char* message_template, const Arg1& message_arg1, const Args&... message_args) { - return System::println(Strings::format(messageTemplate, messageArg1, messageArgs...)); + return System::println(Strings::format(message_template, message_arg1, message_args...)); } template - void println(const Color c, const char* messageTemplate, const Arg1& messageArg1, const Args&... messageArgs) + void println(const Color c, const char* message_template, const Arg1& message_arg1, const Args&... message_args) { - return System::println(c, Strings::format(messageTemplate, messageArg1, messageArgs...)); + return System::println(c, Strings::format(message_template, message_arg1, message_args...)); } Optional get_environment_variable(const CStringView varname) noexcept; @@ -90,17 +90,17 @@ namespace vcpkg::Debug void println(const System::Color c, const CStringView message); template - void println(const char* messageTemplate, const Arg1& messageArg1, const Args&... messageArgs) + void println(const char* message_template, const Arg1& message_arg1, const Args&... message_args) { - return Debug::println(Strings::format(messageTemplate, messageArg1, messageArgs...)); + return Debug::println(Strings::format(message_template, message_arg1, message_args...)); } template void println(const System::Color c, - const char* messageTemplate, - const Arg1& messageArg1, - const Args&... messageArgs) + const char* message_template, + const Arg1& message_arg1, + const Args&... message_args) { - return Debug::println(c, Strings::format(messageTemplate, messageArg1, messageArgs...)); + return Debug::println(c, Strings::format(message_template, message_arg1, message_args...)); } } -- cgit v1.2.3 From 92d1a53215b2cc23dc090368d5218d42e195c478 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 20 Oct 2017 16:43:05 -0700 Subject: [LineInfo] Store empty string instead of null in default construction --- toolsrc/include/vcpkg/base/lineinfo.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/base/lineinfo.h b/toolsrc/include/vcpkg/base/lineinfo.h index 62973462a..e7e8c3031 100644 --- a/toolsrc/include/vcpkg/base/lineinfo.h +++ b/toolsrc/include/vcpkg/base/lineinfo.h @@ -9,7 +9,7 @@ namespace vcpkg int line_number; const char* file_name; - constexpr LineInfo() : line_number(0), file_name(nullptr) {} + constexpr LineInfo() : line_number(0), file_name("") {} constexpr LineInfo(const int lineno, const char* filename) : line_number(lineno), file_name(filename) {} std::string to_string() const; -- cgit v1.2.3 From 23702360ce912b1827afe5559de936cc9a24cd0c Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 20 Oct 2017 16:43:44 -0700 Subject: Merge trim() and trimmed() functions --- toolsrc/include/vcpkg/base/strings.h | 4 +--- toolsrc/src/vcpkg/base/strings.cpp | 16 +++++----------- toolsrc/src/vcpkg/vcpkgpaths.cpp | 2 +- 3 files changed, 7 insertions(+), 15 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/base/strings.h b/toolsrc/include/vcpkg/base/strings.h index 5b03286de..ee1b2fc28 100644 --- a/toolsrc/include/vcpkg/base/strings.h +++ b/toolsrc/include/vcpkg/base/strings.h @@ -78,9 +78,7 @@ namespace vcpkg::Strings std::string replace_all(std::string&& s, const std::string& search, const std::string& rep); - void trim(std::string* s); - - std::string trimmed(const std::string& s); + std::string trim(std::string&& s); void trim_all_and_remove_whitespace_strings(std::vector* strings); diff --git a/toolsrc/src/vcpkg/base/strings.cpp b/toolsrc/src/vcpkg/base/strings.cpp index 36efc3adc..27cfcbe71 100644 --- a/toolsrc/src/vcpkg/base/strings.cpp +++ b/toolsrc/src/vcpkg/base/strings.cpp @@ -125,24 +125,18 @@ namespace vcpkg::Strings return std::move(s); } - void trim(std::string* s) + std::string trim(std::string&& s) { - s->erase(std::find_if_not(s->rbegin(), s->rend(), details::isspace).base(), s->end()); - s->erase(s->begin(), std::find_if_not(s->begin(), s->end(), details::isspace)); - } - - std::string trimmed(const std::string& s) - { - auto whitespace_back = std::find_if_not(s.rbegin(), s.rend(), details::isspace).base(); - auto whitespace_front = std::find_if_not(s.begin(), whitespace_back, details::isspace); - return std::string(whitespace_front, whitespace_back); + s.erase(std::find_if_not(s.rbegin(), s.rend(), details::isspace).base(), s.end()); + s.erase(s.begin(), std::find_if_not(s.begin(), s.end(), details::isspace)); + return std::move(s); } void trim_all_and_remove_whitespace_strings(std::vector* strings) { for (std::string& s : *strings) { - trim(&s); + s = trim(std::move(s)); } Util::erase_remove_if(*strings, [](const std::string& s) { return s.empty(); }); diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index ef9e383bc..363319767 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -91,7 +91,7 @@ namespace vcpkg Checks::exit_with_code(VCPKG_LINE_INFO, rc.exit_code); } - const fs::path actual_downloaded_path = Strings::trimmed(rc.output); + const fs::path actual_downloaded_path = Strings::trim(std::string{rc.output}); std::error_code ec; const auto eq = fs::stdfs::equivalent(expected_downloaded_path, actual_downloaded_path, ec); Checks::check_exit(VCPKG_LINE_INFO, -- cgit v1.2.3 From 8a952743a3a3f856f6be6b985158ea1c1ffb2c6f Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 26 Oct 2017 18:59:11 -0700 Subject: Introduce Util::Sets::contains() --- toolsrc/include/vcpkg/base/util.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/base/util.h b/toolsrc/include/vcpkg/base/util.h index d5db6b6ee..7ffd027f0 100644 --- a/toolsrc/include/vcpkg/base/util.h +++ b/toolsrc/include/vcpkg/base/util.h @@ -20,6 +20,15 @@ namespace vcpkg::Util } } + namespace Sets + { + template> + bool contains(const Container& container, const T& item) + { + return container.find(item) != container.cend(); + } + } + template using FmapOut = decltype(std::declval()(*begin(std::declval()))); -- cgit v1.2.3 From 2c9536ce4fe0ac755e188617ce61076b26646100 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 26 Oct 2017 19:00:30 -0700 Subject: [vcpkg ci] Introduce --exclude option --- toolsrc/include/vcpkg/build.h | 8 +++++--- toolsrc/include/vcpkg/dependencies.h | 3 ++- toolsrc/include/vcpkg/install.h | 2 ++ toolsrc/include/vcpkg/packagespec.h | 2 ++ toolsrc/src/tests.installplan.cpp | 7 ++++--- toolsrc/src/vcpkg/build.cpp | 6 +++++- toolsrc/src/vcpkg/commands.ci.cpp | 39 ++++++++++++++++++++---------------- toolsrc/src/vcpkg/dependencies.cpp | 22 ++++++++------------ toolsrc/src/vcpkg/install.cpp | 21 +++++++++++++++++-- toolsrc/src/vcpkg/packagespec.cpp | 8 ++++++++ 10 files changed, 77 insertions(+), 41 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/build.h b/toolsrc/include/vcpkg/build.h index 774e25922..bf52e54b2 100644 --- a/toolsrc/include/vcpkg/build.h +++ b/toolsrc/include/vcpkg/build.h @@ -65,15 +65,17 @@ namespace vcpkg::Build BUILD_FAILED, POST_BUILD_CHECKS_FAILED, FILE_CONFLICTS, - CASCADED_DUE_TO_MISSING_DEPENDENCIES + CASCADED_DUE_TO_MISSING_DEPENDENCIES, + EXCLUDED, }; - static constexpr std::array BUILD_RESULT_VALUES = { + static constexpr std::array BUILD_RESULT_VALUES = { BuildResult::SUCCEEDED, BuildResult::BUILD_FAILED, BuildResult::POST_BUILD_CHECKS_FAILED, BuildResult::FILE_CONFLICTS, - BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES}; + BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES, + BuildResult::EXCLUDED}; const std::string& to_string(const BuildResult build_result); std::string create_error_message(const BuildResult build_result, const PackageSpec& spec); diff --git a/toolsrc/include/vcpkg/dependencies.h b/toolsrc/include/vcpkg/dependencies.h index 585338ae2..60c83fcca 100644 --- a/toolsrc/include/vcpkg/dependencies.h +++ b/toolsrc/include/vcpkg/dependencies.h @@ -38,7 +38,8 @@ namespace vcpkg::Dependencies UNKNOWN, BUILD_AND_INSTALL, INSTALL, - ALREADY_INSTALLED + ALREADY_INSTALLED, + EXCLUDED }; struct InstallPlanAction : Util::MoveOnlyBase diff --git a/toolsrc/include/vcpkg/install.h b/toolsrc/include/vcpkg/install.h index 809befb16..895028865 100644 --- a/toolsrc/include/vcpkg/install.h +++ b/toolsrc/include/vcpkg/install.h @@ -62,6 +62,8 @@ namespace vcpkg::Install SUCCESS, }; + 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); InstallResult install_package(const VcpkgPaths& paths, const BinaryControlFile& binary_paragraph, diff --git a/toolsrc/include/vcpkg/packagespec.h b/toolsrc/include/vcpkg/packagespec.h index 60c99782e..99aaaf0d7 100644 --- a/toolsrc/include/vcpkg/packagespec.h +++ b/toolsrc/include/vcpkg/packagespec.h @@ -20,6 +20,8 @@ namespace vcpkg static ExpectedT from_name_and_triplet(const std::string& name, const Triplet& triplet); + static std::vector to_package_specs(const std::vector& ports, const Triplet& triplet); + const std::string& name() const; const Triplet& triplet() const; diff --git a/toolsrc/src/tests.installplan.cpp b/toolsrc/src/tests.installplan.cpp index 120009db5..347612abd 100644 --- a/toolsrc/src/tests.installplan.cpp +++ b/toolsrc/src/tests.installplan.cpp @@ -17,8 +17,9 @@ namespace Microsoft::VisualStudio::CppUnitTestFramework case Dependencies::InstallPlanType::ALREADY_INSTALLED: return L"ALREADY_INSTALLED"; case Dependencies::InstallPlanType::BUILD_AND_INSTALL: return L"BUILD_AND_INSTALL"; case Dependencies::InstallPlanType::INSTALL: return L"INSTALL"; + case Dependencies::InstallPlanType::EXCLUDED: return L"EXCLUDED"; case Dependencies::InstallPlanType::UNKNOWN: return L"UNKNOWN"; - default: return ToString((int)t); + default: return ToString(static_cast(t)); } } @@ -30,7 +31,7 @@ namespace Microsoft::VisualStudio::CppUnitTestFramework case Dependencies::RequestType::AUTO_SELECTED: return L"AUTO_SELECTED"; case Dependencies::RequestType::USER_REQUESTED: return L"USER_REQUESTED"; case Dependencies::RequestType::UNKNOWN: return L"UNKNOWN"; - default: return ToString((int)t); + default: return ToString(static_cast(t)); } } } @@ -484,4 +485,4 @@ namespace UnitTest1 features_check(&install_plan[7], "c", {"core"}); } }; -} \ No newline at end of file +} diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index cf16c8f9c..c26dcc591 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -87,6 +87,8 @@ namespace vcpkg::Build::Command Checks::exit_fail(VCPKG_LINE_INFO); } + Checks::check_exit(VCPKG_LINE_INFO, result.code != BuildResult::EXCLUDED); + if (result.code != BuildResult::SUCCEEDED) { System::println(System::Color::error, Build::create_error_message(result.code, spec)); @@ -365,6 +367,7 @@ namespace vcpkg::Build static const std::string FILE_CONFLICTS_STRING = "FILE_CONFLICTS"; static const std::string POST_BUILD_CHECKS_FAILED_STRING = "POST_BUILD_CHECKS_FAILED"; static const std::string CASCADED_DUE_TO_MISSING_DEPENDENCIES_STRING = "CASCADED_DUE_TO_MISSING_DEPENDENCIES"; + static const std::string EXCLUDED_STRING = "EXCLUDED"; switch (build_result) { @@ -372,8 +375,9 @@ namespace vcpkg::Build case BuildResult::SUCCEEDED: return SUCCEEDED_STRING; case BuildResult::BUILD_FAILED: return BUILD_FAILED_STRING; case BuildResult::POST_BUILD_CHECKS_FAILED: return POST_BUILD_CHECKS_FAILED_STRING; - case BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES: return CASCADED_DUE_TO_MISSING_DEPENDENCIES_STRING; case BuildResult::FILE_CONFLICTS: return FILE_CONFLICTS_STRING; + case BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES: return CASCADED_DUE_TO_MISSING_DEPENDENCIES_STRING; + case BuildResult::EXCLUDED: return EXCLUDED_STRING; default: Checks::unreachable(VCPKG_LINE_INFO); } } diff --git a/toolsrc/src/vcpkg/commands.ci.cpp b/toolsrc/src/vcpkg/commands.ci.cpp index ffeaad790..559dc4541 100644 --- a/toolsrc/src/vcpkg/commands.ci.cpp +++ b/toolsrc/src/vcpkg/commands.ci.cpp @@ -1,6 +1,5 @@ #include "pch.h" -#include #include #include #include @@ -10,7 +9,6 @@ #include #include #include -#include #include namespace vcpkg::Commands::CI @@ -19,27 +17,28 @@ namespace vcpkg::Commands::CI using Dependencies::InstallPlanAction; using Dependencies::InstallPlanType; - static std::vector load_all_package_specs(Files::Filesystem& fs, - const fs::path& ports_directory, - const Triplet& triplet) - { - auto ports = Paragraphs::load_all_ports(fs, ports_directory); - return Util::fmap(ports, [&](auto&& control_file) -> PackageSpec { - return PackageSpec::from_name_and_triplet(control_file->core_paragraph->name, triplet) - .value_or_exit(VCPKG_LINE_INFO); - }); - } - - static Install::InstallSummary run_ci_on_triplet(const Triplet& triplet, const VcpkgPaths& paths) + static Install::InstallSummary run_ci_on_triplet(const Triplet& triplet, + const VcpkgPaths& paths, + const std::vector& ports, + const std::set& exclusions_set) { Input::check_triplet(triplet, paths); - const std::vector specs = load_all_package_specs(paths.get_filesystem(), paths.ports, triplet); + const std::vector specs = PackageSpec::to_package_specs(ports, triplet); StatusParagraphs status_db = database_load_check(paths); const auto& paths_port_file = Dependencies::PathsPortFile(paths); std::vector install_plan = Dependencies::create_install_plan(paths_port_file, specs, status_db); + + for (InstallPlanAction& plan : install_plan) + { + if (Util::Sets::contains(exclusions_set, plan.spec.name())) + { + plan.plan_type = InstallPlanType::EXCLUDED; + } + } + Checks::check_exit(VCPKG_LINE_INFO, !install_plan.empty(), "Install plan cannot be empty"); const Build::BuildPackageOptions install_plan_options = {Build::UseHeadVersion::NO, Build::AllowDownloads::YES}; @@ -60,8 +59,13 @@ namespace vcpkg::Commands::CI void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) { + static const std::string OPTION_EXCLUDE = "--exclude"; + static const std::string EXAMPLE = Help::create_example_string("ci x64-windows"); - args.check_and_get_optional_command_arguments({}); + + const ParsedArguments options = args.check_and_get_optional_command_arguments({}, {OPTION_EXCLUDE}); + const std::vector exclusions = Strings::split(options.settings.at(OPTION_EXCLUDE), ","); + const std::set exclusions_set(exclusions.cbegin(), exclusions.cend()); std::vector triplets; for (const std::string& triplet : args.command_arguments) @@ -74,10 +78,11 @@ namespace vcpkg::Commands::CI triplets.push_back(default_triplet); } + const std::vector ports = Install::get_all_port_names(paths); std::vector results; for (const Triplet& triplet : triplets) { - Install::InstallSummary summary = run_ci_on_triplet(triplet, paths); + Install::InstallSummary summary = run_ci_on_triplet(triplet, paths, ports, exclusions_set); results.push_back({triplet, std::move(summary)}); } diff --git a/toolsrc/src/vcpkg/dependencies.cpp b/toolsrc/src/vcpkg/dependencies.cpp index 02b2ec785..9d264baa2 100644 --- a/toolsrc/src/vcpkg/dependencies.cpp +++ b/toolsrc/src/vcpkg/dependencies.cpp @@ -112,27 +112,21 @@ namespace vcpkg::Dependencies std::vector AnyParagraph::dependencies(const Triplet& triplet) const { - auto to_package_specs = [&](const std::vector& dependencies_as_string) { - return Util::fmap(dependencies_as_string, [&](const std::string s) { - return PackageSpec::from_name_and_triplet(s, triplet).value_or_exit(VCPKG_LINE_INFO); - }); - }; - - if (auto p = this->status_paragraph.get()) + if (const auto p = this->status_paragraph.get()) { - return to_package_specs(p->package.depends); + return PackageSpec::to_package_specs(p->package.depends, triplet); } - if (auto p = this->binary_control_file.get()) + if (const auto p = this->binary_control_file.get()) { auto deps = Util::fmap_flatten(p->features, [](const BinaryParagraph& pgh) { return pgh.depends; }); - deps.insert(deps.end(), p->core_paragraph.depends.begin(), p->core_paragraph.depends.end()); - return to_package_specs(deps); + deps.insert(deps.end(), p->core_paragraph.depends.cbegin(), p->core_paragraph.depends.cend()); + return PackageSpec::to_package_specs(deps, triplet); } - if (auto p = this->source_paragraph.get()) + if (const auto p = this->source_paragraph.get()) { - return to_package_specs(filter_dependencies(p->depends, triplet)); + return PackageSpec::to_package_specs(filter_dependencies(p->depends, triplet), triplet); } Checks::exit_with_message(VCPKG_LINE_INFO, @@ -163,7 +157,7 @@ namespace vcpkg::Dependencies InstallPlanAction::InstallPlanAction(const PackageSpec& spec, const std::unordered_set& features, const RequestType& request_type) - : spec(spec), plan_type(InstallPlanType::ALREADY_INSTALLED), request_type(request_type), feature_list(features) + : spec(spec), plan_type(InstallPlanType::UNKNOWN), request_type(request_type), feature_list(features) { } diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp index bd924fcba..76e943e8c 100644 --- a/toolsrc/src/vcpkg/install.cpp +++ b/toolsrc/src/vcpkg/install.cpp @@ -342,6 +342,12 @@ namespace vcpkg::Install } } + if (plan_type == InstallPlanType::EXCLUDED) + { + System::println(System::Color::warning, "Package %s is excluded", display_name); + return BuildResult::EXCLUDED; + } + Checks::unreachable(VCPKG_LINE_INFO); } @@ -352,6 +358,7 @@ namespace vcpkg::Install std::vector only_install_plans; std::vector new_plans; std::vector already_installed_plans; + std::vector excluded; const bool has_non_user_requested_packages = Util::find_if(action_plan, [](const AnyAction& package) -> bool { if (auto iplan = package.install_plan.get()) @@ -382,6 +389,7 @@ namespace vcpkg::Install already_installed_plans.emplace_back(install_action); break; case InstallPlanType::BUILD_AND_INSTALL: new_plans.emplace_back(install_action); break; + case InstallPlanType::EXCLUDED: excluded.emplace_back(install_action); break; default: Checks::unreachable(VCPKG_LINE_INFO); } } @@ -397,6 +405,15 @@ namespace vcpkg::Install std::sort(only_install_plans.begin(), only_install_plans.end(), &InstallPlanAction::compare_by_name); std::sort(new_plans.begin(), new_plans.end(), &InstallPlanAction::compare_by_name); std::sort(already_installed_plans.begin(), already_installed_plans.end(), &InstallPlanAction::compare_by_name); + std::sort(excluded.begin(), excluded.end(), &InstallPlanAction::compare_by_name); + + if (excluded.size() > 0) + { + const std::string excluded_string = Strings::join("\n", excluded, [](const InstallPlanAction* p) { + return to_output_string(p->request_type, p->displayname()); + }); + System::println("The following packages are excluded:\n%s", excluded_string); + } if (already_installed_plans.size() > 0) { @@ -538,7 +555,7 @@ namespace vcpkg::Install }; static const std::array INSTALL_SETTINGS; - static std::vector valid_arguments(const VcpkgPaths& paths) + std::vector get_all_port_names(const VcpkgPaths& paths) { auto sources_and_errors = Paragraphs::try_load_all_ports(paths.get_filesystem(), paths.ports); @@ -552,7 +569,7 @@ namespace vcpkg::Install SIZE_MAX, INSTALL_SWITCHES, INSTALL_SETTINGS, - &valid_arguments, + &get_all_port_names, }; void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) diff --git a/toolsrc/src/vcpkg/packagespec.cpp b/toolsrc/src/vcpkg/packagespec.cpp index 6e40d70f5..eeb9981af 100644 --- a/toolsrc/src/vcpkg/packagespec.cpp +++ b/toolsrc/src/vcpkg/packagespec.cpp @@ -92,6 +92,14 @@ namespace vcpkg return p; } + std::vector PackageSpec::to_package_specs(const std::vector& ports, + const Triplet& triplet) + { + return Util::fmap(ports, [&](const std::string s) { + return PackageSpec::from_name_and_triplet(s, triplet).value_or_exit(VCPKG_LINE_INFO); + }); + } + const std::string& PackageSpec::name() const { return this->m_name; } const Triplet& PackageSpec::triplet() const { return this->m_triplet; } -- cgit v1.2.3 From 79ebd26605e0f621f848206000a5b1c7239d5f37 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 26 Oct 2017 19:14:32 -0700 Subject: Remove VcpkgCmdArguments.check_and_get_optional_command_arguments() overload Also, use Util::Sets::contains() where possible. --- toolsrc/include/vcpkg/build.h | 2 +- toolsrc/include/vcpkg/vcpkgcmdarguments.h | 5 ----- toolsrc/src/vcpkg/build.cpp | 7 +++---- toolsrc/src/vcpkg/commands.buildexternal.cpp | 2 +- toolsrc/src/vcpkg/commands.cache.cpp | 2 +- toolsrc/src/vcpkg/commands.contact.cpp | 2 +- toolsrc/src/vcpkg/commands.create.cpp | 2 +- toolsrc/src/vcpkg/commands.dependinfo.cpp | 2 +- toolsrc/src/vcpkg/commands.edit.cpp | 5 ++--- toolsrc/src/vcpkg/commands.env.cpp | 2 +- toolsrc/src/vcpkg/commands.hash.cpp | 2 +- toolsrc/src/vcpkg/commands.import.cpp | 2 +- toolsrc/src/vcpkg/commands.integrate.cpp | 2 +- toolsrc/src/vcpkg/commands.list.cpp | 7 +++---- toolsrc/src/vcpkg/commands.owns.cpp | 4 ++-- toolsrc/src/vcpkg/commands.portsdiff.cpp | 2 +- toolsrc/src/vcpkg/commands.search.cpp | 19 +++++++++---------- toolsrc/src/vcpkg/commands.version.cpp | 2 +- toolsrc/src/vcpkg/help.cpp | 2 +- toolsrc/src/vcpkg/install.cpp | 16 ++++++++-------- toolsrc/src/vcpkg/remove.cpp | 14 +++++++------- toolsrc/src/vcpkg/update.cpp | 2 +- 22 files changed, 48 insertions(+), 57 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/build.h b/toolsrc/include/vcpkg/build.h index bf52e54b2..94d9fddf5 100644 --- a/toolsrc/include/vcpkg/build.h +++ b/toolsrc/include/vcpkg/build.h @@ -20,7 +20,7 @@ namespace vcpkg::Build { void perform_and_exit(const FullPackageSpec& full_spec, const fs::path& port_dir, - const std::unordered_set& options, + const ParsedArguments& options, const VcpkgPaths& paths); void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet); diff --git a/toolsrc/include/vcpkg/vcpkgcmdarguments.h b/toolsrc/include/vcpkg/vcpkgcmdarguments.h index d9895f4b8..e59979ad1 100644 --- a/toolsrc/include/vcpkg/vcpkgcmdarguments.h +++ b/toolsrc/include/vcpkg/vcpkgcmdarguments.h @@ -34,11 +34,6 @@ namespace vcpkg std::string command; std::vector command_arguments; - std::unordered_set check_and_get_optional_command_arguments( - const std::vector& valid_options) const - { - return std::move(check_and_get_optional_command_arguments(valid_options, {}).switches); - } ParsedArguments check_and_get_optional_command_arguments(const std::vector& valid_switches, const std::vector& valid_settings) const; diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index c26dcc591..30a6a791c 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -30,11 +30,11 @@ namespace vcpkg::Build::Command void perform_and_exit(const FullPackageSpec& full_spec, const fs::path& port_dir, - const std::unordered_set& options, + const ParsedArguments& options, const VcpkgPaths& paths) { const PackageSpec& spec = full_spec.package_spec; - if (options.find(OPTION_CHECKS_ONLY) != options.end()) + if (Util::Sets::contains(options.switches, OPTION_CHECKS_ONLY)) { const auto pre_build_info = Build::PreBuildInfo::from_triplet_file(paths, spec.triplet()); const auto build_info = Build::read_build_info(paths.get_filesystem(), paths.build_info_file_path(spec)); @@ -107,8 +107,7 @@ namespace vcpkg::Build::Command const std::string command_argument = args.command_arguments.at(0); const FullPackageSpec spec = Input::check_and_get_full_package_spec(command_argument, default_triplet, EXAMPLE); Input::check_triplet(spec.package_spec.triplet(), paths); - const std::unordered_set options = - args.check_and_get_optional_command_arguments({OPTION_CHECKS_ONLY}); + const ParsedArguments options = args.check_and_get_optional_command_arguments({OPTION_CHECKS_ONLY}, {}); perform_and_exit(spec, paths.port_dir(spec.package_spec), options, paths); } } diff --git a/toolsrc/src/vcpkg/commands.buildexternal.cpp b/toolsrc/src/vcpkg/commands.buildexternal.cpp index 3991beb62..2cc7aabde 100644 --- a/toolsrc/src/vcpkg/commands.buildexternal.cpp +++ b/toolsrc/src/vcpkg/commands.buildexternal.cpp @@ -15,7 +15,7 @@ namespace vcpkg::Commands::BuildExternal const FullPackageSpec spec = Input::check_and_get_full_package_spec(args.command_arguments.at(0), default_triplet, EXAMPLE); Input::check_triplet(spec.package_spec.triplet(), paths); - const std::unordered_set options = args.check_and_get_optional_command_arguments({}); + const ParsedArguments options = args.check_and_get_optional_command_arguments({}, {}); const fs::path port_dir = args.command_arguments.at(1); Build::Command::perform_and_exit(spec, port_dir, options, paths); diff --git a/toolsrc/src/vcpkg/commands.cache.cpp b/toolsrc/src/vcpkg/commands.cache.cpp index 77f0a20f6..64a3169b1 100644 --- a/toolsrc/src/vcpkg/commands.cache.cpp +++ b/toolsrc/src/vcpkg/commands.cache.cpp @@ -32,7 +32,7 @@ namespace vcpkg::Commands::Cache "The argument should be a substring to search for, or no argument to display all cached libraries.\n%s", Help::create_example_string("cache png")); args.check_max_arg_count(1, EXAMPLE); - args.check_and_get_optional_command_arguments({}); + args.check_and_get_optional_command_arguments({}, {}); const std::vector binary_paragraphs = read_all_binary_paragraphs(paths); if (binary_paragraphs.empty()) diff --git a/toolsrc/src/vcpkg/commands.contact.cpp b/toolsrc/src/vcpkg/commands.contact.cpp index 421b8a230..5694c1fa6 100644 --- a/toolsrc/src/vcpkg/commands.contact.cpp +++ b/toolsrc/src/vcpkg/commands.contact.cpp @@ -14,7 +14,7 @@ namespace vcpkg::Commands::Contact void perform_and_exit(const VcpkgCmdArguments& args) { args.check_exact_arg_count(0); - args.check_and_get_optional_command_arguments({}); + args.check_and_get_optional_command_arguments({}, {}); System::println("Send an email to %s with any feedback.", email()); Checks::exit_success(VCPKG_LINE_INFO); diff --git a/toolsrc/src/vcpkg/commands.create.cpp b/toolsrc/src/vcpkg/commands.create.cpp index 85763f25e..f1acacd14 100644 --- a/toolsrc/src/vcpkg/commands.create.cpp +++ b/toolsrc/src/vcpkg/commands.create.cpp @@ -14,7 +14,7 @@ namespace vcpkg::Commands::Create R"###(create zlib2 http://zlib.net/zlib1211.zip "zlib1211-2.zip")###"); args.check_max_arg_count(3, EXAMPLE); args.check_min_arg_count(2, EXAMPLE); - args.check_and_get_optional_command_arguments({}); + args.check_and_get_optional_command_arguments({}, {}); const std::string port_name = args.command_arguments.at(0); const std::string url = args.command_arguments.at(1); diff --git a/toolsrc/src/vcpkg/commands.dependinfo.cpp b/toolsrc/src/vcpkg/commands.dependinfo.cpp index 89c7e0c7f..e5554f7e2 100644 --- a/toolsrc/src/vcpkg/commands.dependinfo.cpp +++ b/toolsrc/src/vcpkg/commands.dependinfo.cpp @@ -13,7 +13,7 @@ namespace vcpkg::Commands::DependInfo { static const std::string EXAMPLE = Help::create_example_string(R"###(depend-info [pat])###"); args.check_max_arg_count(1, EXAMPLE); - args.check_and_get_optional_command_arguments({}); + args.check_and_get_optional_command_arguments({}, {}); std::vector> source_control_files = Paragraphs::load_all_ports(paths.get_filesystem(), paths.ports); diff --git a/toolsrc/src/vcpkg/commands.edit.cpp b/toolsrc/src/vcpkg/commands.edit.cpp index 668ec9b1a..bf618e256 100644 --- a/toolsrc/src/vcpkg/commands.edit.cpp +++ b/toolsrc/src/vcpkg/commands.edit.cpp @@ -65,8 +65,7 @@ namespace vcpkg::Commands::Edit static const std::string EXAMPLE = Help::create_example_string("edit zlib"); args.check_exact_arg_count(1, EXAMPLE); - const std::unordered_set options = - args.check_and_get_optional_command_arguments({OPTION_BUILDTREES}); + const ParsedArguments options = args.check_and_get_optional_command_arguments({OPTION_BUILDTREES}, {}); const std::string port_name = args.command_arguments.at(0); const fs::path portpath = paths.ports / port_name; @@ -95,7 +94,7 @@ namespace vcpkg::Commands::Edit } const fs::path env_editor = *it; - if (options.find(OPTION_BUILDTREES) != options.cend()) + if (Util::Sets::contains(options.switches, OPTION_BUILDTREES)) { const auto buildtrees_current_dir = paths.buildtrees / port_name; diff --git a/toolsrc/src/vcpkg/commands.env.cpp b/toolsrc/src/vcpkg/commands.env.cpp index 9f8ae5207..c0d26dac2 100644 --- a/toolsrc/src/vcpkg/commands.env.cpp +++ b/toolsrc/src/vcpkg/commands.env.cpp @@ -11,7 +11,7 @@ namespace vcpkg::Commands::Env { static const std::string EXAMPLE = Help::create_example_string(R"(env --triplet x64-windows)"); args.check_exact_arg_count(0, EXAMPLE); - args.check_and_get_optional_command_arguments({}); + args.check_and_get_optional_command_arguments({}, {}); const auto pre_build_info = Build::PreBuildInfo::from_triplet_file(paths, default_triplet); const Toolset& toolset = paths.get_toolset(pre_build_info.platform_toolset, pre_build_info.visual_studio_path); diff --git a/toolsrc/src/vcpkg/commands.hash.cpp b/toolsrc/src/vcpkg/commands.hash.cpp index 4bc58b509..51f6b9ad0 100644 --- a/toolsrc/src/vcpkg/commands.hash.cpp +++ b/toolsrc/src/vcpkg/commands.hash.cpp @@ -34,7 +34,7 @@ namespace vcpkg::Commands::Hash Help::create_example_string("hash boost_1_62_0.tar.bz2")); args.check_min_arg_count(1, EXAMPLE); args.check_max_arg_count(2, EXAMPLE); - args.check_and_get_optional_command_arguments({}); + args.check_and_get_optional_command_arguments({}, {}); if (args.command_arguments.size() == 1) { diff --git a/toolsrc/src/vcpkg/commands.import.cpp b/toolsrc/src/vcpkg/commands.import.cpp index 119aee022..5e74b6d94 100644 --- a/toolsrc/src/vcpkg/commands.import.cpp +++ b/toolsrc/src/vcpkg/commands.import.cpp @@ -97,7 +97,7 @@ namespace vcpkg::Commands::Import static const std::string EXAMPLE = Help::create_example_string( R"(import C:\path\to\CONTROLfile C:\path\to\includedir C:\path\to\projectdir)"); args.check_exact_arg_count(3, EXAMPLE); - args.check_and_get_optional_command_arguments({}); + args.check_and_get_optional_command_arguments({}, {}); const fs::path control_file_path(args.command_arguments[0]); const fs::path include_directory(args.command_arguments[1]); diff --git a/toolsrc/src/vcpkg/commands.integrate.cpp b/toolsrc/src/vcpkg/commands.integrate.cpp index 27e563cfa..604bd2c6e 100644 --- a/toolsrc/src/vcpkg/commands.integrate.cpp +++ b/toolsrc/src/vcpkg/commands.integrate.cpp @@ -359,7 +359,7 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console "%s", INTEGRATE_COMMAND_HELPSTRING); args.check_exact_arg_count(1, EXAMPLE); - args.check_and_get_optional_command_arguments({}); + args.check_and_get_optional_command_arguments({}, {}); #if defined(_WIN32) if (args.command_arguments[0] == Subcommand::INSTALL) diff --git a/toolsrc/src/vcpkg/commands.list.cpp b/toolsrc/src/vcpkg/commands.list.cpp index d0e8e00b4..145d4c931 100644 --- a/toolsrc/src/vcpkg/commands.list.cpp +++ b/toolsrc/src/vcpkg/commands.list.cpp @@ -30,8 +30,7 @@ namespace vcpkg::Commands::List "The argument should be a substring to search for, or no argument to display all installed libraries.\n%s", Help::create_example_string("list png")); args.check_max_arg_count(1, EXAMPLE); - const std::unordered_set options = - args.check_and_get_optional_command_arguments({OPTION_FULLDESC}); + const ParsedArguments options = args.check_and_get_optional_command_arguments({OPTION_FULLDESC}, {}); const StatusParagraphs status_paragraphs = database_load_check(paths); std::vector installed_packages = get_installed_ports(status_paragraphs); @@ -52,7 +51,7 @@ namespace vcpkg::Commands::List { for (const StatusParagraph* status_paragraph : installed_packages) { - do_print(*status_paragraph, options.find(OPTION_FULLDESC) != options.cend()); + do_print(*status_paragraph, Util::Sets::contains(options.switches, OPTION_FULLDESC)); } } else @@ -66,7 +65,7 @@ namespace vcpkg::Commands::List continue; } - do_print(*status_paragraph, options.find(OPTION_FULLDESC) != options.cend()); + do_print(*status_paragraph, Util::Sets::contains(options.switches, OPTION_FULLDESC)); } } diff --git a/toolsrc/src/vcpkg/commands.owns.cpp b/toolsrc/src/vcpkg/commands.owns.cpp index 69079e829..b2db966e1 100644 --- a/toolsrc/src/vcpkg/commands.owns.cpp +++ b/toolsrc/src/vcpkg/commands.owns.cpp @@ -29,9 +29,9 @@ namespace vcpkg::Commands::Owns static const std::string EXAMPLE = Strings::format("The argument should be a pattern to search for. %s", Help::create_example_string("owns zlib.dll")); args.check_exact_arg_count(1, EXAMPLE); - args.check_and_get_optional_command_arguments({}); + args.check_and_get_optional_command_arguments({}, {}); - StatusParagraphs status_db = database_load_check(paths); + const StatusParagraphs status_db = database_load_check(paths); search_file(paths, args.command_arguments[0], status_db); Checks::exit_success(VCPKG_LINE_INFO); } diff --git a/toolsrc/src/vcpkg/commands.portsdiff.cpp b/toolsrc/src/vcpkg/commands.portsdiff.cpp index a8c043751..5008f3e8a 100644 --- a/toolsrc/src/vcpkg/commands.portsdiff.cpp +++ b/toolsrc/src/vcpkg/commands.portsdiff.cpp @@ -120,7 +120,7 @@ namespace vcpkg::Commands::PortsDiff Help::create_example_string("portsdiff mybranchname")); args.check_min_arg_count(1, EXAMPLE); args.check_max_arg_count(2, EXAMPLE); - args.check_and_get_optional_command_arguments({}); + args.check_and_get_optional_command_arguments({}, {}); const fs::path& git_exe = paths.get_git_exe(); diff --git a/toolsrc/src/vcpkg/commands.search.cpp b/toolsrc/src/vcpkg/commands.search.cpp index 3ba8707de..ad3046e6d 100644 --- a/toolsrc/src/vcpkg/commands.search.cpp +++ b/toolsrc/src/vcpkg/commands.search.cpp @@ -85,12 +85,13 @@ namespace vcpkg::Commands::Search "The argument should be a substring to search for, or no argument to display all libraries.\n%s", Help::create_example_string("search png")); args.check_max_arg_count(1, EXAMPLE); - const std::unordered_set options = - args.check_and_get_optional_command_arguments({OPTION_GRAPH, OPTION_FULLDESC}); + const ParsedArguments options = + args.check_and_get_optional_command_arguments({OPTION_GRAPH, OPTION_FULLDESC}, {}); + const bool full_description = Util::Sets::contains(options.switches, OPTION_FULLDESC); auto source_paragraphs = Paragraphs::load_all_ports(paths.get_filesystem(), paths.ports); - if (options.find(OPTION_GRAPH) != options.cend()) + if (Util::Sets::contains(options.switches, OPTION_GRAPH)) { const std::string graph_as_string = create_graph_as_string(source_paragraphs); System::println(graph_as_string); @@ -101,12 +102,10 @@ namespace vcpkg::Commands::Search { for (const auto& source_control_file : source_paragraphs) { - do_print(*source_control_file->core_paragraph, options.find(OPTION_FULLDESC) != options.cend()); + do_print(*source_control_file->core_paragraph, full_description); for (auto&& feature_paragraph : source_control_file->feature_paragraphs) { - do_print(source_control_file->core_paragraph->name, - *feature_paragraph, - options.find(OPTION_FULLDESC) != options.cend()); + do_print(source_control_file->core_paragraph->name, *feature_paragraph, full_description); } } } @@ -120,10 +119,10 @@ namespace vcpkg::Commands::Search { auto&& sp = *source_control_file->core_paragraph; - bool contains_name = icontains(sp.name, args_zero); + const bool contains_name = icontains(sp.name, args_zero); if (contains_name || icontains(sp.description, args_zero)) { - do_print(sp, options.find(OPTION_FULLDESC) != options.cend()); + do_print(sp, full_description); } for (auto&& feature_paragraph : source_control_file->feature_paragraphs) @@ -131,7 +130,7 @@ namespace vcpkg::Commands::Search if (contains_name || icontains(feature_paragraph->name, args_zero) || icontains(feature_paragraph->description, args_zero)) { - do_print(sp.name, *feature_paragraph, options.find(OPTION_FULLDESC) != options.cend()); + do_print(sp.name, *feature_paragraph, full_description); } } } diff --git a/toolsrc/src/vcpkg/commands.version.cpp b/toolsrc/src/vcpkg/commands.version.cpp index 403c355b5..e8756a77d 100644 --- a/toolsrc/src/vcpkg/commands.version.cpp +++ b/toolsrc/src/vcpkg/commands.version.cpp @@ -65,7 +65,7 @@ namespace vcpkg::Commands::Version void perform_and_exit(const VcpkgCmdArguments& args) { args.check_exact_arg_count(0); - args.check_and_get_optional_command_arguments({}); + args.check_and_get_optional_command_arguments({}, {}); System::println("Vcpkg package management program version %s\n" "\n" diff --git a/toolsrc/src/vcpkg/help.cpp b/toolsrc/src/vcpkg/help.cpp index 2a0578211..8783833f2 100644 --- a/toolsrc/src/vcpkg/help.cpp +++ b/toolsrc/src/vcpkg/help.cpp @@ -94,7 +94,7 @@ namespace vcpkg::Help void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { args.check_max_arg_count(1); - args.check_and_get_optional_command_arguments({}); + args.check_and_get_optional_command_arguments({}, {}); if (args.command_arguments.empty()) { diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp index 76e943e8c..7bab740be 100644 --- a/toolsrc/src/vcpkg/install.cpp +++ b/toolsrc/src/vcpkg/install.cpp @@ -351,7 +351,7 @@ namespace vcpkg::Install Checks::unreachable(VCPKG_LINE_INFO); } - static void print_plan(const std::vector& action_plan, bool is_recursive) + static void print_plan(const std::vector& action_plan, const bool is_recursive) { std::vector remove_plans; std::vector rebuilt_plans; @@ -592,13 +592,13 @@ namespace vcpkg::Install } } - const std::unordered_set options = args.check_and_get_optional_command_arguments( - {OPTION_DRY_RUN, OPTION_USE_HEAD_VERSION, OPTION_NO_DOWNLOADS, OPTION_RECURSE, OPTION_KEEP_GOING}); - const bool dry_run = options.find(OPTION_DRY_RUN) != options.cend(); - const bool use_head_version = options.find(OPTION_USE_HEAD_VERSION) != options.cend(); - const bool no_downloads = options.find(OPTION_NO_DOWNLOADS) != options.cend(); - const bool is_recursive = options.find(OPTION_RECURSE) != options.cend(); - const KeepGoing keep_going = to_keep_going(options.find(OPTION_KEEP_GOING) != options.cend()); + const ParsedArguments options = args.check_and_get_optional_command_arguments( + {OPTION_DRY_RUN, OPTION_USE_HEAD_VERSION, OPTION_NO_DOWNLOADS, OPTION_RECURSE, OPTION_KEEP_GOING}, {}); + const bool dry_run = Util::Sets::contains(options.switches, OPTION_DRY_RUN); + const bool use_head_version = Util::Sets::contains(options.switches, (OPTION_USE_HEAD_VERSION)); + const bool no_downloads = Util::Sets::contains(options.switches, (OPTION_NO_DOWNLOADS)); + const bool is_recursive = Util::Sets::contains(options.switches, (OPTION_RECURSE)); + const KeepGoing keep_going = to_keep_going(Util::Sets::contains(options.switches, OPTION_KEEP_GOING)); // create the plan StatusParagraphs status_db = database_load_check(paths); diff --git a/toolsrc/src/vcpkg/remove.cpp b/toolsrc/src/vcpkg/remove.cpp index 6f555b9b8..156f23003 100644 --- a/toolsrc/src/vcpkg/remove.cpp +++ b/toolsrc/src/vcpkg/remove.cpp @@ -198,12 +198,12 @@ namespace vcpkg::Remove void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) { static const std::string EXAMPLE = Help::create_example_string("remove zlib zlib:x64-windows curl boost"); - const std::unordered_set options = args.check_and_get_optional_command_arguments( - {OPTION_PURGE, OPTION_NO_PURGE, OPTION_RECURSE, OPTION_DRY_RUN, OPTION_OUTDATED}); + const ParsedArguments options = args.check_and_get_optional_command_arguments( + {OPTION_PURGE, OPTION_NO_PURGE, OPTION_RECURSE, OPTION_DRY_RUN, OPTION_OUTDATED}, {}); StatusParagraphs status_db = database_load_check(paths); std::vector specs; - if (options.find(OPTION_OUTDATED) != options.cend()) + if (Util::Sets::contains(options.switches, OPTION_OUTDATED)) { args.check_exact_arg_count(0, EXAMPLE); specs = Util::fmap(Update::find_outdated_packages(paths, status_db), @@ -226,8 +226,8 @@ namespace vcpkg::Remove Input::check_triplet(spec.triplet(), paths); } - const bool no_purge_was_passed = options.find(OPTION_NO_PURGE) != options.end(); - const bool purge_was_passed = options.find(OPTION_PURGE) != options.end(); + const bool no_purge_was_passed = Util::Sets::contains(options.switches, OPTION_NO_PURGE); + const bool purge_was_passed = Util::Sets::contains(options.switches, OPTION_PURGE); if (purge_was_passed && no_purge_was_passed) { System::println(System::Color::error, "Error: cannot specify both --no-purge and --purge."); @@ -235,8 +235,8 @@ namespace vcpkg::Remove Checks::exit_fail(VCPKG_LINE_INFO); } const Purge purge = to_purge(purge_was_passed || !no_purge_was_passed); - const bool is_recursive = options.find(OPTION_RECURSE) != options.cend(); - const bool dry_run = options.find(OPTION_DRY_RUN) != options.cend(); + const bool is_recursive = Util::Sets::contains(options.switches, OPTION_RECURSE); + const bool dry_run = Util::Sets::contains(options.switches, OPTION_DRY_RUN); const std::vector remove_plan = Dependencies::create_remove_plan(specs, status_db); Checks::check_exit(VCPKG_LINE_INFO, !remove_plan.empty(), "Remove plan cannot be empty"); diff --git a/toolsrc/src/vcpkg/update.cpp b/toolsrc/src/vcpkg/update.cpp index 168949bc1..7d565251e 100644 --- a/toolsrc/src/vcpkg/update.cpp +++ b/toolsrc/src/vcpkg/update.cpp @@ -41,7 +41,7 @@ namespace vcpkg::Update void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { args.check_exact_arg_count(0); - args.check_and_get_optional_command_arguments({}); + args.check_and_get_optional_command_arguments({}, {}); System::println("Using local portfile versions. To update the local portfiles, use `git pull`."); const StatusParagraphs status_db = database_load_check(paths); -- cgit v1.2.3 From 0796a9df0e4d171ef2c7ab4d0c16ef4dc496ee5c Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 27 Oct 2017 18:53:36 -0700 Subject: [git] Update to 2.14.3 (was 2.14.2.3) --- toolsrc/src/vcpkg/vcpkgpaths.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index 363319767..c6a92f813 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -150,10 +150,10 @@ namespace vcpkg fs::path get_git_path(const fs::path& downloads_folder, const fs::path& scripts_folder) { - static constexpr std::array EXPECTED_VERSION = {2, 14, 2}; + static constexpr std::array EXPECTED_VERSION = {2, 14, 3}; static const std::string VERSION_CHECK_ARGUMENTS = "--version"; - const fs::path downloaded_copy = downloads_folder / "MinGit-2.14.2.3-32-bit" / "cmd" / "git.exe"; + const fs::path downloaded_copy = downloads_folder / "MinGit-2.14.3-32-bit" / "cmd" / "git.exe"; const std::vector from_path = Files::find_from_PATH("git"); std::vector candidate_paths; -- cgit v1.2.3 From a7f3ab84f024fbf3a1f0c66fd1c5915bdcb5cd2e Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 27 Oct 2017 19:20:33 -0700 Subject: Update CHANGELOG and bump version to v0.0.94 --- toolsrc/VERSION.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/VERSION.txt b/toolsrc/VERSION.txt index f439c6467..ac2866fef 100644 --- a/toolsrc/VERSION.txt +++ b/toolsrc/VERSION.txt @@ -1 +1 @@ -"0.0.93" \ No newline at end of file +"0.0.94" \ No newline at end of file -- cgit v1.2.3 From 5f4221420701ff7d78e02b11622a00ee12a8e64a Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Mon, 30 Oct 2017 23:06:04 -0700 Subject: [vcpkg] Enable pkg[*] as alias for all features. --- toolsrc/include/vcpkg/base/util.h | 16 ++++++++++++++++ toolsrc/include/vcpkg/packagespec.h | 16 ++++++++++++++++ toolsrc/include/vcpkg/triplet.h | 1 + toolsrc/src/tests.installplan.cpp | 33 +++++++++++++++++++-------------- toolsrc/src/tests.packagespec.cpp | 34 ++++++++++++++++++++++++++++++++++ toolsrc/src/vcpkg/dependencies.cpp | 36 ++++++++++++++++++++++++++++++++---- 6 files changed, 118 insertions(+), 18 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/base/util.h b/toolsrc/include/vcpkg/base/util.h index 7ffd027f0..e67d38ad8 100644 --- a/toolsrc/include/vcpkg/base/util.h +++ b/toolsrc/include/vcpkg/base/util.h @@ -117,6 +117,22 @@ namespace vcpkg::Util } } + template + void sort(Range& cont) + { + using std::begin; + using std::end; + std::sort(begin(cont), end(cont)); + } + + template + bool all_equal(const Range1& r1, const Range2& r2) + { + using std::begin; + using std::end; + return std::equal(begin(r1), end(r1), begin(r2), end(r2)); + } + template())->first)>> std::vector extract_keys(AssocContainer&& input_map) { diff --git a/toolsrc/include/vcpkg/packagespec.h b/toolsrc/include/vcpkg/packagespec.h index 99aaaf0d7..0487ae6b8 100644 --- a/toolsrc/include/vcpkg/packagespec.h +++ b/toolsrc/include/vcpkg/packagespec.h @@ -50,6 +50,22 @@ namespace vcpkg static std::vector from_strings_and_triplet(const std::vector& depends, const Triplet& t); + bool operator<(const FeatureSpec& other) const + { + if (name() < other.name()) return true; + if (name() > other.name()) return false; + if (feature() < other.feature()) return true; + if (feature() > other.feature()) return false; + return triplet() < other.triplet(); + } + + bool operator==(const FeatureSpec& other) const + { + return triplet() == other.triplet() && name() == other.name() && feature() == other.feature(); + } + + bool operator!=(const FeatureSpec& other) const { return !(*this == other); } + private: PackageSpec m_spec; std::string m_feature; diff --git a/toolsrc/include/vcpkg/triplet.h b/toolsrc/include/vcpkg/triplet.h index 50d731593..2cfc2d02a 100644 --- a/toolsrc/include/vcpkg/triplet.h +++ b/toolsrc/include/vcpkg/triplet.h @@ -24,6 +24,7 @@ namespace vcpkg size_t hash_code() const; bool operator==(const Triplet& other) const; + bool operator<(const Triplet& other) const { return canonical_name() < other.canonical_name(); } private: static const TripletInstance DEFAULT_INSTANCE; diff --git a/toolsrc/src/tests.installplan.cpp b/toolsrc/src/tests.installplan.cpp index 347612abd..129926317 100644 --- a/toolsrc/src/tests.installplan.cpp +++ b/toolsrc/src/tests.installplan.cpp @@ -461,20 +461,6 @@ namespace UnitTest1 FullPackageSpec::to_feature_specs({spec_c_64, spec_a_86, spec_a_64, spec_c_86}), StatusParagraphs(std::move(status_paragraphs))); - /*Assert::AreEqual(size_t(8), install_plan.size()); - auto iterator_pos = [&](const PackageSpec& spec, size_t start) -> int { - auto it = std::find_if(install_plan.begin() + start, install_plan.end(), [&](auto& action) { - return action.spec == spec; - }); - Assert::IsTrue(it != install_plan.end()); - return (int)(it - install_plan.begin()); - }; - int a_64_1 = iterator_pos(spec_a_64.package_spec, 0), a_86_1 = iterator_pos(spec_a_86.package_spec, 0), - b_64 = iterator_pos(spec_b_64.package_spec, 0), b_86 = iterator_pos(spec_b_86.package_spec, 0), - c_64 = iterator_pos(spec_c_64.package_spec, 0), c_86 = iterator_pos(spec_c_86.package_spec, 0), - a_64_2 = iterator_pos(spec_a_64.package_spec, a_64_1 + 1), - a_86_2 = iterator_pos(spec_a_86.package_spec, a_86_1 + 1);*/ - remove_plan_check(&install_plan[0], "a", Triplet::X64_WINDOWS); remove_plan_check(&install_plan[1], "a"); features_check(&install_plan[2], "b", {"core"}, Triplet::X64_WINDOWS); @@ -484,5 +470,24 @@ namespace UnitTest1 features_check(&install_plan[6], "a", {"a1", "core"}); features_check(&install_plan[7], "c", {"core"}); } + + TEST_METHOD(install_all_features_test) + { + std::vector> status_paragraphs; + + PackageSpecMap spec_map(Triplet::X64_WINDOWS); + auto spec_a_64 = FullPackageSpec{spec_map.emplace("a", "", {{"0", ""}, {"1", ""}}), {"core"}}; + + auto install_specs = FullPackageSpec::from_string("a[*]", Triplet::X64_WINDOWS); + Assert::IsTrue(install_specs.has_value()); + if (!install_specs.has_value()) return; + auto install_plan = Dependencies::create_feature_install_plan( + spec_map.map, + FullPackageSpec::to_feature_specs({install_specs.value_or_exit(VCPKG_LINE_INFO)}), + StatusParagraphs(std::move(status_paragraphs))); + + Assert::IsTrue(install_plan.size() == 1); + features_check(&install_plan[0], "a", {"0", "1", "core"}, Triplet::X64_WINDOWS); + } }; } diff --git a/toolsrc/src/tests.packagespec.cpp b/toolsrc/src/tests.packagespec.cpp index cb5c41af0..25498a799 100644 --- a/toolsrc/src/tests.packagespec.cpp +++ b/toolsrc/src/tests.packagespec.cpp @@ -3,6 +3,7 @@ #include #include +#include #pragma comment(lib, "version") #pragma comment(lib, "winhttp") @@ -103,6 +104,39 @@ namespace UnitTest1 Assert::AreEqual("", spec->triplet.c_str()); } + TEST_METHOD(parsed_specifier_wildcard_feature) + { + auto maybe_spec = vcpkg::ParsedSpecifier::from_string("zlib[*]"); + Assert::AreEqual(vcpkg::PackageSpecParseResult::SUCCESS, maybe_spec.error()); + auto spec = maybe_spec.get(); + Assert::AreEqual("zlib", spec->name.c_str()); + Assert::IsTrue(spec->features.size() == 1); + Assert::AreEqual("*", spec->features[0].c_str()); + Assert::AreEqual("", spec->triplet.c_str()); + } + + TEST_METHOD(expand_wildcards) + { + auto zlib = + vcpkg::FullPackageSpec::from_string("zlib[0,1]", Triplet::X86_UWP).value_or_exit(VCPKG_LINE_INFO); + auto openssl = + vcpkg::FullPackageSpec::from_string("openssl[*]", Triplet::X86_UWP).value_or_exit(VCPKG_LINE_INFO); + auto specs = FullPackageSpec::to_feature_specs({zlib, openssl}); + Util::sort(specs); + auto spectargets = FeatureSpec::from_strings_and_triplet( + { + "openssl", + "zlib", + "openssl[*]", + "zlib[0]", + "zlib[1]", + }, + Triplet::X86_UWP); + Util::sort(spectargets); + Assert::IsTrue(specs.size() == spectargets.size()); + Assert::IsTrue(Util::all_equal(specs, spectargets)); + } + TEST_METHOD(utf8_to_utf16) { auto str = vcpkg::Strings::to_utf16("abc"); diff --git a/toolsrc/src/vcpkg/dependencies.cpp b/toolsrc/src/vcpkg/dependencies.cpp index 9d264baa2..4c4a8a31c 100644 --- a/toolsrc/src/vcpkg/dependencies.cpp +++ b/toolsrc/src/vcpkg/dependencies.cpp @@ -157,7 +157,7 @@ namespace vcpkg::Dependencies InstallPlanAction::InstallPlanAction(const PackageSpec& spec, const std::unordered_set& features, const RequestType& request_type) - : spec(spec), plan_type(InstallPlanType::UNKNOWN), request_type(request_type), feature_list(features) + : spec(spec), plan_type(InstallPlanType::ALREADY_INSTALLED), request_type(request_type), feature_list(features) { } @@ -605,10 +605,38 @@ namespace vcpkg::Dependencies { Cluster& spec_cluster = graph.get(spec.spec()); spec_cluster.request_type = RequestType::USER_REQUESTED; - auto res = mark_plus(spec.feature(), spec_cluster, graph, graph_plan); + if (spec.feature() == "*") + { + if (auto p_scf = spec_cluster.source_control_file.value_or(nullptr)) + { + for (auto&& feature : p_scf->feature_paragraphs) + { + auto res = mark_plus(feature->name, spec_cluster, graph, graph_plan); + + Checks::check_exit(VCPKG_LINE_INFO, + res == MarkPlusResult::SUCCESS, + "Error: Unable to locate feature %s", + spec); + } + + auto res = mark_plus("core", spec_cluster, graph, graph_plan); - Checks::check_exit( - VCPKG_LINE_INFO, res == MarkPlusResult::SUCCESS, "Error: Unable to locate feature %s", spec); + Checks::check_exit( + VCPKG_LINE_INFO, res == MarkPlusResult::SUCCESS, "Error: Unable to locate feature %s", spec); + } + else + { + Checks::exit_with_message( + VCPKG_LINE_INFO, "Error: Unable to handle '*' because can't find CONTROL for %s", spec.spec()); + } + } + else + { + auto res = mark_plus(spec.feature(), spec_cluster, graph, graph_plan); + + Checks::check_exit( + VCPKG_LINE_INFO, res == MarkPlusResult::SUCCESS, "Error: Unable to locate feature %s", spec); + } graph_plan.install_graph.add_vertex(ClusterPtr{&spec_cluster}); } -- cgit v1.2.3 From 3457d89d41f19e933929cf4df88892f47cef297c Mon Sep 17 00:00:00 2001 From: sdcb Date: Tue, 31 Oct 2017 10:17:47 +0800 Subject: Using CP_UTF8 macro instead of magic numbers. --- toolsrc/src/vcpkg.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg.cpp b/toolsrc/src/vcpkg.cpp index b4c2d0fe2..2a73c5b0f 100644 --- a/toolsrc/src/vcpkg.cpp +++ b/toolsrc/src/vcpkg.cpp @@ -245,8 +245,8 @@ int main(const int argc, const char* const* const argv) GlobalState::g_init_console_cp = GetConsoleCP(); GlobalState::g_init_console_output_cp = GetConsoleOutputCP(); - SetConsoleCP(65001); - SetConsoleOutputCP(65001); + SetConsoleCP(CP_UTF8); + SetConsoleOutputCP(CP_UTF8); const std::string trimmed_command_line = trim_path_from_command_line(Strings::to_utf8(GetCommandLineW())); #endif -- cgit v1.2.3 From 33fc44a0e3ade2c7e9369723b2ee4965ee8795e6 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Tue, 31 Oct 2017 02:13:49 -0700 Subject: [vcpkg] Add optional Abi field to BinaryParagraph for future use. --- toolsrc/include/vcpkg/binaryparagraph.h | 1 + toolsrc/src/tests.paragraph.cpp | 30 ++++++++++++++++++++++++++++++ toolsrc/src/vcpkg/binaryparagraph.cpp | 4 ++++ 3 files changed, 35 insertions(+) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/binaryparagraph.h b/toolsrc/include/vcpkg/binaryparagraph.h index 7eb50a6d7..f59bf693a 100644 --- a/toolsrc/include/vcpkg/binaryparagraph.h +++ b/toolsrc/include/vcpkg/binaryparagraph.h @@ -30,6 +30,7 @@ namespace vcpkg std::string feature; std::vector default_features; std::vector depends; + std::string abi; }; struct BinaryControlFile diff --git a/toolsrc/src/tests.paragraph.cpp b/toolsrc/src/tests.paragraph.cpp index d9301abd0..13052610f 100644 --- a/toolsrc/src/tests.paragraph.cpp +++ b/toolsrc/src/tests.paragraph.cpp @@ -190,6 +190,20 @@ namespace UnitTest1 Assert::AreEqual("c", pgh.depends[2].c_str()); } + TEST_METHOD(BinaryParagraph_Abi) + { + vcpkg::BinaryParagraph pgh({ + {"Package", "zlib"}, + {"Version", "1.2.8"}, + {"Architecture", "x86-windows"}, + {"Multi-Arch", "same"}, + {"Abi", "abcd123"}, + }); + + Assert::AreEqual(size_t(0), pgh.depends.size()); + Assert::IsTrue(pgh.abi == "abcd123"); + } + TEST_METHOD(parse_paragraphs_empty) { const char* str = ""; @@ -385,5 +399,21 @@ namespace UnitTest1 Assert::AreEqual(size_t(1), pghs.size()); Assert::AreEqual("a, b, c", pghs[0]["Depends"].c_str()); } + + TEST_METHOD(BinaryParagraph_serialize_abi) + { + vcpkg::BinaryParagraph pgh({ + {"Package", "zlib"}, + {"Version", "1.2.8"}, + {"Architecture", "x86-windows"}, + {"Multi-Arch", "same"}, + {"Depends", "a, b, c"}, + {"Abi", "123abc"}, + }); + 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("123abc", pghs[0]["Abi"].c_str()); + } }; } diff --git a/toolsrc/src/vcpkg/binaryparagraph.cpp b/toolsrc/src/vcpkg/binaryparagraph.cpp index 3a493eb4c..c7136b713 100644 --- a/toolsrc/src/vcpkg/binaryparagraph.cpp +++ b/toolsrc/src/vcpkg/binaryparagraph.cpp @@ -16,6 +16,7 @@ namespace vcpkg namespace Fields { + static const std::string ABI = "Abi"; static const std::string FEATURE = "Feature"; static const std::string DESCRIPTION = "Description"; static const std::string MAINTAINER = "Maintainer"; @@ -47,6 +48,8 @@ namespace vcpkg this->description = parser.optional_field(Fields::DESCRIPTION); this->maintainer = parser.optional_field(Fields::MAINTAINER); + this->abi = parser.optional_field(Fields::ABI); + std::string multi_arch; parser.required_field(Fields::MULTI_ARCH, multi_arch); @@ -118,6 +121,7 @@ namespace vcpkg out_str.append("Multi-Arch: same\n"); if (!pgh.maintainer.empty()) out_str.append("Maintainer: ").append(pgh.maintainer).push_back('\n'); + if (!pgh.abi.empty()) out_str.append("Abi: ").append(pgh.abi).push_back('\n'); if (!pgh.description.empty()) out_str.append("Description: ").append(pgh.description).push_back('\n'); } } -- cgit v1.2.3 From 925fab565a76c23e76329193bc25158608bc9fc6 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Tue, 31 Oct 2017 03:04:28 -0700 Subject: [vcpkg] --head should only apply to USER_REQUESTED packages. --- toolsrc/include/vcpkg/dependencies.h | 5 +++ toolsrc/include/vcpkg/install.h | 2 -- toolsrc/src/vcpkg/commands.ci.cpp | 5 +-- toolsrc/src/vcpkg/dependencies.cpp | 14 +++++++++ toolsrc/src/vcpkg/export.cpp | 4 ++- toolsrc/src/vcpkg/install.cpp | 59 ++++++++++++++++++------------------ 6 files changed, 54 insertions(+), 35 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/dependencies.h b/toolsrc/include/vcpkg/dependencies.h index 60c83fcca..5411ee166 100644 --- a/toolsrc/include/vcpkg/dependencies.h +++ b/toolsrc/include/vcpkg/dependencies.h @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -18,6 +19,9 @@ namespace vcpkg::Dependencies AUTO_SELECTED }; + std::string to_output_string(RequestType request_type, + const CStringView s, + const Build::BuildPackageOptions& options); std::string to_output_string(RequestType request_type, const CStringView s); struct AnyParagraph @@ -63,6 +67,7 @@ namespace vcpkg::Dependencies AnyParagraph any_paragraph; InstallPlanType plan_type; RequestType request_type; + Build::BuildPackageOptions build_options; std::unordered_set feature_list; }; diff --git a/toolsrc/include/vcpkg/install.h b/toolsrc/include/vcpkg/install.h index 895028865..7bf823e99 100644 --- a/toolsrc/include/vcpkg/install.h +++ b/toolsrc/include/vcpkg/install.h @@ -53,7 +53,6 @@ namespace vcpkg::Install Build::BuildResult perform_install_plan_action(const VcpkgPaths& paths, const Dependencies::InstallPlanAction& action, - const Build::BuildPackageOptions& install_plan_options, StatusParagraphs& status_db); enum class InstallResult @@ -70,7 +69,6 @@ namespace vcpkg::Install StatusParagraphs* status_db); InstallSummary perform(const std::vector& action_plan, - const Build::BuildPackageOptions& install_plan_options, const KeepGoing keep_going, const VcpkgPaths& paths, StatusParagraphs& status_db); diff --git a/toolsrc/src/vcpkg/commands.ci.cpp b/toolsrc/src/vcpkg/commands.ci.cpp index 559dc4541..d012ff6dc 100644 --- a/toolsrc/src/vcpkg/commands.ci.cpp +++ b/toolsrc/src/vcpkg/commands.ci.cpp @@ -44,11 +44,12 @@ namespace vcpkg::Commands::CI const Build::BuildPackageOptions install_plan_options = {Build::UseHeadVersion::NO, Build::AllowDownloads::YES}; const std::vector action_plan = - Util::fmap(install_plan, [](InstallPlanAction& install_action) { + Util::fmap(install_plan, [&install_plan_options](InstallPlanAction& install_action) { + install_action.build_options = install_plan_options; return Dependencies::AnyAction(std::move(install_action)); }); - return Install::perform(action_plan, install_plan_options, Install::KeepGoing::YES, paths, status_db); + return Install::perform(action_plan, Install::KeepGoing::YES, paths, status_db); } struct TripletAndSummary diff --git a/toolsrc/src/vcpkg/dependencies.cpp b/toolsrc/src/vcpkg/dependencies.cpp index 4c4a8a31c..6f599afd4 100644 --- a/toolsrc/src/vcpkg/dependencies.cpp +++ b/toolsrc/src/vcpkg/dependencies.cpp @@ -133,6 +133,20 @@ namespace vcpkg::Dependencies "Cannot get dependencies because there was none of: source/binary/status paragraphs"); } + std::string to_output_string(RequestType request_type, + const CStringView s, + const Build::BuildPackageOptions& options) + { + const char* const from_head = options.use_head_version == Build::UseHeadVersion::YES ? " (from HEAD)" : ""; + + switch (request_type) + { + case RequestType::AUTO_SELECTED: return Strings::format(" * %s%s", s, from_head); + case RequestType::USER_REQUESTED: return Strings::format(" %s%s", s, from_head); + default: Checks::unreachable(VCPKG_LINE_INFO); + } + } + std::string to_output_string(RequestType request_type, const CStringView s) { switch (request_type) diff --git a/toolsrc/src/vcpkg/export.cpp b/toolsrc/src/vcpkg/export.cpp index f0a3b23d0..eb4f5db3c 100644 --- a/toolsrc/src/vcpkg/export.cpp +++ b/toolsrc/src/vcpkg/export.cpp @@ -68,6 +68,8 @@ namespace vcpkg::Export { static constexpr std::array ORDER = {ExportPlanType::ALREADY_BUILT, ExportPlanType::PORT_AVAILABLE_BUT_NOT_BUILT}; + static constexpr Build::BuildPackageOptions build_options = {Build::UseHeadVersion::NO, + Build::AllowDownloads::YES}; for (const ExportPlanType plan_type : ORDER) { @@ -80,7 +82,7 @@ namespace vcpkg::Export std::vector cont = it->second; std::sort(cont.begin(), cont.end(), &ExportPlanAction::compare_by_name); const std::string as_string = Strings::join("\n", cont, [](const ExportPlanAction* p) { - return Dependencies::to_output_string(p->request_type, p->spec.to_string()); + return Dependencies::to_output_string(p->request_type, p->spec.to_string(), build_options); }); switch (plan_type) diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp index 7bab740be..b1f722d59 100644 --- a/toolsrc/src/vcpkg/install.cpp +++ b/toolsrc/src/vcpkg/install.cpp @@ -250,7 +250,6 @@ namespace vcpkg::Install BuildResult perform_install_plan_action(const VcpkgPaths& paths, const InstallPlanAction& action, - const Build::BuildPackageOptions& build_package_options, StatusParagraphs& status_db) { const InstallPlanType& plan_type = action.plan_type; @@ -259,7 +258,7 @@ namespace vcpkg::Install GlobalState::feature_packages ? action.displayname() : display_name; const bool is_user_requested = action.request_type == RequestType::USER_REQUESTED; - const bool use_head_version = to_bool(build_package_options.use_head_version); + const bool use_head_version = to_bool(action.build_options.use_head_version); if (plan_type == InstallPlanType::ALREADY_INSTALLED) { @@ -285,7 +284,7 @@ namespace vcpkg::Install *action.any_paragraph.source_control_file.value_or_exit(VCPKG_LINE_INFO), action.spec.triplet(), paths.port_dir(action.spec), - build_package_options, + action.build_options, action.feature_list}; return Build::build_package(paths, build_config, status_db); } @@ -295,7 +294,7 @@ namespace vcpkg::Install action.any_paragraph.source_paragraph.value_or_exit(VCPKG_LINE_INFO), action.spec.triplet(), paths.port_dir(action.spec), - build_package_options}; + action.build_options}; return Build::build_package(paths, build_config, status_db); } }(); @@ -407,46 +406,38 @@ namespace vcpkg::Install std::sort(already_installed_plans.begin(), already_installed_plans.end(), &InstallPlanAction::compare_by_name); std::sort(excluded.begin(), excluded.end(), &InstallPlanAction::compare_by_name); + static auto actions_to_output_string = [](const std::vector& v) { + return Strings::join("\n", v, [](const InstallPlanAction* p) { + return to_output_string(p->request_type, p->displayname(), p->build_options); + }); + }; + if (excluded.size() > 0) { - const std::string excluded_string = Strings::join("\n", excluded, [](const InstallPlanAction* p) { - return to_output_string(p->request_type, p->displayname()); - }); - System::println("The following packages are excluded:\n%s", excluded_string); + System::println("The following packages are excluded:\n%s", actions_to_output_string(excluded)); } if (already_installed_plans.size() > 0) { - const std::string already_string = - Strings::join("\n", already_installed_plans, [](const InstallPlanAction* p) { - return to_output_string(p->request_type, p->displayname()); - }); - System::println("The following packages are already installed:\n%s", already_string); + System::println("The following packages are already installed:\n%s", + actions_to_output_string(already_installed_plans)); } if (rebuilt_plans.size() > 0) { - const std::string rebuilt_string = Strings::join("\n", rebuilt_plans, [](const InstallPlanAction* p) { - return to_output_string(p->request_type, p->displayname()); - }); - System::println("The following packages will be rebuilt:\n%s", rebuilt_string); + System::println("The following packages will be rebuilt:\n%s", actions_to_output_string(rebuilt_plans)); } if (new_plans.size() > 0) { - const std::string new_string = Strings::join("\n", new_plans, [](const InstallPlanAction* p) { - return to_output_string(p->request_type, p->displayname()); - }); - System::println("The following packages will be built and installed:\n%s", new_string); + System::println("The following packages will be built and installed:\n%s", + actions_to_output_string(new_plans)); } if (only_install_plans.size() > 0) { - const std::string only_install_string = - Strings::join("\n", only_install_plans, [](const InstallPlanAction* p) { - return to_output_string(p->request_type, p->displayname()); - }); - System::println("The following packages will be directly installed:\n%s", only_install_string); + System::println("The following packages will be directly installed:\n%s", + actions_to_output_string(only_install_plans)); } if (has_non_user_requested_packages) @@ -489,7 +480,6 @@ namespace vcpkg::Install } InstallSummary perform(const std::vector& action_plan, - const Build::BuildPackageOptions& install_plan_options, const KeepGoing keep_going, const VcpkgPaths& paths, StatusParagraphs& status_db) @@ -513,8 +503,7 @@ namespace vcpkg::Install if (const auto install_action = action.install_plan.get()) { - const BuildResult result = - perform_install_plan_action(paths, *install_action, install_plan_options, status_db); + const BuildResult result = perform_install_plan_action(paths, *install_action, status_db); if (result != BuildResult::SUCCEEDED && keep_going == KeepGoing::NO) { System::println(Build::create_user_troubleshooting_message(install_action->spec)); @@ -629,6 +618,16 @@ namespace vcpkg::Install install_plan, [](InstallPlanAction& install_action) { return AnyAction(std::move(install_action)); }); } + for (auto&& action : action_plan) + { + if (auto p_install = action.install_plan.get()) + { + p_install->build_options = install_plan_options; + if (p_install->request_type != RequestType::USER_REQUESTED) + p_install->build_options.use_head_version = Build::UseHeadVersion::NO; + } + } + // install plan will be empty if it is already installed - need to change this at status paragraph part Checks::check_exit(VCPKG_LINE_INFO, !action_plan.empty(), "Install plan cannot be empty"); @@ -650,7 +649,7 @@ namespace vcpkg::Install Checks::exit_success(VCPKG_LINE_INFO); } - const InstallSummary summary = perform(action_plan, install_plan_options, keep_going, paths, status_db); + const InstallSummary summary = perform(action_plan, keep_going, paths, status_db); System::println("\nTotal elapsed time: %s", summary.total_elapsed_time); -- cgit v1.2.3 From a705df80b0f8db81b201492b4012e23e08a53694 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Tue, 31 Oct 2017 03:47:35 -0700 Subject: [vcpkg] Fix bug where packages with uninstalled features appear to be uninstalled. --- toolsrc/include/vcpkg/statusparagraphs.h | 6 +- toolsrc/src/tests.statusparagraphs.cpp | 85 +++++++++++++++++++++++++++++ toolsrc/src/vcpkg/statusparagraphs.cpp | 26 ++++----- toolsrc/vcpkgtest/vcpkgtest.vcxproj | 1 + toolsrc/vcpkgtest/vcpkgtest.vcxproj.filters | 3 + 5 files changed, 102 insertions(+), 19 deletions(-) create mode 100644 toolsrc/src/tests.statusparagraphs.cpp (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/statusparagraphs.h b/toolsrc/include/vcpkg/statusparagraphs.h index c2f3b7b8e..747a0c1ab 100644 --- a/toolsrc/include/vcpkg/statusparagraphs.h +++ b/toolsrc/include/vcpkg/statusparagraphs.h @@ -16,10 +16,10 @@ namespace vcpkg using const_iterator = container::const_reverse_iterator; const_iterator find(const PackageSpec& spec) const { return find(spec.name(), spec.triplet()); } - const_iterator find(const std::string& name, const Triplet& triplet) const; - iterator find(const std::string& name, const Triplet& triplet); + iterator find(const std::string& name, const Triplet& triplet, const std::string& feature = ""); + const_iterator find(const std::string& name, const Triplet& triplet, const std::string& feature = "") const; + std::vector*> find_all(const std::string& name, const Triplet& triplet); - iterator find(const std::string& name, const Triplet& triplet, const std::string& feature); const_iterator find_installed(const PackageSpec& spec) const { diff --git a/toolsrc/src/tests.statusparagraphs.cpp b/toolsrc/src/tests.statusparagraphs.cpp new file mode 100644 index 000000000..4cc1130b1 --- /dev/null +++ b/toolsrc/src/tests.statusparagraphs.cpp @@ -0,0 +1,85 @@ +#include + +#include +#include +#include +#include + +using namespace Microsoft::VisualStudio::CppUnitTestFramework; + +using namespace vcpkg; +using namespace vcpkg::Paragraphs; + +namespace UnitTest1 +{ + class StatusParagraphsTests : public TestClass + { + TEST_METHOD(find_installed) + { + auto pghs = parse_paragraphs(R"( +Package: ffmpeg +Version: 3.3.3 +Architecture: x64-windows +Multi-Arch: same +Description: +Status: install ok installed +)"); + Assert::IsTrue(!!pghs); + if (!pghs) return; + + StatusParagraphs status_db(Util::fmap( + *pghs.get(), [](RawParagraph& rpgh) { return std::make_unique(std::move(rpgh)); })); + + auto it = status_db.find_installed("ffmpeg", Triplet::X64_WINDOWS); + Assert::IsTrue(it != status_db.end()); + } + + TEST_METHOD(find_not_installed) + { + auto pghs = parse_paragraphs(R"( +Package: ffmpeg +Version: 3.3.3 +Architecture: x64-windows +Multi-Arch: same +Description: +Status: purge ok not-installed +)"); + Assert::IsTrue(!!pghs); + if (!pghs) return; + + StatusParagraphs status_db(Util::fmap( + *pghs.get(), [](RawParagraph& rpgh) { return std::make_unique(std::move(rpgh)); })); + + auto it = status_db.find_installed("ffmpeg", Triplet::X64_WINDOWS); + Assert::IsTrue(it == status_db.end()); + } + + TEST_METHOD(find_with_feature_packages) + { + auto pghs = parse_paragraphs(R"( +Package: ffmpeg +Version: 3.3.3 +Architecture: x64-windows +Multi-Arch: same +Description: +Status: install ok installed + +Package: ffmpeg +Feature: openssl +Depends: openssl +Architecture: x64-windows +Multi-Arch: same +Description: +Status: purge ok not-installed +)"); + Assert::IsTrue(!!pghs); + if (!pghs) return; + + StatusParagraphs status_db(Util::fmap( + *pghs.get(), [](RawParagraph& rpgh) { return std::make_unique(std::move(rpgh)); })); + + auto it = status_db.find_installed("ffmpeg", Triplet::X64_WINDOWS); + Assert::IsTrue(it != status_db.end()); + } + }; +} \ No newline at end of file diff --git a/toolsrc/src/vcpkg/statusparagraphs.cpp b/toolsrc/src/vcpkg/statusparagraphs.cpp index 647ed6d3f..d4afc0427 100644 --- a/toolsrc/src/vcpkg/statusparagraphs.cpp +++ b/toolsrc/src/vcpkg/statusparagraphs.cpp @@ -10,22 +10,6 @@ namespace vcpkg StatusParagraphs::StatusParagraphs(std::vector>&& ps) : paragraphs(std::move(ps)){}; - StatusParagraphs::const_iterator StatusParagraphs::find(const std::string& name, const Triplet& triplet) const - { - return std::find_if(begin(), end(), [&](const std::unique_ptr& pgh) { - const PackageSpec& spec = pgh->package.spec; - return spec.name() == name && spec.triplet() == triplet; - }); - } - - StatusParagraphs::iterator StatusParagraphs::find(const std::string& name, const Triplet& triplet) - { - return std::find_if(begin(), end(), [&](const std::unique_ptr& pgh) { - const PackageSpec& spec = pgh->package.spec; - return spec.name() == name && spec.triplet() == triplet; - }); - } - std::vector*> StatusParagraphs::find_all(const std::string& name, const Triplet& triplet) { @@ -50,6 +34,16 @@ namespace vcpkg }); } + StatusParagraphs::const_iterator StatusParagraphs::find(const std::string& name, + const Triplet& triplet, + const std::string& feature) const + { + return std::find_if(begin(), end(), [&](const std::unique_ptr& pgh) { + const PackageSpec& spec = pgh->package.spec; + return spec.name() == name && spec.triplet() == triplet && pgh->package.feature == feature; + }); + } + StatusParagraphs::const_iterator StatusParagraphs::find_installed(const std::string& name, const Triplet& triplet) const { diff --git a/toolsrc/vcpkgtest/vcpkgtest.vcxproj b/toolsrc/vcpkgtest/vcpkgtest.vcxproj index d25748124..766b4bf67 100644 --- a/toolsrc/vcpkgtest/vcpkgtest.vcxproj +++ b/toolsrc/vcpkgtest/vcpkgtest.vcxproj @@ -24,6 +24,7 @@ + diff --git a/toolsrc/vcpkgtest/vcpkgtest.vcxproj.filters b/toolsrc/vcpkgtest/vcpkgtest.vcxproj.filters index 42691c614..b6f1ced06 100644 --- a/toolsrc/vcpkgtest/vcpkgtest.vcxproj.filters +++ b/toolsrc/vcpkgtest/vcpkgtest.vcxproj.filters @@ -30,5 +30,8 @@ Source Files + + Source Files + \ No newline at end of file -- cgit v1.2.3 From 7d0bcceaf028f28b0bc5ae666689f26d8de743a9 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 31 Oct 2017 17:06:07 -0700 Subject: [findVSInstances] Data lines are now placed within tags. Text outside these tags is ignored This means we can print text in powershell now and it won't break vcpkg. --- toolsrc/src/vcpkg/vcpkgpaths.cpp | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index c6a92f813..8b9e6c598 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -320,6 +320,23 @@ namespace vcpkg std::string major_version() const { return version.substr(0, 2); } }; + static std::vector keep_data_lines(const std::string& data_blob) + { + static const std::regex DATA_LINE_REGEX(R"(::(.+?)(?=::))"); + + std::vector data_lines; + + const std::sregex_iterator it(data_blob.cbegin(), data_blob.cend(), DATA_LINE_REGEX); + const std::sregex_iterator end; + for (std::sregex_iterator i = it; i != end; ++i) + { + const std::smatch match = *i; + data_lines.push_back(match[1].str()); + } + + return data_lines; + } + static std::vector get_visual_studio_instances(const VcpkgPaths& paths) { const fs::path script = paths.scripts / "findVisualStudioInstallationInstances.ps1"; @@ -327,9 +344,11 @@ namespace vcpkg Checks::check_exit( VCPKG_LINE_INFO, ec_data.exit_code == 0, "Could not run script to detect Visual Studio instances"); - const std::vector instances_as_strings = Strings::split(ec_data.output, "::"); - Checks::check_exit( - VCPKG_LINE_INFO, !instances_as_strings.empty(), "Could not detect any Visual Studio instances.\n"); + const std::vector instances_as_strings = keep_data_lines(ec_data.output); + Checks::check_exit(VCPKG_LINE_INFO, + !instances_as_strings.empty(), + "Could not detect any Visual Studio instances. Powershell returned: %s\n", + ec_data.output); std::vector output; for (const std::string& instance_as_string : instances_as_strings) -- cgit v1.2.3 From 47bf4b6b5caf44adeaf582e5137377fb9d2cc5c4 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 31 Oct 2017 17:23:09 -0700 Subject: [fetchDependency] Now also returns output in the form data --- toolsrc/src/vcpkg/vcpkgpaths.cpp | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index 8b9e6c598..40f52af73 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -62,6 +62,23 @@ namespace vcpkg return nullopt; } + static std::vector keep_data_lines(const std::string& data_blob) + { + static const std::regex DATA_LINE_REGEX(R"(::(.+?)(?=::))"); + + std::vector data_lines; + + const std::sregex_iterator it(data_blob.cbegin(), data_blob.cend(), DATA_LINE_REGEX); + const std::sregex_iterator end; + for (std::sregex_iterator i = it; i != end; ++i) + { + const std::smatch match = *i; + data_lines.push_back(match[1].str()); + } + + return data_lines; + } + static fs::path fetch_dependency(const fs::path& scripts_folder, const std::string& tool_name, const fs::path& expected_downloaded_path, @@ -91,7 +108,11 @@ namespace vcpkg Checks::exit_with_code(VCPKG_LINE_INFO, rc.exit_code); } - const fs::path actual_downloaded_path = Strings::trim(std::string{rc.output}); + const std::vector dependency_path = keep_data_lines(rc.output); + Checks::check_exit( + VCPKG_LINE_INFO, dependency_path.size() == 1, "Expected dependency path, but got %s", rc.output); + + const fs::path actual_downloaded_path = Strings::trim(std::string{dependency_path.at(0)}); std::error_code ec; const auto eq = fs::stdfs::equivalent(expected_downloaded_path, actual_downloaded_path, ec); Checks::check_exit(VCPKG_LINE_INFO, @@ -320,23 +341,6 @@ namespace vcpkg std::string major_version() const { return version.substr(0, 2); } }; - static std::vector keep_data_lines(const std::string& data_blob) - { - static const std::regex DATA_LINE_REGEX(R"(::(.+?)(?=::))"); - - std::vector data_lines; - - const std::sregex_iterator it(data_blob.cbegin(), data_blob.cend(), DATA_LINE_REGEX); - const std::sregex_iterator end; - for (std::sregex_iterator i = it; i != end; ++i) - { - const std::smatch match = *i; - data_lines.push_back(match[1].str()); - } - - return data_lines; - } - static std::vector get_visual_studio_instances(const VcpkgPaths& paths) { const fs::path script = paths.scripts / "findVisualStudioInstallationInstances.ps1"; -- cgit v1.2.3 From a5b54588eca1d57366f7052ee9ab30da4ba68066 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 31 Oct 2017 17:30:29 -0700 Subject: [git] Update to 2.15.0 (was 2.14.3) --- toolsrc/src/vcpkg/vcpkgpaths.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index 40f52af73..5e43ee4c7 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -171,10 +171,10 @@ namespace vcpkg fs::path get_git_path(const fs::path& downloads_folder, const fs::path& scripts_folder) { - static constexpr std::array EXPECTED_VERSION = {2, 14, 3}; + static constexpr std::array EXPECTED_VERSION = {2, 15, 0}; static const std::string VERSION_CHECK_ARGUMENTS = "--version"; - const fs::path downloaded_copy = downloads_folder / "MinGit-2.14.3-32-bit" / "cmd" / "git.exe"; + const fs::path downloaded_copy = downloads_folder / "MinGit-2.15.0-32-bit" / "cmd" / "git.exe"; const std::vector from_path = Files::find_from_PATH("git"); std::vector candidate_paths; -- cgit v1.2.3 From 47090e68b8deeb5a38b638934b59fe3ddef0fa9f Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Wed, 1 Nov 2017 06:03:10 -0700 Subject: [vcpkg] Fix use of features in undocumented build command --- toolsrc/src/vcpkg/build.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index 30a6a791c..c59b6f7d1 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -52,22 +52,20 @@ namespace vcpkg::Build::Command Checks::exit_fail(VCPKG_LINE_INFO); } - for (const std::string& str : full_spec.features) - { - System::println("%s \n", str); - } const auto& scf = source_control_file.value_or_exit(VCPKG_LINE_INFO); Checks::check_exit(VCPKG_LINE_INFO, spec.name() == scf->core_paragraph->name, - "The Name: field inside the CONTROL does not match the port directory: '%s' != '%s'", + "The Source field inside the CONTROL file does not match the port directory: '%s' != '%s'", scf->core_paragraph->name, spec.name()); const StatusParagraphs status_db = database_load_check(paths); const Build::BuildPackageOptions build_package_options{Build::UseHeadVersion::NO, Build::AllowDownloads::YES}; + const std::unordered_set features_as_set(full_spec.features.begin(), full_spec.features.end()); + const Build::BuildPackageConfig build_config{ - *scf->core_paragraph, spec.triplet(), paths.port_dir(spec), build_package_options}; + *scf, spec.triplet(), fs::path{port_dir}, build_package_options, features_as_set}; const auto build_timer = Chrono::ElapsedTime::create_started(); const auto result = Build::build_package(paths, build_config, status_db); @@ -107,6 +105,11 @@ namespace vcpkg::Build::Command const std::string command_argument = args.command_arguments.at(0); const FullPackageSpec spec = Input::check_and_get_full_package_spec(command_argument, default_triplet, EXAMPLE); Input::check_triplet(spec.package_spec.triplet(), paths); + if (!spec.features.empty() && !GlobalState::feature_packages) + { + Checks::exit_with_message( + VCPKG_LINE_INFO, "Feature packages are experimentally available under the --featurepackages flag."); + } const ParsedArguments options = args.check_and_get_optional_command_arguments({OPTION_CHECKS_ONLY}, {}); perform_and_exit(spec, paths.port_dir(spec.package_spec), options, paths); } -- cgit v1.2.3 From 2e48ccb8a4db43f63dc25748732b529a9972bbfc Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 1 Nov 2017 15:28:51 -0700 Subject: Update CHANGELOG and bump version to v0.0.95 --- toolsrc/VERSION.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/VERSION.txt b/toolsrc/VERSION.txt index ac2866fef..e5fce74a7 100644 --- a/toolsrc/VERSION.txt +++ b/toolsrc/VERSION.txt @@ -1 +1 @@ -"0.0.94" \ No newline at end of file +"0.0.95" \ No newline at end of file -- cgit v1.2.3 From 6a91d1ece10ce0aeda89c44611d5335a07b8e40d Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Thu, 2 Nov 2017 15:20:42 -0700 Subject: [vcpkg] Refactor argument parsing to use common code paths. --- toolsrc/include/vcpkg/base/span.h | 12 +++ toolsrc/include/vcpkg/base/util.h | 2 +- toolsrc/include/vcpkg/build.h | 8 +- toolsrc/include/vcpkg/commands.h | 7 ++ toolsrc/include/vcpkg/vcpkgcmdarguments.h | 65 +++++++----- toolsrc/src/tests.arguments.cpp | 11 +- toolsrc/src/vcpkg/build.cpp | 29 ++++-- toolsrc/src/vcpkg/commands.autocomplete.cpp | 10 +- toolsrc/src/vcpkg/commands.buildexternal.cpp | 20 ++-- toolsrc/src/vcpkg/commands.cache.cpp | 16 ++- toolsrc/src/vcpkg/commands.ci.cpp | 20 +++- toolsrc/src/vcpkg/commands.contact.cpp | 12 ++- toolsrc/src/vcpkg/commands.cpp | 2 +- toolsrc/src/vcpkg/commands.create.cpp | 15 ++- toolsrc/src/vcpkg/commands.dependinfo.cpp | 12 ++- toolsrc/src/vcpkg/commands.edit.cpp | 18 ++-- toolsrc/src/vcpkg/commands.env.cpp | 12 ++- toolsrc/src/vcpkg/commands.hash.cpp | 15 ++- toolsrc/src/vcpkg/commands.import.cpp | 14 ++- toolsrc/src/vcpkg/commands.integrate.cpp | 13 +-- toolsrc/src/vcpkg/commands.list.cpp | 20 +++- toolsrc/src/vcpkg/commands.owns.cpp | 13 ++- toolsrc/src/vcpkg/commands.portsdiff.cpp | 15 ++- toolsrc/src/vcpkg/commands.search.cpp | 22 ++-- toolsrc/src/vcpkg/commands.version.cpp | 11 +- toolsrc/src/vcpkg/export.cpp | 80 ++++++++------- toolsrc/src/vcpkg/help.cpp | 11 +- toolsrc/src/vcpkg/install.cpp | 26 ++--- toolsrc/src/vcpkg/remove.cpp | 42 ++++---- toolsrc/src/vcpkg/update.cpp | 11 +- toolsrc/src/vcpkg/vcpkgcmdarguments.cpp | 147 ++++++++++++--------------- 31 files changed, 424 insertions(+), 287 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/base/span.h b/toolsrc/include/vcpkg/base/span.h index 6be546351..158f1ac74 100644 --- a/toolsrc/include/vcpkg/base/span.h +++ b/toolsrc/include/vcpkg/base/span.h @@ -57,4 +57,16 @@ namespace vcpkg { return {v.data(), v.size()}; } + + template + constexpr T* begin(Span sp) + { + return sp.begin(); + } + + template + constexpr T* end(Span sp) + { + return sp.end(); + } } \ No newline at end of file diff --git a/toolsrc/include/vcpkg/base/util.h b/toolsrc/include/vcpkg/base/util.h index e67d38ad8..155b16cf7 100644 --- a/toolsrc/include/vcpkg/base/util.h +++ b/toolsrc/include/vcpkg/base/util.h @@ -30,7 +30,7 @@ namespace vcpkg::Util } template - using FmapOut = decltype(std::declval()(*begin(std::declval()))); + using FmapOut = decltype(std::declval()(*begin(std::declval()))); template> std::vector fmap(Cont&& xs, Func&& f) diff --git a/toolsrc/include/vcpkg/build.h b/toolsrc/include/vcpkg/build.h index 94d9fddf5..824f3ccaf 100644 --- a/toolsrc/include/vcpkg/build.h +++ b/toolsrc/include/vcpkg/build.h @@ -18,10 +18,10 @@ namespace vcpkg::Build { namespace Command { - void perform_and_exit(const FullPackageSpec& full_spec, - const fs::path& port_dir, - const ParsedArguments& options, - const VcpkgPaths& paths); + void perform_and_exit_ex(const FullPackageSpec& full_spec, + const fs::path& port_dir, + const ParsedArguments& options, + const VcpkgPaths& paths); void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet); } diff --git a/toolsrc/include/vcpkg/commands.h b/toolsrc/include/vcpkg/commands.h index d9ebad2c4..74fd80c03 100644 --- a/toolsrc/include/vcpkg/commands.h +++ b/toolsrc/include/vcpkg/commands.h @@ -23,16 +23,19 @@ namespace vcpkg::Commands namespace CI { + extern const CommandStructure COMMAND_STRUCTURE; void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet); } namespace Env { + extern const CommandStructure COMMAND_STRUCTURE; void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet); } namespace Create { + extern const CommandStructure COMMAND_STRUCTURE; void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); } @@ -49,16 +52,19 @@ namespace vcpkg::Commands namespace Search { + extern const CommandStructure COMMAND_STRUCTURE; void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); } namespace List { + extern const CommandStructure COMMAND_STRUCTURE; void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); } namespace Owns { + extern const CommandStructure COMMAND_STRUCTURE; void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); } @@ -99,6 +105,7 @@ namespace vcpkg::Commands namespace Contact { + extern const CommandStructure COMMAND_STRUCTURE; const std::string& email(); void perform_and_exit(const VcpkgCmdArguments& args); } diff --git a/toolsrc/include/vcpkg/vcpkgcmdarguments.h b/toolsrc/include/vcpkg/vcpkgcmdarguments.h index e59979ad1..a832caf04 100644 --- a/toolsrc/include/vcpkg/vcpkgcmdarguments.h +++ b/toolsrc/include/vcpkg/vcpkgcmdarguments.h @@ -17,13 +17,47 @@ namespace vcpkg std::unordered_map settings; }; - struct VcpkgCmdArguments + struct VcpkgPaths; + + struct CommandSwitch + { + std::string name; + CStringView short_help_text; + }; + + struct CommandSetting { + std::string name; + CStringView short_help_text; + }; + + struct CommandOptionsStructure + { + Span switches; + Span settings; + }; + + struct CommandStructure + { + std::string example_text; + + size_t minimum_arity; + size_t maximum_arity; + + CommandOptionsStructure options; + + std::vector (*valid_arguments)(const VcpkgPaths& paths); + }; + #if defined(_WIN32) - static VcpkgCmdArguments create_from_command_line(const int argc, const wchar_t* const* const argv); + using CommandLineCharType = wchar_t; #else - static VcpkgCmdArguments create_from_command_line(const int argc, const char* const* const argv); + using CommandLineCharType = char; #endif + + struct VcpkgCmdArguments + { + static VcpkgCmdArguments create_from_command_line(const int argc, const CommandLineCharType* const* const argv); static VcpkgCmdArguments create_from_arg_sequence(const std::string* arg_begin, const std::string* arg_end); std::unique_ptr vcpkg_root_dir; @@ -35,32 +69,9 @@ namespace vcpkg std::string command; std::vector command_arguments; - ParsedArguments check_and_get_optional_command_arguments(const std::vector& valid_switches, - const std::vector& valid_settings) const; - - void check_max_arg_count(const size_t expected_arg_count) const; - void check_max_arg_count(const size_t expected_arg_count, const std::string& example_text) const; - void check_min_arg_count(const size_t expected_arg_count) const; - void check_min_arg_count(const size_t expected_arg_count, const std::string& example_text) const; - void check_exact_arg_count(const size_t expected_arg_count) const; - void check_exact_arg_count(const size_t expected_arg_count, const std::string& example_text) const; + ParsedArguments parse_arguments(const CommandStructure& command_structure) const; private: std::unordered_map> optional_command_arguments; }; - - struct VcpkgPaths; - - struct CommandStructure - { - CStringView example_text; - - size_t minimum_arity; - size_t maximum_arity; - - Span switches; - Span settings; - - std::vector (*valid_arguments)(const VcpkgPaths& paths); - }; } diff --git a/toolsrc/src/tests.arguments.cpp b/toolsrc/src/tests.arguments.cpp index 25bf0f085..0f082222d 100644 --- a/toolsrc/src/tests.arguments.cpp +++ b/toolsrc/src/tests.arguments.cpp @@ -34,9 +34,12 @@ namespace UnitTest1 TEST_METHOD(create_from_arg_sequence_valued_options) { + std::array settings = { {{"--a", ""}} }; + CommandStructure cmdstruct = { "", 0, SIZE_MAX, {{}, settings }, nullptr }; + std::vector t = {"--a=b", "command", "argument"}; auto v = VcpkgCmdArguments::create_from_arg_sequence(t.data(), t.data() + t.size()); - auto opts = v.check_and_get_optional_command_arguments({}, {"--a"}); + auto opts = v.parse_arguments(cmdstruct); Assert::AreEqual("b", opts.settings["--a"].c_str()); Assert::AreEqual(size_t{1}, v.command_arguments.size()); Assert::AreEqual("argument", v.command_arguments[0].c_str()); @@ -45,9 +48,13 @@ namespace UnitTest1 TEST_METHOD(create_from_arg_sequence_valued_options2) { + std::array switches = { {{"--a", ""}, {"--c", ""}} }; + std::array settings = { { {"--b", ""}, {"--d", ""}} }; + CommandStructure cmdstruct = {"", 0, SIZE_MAX, {switches, settings}, nullptr}; + std::vector t = {"--a", "--b=c"}; auto v = VcpkgCmdArguments::create_from_arg_sequence(t.data(), t.data() + t.size()); - auto opts = v.check_and_get_optional_command_arguments({"--a", "--c"}, {"--b", "--d"}); + auto opts = v.parse_arguments(cmdstruct); Assert::AreEqual("c", opts.settings["--b"].c_str()); Assert::IsTrue(opts.settings.find("--d") == opts.settings.end()); Assert::IsTrue(opts.switches.find("--a") != opts.switches.end()); diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index c59b6f7d1..8b4654aa8 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -28,10 +28,10 @@ namespace vcpkg::Build::Command static const std::string OPTION_CHECKS_ONLY = "--checks-only"; - void perform_and_exit(const FullPackageSpec& full_spec, - const fs::path& port_dir, - const ParsedArguments& options, - const VcpkgPaths& paths) + void perform_and_exit_ex(const FullPackageSpec& full_spec, + const fs::path& port_dir, + const ParsedArguments& options, + const VcpkgPaths& paths) { const PackageSpec& spec = full_spec.package_spec; if (Util::Sets::contains(options.switches, OPTION_CHECKS_ONLY)) @@ -97,21 +97,32 @@ namespace vcpkg::Build::Command Checks::exit_success(VCPKG_LINE_INFO); } + static const std::array BUILD_SWITCHES = {{ + {OPTION_CHECKS_ONLY, "Only run checks, do not rebuild package"}, + }}; + + const CommandStructure COMMAND_STRUCTURE = { + Help::create_example_string("build zlib:x64-windows"), + 1, + 1, + {BUILD_SWITCHES, {}}, + nullptr, + }; + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) { - static const std::string EXAMPLE = Help::create_example_string("build zlib:x64-windows"); // Build only takes a single package and all dependencies must already be installed - args.check_exact_arg_count(1, EXAMPLE); + const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE); const std::string command_argument = args.command_arguments.at(0); - const FullPackageSpec spec = Input::check_and_get_full_package_spec(command_argument, default_triplet, EXAMPLE); + const FullPackageSpec spec = + Input::check_and_get_full_package_spec(command_argument, default_triplet, COMMAND_STRUCTURE.example_text); Input::check_triplet(spec.package_spec.triplet(), paths); if (!spec.features.empty() && !GlobalState::feature_packages) { Checks::exit_with_message( VCPKG_LINE_INFO, "Feature packages are experimentally available under the --featurepackages flag."); } - const ParsedArguments options = args.check_and_get_optional_command_arguments({OPTION_CHECKS_ONLY}, {}); - perform_and_exit(spec, paths.port_dir(spec.package_spec), options, paths); + perform_and_exit_ex(spec, paths.port_dir(spec.package_spec), options, paths); } } diff --git a/toolsrc/src/vcpkg/commands.autocomplete.cpp b/toolsrc/src/vcpkg/commands.autocomplete.cpp index 410bfcd0d..0df7ec5eb 100644 --- a/toolsrc/src/vcpkg/commands.autocomplete.cpp +++ b/toolsrc/src/vcpkg/commands.autocomplete.cpp @@ -120,7 +120,6 @@ namespace vcpkg::Commands::Autocomplete }; static constexpr CommandEntry COMMANDS[] = { - CommandEntry{"install", R"###(^install\s(.*\s|)(\S*)$)###", Install::COMMAND_STRUCTURE}, CommandEntry{"install", R"###(^install\s(.*\s|)(\S*)$)###", Install::COMMAND_STRUCTURE}, CommandEntry{"edit", R"###(^edit\s(.*\s|)(\S*)$)###", Edit::COMMAND_STRUCTURE}, CommandEntry{"remove", R"###(^remove\s(.*\s|)(\S*)$)###", Remove::COMMAND_STRUCTURE}, @@ -137,11 +136,16 @@ namespace vcpkg::Commands::Autocomplete const bool is_option = Strings::case_insensitive_ascii_starts_with(prefix, "-"); if (is_option) { - results = Util::fmap(command.structure.switches, [](auto&& s) -> std::string { return s; }); + results = + Util::fmap(command.structure.options.switches, [](const CommandSwitch& s) { return s.name; }); + + auto settings = Util::fmap(command.structure.options.settings, [](auto&& s) { return s.name; }); + results.insert(results.end(), settings.begin(), settings.end()); } else { - results = command.structure.valid_arguments(paths); + if (command.structure.valid_arguments != nullptr) + results = command.structure.valid_arguments(paths); } Util::unstable_keep_if(results, [&](const std::string& s) { diff --git a/toolsrc/src/vcpkg/commands.buildexternal.cpp b/toolsrc/src/vcpkg/commands.buildexternal.cpp index 2cc7aabde..82d03db48 100644 --- a/toolsrc/src/vcpkg/commands.buildexternal.cpp +++ b/toolsrc/src/vcpkg/commands.buildexternal.cpp @@ -7,17 +7,23 @@ namespace vcpkg::Commands::BuildExternal { + const CommandStructure COMMAND_STRUCTURE = { + Help::create_example_string(R"(build_external zlib2 C:\path\to\dir\with\controlfile\)"), + 2, + 2, + {}, + nullptr, + }; + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) { - static const std::string EXAMPLE = - Help::create_example_string(R"(build_external zlib2 C:\path\to\dir\with\controlfile\)"); - args.check_exact_arg_count(2, EXAMPLE); - const FullPackageSpec spec = - Input::check_and_get_full_package_spec(args.command_arguments.at(0), default_triplet, EXAMPLE); + const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE); + + const FullPackageSpec spec = Input::check_and_get_full_package_spec( + args.command_arguments.at(0), default_triplet, COMMAND_STRUCTURE.example_text); Input::check_triplet(spec.package_spec.triplet(), paths); - const ParsedArguments options = args.check_and_get_optional_command_arguments({}, {}); const fs::path port_dir = args.command_arguments.at(1); - Build::Command::perform_and_exit(spec, port_dir, options, paths); + Build::Command::perform_and_exit_ex(spec, port_dir, options, paths); } } diff --git a/toolsrc/src/vcpkg/commands.cache.cpp b/toolsrc/src/vcpkg/commands.cache.cpp index 64a3169b1..6fd123b7c 100644 --- a/toolsrc/src/vcpkg/commands.cache.cpp +++ b/toolsrc/src/vcpkg/commands.cache.cpp @@ -26,13 +26,19 @@ namespace vcpkg::Commands::Cache return output; } + const CommandStructure COMMAND_STRUCTURE = { + Strings::format( + "The argument should be a substring to search for, or no argument to display all cached libraries.\n%s", + Help::create_example_string("cache png")), + 0, + 1, + {}, + nullptr, + }; + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { - static const std::string EXAMPLE = Strings::format( - "The argument should be a substring to search for, or no argument to display all cached libraries.\n%s", - Help::create_example_string("cache png")); - args.check_max_arg_count(1, EXAMPLE); - args.check_and_get_optional_command_arguments({}, {}); + args.parse_arguments(COMMAND_STRUCTURE); const std::vector binary_paragraphs = read_all_binary_paragraphs(paths); if (binary_paragraphs.empty()) diff --git a/toolsrc/src/vcpkg/commands.ci.cpp b/toolsrc/src/vcpkg/commands.ci.cpp index d012ff6dc..dce294004 100644 --- a/toolsrc/src/vcpkg/commands.ci.cpp +++ b/toolsrc/src/vcpkg/commands.ci.cpp @@ -58,13 +58,23 @@ namespace vcpkg::Commands::CI Install::InstallSummary summary; }; + static const std::string OPTION_EXCLUDE = "--exclude"; + + static const std::array CI_SETTINGS = {{ + {OPTION_EXCLUDE, "Comma separated list of ports to skip"}, + }}; + + const CommandStructure COMMAND_STRUCTURE = { + Help::create_example_string("ci x64-windows"), + 0, + SIZE_MAX, + {{}, CI_SETTINGS}, + nullptr, + }; + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) { - static const std::string OPTION_EXCLUDE = "--exclude"; - - static const std::string EXAMPLE = Help::create_example_string("ci x64-windows"); - - const ParsedArguments options = args.check_and_get_optional_command_arguments({}, {OPTION_EXCLUDE}); + const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE); const std::vector exclusions = Strings::split(options.settings.at(OPTION_EXCLUDE), ","); const std::set exclusions_set(exclusions.cbegin(), exclusions.cend()); diff --git a/toolsrc/src/vcpkg/commands.contact.cpp b/toolsrc/src/vcpkg/commands.contact.cpp index 5694c1fa6..5d62faeea 100644 --- a/toolsrc/src/vcpkg/commands.contact.cpp +++ b/toolsrc/src/vcpkg/commands.contact.cpp @@ -2,6 +2,7 @@ #include #include +#include namespace vcpkg::Commands::Contact { @@ -11,10 +12,17 @@ namespace vcpkg::Commands::Contact return S_EMAIL; } + const CommandStructure COMMAND_STRUCTURE = { + Help::create_example_string("contact"), + 0, + 0, + {}, + nullptr, + }; + void perform_and_exit(const VcpkgCmdArguments& args) { - args.check_exact_arg_count(0); - args.check_and_get_optional_command_arguments({}, {}); + args.parse_arguments(COMMAND_STRUCTURE); System::println("Send an email to %s with any feedback.", email()); Checks::exit_success(VCPKG_LINE_INFO); diff --git a/toolsrc/src/vcpkg/commands.cpp b/toolsrc/src/vcpkg/commands.cpp index 9d969ea28..15b10c7ea 100644 --- a/toolsrc/src/vcpkg/commands.cpp +++ b/toolsrc/src/vcpkg/commands.cpp @@ -13,7 +13,7 @@ namespace vcpkg::Commands Span> get_available_commands_type_a() { static std::vector> t = { - {"install", &Install::perform_and_exit}, + PackageNameAndFunction{"install", &Install::perform_and_exit}, {"ci", &CI::perform_and_exit}, {"remove", &Remove::perform_and_exit}, {"build", &Build::Command::perform_and_exit}, diff --git a/toolsrc/src/vcpkg/commands.create.cpp b/toolsrc/src/vcpkg/commands.create.cpp index f1acacd14..c7183d257 100644 --- a/toolsrc/src/vcpkg/commands.create.cpp +++ b/toolsrc/src/vcpkg/commands.create.cpp @@ -8,13 +8,18 @@ namespace vcpkg::Commands::Create { + const CommandStructure COMMAND_STRUCTURE = { + Help::create_example_string( + R"###(create zlib2 http://zlib.net/zlib1211.zip "zlib1211-2.zip")###"), + 2, + 3, + {}, + nullptr, + }; + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { - static const std::string EXAMPLE = Help::create_example_string( - R"###(create zlib2 http://zlib.net/zlib1211.zip "zlib1211-2.zip")###"); - args.check_max_arg_count(3, EXAMPLE); - args.check_min_arg_count(2, EXAMPLE); - args.check_and_get_optional_command_arguments({}, {}); + args.parse_arguments(COMMAND_STRUCTURE); const std::string port_name = args.command_arguments.at(0); const std::string url = args.command_arguments.at(1); diff --git a/toolsrc/src/vcpkg/commands.dependinfo.cpp b/toolsrc/src/vcpkg/commands.dependinfo.cpp index e5554f7e2..bb300d96e 100644 --- a/toolsrc/src/vcpkg/commands.dependinfo.cpp +++ b/toolsrc/src/vcpkg/commands.dependinfo.cpp @@ -9,11 +9,17 @@ namespace vcpkg::Commands::DependInfo { + const CommandStructure COMMAND_STRUCTURE = { + Help::create_example_string(R"###(depend-info [pat])###"), + 0, + 1, + {}, + nullptr, + }; + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { - static const std::string EXAMPLE = Help::create_example_string(R"###(depend-info [pat])###"); - args.check_max_arg_count(1, EXAMPLE); - args.check_and_get_optional_command_arguments({}, {}); + args.parse_arguments(COMMAND_STRUCTURE); std::vector> source_control_files = Paragraphs::load_all_ports(paths.get_filesystem(), paths.ports); diff --git a/toolsrc/src/vcpkg/commands.edit.cpp b/toolsrc/src/vcpkg/commands.edit.cpp index bf618e256..e40e394fb 100644 --- a/toolsrc/src/vcpkg/commands.edit.cpp +++ b/toolsrc/src/vcpkg/commands.edit.cpp @@ -34,11 +34,6 @@ namespace vcpkg::Commands::Edit static const std::string OPTION_BUILDTREES = "--buildtrees"; - static const std::array SWITCHES = { - OPTION_BUILDTREES, - }; - static const std::array SETTINGS; - static std::vector valid_arguments(const VcpkgPaths& paths) { auto sources_and_errors = Paragraphs::try_load_all_ports(paths.get_filesystem(), paths.ports); @@ -47,12 +42,15 @@ namespace vcpkg::Commands::Edit [](auto&& pgh) -> std::string { return pgh->core_paragraph->name; }); } + static const std::array EDIT_SWITCHES = {{ + {OPTION_BUILDTREES, "Open editor into the port-specific buildtree subfolder"}, + }}; + const CommandStructure COMMAND_STRUCTURE = { - "edit zlib", + Help::create_example_string("edit zlib"), 1, 1, - SWITCHES, - SETTINGS, + {EDIT_SWITCHES, {}}, &valid_arguments, }; @@ -63,9 +61,7 @@ namespace vcpkg::Commands::Edit auto& fs = paths.get_filesystem(); - static const std::string EXAMPLE = Help::create_example_string("edit zlib"); - args.check_exact_arg_count(1, EXAMPLE); - const ParsedArguments options = args.check_and_get_optional_command_arguments({OPTION_BUILDTREES}, {}); + const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE); const std::string port_name = args.command_arguments.at(0); const fs::path portpath = paths.ports / port_name; diff --git a/toolsrc/src/vcpkg/commands.env.cpp b/toolsrc/src/vcpkg/commands.env.cpp index c0d26dac2..98b5aced9 100644 --- a/toolsrc/src/vcpkg/commands.env.cpp +++ b/toolsrc/src/vcpkg/commands.env.cpp @@ -7,11 +7,17 @@ namespace vcpkg::Commands::Env { + const CommandStructure COMMAND_STRUCTURE = { + Help::create_example_string("env --triplet x64-windows"), + 0, + 0, + {}, + nullptr, + }; + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) { - static const std::string EXAMPLE = Help::create_example_string(R"(env --triplet x64-windows)"); - args.check_exact_arg_count(0, EXAMPLE); - args.check_and_get_optional_command_arguments({}, {}); + args.parse_arguments(COMMAND_STRUCTURE); const auto pre_build_info = Build::PreBuildInfo::from_triplet_file(paths, default_triplet); const Toolset& toolset = paths.get_toolset(pre_build_info.platform_toolset, pre_build_info.visual_studio_path); diff --git a/toolsrc/src/vcpkg/commands.hash.cpp b/toolsrc/src/vcpkg/commands.hash.cpp index 51f6b9ad0..a5940ea1e 100644 --- a/toolsrc/src/vcpkg/commands.hash.cpp +++ b/toolsrc/src/vcpkg/commands.hash.cpp @@ -28,13 +28,18 @@ namespace vcpkg::Commands::Hash System::println(hash); } + const CommandStructure COMMAND_STRUCTURE = { + Strings::format("The argument should be a file path\n%s", + Help::create_example_string("hash boost_1_62_0.tar.bz2")), + 1, + 2, + {}, + nullptr, + }; + void perform_and_exit(const VcpkgCmdArguments& args) { - static const std::string EXAMPLE = Strings::format("The argument should be a file path\n%s", - Help::create_example_string("hash boost_1_62_0.tar.bz2")); - args.check_min_arg_count(1, EXAMPLE); - args.check_max_arg_count(2, EXAMPLE); - args.check_and_get_optional_command_arguments({}, {}); + args.parse_arguments(COMMAND_STRUCTURE); if (args.command_arguments.size() == 1) { diff --git a/toolsrc/src/vcpkg/commands.import.cpp b/toolsrc/src/vcpkg/commands.import.cpp index 5e74b6d94..24394207b 100644 --- a/toolsrc/src/vcpkg/commands.import.cpp +++ b/toolsrc/src/vcpkg/commands.import.cpp @@ -92,12 +92,18 @@ namespace vcpkg::Commands::Import fs.write_contents(control_file_path, Strings::serialize(control_file_data)); } + const CommandStructure COMMAND_STRUCTURE = { + Help::create_example_string( + R"(import C:\path\to\CONTROLfile C:\path\to\includedir C:\path\to\projectdir)"), + 3, + 3, + {}, + nullptr, + }; + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { - static const std::string EXAMPLE = Help::create_example_string( - R"(import C:\path\to\CONTROLfile C:\path\to\includedir C:\path\to\projectdir)"); - args.check_exact_arg_count(3, EXAMPLE); - args.check_and_get_optional_command_arguments({}, {}); + args.parse_arguments(COMMAND_STRUCTURE); const fs::path control_file_path(args.command_arguments[0]); const fs::path include_directory(args.command_arguments[1]); diff --git a/toolsrc/src/vcpkg/commands.integrate.cpp b/toolsrc/src/vcpkg/commands.integrate.cpp index 604bd2c6e..31b9ec722 100644 --- a/toolsrc/src/vcpkg/commands.integrate.cpp +++ b/toolsrc/src/vcpkg/commands.integrate.cpp @@ -333,10 +333,6 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console static const std::string PROJECT = "project"; } - static const std::array INSTALL_SWITCHES; - - static const std::array INSTALL_SETTINGS; - static std::vector valid_arguments(const VcpkgPaths&) { return {Subcommand::INSTALL, Subcommand::REMOVE, Subcommand::PROJECT}; @@ -348,18 +344,13 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console INTEGRATE_COMMAND_HELPSTRING), 1, 1, - INSTALL_SWITCHES, - INSTALL_SETTINGS, + {}, &valid_arguments, }; void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { - static const std::string EXAMPLE = Strings::format("Commands:\n" - "%s", - INTEGRATE_COMMAND_HELPSTRING); - args.check_exact_arg_count(1, EXAMPLE); - args.check_and_get_optional_command_arguments({}, {}); + args.parse_arguments(COMMAND_STRUCTURE); #if defined(_WIN32) if (args.command_arguments[0] == Subcommand::INSTALL) diff --git a/toolsrc/src/vcpkg/commands.list.cpp b/toolsrc/src/vcpkg/commands.list.cpp index 145d4c931..1f2387843 100644 --- a/toolsrc/src/vcpkg/commands.list.cpp +++ b/toolsrc/src/vcpkg/commands.list.cpp @@ -24,13 +24,23 @@ namespace vcpkg::Commands::List } } + static const std::array LIST_SWITCHES = {{ + {OPTION_FULLDESC, "Do not truncate long text"}, + }}; + + const CommandStructure COMMAND_STRUCTURE = { + Strings::format( + "The argument should be a substring to search for, or no argument to display all installed libraries.\n%s", + Help::create_example_string("list png")), + 0, + 1, + {LIST_SWITCHES, {}}, + nullptr, + }; + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { - static const std::string EXAMPLE = Strings::format( - "The argument should be a substring to search for, or no argument to display all installed libraries.\n%s", - Help::create_example_string("list png")); - args.check_max_arg_count(1, EXAMPLE); - const ParsedArguments options = args.check_and_get_optional_command_arguments({OPTION_FULLDESC}, {}); + const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE); const StatusParagraphs status_paragraphs = database_load_check(paths); std::vector installed_packages = get_installed_ports(status_paragraphs); diff --git a/toolsrc/src/vcpkg/commands.owns.cpp b/toolsrc/src/vcpkg/commands.owns.cpp index b2db966e1..52249187b 100644 --- a/toolsrc/src/vcpkg/commands.owns.cpp +++ b/toolsrc/src/vcpkg/commands.owns.cpp @@ -23,13 +23,18 @@ namespace vcpkg::Commands::Owns } } } + const CommandStructure COMMAND_STRUCTURE = { + Strings::format("The argument should be a pattern to search for. %s", + Help::create_example_string("owns zlib.dll")), + 1, + 1, + {}, + nullptr, + }; void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { - static const std::string EXAMPLE = Strings::format("The argument should be a pattern to search for. %s", - Help::create_example_string("owns zlib.dll")); - args.check_exact_arg_count(1, EXAMPLE); - args.check_and_get_optional_command_arguments({}, {}); + args.parse_arguments(COMMAND_STRUCTURE); const StatusParagraphs status_db = database_load_check(paths); search_file(paths, args.command_arguments[0], status_db); diff --git a/toolsrc/src/vcpkg/commands.portsdiff.cpp b/toolsrc/src/vcpkg/commands.portsdiff.cpp index 5008f3e8a..0277c8bdb 100644 --- a/toolsrc/src/vcpkg/commands.portsdiff.cpp +++ b/toolsrc/src/vcpkg/commands.portsdiff.cpp @@ -114,13 +114,18 @@ namespace vcpkg::Commands::PortsDiff VCPKG_LINE_INFO, output.output == VALID_COMMIT_OUTPUT, "Invalid commit id %s", git_commit_id); } + const CommandStructure COMMAND_STRUCTURE = { + Strings::format("The argument should be a branch/tag/hash to checkout.\n%s", + Help::create_example_string("portsdiff mybranchname")), + 1, + 2, + {}, + nullptr, + }; + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { - static const std::string EXAMPLE = Strings::format("The argument should be a branch/tag/hash to checkout.\n%s", - Help::create_example_string("portsdiff mybranchname")); - args.check_min_arg_count(1, EXAMPLE); - args.check_max_arg_count(2, EXAMPLE); - args.check_and_get_optional_command_arguments({}, {}); + args.parse_arguments(COMMAND_STRUCTURE); const fs::path& git_exe = paths.get_git_exe(); diff --git a/toolsrc/src/vcpkg/commands.search.cpp b/toolsrc/src/vcpkg/commands.search.cpp index ad3046e6d..01291ddfb 100644 --- a/toolsrc/src/vcpkg/commands.search.cpp +++ b/toolsrc/src/vcpkg/commands.search.cpp @@ -79,14 +79,24 @@ namespace vcpkg::Commands::Search } } + static std::array SEARCH_SWITCHES = {{ + {OPTION_GRAPH, "Open editor into the port-specific buildtree subfolder"}, + {OPTION_FULLDESC, "Do not truncate long text"}, + }}; + + const CommandStructure COMMAND_STRUCTURE = { + Strings::format( + "The argument should be a substring to search for, or no argument to display all libraries.\n%s", + Help::create_example_string("search png")), + 0, + 1, + {SEARCH_SWITCHES, {}}, + nullptr, + }; + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { - static const std::string EXAMPLE = Strings::format( - "The argument should be a substring to search for, or no argument to display all libraries.\n%s", - Help::create_example_string("search png")); - args.check_max_arg_count(1, EXAMPLE); - const ParsedArguments options = - args.check_and_get_optional_command_arguments({OPTION_GRAPH, OPTION_FULLDESC}, {}); + const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE); const bool full_description = Util::Sets::contains(options.switches, OPTION_FULLDESC); auto source_paragraphs = Paragraphs::load_all_ports(paths.get_filesystem(), paths.ports); diff --git a/toolsrc/src/vcpkg/commands.version.cpp b/toolsrc/src/vcpkg/commands.version.cpp index e8756a77d..3f44cf1a2 100644 --- a/toolsrc/src/vcpkg/commands.version.cpp +++ b/toolsrc/src/vcpkg/commands.version.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #define STRINGIFY(...) #__VA_ARGS__ @@ -61,11 +62,17 @@ namespace vcpkg::Commands::Version } } } + const CommandStructure COMMAND_STRUCTURE = { + Help::create_example_string("version"), + 0, + 0, + {}, + nullptr, + }; void perform_and_exit(const VcpkgCmdArguments& args) { - args.check_exact_arg_count(0); - args.check_and_get_optional_command_arguments({}, {}); + args.parse_arguments(COMMAND_STRUCTURE); System::println("Vcpkg package management program version %s\n" "\n" diff --git a/toolsrc/src/vcpkg/export.cpp b/toolsrc/src/vcpkg/export.cpp index eb4f5db3c..bbeecefed 100644 --- a/toolsrc/src/vcpkg/export.cpp +++ b/toolsrc/src/vcpkg/export.cpp @@ -257,51 +257,57 @@ namespace vcpkg::Export std::vector specs; }; + static const std::string OPTION_DRY_RUN = "--dry-run"; + static const std::string OPTION_RAW = "--raw"; + static const std::string OPTION_NUGET = "--nuget"; + static const std::string OPTION_IFW = "--ifw"; + static const std::string OPTION_ZIP = "--zip"; + static const std::string OPTION_SEVEN_ZIP = "--7zip"; + static const std::string OPTION_NUGET_ID = "--nuget-id"; + static const std::string OPTION_NUGET_VERSION = "--nuget-version"; + static const std::string OPTION_IFW_REPOSITORY_URL = "--ifw-repository-url"; + static const std::string OPTION_IFW_PACKAGES_DIR_PATH = "--ifw-packages-directory-path"; + static const std::string OPTION_IFW_REPOSITORY_DIR_PATH = "--ifw-repository-directory-path"; + static const std::string OPTION_IFW_CONFIG_FILE_PATH = "--ifw-configuration-file-path"; + static const std::string OPTION_IFW_INSTALLER_FILE_PATH = "--ifw-installer-file-path"; + + static const std::array EXPORT_SWITCHES = {{ + {OPTION_DRY_RUN, "Do not actually export"}, + {OPTION_RAW, "Export to an uncompressed directory"}, + {OPTION_NUGET, "Export a NuGet package"}, + {OPTION_IFW, "Export to an IFW-based installer"}, + {OPTION_ZIP, "Export to a zip file"}, + {OPTION_SEVEN_ZIP, "Export to a 7zip (.7z) file"}, + }}; + static const std::array EXPORT_SETTINGS = {{ + {OPTION_NUGET_ID, "Specify the id for the exported NuGet package"}, + {OPTION_NUGET_VERSION, "Specify the version for the exported NuGet package"}, + {OPTION_IFW_REPOSITORY_URL, ""}, + {OPTION_IFW_PACKAGES_DIR_PATH, ""}, + {OPTION_IFW_REPOSITORY_DIR_PATH, ""}, + {OPTION_IFW_CONFIG_FILE_PATH, ""}, + {OPTION_IFW_INSTALLER_FILE_PATH, ""}, + }}; + + const CommandStructure COMMAND_STRUCTURE = { + Help::create_example_string("export zlib zlib:x64-windows boost --nuget"), + 0, + SIZE_MAX, + {EXPORT_SWITCHES, EXPORT_SETTINGS}, + nullptr, + }; + static ExportArguments handle_export_command_arguments(const VcpkgCmdArguments& args, const Triplet& default_triplet) { ExportArguments ret; - static const std::string OPTION_DRY_RUN = "--dry-run"; - static const std::string OPTION_RAW = "--raw"; - static const std::string OPTION_NUGET = "--nuget"; - static const std::string OPTION_IFW = "--ifw"; - static const std::string OPTION_ZIP = "--zip"; - static const std::string OPTION_SEVEN_ZIP = "--7zip"; - static const std::string OPTION_NUGET_ID = "--nuget-id"; - static const std::string OPTION_NUGET_VERSION = "--nuget-version"; - static const std::string OPTION_IFW_REPOSITORY_URL = "--ifw-repository-url"; - static const std::string OPTION_IFW_PACKAGES_DIR_PATH = "--ifw-packages-directory-path"; - static const std::string OPTION_IFW_REPOSITORY_DIR_PATH = "--ifw-repository-directory-path"; - static const std::string OPTION_IFW_CONFIG_FILE_PATH = "--ifw-configuration-file-path"; - static const std::string OPTION_IFW_INSTALLER_FILE_PATH = "--ifw-installer-file-path"; + const auto options = args.parse_arguments(COMMAND_STRUCTURE); // input sanitization - static const std::string EXAMPLE = Help::create_example_string("export zlib zlib:x64-windows boost --nuget"); - args.check_min_arg_count(1, EXAMPLE); - ret.specs = Util::fmap(args.command_arguments, [&](auto&& arg) { - return Input::check_and_get_package_spec(arg, default_triplet, EXAMPLE); + return Input::check_and_get_package_spec(arg, default_triplet, COMMAND_STRUCTURE.example_text); }); - - const auto options = args.check_and_get_optional_command_arguments( - { - OPTION_DRY_RUN, - OPTION_RAW, - OPTION_NUGET, - OPTION_IFW, - OPTION_ZIP, - OPTION_SEVEN_ZIP, - }, - { - OPTION_NUGET_ID, - OPTION_NUGET_VERSION, - OPTION_IFW_REPOSITORY_URL, - OPTION_IFW_PACKAGES_DIR_PATH, - OPTION_IFW_REPOSITORY_DIR_PATH, - OPTION_IFW_CONFIG_FILE_PATH, - OPTION_IFW_INSTALLER_FILE_PATH, - }); ret.dry_run = options.switches.find(OPTION_DRY_RUN) != options.switches.cend(); ret.raw = options.switches.find(OPTION_RAW) != options.switches.cend(); ret.nuget = options.switches.find(OPTION_NUGET) != options.switches.cend(); @@ -313,7 +319,7 @@ namespace vcpkg::Export { System::println(System::Color::error, "Must provide at least one export type: --raw --nuget --ifw --zip --7zip"); - System::print(EXAMPLE); + System::print(COMMAND_STRUCTURE.example_text); Checks::exit_fail(VCPKG_LINE_INFO); } diff --git a/toolsrc/src/vcpkg/help.cpp b/toolsrc/src/vcpkg/help.cpp index 8783833f2..5d4cf99a4 100644 --- a/toolsrc/src/vcpkg/help.cpp +++ b/toolsrc/src/vcpkg/help.cpp @@ -91,10 +91,17 @@ namespace vcpkg::Help System::println(create_example_string(command_and_arguments)); } + const CommandStructure COMMAND_STRUCTURE = { + Help::create_example_string("help"), + 0, + 1, + {}, + nullptr, + }; + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { - args.check_max_arg_count(1); - args.check_and_get_optional_command_arguments({}, {}); + args.parse_arguments(COMMAND_STRUCTURE); if (args.command_arguments.empty()) { diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp index b1f722d59..20ffd3164 100644 --- a/toolsrc/src/vcpkg/install.cpp +++ b/toolsrc/src/vcpkg/install.cpp @@ -535,13 +535,13 @@ namespace vcpkg::Install static const std::string OPTION_RECURSE = "--recurse"; static const std::string OPTION_KEEP_GOING = "--keep-going"; - static const std::array INSTALL_SWITCHES = { - OPTION_DRY_RUN, - OPTION_USE_HEAD_VERSION, - OPTION_NO_DOWNLOADS, - OPTION_RECURSE, - OPTION_KEEP_GOING, - }; + static const std::array INSTALL_SWITCHES = {{ + {OPTION_DRY_RUN, "Do not actually build or install"}, + {OPTION_USE_HEAD_VERSION, "Install the libraries on the command line using the latest upstream sources"}, + {OPTION_NO_DOWNLOADS, "Do not download new sources"}, + {OPTION_RECURSE, "Allow removal of packages as part of installation"}, + {OPTION_KEEP_GOING, "Continue installing packages on failure"}, + }}; static const std::array INSTALL_SETTINGS; std::vector get_all_port_names(const VcpkgPaths& paths) @@ -553,22 +553,20 @@ namespace vcpkg::Install } const CommandStructure COMMAND_STRUCTURE = { - "install zlib zlib:x64-windows curl boost", + Help::create_example_string("install zlib zlib:x64-windows curl boost"), 1, SIZE_MAX, - INSTALL_SWITCHES, - INSTALL_SETTINGS, + {INSTALL_SWITCHES, {}}, &get_all_port_names, }; void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) { // input sanitization - static const std::string EXAMPLE = Help::create_example_string("install zlib zlib:x64-windows curl boost"); - args.check_min_arg_count(1, EXAMPLE); + const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE); const std::vector specs = Util::fmap(args.command_arguments, [&](auto&& arg) { - return Input::check_and_get_full_package_spec(arg, default_triplet, EXAMPLE); + return Input::check_and_get_full_package_spec(arg, default_triplet, COMMAND_STRUCTURE.example_text); }); for (auto&& spec : specs) @@ -581,8 +579,6 @@ namespace vcpkg::Install } } - const ParsedArguments options = args.check_and_get_optional_command_arguments( - {OPTION_DRY_RUN, OPTION_USE_HEAD_VERSION, OPTION_NO_DOWNLOADS, OPTION_RECURSE, OPTION_KEEP_GOING}, {}); const bool dry_run = Util::Sets::contains(options.switches, OPTION_DRY_RUN); const bool use_head_version = Util::Sets::contains(options.switches, (OPTION_USE_HEAD_VERSION)); const bool no_downloads = Util::Sets::contains(options.switches, (OPTION_NO_DOWNLOADS)); diff --git a/toolsrc/src/vcpkg/remove.cpp b/toolsrc/src/vcpkg/remove.cpp index 156f23003..7f40fb16e 100644 --- a/toolsrc/src/vcpkg/remove.cpp +++ b/toolsrc/src/vcpkg/remove.cpp @@ -169,14 +169,13 @@ namespace vcpkg::Remove static const std::string OPTION_DRY_RUN = "--dry-run"; static const std::string OPTION_OUTDATED = "--outdated"; - static const std::array SWITCHES = { - OPTION_PURGE, - OPTION_NO_PURGE, - OPTION_RECURSE, - OPTION_DRY_RUN, - OPTION_OUTDATED, - }; - static const std::array SETTINGS; + static const std::array SWITCHES = {{ + {OPTION_PURGE, "Remove the cached copy of the package (default)"}, + {OPTION_NO_PURGE, "Do not remove the cached copy of the package"}, + {OPTION_RECURSE, "Allow removal of packages not explicitly specified on the command line"}, + {OPTION_DRY_RUN, "Print the packages to be removed, but do not remove them"}, + {OPTION_OUTDATED, "Select all packages with versions that do not match the portfiles"}, + }}; static std::vector valid_arguments(const VcpkgPaths& paths) { @@ -187,25 +186,26 @@ namespace vcpkg::Remove } const CommandStructure COMMAND_STRUCTURE = { - "remove zlib zlib:x64-windows curl boost", - 1, + Help::create_example_string("remove zlib zlib:x64-windows curl boost"), + 0, SIZE_MAX, - SWITCHES, - SETTINGS, + {SWITCHES, {}}, &valid_arguments, }; void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) { - static const std::string EXAMPLE = Help::create_example_string("remove zlib zlib:x64-windows curl boost"); - const ParsedArguments options = args.check_and_get_optional_command_arguments( - {OPTION_PURGE, OPTION_NO_PURGE, OPTION_RECURSE, OPTION_DRY_RUN, OPTION_OUTDATED}, {}); + const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE); StatusParagraphs status_db = database_load_check(paths); std::vector specs; if (Util::Sets::contains(options.switches, OPTION_OUTDATED)) { - args.check_exact_arg_count(0, EXAMPLE); + if (args.command_arguments.size() != 0) + { + System::println(System::Color::error, "Error: 'remove' accepts either libraries or '--outdated'"); + Checks::exit_fail(VCPKG_LINE_INFO); + } specs = Util::fmap(Update::find_outdated_packages(paths, status_db), [](auto&& outdated) { return outdated.spec; }); @@ -217,9 +217,13 @@ namespace vcpkg::Remove } else { - args.check_min_arg_count(1, EXAMPLE); + if (args.command_arguments.size() < 1) + { + System::println(System::Color::error, "Error: 'remove' accepts either libraries or '--outdated'"); + Checks::exit_fail(VCPKG_LINE_INFO); + } specs = Util::fmap(args.command_arguments, [&](auto&& arg) { - return Input::check_and_get_package_spec(arg, default_triplet, EXAMPLE); + return Input::check_and_get_package_spec(arg, default_triplet, COMMAND_STRUCTURE.example_text); }); for (auto&& spec : specs) @@ -231,7 +235,7 @@ namespace vcpkg::Remove if (purge_was_passed && no_purge_was_passed) { System::println(System::Color::error, "Error: cannot specify both --no-purge and --purge."); - System::print(EXAMPLE); + System::print(COMMAND_STRUCTURE.example_text); Checks::exit_fail(VCPKG_LINE_INFO); } const Purge purge = to_purge(purge_was_passed || !no_purge_was_passed); diff --git a/toolsrc/src/vcpkg/update.cpp b/toolsrc/src/vcpkg/update.cpp index 7d565251e..61a3f89c5 100644 --- a/toolsrc/src/vcpkg/update.cpp +++ b/toolsrc/src/vcpkg/update.cpp @@ -38,10 +38,17 @@ namespace vcpkg::Update return output; } + const CommandStructure COMMAND_STRUCTURE = { + Help::create_example_string("update"), + 0, + 0, + {}, + nullptr, + }; + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { - args.check_exact_arg_count(0); - args.check_and_get_optional_command_arguments({}, {}); + args.parse_arguments(COMMAND_STRUCTURE); System::println("Using local portfile versions. To update the local portfiles, use `git pull`."); const StatusParagraphs status_db = database_load_check(paths); diff --git a/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp b/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp index 209f6a3f2..35cdbc12e 100644 --- a/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp +++ b/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp @@ -45,11 +45,8 @@ namespace vcpkg option_field = new_setting; } -#if defined(_WIN32) - VcpkgCmdArguments VcpkgCmdArguments::create_from_command_line(const int argc, const wchar_t* const* const argv) -#else - VcpkgCmdArguments VcpkgCmdArguments::create_from_command_line(const int argc, const char* const* const argv) -#endif + VcpkgCmdArguments VcpkgCmdArguments::create_from_command_line(const int argc, + const CommandLineCharType* const* const argv) { std::vector v; for (int i = 1; i < argc; ++i) @@ -158,46 +155,83 @@ namespace vcpkg return args; } - ParsedArguments VcpkgCmdArguments::check_and_get_optional_command_arguments( - const std::vector& valid_switches, const std::vector& valid_settings) const + ParsedArguments VcpkgCmdArguments::parse_arguments(const CommandStructure& command_structure) const { bool failed = false; ParsedArguments output; + const size_t actual_arg_count = command_arguments.size(); + + if (command_structure.minimum_arity == command_structure.maximum_arity) + { + if (actual_arg_count != command_structure.minimum_arity) + { + System::println(System::Color::error, + "Error: '%s' requires %u arguments, but %u were provided.", + this->command, + command_structure.minimum_arity, + actual_arg_count); + failed = true; + } + } + else + { + if (actual_arg_count < command_structure.minimum_arity) + { + System::println(System::Color::error, + "Error: '%s' requires at least %u arguments, but %u were provided", + this->command, + command_structure.minimum_arity, + actual_arg_count); + failed = true; + } + if (actual_arg_count > command_structure.maximum_arity) + { + System::println(System::Color::error, + "Error: '%s' requires at most %u arguments, but %u were provided", + this->command, + command_structure.maximum_arity, + actual_arg_count); + failed = true; + } + } + auto options_copy = this->optional_command_arguments; - for (const std::string& option : valid_switches) + for (auto&& option : command_structure.options.switches) { - const auto it = options_copy.find(option); + const auto it = options_copy.find(option.name); if (it != options_copy.end()) { if (it->second.has_value()) { // Having a string value indicates it was passed like '--a=xyz' - System::println(System::Color::error, "The option '%s' does not accept an argument.", option); + System::println( + System::Color::error, "Error: The option '%s' does not accept an argument.", option.name); failed = true; } else { - output.switches.insert(option); + output.switches.insert(option.name); options_copy.erase(it); } } } - for (const std::string& option : valid_settings) + for (auto&& option : command_structure.options.settings) { - const auto it = options_copy.find(option); + const auto it = options_copy.find(option.name); if (it != options_copy.end()) { if (!it->second.has_value()) { // Not having a string value indicates it was passed like '--a' - System::println(System::Color::error, "The option '%s' must be passed an argument.", option); + System::println( + System::Color::error, "Error: The option '%s' must be passed an argument.", option.name); failed = true; } else { - output.settings.emplace(option, it->second.value_or_exit(VCPKG_LINE_INFO)); + output.settings.emplace(option.name, it->second.value_or_exit(VCPKG_LINE_INFO)); options_copy.erase(it); } } @@ -210,83 +244,32 @@ namespace vcpkg { System::println(" %s", option.first); } - System::println("\nValid options are:", this->command); - for (auto&& option : valid_switches) + System::println(); + failed = true; + } + + if (failed) + { + if (!command_structure.example_text.empty()) { - System::println(" %s", option); + System::println("%s", command_structure.example_text); } - for (auto&& option : valid_settings) + + System::println("Options:", this->command); + for (auto&& option : command_structure.options.switches) { - System::println(" %s=...", option); + System::println(" %-40s %s", option.name, option.short_help_text); + } + for (auto&& option : command_structure.options.settings) + { + System::println(" %-40s %s", (option.name + "=..."), option.short_help_text); } System::println(" --triplet "); System::println(" --vcpkg-root "); Checks::exit_fail(VCPKG_LINE_INFO); } - if (failed) Checks::exit_fail(VCPKG_LINE_INFO); return output; } - - void VcpkgCmdArguments::check_max_arg_count(const size_t expected_arg_count) const - { - return check_max_arg_count(expected_arg_count, ""); - } - - void VcpkgCmdArguments::check_min_arg_count(const size_t expected_arg_count) const - { - return check_min_arg_count(expected_arg_count, ""); - } - - void VcpkgCmdArguments::check_exact_arg_count(const size_t expected_arg_count) const - { - return check_exact_arg_count(expected_arg_count, ""); - } - - void VcpkgCmdArguments::check_max_arg_count(const size_t expected_arg_count, const std::string& example_text) const - { - const size_t actual_arg_count = command_arguments.size(); - if (actual_arg_count > expected_arg_count) - { - System::println(System::Color::error, - "Error: `%s` requires at most %u arguments, but %u were provided", - this->command, - expected_arg_count, - actual_arg_count); - System::print(example_text); - Checks::exit_fail(VCPKG_LINE_INFO); - } - } - - void VcpkgCmdArguments::check_min_arg_count(const size_t expected_arg_count, const std::string& example_text) const - { - const size_t actual_arg_count = command_arguments.size(); - if (actual_arg_count < expected_arg_count) - { - System::println(System::Color::error, - "Error: `%s` requires at least %u arguments, but %u were provided", - this->command, - expected_arg_count, - actual_arg_count); - System::print(example_text); - Checks::exit_fail(VCPKG_LINE_INFO); - } - } - - void VcpkgCmdArguments::check_exact_arg_count(const size_t expected_arg_count, - const std::string& example_text) const - { - const size_t actual_arg_count = command_arguments.size(); - if (actual_arg_count != expected_arg_count) - { - System::println(System::Color::error, - "Error: `%s` requires %u arguments, but %u were provided", - this->command, - expected_arg_count, - actual_arg_count); - System::print(example_text); - Checks::exit_fail(VCPKG_LINE_INFO); - } - } } -- cgit v1.2.3 From 2feea0828ba94d2a365e8825fe799ed12acc6e6c Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Thu, 2 Nov 2017 18:17:21 -0700 Subject: [vcpkg] Improve `vcpkg help` -- now has per-command help! --- toolsrc/include/vcpkg/base/cstringview.h | 2 + toolsrc/include/vcpkg/export.h | 2 + toolsrc/include/vcpkg/help.h | 4 +- toolsrc/include/vcpkg/vcpkgcmdarguments.h | 2 + toolsrc/src/vcpkg/export.cpp | 3 +- toolsrc/src/vcpkg/help.cpp | 116 +++++++++++++++++------------- toolsrc/src/vcpkg/vcpkgcmdarguments.cpp | 40 ++++++----- 7 files changed, 99 insertions(+), 70 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/base/cstringview.h b/toolsrc/include/vcpkg/base/cstringview.h index 342455402..0441bc573 100644 --- a/toolsrc/include/vcpkg/base/cstringview.h +++ b/toolsrc/include/vcpkg/base/cstringview.h @@ -63,6 +63,8 @@ namespace vcpkg inline bool operator!=(const std::string& l, const CStringView& r) { return l != r.c_str(); } + inline std::string operator+(std::string&& l, const CStringView& r) { return std::move(l) + r.c_str(); } + inline const char* to_printf_arg(const CStringView string_view) { return string_view.c_str(); } static_assert(sizeof(CStringView) == sizeof(void*), "CStringView must be a simple wrapper around char*"); diff --git a/toolsrc/include/vcpkg/export.h b/toolsrc/include/vcpkg/export.h index f3285e187..eb99b4fb1 100644 --- a/toolsrc/include/vcpkg/export.h +++ b/toolsrc/include/vcpkg/export.h @@ -4,6 +4,8 @@ namespace vcpkg::Export { + extern const CommandStructure COMMAND_STRUCTURE; + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet); void export_integration_files(const fs::path& raw_exported_dir_path, const VcpkgPaths& paths); diff --git a/toolsrc/include/vcpkg/help.h b/toolsrc/include/vcpkg/help.h index 39ad6912d..73549efd7 100644 --- a/toolsrc/include/vcpkg/help.h +++ b/toolsrc/include/vcpkg/help.h @@ -7,13 +7,13 @@ namespace vcpkg::Help { + extern const CommandStructure COMMAND_STRUCTURE; + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); void help_topic_valid_triplet(const VcpkgPaths& paths); void print_usage(); - void print_example(const std::string& command_and_arguments); - std::string create_example_string(const std::string& command_and_arguments); } diff --git a/toolsrc/include/vcpkg/vcpkgcmdarguments.h b/toolsrc/include/vcpkg/vcpkgcmdarguments.h index a832caf04..93eeb6ef5 100644 --- a/toolsrc/include/vcpkg/vcpkgcmdarguments.h +++ b/toolsrc/include/vcpkg/vcpkgcmdarguments.h @@ -49,6 +49,8 @@ namespace vcpkg std::vector (*valid_arguments)(const VcpkgPaths& paths); }; + void display_usage(const CommandStructure& command_structure); + #if defined(_WIN32) using CommandLineCharType = wchar_t; #else diff --git a/toolsrc/src/vcpkg/export.cpp b/toolsrc/src/vcpkg/export.cpp index bbeecefed..625dff8b1 100644 --- a/toolsrc/src/vcpkg/export.cpp +++ b/toolsrc/src/vcpkg/export.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -289,7 +290,7 @@ namespace vcpkg::Export {OPTION_IFW_INSTALLER_FILE_PATH, ""}, }}; - const CommandStructure COMMAND_STRUCTURE = { + const CommandStructure vcpkg::Export::COMMAND_STRUCTURE = { Help::create_example_string("export zlib zlib:x64-windows boost --nuget"), 0, SIZE_MAX, diff --git a/toolsrc/src/vcpkg/help.cpp b/toolsrc/src/vcpkg/help.cpp index 5d4cf99a4..c83f0277b 100644 --- a/toolsrc/src/vcpkg/help.cpp +++ b/toolsrc/src/vcpkg/help.cpp @@ -2,15 +2,68 @@ #include #include +#include +#include +#include +#include namespace vcpkg::Help { - void help_topics() + struct Topic + { + using topic_function = void (*)(const VcpkgPaths& paths); + + constexpr Topic(CStringView n, topic_function fn) : name(n), print(fn) {} + + CStringView name; + topic_function print; + }; + + template + static void command_topic_fn(const VcpkgPaths&) + { + display_usage(S); + } + + static void integrate_topic_fn(const VcpkgPaths&) + { + System::print("Commands:\n" + "%s", + Commands::Integrate::INTEGRATE_COMMAND_HELPSTRING); + } + + static void help_topics(const VcpkgPaths&); + + const CommandStructure COMMAND_STRUCTURE = { + Help::create_example_string("help"), + 0, + 1, + {}, + nullptr, + }; + + static constexpr std::array topics = {{ + {"create", command_topic_fn}, + {"edit", command_topic_fn}, + {"env", command_topic_fn}, + {"export", command_topic_fn}, + {"help", command_topic_fn}, + {"install", command_topic_fn}, + {"integrate", integrate_topic_fn}, + {"list", command_topic_fn}, + {"owns", command_topic_fn}, + {"remove", command_topic_fn}, + {"search", command_topic_fn}, + {"topics", help_topics}, + }}; + + static void help_topics(const VcpkgPaths&) { System::println("Available help topics:\n" " triplet\n" - " integrate\n" - " export"); + " integrate" + "%s", + Strings::join("", topics, [](const Topic& topic) { return std::string("\n ") + topic.name; })); } void help_topic_valid_triplet(const VcpkgPaths& paths) @@ -22,21 +75,6 @@ namespace vcpkg::Help } } - void help_topic_export() - { - System::println("Summary:\n" - " vcpkg export [options] ...\n" - "\n" - "Options:\n" - " --7zip Export to a 7zip (.7z) file\n" - " --dry-run Do not actually export\n" - " --nuget Export a NuGet package\n" - " --nuget-id= Specify the id for the exported NuGet package\n" - " --nuget-version= Specify the version for the exported NuGet package\n" - " --raw Export to an uncompressed directory\n" - " --zip Export to a zip file"); - } - void print_usage() { System::println( @@ -86,19 +124,6 @@ namespace vcpkg::Help return cs; } - void print_example(const std::string& command_and_arguments) - { - System::println(create_example_string(command_and_arguments)); - } - - const CommandStructure COMMAND_STRUCTURE = { - Help::create_example_string("help"), - 0, - 1, - {}, - nullptr, - }; - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { args.parse_arguments(COMMAND_STRUCTURE); @@ -112,27 +137,18 @@ namespace vcpkg::Help if (topic == "triplet" || topic == "triplets" || topic == "triple") { help_topic_valid_triplet(paths); + Checks::exit_success(VCPKG_LINE_INFO); } - else if (topic == "export") - { - help_topic_export(); - } - else if (topic == "integrate") - { - System::print("Commands:\n" - "%s", - Commands::Integrate::INTEGRATE_COMMAND_HELPSTRING); - } - else if (topic == "topics") - { - help_topics(); - } - else + + auto it_topic = Util::find_if(topics, [&](const Topic& t) { return t.name == topic; }); + if (it_topic != topics.end()) { - System::println(System::Color::error, "Error: unknown topic %s", topic); - help_topics(); - Checks::exit_fail(VCPKG_LINE_INFO); + it_topic->print(paths); + Checks::exit_success(VCPKG_LINE_INFO); } - Checks::exit_success(VCPKG_LINE_INFO); + + System::println(System::Color::error, "Error: unknown topic %s", topic); + help_topics(paths); + Checks::exit_fail(VCPKG_LINE_INFO); } } diff --git a/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp b/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp index 35cdbc12e..671a89892 100644 --- a/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp +++ b/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp @@ -250,26 +250,32 @@ namespace vcpkg if (failed) { - if (!command_structure.example_text.empty()) - { - System::println("%s", command_structure.example_text); - } - - System::println("Options:", this->command); - for (auto&& option : command_structure.options.switches) - { - System::println(" %-40s %s", option.name, option.short_help_text); - } - for (auto&& option : command_structure.options.settings) - { - System::println(" %-40s %s", (option.name + "=..."), option.short_help_text); - } - System::println(" --triplet "); - System::println(" --vcpkg-root "); - + display_usage(command_structure); Checks::exit_fail(VCPKG_LINE_INFO); } return output; } + + void display_usage(const CommandStructure& command_structure) + { + if (!command_structure.example_text.empty()) + { + System::println("%s", command_structure.example_text); + } + + System::println("Options:"); + for (auto&& option : command_structure.options.switches) + { + System::println(" %-40s %s", option.name, option.short_help_text); + } + for (auto&& option : command_structure.options.settings) + { + System::println(" %-40s %s", (option.name + "=..."), option.short_help_text); + } + System::println(" %-40s %s", "--triplet ", "Set the default triplet for unqualified packages"); + System::println(" %-40s %s", + "--vcpkg-root ", + "Specify the vcpkg directory to use instead of current directory or tool directory"); + } } -- cgit v1.2.3 From 115cd5f69f1060d3662355a3276948cd77b7fa31 Mon Sep 17 00:00:00 2001 From: Konstantin Podsvirov Date: Fri, 3 Nov 2017 20:31:13 +0300 Subject: [vcpkg-help-export-ifw] Add settings description --- toolsrc/src/vcpkg/export.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/export.cpp b/toolsrc/src/vcpkg/export.cpp index 625dff8b1..9b86863eb 100644 --- a/toolsrc/src/vcpkg/export.cpp +++ b/toolsrc/src/vcpkg/export.cpp @@ -283,11 +283,11 @@ namespace vcpkg::Export static const std::array EXPORT_SETTINGS = {{ {OPTION_NUGET_ID, "Specify the id for the exported NuGet package"}, {OPTION_NUGET_VERSION, "Specify the version for the exported NuGet package"}, - {OPTION_IFW_REPOSITORY_URL, ""}, - {OPTION_IFW_PACKAGES_DIR_PATH, ""}, - {OPTION_IFW_REPOSITORY_DIR_PATH, ""}, - {OPTION_IFW_CONFIG_FILE_PATH, ""}, - {OPTION_IFW_INSTALLER_FILE_PATH, ""}, + {OPTION_IFW_REPOSITORY_URL, "Specify the remote repository URL for the online installer"}, + {OPTION_IFW_PACKAGES_DIR_PATH, "Specify the temporary directory path for the repacked packages"}, + {OPTION_IFW_REPOSITORY_DIR_PATH, "Specify the directory path for the exported repository"}, + {OPTION_IFW_CONFIG_FILE_PATH, "Specify the temporary file path for the installer configuration"}, + {OPTION_IFW_INSTALLER_FILE_PATH, "Specify the file path for the exported installer"}, }}; const CommandStructure vcpkg::Export::COMMAND_STRUCTURE = { -- cgit v1.2.3 From 57934e5bbe485e904b47d49b3609d4000a4ca952 Mon Sep 17 00:00:00 2001 From: bjornpiltz Date: Thu, 2 Nov 2017 10:48:52 +0100 Subject: Print error message when there is a syntax error in triplet file As it is now vcpkg fails silently (actually, it outputs two empty lines). --- toolsrc/src/vcpkg/build.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index 8b4654aa8..ca0712a06 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -489,7 +489,7 @@ namespace vcpkg::Build {"CMAKE_TRIPLET_FILE", triplet_file_path}, }); const auto ec_data = System::cmd_execute_and_capture_output(cmd_launch_cmake); - Checks::check_exit(VCPKG_LINE_INFO, ec_data.exit_code == 0); + Checks::check_exit(VCPKG_LINE_INFO, ec_data.exit_code == 0, ec_data.output); const std::vector lines = Strings::split(ec_data.output, "\n"); -- cgit v1.2.3 From 3b90bc07ce6fb8639fbb0a142bdbbd458e85462a Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 3 Nov 2017 18:25:54 -0700 Subject: [cmake] Update to 3.9.5 (was 3.9.4) --- toolsrc/src/vcpkg/vcpkgpaths.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index 5e43ee4c7..c17b029c0 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -125,10 +125,10 @@ namespace vcpkg static fs::path get_cmake_path(const fs::path& downloads_folder, const fs::path& scripts_folder) { - static constexpr std::array EXPECTED_VERSION = {3, 9, 4}; + static constexpr std::array EXPECTED_VERSION = {3, 9, 5}; static const std::string VERSION_CHECK_ARGUMENTS = "--version"; - const fs::path downloaded_copy = downloads_folder / "cmake-3.9.4-win32-x86" / "bin" / "cmake.exe"; + const fs::path downloaded_copy = downloads_folder / "cmake-3.9.5-win32-x86" / "bin" / "cmake.exe"; const std::vector from_path = Files::find_from_PATH("cmake"); std::vector candidate_paths; -- cgit v1.2.3 From aec7d6d60628602fa153633f7e7e92fe66af0655 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 3 Nov 2017 18:41:19 -0700 Subject: Update CHANGELOG and bump version to v0.0.96 --- toolsrc/VERSION.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/VERSION.txt b/toolsrc/VERSION.txt index e5fce74a7..bc63ef127 100644 --- a/toolsrc/VERSION.txt +++ b/toolsrc/VERSION.txt @@ -1 +1 @@ -"0.0.95" \ No newline at end of file +"0.0.96" \ No newline at end of file -- cgit v1.2.3 From 61c0a337842b50d4b914893030193f3a1faaedf4 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Sat, 4 Nov 2017 16:40:11 -0700 Subject: Improve error messages around calling powershell scripts --- toolsrc/include/vcpkg/base/system.h | 4 +++- toolsrc/src/vcpkg/base/system.cpp | 28 ++++++++++++++++++++-- toolsrc/src/vcpkg/vcpkgpaths.cpp | 47 +++++++++++++++---------------------- 3 files changed, 48 insertions(+), 31 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/base/system.h b/toolsrc/include/vcpkg/base/system.h index a696bf3ae..9f2d91435 100644 --- a/toolsrc/include/vcpkg/base/system.h +++ b/toolsrc/include/vcpkg/base/system.h @@ -22,7 +22,9 @@ namespace vcpkg::System ExitCodeAndOutput cmd_execute_and_capture_output(const CStringView cmd_line); - ExitCodeAndOutput powershell_execute_and_capture_output(const fs::path& script_path, const CStringView args = ""); + std::string powershell_execute_and_capture_output(const std::string& title, + const fs::path& script_path, + const CStringView args = ""); enum class Color { diff --git a/toolsrc/src/vcpkg/base/system.cpp b/toolsrc/src/vcpkg/base/system.cpp index a1bc9daf6..47096ed63 100644 --- a/toolsrc/src/vcpkg/base/system.cpp +++ b/toolsrc/src/vcpkg/base/system.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include @@ -269,7 +270,9 @@ namespace vcpkg::System #endif } - ExitCodeAndOutput powershell_execute_and_capture_output(const fs::path& script_path, const CStringView args) + std::string powershell_execute_and_capture_output(const std::string& title, + const fs::path& script_path, + const CStringView args) { // TODO: switch out ExecutionPolicy Bypass with "Remove Mark Of The Web" code and restore RemoteSigned const std::string cmd = Strings::format( @@ -277,6 +280,27 @@ namespace vcpkg::System auto rc = System::cmd_execute_and_capture_output(cmd); + if (rc.exit_code) + { + System::println(Color::error, + "%s\n" + "Could not run:\n" + " '%s'\n" + "Error message was:\n" + " %s", + title, + script_path.generic_string(), + rc.output); + + { + auto locked_metrics = Metrics::g_metrics.lock(); + locked_metrics->track_property("error", "powershell script failed"); + locked_metrics->track_property("title", title); + } + + Checks::exit_with_code(VCPKG_LINE_INFO, rc.exit_code); + } + // Remove newline from all output. // Powershell returns newlines when it hits the column count of the console. // For example, this is 80 in cmd on Windows 7. If the expected output is longer than 80 lines, we get @@ -285,7 +309,7 @@ namespace vcpkg::System // and then strip all newlines here. rc.output = Strings::replace_all(std::move(rc.output), "\n", ""); - return rc; + return rc.output; } void println() { putchar('\n'); } diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index c17b029c0..a553f4199 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -91,26 +91,13 @@ namespace vcpkg tool_name, version_as_string); const fs::path script = scripts_folder / "fetchDependency.ps1"; - const System::ExitCodeAndOutput rc = - System::powershell_execute_and_capture_output(script, Strings::format("-Dependency %s", tool_name)); - if (rc.exit_code) - { - System::println(System::Color::error, - "Launching powershell failed or was denied when trying to fetch %s version %s.\n" - "(No sufficient installed version was found)", - tool_name, - version_as_string); - { - auto locked_metrics = Metrics::g_metrics.lock(); - locked_metrics->track_property("error", "powershell install failed"); - locked_metrics->track_property("dependency", tool_name); - } - Checks::exit_with_code(VCPKG_LINE_INFO, rc.exit_code); - } + const std::string title = "Fetching %s version %s (No sufficient installed version was found)"; + const std::string output = + System::powershell_execute_and_capture_output(title, script, Strings::format("-Dependency %s", tool_name)); - const std::vector dependency_path = keep_data_lines(rc.output); + const std::vector dependency_path = keep_data_lines(output); Checks::check_exit( - VCPKG_LINE_INFO, dependency_path.size() == 1, "Expected dependency path, but got %s", rc.output); + VCPKG_LINE_INFO, dependency_path.size() == 1, "Expected dependency path, but got %s", output); const fs::path actual_downloaded_path = Strings::trim(std::string{dependency_path.at(0)}); std::error_code ec; @@ -344,17 +331,21 @@ namespace vcpkg static std::vector get_visual_studio_instances(const VcpkgPaths& paths) { const fs::path script = paths.scripts / "findVisualStudioInstallationInstances.ps1"; - const System::ExitCodeAndOutput ec_data = System::powershell_execute_and_capture_output(script); - Checks::check_exit( - VCPKG_LINE_INFO, ec_data.exit_code == 0, "Could not run script to detect Visual Studio instances"); + const std::string output = + System::powershell_execute_and_capture_output("Detecting Visual Studio instances", script); - const std::vector instances_as_strings = keep_data_lines(ec_data.output); + const std::vector instances_as_strings = keep_data_lines(output); Checks::check_exit(VCPKG_LINE_INFO, !instances_as_strings.empty(), - "Could not detect any Visual Studio instances. Powershell returned: %s\n", - ec_data.output); - - std::vector output; + "Could not detect any Visual Studio instances.\n" + "Powershell script:\n" + " %s\n" + "returned:\n" + "%s", + script.generic_string(), + output); + + std::vector instances; for (const std::string& instance_as_string : instances_as_strings) { const std::vector split = Strings::split(instance_as_string, "::"); @@ -364,10 +355,10 @@ namespace vcpkg "Expected: PreferenceWeight::ReleaseType::Version::PathToVisualStudio\n" "Actual : %s\n", instance_as_string); - output.push_back({split.at(3), split.at(2), split.at(1), split.at(0)}); + instances.push_back({split.at(3), split.at(2), split.at(1), split.at(0)}); } - return output; + return instances; } static std::vector find_toolset_instances(const VcpkgPaths& paths) -- cgit v1.2.3 From eb99b0c705b78e6c278e0a3782a8324e9d304e69 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Mon, 6 Nov 2017 14:22:10 -0800 Subject: [vcpkg] Add tests for remove plans. --- toolsrc/src/tests.installplan.cpp | 493 ------------------------ toolsrc/src/tests.plan.cpp | 561 ++++++++++++++++++++++++++++ toolsrc/vcpkgtest/vcpkgtest.vcxproj | 2 +- toolsrc/vcpkgtest/vcpkgtest.vcxproj.filters | 6 +- 4 files changed, 565 insertions(+), 497 deletions(-) delete mode 100644 toolsrc/src/tests.installplan.cpp create mode 100644 toolsrc/src/tests.plan.cpp (limited to 'toolsrc') diff --git a/toolsrc/src/tests.installplan.cpp b/toolsrc/src/tests.installplan.cpp deleted file mode 100644 index 129926317..000000000 --- a/toolsrc/src/tests.installplan.cpp +++ /dev/null @@ -1,493 +0,0 @@ -#include -#include - -#include - -using namespace Microsoft::VisualStudio::CppUnitTestFramework; - -using namespace vcpkg; - -namespace Microsoft::VisualStudio::CppUnitTestFramework -{ - template<> - inline std::wstring ToString(const vcpkg::Dependencies::InstallPlanType& t) - { - switch (t) - { - case Dependencies::InstallPlanType::ALREADY_INSTALLED: return L"ALREADY_INSTALLED"; - case Dependencies::InstallPlanType::BUILD_AND_INSTALL: return L"BUILD_AND_INSTALL"; - case Dependencies::InstallPlanType::INSTALL: return L"INSTALL"; - case Dependencies::InstallPlanType::EXCLUDED: return L"EXCLUDED"; - case Dependencies::InstallPlanType::UNKNOWN: return L"UNKNOWN"; - default: return ToString(static_cast(t)); - } - } - - template<> - inline std::wstring ToString(const vcpkg::Dependencies::RequestType& t) - { - switch (t) - { - case Dependencies::RequestType::AUTO_SELECTED: return L"AUTO_SELECTED"; - case Dependencies::RequestType::USER_REQUESTED: return L"USER_REQUESTED"; - case Dependencies::RequestType::UNKNOWN: return L"UNKNOWN"; - default: return ToString(static_cast(t)); - } - } -} - -namespace UnitTest1 -{ - class InstallPlanTests : public TestClass - { - static std::unique_ptr make_control_file( - const char* name, - const char* depends, - const std::vector>& features = {}) - { - using Pgh = std::unordered_map; - std::vector scf_pghs; - scf_pghs.push_back(Pgh{ - {"Source", name}, - {"Version", "0"}, - {"Build-Depends", depends}, - }); - for (auto&& feature : features) - { - scf_pghs.push_back(Pgh{ - {"Feature", feature.first}, - {"Description", "feature"}, - {"Build-Depends", feature.second}, - }); - } - auto m_pgh = vcpkg::SourceControlFile::parse_control_file(std::move(scf_pghs)); - Assert::IsTrue(m_pgh.has_value()); - return std::move(*m_pgh.get()); - } - - static void features_check(Dependencies::AnyAction* install_action, - std::string pkg_name, - std::vector vec, - const Triplet& triplet = Triplet::X86_WINDOWS) - { - const auto& plan = install_action->install_plan.value_or_exit(VCPKG_LINE_INFO); - const auto& feature_list = plan.feature_list; - - Assert::AreEqual(plan.spec.triplet().to_string().c_str(), triplet.to_string().c_str()); - - Assert::AreEqual(pkg_name.c_str(), - (*plan.any_paragraph.source_control_file.get())->core_paragraph->name.c_str()); - Assert::AreEqual(size_t(vec.size()), feature_list.size()); - - for (auto&& feature_name : vec) - { - if (feature_name == "core" || feature_name == "") - { - Assert::IsTrue(Util::find(feature_list, "core") != feature_list.end() || - Util::find(feature_list, "") != feature_list.end()); - continue; - } - Assert::IsTrue(Util::find(feature_list, feature_name) != feature_list.end()); - } - } - - static void remove_plan_check(Dependencies::AnyAction* remove_action, - std::string pkg_name, - const Triplet& triplet = Triplet::X86_WINDOWS) - { - const auto& plan = remove_action->remove_plan.value_or_exit(VCPKG_LINE_INFO); - Assert::AreEqual(plan.spec.triplet().to_string().c_str(), triplet.to_string().c_str()); - Assert::AreEqual(pkg_name.c_str(), plan.spec.name().c_str()); - } - - static std::unique_ptr make_status_pgh(const char* name, const char* depends = "") - { - using Pgh = std::unordered_map; - return std::make_unique(Pgh{{"Package", name}, - {"Version", "1"}, - {"Architecture", "x86-windows"}, - {"Multi-Arch", "same"}, - {"Depends", depends}, - {"Status", "install ok installed"}}); - } - static std::unique_ptr make_status_feature_pgh(const char* name, - const char* feature, - const char* depends = "") - { - using Pgh = std::unordered_map; - return std::make_unique(Pgh{{"Package", name}, - {"Version", "1"}, - {"Feature", feature}, - {"Architecture", "x86-windows"}, - {"Multi-Arch", "same"}, - {"Depends", depends}, - {"Status", "install ok installed"}}); - } - struct PackageSpecMap - { - std::unordered_map map; - Triplet triplet; - PackageSpecMap(const Triplet& t) { triplet = t; } - - PackageSpec emplace(const char* name, - const char* depends = "", - const std::vector>& features = {}) - { - return emplace(std::move(*make_control_file(name, depends, features))); - } - PackageSpec emplace(vcpkg::SourceControlFile&& scf) - { - auto spec = PackageSpec::from_name_and_triplet(scf.core_paragraph->name, triplet); - Assert::IsTrue(spec.has_value()); - map.emplace(scf.core_paragraph->name, std::move(scf)); - return PackageSpec{*spec.get()}; - } - }; - - TEST_METHOD(basic_install_scheme) - { - std::vector> status_paragraphs; - - PackageSpecMap spec_map(Triplet::X86_WINDOWS); - auto spec_a = spec_map.emplace("a", "b"); - auto spec_b = spec_map.emplace("b", "c"); - auto spec_c = spec_map.emplace("c"); - - Dependencies::MapPortFile map_port(spec_map.map); - auto install_plan = - Dependencies::create_install_plan(map_port, {spec_a}, StatusParagraphs(std::move(status_paragraphs))); - - Assert::AreEqual(size_t(3), install_plan.size()); - Assert::AreEqual("c", install_plan[0].spec.name().c_str()); - Assert::AreEqual("b", install_plan[1].spec.name().c_str()); - Assert::AreEqual("a", install_plan[2].spec.name().c_str()); - } - - TEST_METHOD(multiple_install_scheme) - { - std::vector> status_paragraphs; - - PackageSpecMap spec_map(Triplet::X86_WINDOWS); - auto spec_a = spec_map.emplace("a", "d"); - auto spec_b = spec_map.emplace("b", "d, e"); - auto spec_c = spec_map.emplace("c", "e, h"); - auto spec_d = spec_map.emplace("d", "f, g, h"); - auto spec_e = spec_map.emplace("e", "g"); - auto spec_f = spec_map.emplace("f"); - auto spec_g = spec_map.emplace("g"); - auto spec_h = spec_map.emplace("h"); - - Dependencies::MapPortFile map_port(spec_map.map); - auto install_plan = Dependencies::create_install_plan( - map_port, {spec_a, spec_b, spec_c}, StatusParagraphs(std::move(status_paragraphs))); - - auto iterator_pos = [&](const PackageSpec& spec) -> int { - auto it = std::find_if( - install_plan.begin(), install_plan.end(), [&](auto& action) { return action.spec == spec; }); - Assert::IsTrue(it != install_plan.end()); - return (int)(it - install_plan.begin()); - }; - - int a_pos = iterator_pos(spec_a), b_pos = iterator_pos(spec_b), c_pos = iterator_pos(spec_c), - d_pos = iterator_pos(spec_d), e_pos = iterator_pos(spec_e), f_pos = iterator_pos(spec_f), - g_pos = iterator_pos(spec_g), h_pos = iterator_pos(spec_h); - - Assert::IsTrue(a_pos > d_pos); - Assert::IsTrue(b_pos > e_pos); - Assert::IsTrue(b_pos > d_pos); - Assert::IsTrue(c_pos > e_pos); - Assert::IsTrue(c_pos > h_pos); - Assert::IsTrue(d_pos > f_pos); - Assert::IsTrue(d_pos > g_pos); - Assert::IsTrue(d_pos > h_pos); - Assert::IsTrue(e_pos > g_pos); - } - - TEST_METHOD(existing_package_scheme) - { - std::vector> status_paragraphs; - status_paragraphs.push_back(make_status_pgh("a")); - - PackageSpecMap spec_map(Triplet::X86_WINDOWS); - auto spec_a = FullPackageSpec{spec_map.emplace("a")}; - - auto install_plan = - Dependencies::create_feature_install_plan(spec_map.map, - FullPackageSpec::to_feature_specs({spec_a}), - StatusParagraphs(std::move(status_paragraphs))); - - Assert::AreEqual(size_t(1), install_plan.size()); - auto p = install_plan[0].install_plan.get(); - Assert::IsNotNull(p); - Assert::AreEqual("a", p->spec.name().c_str()); - Assert::AreEqual(Dependencies::InstallPlanType::ALREADY_INSTALLED, p->plan_type); - Assert::AreEqual(Dependencies::RequestType::USER_REQUESTED, p->request_type); - } - - TEST_METHOD(user_requested_package_scheme) - { - std::vector> status_paragraphs; - - PackageSpecMap spec_map(Triplet::X86_WINDOWS); - auto spec_a = FullPackageSpec{spec_map.emplace("a", "b")}; - auto spec_b = FullPackageSpec{spec_map.emplace("b")}; - - auto install_plan = - Dependencies::create_feature_install_plan(spec_map.map, - FullPackageSpec::to_feature_specs({spec_a}), - StatusParagraphs(std::move(status_paragraphs))); - - Assert::AreEqual(size_t(2), install_plan.size()); - auto p = install_plan[0].install_plan.get(); - Assert::IsNotNull(p); - Assert::AreEqual("b", p->spec.name().c_str()); - Assert::AreEqual(Dependencies::InstallPlanType::BUILD_AND_INSTALL, p->plan_type); - Assert::AreEqual(Dependencies::RequestType::AUTO_SELECTED, p->request_type); - - auto p2 = install_plan[1].install_plan.get(); - Assert::IsNotNull(p2); - Assert::AreEqual("a", p2->spec.name().c_str()); - Assert::AreEqual(Dependencies::InstallPlanType::BUILD_AND_INSTALL, p2->plan_type); - Assert::AreEqual(Dependencies::RequestType::USER_REQUESTED, p2->request_type); - } - - TEST_METHOD(long_install_scheme) - { - std::vector> status_paragraphs; - status_paragraphs.push_back(make_status_pgh("j", "k")); - status_paragraphs.push_back(make_status_pgh("k")); - - PackageSpecMap spec_map(Triplet::X86_WINDOWS); - - auto spec_a = spec_map.emplace("a", "b, c, d, e, f, g, h, j, k"); - auto spec_b = spec_map.emplace("b", "c, d, e, f, g, h, j, k"); - auto spec_c = spec_map.emplace("c", "d, e, f, g, h, j, k"); - auto spec_d = spec_map.emplace("d", "e, f, g, h, j, k"); - auto spec_e = spec_map.emplace("e", "f, g, h, j, k"); - auto spec_f = spec_map.emplace("f", "g, h, j, k"); - auto spec_g = spec_map.emplace("g", "h, j, k"); - auto spec_h = spec_map.emplace("h", "j, k"); - auto spec_j = spec_map.emplace("j", "k"); - auto spec_k = spec_map.emplace("k"); - - Dependencies::MapPortFile map_port(spec_map.map); - auto install_plan = - Dependencies::create_install_plan(map_port, {spec_a}, StatusParagraphs(std::move(status_paragraphs))); - - Assert::AreEqual(size_t(8), install_plan.size()); - Assert::AreEqual("h", install_plan[0].spec.name().c_str()); - Assert::AreEqual("g", install_plan[1].spec.name().c_str()); - Assert::AreEqual("f", install_plan[2].spec.name().c_str()); - Assert::AreEqual("e", install_plan[3].spec.name().c_str()); - Assert::AreEqual("d", install_plan[4].spec.name().c_str()); - Assert::AreEqual("c", install_plan[5].spec.name().c_str()); - Assert::AreEqual("b", install_plan[6].spec.name().c_str()); - Assert::AreEqual("a", install_plan[7].spec.name().c_str()); - } - - TEST_METHOD(basic_feature_test_1) - { - std::vector> status_paragraphs; - status_paragraphs.push_back(make_status_pgh("a", "b, b[b1]")); - status_paragraphs.push_back(make_status_pgh("b")); - status_paragraphs.push_back(make_status_feature_pgh("b", "b1")); - - PackageSpecMap spec_map(Triplet::X86_WINDOWS); - auto spec_a = FullPackageSpec{spec_map.emplace("a", "b, b[b1]", {{"a1", "b[b2]"}}), {"a1"}}; - auto spec_b = FullPackageSpec{spec_map.emplace("b", "", {{"b1", ""}, {"b2", ""}, {"b3", ""}})}; - - auto install_plan = - Dependencies::create_feature_install_plan(spec_map.map, - FullPackageSpec::to_feature_specs({spec_a}), - StatusParagraphs(std::move(status_paragraphs))); - - Assert::AreEqual(size_t(4), install_plan.size()); - remove_plan_check(&install_plan[0], "a"); - remove_plan_check(&install_plan[1], "b"); - features_check(&install_plan[2], "b", {"b1", "core", "b1"}); - features_check(&install_plan[3], "a", {"a1", "core"}); - } - - TEST_METHOD(basic_feature_test_2) - { - std::vector> status_paragraphs; - - PackageSpecMap spec_map(Triplet::X86_WINDOWS); - - auto spec_a = FullPackageSpec{spec_map.emplace("a", "b[b1]", {{"a1", "b[b2]"}}), {"a1"}}; - auto spec_b = FullPackageSpec{spec_map.emplace("b", "", {{"b1", ""}, {"b2", ""}, {"b3", ""}})}; - - auto install_plan = - Dependencies::create_feature_install_plan(spec_map.map, - FullPackageSpec::to_feature_specs({spec_a}), - StatusParagraphs(std::move(status_paragraphs))); - - Assert::AreEqual(size_t(2), install_plan.size()); - features_check(&install_plan[0], "b", {"b1", "b2", "core"}); - features_check(&install_plan[1], "a", {"a1", "core"}); - } - - TEST_METHOD(basic_feature_test_3) - { - std::vector> status_paragraphs; - status_paragraphs.push_back(make_status_pgh("a")); - - PackageSpecMap spec_map(Triplet::X86_WINDOWS); - - auto spec_a = FullPackageSpec{spec_map.emplace("a", "b", {{"a1", ""}}), {"core"}}; - auto spec_b = FullPackageSpec{spec_map.emplace("b")}; - auto spec_c = FullPackageSpec{spec_map.emplace("c", "a[a1]"), {"core"}}; - - auto install_plan = - Dependencies::create_feature_install_plan(spec_map.map, - FullPackageSpec::to_feature_specs({spec_c, spec_a}), - StatusParagraphs(std::move(status_paragraphs))); - - Assert::AreEqual(size_t(4), install_plan.size()); - remove_plan_check(&install_plan[0], "a"); - features_check(&install_plan[1], "b", {"core"}); - features_check(&install_plan[2], "a", {"a1", "core"}); - features_check(&install_plan[3], "c", {"core"}); - } - - TEST_METHOD(basic_feature_test_4) - { - std::vector> status_paragraphs; - status_paragraphs.push_back(make_status_pgh("a")); - status_paragraphs.push_back(make_status_feature_pgh("a", "a1", "")); - - PackageSpecMap spec_map(Triplet::X86_WINDOWS); - - auto spec_a = FullPackageSpec{spec_map.emplace("a", "b", {{"a1", ""}})}; - auto spec_b = FullPackageSpec{spec_map.emplace("b")}; - auto spec_c = FullPackageSpec{spec_map.emplace("c", "a[a1]"), {"core"}}; - - auto install_plan = - Dependencies::create_feature_install_plan(spec_map.map, - FullPackageSpec::to_feature_specs({spec_c}), - StatusParagraphs(std::move(status_paragraphs))); - - Assert::AreEqual(size_t(1), install_plan.size()); - features_check(&install_plan[0], "c", {"core"}); - } - - TEST_METHOD(basic_feature_test_5) - { - std::vector> status_paragraphs; - - PackageSpecMap spec_map(Triplet::X86_WINDOWS); - - auto spec_a = - FullPackageSpec{spec_map.emplace("a", "", {{"a1", "b[b1]"}, {"a2", "b[b2]"}, {"a3", "a[a2]"}}), {"a3"}}; - auto spec_b = FullPackageSpec{spec_map.emplace("b", "", {{"b1", ""}, {"b2", ""}})}; - - auto install_plan = - Dependencies::create_feature_install_plan(spec_map.map, - FullPackageSpec::to_feature_specs({spec_a}), - StatusParagraphs(std::move(status_paragraphs))); - - Assert::AreEqual(size_t(2), install_plan.size()); - features_check(&install_plan[0], "b", {"core", "b2"}); - features_check(&install_plan[1], "a", {"core", "a3", "a2"}); - } - - TEST_METHOD(basic_feature_test_6) - { - std::vector> status_paragraphs; - status_paragraphs.push_back(make_status_pgh("b")); - - PackageSpecMap spec_map(Triplet::X86_WINDOWS); - auto spec_a = FullPackageSpec{spec_map.emplace("a", "b[core]"), {"core"}}; - auto spec_b = FullPackageSpec{spec_map.emplace("b", "", {{"b1", ""}}), {"b1"}}; - - auto install_plan = - Dependencies::create_feature_install_plan(spec_map.map, - FullPackageSpec::to_feature_specs({spec_a, spec_b}), - StatusParagraphs(std::move(status_paragraphs))); - - Assert::AreEqual(size_t(3), install_plan.size()); - remove_plan_check(&install_plan[0], "b"); - features_check(&install_plan[1], "b", {"core", "b1"}); - features_check(&install_plan[2], "a", {"core"}); - } - - TEST_METHOD(basic_feature_test_7) - { - std::vector> status_paragraphs; - status_paragraphs.push_back(make_status_pgh("x", "b")); - status_paragraphs.push_back(make_status_pgh("b")); - - PackageSpecMap spec_map(Triplet::X86_WINDOWS); - - auto spec_a = FullPackageSpec{spec_map.emplace("a")}; - auto spec_x = FullPackageSpec{spec_map.emplace("x", "a"), {"core"}}; - auto spec_b = FullPackageSpec{spec_map.emplace("b", "", {{"b1", ""}}), {"b1"}}; - - auto install_plan = - Dependencies::create_feature_install_plan(spec_map.map, - FullPackageSpec::to_feature_specs({spec_b}), - StatusParagraphs(std::move(status_paragraphs))); - - Assert::AreEqual(size_t(5), install_plan.size()); - remove_plan_check(&install_plan[0], "x"); - remove_plan_check(&install_plan[1], "b"); - - // TODO: order here may change but A < X, and B anywhere - features_check(&install_plan[2], "b", {"core", "b1"}); - features_check(&install_plan[3], "a", {"core"}); - features_check(&install_plan[4], "x", {"core"}); - } - - TEST_METHOD(basic_feature_test_8) - { - std::vector> status_paragraphs; - status_paragraphs.push_back(make_status_pgh("a")); - status_paragraphs.push_back(make_status_pgh("a")); - status_paragraphs.back()->package.spec = - PackageSpec::from_name_and_triplet("a", Triplet::X64_WINDOWS).value_or_exit(VCPKG_LINE_INFO); - - PackageSpecMap spec_map(Triplet::X64_WINDOWS); - auto spec_a_64 = FullPackageSpec{spec_map.emplace("a", "b", {{"a1", ""}}), {"core"}}; - auto spec_b_64 = FullPackageSpec{spec_map.emplace("b")}; - auto spec_c_64 = FullPackageSpec{spec_map.emplace("c", "a[a1]"), {"core"}}; - - spec_map.triplet = Triplet::X86_WINDOWS; - auto spec_a_86 = FullPackageSpec{spec_map.emplace("a", "b", {{"a1", ""}}), {"core"}}; - auto spec_b_86 = FullPackageSpec{spec_map.emplace("b")}; - auto spec_c_86 = FullPackageSpec{spec_map.emplace("c", "a[a1]"), {"core"}}; - - auto install_plan = Dependencies::create_feature_install_plan( - spec_map.map, - FullPackageSpec::to_feature_specs({spec_c_64, spec_a_86, spec_a_64, spec_c_86}), - StatusParagraphs(std::move(status_paragraphs))); - - remove_plan_check(&install_plan[0], "a", Triplet::X64_WINDOWS); - remove_plan_check(&install_plan[1], "a"); - features_check(&install_plan[2], "b", {"core"}, Triplet::X64_WINDOWS); - features_check(&install_plan[3], "a", {"a1", "core"}, Triplet::X64_WINDOWS); - features_check(&install_plan[4], "c", {"core"}, Triplet::X64_WINDOWS); - features_check(&install_plan[5], "b", {"core"}); - features_check(&install_plan[6], "a", {"a1", "core"}); - features_check(&install_plan[7], "c", {"core"}); - } - - TEST_METHOD(install_all_features_test) - { - std::vector> status_paragraphs; - - PackageSpecMap spec_map(Triplet::X64_WINDOWS); - auto spec_a_64 = FullPackageSpec{spec_map.emplace("a", "", {{"0", ""}, {"1", ""}}), {"core"}}; - - auto install_specs = FullPackageSpec::from_string("a[*]", Triplet::X64_WINDOWS); - Assert::IsTrue(install_specs.has_value()); - if (!install_specs.has_value()) return; - auto install_plan = Dependencies::create_feature_install_plan( - spec_map.map, - FullPackageSpec::to_feature_specs({install_specs.value_or_exit(VCPKG_LINE_INFO)}), - StatusParagraphs(std::move(status_paragraphs))); - - Assert::IsTrue(install_plan.size() == 1); - features_check(&install_plan[0], "a", {"0", "1", "core"}, Triplet::X64_WINDOWS); - } - }; -} diff --git a/toolsrc/src/tests.plan.cpp b/toolsrc/src/tests.plan.cpp new file mode 100644 index 000000000..d62178bdf --- /dev/null +++ b/toolsrc/src/tests.plan.cpp @@ -0,0 +1,561 @@ +#include +#include + +#include + +using namespace Microsoft::VisualStudio::CppUnitTestFramework; + +using namespace vcpkg; + +namespace Microsoft::VisualStudio::CppUnitTestFramework +{ + template<> + inline std::wstring ToString(const vcpkg::Dependencies::InstallPlanType& t) + { + switch (t) + { + case Dependencies::InstallPlanType::ALREADY_INSTALLED: return L"ALREADY_INSTALLED"; + case Dependencies::InstallPlanType::BUILD_AND_INSTALL: return L"BUILD_AND_INSTALL"; + case Dependencies::InstallPlanType::INSTALL: return L"INSTALL"; + case Dependencies::InstallPlanType::EXCLUDED: return L"EXCLUDED"; + case Dependencies::InstallPlanType::UNKNOWN: return L"UNKNOWN"; + default: return ToString(static_cast(t)); + } + } + + template<> + inline std::wstring ToString(const vcpkg::Dependencies::RequestType& t) + { + switch (t) + { + case Dependencies::RequestType::AUTO_SELECTED: return L"AUTO_SELECTED"; + case Dependencies::RequestType::USER_REQUESTED: return L"USER_REQUESTED"; + case Dependencies::RequestType::UNKNOWN: return L"UNKNOWN"; + default: return ToString(static_cast(t)); + } + } +} + +namespace UnitTest1 +{ + static std::unique_ptr make_control_file( + const char* name, + const char* depends, + const std::vector>& features = {}) + { + using Pgh = std::unordered_map; + std::vector scf_pghs; + scf_pghs.push_back(Pgh{ + { "Source", name }, + { "Version", "0" }, + { "Build-Depends", depends }, + }); + for (auto&& feature : features) + { + scf_pghs.push_back(Pgh{ + { "Feature", feature.first }, + { "Description", "feature" }, + { "Build-Depends", feature.second }, + }); + } + auto m_pgh = vcpkg::SourceControlFile::parse_control_file(std::move(scf_pghs)); + Assert::IsTrue(m_pgh.has_value()); + return std::move(*m_pgh.get()); + } + + static void features_check(Dependencies::AnyAction* install_action, + std::string pkg_name, + std::vector vec, + const Triplet& triplet = Triplet::X86_WINDOWS) + { + const auto& plan = install_action->install_plan.value_or_exit(VCPKG_LINE_INFO); + const auto& feature_list = plan.feature_list; + + Assert::AreEqual(plan.spec.triplet().to_string().c_str(), triplet.to_string().c_str()); + + Assert::AreEqual(pkg_name.c_str(), + (*plan.any_paragraph.source_control_file.get())->core_paragraph->name.c_str()); + Assert::AreEqual(size_t(vec.size()), feature_list.size()); + + for (auto&& feature_name : vec) + { + if (feature_name == "core" || feature_name == "") + { + Assert::IsTrue(Util::find(feature_list, "core") != feature_list.end() || + Util::find(feature_list, "") != feature_list.end()); + continue; + } + Assert::IsTrue(Util::find(feature_list, feature_name) != feature_list.end()); + } + } + + static void remove_plan_check(Dependencies::AnyAction* remove_action, + std::string pkg_name, + const Triplet& triplet = Triplet::X86_WINDOWS) + { + const auto& plan = remove_action->remove_plan.value_or_exit(VCPKG_LINE_INFO); + Assert::AreEqual(plan.spec.triplet().to_string().c_str(), triplet.to_string().c_str()); + Assert::AreEqual(pkg_name.c_str(), plan.spec.name().c_str()); + } + + static std::unique_ptr make_status_pgh(const char* name, const char* depends = "") + { + using Pgh = std::unordered_map; + return std::make_unique(Pgh{ { "Package", name }, + { "Version", "1" }, + { "Architecture", "x86-windows" }, + { "Multi-Arch", "same" }, + { "Depends", depends }, + { "Status", "install ok installed" } }); + } + static std::unique_ptr make_status_feature_pgh(const char* name, + const char* feature, + const char* depends = "") + { + using Pgh = std::unordered_map; + return std::make_unique(Pgh{ { "Package", name }, + { "Version", "1" }, + { "Feature", feature }, + { "Architecture", "x86-windows" }, + { "Multi-Arch", "same" }, + { "Depends", depends }, + { "Status", "install ok installed" } }); + } + struct PackageSpecMap + { + std::unordered_map map; + Triplet triplet; + PackageSpecMap(const Triplet& t) { triplet = t; } + + PackageSpec emplace(const char* name, + const char* depends = "", + const std::vector>& features = {}) + { + return emplace(std::move(*make_control_file(name, depends, features))); + } + PackageSpec emplace(vcpkg::SourceControlFile&& scf) + { + auto spec = PackageSpec::from_name_and_triplet(scf.core_paragraph->name, triplet); + Assert::IsTrue(spec.has_value()); + map.emplace(scf.core_paragraph->name, std::move(scf)); + return PackageSpec{ *spec.get() }; + } + }; + + class InstallPlanTests : public TestClass + { + TEST_METHOD(basic_install_scheme) + { + std::vector> status_paragraphs; + + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + auto spec_a = spec_map.emplace("a", "b"); + auto spec_b = spec_map.emplace("b", "c"); + auto spec_c = spec_map.emplace("c"); + + Dependencies::MapPortFile map_port(spec_map.map); + auto install_plan = + Dependencies::create_install_plan(map_port, {spec_a}, StatusParagraphs(std::move(status_paragraphs))); + + Assert::AreEqual(size_t(3), install_plan.size()); + Assert::AreEqual("c", install_plan[0].spec.name().c_str()); + Assert::AreEqual("b", install_plan[1].spec.name().c_str()); + Assert::AreEqual("a", install_plan[2].spec.name().c_str()); + } + + TEST_METHOD(multiple_install_scheme) + { + std::vector> status_paragraphs; + + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + auto spec_a = spec_map.emplace("a", "d"); + auto spec_b = spec_map.emplace("b", "d, e"); + auto spec_c = spec_map.emplace("c", "e, h"); + auto spec_d = spec_map.emplace("d", "f, g, h"); + auto spec_e = spec_map.emplace("e", "g"); + auto spec_f = spec_map.emplace("f"); + auto spec_g = spec_map.emplace("g"); + auto spec_h = spec_map.emplace("h"); + + Dependencies::MapPortFile map_port(spec_map.map); + auto install_plan = Dependencies::create_install_plan( + map_port, {spec_a, spec_b, spec_c}, StatusParagraphs(std::move(status_paragraphs))); + + auto iterator_pos = [&](const PackageSpec& spec) -> int { + auto it = std::find_if( + install_plan.begin(), install_plan.end(), [&](auto& action) { return action.spec == spec; }); + Assert::IsTrue(it != install_plan.end()); + return (int)(it - install_plan.begin()); + }; + + int a_pos = iterator_pos(spec_a), b_pos = iterator_pos(spec_b), c_pos = iterator_pos(spec_c), + d_pos = iterator_pos(spec_d), e_pos = iterator_pos(spec_e), f_pos = iterator_pos(spec_f), + g_pos = iterator_pos(spec_g), h_pos = iterator_pos(spec_h); + + Assert::IsTrue(a_pos > d_pos); + Assert::IsTrue(b_pos > e_pos); + Assert::IsTrue(b_pos > d_pos); + Assert::IsTrue(c_pos > e_pos); + Assert::IsTrue(c_pos > h_pos); + Assert::IsTrue(d_pos > f_pos); + Assert::IsTrue(d_pos > g_pos); + Assert::IsTrue(d_pos > h_pos); + Assert::IsTrue(e_pos > g_pos); + } + + TEST_METHOD(existing_package_scheme) + { + std::vector> status_paragraphs; + status_paragraphs.push_back(make_status_pgh("a")); + + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + auto spec_a = FullPackageSpec{spec_map.emplace("a")}; + + auto install_plan = + Dependencies::create_feature_install_plan(spec_map.map, + FullPackageSpec::to_feature_specs({spec_a}), + StatusParagraphs(std::move(status_paragraphs))); + + Assert::AreEqual(size_t(1), install_plan.size()); + auto p = install_plan[0].install_plan.get(); + Assert::IsNotNull(p); + Assert::AreEqual("a", p->spec.name().c_str()); + Assert::AreEqual(Dependencies::InstallPlanType::ALREADY_INSTALLED, p->plan_type); + Assert::AreEqual(Dependencies::RequestType::USER_REQUESTED, p->request_type); + } + + TEST_METHOD(user_requested_package_scheme) + { + std::vector> status_paragraphs; + + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + auto spec_a = FullPackageSpec{spec_map.emplace("a", "b")}; + auto spec_b = FullPackageSpec{spec_map.emplace("b")}; + + auto install_plan = + Dependencies::create_feature_install_plan(spec_map.map, + FullPackageSpec::to_feature_specs({spec_a}), + StatusParagraphs(std::move(status_paragraphs))); + + Assert::AreEqual(size_t(2), install_plan.size()); + auto p = install_plan[0].install_plan.get(); + Assert::IsNotNull(p); + Assert::AreEqual("b", p->spec.name().c_str()); + Assert::AreEqual(Dependencies::InstallPlanType::BUILD_AND_INSTALL, p->plan_type); + Assert::AreEqual(Dependencies::RequestType::AUTO_SELECTED, p->request_type); + + auto p2 = install_plan[1].install_plan.get(); + Assert::IsNotNull(p2); + Assert::AreEqual("a", p2->spec.name().c_str()); + Assert::AreEqual(Dependencies::InstallPlanType::BUILD_AND_INSTALL, p2->plan_type); + Assert::AreEqual(Dependencies::RequestType::USER_REQUESTED, p2->request_type); + } + + TEST_METHOD(long_install_scheme) + { + std::vector> status_paragraphs; + status_paragraphs.push_back(make_status_pgh("j", "k")); + status_paragraphs.push_back(make_status_pgh("k")); + + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + + auto spec_a = spec_map.emplace("a", "b, c, d, e, f, g, h, j, k"); + auto spec_b = spec_map.emplace("b", "c, d, e, f, g, h, j, k"); + auto spec_c = spec_map.emplace("c", "d, e, f, g, h, j, k"); + auto spec_d = spec_map.emplace("d", "e, f, g, h, j, k"); + auto spec_e = spec_map.emplace("e", "f, g, h, j, k"); + auto spec_f = spec_map.emplace("f", "g, h, j, k"); + auto spec_g = spec_map.emplace("g", "h, j, k"); + auto spec_h = spec_map.emplace("h", "j, k"); + auto spec_j = spec_map.emplace("j", "k"); + auto spec_k = spec_map.emplace("k"); + + Dependencies::MapPortFile map_port(spec_map.map); + auto install_plan = + Dependencies::create_install_plan(map_port, {spec_a}, StatusParagraphs(std::move(status_paragraphs))); + + Assert::AreEqual(size_t(8), install_plan.size()); + Assert::AreEqual("h", install_plan[0].spec.name().c_str()); + Assert::AreEqual("g", install_plan[1].spec.name().c_str()); + Assert::AreEqual("f", install_plan[2].spec.name().c_str()); + Assert::AreEqual("e", install_plan[3].spec.name().c_str()); + Assert::AreEqual("d", install_plan[4].spec.name().c_str()); + Assert::AreEqual("c", install_plan[5].spec.name().c_str()); + Assert::AreEqual("b", install_plan[6].spec.name().c_str()); + Assert::AreEqual("a", install_plan[7].spec.name().c_str()); + } + + TEST_METHOD(basic_feature_test_1) + { + std::vector> status_paragraphs; + status_paragraphs.push_back(make_status_pgh("a", "b, b[b1]")); + status_paragraphs.push_back(make_status_pgh("b")); + status_paragraphs.push_back(make_status_feature_pgh("b", "b1")); + + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + auto spec_a = FullPackageSpec{spec_map.emplace("a", "b, b[b1]", {{"a1", "b[b2]"}}), {"a1"}}; + auto spec_b = FullPackageSpec{spec_map.emplace("b", "", {{"b1", ""}, {"b2", ""}, {"b3", ""}})}; + + auto install_plan = + Dependencies::create_feature_install_plan(spec_map.map, + FullPackageSpec::to_feature_specs({spec_a}), + StatusParagraphs(std::move(status_paragraphs))); + + Assert::AreEqual(size_t(4), install_plan.size()); + remove_plan_check(&install_plan[0], "a"); + remove_plan_check(&install_plan[1], "b"); + features_check(&install_plan[2], "b", {"b1", "core", "b1"}); + features_check(&install_plan[3], "a", {"a1", "core"}); + } + + TEST_METHOD(basic_feature_test_2) + { + std::vector> status_paragraphs; + + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + + auto spec_a = FullPackageSpec{spec_map.emplace("a", "b[b1]", {{"a1", "b[b2]"}}), {"a1"}}; + auto spec_b = FullPackageSpec{spec_map.emplace("b", "", {{"b1", ""}, {"b2", ""}, {"b3", ""}})}; + + auto install_plan = + Dependencies::create_feature_install_plan(spec_map.map, + FullPackageSpec::to_feature_specs({spec_a}), + StatusParagraphs(std::move(status_paragraphs))); + + Assert::AreEqual(size_t(2), install_plan.size()); + features_check(&install_plan[0], "b", {"b1", "b2", "core"}); + features_check(&install_plan[1], "a", {"a1", "core"}); + } + + TEST_METHOD(basic_feature_test_3) + { + std::vector> status_paragraphs; + status_paragraphs.push_back(make_status_pgh("a")); + + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + + auto spec_a = FullPackageSpec{spec_map.emplace("a", "b", {{"a1", ""}}), {"core"}}; + auto spec_b = FullPackageSpec{spec_map.emplace("b")}; + auto spec_c = FullPackageSpec{spec_map.emplace("c", "a[a1]"), {"core"}}; + + auto install_plan = + Dependencies::create_feature_install_plan(spec_map.map, + FullPackageSpec::to_feature_specs({spec_c, spec_a}), + StatusParagraphs(std::move(status_paragraphs))); + + Assert::AreEqual(size_t(4), install_plan.size()); + remove_plan_check(&install_plan[0], "a"); + features_check(&install_plan[1], "b", {"core"}); + features_check(&install_plan[2], "a", {"a1", "core"}); + features_check(&install_plan[3], "c", {"core"}); + } + + TEST_METHOD(basic_feature_test_4) + { + std::vector> status_paragraphs; + status_paragraphs.push_back(make_status_pgh("a")); + status_paragraphs.push_back(make_status_feature_pgh("a", "a1", "")); + + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + + auto spec_a = FullPackageSpec{spec_map.emplace("a", "b", {{"a1", ""}})}; + auto spec_b = FullPackageSpec{spec_map.emplace("b")}; + auto spec_c = FullPackageSpec{spec_map.emplace("c", "a[a1]"), {"core"}}; + + auto install_plan = + Dependencies::create_feature_install_plan(spec_map.map, + FullPackageSpec::to_feature_specs({spec_c}), + StatusParagraphs(std::move(status_paragraphs))); + + Assert::AreEqual(size_t(1), install_plan.size()); + features_check(&install_plan[0], "c", {"core"}); + } + + TEST_METHOD(basic_feature_test_5) + { + std::vector> status_paragraphs; + + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + + auto spec_a = + FullPackageSpec{spec_map.emplace("a", "", {{"a1", "b[b1]"}, {"a2", "b[b2]"}, {"a3", "a[a2]"}}), {"a3"}}; + auto spec_b = FullPackageSpec{spec_map.emplace("b", "", {{"b1", ""}, {"b2", ""}})}; + + auto install_plan = + Dependencies::create_feature_install_plan(spec_map.map, + FullPackageSpec::to_feature_specs({spec_a}), + StatusParagraphs(std::move(status_paragraphs))); + + Assert::AreEqual(size_t(2), install_plan.size()); + features_check(&install_plan[0], "b", {"core", "b2"}); + features_check(&install_plan[1], "a", {"core", "a3", "a2"}); + } + + TEST_METHOD(basic_feature_test_6) + { + std::vector> status_paragraphs; + status_paragraphs.push_back(make_status_pgh("b")); + + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + auto spec_a = FullPackageSpec{spec_map.emplace("a", "b[core]"), {"core"}}; + auto spec_b = FullPackageSpec{spec_map.emplace("b", "", {{"b1", ""}}), {"b1"}}; + + auto install_plan = + Dependencies::create_feature_install_plan(spec_map.map, + FullPackageSpec::to_feature_specs({spec_a, spec_b}), + StatusParagraphs(std::move(status_paragraphs))); + + Assert::AreEqual(size_t(3), install_plan.size()); + remove_plan_check(&install_plan[0], "b"); + features_check(&install_plan[1], "b", {"core", "b1"}); + features_check(&install_plan[2], "a", {"core"}); + } + + TEST_METHOD(basic_feature_test_7) + { + std::vector> status_paragraphs; + status_paragraphs.push_back(make_status_pgh("x", "b")); + status_paragraphs.push_back(make_status_pgh("b")); + + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + + auto spec_a = FullPackageSpec{spec_map.emplace("a")}; + auto spec_x = FullPackageSpec{spec_map.emplace("x", "a"), {"core"}}; + auto spec_b = FullPackageSpec{spec_map.emplace("b", "", {{"b1", ""}}), {"b1"}}; + + auto install_plan = + Dependencies::create_feature_install_plan(spec_map.map, + FullPackageSpec::to_feature_specs({spec_b}), + StatusParagraphs(std::move(status_paragraphs))); + + Assert::AreEqual(size_t(5), install_plan.size()); + remove_plan_check(&install_plan[0], "x"); + remove_plan_check(&install_plan[1], "b"); + + // TODO: order here may change but A < X, and B anywhere + features_check(&install_plan[2], "b", {"core", "b1"}); + features_check(&install_plan[3], "a", {"core"}); + features_check(&install_plan[4], "x", {"core"}); + } + + TEST_METHOD(basic_feature_test_8) + { + std::vector> status_paragraphs; + status_paragraphs.push_back(make_status_pgh("a")); + status_paragraphs.push_back(make_status_pgh("a")); + status_paragraphs.back()->package.spec = + PackageSpec::from_name_and_triplet("a", Triplet::X64_WINDOWS).value_or_exit(VCPKG_LINE_INFO); + + PackageSpecMap spec_map(Triplet::X64_WINDOWS); + auto spec_a_64 = FullPackageSpec{spec_map.emplace("a", "b", {{"a1", ""}}), {"core"}}; + auto spec_b_64 = FullPackageSpec{spec_map.emplace("b")}; + auto spec_c_64 = FullPackageSpec{spec_map.emplace("c", "a[a1]"), {"core"}}; + + spec_map.triplet = Triplet::X86_WINDOWS; + auto spec_a_86 = FullPackageSpec{spec_map.emplace("a", "b", {{"a1", ""}}), {"core"}}; + auto spec_b_86 = FullPackageSpec{spec_map.emplace("b")}; + auto spec_c_86 = FullPackageSpec{spec_map.emplace("c", "a[a1]"), {"core"}}; + + auto install_plan = Dependencies::create_feature_install_plan( + spec_map.map, + FullPackageSpec::to_feature_specs({spec_c_64, spec_a_86, spec_a_64, spec_c_86}), + StatusParagraphs(std::move(status_paragraphs))); + + remove_plan_check(&install_plan[0], "a", Triplet::X64_WINDOWS); + remove_plan_check(&install_plan[1], "a"); + features_check(&install_plan[2], "b", {"core"}, Triplet::X64_WINDOWS); + features_check(&install_plan[3], "a", {"a1", "core"}, Triplet::X64_WINDOWS); + features_check(&install_plan[4], "c", {"core"}, Triplet::X64_WINDOWS); + features_check(&install_plan[5], "b", {"core"}); + features_check(&install_plan[6], "a", {"a1", "core"}); + features_check(&install_plan[7], "c", {"core"}); + } + + TEST_METHOD(install_all_features_test) + { + std::vector> status_paragraphs; + + PackageSpecMap spec_map(Triplet::X64_WINDOWS); + auto spec_a_64 = FullPackageSpec{spec_map.emplace("a", "", {{"0", ""}, {"1", ""}}), {"core"}}; + + auto install_specs = FullPackageSpec::from_string("a[*]", Triplet::X64_WINDOWS); + Assert::IsTrue(install_specs.has_value()); + if (!install_specs.has_value()) return; + auto install_plan = Dependencies::create_feature_install_plan( + spec_map.map, + FullPackageSpec::to_feature_specs({install_specs.value_or_exit(VCPKG_LINE_INFO)}), + StatusParagraphs(std::move(status_paragraphs))); + + Assert::IsTrue(install_plan.size() == 1); + features_check(&install_plan[0], "a", {"0", "1", "core"}, Triplet::X64_WINDOWS); + } + }; + + static PackageSpec unsafe_pspec(std::string name, Triplet t = Triplet::X86_WINDOWS) + { + auto m_ret = PackageSpec::from_name_and_triplet(name, t); + Assert::IsTrue(m_ret.has_value()); + return m_ret.value_or_exit(VCPKG_LINE_INFO); + } + + class RemovePlanTests : public TestClass + { + TEST_METHOD(basic_remove_scheme) + { + std::vector> pghs; + pghs.push_back(make_status_pgh("a")); + StatusParagraphs status_db(std::move(pghs)); + + auto remove_plan = Dependencies::create_remove_plan({ unsafe_pspec("a") }, status_db); + + Assert::AreEqual(size_t(1), remove_plan.size()); + Assert::AreEqual("a", remove_plan[0].spec.name().c_str()); + } + + TEST_METHOD(recurse_remove_scheme) + { + std::vector> pghs; + pghs.push_back(make_status_pgh("a")); + pghs.push_back(make_status_pgh("b", "a")); + StatusParagraphs status_db(std::move(pghs)); + + auto remove_plan = Dependencies::create_remove_plan({ unsafe_pspec("a") }, status_db); + + Assert::AreEqual(size_t(2), remove_plan.size()); + Assert::AreEqual("b", remove_plan[0].spec.name().c_str()); + Assert::AreEqual("a", remove_plan[1].spec.name().c_str()); + } + + TEST_METHOD(features_depend_remove_scheme) + { + std::vector> pghs; + pghs.push_back(make_status_pgh("a")); + pghs.push_back(make_status_pgh("b")); + pghs.push_back(make_status_feature_pgh("b", "0", "a")); + StatusParagraphs status_db(std::move(pghs)); + + auto remove_plan = Dependencies::create_remove_plan({ unsafe_pspec("a") }, status_db); + + Assert::AreEqual(size_t(2), remove_plan.size()); + Assert::AreEqual("b", remove_plan[0].spec.name().c_str()); + Assert::AreEqual("a", remove_plan[1].spec.name().c_str()); + } + + TEST_METHOD(features_depend_remove_scheme_once_removed) + { + std::vector> pghs; + pghs.push_back(make_status_pgh("expat")); + pghs.push_back(make_status_pgh("vtk", "expat")); + pghs.push_back(make_status_pgh("opencv")); + pghs.push_back(make_status_feature_pgh("opencv", "vtk", "vtk")); + StatusParagraphs status_db(std::move(pghs)); + + auto remove_plan = Dependencies::create_remove_plan({ unsafe_pspec("expat") }, status_db); + + Assert::AreEqual(size_t(3), remove_plan.size()); + Assert::AreEqual("opencv", remove_plan[0].spec.name().c_str()); + Assert::AreEqual("vtk", remove_plan[1].spec.name().c_str()); + Assert::AreEqual("expat", remove_plan[2].spec.name().c_str()); + } + }; +} diff --git a/toolsrc/vcpkgtest/vcpkgtest.vcxproj b/toolsrc/vcpkgtest/vcpkgtest.vcxproj index 766b4bf67..88dc14a75 100644 --- a/toolsrc/vcpkgtest/vcpkgtest.vcxproj +++ b/toolsrc/vcpkgtest/vcpkgtest.vcxproj @@ -23,7 +23,7 @@ - + diff --git a/toolsrc/vcpkgtest/vcpkgtest.vcxproj.filters b/toolsrc/vcpkgtest/vcpkgtest.vcxproj.filters index b6f1ced06..217c5b608 100644 --- a/toolsrc/vcpkgtest/vcpkgtest.vcxproj.filters +++ b/toolsrc/vcpkgtest/vcpkgtest.vcxproj.filters @@ -15,9 +15,6 @@ - - Source Files - Source Files @@ -33,5 +30,8 @@ Source Files + + Source Files + \ No newline at end of file -- cgit v1.2.3 From e2575e8c961e90b5dd35ef37c0b241b6cdb2914a Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Mon, 6 Nov 2017 14:29:57 -0800 Subject: [vcpkg] Reformat tests.plan.cpp and add :x64 version of test --- toolsrc/src/tests.plan.cpp | 97 +++++++++++++++++++++++++++------------------- 1 file changed, 58 insertions(+), 39 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/tests.plan.cpp b/toolsrc/src/tests.plan.cpp index d62178bdf..9cf3cfd8e 100644 --- a/toolsrc/src/tests.plan.cpp +++ b/toolsrc/src/tests.plan.cpp @@ -39,23 +39,21 @@ namespace Microsoft::VisualStudio::CppUnitTestFramework namespace UnitTest1 { static std::unique_ptr make_control_file( - const char* name, - const char* depends, - const std::vector>& features = {}) + const char* name, const char* depends, const std::vector>& features = {}) { using Pgh = std::unordered_map; std::vector scf_pghs; scf_pghs.push_back(Pgh{ - { "Source", name }, - { "Version", "0" }, - { "Build-Depends", depends }, + {"Source", name}, + {"Version", "0"}, + {"Build-Depends", depends}, }); for (auto&& feature : features) { scf_pghs.push_back(Pgh{ - { "Feature", feature.first }, - { "Description", "feature" }, - { "Build-Depends", feature.second }, + {"Feature", feature.first}, + {"Description", "feature"}, + {"Build-Depends", feature.second}, }); } auto m_pgh = vcpkg::SourceControlFile::parse_control_file(std::move(scf_pghs)); @@ -64,9 +62,9 @@ namespace UnitTest1 } static void features_check(Dependencies::AnyAction* install_action, - std::string pkg_name, - std::vector vec, - const Triplet& triplet = Triplet::X86_WINDOWS) + std::string pkg_name, + std::vector vec, + const Triplet& triplet = Triplet::X86_WINDOWS) { const auto& plan = install_action->install_plan.value_or_exit(VCPKG_LINE_INFO); const auto& feature_list = plan.feature_list; @@ -74,7 +72,7 @@ namespace UnitTest1 Assert::AreEqual(plan.spec.triplet().to_string().c_str(), triplet.to_string().c_str()); Assert::AreEqual(pkg_name.c_str(), - (*plan.any_paragraph.source_control_file.get())->core_paragraph->name.c_str()); + (*plan.any_paragraph.source_control_file.get())->core_paragraph->name.c_str()); Assert::AreEqual(size_t(vec.size()), feature_list.size()); for (auto&& feature_name : vec) @@ -82,7 +80,7 @@ namespace UnitTest1 if (feature_name == "core" || feature_name == "") { Assert::IsTrue(Util::find(feature_list, "core") != feature_list.end() || - Util::find(feature_list, "") != feature_list.end()); + Util::find(feature_list, "") != feature_list.end()); continue; } Assert::IsTrue(Util::find(feature_list, feature_name) != feature_list.end()); @@ -90,36 +88,39 @@ namespace UnitTest1 } static void remove_plan_check(Dependencies::AnyAction* remove_action, - std::string pkg_name, - const Triplet& triplet = Triplet::X86_WINDOWS) + std::string pkg_name, + const Triplet& triplet = Triplet::X86_WINDOWS) { const auto& plan = remove_action->remove_plan.value_or_exit(VCPKG_LINE_INFO); Assert::AreEqual(plan.spec.triplet().to_string().c_str(), triplet.to_string().c_str()); Assert::AreEqual(pkg_name.c_str(), plan.spec.name().c_str()); } - static std::unique_ptr make_status_pgh(const char* name, const char* depends = "") + static std::unique_ptr make_status_pgh(const char* name, + const char* depends = "", + const char* triplet = "x86-windows") { using Pgh = std::unordered_map; - return std::make_unique(Pgh{ { "Package", name }, - { "Version", "1" }, - { "Architecture", "x86-windows" }, - { "Multi-Arch", "same" }, - { "Depends", depends }, - { "Status", "install ok installed" } }); + return std::make_unique(Pgh{{"Package", name}, + {"Version", "1"}, + {"Architecture", triplet}, + {"Multi-Arch", "same"}, + {"Depends", depends}, + {"Status", "install ok installed"}}); } static std::unique_ptr make_status_feature_pgh(const char* name, - const char* feature, - const char* depends = "") + const char* feature, + const char* depends = "", + const char* triplet = "x86-windows") { using Pgh = std::unordered_map; - return std::make_unique(Pgh{ { "Package", name }, - { "Version", "1" }, - { "Feature", feature }, - { "Architecture", "x86-windows" }, - { "Multi-Arch", "same" }, - { "Depends", depends }, - { "Status", "install ok installed" } }); + return std::make_unique(Pgh{{"Package", name}, + {"Version", "1"}, + {"Feature", feature}, + {"Architecture", triplet}, + {"Multi-Arch", "same"}, + {"Depends", depends}, + {"Status", "install ok installed"}}); } struct PackageSpecMap { @@ -128,8 +129,8 @@ namespace UnitTest1 PackageSpecMap(const Triplet& t) { triplet = t; } PackageSpec emplace(const char* name, - const char* depends = "", - const std::vector>& features = {}) + const char* depends = "", + const std::vector>& features = {}) { return emplace(std::move(*make_control_file(name, depends, features))); } @@ -138,7 +139,7 @@ namespace UnitTest1 auto spec = PackageSpec::from_name_and_triplet(scf.core_paragraph->name, triplet); Assert::IsTrue(spec.has_value()); map.emplace(scf.core_paragraph->name, std::move(scf)); - return PackageSpec{ *spec.get() }; + return PackageSpec{*spec.get()}; } }; @@ -506,7 +507,7 @@ namespace UnitTest1 pghs.push_back(make_status_pgh("a")); StatusParagraphs status_db(std::move(pghs)); - auto remove_plan = Dependencies::create_remove_plan({ unsafe_pspec("a") }, status_db); + auto remove_plan = Dependencies::create_remove_plan({unsafe_pspec("a")}, status_db); Assert::AreEqual(size_t(1), remove_plan.size()); Assert::AreEqual("a", remove_plan[0].spec.name().c_str()); @@ -519,7 +520,7 @@ namespace UnitTest1 pghs.push_back(make_status_pgh("b", "a")); StatusParagraphs status_db(std::move(pghs)); - auto remove_plan = Dependencies::create_remove_plan({ unsafe_pspec("a") }, status_db); + auto remove_plan = Dependencies::create_remove_plan({unsafe_pspec("a")}, status_db); Assert::AreEqual(size_t(2), remove_plan.size()); Assert::AreEqual("b", remove_plan[0].spec.name().c_str()); @@ -534,7 +535,7 @@ namespace UnitTest1 pghs.push_back(make_status_feature_pgh("b", "0", "a")); StatusParagraphs status_db(std::move(pghs)); - auto remove_plan = Dependencies::create_remove_plan({ unsafe_pspec("a") }, status_db); + auto remove_plan = Dependencies::create_remove_plan({unsafe_pspec("a")}, status_db); Assert::AreEqual(size_t(2), remove_plan.size()); Assert::AreEqual("b", remove_plan[0].spec.name().c_str()); @@ -550,7 +551,25 @@ namespace UnitTest1 pghs.push_back(make_status_feature_pgh("opencv", "vtk", "vtk")); StatusParagraphs status_db(std::move(pghs)); - auto remove_plan = Dependencies::create_remove_plan({ unsafe_pspec("expat") }, status_db); + auto remove_plan = Dependencies::create_remove_plan({unsafe_pspec("expat")}, status_db); + + Assert::AreEqual(size_t(3), remove_plan.size()); + Assert::AreEqual("opencv", remove_plan[0].spec.name().c_str()); + Assert::AreEqual("vtk", remove_plan[1].spec.name().c_str()); + Assert::AreEqual("expat", remove_plan[2].spec.name().c_str()); + } + + TEST_METHOD(features_depend_remove_scheme_once_removed_x64) + { + std::vector> pghs; + pghs.push_back(make_status_pgh("expat", "", "x64")); + pghs.push_back(make_status_pgh("vtk", "expat", "x64")); + pghs.push_back(make_status_pgh("opencv", "", "x64")); + pghs.push_back(make_status_feature_pgh("opencv", "vtk", "vtk", "x64")); + StatusParagraphs status_db(std::move(pghs)); + + auto remove_plan = Dependencies::create_remove_plan( + {unsafe_pspec("expat", Triplet::from_canonical_name("x64"))}, status_db); Assert::AreEqual(size_t(3), remove_plan.size()); Assert::AreEqual("opencv", remove_plan[0].spec.name().c_str()); -- cgit v1.2.3 From 192087563d08d659c219700358803c748a71f72e Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 9 Nov 2017 21:42:03 -0800 Subject: Join declaration and assignment. Add const --- toolsrc/src/vcpkg/build.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index ca0712a06..b0ca3501b 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -317,9 +317,8 @@ namespace vcpkg::Build {"FEATURES", features}, }); - std::string command; const auto cmd_set_environment = make_build_env_cmd(pre_build_info, toolset); - command = Strings::format(R"(%s && %s)", cmd_set_environment, cmd_launch_cmake); + const std::string command = Strings::format(R"(%s && %s)", cmd_set_environment, cmd_launch_cmake); const auto timer = Chrono::ElapsedTime::create_started(); -- cgit v1.2.3 From ecd21d6cb429a91076c0fc1bb3c6d4af447343e8 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Sat, 11 Nov 2017 19:47:56 -0800 Subject: [vcpkg-tests] Use PCH. [vcpkg-update] Fix feature packages with update command. Fixes #2003. --- toolsrc/include/tests.pch.h | 18 ++++++ toolsrc/include/tests.utils.h | 26 ++++++++ toolsrc/include/vcpkg/base/sortedvector.h | 2 + toolsrc/include/vcpkg/update.h | 3 +- toolsrc/include/vcpkg/versiont.h | 3 +- toolsrc/src/tests.arguments.cpp | 3 +- toolsrc/src/tests.dependencies.cpp | 4 +- toolsrc/src/tests.packagespec.cpp | 24 +------- toolsrc/src/tests.paragraph.cpp | 6 +- toolsrc/src/tests.pch.cpp | 1 + toolsrc/src/tests.plan.cpp | 60 +----------------- toolsrc/src/tests.statusparagraphs.cpp | 7 +-- toolsrc/src/tests.update.cpp | 96 +++++++++++++++++++++++++++++ toolsrc/src/tests.utils.cpp | 62 +++++++++++++++++++ toolsrc/src/vcpkg/remove.cpp | 7 ++- toolsrc/src/vcpkg/update.cpp | 17 +++-- toolsrc/src/vcpkg/versiont.cpp | 13 ++-- toolsrc/vcpkgtest/vcpkgtest.vcxproj | 28 ++++++--- toolsrc/vcpkgtest/vcpkgtest.vcxproj.filters | 17 +++++ 19 files changed, 279 insertions(+), 118 deletions(-) create mode 100644 toolsrc/include/tests.pch.h create mode 100644 toolsrc/include/tests.utils.h create mode 100644 toolsrc/src/tests.pch.cpp create mode 100644 toolsrc/src/tests.update.cpp create mode 100644 toolsrc/src/tests.utils.cpp (limited to 'toolsrc') diff --git a/toolsrc/include/tests.pch.h b/toolsrc/include/tests.pch.h new file mode 100644 index 000000000..0037af585 --- /dev/null +++ b/toolsrc/include/tests.pch.h @@ -0,0 +1,18 @@ +#pragma once + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include diff --git a/toolsrc/include/tests.utils.h b/toolsrc/include/tests.utils.h new file mode 100644 index 000000000..485b8c294 --- /dev/null +++ b/toolsrc/include/tests.utils.h @@ -0,0 +1,26 @@ +#pragma once + +#include + +#include +#include +#include +#include + +#include + +namespace Microsoft::VisualStudio::CppUnitTestFramework +{ + std::wstring ToString(const vcpkg::Dependencies::InstallPlanType& t); + std::wstring ToString(const vcpkg::Dependencies::RequestType& t); + std::wstring ToString(const vcpkg::PackageSpecParseResult& t); + std::wstring ToString(const vcpkg::PackageSpec& t); +} + +std::unique_ptr make_status_pgh(const char* name, + const char* depends = "", + const char* triplet = "x86-windows"); +std::unique_ptr make_status_feature_pgh(const char* name, + const char* feature, + const char* depends = "", + const char* triplet = "x86-windows"); \ No newline at end of file diff --git a/toolsrc/include/vcpkg/base/sortedvector.h b/toolsrc/include/vcpkg/base/sortedvector.h index 62808cc2f..fbb7e5a5a 100644 --- a/toolsrc/include/vcpkg/base/sortedvector.h +++ b/toolsrc/include/vcpkg/base/sortedvector.h @@ -44,6 +44,8 @@ namespace vcpkg size_type size() const { return this->m_data.size(); } + const T& operator[](int i) const { return this->m_data[i]; } + private: std::vector m_data; }; diff --git a/toolsrc/include/vcpkg/update.h b/toolsrc/include/vcpkg/update.h index e7303d1b0..7587b9eb2 100644 --- a/toolsrc/include/vcpkg/update.h +++ b/toolsrc/include/vcpkg/update.h @@ -16,6 +16,7 @@ namespace vcpkg::Update VersionDiff version_diff; }; - std::vector find_outdated_packages(const VcpkgPaths& paths, const StatusParagraphs& status_db); + std::vector find_outdated_packages(const std::map& src_names_to_versions, + const StatusParagraphs& status_db); void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); } \ No newline at end of file diff --git a/toolsrc/include/vcpkg/versiont.h b/toolsrc/include/vcpkg/versiont.h index 67efd8da3..6d8332521 100644 --- a/toolsrc/include/vcpkg/versiont.h +++ b/toolsrc/include/vcpkg/versiont.h @@ -8,8 +8,9 @@ namespace vcpkg VersionT(); VersionT(const std::string& value); - std::string to_string() const; + const std::string& to_string() const; + private: std::string value; }; diff --git a/toolsrc/src/tests.arguments.cpp b/toolsrc/src/tests.arguments.cpp index 0f082222d..c87281fa8 100644 --- a/toolsrc/src/tests.arguments.cpp +++ b/toolsrc/src/tests.arguments.cpp @@ -1,5 +1,4 @@ -#include -#include +#include "tests.pch.h" #pragma comment(lib, "version") #pragma comment(lib, "winhttp") diff --git a/toolsrc/src/tests.dependencies.cpp b/toolsrc/src/tests.dependencies.cpp index 3f6e0dd10..f82fad4e4 100644 --- a/toolsrc/src/tests.dependencies.cpp +++ b/toolsrc/src/tests.dependencies.cpp @@ -1,6 +1,4 @@ -#include -#include -#include +#include "tests.pch.h" #pragma comment(lib, "version") #pragma comment(lib, "winhttp") diff --git a/toolsrc/src/tests.packagespec.cpp b/toolsrc/src/tests.packagespec.cpp index 25498a799..32ad81227 100644 --- a/toolsrc/src/tests.packagespec.cpp +++ b/toolsrc/src/tests.packagespec.cpp @@ -1,32 +1,12 @@ -#include -#include -#include +#include "tests.pch.h" -#include -#include +#include #pragma comment(lib, "version") #pragma comment(lib, "winhttp") using namespace Microsoft::VisualStudio::CppUnitTestFramework; -namespace Microsoft::VisualStudio::CppUnitTestFramework -{ - template<> - inline std::wstring ToString(const vcpkg::PackageSpecParseResult& t) - { - return ToString(static_cast(t)); - } - - template<> - inline std::wstring ToString(const vcpkg::PackageSpec& t) - { - return ToString(t.to_string()); - } -} - -namespace Strings = vcpkg::Strings; - namespace UnitTest1 { using namespace vcpkg; diff --git a/toolsrc/src/tests.paragraph.cpp b/toolsrc/src/tests.paragraph.cpp index 13052610f..9cddd7bdb 100644 --- a/toolsrc/src/tests.paragraph.cpp +++ b/toolsrc/src/tests.paragraph.cpp @@ -1,8 +1,4 @@ -#include -#include -#include - -#include +#include "tests.pch.h" #pragma comment(lib, "version") #pragma comment(lib, "winhttp") diff --git a/toolsrc/src/tests.pch.cpp b/toolsrc/src/tests.pch.cpp new file mode 100644 index 000000000..bdddab76a --- /dev/null +++ b/toolsrc/src/tests.pch.cpp @@ -0,0 +1 @@ +#include "tests.pch.h" diff --git a/toolsrc/src/tests.plan.cpp b/toolsrc/src/tests.plan.cpp index 9cf3cfd8e..122a4ffef 100644 --- a/toolsrc/src/tests.plan.cpp +++ b/toolsrc/src/tests.plan.cpp @@ -1,41 +1,11 @@ -#include -#include +#include "tests.pch.h" -#include +#include using namespace Microsoft::VisualStudio::CppUnitTestFramework; using namespace vcpkg; -namespace Microsoft::VisualStudio::CppUnitTestFramework -{ - template<> - inline std::wstring ToString(const vcpkg::Dependencies::InstallPlanType& t) - { - switch (t) - { - case Dependencies::InstallPlanType::ALREADY_INSTALLED: return L"ALREADY_INSTALLED"; - case Dependencies::InstallPlanType::BUILD_AND_INSTALL: return L"BUILD_AND_INSTALL"; - case Dependencies::InstallPlanType::INSTALL: return L"INSTALL"; - case Dependencies::InstallPlanType::EXCLUDED: return L"EXCLUDED"; - case Dependencies::InstallPlanType::UNKNOWN: return L"UNKNOWN"; - default: return ToString(static_cast(t)); - } - } - - template<> - inline std::wstring ToString(const vcpkg::Dependencies::RequestType& t) - { - switch (t) - { - case Dependencies::RequestType::AUTO_SELECTED: return L"AUTO_SELECTED"; - case Dependencies::RequestType::USER_REQUESTED: return L"USER_REQUESTED"; - case Dependencies::RequestType::UNKNOWN: return L"UNKNOWN"; - default: return ToString(static_cast(t)); - } - } -} - namespace UnitTest1 { static std::unique_ptr make_control_file( @@ -96,32 +66,6 @@ namespace UnitTest1 Assert::AreEqual(pkg_name.c_str(), plan.spec.name().c_str()); } - static std::unique_ptr make_status_pgh(const char* name, - const char* depends = "", - const char* triplet = "x86-windows") - { - using Pgh = std::unordered_map; - return std::make_unique(Pgh{{"Package", name}, - {"Version", "1"}, - {"Architecture", triplet}, - {"Multi-Arch", "same"}, - {"Depends", depends}, - {"Status", "install ok installed"}}); - } - static std::unique_ptr make_status_feature_pgh(const char* name, - const char* feature, - const char* depends = "", - const char* triplet = "x86-windows") - { - using Pgh = std::unordered_map; - return std::make_unique(Pgh{{"Package", name}, - {"Version", "1"}, - {"Feature", feature}, - {"Architecture", triplet}, - {"Multi-Arch", "same"}, - {"Depends", depends}, - {"Status", "install ok installed"}}); - } struct PackageSpecMap { std::unordered_map map; diff --git a/toolsrc/src/tests.statusparagraphs.cpp b/toolsrc/src/tests.statusparagraphs.cpp index 4cc1130b1..ed6eaa764 100644 --- a/toolsrc/src/tests.statusparagraphs.cpp +++ b/toolsrc/src/tests.statusparagraphs.cpp @@ -1,9 +1,4 @@ -#include - -#include -#include -#include -#include +#include "tests.pch.h" using namespace Microsoft::VisualStudio::CppUnitTestFramework; diff --git a/toolsrc/src/tests.update.cpp b/toolsrc/src/tests.update.cpp new file mode 100644 index 000000000..06ae797f4 --- /dev/null +++ b/toolsrc/src/tests.update.cpp @@ -0,0 +1,96 @@ +#include "tests.pch.h" + +#include + +using namespace Microsoft::VisualStudio::CppUnitTestFramework; + +using namespace vcpkg; +using namespace vcpkg::Update; + +namespace UnitTest1 +{ + class UpdateTests : public TestClass + { + TEST_METHOD(find_outdated_packages_basic) + { + std::vector> status_paragraphs; + status_paragraphs.push_back(make_status_pgh("a")); + status_paragraphs.back()->package.version = "2"; + + StatusParagraphs status_db(std::move(status_paragraphs)); + + std::map port_versions; + port_versions["a"] = VersionT("0"); + + auto pkgs = SortedVector(Update::find_outdated_packages(port_versions, status_db), + &OutdatedPackage::compare_by_name); + + Assert::AreEqual(size_t(1), pkgs.size()); + Assert::AreEqual("2", pkgs[0].version_diff.left.to_string().c_str()); + Assert::AreEqual("0", pkgs[0].version_diff.right.to_string().c_str()); + } + + TEST_METHOD(find_outdated_packages_features) + { + std::vector> status_paragraphs; + status_paragraphs.push_back(make_status_pgh("a")); + status_paragraphs.back()->package.version = "2"; + + status_paragraphs.push_back(make_status_feature_pgh("a", "b")); + status_paragraphs.back()->package.version = "2"; + + StatusParagraphs status_db(std::move(status_paragraphs)); + + std::map port_versions; + port_versions["a"] = VersionT("0"); + + auto pkgs = SortedVector(Update::find_outdated_packages(port_versions, status_db), + &OutdatedPackage::compare_by_name); + + Assert::AreEqual(size_t(1), pkgs.size()); + Assert::AreEqual("2", pkgs[0].version_diff.left.to_string().c_str()); + Assert::AreEqual("0", pkgs[0].version_diff.right.to_string().c_str()); + } + + TEST_METHOD(find_outdated_packages_features_2) + { + std::vector> status_paragraphs; + status_paragraphs.push_back(make_status_pgh("a")); + status_paragraphs.back()->package.version = "2"; + + status_paragraphs.push_back(make_status_feature_pgh("a", "b")); + status_paragraphs.back()->package.version = "0"; + status_paragraphs.back()->state = InstallState::NOT_INSTALLED; + status_paragraphs.back()->want = Want::PURGE; + + StatusParagraphs status_db(std::move(status_paragraphs)); + + std::map port_versions; + port_versions["a"] = VersionT("0"); + + auto pkgs = SortedVector(Update::find_outdated_packages(port_versions, status_db), + &OutdatedPackage::compare_by_name); + + Assert::AreEqual(size_t(1), pkgs.size()); + Assert::AreEqual("2", pkgs[0].version_diff.left.to_string().c_str()); + Assert::AreEqual("0", pkgs[0].version_diff.right.to_string().c_str()); + } + + TEST_METHOD(find_outdated_packages_none) + { + std::vector> status_paragraphs; + status_paragraphs.push_back(make_status_pgh("a")); + status_paragraphs.back()->package.version = "2"; + + StatusParagraphs status_db(std::move(status_paragraphs)); + + std::map port_versions; + port_versions["a"] = VersionT("2"); + + auto pkgs = SortedVector(Update::find_outdated_packages(port_versions, status_db), + &OutdatedPackage::compare_by_name); + + Assert::AreEqual(size_t(0), pkgs.size()); + } + }; +} diff --git a/toolsrc/src/tests.utils.cpp b/toolsrc/src/tests.utils.cpp new file mode 100644 index 000000000..b9fb51a59 --- /dev/null +++ b/toolsrc/src/tests.utils.cpp @@ -0,0 +1,62 @@ +#include "tests.pch.h" + +#include "tests.utils.h" + +using namespace Microsoft::VisualStudio::CppUnitTestFramework; +using namespace vcpkg; + +namespace Microsoft::VisualStudio::CppUnitTestFramework +{ + std::wstring ToString(const vcpkg::Dependencies::InstallPlanType& t) + { + switch (t) + { + case Dependencies::InstallPlanType::ALREADY_INSTALLED: return L"ALREADY_INSTALLED"; + case Dependencies::InstallPlanType::BUILD_AND_INSTALL: return L"BUILD_AND_INSTALL"; + case Dependencies::InstallPlanType::INSTALL: return L"INSTALL"; + case Dependencies::InstallPlanType::EXCLUDED: return L"EXCLUDED"; + case Dependencies::InstallPlanType::UNKNOWN: return L"UNKNOWN"; + default: return ToString(static_cast(t)); + } + } + + std::wstring ToString(const vcpkg::Dependencies::RequestType& t) + { + switch (t) + { + case Dependencies::RequestType::AUTO_SELECTED: return L"AUTO_SELECTED"; + case Dependencies::RequestType::USER_REQUESTED: return L"USER_REQUESTED"; + case Dependencies::RequestType::UNKNOWN: return L"UNKNOWN"; + default: return ToString(static_cast(t)); + } + } + + std::wstring ToString(const vcpkg::PackageSpecParseResult& t) { return ToString(static_cast(t)); } + + std::wstring ToString(const vcpkg::PackageSpec& t) { return ToString(t.to_string()); } +} + +std::unique_ptr make_status_pgh(const char* name, const char* depends, const char* triplet) +{ + using Pgh = std::unordered_map; + return std::make_unique(Pgh{{"Package", name}, + {"Version", "1"}, + {"Architecture", triplet}, + {"Multi-Arch", "same"}, + {"Depends", depends}, + {"Status", "install ok installed"}}); +} +std::unique_ptr make_status_feature_pgh(const char* name, + const char* feature, + const char* depends, + const char* triplet) +{ + using Pgh = std::unordered_map; + return std::make_unique(Pgh{{"Package", name}, + {"Version", "1"}, + {"Feature", feature}, + {"Architecture", triplet}, + {"Multi-Arch", "same"}, + {"Depends", depends}, + {"Status", "install ok installed"}}); +} diff --git a/toolsrc/src/vcpkg/remove.cpp b/toolsrc/src/vcpkg/remove.cpp index 7f40fb16e..8ae0bc881 100644 --- a/toolsrc/src/vcpkg/remove.cpp +++ b/toolsrc/src/vcpkg/remove.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -206,8 +207,10 @@ namespace vcpkg::Remove System::println(System::Color::error, "Error: 'remove' accepts either libraries or '--outdated'"); Checks::exit_fail(VCPKG_LINE_INFO); } - specs = Util::fmap(Update::find_outdated_packages(paths, status_db), - [](auto&& outdated) { return outdated.spec; }); + specs = Util::fmap( + Update::find_outdated_packages( + Paragraphs::load_all_port_names_and_versions(paths.get_filesystem(), paths.ports), status_db), + [](auto&& outdated) { return outdated.spec; }); if (specs.empty()) { diff --git a/toolsrc/src/vcpkg/update.cpp b/toolsrc/src/vcpkg/update.cpp index 61a3f89c5..29baef91e 100644 --- a/toolsrc/src/vcpkg/update.cpp +++ b/toolsrc/src/vcpkg/update.cpp @@ -14,15 +14,20 @@ namespace vcpkg::Update return left.spec.name() < right.spec.name(); } - std::vector find_outdated_packages(const VcpkgPaths& paths, const StatusParagraphs& status_db) + std::vector find_outdated_packages(const std::map& src_names_to_versions, + const StatusParagraphs& status_db) { - const std::map src_names_to_versions = - Paragraphs::load_all_port_names_and_versions(paths.get_filesystem(), paths.ports); const std::vector installed_packages = get_installed_ports(status_db); std::vector output; for (const StatusParagraph* pgh : installed_packages) { + if (!pgh->package.feature.empty()) + { + // Skip feature packages; only consider master packages for needing updates. + continue; + } + const auto it = src_names_to_versions.find(pgh->package.spec.name()); if (it == src_names_to_versions.end()) { @@ -53,8 +58,10 @@ namespace vcpkg::Update const StatusParagraphs status_db = database_load_check(paths); - const auto outdated_packages = - SortedVector(find_outdated_packages(paths, status_db), &OutdatedPackage::compare_by_name); + const auto outdated_packages = SortedVector( + find_outdated_packages(Paragraphs::load_all_port_names_and_versions(paths.get_filesystem(), paths.ports), + status_db), + &OutdatedPackage::compare_by_name); if (outdated_packages.empty()) { diff --git a/toolsrc/src/vcpkg/versiont.cpp b/toolsrc/src/vcpkg/versiont.cpp index 1c52d674a..91f7e23ef 100644 --- a/toolsrc/src/vcpkg/versiont.cpp +++ b/toolsrc/src/vcpkg/versiont.cpp @@ -7,13 +7,16 @@ namespace vcpkg { VersionT::VersionT() : value("0.0.0") {} VersionT::VersionT(const std::string& value) : value(value) {} - std::string VersionT::to_string() const { return value; } - bool operator==(const VersionT& left, const VersionT& right) { return left.value == right.value; } - bool operator!=(const VersionT& left, const VersionT& right) { return left.value != right.value; } - std::string to_printf_arg(const VersionT& version) { return version.value; } + const std::string& VersionT::to_string() const { return value; } + bool operator==(const VersionT& left, const VersionT& right) { return left.to_string() == right.to_string(); } + bool operator!=(const VersionT& left, const VersionT& right) { return left.to_string() != right.to_string(); } + std::string to_printf_arg(const VersionT& version) { return version.to_string(); } VersionDiff::VersionDiff() : left(), right() {} VersionDiff::VersionDiff(const VersionT& left, const VersionT& right) : left(left), right(right) {} - std::string VersionDiff::to_string() const { return Strings::format("%s -> %s", left.value, right.value); } + std::string VersionDiff::to_string() const + { + return Strings::format("%s -> %s", left.to_string(), right.to_string()); + } } diff --git a/toolsrc/vcpkgtest/vcpkgtest.vcxproj b/toolsrc/vcpkgtest/vcpkgtest.vcxproj index 88dc14a75..9eafc1ada 100644 --- a/toolsrc/vcpkgtest/vcpkgtest.vcxproj +++ b/toolsrc/vcpkgtest/vcpkgtest.vcxproj @@ -23,14 +23,26 @@ + + Create + Create + Create + Create + + + {b98c92b7-2874-4537-9d46-d14e5c237f04} + + + + {F27B8DB0-1279-4AF8-A2E3-1D49C4F0220D} Win32Proj @@ -93,13 +105,13 @@ - NotUsing + Use Level3 Disabled ..\include;$(VCInstallDir)UnitTest\include;$(VsInstallRoot)\VC\Auxiliary\VS\UnitTest\include;%(AdditionalIncludeDirectories) WIN32;_DEBUG;%(PreprocessorDefinitions) true - + tests.pch.h /std:c++latest %(AdditionalOptions) true false @@ -111,13 +123,13 @@ - NotUsing + Use Level4 Disabled ..\include;$(VCInstallDir)UnitTest\include;$(VsInstallRoot)\VC\Auxiliary\VS\UnitTest\include;%(AdditionalIncludeDirectories) _DEBUG;%(PreprocessorDefinitions) true - + tests.pch.h /std:c++latest %(AdditionalOptions) true false @@ -130,14 +142,14 @@ Level3 - NotUsing + Use MaxSpeed true true ..\include;$(VCInstallDir)UnitTest\include;$(VsInstallRoot)\VC\Auxiliary\VS\UnitTest\include;%(AdditionalIncludeDirectories) WIN32;NDEBUG;%(PreprocessorDefinitions) true - + tests.pch.h /std:c++latest %(AdditionalOptions) true @@ -151,14 +163,14 @@ Level3 - NotUsing + Use MaxSpeed true true ..\include;$(VCInstallDir)UnitTest\include;$(VsInstallRoot)\VC\Auxiliary\VS\UnitTest\include;%(AdditionalIncludeDirectories) NDEBUG;%(PreprocessorDefinitions) true - + tests.pch.h /std:c++latest %(AdditionalOptions) true diff --git a/toolsrc/vcpkgtest/vcpkgtest.vcxproj.filters b/toolsrc/vcpkgtest/vcpkgtest.vcxproj.filters index 217c5b608..2121f9782 100644 --- a/toolsrc/vcpkgtest/vcpkgtest.vcxproj.filters +++ b/toolsrc/vcpkgtest/vcpkgtest.vcxproj.filters @@ -33,5 +33,22 @@ Source Files + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + \ No newline at end of file -- cgit v1.2.3 From e4d38bb874fe47317e1dd4128c013af882408bbf Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Sat, 11 Nov 2017 21:45:37 -0800 Subject: [vcpkg-ci] Fix crash when not passed --exclude. Added Util::Maps::maybe_find. Added Optional. --- toolsrc/include/vcpkg/base/optional.h | 73 +++++++++++++++++++++++++++-------- toolsrc/include/vcpkg/base/util.h | 18 +++++++++ toolsrc/src/vcpkg/commands.ci.cpp | 10 ++++- 3 files changed, 82 insertions(+), 19 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/base/optional.h b/toolsrc/include/vcpkg/base/optional.h index ff7a210c7..aa9e480fd 100644 --- a/toolsrc/include/vcpkg/base/optional.h +++ b/toolsrc/include/vcpkg/base/optional.h @@ -11,59 +11,98 @@ namespace vcpkg const static constexpr NullOpt nullopt{0}; + namespace details + { + template + struct OptionalStorage + { + constexpr OptionalStorage() : m_is_present(false), m_t() {} + constexpr OptionalStorage(const T& t) : m_is_present(true), m_t(t) {} + constexpr OptionalStorage(T&& t) : m_is_present(true), m_t(std::move(t)) {} + + constexpr bool has_value() const { return m_is_present; } + + const T& value() const { return this->m_t; } + T& value() { return this->m_t; } + + private: + bool m_is_present; + T m_t; + }; + + template + struct OptionalStorage + { + constexpr OptionalStorage() : m_t(nullptr) {} + constexpr OptionalStorage(T& t) : m_t(&t) {} + + constexpr bool has_value() const { return m_t != nullptr; } + + T& value() const { return *this->m_t; } + + private: + T* m_t; + }; + } + template - class Optional + struct Optional { - public: - constexpr Optional() : m_is_present(false), m_t() {} + constexpr Optional() {} // Constructors are intentionally implicit - constexpr Optional(NullOpt) : m_is_present(false), m_t() {} + constexpr Optional(NullOpt) {} - Optional(const T& t) : m_is_present(true), m_t(t) {} + Optional(const T& t) : m_base(t) {} - Optional(T&& t) : m_is_present(true), m_t(std::move(t)) {} + template::value>> + Optional(T&& t) : m_base(std::move(t)) + { + } T&& value_or_exit(const LineInfo& line_info) && { this->exit_if_null(line_info); - return std::move(this->m_t); + return std::move(this->m_base.value()); } const T& value_or_exit(const LineInfo& line_info) const& { this->exit_if_null(line_info); - return this->m_t; + return this->m_base.value(); } - constexpr explicit operator bool() const { return this->m_is_present; } + constexpr explicit operator bool() const { return this->m_base.has_value(); } - constexpr bool has_value() const { return m_is_present; } + constexpr bool has_value() const { return this->m_base.has_value(); } template T value_or(U&& default_value) const& { - return bool(*this) ? this->m_t : static_cast(std::forward(default_value)); + return this->m_base.has_value() ? this->m_base.value() : static_cast(std::forward(default_value)); } template T value_or(U&& default_value) && { - return bool(*this) ? std::move(this->m_t) : static_cast(std::forward(default_value)); + return this->m_base.has_value() ? std::move(this->m_base.value()) + : static_cast(std::forward(default_value)); } - const T* get() const { return bool(*this) ? &this->m_t : nullptr; } + typename std::add_pointer::type get() const + { + return this->m_base.has_value() ? &this->m_base.value() : nullptr; + } - T* get() { return bool(*this) ? &this->m_t : nullptr; } + typename std::add_pointer::type get() { return this->m_base.has_value() ? &this->m_base.value() : nullptr; } private: void exit_if_null(const LineInfo& line_info) const { - Checks::check_exit(line_info, this->m_is_present, "Value was null"); + Checks::check_exit(line_info, this->m_base.has_value(), "Value was null"); } - bool m_is_present; - T m_t; + details::OptionalStorage m_base; }; template diff --git a/toolsrc/include/vcpkg/base/util.h b/toolsrc/include/vcpkg/base/util.h index 155b16cf7..44d09ae15 100644 --- a/toolsrc/include/vcpkg/base/util.h +++ b/toolsrc/include/vcpkg/base/util.h @@ -6,6 +6,8 @@ #include #include +#include + namespace vcpkg::Util { template @@ -29,6 +31,22 @@ namespace vcpkg::Util } } + namespace Maps + { + template + using FirstT = std::remove_reference_t().first)>; + + template>> + Optional maybe_find(Container&& assoc_container, const K& key) + { + auto it = assoc_container.find(key); + if (it == assoc_container.end()) + return nullopt; + else + return it->second; + } + } + template using FmapOut = decltype(std::declval()(*begin(std::declval()))); diff --git a/toolsrc/src/vcpkg/commands.ci.cpp b/toolsrc/src/vcpkg/commands.ci.cpp index dce294004..ee25f272a 100644 --- a/toolsrc/src/vcpkg/commands.ci.cpp +++ b/toolsrc/src/vcpkg/commands.ci.cpp @@ -75,8 +75,14 @@ namespace vcpkg::Commands::CI void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) { const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE); - const std::vector exclusions = Strings::split(options.settings.at(OPTION_EXCLUDE), ","); - const std::set exclusions_set(exclusions.cbegin(), exclusions.cend()); + + std::set exclusions_set; + auto maybe_exclusions = Util::Maps::maybe_find(options.settings, OPTION_EXCLUDE); + if (auto p_exclusions = maybe_exclusions.get()) + { + auto exclusions = Strings::split(*p_exclusions, ","); + exclusions_set.insert(exclusions.begin(), exclusions.end()); + } std::vector triplets; for (const std::string& triplet : args.command_arguments) -- cgit v1.2.3 From 6ece1871b1c4249c667d6f1ca096fcb12861303f Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Sat, 11 Nov 2017 22:10:38 -0800 Subject: [vcpkg] Simplify code -- Maps::maybe_find is not very useful compared to iterators. --- toolsrc/include/vcpkg/base/util.h | 16 ---------------- toolsrc/src/vcpkg/commands.ci.cpp | 6 +++--- 2 files changed, 3 insertions(+), 19 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/base/util.h b/toolsrc/include/vcpkg/base/util.h index 44d09ae15..3d56c1e10 100644 --- a/toolsrc/include/vcpkg/base/util.h +++ b/toolsrc/include/vcpkg/base/util.h @@ -31,22 +31,6 @@ namespace vcpkg::Util } } - namespace Maps - { - template - using FirstT = std::remove_reference_t().first)>; - - template>> - Optional maybe_find(Container&& assoc_container, const K& key) - { - auto it = assoc_container.find(key); - if (it == assoc_container.end()) - return nullopt; - else - return it->second; - } - } - template using FmapOut = decltype(std::declval()(*begin(std::declval()))); diff --git a/toolsrc/src/vcpkg/commands.ci.cpp b/toolsrc/src/vcpkg/commands.ci.cpp index ee25f272a..65adade1a 100644 --- a/toolsrc/src/vcpkg/commands.ci.cpp +++ b/toolsrc/src/vcpkg/commands.ci.cpp @@ -77,10 +77,10 @@ namespace vcpkg::Commands::CI const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE); std::set exclusions_set; - auto maybe_exclusions = Util::Maps::maybe_find(options.settings, OPTION_EXCLUDE); - if (auto p_exclusions = maybe_exclusions.get()) + auto it_exclusions = options.settings.find(OPTION_EXCLUDE); + if (it_exclusions != options.settings.end()) { - auto exclusions = Strings::split(*p_exclusions, ","); + auto exclusions = Strings::split(it_exclusions->second, ","); exclusions_set.insert(exclusions.begin(), exclusions.end()); } -- cgit v1.2.3 From e4786a054d53d1c7f3f1ae24ce6004733af61a43 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Sat, 11 Nov 2017 22:40:53 -0800 Subject: Improve error message --- toolsrc/src/vcpkg/postbuildlint.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/postbuildlint.cpp b/toolsrc/src/vcpkg/postbuildlint.cpp index 0063f8d98..d83d656cf 100644 --- a/toolsrc/src/vcpkg/postbuildlint.cpp +++ b/toolsrc/src/vcpkg/postbuildlint.cpp @@ -74,8 +74,9 @@ namespace vcpkg::PostBuildLint const fs::path include_dir = package_dir / "include"; 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."); + System::println( + System::Color::warning, + "The folder /include is empty or not present. This indicates the library was not correctly installed."); return LintStatus::ERROR_DETECTED; } -- cgit v1.2.3 From 415789b42e5fd43ac984902cd72848f6ef6b450a Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Mon, 13 Nov 2017 21:36:29 -0800 Subject: [vcpkg-metrics] Replace SQM with MAC hash. --- toolsrc/include/vcpkg/metrics.h | 4 +-- toolsrc/src/vcpkg.cpp | 59 ++++++++++++++++++++++++++--------------- toolsrc/src/vcpkg/metrics.cpp | 36 ++++++++++++++++++++++--- 3 files changed, 71 insertions(+), 28 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/metrics.h b/toolsrc/include/vcpkg/metrics.h index f73c636cf..ee6f8eb51 100644 --- a/toolsrc/include/vcpkg/metrics.h +++ b/toolsrc/include/vcpkg/metrics.h @@ -11,7 +11,7 @@ namespace vcpkg::Metrics void set_send_metrics(bool should_send_metrics); void set_print_metrics(bool should_print_metrics); void set_user_information(const std::string& user_id, const std::string& first_use_time); - void init_user_information(std::string& user_id, std::string& first_use_time); + static void init_user_information(std::string& user_id, std::string& first_use_time); void track_metric(const std::string& name, double value); void track_property(const std::string& name, const std::string& value); @@ -22,6 +22,6 @@ namespace vcpkg::Metrics extern Util::LockGuarded g_metrics; - std::string get_SQM_user(); + std::string get_MAC_user(); bool get_compiled_metrics_enabled(); } diff --git a/toolsrc/src/vcpkg.cpp b/toolsrc/src/vcpkg.cpp index 2a73c5b0f..5642f937c 100644 --- a/toolsrc/src/vcpkg.cpp +++ b/toolsrc/src/vcpkg.cpp @@ -157,6 +157,7 @@ static void load_config() CoTaskMemFree(localappdatapath); } + std::string user_id, user_time, user_mac; try { auto maybe_pghs = Paragraphs::get_paragraphs(Files::get_real_filesystem(), localappdata / "vcpkg" / "config"); @@ -173,39 +174,54 @@ static void load_config() keys.insert(p); } - auto user_id = keys["User-Id"]; - auto user_time = keys["User-Since"]; - if (!user_id.empty() && !user_time.empty()) - { - Metrics::g_metrics.lock()->set_user_information(user_id, user_time); - return; - } + user_id = keys["User-Id"]; + user_time = keys["User-Since"]; + user_mac = keys["Mac-Hash"]; } } catch (...) { } + bool write_config = false; + // config file not found, could not be read, or invalid - std::string user_id, user_time; + if (user_id.empty() || user_time.empty()) { - auto locked_metrics = Metrics::g_metrics.lock(); - locked_metrics->init_user_information(user_id, user_time); - locked_metrics->set_user_information(user_id, user_time); + ::vcpkg::Metrics::Metrics::init_user_information(user_id, user_time); + write_config = true; } - try + + if (user_mac.empty()) { - std::error_code ec; - 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)); + user_mac = Metrics::get_MAC_user(); + write_config = true; } - catch (...) + { + auto locked_metrics = Metrics::g_metrics.lock(); + locked_metrics->set_user_information(user_id, user_time); + locked_metrics->track_property("user_mac", user_mac); + } + + if (write_config) + { + try + { + std::error_code ec; + 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" + "Mac-Hash: %s\n", + user_id, + user_time, + user_mac)); + } + catch (...) + { + } } #endif } @@ -259,7 +275,6 @@ int main(const int argc, const char* const* const argv) #endif } load_config(); - Metrics::g_metrics.lock()->track_property("sqmuser", Metrics::get_SQM_user()); const VcpkgCmdArguments args = VcpkgCmdArguments::create_from_command_line(argc, argv); diff --git a/toolsrc/src/vcpkg/metrics.cpp b/toolsrc/src/vcpkg/metrics.cpp index 8f2575886..d7e18a176 100644 --- a/toolsrc/src/vcpkg/metrics.cpp +++ b/toolsrc/src/vcpkg/metrics.cpp @@ -233,12 +233,40 @@ namespace vcpkg::Metrics bool get_compiled_metrics_enabled() { return DISABLE_METRICS == 0; } - std::string get_SQM_user() + static fs::path get_vcpkg_root() + { + return Files::get_real_filesystem().find_file_recursively_up( + fs::stdfs::absolute(System::get_exe_path_of_current_process()), ".vcpkg-root"); + } + + std::string get_MAC_user() { #if defined(_WIN32) - auto hkcu_sqmclient = - System::get_registry_string(HKEY_CURRENT_USER, R"(Software\Microsoft\SQMClient)", "UserId"); - return hkcu_sqmclient.value_or("{}"); + auto getmac = System::cmd_execute_and_capture_output("getmac"); + + if (getmac.exit_code != 0) return "0"; + + std::regex mac_regex("([a-fA-F0-9]{2}(-[a-fA-F0-9]{2}){5})"); + std::sregex_iterator next(getmac.output.begin(), getmac.output.end(), mac_regex); + std::sregex_iterator last; + + while (next != last) + { + auto match = *next; + if (match[0] != "00-00-00-00-00-00") + { + std::string matchstr = match[0]; + auto hash_result = System::powershell_execute_and_capture_output( + "SHA256Hash", get_vcpkg_root() / "SHA256Hash.ps1", Strings::format("-Value \"%s\"", matchstr)); + Util::erase_remove_if(hash_result, + [](char ch) { return !(ch >= 'A' && ch <= 'F') && !(ch >= '0' && ch <= '9'); }); + hash_result = Strings::ascii_to_lowercase(hash_result); + return hash_result; + } + ++next; + } + + return "0"; #else return "{}"; #endif -- cgit v1.2.3 From 71289ee5e8e5286fde47ec563bfdcdb2cb9c369d Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Mon, 13 Nov 2017 23:06:04 -0800 Subject: [vcpkg-contact] Add --survey so users can easily provide feedback --- toolsrc/include/vcpkg/base/util.h | 4 ++-- toolsrc/src/vcpkg/commands.contact.cpp | 16 +++++++++++++--- 2 files changed, 15 insertions(+), 5 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/base/util.h b/toolsrc/include/vcpkg/base/util.h index 3d56c1e10..8d78fd6cc 100644 --- a/toolsrc/include/vcpkg/base/util.h +++ b/toolsrc/include/vcpkg/base/util.h @@ -24,8 +24,8 @@ namespace vcpkg::Util namespace Sets { - template> - bool contains(const Container& container, const T& item) + template + bool contains(const Container& container, const ElementT& item) { return container.find(item) != container.cend(); } diff --git a/toolsrc/src/vcpkg/commands.contact.cpp b/toolsrc/src/vcpkg/commands.contact.cpp index 5d62faeea..07dcea80e 100644 --- a/toolsrc/src/vcpkg/commands.contact.cpp +++ b/toolsrc/src/vcpkg/commands.contact.cpp @@ -12,19 +12,29 @@ namespace vcpkg::Commands::Contact return S_EMAIL; } + static const CommandSwitch switches[] = {{"--survey", "Launch default browser to the current vcpkg survey"}}; + const CommandStructure COMMAND_STRUCTURE = { Help::create_example_string("contact"), 0, 0, - {}, + {switches, {}}, nullptr, }; void perform_and_exit(const VcpkgCmdArguments& args) { - args.parse_arguments(COMMAND_STRUCTURE); + auto parsed_args = args.parse_arguments(COMMAND_STRUCTURE); - System::println("Send an email to %s with any feedback.", email()); + if (Util::Sets::contains(parsed_args.switches, switches[0].name)) + { + System::cmd_execute("start https://aka.ms/NPS_vcpkg"); + System::println("Default browser launched to https://aka.ms/NPS_vcpkg, thank you for your feedback!"); + } + else + { + System::println("Send an email to %s with any feedback.", email()); + } Checks::exit_success(VCPKG_LINE_INFO); } } -- cgit v1.2.3 From ca1aa816d2af1b600f68b1c965bed5bd180d829a Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Tue, 14 Nov 2017 15:27:12 -0800 Subject: [vcpkg-ci] Clean up buildtrees during build to avoid consuming 200+ Gb of SSD --- toolsrc/include/vcpkg/install.h | 12 ++++++++++++ toolsrc/src/vcpkg/commands.ci.cpp | 2 +- toolsrc/src/vcpkg/install.cpp | 18 +++++++++++++++++- 3 files changed, 30 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/install.h b/toolsrc/include/vcpkg/install.h index 7bf823e99..df7542318 100644 --- a/toolsrc/include/vcpkg/install.h +++ b/toolsrc/include/vcpkg/install.h @@ -17,6 +17,17 @@ namespace vcpkg::Install inline KeepGoing to_keep_going(const bool value) { return value ? KeepGoing::YES : KeepGoing::NO; } + enum class CleanBuildtrees + { + NO = 0, + YES + }; + + inline CleanBuildtrees to_clean_buildtrees(const bool value) + { + return value ? CleanBuildtrees::YES : CleanBuildtrees::NO; + } + struct SpecSummary { explicit SpecSummary(const PackageSpec& spec); @@ -70,6 +81,7 @@ namespace vcpkg::Install InstallSummary perform(const std::vector& action_plan, const KeepGoing keep_going, + const CleanBuildtrees clean_buildtrees, const VcpkgPaths& paths, StatusParagraphs& status_db); diff --git a/toolsrc/src/vcpkg/commands.ci.cpp b/toolsrc/src/vcpkg/commands.ci.cpp index 65adade1a..3c1c443f0 100644 --- a/toolsrc/src/vcpkg/commands.ci.cpp +++ b/toolsrc/src/vcpkg/commands.ci.cpp @@ -49,7 +49,7 @@ namespace vcpkg::Commands::CI return Dependencies::AnyAction(std::move(install_action)); }); - return Install::perform(action_plan, Install::KeepGoing::YES, paths, status_db); + return Install::perform(action_plan, Install::KeepGoing::YES, Install::CleanBuildtrees::YES, paths, status_db); } struct TripletAndSummary diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp index 20ffd3164..88ef5c73d 100644 --- a/toolsrc/src/vcpkg/install.cpp +++ b/toolsrc/src/vcpkg/install.cpp @@ -481,6 +481,7 @@ namespace vcpkg::Install InstallSummary perform(const std::vector& action_plan, const KeepGoing keep_going, + const CleanBuildtrees clean_buildtrees, const VcpkgPaths& paths, StatusParagraphs& status_db) { @@ -504,6 +505,21 @@ namespace vcpkg::Install if (const auto install_action = action.install_plan.get()) { const BuildResult result = perform_install_plan_action(paths, *install_action, status_db); + if (clean_buildtrees == CleanBuildtrees::YES) + { + auto& fs = paths.get_filesystem(); + auto buildtrees_dir = paths.buildtrees / install_action->spec.name(); + auto buildtree_files = fs.get_files_non_recursive(buildtrees_dir); + for (auto&& file : buildtree_files) + { + if (fs.is_directory(file) && file.filename() != "src") + { + std::error_code ec; + fs.remove_all(file, ec); + } + } + } + if (result != BuildResult::SUCCEEDED && keep_going == KeepGoing::NO) { System::println(Build::create_user_troubleshooting_message(install_action->spec)); @@ -645,7 +661,7 @@ namespace vcpkg::Install Checks::exit_success(VCPKG_LINE_INFO); } - const InstallSummary summary = perform(action_plan, keep_going, paths, status_db); + const InstallSummary summary = perform(action_plan, keep_going, Install::CleanBuildtrees::NO, paths, status_db); System::println("\nTotal elapsed time: %s", summary.total_elapsed_time); -- cgit v1.2.3 From 2b7cd655c8d52ce40453497ecc06c81dc2977aab Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 14 Nov 2017 16:01:13 -0800 Subject: Update CHANGELOG and bump version to v0.0.97 --- toolsrc/VERSION.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/VERSION.txt b/toolsrc/VERSION.txt index bc63ef127..d7db639a5 100644 --- a/toolsrc/VERSION.txt +++ b/toolsrc/VERSION.txt @@ -1 +1 @@ -"0.0.96" \ No newline at end of file +"0.0.97" \ No newline at end of file -- cgit v1.2.3 From 34b4db1fb45df541b8a2c7592a57ac6a8fd0b900 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Thu, 16 Nov 2017 17:42:15 -0800 Subject: [vcpkg] Output autodetected CMake usage information after install. --- toolsrc/include/vcpkg/build.h | 6 ++ toolsrc/include/vcpkg/install.h | 14 ++-- toolsrc/src/vcpkg/install.cpp | 140 ++++++++++++++++++++++++++++++++++------ 3 files changed, 134 insertions(+), 26 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/build.h b/toolsrc/include/vcpkg/build.h index 824f3ccaf..cbd34c730 100644 --- a/toolsrc/include/vcpkg/build.h +++ b/toolsrc/include/vcpkg/build.h @@ -69,6 +69,12 @@ namespace vcpkg::Build EXCLUDED, }; + struct BuildResults + { + BuildResult result_code; + std::unique_ptr binary_control_file; + }; + static constexpr std::array BUILD_RESULT_VALUES = { BuildResult::SUCCEEDED, BuildResult::BUILD_FAILED, diff --git a/toolsrc/include/vcpkg/install.h b/toolsrc/include/vcpkg/install.h index df7542318..e436e2238 100644 --- a/toolsrc/include/vcpkg/install.h +++ b/toolsrc/include/vcpkg/install.h @@ -30,11 +30,15 @@ namespace vcpkg::Install struct SpecSummary { - explicit SpecSummary(const PackageSpec& spec); + SpecSummary(const PackageSpec& spec, const Dependencies::AnyAction* action); + + const BinaryParagraph* get_binary_paragraph() const; PackageSpec spec; - Build::BuildResult result; + Build::BuildResults build_result; std::string timing; + + const Dependencies::AnyAction* action; }; struct InstallSummary @@ -62,9 +66,9 @@ namespace vcpkg::Install const fs::path& listfile() const; }; - Build::BuildResult perform_install_plan_action(const VcpkgPaths& paths, - const Dependencies::InstallPlanAction& action, - StatusParagraphs& status_db); + Build::BuildResults perform_install_plan_action(const VcpkgPaths& paths, + const Dependencies::InstallPlanAction& action, + StatusParagraphs& status_db); enum class InstallResult { diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp index 88ef5c73d..7edcafb1f 100644 --- a/toolsrc/src/vcpkg/install.cpp +++ b/toolsrc/src/vcpkg/install.cpp @@ -247,10 +247,11 @@ namespace vcpkg::Install } using Build::BuildResult; + using Build::BuildResults; - BuildResult perform_install_plan_action(const VcpkgPaths& paths, - const InstallPlanAction& action, - StatusParagraphs& status_db) + BuildResults perform_install_plan_action(const VcpkgPaths& paths, + const InstallPlanAction& action, + StatusParagraphs& status_db) { const InstallPlanType& plan_type = action.plan_type; const std::string display_name = action.spec.to_string(); @@ -267,7 +268,7 @@ namespace vcpkg::Install System::Color::warning, "Package %s is already installed -- not building from HEAD", display_name); else System::println(System::Color::success, "Package %s is already installed", display_name); - return BuildResult::SUCCEEDED; + return {BuildResult::SUCCEEDED, nullptr}; } if (plan_type == InstallPlanType::BUILD_AND_INSTALL) @@ -302,21 +303,21 @@ namespace vcpkg::Install if (result.code != Build::BuildResult::SUCCEEDED) { System::println(System::Color::error, Build::create_error_message(result.code, action.spec)); - return result.code; + return {result.code, nullptr}; } System::println("Building package %s... done", display_name_with_features); - const BinaryControlFile bcf = - Paragraphs::try_load_cached_control_package(paths, action.spec).value_or_exit(VCPKG_LINE_INFO); + auto bcf = std::make_unique( + Paragraphs::try_load_cached_control_package(paths, action.spec).value_or_exit(VCPKG_LINE_INFO)); System::println("Installing package %s... ", display_name_with_features); - const auto install_result = install_package(paths, bcf, &status_db); + const auto install_result = install_package(paths, *bcf, &status_db); switch (install_result) { case InstallResult::SUCCESS: System::println(System::Color::success, "Installing package %s... done", display_name); - return BuildResult::SUCCEEDED; - case InstallResult::FILE_CONFLICTS: return BuildResult::FILE_CONFLICTS; + return {BuildResult::SUCCEEDED, std::move(bcf)}; + case InstallResult::FILE_CONFLICTS: return {BuildResult::FILE_CONFLICTS, nullptr}; default: Checks::unreachable(VCPKG_LINE_INFO); } } @@ -335,8 +336,8 @@ namespace vcpkg::Install { case InstallResult::SUCCESS: System::println(System::Color::success, "Installing package %s... done", display_name); - return BuildResult::SUCCEEDED; - case InstallResult::FILE_CONFLICTS: return BuildResult::FILE_CONFLICTS; + return {BuildResult::SUCCEEDED, nullptr}; + case InstallResult::FILE_CONFLICTS: return {BuildResult::FILE_CONFLICTS, nullptr}; default: Checks::unreachable(VCPKG_LINE_INFO); } } @@ -344,7 +345,7 @@ namespace vcpkg::Install if (plan_type == InstallPlanType::EXCLUDED) { System::println(System::Color::warning, "Package %s is excluded", display_name); - return BuildResult::EXCLUDED; + return {BuildResult::EXCLUDED, nullptr}; } Checks::unreachable(VCPKG_LINE_INFO); @@ -458,7 +459,8 @@ namespace vcpkg::Install for (const SpecSummary& result : this->results) { - System::println(" %s: %s: %s", result.spec, Build::to_string(result.result), result.timing); + System::println( + " %s: %s: %s", result.spec, Build::to_string(result.build_result.result_code), result.timing); } std::map summary; @@ -469,7 +471,7 @@ namespace vcpkg::Install for (const SpecSummary& r : this->results) { - summary[r.result]++; + summary[r.build_result.result_code]++; } System::println("\nSUMMARY"); @@ -500,11 +502,11 @@ namespace vcpkg::Install const std::string display_name = spec.to_string(); System::println("Starting package %d/%d: %s", counter, package_count, display_name); - results.push_back(SpecSummary{spec}); + results.emplace_back(spec, &action); if (const auto install_action = action.install_plan.get()) { - const BuildResult result = perform_install_plan_action(paths, *install_action, status_db); + Build::BuildResults result = perform_install_plan_action(paths, *install_action, status_db); if (clean_buildtrees == CleanBuildtrees::YES) { auto& fs = paths.get_filesystem(); @@ -520,13 +522,13 @@ namespace vcpkg::Install } } - if (result != BuildResult::SUCCEEDED && keep_going == KeepGoing::NO) + if (result.result_code != BuildResult::SUCCEEDED && keep_going == KeepGoing::NO) { System::println(Build::create_user_troubleshooting_message(install_action->spec)); Checks::exit_fail(VCPKG_LINE_INFO); } - results.back().result = result; + results.back().build_result = std::move(result); } else if (const auto remove_action = action.remove_plan.get()) { @@ -542,7 +544,7 @@ namespace vcpkg::Install System::println("Elapsed time for package %s: %s", display_name, build_timer.to_string()); } - return InstallSummary{results, timer.to_string()}; + return InstallSummary{std::move(results), timer.to_string()}; } static const std::string OPTION_DRY_RUN = "--dry-run"; @@ -576,6 +578,69 @@ namespace vcpkg::Install &get_all_port_names, }; + static void print_cmake_information(const BinaryParagraph& bpgh, const VcpkgPaths& paths) + { + static const std::regex cmake_library_regex("^add_library\\(([^\\s\\$\\)]+)\\s"); + + auto& fs = paths.get_filesystem(); + + auto files = fs.read_lines(paths.listfile_path(bpgh)); + if (auto p_lines = files.get()) + { + for (auto&& suffix : *p_lines) + { + if (Strings::case_insensitive_ascii_find(suffix, "/share/") != suffix.end()) + { + std::vector library_targets; + + // File is inside the share folder + auto path = paths.installed / suffix; + auto maybe_contents = fs.read_contents(path); + if (auto p_contents = maybe_contents.get()) + { + std::sregex_iterator next(p_contents->begin(), p_contents->end(), cmake_library_regex); + std::sregex_iterator last; + + while (next != last) + { + auto match = *next; + library_targets.push_back(match[1]); + ++next; + } + } + + if (library_targets.empty()) + { + } + else if (library_targets.size() <= 4) + { + System::println("\nThe package %s provides CMake targets:\n" + "\n" + " find_package(%s REQUIRED)\n" + " target_link_libraries(main PRIVATE %s)", + bpgh.spec, + path.parent_path().filename().u8string(), + Strings::join(" ", library_targets)); + } + else + { + auto omitted = library_targets.size() - 4; + library_targets.erase(library_targets.begin() + 4, library_targets.end()); + System::println("\nThe package %s provides CMake targets:\n" + "\n" + " find_package(%s REQUIRED)\n" + " # Note: %d targets were omitted\n" + " target_link_libraries(main PRIVATE %s)", + bpgh.spec, + path.parent_path().filename().u8string(), + omitted, + Strings::join(" ", library_targets)); + } + } + } + } + } + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) { // input sanitization @@ -670,8 +735,41 @@ namespace vcpkg::Install summary.print(); } + auto& fs = paths.get_filesystem(); + + for (auto&& result : summary.results) + { + if (!result.action) continue; + if (auto p_install_action = result.action->install_plan.get()) + { + if (p_install_action->request_type != RequestType::USER_REQUESTED) continue; + auto bpgh = result.get_binary_paragraph(); + if (!bpgh) continue; + print_cmake_information(*bpgh, paths); + } + } + Checks::exit_success(VCPKG_LINE_INFO); } - SpecSummary::SpecSummary(const PackageSpec& spec) : spec(spec), result(BuildResult::NULLVALUE), timing("0") {} + SpecSummary::SpecSummary(const PackageSpec& spec, const Dependencies::AnyAction* action) + : spec(spec), build_result{BuildResult::NULLVALUE, nullptr}, timing("0"), action(action) + { + } + + const BinaryParagraph* SpecSummary::get_binary_paragraph() const + { + if (build_result.binary_control_file) return &build_result.binary_control_file->core_paragraph; + if (action) + if (auto p_install_plan = action->install_plan.get()) + { + if (auto p_bcf = p_install_plan->any_paragraph.binary_control_file.get()) + return &p_bcf->core_paragraph; + else if (auto p_status = p_install_plan->any_paragraph.status_paragraph.get()) + { + return &p_status->package; + } + } + return nullptr; + } } -- cgit v1.2.3 From 468e9e70e644eb26258434c9e27e34935eb3e06d Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Thu, 16 Nov 2017 19:29:32 -0800 Subject: [vcpkg] Refactor to remove Build::BuildResults -- too similar to ExtendedBuildResult --- toolsrc/include/vcpkg/base/util.h | 15 +++++++ toolsrc/include/vcpkg/build.h | 28 +++++------- toolsrc/include/vcpkg/install.h | 20 ++------- toolsrc/src/vcpkg/build.cpp | 66 ++++++++++++++++++---------- toolsrc/src/vcpkg/commands.ci.cpp | 8 +++- toolsrc/src/vcpkg/install.cpp | 90 ++++++++++++++++----------------------- 6 files changed, 115 insertions(+), 112 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/base/util.h b/toolsrc/include/vcpkg/base/util.h index 8d78fd6cc..6c05a3a9e 100644 --- a/toolsrc/include/vcpkg/base/util.h +++ b/toolsrc/include/vcpkg/base/util.h @@ -190,4 +190,19 @@ namespace vcpkg::Util std::unique_lock m_lock; T& m_ptr; }; + + namespace Enum + { + template + E to_enum(bool b) + { + return b ? E::YES : E::NO; + } + + template + bool to_bool(E e) + { + return e == E::YES; + } + } } diff --git a/toolsrc/include/vcpkg/build.h b/toolsrc/include/vcpkg/build.h index cbd34c730..1f6782ccf 100644 --- a/toolsrc/include/vcpkg/build.h +++ b/toolsrc/include/vcpkg/build.h @@ -32,30 +32,23 @@ namespace vcpkg::Build YES }; - inline UseHeadVersion to_use_head_version(const bool value) - { - return value ? UseHeadVersion::YES : UseHeadVersion::NO; - } - - inline bool to_bool(const UseHeadVersion value) { return value == UseHeadVersion::YES; } - enum class AllowDownloads { NO = 0, YES }; - inline AllowDownloads to_allow_downloads(const bool value) + enum class CleanBuildtrees { - return value ? AllowDownloads::YES : AllowDownloads::NO; - } - - inline bool to_bool(const AllowDownloads value) { return value == AllowDownloads::YES; } + NO = 0, + YES + }; struct BuildPackageOptions { UseHeadVersion use_head_version; AllowDownloads allow_downloads; + CleanBuildtrees clean_buildtrees; }; enum class BuildResult @@ -69,12 +62,6 @@ namespace vcpkg::Build EXCLUDED, }; - struct BuildResults - { - BuildResult result_code; - std::unique_ptr binary_control_file; - }; - static constexpr std::array BUILD_RESULT_VALUES = { BuildResult::SUCCEEDED, BuildResult::BUILD_FAILED, @@ -108,8 +95,13 @@ namespace vcpkg::Build struct ExtendedBuildResult { + ExtendedBuildResult(BuildResult code); + ExtendedBuildResult(BuildResult code, std::vector&& unmet_deps); + ExtendedBuildResult(BuildResult code, std::unique_ptr&& bcf); + BuildResult code; std::vector unmet_dependencies; + std::unique_ptr binary_control_file; }; struct BuildPackageConfig diff --git a/toolsrc/include/vcpkg/install.h b/toolsrc/include/vcpkg/install.h index e436e2238..28896adee 100644 --- a/toolsrc/include/vcpkg/install.h +++ b/toolsrc/include/vcpkg/install.h @@ -17,17 +17,6 @@ namespace vcpkg::Install inline KeepGoing to_keep_going(const bool value) { return value ? KeepGoing::YES : KeepGoing::NO; } - enum class CleanBuildtrees - { - NO = 0, - YES - }; - - inline CleanBuildtrees to_clean_buildtrees(const bool value) - { - return value ? CleanBuildtrees::YES : CleanBuildtrees::NO; - } - struct SpecSummary { SpecSummary(const PackageSpec& spec, const Dependencies::AnyAction* action); @@ -35,7 +24,7 @@ namespace vcpkg::Install const BinaryParagraph* get_binary_paragraph() const; PackageSpec spec; - Build::BuildResults build_result; + Build::ExtendedBuildResult build_result; std::string timing; const Dependencies::AnyAction* action; @@ -66,9 +55,9 @@ namespace vcpkg::Install const fs::path& listfile() const; }; - Build::BuildResults perform_install_plan_action(const VcpkgPaths& paths, - const Dependencies::InstallPlanAction& action, - StatusParagraphs& status_db); + Build::ExtendedBuildResult perform_install_plan_action(const VcpkgPaths& paths, + const Dependencies::InstallPlanAction& action, + StatusParagraphs& status_db); enum class InstallResult { @@ -85,7 +74,6 @@ namespace vcpkg::Install InstallSummary perform(const std::vector& action_plan, const KeepGoing keep_going, - const CleanBuildtrees clean_buildtrees, const VcpkgPaths& paths, StatusParagraphs& status_db); diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index b0ca3501b..e3787a97e 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -220,26 +220,25 @@ namespace vcpkg::Build tonull); } - static void create_binary_feature_control_file(const SourceParagraph& source_paragraph, - const FeatureParagraph& feature_paragraph, - const Triplet& triplet, - BinaryControlFile& bcf) + static BinaryParagraph create_binary_feature_control_file(const SourceParagraph& source_paragraph, + const FeatureParagraph& feature_paragraph, + const Triplet& triplet) { - BinaryParagraph bpgh(source_paragraph, feature_paragraph, triplet); - bcf.features.emplace_back(std::move(bpgh)); + return BinaryParagraph(source_paragraph, feature_paragraph, triplet); } - static void create_binary_control_file(const SourceParagraph& source_paragraph, - const Triplet& triplet, - const BuildInfo& build_info, - BinaryControlFile& bcf) + static std::unique_ptr create_binary_control_file(const SourceParagraph& source_paragraph, + const Triplet& triplet, + const BuildInfo& build_info) { + auto bcf = std::make_unique(); BinaryParagraph bpgh(source_paragraph, triplet); if (const auto p_ver = build_info.version.get()) { bpgh.version = *p_ver; } - bcf.core_paragraph = std::move(bpgh); + bcf->core_paragraph = std::move(bpgh); + return bcf; } static void write_binary_control_file(const VcpkgPaths& paths, BinaryControlFile bcf) @@ -311,8 +310,9 @@ namespace vcpkg::Build {"CURRENT_PORT_DIR", config.port_dir / "/."}, {"TARGET_TRIPLET", triplet.canonical_name()}, {"VCPKG_PLATFORM_TOOLSET", toolset.version.c_str()}, - {"VCPKG_USE_HEAD_VERSION", to_bool(config.build_package_options.use_head_version) ? "1" : "0"}, - {"_VCPKG_NO_DOWNLOADS", !to_bool(config.build_package_options.allow_downloads) ? "1" : "0"}, + {"VCPKG_USE_HEAD_VERSION", + Util::Enum::to_bool(config.build_package_options.use_head_version) ? "1" : "0"}, + {"_VCPKG_NO_DOWNLOADS", !Util::Enum::to_bool(config.build_package_options.allow_downloads) ? "1" : "0"}, {"GIT", git_exe_path}, {"FEATURES", features}, }); @@ -333,20 +333,18 @@ namespace vcpkg::Build { locked_metrics->track_property("error", "build failed"); locked_metrics->track_property("build_error", spec_string); - return {BuildResult::BUILD_FAILED, {}}; + return BuildResult::BUILD_FAILED; } } const BuildInfo build_info = read_build_info(paths.get_filesystem(), paths.build_info_file_path(spec)); const size_t error_count = PostBuildLint::perform_all_checks(spec, paths, pre_build_info, build_info); - BinaryControlFile bcf; - - create_binary_control_file(config.src, triplet, build_info, bcf); + auto bcf = create_binary_control_file(config.src, triplet, build_info); if (error_count != 0) { - return {BuildResult::POST_BUILD_CHECKS_FAILED, {}}; + return BuildResult::POST_BUILD_CHECKS_FAILED; } if (GlobalState::feature_packages) { @@ -357,18 +355,31 @@ namespace vcpkg::Build for (auto&& f_pgh : config.scf->feature_paragraphs) { if (f_pgh->name == feature) - create_binary_feature_control_file(*config.scf->core_paragraph, *f_pgh, triplet, bcf); + bcf->features.push_back( + create_binary_feature_control_file(*config.scf->core_paragraph, *f_pgh, triplet)); } } } } - write_binary_control_file(paths, bcf); + write_binary_control_file(paths, *bcf); - // const fs::path port_buildtrees_dir = paths.buildtrees / spec.name; - // delete_directory(port_buildtrees_dir); + if (config.build_package_options.clean_buildtrees == CleanBuildtrees::YES) + { + auto& fs = paths.get_filesystem(); + auto buildtrees_dir = paths.buildtrees / spec.name(); + auto buildtree_files = fs.get_files_non_recursive(buildtrees_dir); + for (auto&& file : buildtree_files) + { + if (fs.is_directory(file) && file.filename() != "src") + { + std::error_code ec; + fs.remove_all(file, ec); + } + } + } - return {BuildResult::SUCCEEDED, {}}; + return {BuildResult::SUCCEEDED, std::move(bcf)}; } const std::string& to_string(const BuildResult build_result) @@ -549,4 +560,13 @@ namespace vcpkg::Build return pre_build_info; } + ExtendedBuildResult::ExtendedBuildResult(BuildResult code) : code(code) {} + ExtendedBuildResult::ExtendedBuildResult(BuildResult code, std::unique_ptr&& bcf) + : code(code), binary_control_file(std::move(bcf)) + { + } + ExtendedBuildResult::ExtendedBuildResult(BuildResult code, std::vector&& unmet_deps) + : code(code), unmet_dependencies(std::move(unmet_deps)) + { + } } diff --git a/toolsrc/src/vcpkg/commands.ci.cpp b/toolsrc/src/vcpkg/commands.ci.cpp index 3c1c443f0..8f79b83e1 100644 --- a/toolsrc/src/vcpkg/commands.ci.cpp +++ b/toolsrc/src/vcpkg/commands.ci.cpp @@ -41,7 +41,11 @@ namespace vcpkg::Commands::CI Checks::check_exit(VCPKG_LINE_INFO, !install_plan.empty(), "Install plan cannot be empty"); - const Build::BuildPackageOptions install_plan_options = {Build::UseHeadVersion::NO, Build::AllowDownloads::YES}; + const Build::BuildPackageOptions install_plan_options = { + Build::UseHeadVersion::NO, + Build::AllowDownloads::YES, + Build::CleanBuildtrees::YES, + }; const std::vector action_plan = Util::fmap(install_plan, [&install_plan_options](InstallPlanAction& install_action) { @@ -49,7 +53,7 @@ namespace vcpkg::Commands::CI return Dependencies::AnyAction(std::move(install_action)); }); - return Install::perform(action_plan, Install::KeepGoing::YES, Install::CleanBuildtrees::YES, paths, status_db); + return Install::perform(action_plan, Install::KeepGoing::YES, paths, status_db); } struct TripletAndSummary diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp index 7edcafb1f..cc006811b 100644 --- a/toolsrc/src/vcpkg/install.cpp +++ b/toolsrc/src/vcpkg/install.cpp @@ -247,11 +247,11 @@ namespace vcpkg::Install } using Build::BuildResult; - using Build::BuildResults; + using Build::ExtendedBuildResult; - BuildResults perform_install_plan_action(const VcpkgPaths& paths, - const InstallPlanAction& action, - StatusParagraphs& status_db) + ExtendedBuildResult perform_install_plan_action(const VcpkgPaths& paths, + const InstallPlanAction& action, + StatusParagraphs& status_db) { const InstallPlanType& plan_type = action.plan_type; const std::string display_name = action.spec.to_string(); @@ -259,7 +259,7 @@ namespace vcpkg::Install GlobalState::feature_packages ? action.displayname() : display_name; const bool is_user_requested = action.request_type == RequestType::USER_REQUESTED; - const bool use_head_version = to_bool(action.build_options.use_head_version); + const bool use_head_version = Util::Enum::to_bool(action.build_options.use_head_version); if (plan_type == InstallPlanType::ALREADY_INSTALLED) { @@ -268,9 +268,22 @@ namespace vcpkg::Install System::Color::warning, "Package %s is already installed -- not building from HEAD", display_name); else System::println(System::Color::success, "Package %s is already installed", display_name); - return {BuildResult::SUCCEEDED, nullptr}; + return BuildResult::SUCCEEDED; } + auto aux_install = [&](const std::string& name, const BinaryControlFile& bcf) -> BuildResult { + System::println("Installing package %s... ", name); + const auto install_result = install_package(paths, bcf, &status_db); + switch (install_result) + { + case InstallResult::SUCCESS: + System::println(System::Color::success, "Installing package %s... done", name); + return BuildResult::SUCCEEDED; + case InstallResult::FILE_CONFLICTS: return BuildResult::FILE_CONFLICTS; + default: Checks::unreachable(VCPKG_LINE_INFO); + } + }; + if (plan_type == InstallPlanType::BUILD_AND_INSTALL) { if (use_head_version) @@ -278,7 +291,7 @@ namespace vcpkg::Install else System::println("Building package %s... ", display_name_with_features); - const auto result = [&]() -> Build::ExtendedBuildResult { + auto result = [&]() -> Build::ExtendedBuildResult { if (GlobalState::feature_packages) { const Build::BuildPackageConfig build_config{ @@ -303,23 +316,15 @@ namespace vcpkg::Install if (result.code != Build::BuildResult::SUCCEEDED) { System::println(System::Color::error, Build::create_error_message(result.code, action.spec)); - return {result.code, nullptr}; + return result; } System::println("Building package %s... done", display_name_with_features); auto bcf = std::make_unique( Paragraphs::try_load_cached_control_package(paths, action.spec).value_or_exit(VCPKG_LINE_INFO)); - System::println("Installing package %s... ", display_name_with_features); - const auto install_result = install_package(paths, *bcf, &status_db); - switch (install_result) - { - case InstallResult::SUCCESS: - System::println(System::Color::success, "Installing package %s... done", display_name); - return {BuildResult::SUCCEEDED, std::move(bcf)}; - case InstallResult::FILE_CONFLICTS: return {BuildResult::FILE_CONFLICTS, nullptr}; - default: Checks::unreachable(VCPKG_LINE_INFO); - } + auto code = aux_install(display_name_with_features, *bcf); + return {code, std::move(bcf)}; } if (plan_type == InstallPlanType::INSTALL) @@ -329,23 +334,15 @@ namespace vcpkg::Install System::println( System::Color::warning, "Package %s is already built -- not building from HEAD", display_name); } - System::println("Installing package %s... ", display_name); - const auto install_result = install_package( - paths, action.any_paragraph.binary_control_file.value_or_exit(VCPKG_LINE_INFO), &status_db); - switch (install_result) - { - case InstallResult::SUCCESS: - System::println(System::Color::success, "Installing package %s... done", display_name); - return {BuildResult::SUCCEEDED, nullptr}; - case InstallResult::FILE_CONFLICTS: return {BuildResult::FILE_CONFLICTS, nullptr}; - default: Checks::unreachable(VCPKG_LINE_INFO); - } + auto code = aux_install(display_name_with_features, + action.any_paragraph.binary_control_file.value_or_exit(VCPKG_LINE_INFO)); + return code; } if (plan_type == InstallPlanType::EXCLUDED) { System::println(System::Color::warning, "Package %s is excluded", display_name); - return {BuildResult::EXCLUDED, nullptr}; + return BuildResult::EXCLUDED; } Checks::unreachable(VCPKG_LINE_INFO); @@ -459,8 +456,7 @@ namespace vcpkg::Install for (const SpecSummary& result : this->results) { - System::println( - " %s: %s: %s", result.spec, Build::to_string(result.build_result.result_code), result.timing); + System::println(" %s: %s: %s", result.spec, Build::to_string(result.build_result.code), result.timing); } std::map summary; @@ -471,7 +467,7 @@ namespace vcpkg::Install for (const SpecSummary& r : this->results) { - summary[r.build_result.result_code]++; + summary[r.build_result.code]++; } System::println("\nSUMMARY"); @@ -483,7 +479,6 @@ namespace vcpkg::Install InstallSummary perform(const std::vector& action_plan, const KeepGoing keep_going, - const CleanBuildtrees clean_buildtrees, const VcpkgPaths& paths, StatusParagraphs& status_db) { @@ -506,23 +501,9 @@ namespace vcpkg::Install if (const auto install_action = action.install_plan.get()) { - Build::BuildResults result = perform_install_plan_action(paths, *install_action, status_db); - if (clean_buildtrees == CleanBuildtrees::YES) - { - auto& fs = paths.get_filesystem(); - auto buildtrees_dir = paths.buildtrees / install_action->spec.name(); - auto buildtree_files = fs.get_files_non_recursive(buildtrees_dir); - for (auto&& file : buildtree_files) - { - if (fs.is_directory(file) && file.filename() != "src") - { - std::error_code ec; - fs.remove_all(file, ec); - } - } - } + auto result = perform_install_plan_action(paths, *install_action, status_db); - if (result.result_code != BuildResult::SUCCEEDED && keep_going == KeepGoing::NO) + if (result.code != BuildResult::SUCCEEDED && keep_going == KeepGoing::NO) { System::println(Build::create_user_troubleshooting_message(install_action->spec)); Checks::exit_fail(VCPKG_LINE_INFO); @@ -669,8 +650,11 @@ namespace vcpkg::Install // create the plan StatusParagraphs status_db = database_load_check(paths); - const Build::BuildPackageOptions install_plan_options = {Build::to_use_head_version(use_head_version), - Build::to_allow_downloads(!no_downloads)}; + const Build::BuildPackageOptions install_plan_options = { + Util::Enum::to_enum(use_head_version), + Util::Enum::to_enum(!no_downloads), + Build::CleanBuildtrees::NO, + }; // Note: action_plan will hold raw pointers to SourceControlFiles from this map std::unordered_map scf_map; @@ -726,7 +710,7 @@ namespace vcpkg::Install Checks::exit_success(VCPKG_LINE_INFO); } - const InstallSummary summary = perform(action_plan, keep_going, Install::CleanBuildtrees::NO, paths, status_db); + const InstallSummary summary = perform(action_plan, keep_going, paths, status_db); System::println("\nTotal elapsed time: %s", summary.total_elapsed_time); -- cgit v1.2.3 From 1b2f75be941e9eed5986c10eb99fd6049490daec Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Thu, 16 Nov 2017 23:54:55 -0800 Subject: [vcpkg] Support \share\\usage to handle libraries which are found through built-in Find Modules. --- toolsrc/src/vcpkg/install.cpp | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp index cc006811b..f48b04d68 100644 --- a/toolsrc/src/vcpkg/install.cpp +++ b/toolsrc/src/vcpkg/install.cpp @@ -565,6 +565,17 @@ namespace vcpkg::Install auto& fs = paths.get_filesystem(); + auto usage_file = paths.installed / bpgh.spec.triplet().canonical_name() / "share" / bpgh.spec.name() / "usage"; + if (fs.exists(usage_file)) + { + auto maybe_contents = fs.read_contents(usage_file); + if (auto p_contents = maybe_contents.get()) + { + System::println(*p_contents); + } + return; + } + auto files = fs.read_lines(paths.listfile_path(bpgh)); if (auto p_lines = files.get()) { @@ -595,10 +606,10 @@ namespace vcpkg::Install } else if (library_targets.size() <= 4) { - System::println("\nThe package %s provides CMake targets:\n" + System::println("The package %s provides CMake targets:\n" "\n" " find_package(%s REQUIRED)\n" - " target_link_libraries(main PRIVATE %s)", + " target_link_libraries(main PRIVATE %s)\n", bpgh.spec, path.parent_path().filename().u8string(), Strings::join(" ", library_targets)); @@ -607,11 +618,11 @@ namespace vcpkg::Install { auto omitted = library_targets.size() - 4; library_targets.erase(library_targets.begin() + 4, library_targets.end()); - System::println("\nThe package %s provides CMake targets:\n" + System::println("The package %s provides CMake targets:\n" "\n" " find_package(%s REQUIRED)\n" " # Note: %d targets were omitted\n" - " target_link_libraries(main PRIVATE %s)", + " target_link_libraries(main PRIVATE %s)\n", bpgh.spec, path.parent_path().filename().u8string(), omitted, @@ -712,7 +723,7 @@ namespace vcpkg::Install const InstallSummary summary = perform(action_plan, keep_going, paths, status_db); - System::println("\nTotal elapsed time: %s", summary.total_elapsed_time); + System::println("\nTotal elapsed time: %s\n", summary.total_elapsed_time); if (keep_going == KeepGoing::YES) { -- cgit v1.2.3 From 1313a418cfe26d29c7b4ec2f871d93a07e884d10 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 20 Nov 2017 18:17:24 -0800 Subject: Introduce PowershellParameter to add '' to parameter values. Also place that and CMakeVariable in System.h --- toolsrc/include/vcpkg/base/system.h | 24 +++++++++++++++++++- toolsrc/include/vcpkg/vcpkglib.h | 15 +------------ toolsrc/src/vcpkg/base/system.cpp | 41 ++++++++++++++++++++++++++++++++++- toolsrc/src/vcpkg/build.cpp | 12 +++++----- toolsrc/src/vcpkg/commands.create.cpp | 3 +-- toolsrc/src/vcpkg/export.cpp | 3 ++- toolsrc/src/vcpkg/metrics.cpp | 5 +++-- toolsrc/src/vcpkg/vcpkglib.cpp | 24 +------------------- toolsrc/src/vcpkg/vcpkgpaths.cpp | 4 ++-- 9 files changed, 79 insertions(+), 52 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/base/system.h b/toolsrc/include/vcpkg/base/system.h index 9f2d91435..db537db4b 100644 --- a/toolsrc/include/vcpkg/base/system.h +++ b/toolsrc/include/vcpkg/base/system.h @@ -10,6 +10,28 @@ namespace vcpkg::System fs::path get_exe_path_of_current_process(); + struct CMakeVariable + { + CMakeVariable(const CStringView varname, const char* varvalue); + CMakeVariable(const CStringView varname, const std::string& varvalue); + CMakeVariable(const CStringView varname, const fs::path& path); + + std::string s; + }; + + std::string make_cmake_cmd(const fs::path& cmake_exe, + const fs::path& cmake_script, + const std::vector& pass_variables); + + struct PowershellParameter + { + PowershellParameter(const CStringView varname, const char* varvalue); + PowershellParameter(const CStringView varname, const std::string& varvalue); + PowershellParameter(const CStringView varname, const fs::path& path); + + std::string s; + }; + struct ExitCodeAndOutput { int exit_code; @@ -24,7 +46,7 @@ namespace vcpkg::System std::string powershell_execute_and_capture_output(const std::string& title, const fs::path& script_path, - const CStringView args = ""); + const std::vector& parameters = {}); enum class Color { diff --git a/toolsrc/include/vcpkg/vcpkglib.h b/toolsrc/include/vcpkg/vcpkglib.h index 9a7fdb861..3c8e676bf 100644 --- a/toolsrc/include/vcpkg/vcpkglib.h +++ b/toolsrc/include/vcpkg/vcpkglib.h @@ -20,18 +20,5 @@ namespace vcpkg std::vector get_installed_files(const VcpkgPaths& paths, const StatusParagraphs& status_db); - struct CMakeVariable - { - CMakeVariable(const CStringView varname, const char* varvalue); - CMakeVariable(const CStringView varname, const std::string& varvalue); - CMakeVariable(const CStringView varname, const fs::path& path); - - std::string s; - }; - - std::string make_cmake_cmd(const fs::path& cmake_exe, - const fs::path& cmake_script, - const std::vector& pass_variables); - - std::string shorten_text(const std::string& desc, size_t length); + std::string shorten_text(const std::string& desc, const size_t length); } // namespace vcpkg diff --git a/toolsrc/src/vcpkg/base/system.cpp b/toolsrc/src/vcpkg/base/system.cpp index 47096ed63..56b725f6b 100644 --- a/toolsrc/src/vcpkg/base/system.cpp +++ b/toolsrc/src/vcpkg/base/system.cpp @@ -72,6 +72,43 @@ namespace vcpkg::System return supported_architectures; } + CMakeVariable::CMakeVariable(const CStringView varname, const char* varvalue) + : s(Strings::format(R"("-D%s=%s")", varname, varvalue)) + { + } + CMakeVariable::CMakeVariable(const CStringView varname, const std::string& varvalue) + : CMakeVariable(varname, varvalue.c_str()) + { + } + CMakeVariable::CMakeVariable(const CStringView varname, const fs::path& path) + : CMakeVariable(varname, path.generic_u8string()) + { + } + + std::string make_cmake_cmd(const fs::path& cmake_exe, + const fs::path& cmake_script, + const std::vector& pass_variables) + { + const std::string cmd_cmake_pass_variables = Strings::join(" ", pass_variables, [](auto&& v) { return v.s; }); + return Strings::format( + R"("%s" %s -P "%s")", cmake_exe.u8string(), cmd_cmake_pass_variables, cmake_script.generic_u8string()); + } + + PowershellParameter::PowershellParameter(const CStringView varname, const char* varvalue) + : s(Strings::format(R"(-%s '%s')", varname, varvalue)) + { + } + + PowershellParameter::PowershellParameter(const CStringView varname, const std::string& varvalue) + : PowershellParameter(varname, varvalue.c_str()) + { + } + + PowershellParameter::PowershellParameter(const CStringView varname, const fs::path& path) + : PowershellParameter(varname, path.generic_u8string()) + { + } + int cmd_execute_clean(const CStringView cmd_line) { #if defined(_WIN32) @@ -272,8 +309,10 @@ namespace vcpkg::System std::string powershell_execute_and_capture_output(const std::string& title, const fs::path& script_path, - const CStringView args) + const std::vector& parameters) { + const std::string args = Strings::join(" ", parameters, [](auto&& v) { return v.s; }); + // TODO: switch out ExecutionPolicy Bypass with "Remove Mark Of The Web" code and restore RemoteSigned const std::string cmd = Strings::format( R"(powershell -NoProfile -ExecutionPolicy Bypass -Command "& {& '%s' %s}")", script_path.u8string(), args); diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index e3787a97e..804573d91 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -301,7 +301,7 @@ namespace vcpkg::Build const Toolset& toolset = paths.get_toolset(pre_build_info.platform_toolset, pre_build_info.visual_studio_path); - const std::string cmd_launch_cmake = make_cmake_cmd( + const std::string cmd_launch_cmake = System::make_cmake_cmd( cmake_exe_path, ports_cmake_script_path, { @@ -493,11 +493,11 @@ namespace vcpkg::Build const fs::path ports_cmake_script_path = paths.scripts / "get_triplet_environment.cmake"; const fs::path triplet_file_path = paths.triplets / (triplet.canonical_name() + ".cmake"); - const auto cmd_launch_cmake = make_cmake_cmd(cmake_exe_path, - ports_cmake_script_path, - { - {"CMAKE_TRIPLET_FILE", triplet_file_path}, - }); + const auto cmd_launch_cmake = System::make_cmake_cmd(cmake_exe_path, + ports_cmake_script_path, + { + {"CMAKE_TRIPLET_FILE", triplet_file_path}, + }); const auto ec_data = System::cmd_execute_and_capture_output(cmd_launch_cmake); Checks::check_exit(VCPKG_LINE_INFO, ec_data.exit_code == 0, ec_data.output); diff --git a/toolsrc/src/vcpkg/commands.create.cpp b/toolsrc/src/vcpkg/commands.create.cpp index c7183d257..44f5f7928 100644 --- a/toolsrc/src/vcpkg/commands.create.cpp +++ b/toolsrc/src/vcpkg/commands.create.cpp @@ -4,7 +4,6 @@ #include #include #include -#include namespace vcpkg::Commands::Create { @@ -25,7 +24,7 @@ namespace vcpkg::Commands::Create const fs::path& cmake_exe = paths.get_cmake_exe(); - std::vector cmake_args{{"CMD", "CREATE"}, {"PORT", port_name}, {"URL", url}}; + std::vector cmake_args{{"CMD", "CREATE"}, {"PORT", port_name}, {"URL", url}}; if (args.command_arguments.size() >= 3) { diff --git a/toolsrc/src/vcpkg/export.cpp b/toolsrc/src/vcpkg/export.cpp index 9b86863eb..f237c72f8 100644 --- a/toolsrc/src/vcpkg/export.cpp +++ b/toolsrc/src/vcpkg/export.cpp @@ -369,7 +369,8 @@ namespace vcpkg::Export static void print_next_step_info(const fs::path& prefix) { const fs::path cmake_toolchain = prefix / "scripts" / "buildsystems" / "vcpkg.cmake"; - const CMakeVariable cmake_variable = CMakeVariable("CMAKE_TOOLCHAIN_FILE", cmake_toolchain.generic_string()); + const System::CMakeVariable cmake_variable = + System::CMakeVariable("CMAKE_TOOLCHAIN_FILE", cmake_toolchain.generic_string()); System::println("\n" "To use the exported libraries in CMake projects use:" "\n" diff --git a/toolsrc/src/vcpkg/metrics.cpp b/toolsrc/src/vcpkg/metrics.cpp index d7e18a176..15bcb4516 100644 --- a/toolsrc/src/vcpkg/metrics.cpp +++ b/toolsrc/src/vcpkg/metrics.cpp @@ -255,9 +255,10 @@ namespace vcpkg::Metrics auto match = *next; if (match[0] != "00-00-00-00-00-00") { - std::string matchstr = match[0]; + const std::string matchstr = match[0]; + const System::PowershellParameter value("Value", matchstr); auto hash_result = System::powershell_execute_and_capture_output( - "SHA256Hash", get_vcpkg_root() / "SHA256Hash.ps1", Strings::format("-Value \"%s\"", matchstr)); + "SHA256Hash", get_vcpkg_root() / "SHA256Hash.ps1", {value}); Util::erase_remove_if(hash_result, [](char ch) { return !(ch >= 'A' && ch <= 'F') && !(ch >= '0' && ch <= '9'); }); hash_result = Strings::ascii_to_lowercase(hash_result); diff --git a/toolsrc/src/vcpkg/vcpkglib.cpp b/toolsrc/src/vcpkg/vcpkglib.cpp index 38b130f6f..5b2cec4d0 100644 --- a/toolsrc/src/vcpkg/vcpkglib.cpp +++ b/toolsrc/src/vcpkg/vcpkglib.cpp @@ -212,29 +212,7 @@ namespace vcpkg return installed_files; } - CMakeVariable::CMakeVariable(const CStringView varname, const char* varvalue) - : s(Strings::format(R"("-D%s=%s")", varname, varvalue)) - { - } - CMakeVariable::CMakeVariable(const CStringView varname, const std::string& varvalue) - : CMakeVariable(varname, varvalue.c_str()) - { - } - CMakeVariable::CMakeVariable(const CStringView varname, const fs::path& path) - : CMakeVariable(varname, path.generic_u8string()) - { - } - - std::string make_cmake_cmd(const fs::path& cmake_exe, - const fs::path& cmake_script, - const std::vector& pass_variables) - { - const std::string cmd_cmake_pass_variables = Strings::join(" ", pass_variables, [](auto&& v) { return v.s; }); - return Strings::format( - R"("%s" %s -P "%s")", cmake_exe.u8string(), cmd_cmake_pass_variables, cmake_script.generic_u8string()); - } - - std::string shorten_text(const std::string& desc, size_t length) + std::string shorten_text(const std::string& desc, const size_t length) { Checks::check_exit(VCPKG_LINE_INFO, length >= 3); auto simple_desc = std::regex_replace(desc, std::regex("\\s+"), " "); diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index a553f4199..460979693 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -92,8 +92,8 @@ namespace vcpkg version_as_string); const fs::path script = scripts_folder / "fetchDependency.ps1"; const std::string title = "Fetching %s version %s (No sufficient installed version was found)"; - const std::string output = - System::powershell_execute_and_capture_output(title, script, Strings::format("-Dependency %s", tool_name)); + const System::PowershellParameter dependency_param("Dependency", tool_name); + const std::string output = System::powershell_execute_and_capture_output(title, script, {dependency_param}); const std::vector dependency_path = keep_data_lines(output); Checks::check_exit( -- cgit v1.2.3 From 7c07ff813b0528fdd37f8835b99bc2e449fcf10c Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 20 Nov 2017 18:22:55 -0800 Subject: Fix path --- toolsrc/src/vcpkg/metrics.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/metrics.cpp b/toolsrc/src/vcpkg/metrics.cpp index 15bcb4516..69160705c 100644 --- a/toolsrc/src/vcpkg/metrics.cpp +++ b/toolsrc/src/vcpkg/metrics.cpp @@ -258,7 +258,7 @@ namespace vcpkg::Metrics const std::string matchstr = match[0]; const System::PowershellParameter value("Value", matchstr); auto hash_result = System::powershell_execute_and_capture_output( - "SHA256Hash", get_vcpkg_root() / "SHA256Hash.ps1", {value}); + "SHA256Hash", get_vcpkg_root() / "scripts" / "SHA256Hash.ps1", {value}); Util::erase_remove_if(hash_result, [](char ch) { return !(ch >= 'A' && ch <= 'F') && !(ch >= '0' && ch <= '9'); }); hash_result = Strings::ascii_to_lowercase(hash_result); -- cgit v1.2.3 From 786d53c002c044e9340e43070b393d69e14e78be Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 20 Nov 2017 19:15:47 -0800 Subject: Fix `vcpkg integrate install` for unicode usernames --- toolsrc/include/vcpkg/base/files.h | 1 + toolsrc/src/vcpkg/commands.integrate.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/base/files.h b/toolsrc/include/vcpkg/base/files.h index 63cf3c6fd..51a12ceba 100644 --- a/toolsrc/include/vcpkg/base/files.h +++ b/toolsrc/include/vcpkg/base/files.h @@ -15,6 +15,7 @@ namespace fs using stdfs::copy_options; using stdfs::file_status; using stdfs::path; + using stdfs::u8path; inline bool is_regular_file(file_status s) { return stdfs::is_regular_file(s); } inline bool is_directory(file_status s) { return stdfs::is_directory(s); } diff --git a/toolsrc/src/vcpkg/commands.integrate.cpp b/toolsrc/src/vcpkg/commands.integrate.cpp index 31b9ec722..f13a999fa 100644 --- a/toolsrc/src/vcpkg/commands.integrate.cpp +++ b/toolsrc/src/vcpkg/commands.integrate.cpp @@ -139,7 +139,7 @@ namespace vcpkg::Commands::Integrate static fs::path get_appdata_targets_path() { static const fs::path LOCAL_APP_DATA = - fs::path(System::get_environment_variable("LOCALAPPDATA").value_or_exit(VCPKG_LINE_INFO)); + fs::u8path(System::get_environment_variable("LOCALAPPDATA").value_or_exit(VCPKG_LINE_INFO)); return LOCAL_APP_DATA / "vcpkg" / "vcpkg.user.targets"; } #endif -- cgit v1.2.3 From 480f50a7b0e050885fa79eb6c2ffc85e0a4e7649 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Tue, 21 Nov 2017 19:58:38 -0800 Subject: [vcpkg] Improve cmake targets output --- toolsrc/src/vcpkg/install.cpp | 51 +++++++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 24 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp index f48b04d68..249e36e0f 100644 --- a/toolsrc/src/vcpkg/install.cpp +++ b/toolsrc/src/vcpkg/install.cpp @@ -579,15 +579,17 @@ namespace vcpkg::Install auto files = fs.read_lines(paths.listfile_path(bpgh)); if (auto p_lines = files.get()) { + std::map> library_targets; + for (auto&& suffix : *p_lines) { - if (Strings::case_insensitive_ascii_find(suffix, "/share/") != suffix.end()) + if (Strings::case_insensitive_ascii_find(suffix, "/share/") != suffix.end() && + suffix.substr(suffix.size() - 6) == ".cmake") { - std::vector library_targets; - // File is inside the share folder auto path = paths.installed / suffix; auto maybe_contents = fs.read_contents(path); + auto find_package_name = path.parent_path().filename().u8string(); if (auto p_contents = maybe_contents.get()) { std::sregex_iterator next(p_contents->begin(), p_contents->end(), cmake_library_regex); @@ -596,37 +598,40 @@ namespace vcpkg::Install while (next != last) { auto match = *next; - library_targets.push_back(match[1]); + library_targets[find_package_name].push_back(match[1]); ++next; } } + } + } - if (library_targets.empty()) - { - } - else if (library_targets.size() <= 4) + if (library_targets.empty()) + { + } + else + { + System::println("The package %s provides CMake targets:\n", bpgh.spec); + + for (auto&& library_target_pair : library_targets) + { + if (library_target_pair.second.size() <= 4) { - System::println("The package %s provides CMake targets:\n" - "\n" - " find_package(%s REQUIRED)\n" + System::println(" find_package(%s REQUIRED)\n" " target_link_libraries(main PRIVATE %s)\n", - bpgh.spec, - path.parent_path().filename().u8string(), - Strings::join(" ", library_targets)); + library_target_pair.first, + Strings::join(" ", library_target_pair.second)); } else { - auto omitted = library_targets.size() - 4; - library_targets.erase(library_targets.begin() + 4, library_targets.end()); - System::println("The package %s provides CMake targets:\n" - "\n" - " find_package(%s REQUIRED)\n" + auto omitted = library_target_pair.second.size() - 4; + library_target_pair.second.erase(library_target_pair.second.begin() + 4, + library_target_pair.second.end()); + System::println(" find_package(%s REQUIRED)\n" " # Note: %d targets were omitted\n" " target_link_libraries(main PRIVATE %s)\n", - bpgh.spec, - path.parent_path().filename().u8string(), + library_target_pair.first, omitted, - Strings::join(" ", library_targets)); + Strings::join(" ", library_target_pair.second)); } } } @@ -730,8 +735,6 @@ namespace vcpkg::Install summary.print(); } - auto& fs = paths.get_filesystem(); - for (auto&& result : summary.results) { if (!result.action) continue; -- cgit v1.2.3 From 141f10801c2fae8ab844e94fe5338d055892c0ac Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Sat, 25 Nov 2017 11:49:15 -0800 Subject: [vcpkg] Improve external toolchain handling. --- toolsrc/include/vcpkg/build.h | 1 + toolsrc/include/vcpkg/vcpkgpaths.h | 8 ++++-- toolsrc/src/vcpkg/base/files.cpp | 3 ++- toolsrc/src/vcpkg/base/system.cpp | 10 ++++++++ toolsrc/src/vcpkg/build.cpp | 14 ++++++++-- toolsrc/src/vcpkg/commands.env.cpp | 2 +- toolsrc/src/vcpkg/export.cpp | 2 +- toolsrc/src/vcpkg/install.cpp | 2 +- toolsrc/src/vcpkg/postbuildlint.cpp | 2 +- toolsrc/src/vcpkg/vcpkgpaths.cpp | 37 ++++++++++++++++++++++----- toolsrc/vcpkg.sln | 51 +++++++++++++++++++++++++++++++++++++ 11 files changed, 117 insertions(+), 15 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/build.h b/toolsrc/include/vcpkg/build.h index 1f6782ccf..09e74905f 100644 --- a/toolsrc/include/vcpkg/build.h +++ b/toolsrc/include/vcpkg/build.h @@ -89,6 +89,7 @@ namespace vcpkg::Build std::string cmake_system_version; Optional platform_toolset; Optional visual_studio_path; + Optional external_toolchain_file; }; std::string make_build_env_cmd(const PreBuildInfo& pre_build_info, const Toolset& toolset); diff --git a/toolsrc/include/vcpkg/vcpkgpaths.h b/toolsrc/include/vcpkg/vcpkgpaths.h index 0790be785..33a9b0067 100644 --- a/toolsrc/include/vcpkg/vcpkgpaths.h +++ b/toolsrc/include/vcpkg/vcpkgpaths.h @@ -26,6 +26,11 @@ namespace vcpkg std::vector supported_architectures; }; + namespace Build + { + struct PreBuildInfo; + } + struct VcpkgPaths { static Expected create(const fs::path& vcpkg_root_dir); @@ -69,8 +74,7 @@ namespace vcpkg /// /// Valid version strings are "v120", "v140", "v141", and "". Empty string gets the latest. /// - const Toolset& get_toolset(const Optional& toolset_version, - const Optional& visual_studio_path) const; + const Toolset& get_toolset(const Build::PreBuildInfo& prebuildinfo) const; Files::Filesystem& get_filesystem() const; diff --git a/toolsrc/src/vcpkg/base/files.cpp b/toolsrc/src/vcpkg/base/files.cpp index 6e43debb1..8c9e137ed 100644 --- a/toolsrc/src/vcpkg/base/files.cpp +++ b/toolsrc/src/vcpkg/base/files.cpp @@ -72,7 +72,8 @@ namespace vcpkg::Files { std::vector ret; - fs::stdfs::recursive_directory_iterator b(dir), e{}; + std::error_code ec; + fs::stdfs::recursive_directory_iterator b(dir, ec), e{}; for (; b != e; ++b) { ret.push_back(b->path()); diff --git a/toolsrc/src/vcpkg/base/system.cpp b/toolsrc/src/vcpkg/base/system.cpp index 56b725f6b..9d8e1ce84 100644 --- a/toolsrc/src/vcpkg/base/system.cpp +++ b/toolsrc/src/vcpkg/base/system.cpp @@ -51,11 +51,21 @@ namespace vcpkg::System CPUArchitecture get_host_processor() { +#if defined(_WIN32) auto w6432 = get_environment_variable("PROCESSOR_ARCHITEW6432"); if (const auto p = w6432.get()) return to_cpu_architecture(*p).value_or_exit(VCPKG_LINE_INFO); const auto procarch = get_environment_variable("PROCESSOR_ARCHITECTURE").value_or_exit(VCPKG_LINE_INFO); return to_cpu_architecture(procarch).value_or_exit(VCPKG_LINE_INFO); +#else +#if defined(__x86_64__) || defined(_M_X64) + return CPUArchitecture::X64; +#elif defined(__x86__) || defined(_M_X86) + return CPUArchitecture::X86; +#else +#error "Unknown host architecture" +#endif +#endif } std::vector get_supported_host_architectures() diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index 804573d91..fd605ac08 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -203,6 +203,10 @@ namespace vcpkg::Build std::string make_build_env_cmd(const PreBuildInfo& pre_build_info, const Toolset& toolset) { + if (pre_build_info.external_toolchain_file) + return Strings::format( + R"("%s" %s 2>&1)", toolset.vcvarsall.u8string(), Strings::join(" ", toolset.vcvarsall_options)); + const char* tonull = " >nul"; if (GlobalState::debugging) { @@ -299,8 +303,7 @@ namespace vcpkg::Build } } - const Toolset& toolset = paths.get_toolset(pre_build_info.platform_toolset, pre_build_info.visual_studio_path); - + const Toolset& toolset = paths.get_toolset(pre_build_info); const std::string cmd_launch_cmake = System::make_cmake_cmd( cmake_exe_path, ports_cmake_script_path, @@ -555,6 +558,13 @@ namespace vcpkg::Build continue; } + if (variable_name == "VCPKG_CHAINLOAD_TOOLCHAIN_FILE") + { + pre_build_info.external_toolchain_file = + variable_value.empty() ? nullopt : Optional{variable_value}; + continue; + } + Checks::exit_with_message(VCPKG_LINE_INFO, "Unknown variable name %s", line); } diff --git a/toolsrc/src/vcpkg/commands.env.cpp b/toolsrc/src/vcpkg/commands.env.cpp index 98b5aced9..6e52383d8 100644 --- a/toolsrc/src/vcpkg/commands.env.cpp +++ b/toolsrc/src/vcpkg/commands.env.cpp @@ -20,7 +20,7 @@ namespace vcpkg::Commands::Env args.parse_arguments(COMMAND_STRUCTURE); const auto pre_build_info = Build::PreBuildInfo::from_triplet_file(paths, default_triplet); - const Toolset& toolset = paths.get_toolset(pre_build_info.platform_toolset, pre_build_info.visual_studio_path); + const Toolset& toolset = paths.get_toolset(pre_build_info); System::cmd_execute_clean(Build::make_build_env_cmd(pre_build_info, toolset) + " && cmd"); Checks::exit_success(VCPKG_LINE_INFO); diff --git a/toolsrc/src/vcpkg/export.cpp b/toolsrc/src/vcpkg/export.cpp index f237c72f8..32cb6f03e 100644 --- a/toolsrc/src/vcpkg/export.cpp +++ b/toolsrc/src/vcpkg/export.cpp @@ -290,7 +290,7 @@ namespace vcpkg::Export {OPTION_IFW_INSTALLER_FILE_PATH, "Specify the file path for the exported installer"}, }}; - const CommandStructure vcpkg::Export::COMMAND_STRUCTURE = { + const CommandStructure COMMAND_STRUCTURE = { Help::create_example_string("export zlib zlib:x64-windows boost --nuget"), 0, SIZE_MAX, diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp index 249e36e0f..0888e21d5 100644 --- a/toolsrc/src/vcpkg/install.cpp +++ b/toolsrc/src/vcpkg/install.cpp @@ -561,7 +561,7 @@ namespace vcpkg::Install static void print_cmake_information(const BinaryParagraph& bpgh, const VcpkgPaths& paths) { - static const std::regex cmake_library_regex("^add_library\\(([^\\s\\$\\)]+)\\s"); + static const std::regex cmake_library_regex(R"(\badd_library\(([^\s\)]+)\s)", std::regex_constants::ECMAScript); auto& fs = paths.get_filesystem(); diff --git a/toolsrc/src/vcpkg/postbuildlint.cpp b/toolsrc/src/vcpkg/postbuildlint.cpp index 1f13c0a4f..10af41bb0 100644 --- a/toolsrc/src/vcpkg/postbuildlint.cpp +++ b/toolsrc/src/vcpkg/postbuildlint.cpp @@ -726,7 +726,7 @@ namespace vcpkg::PostBuildLint const auto& fs = paths.get_filesystem(); // for dumpbin - const Toolset& toolset = paths.get_toolset(pre_build_info.platform_toolset, pre_build_info.visual_studio_path); + const Toolset& toolset = paths.get_toolset(pre_build_info); const fs::path package_dir = paths.package_dir(spec); size_t error_count = 0; diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index 7c4d41815..0114b51b8 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -115,11 +116,13 @@ namespace vcpkg static constexpr std::array EXPECTED_VERSION = {3, 9, 5}; static const std::string VERSION_CHECK_ARGUMENTS = "--version"; - const fs::path downloaded_copy = downloads_folder / "cmake-3.9.5-win32-x86" / "bin" / "cmake.exe"; const std::vector from_path = Files::find_from_PATH("cmake"); std::vector candidate_paths; + const fs::path downloaded_copy = downloads_folder / "cmake-3.9.5-win32-x86" / "bin" / "cmake.exe"; +#if defined(_WIN32) candidate_paths.push_back(downloaded_copy); +#endif candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); #if defined(_WIN32) candidate_paths.push_back(System::get_program_files_platform_bitness() / "CMake" / "bin" / "cmake.exe"); @@ -161,11 +164,13 @@ namespace vcpkg static constexpr std::array EXPECTED_VERSION = {2, 15, 0}; static const std::string VERSION_CHECK_ARGUMENTS = "--version"; - const fs::path downloaded_copy = downloads_folder / "MinGit-2.15.0-32-bit" / "cmd" / "git.exe"; const std::vector from_path = Files::find_from_PATH("git"); + const fs::path downloaded_copy = downloads_folder / "MinGit-2.15.0-32-bit" / "cmd" / "git.exe"; std::vector candidate_paths; +#if defined(_WIN32) candidate_paths.push_back(downloaded_copy); +#endif candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); #if defined(_WIN32) candidate_paths.push_back(System::get_program_files_platform_bitness() / "git" / "cmd" / "git.exe"); @@ -499,16 +504,36 @@ namespace vcpkg return found_toolsets; } - const Toolset& VcpkgPaths::get_toolset(const Optional& toolset_version, - const Optional& visual_studio_path) const + const Toolset& VcpkgPaths::get_toolset(const Build::PreBuildInfo& prebuildinfo) const { + if (prebuildinfo.external_toolchain_file) + { + static Toolset external_toolset = []() -> Toolset { + Toolset ret; + ret.dumpbin = ""; + ret.supported_architectures = { + ToolsetArchOption{"", System::get_host_processor(), System::get_host_processor()}}; +#if defined(_WIN32) + ret.vcvarsall = "cmd"; + ret.vcvarsall_options = {"/c", "echo done"}; +#else + ret.vcvarsall = "true"; + ret.vcvarsall_options = {}; +#endif + ret.version = "external"; + ret.visual_studio_root_path = ""; + return ret; + }(); + return external_toolset; + } + // Invariant: toolsets are non-empty and sorted with newest at back() const std::vector& vs_toolsets = this->toolsets.get_lazy([this]() { return find_toolset_instances(*this); }); std::vector candidates = Util::element_pointers(vs_toolsets); - const auto tsv = toolset_version.get(); - const auto vsp = visual_studio_path.get(); + const auto tsv = prebuildinfo.platform_toolset.get(); + const auto vsp = prebuildinfo.visual_studio_path.get(); if (tsv && vsp) { diff --git a/toolsrc/vcpkg.sln b/toolsrc/vcpkg.sln index c97756c21..c2df757fc 100644 --- a/toolsrc/vcpkg.sln +++ b/toolsrc/vcpkg.sln @@ -11,6 +11,51 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vcpkgmetricsuploader", "vcp EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vcpkgtest", "vcpkgtest\vcpkgtest.vcxproj", "{F27B8DB0-1279-4AF8-A2E3-1D49C4F0220D}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "scripts", "scripts", "{F5893B21-EA71-4432-84D6-5FB0E0461A2A}" + ProjectSection(SolutionItems) = preProject + ..\scripts\bootstrap.ps1 = ..\scripts\bootstrap.ps1 + ..\scripts\fetchDependency.ps1 = ..\scripts\fetchDependency.ps1 + ..\scripts\findAnyMSBuildWithCppPlatformToolset.ps1 = ..\scripts\findAnyMSBuildWithCppPlatformToolset.ps1 + ..\scripts\findFileRecursivelyUp.ps1 = ..\scripts\findFileRecursivelyUp.ps1 + ..\scripts\findVisualStudioInstallationInstances.ps1 = ..\scripts\findVisualStudioInstallationInstances.ps1 + ..\scripts\get_triplet_environment.cmake = ..\scripts\get_triplet_environment.cmake + ..\scripts\getProgramFiles32bit.ps1 = ..\scripts\getProgramFiles32bit.ps1 + ..\scripts\getProgramFilesPlatformBitness.ps1 = ..\scripts\getProgramFilesPlatformBitness.ps1 + ..\scripts\getWindowsSDK.ps1 = ..\scripts\getWindowsSDK.ps1 + ..\scripts\internalCI.ps1 = ..\scripts\internalCI.ps1 + ..\scripts\ports.cmake = ..\scripts\ports.cmake + ..\scripts\SHA256Hash.ps1 = ..\scripts\SHA256Hash.ps1 + ..\scripts\VcpkgPowershellUtils.ps1 = ..\scripts\VcpkgPowershellUtils.ps1 + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "cmake", "cmake", "{A0122231-04D5-420B-81CA-7960946E5E65}" + ProjectSection(SolutionItems) = preProject + ..\scripts\cmake\vcpkg_acquire_msys.cmake = ..\scripts\cmake\vcpkg_acquire_msys.cmake + ..\scripts\cmake\vcpkg_apply_patches.cmake = ..\scripts\cmake\vcpkg_apply_patches.cmake + ..\scripts\cmake\vcpkg_build_cmake.cmake = ..\scripts\cmake\vcpkg_build_cmake.cmake + ..\scripts\cmake\vcpkg_build_msbuild.cmake = ..\scripts\cmake\vcpkg_build_msbuild.cmake + ..\scripts\cmake\vcpkg_build_qmake.cmake = ..\scripts\cmake\vcpkg_build_qmake.cmake + ..\scripts\cmake\vcpkg_common_functions.cmake = ..\scripts\cmake\vcpkg_common_functions.cmake + ..\scripts\cmake\vcpkg_configure_cmake.cmake = ..\scripts\cmake\vcpkg_configure_cmake.cmake + ..\scripts\cmake\vcpkg_configure_meson.cmake = ..\scripts\cmake\vcpkg_configure_meson.cmake + ..\scripts\cmake\vcpkg_configure_qmake.cmake = ..\scripts\cmake\vcpkg_configure_qmake.cmake + ..\scripts\cmake\vcpkg_copy_pdbs.cmake = ..\scripts\cmake\vcpkg_copy_pdbs.cmake + ..\scripts\cmake\vcpkg_copy_tool_dependencies.cmake = ..\scripts\cmake\vcpkg_copy_tool_dependencies.cmake + ..\scripts\cmake\vcpkg_download_distfile.cmake = ..\scripts\cmake\vcpkg_download_distfile.cmake + ..\scripts\cmake\vcpkg_execute_required_process.cmake = ..\scripts\cmake\vcpkg_execute_required_process.cmake + ..\scripts\cmake\vcpkg_execute_required_process_repeat.cmake = ..\scripts\cmake\vcpkg_execute_required_process_repeat.cmake + ..\scripts\cmake\vcpkg_extract_source_archive.cmake = ..\scripts\cmake\vcpkg_extract_source_archive.cmake + ..\scripts\cmake\vcpkg_find_acquire_program.cmake = ..\scripts\cmake\vcpkg_find_acquire_program.cmake + ..\scripts\cmake\vcpkg_fixup_cmake_targets.cmake = ..\scripts\cmake\vcpkg_fixup_cmake_targets.cmake + ..\scripts\cmake\vcpkg_from_bitbucket.cmake = ..\scripts\cmake\vcpkg_from_bitbucket.cmake + ..\scripts\cmake\vcpkg_from_github.cmake = ..\scripts\cmake\vcpkg_from_github.cmake + ..\scripts\cmake\vcpkg_get_program_files_32_bit.cmake = ..\scripts\cmake\vcpkg_get_program_files_32_bit.cmake + ..\scripts\cmake\vcpkg_get_program_files_platform_bitness.cmake = ..\scripts\cmake\vcpkg_get_program_files_platform_bitness.cmake + ..\scripts\cmake\vcpkg_get_windows_sdk.cmake = ..\scripts\cmake\vcpkg_get_windows_sdk.cmake + ..\scripts\cmake\vcpkg_install_cmake.cmake = ..\scripts\cmake\vcpkg_install_cmake.cmake + ..\scripts\cmake\vcpkg_install_meson.cmake = ..\scripts\cmake\vcpkg_install_meson.cmake + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 @@ -55,4 +100,10 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {A0122231-04D5-420B-81CA-7960946E5E65} = {F5893B21-EA71-4432-84D6-5FB0E0461A2A} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {DEDCC7AF-0FE6-4387-9FFE-495D6C1AEE1B} + EndGlobalSection EndGlobal -- cgit v1.2.3 From 5335d17f53d491d83d98e80ab0e750ec0f6f430b Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Sat, 25 Nov 2017 15:25:18 -0800 Subject: [vcpkg] Initial experimental support for VCPKG_BUILD_TYPE release --- toolsrc/VERSION.txt | 2 +- toolsrc/include/vcpkg/build.h | 7 +++++++ toolsrc/include/vcpkg/postbuildlint.buildtype.h | 24 ++++++++++-------------- toolsrc/src/vcpkg/build.cpp | 14 ++++++++++++++ toolsrc/src/vcpkg/postbuildlint.buildtype.cpp | 2 ++ toolsrc/src/vcpkg/postbuildlint.cpp | 22 ++++++++++++---------- toolsrc/vcpkg/vcpkg.vcxproj | 3 +++ toolsrc/vcpkg/vcpkg.vcxproj.filters | 5 +++++ 8 files changed, 54 insertions(+), 25 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/VERSION.txt b/toolsrc/VERSION.txt index d7db639a5..b9553cc3e 100644 --- a/toolsrc/VERSION.txt +++ b/toolsrc/VERSION.txt @@ -1 +1 @@ -"0.0.97" \ No newline at end of file +"0.0.98" \ No newline at end of file diff --git a/toolsrc/include/vcpkg/build.h b/toolsrc/include/vcpkg/build.h index 09e74905f..18408e207 100644 --- a/toolsrc/include/vcpkg/build.h +++ b/toolsrc/include/vcpkg/build.h @@ -44,6 +44,12 @@ namespace vcpkg::Build YES }; + enum class ConfigurationType + { + DEBUG, + RELEASE, + }; + struct BuildPackageOptions { UseHeadVersion use_head_version; @@ -90,6 +96,7 @@ namespace vcpkg::Build Optional platform_toolset; Optional visual_studio_path; Optional external_toolchain_file; + Optional build_type; }; std::string make_build_env_cmd(const PreBuildInfo& pre_build_info, const Toolset& toolset); diff --git a/toolsrc/include/vcpkg/postbuildlint.buildtype.h b/toolsrc/include/vcpkg/postbuildlint.buildtype.h index ff651fd7a..0b469d9a0 100644 --- a/toolsrc/include/vcpkg/postbuildlint.buildtype.h +++ b/toolsrc/include/vcpkg/postbuildlint.buildtype.h @@ -8,12 +8,6 @@ namespace vcpkg::PostBuildLint { - enum class ConfigurationType - { - DEBUG, - RELEASE, - }; - struct BuildType { enum class BackingEnum @@ -24,12 +18,12 @@ namespace vcpkg::PostBuildLint RELEASE_DYNAMIC }; - static BuildType value_of(const ConfigurationType& config, const Build::LinkageType& linkage); + static BuildType value_of(const Build::ConfigurationType& config, const Build::LinkageType& linkage); BuildType() = delete; constexpr BuildType(const BackingEnum backing_enum, - const ConfigurationType config, + const Build::ConfigurationType config, const Build::LinkageType linkage) : backing_enum(backing_enum), m_config(config), m_linkage(linkage) { @@ -37,14 +31,14 @@ namespace vcpkg::PostBuildLint constexpr operator BackingEnum() const { return backing_enum; } - const ConfigurationType& config() const; + const Build::ConfigurationType& config() const; const Build::LinkageType& linkage() const; const std::regex& crt_regex() const; const std::string& to_string() const; private: BackingEnum backing_enum; - ConfigurationType m_config; + Build::ConfigurationType m_config; Build::LinkageType m_linkage; }; @@ -55,12 +49,14 @@ namespace vcpkg::PostBuildLint static constexpr CStringView ENUM_NAME = "vcpkg::PostBuildLint::BuildType"; - static constexpr BuildType DEBUG_STATIC = {BE::DEBUG_STATIC, ConfigurationType::DEBUG, LinkageType::STATIC}; - static constexpr BuildType DEBUG_DYNAMIC = {BE::DEBUG_DYNAMIC, ConfigurationType::DEBUG, LinkageType::DYNAMIC}; + static constexpr BuildType DEBUG_STATIC = { + BE::DEBUG_STATIC, Build::ConfigurationType::DEBUG, LinkageType::STATIC}; + static constexpr BuildType DEBUG_DYNAMIC = { + BE::DEBUG_DYNAMIC, Build::ConfigurationType::DEBUG, LinkageType::DYNAMIC}; static constexpr BuildType RELEASE_STATIC = { - BE::RELEASE_STATIC, ConfigurationType::RELEASE, LinkageType::STATIC}; + BE::RELEASE_STATIC, Build::ConfigurationType::RELEASE, LinkageType::STATIC}; static constexpr BuildType RELEASE_DYNAMIC = { - BE::RELEASE_DYNAMIC, ConfigurationType::RELEASE, LinkageType::DYNAMIC}; + BE::RELEASE_DYNAMIC, Build::ConfigurationType::RELEASE, LinkageType::DYNAMIC}; static constexpr std::array VALUES = { DEBUG_STATIC, DEBUG_DYNAMIC, RELEASE_STATIC, RELEASE_DYNAMIC}; diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index fd605ac08..6ef72b639 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -565,6 +565,20 @@ namespace vcpkg::Build continue; } + if (variable_name == "VCPKG_BUILD_TYPE") + { + if (variable_value.empty()) + pre_build_info.build_type = nullopt; + else if (Strings::case_insensitive_ascii_equals(variable_value, "debug")) + pre_build_info.build_type = ConfigurationType::DEBUG; + else if (Strings::case_insensitive_ascii_equals(variable_value, "release")) + pre_build_info.build_type = ConfigurationType::RELEASE; + else + Checks::exit_with_message( + VCPKG_LINE_INFO, "Unknown setting for VCPKG_BUILD_TYPE: %s", variable_value); + continue; + } + Checks::exit_with_message(VCPKG_LINE_INFO, "Unknown variable name %s", line); } diff --git a/toolsrc/src/vcpkg/postbuildlint.buildtype.cpp b/toolsrc/src/vcpkg/postbuildlint.buildtype.cpp index 2baaddb5e..e966ce78a 100644 --- a/toolsrc/src/vcpkg/postbuildlint.buildtype.cpp +++ b/toolsrc/src/vcpkg/postbuildlint.buildtype.cpp @@ -3,6 +3,8 @@ #include #include +using vcpkg::Build::ConfigurationType; + namespace vcpkg::PostBuildLint { BuildType BuildType::value_of(const ConfigurationType& config, const Build::LinkageType& linkage) diff --git a/toolsrc/src/vcpkg/postbuildlint.cpp b/toolsrc/src/vcpkg/postbuildlint.cpp index 10af41bb0..0532bce58 100644 --- a/toolsrc/src/vcpkg/postbuildlint.cpp +++ b/toolsrc/src/vcpkg/postbuildlint.cpp @@ -758,7 +758,8 @@ namespace vcpkg::PostBuildLint std::vector 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); + if (!pre_build_info.build_type) + error_count += check_matching_debug_and_release_binaries(debug_libs, release_libs); { std::vector libs; @@ -777,7 +778,8 @@ namespace vcpkg::PostBuildLint { case Build::LinkageType::DYNAMIC: { - error_count += check_matching_debug_and_release_binaries(debug_dlls, release_dlls); + if (!pre_build_info.build_type) + error_count += check_matching_debug_and_release_binaries(debug_dlls, release_dlls); error_count += check_lib_files_are_available_if_dlls_are_available( build_info.policies, debug_libs.size(), debug_dlls.size(), debug_lib_dir); @@ -805,15 +807,15 @@ namespace vcpkg::PostBuildLint if (!build_info.policies.is_enabled(BuildPolicy::ONLY_RELEASE_CRT)) { - error_count += - check_crt_linkage_of_libs(BuildType::value_of(ConfigurationType::DEBUG, build_info.crt_linkage), - debug_libs, - toolset.dumpbin); + error_count += check_crt_linkage_of_libs( + BuildType::value_of(Build::ConfigurationType::DEBUG, build_info.crt_linkage), + debug_libs, + toolset.dumpbin); } - error_count += - check_crt_linkage_of_libs(BuildType::value_of(ConfigurationType::RELEASE, build_info.crt_linkage), - release_libs, - toolset.dumpbin); + error_count += check_crt_linkage_of_libs( + BuildType::value_of(Build::ConfigurationType::RELEASE, build_info.crt_linkage), + release_libs, + toolset.dumpbin); break; } default: Checks::unreachable(VCPKG_LINE_INFO); diff --git a/toolsrc/vcpkg/vcpkg.vcxproj b/toolsrc/vcpkg/vcpkg.vcxproj index fd8e5d33e..d15e8dd44 100644 --- a/toolsrc/vcpkg/vcpkg.vcxproj +++ b/toolsrc/vcpkg/vcpkg.vcxproj @@ -138,6 +138,9 @@ + + + diff --git a/toolsrc/vcpkg/vcpkg.vcxproj.filters b/toolsrc/vcpkg/vcpkg.vcxproj.filters index ca9723bbf..45a6238f6 100644 --- a/toolsrc/vcpkg/vcpkg.vcxproj.filters +++ b/toolsrc/vcpkg/vcpkg.vcxproj.filters @@ -19,4 +19,9 @@ Source Files + + + Source Files + + \ No newline at end of file -- cgit v1.2.3 From 14cbe496bcc136aac590f10d79848ec224088e85 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Sat, 25 Nov 2017 15:53:32 -0800 Subject: [vcpkg] Allow compilation inside WSL --- toolsrc/CMakeLists.txt | 14 ++++++++++++++ toolsrc/src/vcpkg/vcpkgpaths.cpp | 8 ++++++++ 2 files changed, 22 insertions(+) create mode 100644 toolsrc/CMakeLists.txt (limited to 'toolsrc') diff --git a/toolsrc/CMakeLists.txt b/toolsrc/CMakeLists.txt new file mode 100644 index 000000000..af281f12f --- /dev/null +++ b/toolsrc/CMakeLists.txt @@ -0,0 +1,14 @@ +cmake_minimum_required(VERSION 3.3) +project(vcpkg CXX) + +add_compile_options(-std=c++1z) + +file(GLOB_RECURSE VCPKGLIB_SOURCES src/vcpkg/*.cpp) + +add_library(vcpkglib STATIC ${VCPKGLIB_SOURCES}) +target_compile_definitions(vcpkglib PRIVATE -DDISABLE_METRICS=0) +target_include_directories(vcpkglib PUBLIC include) +target_link_libraries(vcpkglib PRIVATE stdc++fs) + +add_executable(vcpkg src/vcpkg.cpp) +target_link_libraries(vcpkg PRIVATE vcpkglib) diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index 0114b51b8..016f26f6d 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -113,7 +113,11 @@ namespace vcpkg static fs::path get_cmake_path(const fs::path& downloads_folder, const fs::path& scripts_folder) { +#if defined(_WIN32) static constexpr std::array EXPECTED_VERSION = {3, 9, 5}; +#else + static constexpr std::array EXPECTED_VERSION = {3, 5, 1}; +#endif static const std::string VERSION_CHECK_ARGUMENTS = "--version"; const std::vector from_path = Files::find_from_PATH("cmake"); @@ -161,7 +165,11 @@ namespace vcpkg fs::path get_git_path(const fs::path& downloads_folder, const fs::path& scripts_folder) { +#if defined(_WIN32) static constexpr std::array EXPECTED_VERSION = {2, 15, 0}; +#else + static constexpr std::array EXPECTED_VERSION = {2, 7, 4}; +#endif static const std::string VERSION_CHECK_ARGUMENTS = "--version"; const std::vector from_path = Files::find_from_PATH("git"); -- cgit v1.2.3 From 2af7fe8690a9b78f1eab1e532670ed133f82aff9 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Sun, 26 Nov 2017 02:49:23 -0800 Subject: Add System::powershell_execute() --- toolsrc/include/vcpkg/base/system.h | 4 ++++ toolsrc/src/vcpkg/base/system.cpp | 43 +++++++++++++++++++++++++++++++------ 2 files changed, 41 insertions(+), 6 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/base/system.h b/toolsrc/include/vcpkg/base/system.h index db537db4b..31034f6b4 100644 --- a/toolsrc/include/vcpkg/base/system.h +++ b/toolsrc/include/vcpkg/base/system.h @@ -44,6 +44,10 @@ namespace vcpkg::System ExitCodeAndOutput cmd_execute_and_capture_output(const CStringView cmd_line); + void powershell_execute(const std::string& title, + const fs::path& script_path, + const std::vector& parameters = {}); + std::string powershell_execute_and_capture_output(const std::string& title, const fs::path& script_path, const std::vector& parameters = {}); diff --git a/toolsrc/src/vcpkg/base/system.cpp b/toolsrc/src/vcpkg/base/system.cpp index 9d8e1ce84..e3d3ad292 100644 --- a/toolsrc/src/vcpkg/base/system.cpp +++ b/toolsrc/src/vcpkg/base/system.cpp @@ -119,6 +119,16 @@ namespace vcpkg::System { } + static std::string make_powershell_cmd(const fs::path& script_path, + const std::vector& parameters) + { + const std::string args = Strings::join(" ", parameters, [](auto&& v) { return v.s; }); + + // TODO: switch out ExecutionPolicy Bypass with "Remove Mark Of The Web" code and restore RemoteSigned + return Strings::format( + R"(powershell -NoProfile -ExecutionPolicy Bypass -Command "& {& '%s' %s}")", script_path.u8string(), args); + } + int cmd_execute_clean(const CStringView cmd_line) { #if defined(_WIN32) @@ -317,16 +327,37 @@ namespace vcpkg::System #endif } + void powershell_execute(const std::string& title, + const fs::path& script_path, + const std::vector& parameters) + { + const std::string cmd = make_powershell_cmd(script_path, parameters); + const int rc = System::cmd_execute(cmd); + + if (rc) + { + System::println(Color::error, + "%s\n" + "Could not run:\n" + " '%s'", + title, + script_path.generic_string()); + + { + auto locked_metrics = Metrics::g_metrics.lock(); + locked_metrics->track_property("error", "powershell script failed"); + locked_metrics->track_property("title", title); + } + + Checks::exit_with_code(VCPKG_LINE_INFO, rc); + } + } + std::string powershell_execute_and_capture_output(const std::string& title, const fs::path& script_path, const std::vector& parameters) { - const std::string args = Strings::join(" ", parameters, [](auto&& v) { return v.s; }); - - // TODO: switch out ExecutionPolicy Bypass with "Remove Mark Of The Web" code and restore RemoteSigned - const std::string cmd = Strings::format( - R"(powershell -NoProfile -ExecutionPolicy Bypass -Command "& {& '%s' %s}")", script_path.u8string(), args); - + const std::string cmd = make_powershell_cmd(script_path, parameters); auto rc = System::cmd_execute_and_capture_output(cmd); if (rc.exit_code) -- cgit v1.2.3 From e009618ba0850ef54e837e8fb76910245d99b456 Mon Sep 17 00:00:00 2001 From: Mikhail Paulyshka Date: Sun, 26 Nov 2017 14:18:35 +0300 Subject: [cmake] update to 3.10.0 (#2236) --- toolsrc/src/vcpkg/vcpkgpaths.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index 016f26f6d..d5763921e 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -114,7 +114,7 @@ namespace vcpkg static fs::path get_cmake_path(const fs::path& downloads_folder, const fs::path& scripts_folder) { #if defined(_WIN32) - static constexpr std::array EXPECTED_VERSION = {3, 9, 5}; + static constexpr std::array EXPECTED_VERSION = {3, 10, 0}; #else static constexpr std::array EXPECTED_VERSION = {3, 5, 1}; #endif @@ -123,7 +123,7 @@ namespace vcpkg const std::vector from_path = Files::find_from_PATH("cmake"); std::vector candidate_paths; - const fs::path downloaded_copy = downloads_folder / "cmake-3.9.5-win32-x86" / "bin" / "cmake.exe"; + const fs::path downloaded_copy = downloads_folder / "cmake-3.10.0-win32-x86" / "bin" / "cmake.exe"; #if defined(_WIN32) candidate_paths.push_back(downloaded_copy); #endif -- cgit v1.2.3 From 7da4a498b3bf6686c1b08abafb59ab2e14cee681 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Sun, 26 Nov 2017 03:38:40 -0800 Subject: Update CHANGELOG and bump version to v0.0.99 --- toolsrc/VERSION.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/VERSION.txt b/toolsrc/VERSION.txt index b9553cc3e..2f0f54a23 100644 --- a/toolsrc/VERSION.txt +++ b/toolsrc/VERSION.txt @@ -1 +1 @@ -"0.0.98" \ No newline at end of file +"0.0.99" \ No newline at end of file -- cgit v1.2.3 From 8ba327914306a1545c039c0c1b55b962adeeebfb Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Tue, 28 Nov 2017 10:50:33 -0800 Subject: [vcpkg] Use c++experimental in clang --- toolsrc/CMakeLists.txt | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/CMakeLists.txt b/toolsrc/CMakeLists.txt index af281f12f..0325160ee 100644 --- a/toolsrc/CMakeLists.txt +++ b/toolsrc/CMakeLists.txt @@ -1,14 +1,19 @@ cmake_minimum_required(VERSION 3.3) project(vcpkg CXX) -add_compile_options(-std=c++1z) - file(GLOB_RECURSE VCPKGLIB_SOURCES src/vcpkg/*.cpp) add_library(vcpkglib STATIC ${VCPKGLIB_SOURCES}) target_compile_definitions(vcpkglib PRIVATE -DDISABLE_METRICS=0) target_include_directories(vcpkglib PUBLIC include) -target_link_libraries(vcpkglib PRIVATE stdc++fs) + +if(CMAKE_COMPILER_IS_GNUXX) + target_link_libraries(vcpkglib PRIVATE stdc++fs) + target_compile_options(vcpkglib PRIVATE -std=c++1z) +elseif(CMAKE_CXX_COMPILER_ID MATCHES "[Cc]lang") + target_link_libraries(vcpkglib PRIVATE c++experimental) + target_compile_options(vcpkglib PRIVATE -std=c++1z) +endif() add_executable(vcpkg src/vcpkg.cpp) target_link_libraries(vcpkg PRIVATE vcpkglib) -- cgit v1.2.3 From b496f7df493085d4e9b83082f33258bc164dcece Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Tue, 28 Nov 2017 13:06:56 -0800 Subject: [vcpkg] Further fix for clang/gcc --- toolsrc/CMakeLists.txt | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/CMakeLists.txt b/toolsrc/CMakeLists.txt index 0325160ee..51578e4e4 100644 --- a/toolsrc/CMakeLists.txt +++ b/toolsrc/CMakeLists.txt @@ -1,18 +1,24 @@ cmake_minimum_required(VERSION 3.3) project(vcpkg CXX) +add_compile_options(-std=c++1z) + +if(CMAKE_COMPILER_IS_GNUXX) + set(GCC 1) +elseif(CMAKE_CXX_COMPILER_ID MATCHES "[Cc]lang") + set(CLANG 1) +endif() + file(GLOB_RECURSE VCPKGLIB_SOURCES src/vcpkg/*.cpp) add_library(vcpkglib STATIC ${VCPKGLIB_SOURCES}) target_compile_definitions(vcpkglib PRIVATE -DDISABLE_METRICS=0) target_include_directories(vcpkglib PUBLIC include) -if(CMAKE_COMPILER_IS_GNUXX) - target_link_libraries(vcpkglib PRIVATE stdc++fs) - target_compile_options(vcpkglib PRIVATE -std=c++1z) -elseif(CMAKE_CXX_COMPILER_ID MATCHES "[Cc]lang") - target_link_libraries(vcpkglib PRIVATE c++experimental) - target_compile_options(vcpkglib PRIVATE -std=c++1z) +if(GCC) + target_link_libraries(vcpkglib PUBLIC stdc++fs) +elseif(CLANG) + target_link_libraries(vcpkglib PUBLIC c++experimental) endif() add_executable(vcpkg src/vcpkg.cpp) -- cgit v1.2.3 From d38d4a75408e0e9d0820187b16da2e06ce0ee316 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Wed, 29 Nov 2017 23:45:47 -0800 Subject: [vcpkg] Add --x-xunit internal command to print installation results in a VSTS friendly format. --- toolsrc/include/vcpkg/base/chrono.h | 31 +++++++++++--- toolsrc/include/vcpkg/globalstate.h | 4 +- toolsrc/include/vcpkg/install.h | 4 +- toolsrc/src/vcpkg.cpp | 2 +- toolsrc/src/vcpkg/base/chrono.cpp | 8 ++-- toolsrc/src/vcpkg/build.cpp | 4 +- toolsrc/src/vcpkg/commands.ci.cpp | 16 +++++++- toolsrc/src/vcpkg/commands.integrate.cpp | 2 +- toolsrc/src/vcpkg/commands.portsdiff.cpp | 6 +-- toolsrc/src/vcpkg/globalstate.cpp | 2 +- toolsrc/src/vcpkg/install.cpp | 69 +++++++++++++++++++++++++++----- toolsrc/src/vcpkg/postbuildlint.cpp | 2 +- 12 files changed, 119 insertions(+), 31 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/base/chrono.h b/toolsrc/include/vcpkg/base/chrono.h index b525852f2..c791f53fa 100644 --- a/toolsrc/include/vcpkg/base/chrono.h +++ b/toolsrc/include/vcpkg/base/chrono.h @@ -7,18 +7,37 @@ namespace vcpkg::Chrono { class ElapsedTime { - public: - static ElapsedTime create_started(); + using duration = std::chrono::high_resolution_clock::time_point::duration; - constexpr ElapsedTime() : m_start_tick() {} + public: + constexpr ElapsedTime() : m_duration() {} + constexpr ElapsedTime(duration d) : m_duration(d) {} template - TimeUnit elapsed() const + TimeUnit as() const + { + return std::chrono::duration_cast(m_duration); + } + + std::string to_string() const; + + private: + std::chrono::high_resolution_clock::time_point::duration m_duration; + }; + + class ElapsedTimer + { + public: + static ElapsedTimer create_started(); + + constexpr ElapsedTimer() : m_start_tick() {} + + ElapsedTime elapsed() const { - return std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - this->m_start_tick); + return ElapsedTime(std::chrono::high_resolution_clock::now() - this->m_start_tick); } - double microseconds() const { return elapsed>().count(); } + double microseconds() const { return elapsed().as>().count(); } std::string to_string() const; diff --git a/toolsrc/include/vcpkg/globalstate.h b/toolsrc/include/vcpkg/globalstate.h index 7cea361cf..40ec7958e 100644 --- a/toolsrc/include/vcpkg/globalstate.h +++ b/toolsrc/include/vcpkg/globalstate.h @@ -9,11 +9,11 @@ namespace vcpkg { struct GlobalState { - static Util::LockGuarded timer; + static Util::LockGuarded timer; static std::atomic debugging; static std::atomic feature_packages; static std::atomic g_init_console_cp; static std::atomic g_init_console_output_cp; }; -} \ No newline at end of file +} diff --git a/toolsrc/include/vcpkg/install.h b/toolsrc/include/vcpkg/install.h index 28896adee..2e92764dc 100644 --- a/toolsrc/include/vcpkg/install.h +++ b/toolsrc/include/vcpkg/install.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -25,7 +26,7 @@ namespace vcpkg::Install PackageSpec spec; Build::ExtendedBuildResult build_result; - std::string timing; + vcpkg::Chrono::ElapsedTime timing; const Dependencies::AnyAction* action; }; @@ -36,6 +37,7 @@ namespace vcpkg::Install std::string total_elapsed_time; void print() const; + std::string xunit_results() const; }; struct InstallDir diff --git a/toolsrc/src/vcpkg.cpp b/toolsrc/src/vcpkg.cpp index 5642f937c..04d44c414 100644 --- a/toolsrc/src/vcpkg.cpp +++ b/toolsrc/src/vcpkg.cpp @@ -255,7 +255,7 @@ int main(const int argc, const char* const* const argv) { if (argc == 0) std::abort(); - *GlobalState::timer.lock() = Chrono::ElapsedTime::create_started(); + *GlobalState::timer.lock() = Chrono::ElapsedTimer::create_started(); #if defined(_WIN32) GlobalState::g_init_console_cp = GetConsoleCP(); diff --git a/toolsrc/src/vcpkg/base/chrono.cpp b/toolsrc/src/vcpkg/base/chrono.cpp index 5d28909fc..f0e450231 100644 --- a/toolsrc/src/vcpkg/base/chrono.cpp +++ b/toolsrc/src/vcpkg/base/chrono.cpp @@ -50,12 +50,14 @@ namespace vcpkg::Chrono return Strings::format("%.4g ns", nanos_as_double); } - ElapsedTime ElapsedTime::create_started() + ElapsedTimer ElapsedTimer::create_started() { - ElapsedTime t; + ElapsedTimer t; t.m_start_tick = std::chrono::high_resolution_clock::now(); return t; } - std::string ElapsedTime::to_string() const { return format_time_userfriendly(elapsed()); } + std::string ElapsedTime::to_string() const { return format_time_userfriendly(as()); } + + std::string ElapsedTimer::to_string() const { return elapsed().to_string(); } } diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index 6ef72b639..b8f122b27 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -67,7 +67,7 @@ namespace vcpkg::Build::Command const Build::BuildPackageConfig build_config{ *scf, spec.triplet(), fs::path{port_dir}, build_package_options, features_as_set}; - const auto build_timer = Chrono::ElapsedTime::create_started(); + const auto build_timer = Chrono::ElapsedTimer::create_started(); const auto result = Build::build_package(paths, build_config, status_db); System::println("Elapsed time for package %s: %s", spec.to_string(), build_timer.to_string()); @@ -323,7 +323,7 @@ namespace vcpkg::Build const auto cmd_set_environment = make_build_env_cmd(pre_build_info, toolset); const std::string command = Strings::format(R"(%s && %s)", cmd_set_environment, cmd_launch_cmake); - const auto timer = Chrono::ElapsedTime::create_started(); + const auto timer = Chrono::ElapsedTimer::create_started(); const int return_code = System::cmd_execute_clean(command); const auto buildtimeus = timer.microseconds(); diff --git a/toolsrc/src/vcpkg/commands.ci.cpp b/toolsrc/src/vcpkg/commands.ci.cpp index 8f79b83e1..f2e984bf8 100644 --- a/toolsrc/src/vcpkg/commands.ci.cpp +++ b/toolsrc/src/vcpkg/commands.ci.cpp @@ -63,9 +63,11 @@ namespace vcpkg::Commands::CI }; static const std::string OPTION_EXCLUDE = "--exclude"; + static const std::string OPTION_XUNIT = "--x-xunit"; - static const std::array CI_SETTINGS = {{ + static const std::array CI_SETTINGS = {{ {OPTION_EXCLUDE, "Comma separated list of ports to skip"}, + {OPTION_XUNIT, "File to output results in XUnit format (internal)"}, }}; const CommandStructure COMMAND_STRUCTURE = { @@ -114,6 +116,18 @@ namespace vcpkg::Commands::CI result.summary.print(); } + auto it_xunit = options.settings.find(OPTION_XUNIT); + if (it_xunit != options.settings.end()) + { + std::string xunit_doc = "\n"; + + for (auto&& result : results) + xunit_doc += result.summary.xunit_results(); + + xunit_doc += "\n"; + paths.get_filesystem().write_contents(fs::u8path(it_xunit->second), xunit_doc); + } + Checks::exit_success(VCPKG_LINE_INFO); } } diff --git a/toolsrc/src/vcpkg/commands.integrate.cpp b/toolsrc/src/vcpkg/commands.integrate.cpp index f13a999fa..66c5eb5a9 100644 --- a/toolsrc/src/vcpkg/commands.integrate.cpp +++ b/toolsrc/src/vcpkg/commands.integrate.cpp @@ -257,7 +257,7 @@ CMake projects should use: "-DCMAKE_TOOLCHAIN_FILE=%s")", std::error_code ec; const bool was_deleted = fs.remove(path, ec); - Checks::check_exit(VCPKG_LINE_INFO, !ec, "Error: Unable to remove user-wide integration: %d", ec.message()); + Checks::check_exit(VCPKG_LINE_INFO, !ec, "Error: Unable to remove user-wide integration: %s", ec.message()); if (was_deleted) { diff --git a/toolsrc/src/vcpkg/commands.portsdiff.cpp b/toolsrc/src/vcpkg/commands.portsdiff.cpp index 0277c8bdb..6752715e4 100644 --- a/toolsrc/src/vcpkg/commands.portsdiff.cpp +++ b/toolsrc/src/vcpkg/commands.portsdiff.cpp @@ -151,14 +151,14 @@ namespace vcpkg::Commands::PortsDiff const std::vector& added_ports = setp.only_left; if (!added_ports.empty()) { - System::println("\nThe following %d ports were added:", added_ports.size()); + System::println("\nThe following %zd ports were added:", added_ports.size()); do_print_name_and_version(added_ports, current_names_and_versions); } const std::vector& removed_ports = setp.only_right; if (!removed_ports.empty()) { - System::println("\nThe following %d ports were removed:", removed_ports.size()); + System::println("\nThe following %zd ports were removed:", removed_ports.size()); do_print_name_and_version(removed_ports, previous_names_and_versions); } @@ -168,7 +168,7 @@ namespace vcpkg::Commands::PortsDiff if (!updated_ports.empty()) { - System::println("\nThe following %d ports were updated:", updated_ports.size()); + System::println("\nThe following %zd ports were updated:", updated_ports.size()); for (const UpdatedPort& p : updated_ports) { System::println(" - %-14s %-16s", p.port, p.version_diff.to_string()); diff --git a/toolsrc/src/vcpkg/globalstate.cpp b/toolsrc/src/vcpkg/globalstate.cpp index 43230fa4b..149401b2c 100644 --- a/toolsrc/src/vcpkg/globalstate.cpp +++ b/toolsrc/src/vcpkg/globalstate.cpp @@ -4,7 +4,7 @@ namespace vcpkg { - Util::LockGuarded GlobalState::timer; + Util::LockGuarded GlobalState::timer; std::atomic GlobalState::debugging(false); std::atomic GlobalState::feature_packages(false); diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp index 0888e21d5..76dc7a527 100644 --- a/toolsrc/src/vcpkg/install.cpp +++ b/toolsrc/src/vcpkg/install.cpp @@ -484,18 +484,18 @@ namespace vcpkg::Install { std::vector results; - const auto timer = Chrono::ElapsedTime::create_started(); + const auto timer = Chrono::ElapsedTimer::create_started(); size_t counter = 0; const size_t package_count = action_plan.size(); for (const auto& action : action_plan) { - const auto build_timer = Chrono::ElapsedTime::create_started(); + const auto build_timer = Chrono::ElapsedTimer::create_started(); counter++; const PackageSpec& spec = action.spec(); const std::string display_name = spec.to_string(); - System::println("Starting package %d/%d: %s", counter, package_count, display_name); + System::println("Starting package %zd/%zd: %s", counter, package_count, display_name); results.emplace_back(spec, &action); @@ -521,8 +521,8 @@ namespace vcpkg::Install Checks::unreachable(VCPKG_LINE_INFO); } - results.back().timing = build_timer.to_string(); - System::println("Elapsed time for package %s: %s", display_name, build_timer.to_string()); + results.back().timing = build_timer.elapsed(); + System::println("Elapsed time for package %s: %s", display_name, results.back().timing.to_string()); } return InstallSummary{std::move(results), timer.to_string()}; @@ -533,6 +533,7 @@ namespace vcpkg::Install static const std::string OPTION_NO_DOWNLOADS = "--no-downloads"; static const std::string OPTION_RECURSE = "--recurse"; static const std::string OPTION_KEEP_GOING = "--keep-going"; + static const std::string OPTION_XUNIT = "--x-xunit"; static const std::array INSTALL_SWITCHES = {{ {OPTION_DRY_RUN, "Do not actually build or install"}, @@ -541,7 +542,9 @@ namespace vcpkg::Install {OPTION_RECURSE, "Allow removal of packages as part of installation"}, {OPTION_KEEP_GOING, "Continue installing packages on failure"}, }}; - static const std::array INSTALL_SETTINGS; + static const std::array INSTALL_SETTINGS = {{ + {OPTION_XUNIT, "File to output results in XUnit format (Internal use)"}, + }}; std::vector get_all_port_names(const VcpkgPaths& paths) { @@ -555,7 +558,7 @@ namespace vcpkg::Install Help::create_example_string("install zlib zlib:x64-windows curl boost"), 1, SIZE_MAX, - {INSTALL_SWITCHES, {}}, + {INSTALL_SWITCHES, INSTALL_SETTINGS}, &get_all_port_names, }; @@ -627,7 +630,7 @@ namespace vcpkg::Install library_target_pair.second.erase(library_target_pair.second.begin() + 4, library_target_pair.second.end()); System::println(" find_package(%s REQUIRED)\n" - " # Note: %d targets were omitted\n" + " # Note: %zd targets were omitted\n" " target_link_libraries(main PRIVATE %s)\n", library_target_pair.first, omitted, @@ -735,6 +738,17 @@ namespace vcpkg::Install summary.print(); } + auto it_xunit = options.settings.find(OPTION_XUNIT); + if (it_xunit != options.settings.end()) + { + std::string xunit_doc = "\n"; + + xunit_doc += summary.xunit_results(); + + xunit_doc += "\n"; + paths.get_filesystem().write_contents(fs::u8path(it_xunit->second), xunit_doc); + } + for (auto&& result : summary.results) { if (!result.action) continue; @@ -751,7 +765,7 @@ namespace vcpkg::Install } SpecSummary::SpecSummary(const PackageSpec& spec, const Dependencies::AnyAction* action) - : spec(spec), build_result{BuildResult::NULLVALUE, nullptr}, timing("0"), action(action) + : spec(spec), build_result{BuildResult::NULLVALUE, nullptr}, action(action) { } @@ -770,4 +784,41 @@ namespace vcpkg::Install } return nullptr; } + + std::string InstallSummary::xunit_results() const + { + std::string xunit_doc; + for (auto&& result : results) + { + std::string inner_block; + const char* result_string = ""; + switch (result.build_result.code) + { + case BuildResult::POST_BUILD_CHECKS_FAILED: + case BuildResult::FILE_CONFLICTS: + case BuildResult::BUILD_FAILED: + result_string = "Fail"; + inner_block = Strings::format("", + to_string(result.build_result.code)); + break; + case BuildResult::EXCLUDED: + case BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES: + result_string = "Skip"; + inner_block = + Strings::format("", to_string(result.build_result.code)); + break; + case BuildResult::SUCCEEDED: result_string = "Pass"; break; + default: Checks::exit_fail(VCPKG_LINE_INFO); + } + + xunit_doc += Strings::format(R"(%s)" + "\n", + result.spec, + result.spec, + result.timing.as().count(), + result_string, + inner_block); + } + return xunit_doc; + } } diff --git a/toolsrc/src/vcpkg/postbuildlint.cpp b/toolsrc/src/vcpkg/postbuildlint.cpp index 0532bce58..2b427737a 100644 --- a/toolsrc/src/vcpkg/postbuildlint.cpp +++ b/toolsrc/src/vcpkg/postbuildlint.cpp @@ -479,7 +479,7 @@ namespace vcpkg::PostBuildLint } System::println(System::Color::warning, - "Mismatching number of debug and release binaries. Found %d for debug but %d for release.", + "Mismatching number of debug and release binaries. Found %zd for debug but %zd for release.", debug_count, release_count); System::println("Debug binaries"); -- cgit v1.2.3 From c9642097a8aa85c652daed2fc28e6a828688801e Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 30 Nov 2017 21:44:34 -0800 Subject: Specify VSLANG=1033 to use english locale in builds Resolves several locale-specific issues outside our control --- toolsrc/src/vcpkg/base/system.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/base/system.cpp b/toolsrc/src/vcpkg/base/system.cpp index e3d3ad292..8dd73c32f 100644 --- a/toolsrc/src/vcpkg/base/system.cpp +++ b/toolsrc/src/vcpkg/base/system.cpp @@ -202,6 +202,7 @@ namespace vcpkg::System env_cstr.append(Strings::to_utf16(NEW_PATH)); env_cstr.push_back(L'\0'); + env_cstr.append(L"VSLANG=1033\0"); STARTUPINFOW startup_info; memset(&startup_info, 0, sizeof(STARTUPINFOW)); -- cgit v1.2.3 From f174d5561af49cccbfb4d9618be123cf7ee971d6 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 30 Nov 2017 21:46:23 -0800 Subject: Exclude and warn about VS instances without English language pack Resolves several locale-specific issues outside our control --- toolsrc/src/vcpkg/vcpkgpaths.cpp | 64 ++++++++++++++++++++++++++++++---------- 1 file changed, 49 insertions(+), 15 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index d5763921e..324ca29d1 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -280,7 +280,6 @@ namespace vcpkg const std::vector& VcpkgPaths::get_available_triplets() const { return this->available_triplets.get_lazy([this]() -> std::vector { - std::vector output; for (auto&& path : this->get_filesystem().get_files_non_recursive(this->triplets)) { @@ -384,6 +383,7 @@ namespace vcpkg std::vector paths_examined; std::vector found_toolsets; + std::vector excluded_toolsets; const std::vector vs_instances = get_visual_studio_instances(paths); const bool v140_is_available = Util::find_if(vs_instances, [&](const VisualStudioInstance& vs_instance) { @@ -440,17 +440,28 @@ namespace vcpkg paths_examined.push_back(dumpbin_path); if (fs.exists(dumpbin_path)) { - found_toolsets.push_back(Toolset{ - vs_instance.root_path, dumpbin_path, vcvarsall_bat, {}, V_141, supported_architectures}); + const Toolset v141toolset = Toolset{ + vs_instance.root_path, dumpbin_path, vcvarsall_bat, {}, V_141, supported_architectures}; + + auto english_language_pack = dumpbin_path.parent_path() / "1033"; + + if (!fs.exists(english_language_pack)) + { + excluded_toolsets.push_back(v141toolset); + break; + } + + found_toolsets.push_back(v141toolset); if (v140_is_available) { - found_toolsets.push_back(Toolset{vs_instance.root_path, - dumpbin_path, - vcvarsall_bat, - {"-vcvars_ver=14.0"}, - V_140, - supported_architectures}); + const Toolset v140toolset = Toolset{vs_instance.root_path, + dumpbin_path, + vcvarsall_bat, + {"-vcvars_ver=14.0"}, + V_140, + supported_architectures}; + found_toolsets.push_back(v140toolset); } break; @@ -487,17 +498,39 @@ namespace vcpkg if (fs.exists(vs_dumpbin_exe)) { - found_toolsets.push_back({vs_instance.root_path, - vs_dumpbin_exe, - vcvarsall_bat, - {}, - major_version == "14" ? V_140 : V_120, - supported_architectures}); + const Toolset toolset = {vs_instance.root_path, + vs_dumpbin_exe, + vcvarsall_bat, + {}, + major_version == "14" ? V_140 : V_120, + supported_architectures}; + + auto english_language_pack = vs_dumpbin_exe.parent_path() / "1033"; + + if (!fs.exists(english_language_pack)) + { + excluded_toolsets.push_back(toolset); + break; + } + + found_toolsets.push_back(toolset); } } } } + if (!excluded_toolsets.empty()) + { + System::println( + System::Color::warning, + "Warning: The following VS instances are exluded because the English language pack is unavailable."); + for (const Toolset& toolset : excluded_toolsets) + { + System::println(" %s", toolset.visual_studio_root_path.u8string()); + } + System::println(System::Color::warning, "Please install the English language pack."); + } + if (found_toolsets.empty()) { System::println(System::Color::error, "Could not locate a complete toolset."); @@ -575,6 +608,7 @@ namespace vcpkg vs_root_path.generic_string()); } + Checks::check_exit(VCPKG_LINE_INFO, !candidates.empty(), "No suitable Visual Studio instances were found"); return *candidates.front(); } -- cgit v1.2.3 From 88d953a88d7061c4c49a5cb3d6323bb8f4442521 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 1 Dec 2017 05:57:47 -0800 Subject: [hotfix] Remove VSLANG=1033. It is causing a lot of Process creation failed with error code: 87 --- toolsrc/src/vcpkg/base/system.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/base/system.cpp b/toolsrc/src/vcpkg/base/system.cpp index 8dd73c32f..8684cefe2 100644 --- a/toolsrc/src/vcpkg/base/system.cpp +++ b/toolsrc/src/vcpkg/base/system.cpp @@ -202,7 +202,7 @@ namespace vcpkg::System env_cstr.append(Strings::to_utf16(NEW_PATH)); env_cstr.push_back(L'\0'); - env_cstr.append(L"VSLANG=1033\0"); + // env_cstr.append(L"VSLANG=1033\0"); STARTUPINFOW startup_info; memset(&startup_info, 0, sizeof(STARTUPINFOW)); -- cgit v1.2.3 From d3314dfd4ea773509588084febd8ce48fe1589fa Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 1 Dec 2017 06:09:56 -0800 Subject: Properly fix VSLANG=1033 --- toolsrc/src/vcpkg/base/system.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/base/system.cpp b/toolsrc/src/vcpkg/base/system.cpp index 8684cefe2..625ee6ce0 100644 --- a/toolsrc/src/vcpkg/base/system.cpp +++ b/toolsrc/src/vcpkg/base/system.cpp @@ -202,7 +202,8 @@ namespace vcpkg::System env_cstr.append(Strings::to_utf16(NEW_PATH)); env_cstr.push_back(L'\0'); - // env_cstr.append(L"VSLANG=1033\0"); + env_cstr.append(L"VSLANG=1033"); + env_cstr.push_back(L'\0'); STARTUPINFOW startup_info; memset(&startup_info, 0, sizeof(STARTUPINFOW)); -- cgit v1.2.3 From 71f8958a069208b08a4bcca207956ef8a15238ab Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Fri, 1 Dec 2017 16:08:09 -0800 Subject: [vcpkg-contact-survey] Add monthly survey prompt --- toolsrc/include/pch.h | 1 + toolsrc/include/tests.pch.h | 1 + toolsrc/include/vcpkg/base/chrono.h | 19 ++++++ toolsrc/include/vcpkg/globalstate.h | 2 + toolsrc/include/vcpkg/userconfig.h | 20 ++++++ toolsrc/src/tests.chrono.cpp | 41 +++++++++++++ toolsrc/src/vcpkg.cpp | 95 ++++++++++++----------------- toolsrc/src/vcpkg/base/chrono.cpp | 62 +++++++++++++++++++ toolsrc/src/vcpkg/commands.contact.cpp | 13 ++++ toolsrc/src/vcpkg/globalstate.cpp | 2 + toolsrc/src/vcpkg/metrics.cpp | 28 ++------- toolsrc/src/vcpkg/userconfig.cpp | 83 +++++++++++++++++++++++++ toolsrc/vcpkglib/vcpkglib.vcxproj | 2 + toolsrc/vcpkglib/vcpkglib.vcxproj.filters | 6 ++ toolsrc/vcpkgtest/vcpkgtest.vcxproj | 1 + toolsrc/vcpkgtest/vcpkgtest.vcxproj.filters | 3 + 16 files changed, 301 insertions(+), 78 deletions(-) create mode 100644 toolsrc/include/vcpkg/userconfig.h create mode 100644 toolsrc/src/tests.chrono.cpp create mode 100644 toolsrc/src/vcpkg/userconfig.cpp (limited to 'toolsrc') diff --git a/toolsrc/include/pch.h b/toolsrc/include/pch.h index 5c31fbbd1..683bef171 100644 --- a/toolsrc/include/pch.h +++ b/toolsrc/include/pch.h @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include diff --git a/toolsrc/include/tests.pch.h b/toolsrc/include/tests.pch.h index 0037af585..5c00fca4a 100644 --- a/toolsrc/include/tests.pch.h +++ b/toolsrc/include/tests.pch.h @@ -2,6 +2,7 @@ #include +#include #include #include #include diff --git a/toolsrc/include/vcpkg/base/chrono.h b/toolsrc/include/vcpkg/base/chrono.h index c791f53fa..4291115f7 100644 --- a/toolsrc/include/vcpkg/base/chrono.h +++ b/toolsrc/include/vcpkg/base/chrono.h @@ -2,6 +2,8 @@ #include #include +#include +#include namespace vcpkg::Chrono { @@ -44,4 +46,21 @@ namespace vcpkg::Chrono private: std::chrono::high_resolution_clock::time_point m_start_tick; }; + + class CTime + { + public: + static Optional get_current_date_time(); + static Optional parse(CStringView str); + + constexpr CTime() : m_tm{0} {} + explicit constexpr CTime(tm t) : m_tm{t} {} + + std::string to_string() const; + + std::chrono::system_clock::time_point to_time_point() const; + + private: + mutable tm m_tm; + }; } diff --git a/toolsrc/include/vcpkg/globalstate.h b/toolsrc/include/vcpkg/globalstate.h index 40ec7958e..360d3f43e 100644 --- a/toolsrc/include/vcpkg/globalstate.h +++ b/toolsrc/include/vcpkg/globalstate.h @@ -10,6 +10,8 @@ namespace vcpkg struct GlobalState { static Util::LockGuarded timer; + static Util::LockGuarded g_surveydate; + static std::atomic debugging; static std::atomic feature_packages; diff --git a/toolsrc/include/vcpkg/userconfig.h b/toolsrc/include/vcpkg/userconfig.h new file mode 100644 index 000000000..63b8e5481 --- /dev/null +++ b/toolsrc/include/vcpkg/userconfig.h @@ -0,0 +1,20 @@ +#pragma once + +#include +#include + +namespace vcpkg +{ + struct UserConfig + { + std::string user_id; + std::string user_time; + std::string user_mac; + + std::string last_completed_survey; + + static UserConfig try_read_data(const Files::Filesystem& fs); + + void try_write_data(Files::Filesystem& fs) const; + }; +} diff --git a/toolsrc/src/tests.chrono.cpp b/toolsrc/src/tests.chrono.cpp new file mode 100644 index 000000000..269cdca58 --- /dev/null +++ b/toolsrc/src/tests.chrono.cpp @@ -0,0 +1,41 @@ +#include "tests.pch.h" + +using namespace Microsoft::VisualStudio::CppUnitTestFramework; + +namespace Chrono = vcpkg::Chrono; + +namespace UnitTest1 +{ + class ChronoTests : public TestClass + { + TEST_METHOD(parse_time) + { + auto timestring = "1990-02-03T04:05:06.0Z"; + auto maybe_time = Chrono::CTime::parse(timestring); + + Assert::IsTrue(maybe_time.has_value()); + + Assert::AreEqual(timestring, maybe_time.get()->to_string().c_str()); + } + + TEST_METHOD(parse_time_blank) + { + auto maybe_time = Chrono::CTime::parse(""); + + Assert::IsFalse(maybe_time.has_value()); + } + + TEST_METHOD(time_difference) + { + auto maybe_time1 = Chrono::CTime::parse("1990-02-03T04:05:06.0Z"); + auto maybe_time2 = Chrono::CTime::parse("1990-02-10T04:05:06.0Z"); + + Assert::IsTrue(maybe_time1.has_value()); + Assert::IsTrue(maybe_time2.has_value()); + + auto delta = maybe_time2.get()->to_time_point() - maybe_time1.get()->to_time_point(); + + Assert::AreEqual(24 * 7, std::chrono::duration_cast(delta).count()); + } + }; +} diff --git a/toolsrc/src/vcpkg.cpp b/toolsrc/src/vcpkg.cpp index 04d44c414..094ea1dc5 100644 --- a/toolsrc/src/vcpkg.cpp +++ b/toolsrc/src/vcpkg.cpp @@ -20,11 +20,13 @@ #include #include #include +#include #include #include #include #include +#include #pragma comment(lib, "ole32") #pragma comment(lib, "shell32") @@ -110,6 +112,28 @@ static void inner(const VcpkgCmdArguments& args) if (args.command != "autocomplete") { Commands::Version::warn_if_vcpkg_version_mismatch(paths); + std::string surveydate = *GlobalState::g_surveydate.lock(); + auto maybe_surveydate = Chrono::CTime::parse(surveydate); + if (auto p_surveydate = maybe_surveydate.get()) + { + auto delta = std::chrono::system_clock::now() - p_surveydate->to_time_point(); + // 24 hours/day * 30 days/month + if (std::chrono::duration_cast(delta).count() > 24 * 30) + { + std::default_random_engine generator( + static_cast(std::chrono::system_clock::now().time_since_epoch().count())); + std::uniform_int_distribution distribution(1, 4); + + if (distribution(generator) == 1) + { + Metrics::g_metrics.lock()->track_property("surveyprompt", "true"); + System::println( + System::Color::success, + "Your feedback is important to improve Vcpkg! Please take 3 minutes to complete our survey " + "by running: vcpkg contact --survey"); + } + } + } } if (const auto command_function = find_command(Commands::get_available_commands_type_b())) @@ -148,80 +172,41 @@ static void inner(const VcpkgCmdArguments& args) static void load_config() { #if defined(_WIN32) - fs::path localappdata; - { - // Config path in AppDataLocal - wchar_t* localappdatapath = nullptr; - if (S_OK != SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, nullptr, &localappdatapath)) __fastfail(1); - localappdata = localappdatapath; - CoTaskMemFree(localappdatapath); - } - - std::string user_id, user_time, user_mac; - try - { - auto maybe_pghs = Paragraphs::get_paragraphs(Files::get_real_filesystem(), localappdata / "vcpkg" / "config"); - if (const auto p_pghs = maybe_pghs.get()) - { - const auto& pghs = *p_pghs; + auto& fs = Files::get_real_filesystem(); - std::unordered_map keys; - if (pghs.size() > 0) keys = pghs[0]; - - for (size_t x = 1; x < pghs.size(); ++x) - { - for (auto&& p : pghs[x]) - keys.insert(p); - } - - user_id = keys["User-Id"]; - user_time = keys["User-Since"]; - user_mac = keys["Mac-Hash"]; - } - } - catch (...) - { - } + auto config = UserConfig::try_read_data(fs); bool write_config = false; // config file not found, could not be read, or invalid - if (user_id.empty() || user_time.empty()) + if (config.user_id.empty() || config.user_time.empty()) { - ::vcpkg::Metrics::Metrics::init_user_information(user_id, user_time); + ::vcpkg::Metrics::Metrics::init_user_information(config.user_id, config.user_time); write_config = true; } - if (user_mac.empty()) + if (config.user_mac.empty()) { - user_mac = Metrics::get_MAC_user(); + config.user_mac = Metrics::get_MAC_user(); write_config = true; } { auto locked_metrics = Metrics::g_metrics.lock(); - locked_metrics->set_user_information(user_id, user_time); - locked_metrics->track_property("user_mac", user_mac); + locked_metrics->set_user_information(config.user_id, config.user_time); + locked_metrics->track_property("user_mac", config.user_mac); } + if (config.last_completed_survey.empty()) + { + config.last_completed_survey = config.user_time; + } + + GlobalState::g_surveydate.lock()->assign(config.last_completed_survey); + if (write_config) { - try - { - std::error_code ec; - 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" - "Mac-Hash: %s\n", - user_id, - user_time, - user_mac)); - } - catch (...) - { - } + config.try_write_data(fs); } #endif } diff --git a/toolsrc/src/vcpkg/base/chrono.cpp b/toolsrc/src/vcpkg/base/chrono.cpp index f0e450231..03c1ecce9 100644 --- a/toolsrc/src/vcpkg/base/chrono.cpp +++ b/toolsrc/src/vcpkg/base/chrono.cpp @@ -60,4 +60,66 @@ namespace vcpkg::Chrono std::string ElapsedTime::to_string() const { return format_time_userfriendly(as()); } std::string ElapsedTimer::to_string() const { return elapsed().to_string(); } + + Optional CTime::get_current_date_time() + { + CTime ret; + +#if defined(_WIN32) + struct _timeb timebuffer; + + _ftime_s(&timebuffer); + + const errno_t err = gmtime_s(&ret.m_tm, &timebuffer.time); + + if (err) + { + return nullopt; + } +#else + time_t now = {0}; + time(&now); + auto null_if_failed = gmtime_r(&now, &ret.m_tm); + if (null_if_failed == nullptr) + { + return nullopt; + } +#endif + + return ret; + } + + Optional CTime::parse(CStringView str) + { + CTime ret; + auto assigned = sscanf_s(str.c_str(), + "%d-%d-%dT%d:%d:%d.", + &ret.m_tm.tm_year, + &ret.m_tm.tm_mon, + &ret.m_tm.tm_mday, + &ret.m_tm.tm_hour, + &ret.m_tm.tm_min, + &ret.m_tm.tm_sec); + if (assigned != 6) return nullopt; + if (ret.m_tm.tm_year < 1900) return nullopt; + ret.m_tm.tm_year -= 1900; + if (ret.m_tm.tm_mon < 1) return nullopt; + ret.m_tm.tm_mon -= 1; + mktime(&ret.m_tm); + return ret; + } + + std::string CTime::to_string() const + { + std::array date; + date.fill(0); + + strftime(&date[0], date.size(), "%Y-%m-%dT%H:%M:%S.0Z", &m_tm); + return &date[0]; + } + std::chrono::system_clock::time_point CTime::to_time_point() const + { + auto t = mktime(&m_tm); + return std::chrono::system_clock::from_time_t(t); + } } diff --git a/toolsrc/src/vcpkg/commands.contact.cpp b/toolsrc/src/vcpkg/commands.contact.cpp index 07dcea80e..8063fe317 100644 --- a/toolsrc/src/vcpkg/commands.contact.cpp +++ b/toolsrc/src/vcpkg/commands.contact.cpp @@ -1,8 +1,10 @@ #include "pch.h" +#include #include #include #include +#include namespace vcpkg::Commands::Contact { @@ -28,6 +30,17 @@ namespace vcpkg::Commands::Contact if (Util::Sets::contains(parsed_args.switches, switches[0].name)) { +#if defined(_WIN32) + auto maybe_now = Chrono::CTime::get_current_date_time(); + if (auto p_now = maybe_now.get()) + { + auto& fs = Files::get_real_filesystem(); + auto config = UserConfig::try_read_data(fs); + config.last_completed_survey = p_now->to_string(); + config.try_write_data(fs); + } +#endif + System::cmd_execute("start https://aka.ms/NPS_vcpkg"); System::println("Default browser launched to https://aka.ms/NPS_vcpkg, thank you for your feedback!"); } diff --git a/toolsrc/src/vcpkg/globalstate.cpp b/toolsrc/src/vcpkg/globalstate.cpp index 149401b2c..123c77d46 100644 --- a/toolsrc/src/vcpkg/globalstate.cpp +++ b/toolsrc/src/vcpkg/globalstate.cpp @@ -5,6 +5,8 @@ namespace vcpkg { Util::LockGuarded GlobalState::timer; + Util::LockGuarded GlobalState::g_surveydate; + std::atomic GlobalState::debugging(false); std::atomic GlobalState::feature_packages(false); diff --git a/toolsrc/src/vcpkg/metrics.cpp b/toolsrc/src/vcpkg/metrics.cpp index 69160705c..a0d40e7d3 100644 --- a/toolsrc/src/vcpkg/metrics.cpp +++ b/toolsrc/src/vcpkg/metrics.cpp @@ -2,6 +2,7 @@ #include +#include #include #include #include @@ -15,32 +16,13 @@ namespace vcpkg::Metrics static std::string get_current_date_time() { - struct tm newtime; - std::array date; - date.fill(0); - -#if defined(_WIN32) - struct _timeb timebuffer; - - _ftime_s(&timebuffer); - time_t now = timebuffer.time; - const int milli = timebuffer.millitm; - - const errno_t err = gmtime_s(&newtime, &now); - - if (err) + auto maybe_time = Chrono::CTime::get_current_date_time(); + if (auto ptime = maybe_time.get()) { - return ""; + return ptime->to_string(); } -#else - time_t now; - time(&now); - gmtime_r(&now, &newtime); - const int milli = 0; -#endif - strftime(&date[0], date.size(), "%Y-%m-%dT%H:%M:%S", &newtime); - return std::string(&date[0]) + "." + std::to_string(milli) + "Z"; + return ""; } static std::string generate_random_UUID() diff --git a/toolsrc/src/vcpkg/userconfig.cpp b/toolsrc/src/vcpkg/userconfig.cpp new file mode 100644 index 000000000..d13a46f41 --- /dev/null +++ b/toolsrc/src/vcpkg/userconfig.cpp @@ -0,0 +1,83 @@ +#include "pch.h" + +#include +#include +#include +#include + +namespace +{ + static vcpkg::Lazy s_localappdata; + + static const fs::path& get_localappdata() + { + return s_localappdata.get_lazy([]() { + fs::path localappdata; + { + // Config path in AppDataLocal + wchar_t* localappdatapath = nullptr; + if (S_OK != SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, nullptr, &localappdatapath)) __fastfail(1); + localappdata = localappdatapath; + CoTaskMemFree(localappdatapath); + } + return localappdata; + }); + } +} + +namespace vcpkg +{ + UserConfig UserConfig::try_read_data(const Files::Filesystem& fs) + { + UserConfig ret; + + try + { + auto maybe_pghs = Paragraphs::get_paragraphs(fs, get_localappdata() / "vcpkg" / "config"); + if (const auto p_pghs = maybe_pghs.get()) + { + const auto& pghs = *p_pghs; + + std::unordered_map keys; + if (pghs.size() > 0) keys = pghs[0]; + + for (size_t x = 1; x < pghs.size(); ++x) + { + for (auto&& p : pghs[x]) + keys.insert(p); + } + + ret.user_id = keys["User-Id"]; + ret.user_time = keys["User-Since"]; + ret.user_mac = keys["Mac-Hash"]; + ret.last_completed_survey = keys["Survey-Completed"]; + } + } + catch (...) + { + } + + return ret; + } + + void UserConfig::try_write_data(Files::Filesystem& fs) const + { + try + { + std::error_code ec; + fs.create_directory(get_localappdata() / "vcpkg", ec); + fs.write_contents(get_localappdata() / "vcpkg" / "config", + Strings::format("User-Id: %s\n" + "User-Since: %s\n" + "Mac-Hash: %s\n" + "Survey-Completed: %s\n", + user_id, + user_time, + user_mac, + last_completed_survey)); + } + catch (...) + { + } + } +} diff --git a/toolsrc/vcpkglib/vcpkglib.vcxproj b/toolsrc/vcpkglib/vcpkglib.vcxproj index ae332e015..9a7ad6dc0 100644 --- a/toolsrc/vcpkglib/vcpkglib.vcxproj +++ b/toolsrc/vcpkglib/vcpkglib.vcxproj @@ -178,6 +178,7 @@ + @@ -240,6 +241,7 @@ + diff --git a/toolsrc/vcpkglib/vcpkglib.vcxproj.filters b/toolsrc/vcpkglib/vcpkglib.vcxproj.filters index e902bffbb..966fc7fb9 100644 --- a/toolsrc/vcpkglib/vcpkglib.vcxproj.filters +++ b/toolsrc/vcpkglib/vcpkglib.vcxproj.filters @@ -192,6 +192,9 @@ Source Files\vcpkg\base + + Source Files\vcpkg + @@ -332,5 +335,8 @@ Header Files\vcpkg + + Header Files\vcpkg + \ No newline at end of file diff --git a/toolsrc/vcpkgtest/vcpkgtest.vcxproj b/toolsrc/vcpkgtest/vcpkgtest.vcxproj index 9eafc1ada..166216c45 100644 --- a/toolsrc/vcpkgtest/vcpkgtest.vcxproj +++ b/toolsrc/vcpkgtest/vcpkgtest.vcxproj @@ -20,6 +20,7 @@ + diff --git a/toolsrc/vcpkgtest/vcpkgtest.vcxproj.filters b/toolsrc/vcpkgtest/vcpkgtest.vcxproj.filters index 2121f9782..422f9298e 100644 --- a/toolsrc/vcpkgtest/vcpkgtest.vcxproj.filters +++ b/toolsrc/vcpkgtest/vcpkgtest.vcxproj.filters @@ -42,6 +42,9 @@ Source Files + + Source Files + -- cgit v1.2.3 From d26a6b067c24e324b111849c320bdc4cf681e713 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Sun, 26 Nov 2017 02:51:31 -0800 Subject: Add `vcpkg integrate powershell` for tab completion --- toolsrc/src/vcpkg/commands.integrate.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/commands.integrate.cpp b/toolsrc/src/vcpkg/commands.integrate.cpp index 66c5eb5a9..460e99b88 100644 --- a/toolsrc/src/vcpkg/commands.integrate.cpp +++ b/toolsrc/src/vcpkg/commands.integrate.cpp @@ -324,18 +324,20 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console " vcpkg integrate install Make installed packages available user-wide. Requires admin privileges on " "first use\n" " vcpkg integrate remove Remove user-wide integration\n" - " vcpkg integrate project Generate a referencing nuget package for individual VS project use\n"; + " vcpkg integrate project Generate a referencing nuget package for individual VS project use\n" + " vcpkg integrate powershell Enable PowerShell Tab-Completion\n"; namespace Subcommand { static const std::string INSTALL = "install"; static const std::string REMOVE = "remove"; static const std::string PROJECT = "project"; + static const std::string POWERSHELL = "powershell"; } static std::vector valid_arguments(const VcpkgPaths&) { - return {Subcommand::INSTALL, Subcommand::REMOVE, Subcommand::PROJECT}; + return {Subcommand::INSTALL, Subcommand::REMOVE, Subcommand::PROJECT, Subcommand::POWERSHELL}; } const CommandStructure COMMAND_STRUCTURE = { @@ -365,6 +367,12 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console { return integrate_project(paths); } + if (args.command_arguments[0] == Subcommand::POWERSHELL) + { + System::powershell_execute("PowerShell Tab-Completion", + paths.scripts / "addPoshVcpkgToPowershellProfile.ps1"); + Checks::exit_success(VCPKG_LINE_INFO); + } #endif Checks::exit_with_message(VCPKG_LINE_INFO, "Unknown parameter %s for integrate", args.command_arguments[0]); -- cgit v1.2.3 From ca3604738687d0c95042c8b9ba6d0514d2ed66ac Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 4 Dec 2017 16:53:31 -0800 Subject: Update CHANGELOG and bump version to v0.0.100 --- toolsrc/VERSION.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/VERSION.txt b/toolsrc/VERSION.txt index 2f0f54a23..e45ea373f 100644 --- a/toolsrc/VERSION.txt +++ b/toolsrc/VERSION.txt @@ -1 +1 @@ -"0.0.99" \ No newline at end of file +"0.0.100" \ No newline at end of file -- cgit v1.2.3 From 705c8f201273e9bdad9508903d26b21f5d76f1c3 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 5 Dec 2017 18:03:36 -0800 Subject: Improve error message when failing to parse package --- toolsrc/src/vcpkg/packagespec.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/packagespec.cpp b/toolsrc/src/vcpkg/packagespec.cpp index eeb9981af..17189afcf 100644 --- a/toolsrc/src/vcpkg/packagespec.cpp +++ b/toolsrc/src/vcpkg/packagespec.cpp @@ -2,6 +2,7 @@ #include #include +#include #include using vcpkg::Parse::parse_comma_list; @@ -95,8 +96,19 @@ namespace vcpkg std::vector PackageSpec::to_package_specs(const std::vector& ports, const Triplet& triplet) { - return Util::fmap(ports, [&](const std::string s) { - return PackageSpec::from_name_and_triplet(s, triplet).value_or_exit(VCPKG_LINE_INFO); + return Util::fmap(ports, [&](const std::string& s) -> PackageSpec { + auto maybe_spec = PackageSpec::from_name_and_triplet(s, triplet); + if (auto spec = maybe_spec.get()) + { + return std::move(*spec); + } + + const PackageSpecParseResult error_type = maybe_spec.error(); + Checks::exit_with_message(VCPKG_LINE_INFO, + "Invalid package: %s\n" + "%s", + s, + vcpkg::to_string(error_type)); }); } -- cgit v1.2.3 From d540915a3aaab722e9b627ae001168be52333662 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 6 Dec 2017 14:42:17 -0800 Subject: Improve error message on invalid dependency of package --- toolsrc/include/vcpkg/packagespec.h | 4 ++++ toolsrc/src/vcpkg/dependencies.cpp | 6 +++--- toolsrc/src/vcpkg/packagespec.cpp | 27 ++++++++++++++++++++++++--- 3 files changed, 31 insertions(+), 6 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/packagespec.h b/toolsrc/include/vcpkg/packagespec.h index 0487ae6b8..071487e1a 100644 --- a/toolsrc/include/vcpkg/packagespec.h +++ b/toolsrc/include/vcpkg/packagespec.h @@ -22,6 +22,10 @@ namespace vcpkg static std::vector to_package_specs(const std::vector& ports, const Triplet& triplet); + static std::vector from_dependencies_of_port(const std::string& port, + const std::vector& dependencies, + const Triplet& triplet); + const std::string& name() const; const Triplet& triplet() const; diff --git a/toolsrc/src/vcpkg/dependencies.cpp b/toolsrc/src/vcpkg/dependencies.cpp index 6f599afd4..0a1f79834 100644 --- a/toolsrc/src/vcpkg/dependencies.cpp +++ b/toolsrc/src/vcpkg/dependencies.cpp @@ -114,19 +114,19 @@ namespace vcpkg::Dependencies { if (const auto p = this->status_paragraph.get()) { - return PackageSpec::to_package_specs(p->package.depends, triplet); + return PackageSpec::from_dependencies_of_port(p->package.spec.name(), p->package.depends, triplet); } if (const auto p = this->binary_control_file.get()) { auto deps = Util::fmap_flatten(p->features, [](const BinaryParagraph& pgh) { return pgh.depends; }); deps.insert(deps.end(), p->core_paragraph.depends.cbegin(), p->core_paragraph.depends.cend()); - return PackageSpec::to_package_specs(deps, triplet); + return PackageSpec::from_dependencies_of_port(p->core_paragraph.spec.name(), deps, triplet); } if (const auto p = this->source_paragraph.get()) { - return PackageSpec::to_package_specs(filter_dependencies(p->depends, triplet), triplet); + return PackageSpec::from_dependencies_of_port(p->name, filter_dependencies(p->depends, triplet), triplet); } Checks::exit_with_message(VCPKG_LINE_INFO, diff --git a/toolsrc/src/vcpkg/packagespec.cpp b/toolsrc/src/vcpkg/packagespec.cpp index 17189afcf..a9e072094 100644 --- a/toolsrc/src/vcpkg/packagespec.cpp +++ b/toolsrc/src/vcpkg/packagespec.cpp @@ -96,8 +96,8 @@ namespace vcpkg std::vector PackageSpec::to_package_specs(const std::vector& ports, const Triplet& triplet) { - return Util::fmap(ports, [&](const std::string& s) -> PackageSpec { - auto maybe_spec = PackageSpec::from_name_and_triplet(s, triplet); + return Util::fmap(ports, [&](const std::string& spec_as_string) -> PackageSpec { + auto maybe_spec = PackageSpec::from_name_and_triplet(spec_as_string, triplet); if (auto spec = maybe_spec.get()) { return std::move(*spec); @@ -107,7 +107,28 @@ namespace vcpkg Checks::exit_with_message(VCPKG_LINE_INFO, "Invalid package: %s\n" "%s", - s, + spec_as_string, + vcpkg::to_string(error_type)); + }); + } + + std::vector PackageSpec::from_dependencies_of_port(const std::string& port, + const std::vector& dependencies, + const Triplet& triplet) + { + return Util::fmap(dependencies, [&](const std::string& spec_as_string) -> PackageSpec { + auto maybe_spec = PackageSpec::from_name_and_triplet(spec_as_string, triplet); + if (auto spec = maybe_spec.get()) + { + return std::move(*spec); + } + + const PackageSpecParseResult error_type = maybe_spec.error(); + Checks::exit_with_message(VCPKG_LINE_INFO, + "Invalid dependency [%s] in package [%s]\n" + "%s", + spec_as_string, + port, vcpkg::to_string(error_type)); }); } -- cgit v1.2.3 From dd1c2d9d6256d345659372ae4731bc81a91ad63b Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 12 Dec 2017 18:01:12 -0800 Subject: Fix fetching dependency text --- toolsrc/src/vcpkg/vcpkgpaths.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index 324ca29d1..e64a681e2 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -92,7 +92,8 @@ namespace vcpkg tool_name, version_as_string); const fs::path script = scripts_folder / "fetchDependency.ps1"; - const std::string title = "Fetching %s version %s (No sufficient installed version was found)"; + const std::string title = Strings::format( + "Fetching %s version %s (No sufficient installed version was found)", tool_name, version_as_string); const System::PowershellParameter dependency_param("Dependency", tool_name); const std::string output = System::powershell_execute_and_capture_output(title, script, {dependency_param}); -- cgit v1.2.3 From 803347a0c545687f6e6b8b3594b52d11435491b3 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Wed, 13 Dec 2017 02:22:52 -0800 Subject: [vcpkg-upgrade] Initial commit of upgrade command. --- toolsrc/include/tests.utils.h | 16 +- toolsrc/include/vcpkg/commands.h | 6 + toolsrc/include/vcpkg/dependencies.h | 50 +++- toolsrc/include/vcpkg/paragraphs.h | 3 - toolsrc/include/vcpkg/update.h | 6 +- toolsrc/src/commands.upgrade.cpp | 79 ++++++ toolsrc/src/tests.plan.cpp | 150 +++++++++++- toolsrc/src/tests.update.cpp | 34 ++- toolsrc/src/vcpkg/commands.ci.cpp | 2 +- toolsrc/src/vcpkg/commands.cpp | 3 +- toolsrc/src/vcpkg/commands.portsdiff.cpp | 7 +- toolsrc/src/vcpkg/dependencies.cpp | 391 +++++++++++++++++++----------- toolsrc/src/vcpkg/help.cpp | 1 + toolsrc/src/vcpkg/install.cpp | 120 +-------- toolsrc/src/vcpkg/paragraphs.cpp | 12 - toolsrc/src/vcpkg/remove.cpp | 9 +- toolsrc/src/vcpkg/update.cpp | 40 +-- toolsrc/vcpkglib/vcpkglib.vcxproj | 1 + toolsrc/vcpkglib/vcpkglib.vcxproj.filters | 3 + 19 files changed, 600 insertions(+), 333 deletions(-) create mode 100644 toolsrc/src/commands.upgrade.cpp (limited to 'toolsrc') diff --git a/toolsrc/include/tests.utils.h b/toolsrc/include/tests.utils.h index 485b8c294..0c0add7ab 100644 --- a/toolsrc/include/tests.utils.h +++ b/toolsrc/include/tests.utils.h @@ -23,4 +23,18 @@ std::unique_ptr make_status_pgh(const char* name, std::unique_ptr make_status_feature_pgh(const char* name, const char* feature, const char* depends = "", - const char* triplet = "x86-windows"); \ No newline at end of file + const char* triplet = "x86-windows"); + +template +T&& unwrap(vcpkg::ExpectedT&& p) +{ + Assert::IsTrue(p.has_value()); + return std::move(*p.get()); +} + +template +T&& unwrap(vcpkg::Optional&& opt) +{ + Assert::IsTrue(opt.has_value()); + return std::move(*opt.get()); +} diff --git a/toolsrc/include/vcpkg/commands.h b/toolsrc/include/vcpkg/commands.h index 74fd80c03..b852a973e 100644 --- a/toolsrc/include/vcpkg/commands.h +++ b/toolsrc/include/vcpkg/commands.h @@ -39,6 +39,12 @@ namespace vcpkg::Commands void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); } + namespace Upgrade + { + extern const CommandStructure COMMAND_STRUCTURE; + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet); + } + namespace Edit { extern const CommandStructure COMMAND_STRUCTURE; diff --git a/toolsrc/include/vcpkg/dependencies.h b/toolsrc/include/vcpkg/dependencies.h index 5411ee166..f1249dc88 100644 --- a/toolsrc/include/vcpkg/dependencies.h +++ b/toolsrc/include/vcpkg/dependencies.h @@ -92,11 +92,11 @@ namespace vcpkg::Dependencies struct AnyAction { - AnyAction(InstallPlanAction&& iplan) : install_plan(std::move(iplan)) {} - AnyAction(RemovePlanAction&& rplan) : remove_plan(std::move(rplan)) {} + AnyAction(InstallPlanAction&& iplan) : install_action(std::move(iplan)) {} + AnyAction(RemovePlanAction&& rplan) : remove_action(std::move(rplan)) {} - Optional install_plan; - Optional remove_plan; + Optional install_action; + Optional remove_action; const PackageSpec& spec() const; }; @@ -123,22 +123,44 @@ namespace vcpkg::Dependencies struct PortFileProvider { - virtual const SourceControlFile& get_control_file(const std::string& spec) const = 0; + virtual Optional get_control_file(const std::string& src_name) const = 0; }; - struct MapPortFile : Util::ResourceBase, PortFileProvider + struct MapPortFileProvider : Util::ResourceBase, PortFileProvider { + explicit MapPortFileProvider(const std::unordered_map& map); + Optional get_control_file(const std::string& src_name) const override; + + private: const std::unordered_map& ports; - explicit MapPortFile(const std::unordered_map& map); - const SourceControlFile& get_control_file(const std::string& spec) const override; }; - struct PathsPortFile : Util::ResourceBase, PortFileProvider + struct PathsPortFileProvider : Util::ResourceBase, PortFileProvider { + explicit PathsPortFileProvider(const VcpkgPaths& paths); + Optional get_control_file(const std::string& src_name) const override; + + private: const VcpkgPaths& ports; mutable std::unordered_map cache; - explicit PathsPortFile(const VcpkgPaths& paths); - const SourceControlFile& get_control_file(const std::string& spec) const override; + }; + + struct ClusterGraph; + struct GraphPlan; + + struct PackageGraph + { + PackageGraph(const PortFileProvider& provider, const StatusParagraphs& status_db); + ~PackageGraph(); + + void install(const FeatureSpec& spec); + void upgrade(const PackageSpec& spec); + + std::vector serialize() const; + + private: + std::unique_ptr m_graph_plan; + std::unique_ptr m_graph; }; std::vector create_install_plan(const PortFileProvider& port_file_provider, @@ -155,4 +177,10 @@ namespace vcpkg::Dependencies std::vector create_feature_install_plan(const std::unordered_map& map, const std::vector& specs, const StatusParagraphs& status_db); + + std::vector create_feature_install_plan(const PortFileProvider& port_file_provider, + const std::vector& specs, + const StatusParagraphs& status_db); + + void print_plan(const std::vector& action_plan, const bool is_recursive = true); } diff --git a/toolsrc/include/vcpkg/paragraphs.h b/toolsrc/include/vcpkg/paragraphs.h index c8dbea646..e2c7f2d99 100644 --- a/toolsrc/include/vcpkg/paragraphs.h +++ b/toolsrc/include/vcpkg/paragraphs.h @@ -32,7 +32,4 @@ namespace vcpkg::Paragraphs std::vector> load_all_ports(const Files::Filesystem& fs, const fs::path& ports_dir); - - std::map load_all_port_names_and_versions(const Files::Filesystem& fs, - const fs::path& ports_dir); } diff --git a/toolsrc/include/vcpkg/update.h b/toolsrc/include/vcpkg/update.h index 7587b9eb2..b85f7b2b3 100644 --- a/toolsrc/include/vcpkg/update.h +++ b/toolsrc/include/vcpkg/update.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -16,7 +17,8 @@ namespace vcpkg::Update VersionDiff version_diff; }; - std::vector find_outdated_packages(const std::map& src_names_to_versions, + std::vector find_outdated_packages(const Dependencies::PortFileProvider& provider, const StatusParagraphs& status_db); + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); -} \ No newline at end of file +} diff --git a/toolsrc/src/commands.upgrade.cpp b/toolsrc/src/commands.upgrade.cpp new file mode 100644 index 000000000..7a3210042 --- /dev/null +++ b/toolsrc/src/commands.upgrade.cpp @@ -0,0 +1,79 @@ +#include "pch.h" + +#include +#include +#include +#include +#include +#include +#include + +namespace vcpkg::Commands::Upgrade +{ + using Install::KeepGoing; + using Install::to_keep_going; + + static const std::string OPTION_NO_DRY_RUN = "--no-dry-run"; + static const std::string OPTION_KEEP_GOING = "--keep-going"; + + static const std::array INSTALL_SWITCHES = {{ + {OPTION_NO_DRY_RUN, "Actually upgrade"}, + {OPTION_KEEP_GOING, "Continue installing packages on failure"}, + }}; + + const CommandStructure COMMAND_STRUCTURE = { + Help::create_example_string("upgrade --no-dry-run"), + 0, + 0, + {INSTALL_SWITCHES, {}}, + nullptr, + }; + + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet&) + { + // input sanitization + const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE); + + const bool no_dry_run = Util::Sets::contains(options.switches, OPTION_NO_DRY_RUN); + const KeepGoing keep_going = to_keep_going(Util::Sets::contains(options.switches, OPTION_KEEP_GOING)); + + // create the plan + StatusParagraphs status_db = database_load_check(paths); + + Dependencies::PathsPortFileProvider provider(paths); + Dependencies::PackageGraph graph(provider, status_db); + + auto outdated_packages = Update::find_outdated_packages(provider, status_db); + for (auto&& outdated_package : outdated_packages) + graph.upgrade(outdated_package.spec); + + auto plan = graph.serialize(); + + if (plan.empty()) + { + System::println("All packages are up-to-date."); + Checks::exit_success(VCPKG_LINE_INFO); + } + + Dependencies::print_plan(plan, true); + + if (!no_dry_run) + { + System::println(System::Color::warning, + "If you are sure you want to rebuild the above packages, run this command with the " + "--no-dry-run option."); + Checks::exit_fail(VCPKG_LINE_INFO); + } + + const Install::InstallSummary summary = Install::perform(plan, keep_going, paths, status_db); + + System::println("\nTotal elapsed time: %s\n", summary.total_elapsed_time); + + if (keep_going == KeepGoing::YES) + { + summary.print(); + } + + Checks::exit_success(VCPKG_LINE_INFO); + } +} diff --git a/toolsrc/src/tests.plan.cpp b/toolsrc/src/tests.plan.cpp index 122a4ffef..781588c91 100644 --- a/toolsrc/src/tests.plan.cpp +++ b/toolsrc/src/tests.plan.cpp @@ -36,7 +36,7 @@ namespace UnitTest1 std::vector vec, const Triplet& triplet = Triplet::X86_WINDOWS) { - const auto& plan = install_action->install_plan.value_or_exit(VCPKG_LINE_INFO); + const auto& plan = install_action->install_action.value_or_exit(VCPKG_LINE_INFO); const auto& feature_list = plan.feature_list; Assert::AreEqual(plan.spec.triplet().to_string().c_str(), triplet.to_string().c_str()); @@ -61,7 +61,7 @@ namespace UnitTest1 std::string pkg_name, const Triplet& triplet = Triplet::X86_WINDOWS) { - const auto& plan = remove_action->remove_plan.value_or_exit(VCPKG_LINE_INFO); + const auto& plan = remove_action->remove_action.value_or_exit(VCPKG_LINE_INFO); Assert::AreEqual(plan.spec.triplet().to_string().c_str(), triplet.to_string().c_str()); Assert::AreEqual(pkg_name.c_str(), plan.spec.name().c_str()); } @@ -98,7 +98,7 @@ namespace UnitTest1 auto spec_b = spec_map.emplace("b", "c"); auto spec_c = spec_map.emplace("c"); - Dependencies::MapPortFile map_port(spec_map.map); + Dependencies::MapPortFileProvider map_port(spec_map.map); auto install_plan = Dependencies::create_install_plan(map_port, {spec_a}, StatusParagraphs(std::move(status_paragraphs))); @@ -122,7 +122,7 @@ namespace UnitTest1 auto spec_g = spec_map.emplace("g"); auto spec_h = spec_map.emplace("h"); - Dependencies::MapPortFile map_port(spec_map.map); + Dependencies::MapPortFileProvider map_port(spec_map.map); auto install_plan = Dependencies::create_install_plan( map_port, {spec_a, spec_b, spec_c}, StatusParagraphs(std::move(status_paragraphs))); @@ -162,7 +162,7 @@ namespace UnitTest1 StatusParagraphs(std::move(status_paragraphs))); Assert::AreEqual(size_t(1), install_plan.size()); - auto p = install_plan[0].install_plan.get(); + auto p = install_plan[0].install_action.get(); Assert::IsNotNull(p); Assert::AreEqual("a", p->spec.name().c_str()); Assert::AreEqual(Dependencies::InstallPlanType::ALREADY_INSTALLED, p->plan_type); @@ -183,13 +183,13 @@ namespace UnitTest1 StatusParagraphs(std::move(status_paragraphs))); Assert::AreEqual(size_t(2), install_plan.size()); - auto p = install_plan[0].install_plan.get(); + auto p = install_plan[0].install_action.get(); Assert::IsNotNull(p); Assert::AreEqual("b", p->spec.name().c_str()); Assert::AreEqual(Dependencies::InstallPlanType::BUILD_AND_INSTALL, p->plan_type); Assert::AreEqual(Dependencies::RequestType::AUTO_SELECTED, p->request_type); - auto p2 = install_plan[1].install_plan.get(); + auto p2 = install_plan[1].install_action.get(); Assert::IsNotNull(p2); Assert::AreEqual("a", p2->spec.name().c_str()); Assert::AreEqual(Dependencies::InstallPlanType::BUILD_AND_INSTALL, p2->plan_type); @@ -215,7 +215,7 @@ namespace UnitTest1 auto spec_j = spec_map.emplace("j", "k"); auto spec_k = spec_map.emplace("k"); - Dependencies::MapPortFile map_port(spec_map.map); + Dependencies::MapPortFileProvider map_port(spec_map.map); auto install_plan = Dependencies::create_install_plan(map_port, {spec_a}, StatusParagraphs(std::move(status_paragraphs))); @@ -521,4 +521,138 @@ namespace UnitTest1 Assert::AreEqual("expat", remove_plan[2].spec.name().c_str()); } }; + + class UpgradePlanTests : public TestClass + { + TEST_METHOD(basic_upgrade_scheme) + { + std::vector> pghs; + pghs.push_back(make_status_pgh("a")); + StatusParagraphs status_db(std::move(pghs)); + + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + auto spec_a = spec_map.emplace("a"); + + Dependencies::MapPortFileProvider provider(spec_map.map); + Dependencies::PackageGraph graph(provider, status_db); + + graph.upgrade(spec_a); + + auto plan = graph.serialize(); + + Assert::AreEqual(size_t(2), plan.size()); + Assert::AreEqual("a", plan[0].spec().name().c_str()); + Assert::IsTrue(plan[0].remove_action.has_value()); + Assert::AreEqual("a", plan[1].spec().name().c_str()); + Assert::IsTrue(plan[1].install_action.has_value()); + } + + TEST_METHOD(basic_upgrade_scheme_with_recurse) + { + std::vector> pghs; + pghs.push_back(make_status_pgh("a")); + pghs.push_back(make_status_pgh("b", "a")); + StatusParagraphs status_db(std::move(pghs)); + + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + auto spec_a = spec_map.emplace("a"); + spec_map.emplace("b", "a"); + + Dependencies::MapPortFileProvider provider(spec_map.map); + Dependencies::PackageGraph graph(provider, status_db); + + graph.upgrade(spec_a); + + auto plan = graph.serialize(); + + Assert::AreEqual(size_t(4), plan.size()); + Assert::AreEqual("b", plan[0].spec().name().c_str()); + Assert::IsTrue(plan[0].remove_action.has_value()); + + Assert::AreEqual("a", plan[1].spec().name().c_str()); + Assert::IsTrue(plan[1].remove_action.has_value()); + + Assert::AreEqual("a", plan[2].spec().name().c_str()); + Assert::IsTrue(plan[2].install_action.has_value()); + + Assert::AreEqual("b", plan[3].spec().name().c_str()); + Assert::IsTrue(plan[3].install_action.has_value()); + } + + TEST_METHOD(basic_upgrade_scheme_with_bystander) + { + std::vector> pghs; + pghs.push_back(make_status_pgh("a")); + pghs.push_back(make_status_pgh("b")); + StatusParagraphs status_db(std::move(pghs)); + + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + auto spec_a = spec_map.emplace("a"); + spec_map.emplace("b", "a"); + + Dependencies::MapPortFileProvider provider(spec_map.map); + Dependencies::PackageGraph graph(provider, status_db); + + graph.upgrade(spec_a); + + auto plan = graph.serialize(); + + Assert::AreEqual(size_t(2), plan.size()); + Assert::AreEqual("a", plan[0].spec().name().c_str()); + Assert::IsTrue(plan[0].remove_action.has_value()); + Assert::AreEqual("a", plan[1].spec().name().c_str()); + Assert::IsTrue(plan[1].install_action.has_value()); + } + + TEST_METHOD(basic_upgrade_scheme_with_new_dep) + { + std::vector> pghs; + pghs.push_back(make_status_pgh("a")); + StatusParagraphs status_db(std::move(pghs)); + + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + auto spec_a = spec_map.emplace("a", "b"); + spec_map.emplace("b"); + + Dependencies::MapPortFileProvider provider(spec_map.map); + Dependencies::PackageGraph graph(provider, status_db); + + graph.upgrade(spec_a); + + auto plan = graph.serialize(); + + Assert::AreEqual(size_t(3), plan.size()); + Assert::AreEqual("a", plan[0].spec().name().c_str()); + Assert::IsTrue(plan[0].remove_action.has_value()); + Assert::AreEqual("b", plan[1].spec().name().c_str()); + Assert::IsTrue(plan[1].install_action.has_value()); + Assert::AreEqual("a", plan[2].spec().name().c_str()); + Assert::IsTrue(plan[2].install_action.has_value()); + } + + TEST_METHOD(basic_upgrade_scheme_with_features) + { + std::vector> pghs; + pghs.push_back(make_status_pgh("a")); + pghs.push_back(make_status_feature_pgh("a", "a1")); + StatusParagraphs status_db(std::move(pghs)); + + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + auto spec_a = spec_map.emplace("a", "", {{"a1", ""}}); + + Dependencies::MapPortFileProvider provider(spec_map.map); + Dependencies::PackageGraph graph(provider, status_db); + + graph.upgrade(spec_a); + + auto plan = graph.serialize(); + + Assert::AreEqual(size_t(2), plan.size()); + + Assert::AreEqual("a", plan[0].spec().name().c_str()); + Assert::IsTrue(plan[0].remove_action.has_value()); + + features_check(&plan[1], "a", {"core", "a1"}); + } + }; } diff --git a/toolsrc/src/tests.update.cpp b/toolsrc/src/tests.update.cpp index 06ae797f4..b6e487c17 100644 --- a/toolsrc/src/tests.update.cpp +++ b/toolsrc/src/tests.update.cpp @@ -9,6 +9,8 @@ using namespace vcpkg::Update; namespace UnitTest1 { + using Pgh = std::vector>; + class UpdateTests : public TestClass { TEST_METHOD(find_outdated_packages_basic) @@ -19,10 +21,12 @@ namespace UnitTest1 StatusParagraphs status_db(std::move(status_paragraphs)); - std::map port_versions; - port_versions["a"] = VersionT("0"); + std::unordered_map map; + auto scf = unwrap(SourceControlFile::parse_control_file(Pgh{{{"Source", "a"}, {"Version", "0"}}})); + map.emplace("a", std::move(*scf)); + Dependencies::MapPortFileProvider provider(map); - auto pkgs = SortedVector(Update::find_outdated_packages(port_versions, status_db), + auto pkgs = SortedVector(Update::find_outdated_packages(provider, status_db), &OutdatedPackage::compare_by_name); Assert::AreEqual(size_t(1), pkgs.size()); @@ -41,10 +45,12 @@ namespace UnitTest1 StatusParagraphs status_db(std::move(status_paragraphs)); - std::map port_versions; - port_versions["a"] = VersionT("0"); + std::unordered_map map; + auto scf = unwrap(SourceControlFile::parse_control_file(Pgh{{{"Source", "a"}, {"Version", "0"}}})); + map.emplace("a", std::move(*scf)); + Dependencies::MapPortFileProvider provider(map); - auto pkgs = SortedVector(Update::find_outdated_packages(port_versions, status_db), + auto pkgs = SortedVector(Update::find_outdated_packages(provider, status_db), &OutdatedPackage::compare_by_name); Assert::AreEqual(size_t(1), pkgs.size()); @@ -65,10 +71,12 @@ namespace UnitTest1 StatusParagraphs status_db(std::move(status_paragraphs)); - std::map port_versions; - port_versions["a"] = VersionT("0"); + std::unordered_map map; + auto scf = unwrap(SourceControlFile::parse_control_file(Pgh{{{"Source", "a"}, {"Version", "0"}}})); + map.emplace("a", std::move(*scf)); + Dependencies::MapPortFileProvider provider(map); - auto pkgs = SortedVector(Update::find_outdated_packages(port_versions, status_db), + auto pkgs = SortedVector(Update::find_outdated_packages(provider, status_db), &OutdatedPackage::compare_by_name); Assert::AreEqual(size_t(1), pkgs.size()); @@ -84,10 +92,12 @@ namespace UnitTest1 StatusParagraphs status_db(std::move(status_paragraphs)); - std::map port_versions; - port_versions["a"] = VersionT("2"); + std::unordered_map map; + auto scf = unwrap(SourceControlFile::parse_control_file(Pgh{{{"Source", "a"}, {"Version", "2"}}})); + map.emplace("a", std::move(*scf)); + Dependencies::MapPortFileProvider provider(map); - auto pkgs = SortedVector(Update::find_outdated_packages(port_versions, status_db), + auto pkgs = SortedVector(Update::find_outdated_packages(provider, status_db), &OutdatedPackage::compare_by_name); Assert::AreEqual(size_t(0), pkgs.size()); diff --git a/toolsrc/src/vcpkg/commands.ci.cpp b/toolsrc/src/vcpkg/commands.ci.cpp index f2e984bf8..1a2f9b47f 100644 --- a/toolsrc/src/vcpkg/commands.ci.cpp +++ b/toolsrc/src/vcpkg/commands.ci.cpp @@ -27,7 +27,7 @@ namespace vcpkg::Commands::CI const std::vector specs = PackageSpec::to_package_specs(ports, triplet); StatusParagraphs status_db = database_load_check(paths); - const auto& paths_port_file = Dependencies::PathsPortFile(paths); + const auto& paths_port_file = Dependencies::PathsPortFileProvider(paths); std::vector install_plan = Dependencies::create_install_plan(paths_port_file, specs, status_db); diff --git a/toolsrc/src/vcpkg/commands.cpp b/toolsrc/src/vcpkg/commands.cpp index 15b10c7ea..ccf6fa729 100644 --- a/toolsrc/src/vcpkg/commands.cpp +++ b/toolsrc/src/vcpkg/commands.cpp @@ -13,9 +13,10 @@ namespace vcpkg::Commands Span> get_available_commands_type_a() { static std::vector> t = { - PackageNameAndFunction{"install", &Install::perform_and_exit}, + {"install", &Install::perform_and_exit}, {"ci", &CI::perform_and_exit}, {"remove", &Remove::perform_and_exit}, + {"upgrade", &Upgrade::perform_and_exit}, {"build", &Build::Command::perform_and_exit}, {"env", &Env::perform_and_exit}, {"build-external", &BuildExternal::perform_and_exit}, diff --git a/toolsrc/src/vcpkg/commands.portsdiff.cpp b/toolsrc/src/vcpkg/commands.portsdiff.cpp index 6752715e4..dba04ce5b 100644 --- a/toolsrc/src/vcpkg/commands.portsdiff.cpp +++ b/toolsrc/src/vcpkg/commands.portsdiff.cpp @@ -98,8 +98,11 @@ namespace vcpkg::Commands::PortsDiff ".vcpkg-root", git_exe.u8string()); System::cmd_execute_clean(cmd); - const std::map names_and_versions = Paragraphs::load_all_port_names_and_versions( - paths.get_filesystem(), temp_checkout_path / ports_dir_name_as_string); + const auto all_ports = + Paragraphs::load_all_ports(paths.get_filesystem(), temp_checkout_path / ports_dir_name_as_string); + std::map names_and_versions; + for (auto&& port : all_ports) + names_and_versions.emplace(port->core_paragraph->name, port->core_paragraph->version); fs.remove_all(temp_checkout_path, ec); return names_and_versions; } diff --git a/toolsrc/src/vcpkg/dependencies.cpp b/toolsrc/src/vcpkg/dependencies.cpp index 0a1f79834..5148a10f5 100644 --- a/toolsrc/src/vcpkg/dependencies.cpp +++ b/toolsrc/src/vcpkg/dependencies.cpp @@ -65,26 +65,19 @@ namespace vcpkg::Dependencies struct ClusterGraph : Util::MoveOnlyBase { - explicit ClusterGraph(std::unordered_map&& ports) - : m_ports(std::move(ports)) - { - } + explicit ClusterGraph(const PortFileProvider& provider) : m_provider(provider) {} Cluster& get(const PackageSpec& spec) { auto it = m_graph.find(spec); if (it == m_graph.end()) { - // Load on-demand from m_ports - auto it_ports = m_ports.find(spec.name()); - if (it_ports != m_ports.end()) - { - auto& clust = m_graph[spec]; - clust.spec = spec; - cluster_from_scf(*it_ports->second, clust); - return clust; - } - return m_graph[spec]; + // Load on-demand from m_provider + auto maybe_scf = m_provider.get_control_file(spec.name()); + auto& clust = m_graph[spec]; + clust.spec = spec; + if (auto p_scf = maybe_scf.get()) cluster_from_scf(*p_scf, clust); + return clust; } return it->second; } @@ -107,7 +100,7 @@ namespace vcpkg::Dependencies } std::unordered_map m_graph; - std::unordered_map m_ports; + const PortFileProvider& m_provider; }; std::vector AnyParagraph::dependencies(const Triplet& triplet) const @@ -226,12 +219,12 @@ namespace vcpkg::Dependencies const PackageSpec& AnyAction::spec() const { - if (const auto p = install_plan.get()) + if (const auto p = install_action.get()) { return p->spec; } - if (const auto p = remove_plan.get()) + if (const auto p = remove_action.get()) { return p->spec; } @@ -269,21 +262,20 @@ namespace vcpkg::Dependencies return left->spec.name() < right->spec.name(); } - MapPortFile::MapPortFile(const std::unordered_map& map) : ports(map) {} + MapPortFileProvider::MapPortFileProvider(const std::unordered_map& map) : ports(map) + { + } - const SourceControlFile& MapPortFile::get_control_file(const std::string& spec) const + Optional MapPortFileProvider::get_control_file(const std::string& spec) const { auto scf = ports.find(spec); - if (scf == ports.end()) - { - Checks::exit_fail(VCPKG_LINE_INFO); - } + if (scf == ports.end()) return nullopt; return scf->second; } - PathsPortFile::PathsPortFile(const VcpkgPaths& paths) : ports(paths) {} + PathsPortFileProvider::PathsPortFileProvider(const VcpkgPaths& paths) : ports(paths) {} - const SourceControlFile& PathsPortFile::get_control_file(const std::string& spec) const + Optional PathsPortFileProvider::get_control_file(const std::string& spec) const { auto cache_it = cache.find(spec); if (cache_it != cache.end()) @@ -298,56 +290,34 @@ namespace vcpkg::Dependencies auto it = cache.emplace(spec, std::move(*scf->get())); return it.first->second; } - print_error_message(source_control_file.error()); - Checks::exit_fail(VCPKG_LINE_INFO); + return nullopt; } std::vector create_install_plan(const PortFileProvider& port_file_provider, const std::vector& specs, const StatusParagraphs& status_db) { - struct InstallAdjacencyProvider final : Graphs::AdjacencyProvider - { - const PortFileProvider& port_file_provider; - const StatusParagraphs& status_db; - const std::unordered_set& specs_as_set; + auto fspecs = Util::fmap(specs, [](const PackageSpec& spec) { return FeatureSpec(spec, ""); }); + auto plan = create_feature_install_plan(port_file_provider, fspecs, status_db); - InstallAdjacencyProvider(const PortFileProvider& port_file_provider, - const StatusParagraphs& s, - const std::unordered_set& specs_as_set) - : port_file_provider(port_file_provider), status_db(s), specs_as_set(specs_as_set) - { - } + std::vector ret; + ret.reserve(plan.size()); - std::vector adjacency_list(const InstallPlanAction& plan) const override + for (auto&& action : plan) + { + if (auto p_install = action.install_action.get()) { - if (plan.any_paragraph.status_paragraph.get()) return std::vector{}; - return plan.any_paragraph.dependencies(plan.spec.triplet()); + ret.push_back(std::move(*p_install)); } - - InstallPlanAction load_vertex_data(const PackageSpec& spec) const override + else { - const RequestType request_type = specs_as_set.find(spec) != specs_as_set.end() - ? RequestType::USER_REQUESTED - : RequestType::AUTO_SELECTED; - auto it = status_db.find_installed(spec); - if (it != status_db.end()) return InstallPlanAction{spec, {*it->get(), nullopt, nullopt}, request_type}; - return InstallPlanAction{ - spec, - {nullopt, nullopt, *port_file_provider.get_control_file(spec.name()).core_paragraph}, - request_type}; + Checks::exit_with_message(VCPKG_LINE_INFO, + "The installation plan requires feature packages support. Please re-run the " + "command with --featurepackages."); } - }; - - const std::unordered_set specs_as_set(specs.cbegin(), specs.cend()); - std::vector toposort = - Graphs::topological_sort(specs, InstallAdjacencyProvider{port_file_provider, status_db, specs_as_set}); - Util::erase_remove_if(toposort, [](const InstallPlanAction& plan) { - return plan.request_type == RequestType::AUTO_SELECTED && - plan.plan_type == InstallPlanType::ALREADY_INSTALLED; - }); + } - return toposort; + return ret; } std::vector create_remove_plan(const std::vector& specs, @@ -461,11 +431,12 @@ namespace vcpkg::Dependencies SUCCESS, }; - MarkPlusResult mark_plus(const std::string& feature, - Cluster& cluster, - ClusterGraph& pkg_to_cluster, - GraphPlan& graph_plan); - void mark_minus(Cluster& cluster, ClusterGraph& pkg_to_cluster, GraphPlan& graph_plan); + static MarkPlusResult mark_plus(const std::string& feature, + Cluster& cluster, + ClusterGraph& pkg_to_cluster, + GraphPlan& graph_plan); + + static void mark_minus(Cluster& cluster, ClusterGraph& pkg_to_cluster, GraphPlan& graph_plan); MarkPlusResult mark_plus(const std::string& feature, Cluster& cluster, ClusterGraph& graph, GraphPlan& graph_plan) { @@ -557,110 +528,80 @@ namespace vcpkg::Dependencies } } - static ClusterGraph create_feature_install_graph(const std::unordered_map& map, - const StatusParagraphs& status_db) + std::vector create_feature_install_plan(const PortFileProvider& provider, + const std::vector& specs, + const StatusParagraphs& status_db) { - std::unordered_map ptr_map; - for (auto&& p : map) - ptr_map.emplace(p.first, &p.second); - ClusterGraph graph(std::move(ptr_map)); - - auto installed_ports = get_installed_ports(status_db); - - for (auto&& status_paragraph : installed_ports) - { - Cluster& cluster = graph.get(status_paragraph->package.spec); - - cluster.transient_uninstalled = false; - - cluster.status_paragraphs.emplace_back(status_paragraph); - - auto& status_paragraph_feature = status_paragraph->package.feature; - // In this case, empty string indicates the "core" paragraph for a package. - if (status_paragraph_feature.empty()) - { - cluster.original_features.insert("core"); - } - else - { - cluster.original_features.insert(status_paragraph_feature); - } - } - - for (auto&& status_paragraph : installed_ports) - { - auto& spec = status_paragraph->package.spec; - auto& status_paragraph_feature = status_paragraph->package.feature; - auto reverse_edges = FeatureSpec::from_strings_and_triplet(status_paragraph->package.depends, - status_paragraph->package.spec.triplet()); - - for (auto&& dependency : reverse_edges) - { - auto& dep_cluster = graph.get(dependency.spec()); - - auto depends_name = dependency.feature(); - if (depends_name.empty()) depends_name = "core"; + PackageGraph pgraph(provider, status_db); + for (auto&& spec : specs) + pgraph.install(spec); - auto& target_node = dep_cluster.edges[depends_name]; - target_node.remove_edges.emplace_back(FeatureSpec{spec, status_paragraph_feature}); - } - } - return graph; + return pgraph.serialize(); } std::vector create_feature_install_plan(const std::unordered_map& map, const std::vector& specs, const StatusParagraphs& status_db) { - ClusterGraph graph = create_feature_install_graph(map, status_db); + MapPortFileProvider provider(map); + return create_feature_install_plan(provider, specs, status_db); + } - GraphPlan graph_plan; - for (auto&& spec : specs) + void PackageGraph::install(const FeatureSpec& spec) + { + Cluster& spec_cluster = m_graph->get(spec.spec()); + spec_cluster.request_type = RequestType::USER_REQUESTED; + if (spec.feature() == "*") { - Cluster& spec_cluster = graph.get(spec.spec()); - spec_cluster.request_type = RequestType::USER_REQUESTED; - if (spec.feature() == "*") + if (auto p_scf = spec_cluster.source_control_file.value_or(nullptr)) { - if (auto p_scf = spec_cluster.source_control_file.value_or(nullptr)) + for (auto&& feature : p_scf->feature_paragraphs) { - for (auto&& feature : p_scf->feature_paragraphs) - { - auto res = mark_plus(feature->name, spec_cluster, graph, graph_plan); - - Checks::check_exit(VCPKG_LINE_INFO, - res == MarkPlusResult::SUCCESS, - "Error: Unable to locate feature %s", - spec); - } - - auto res = mark_plus("core", spec_cluster, graph, graph_plan); + auto res = mark_plus(feature->name, spec_cluster, *m_graph, *m_graph_plan); Checks::check_exit( VCPKG_LINE_INFO, res == MarkPlusResult::SUCCESS, "Error: Unable to locate feature %s", spec); } - else - { - Checks::exit_with_message( - VCPKG_LINE_INFO, "Error: Unable to handle '*' because can't find CONTROL for %s", spec.spec()); - } - } - else - { - auto res = mark_plus(spec.feature(), spec_cluster, graph, graph_plan); + + auto res = mark_plus("core", spec_cluster, *m_graph, *m_graph_plan); Checks::check_exit( VCPKG_LINE_INFO, res == MarkPlusResult::SUCCESS, "Error: Unable to locate feature %s", spec); } + else + { + Checks::exit_with_message( + VCPKG_LINE_INFO, "Error: Unable to handle '*' because can't find CONTROL for %s", spec.spec()); + } + } + else + { + auto res = mark_plus(spec.feature(), spec_cluster, *m_graph, *m_graph_plan); - graph_plan.install_graph.add_vertex(ClusterPtr{&spec_cluster}); + Checks::check_exit( + VCPKG_LINE_INFO, res == MarkPlusResult::SUCCESS, "Error: Unable to locate feature %s", spec); } - Graphs::GraphAdjacencyProvider adjacency_remove_graph(graph_plan.remove_graph.adjacency_list()); - auto remove_vertex_list = graph_plan.remove_graph.vertex_list(); + m_graph_plan->install_graph.add_vertex(ClusterPtr{&spec_cluster}); + } + + void PackageGraph::upgrade(const PackageSpec& spec) + { + Cluster& spec_cluster = m_graph->get(spec); + spec_cluster.request_type = RequestType::USER_REQUESTED; + + mark_minus(spec_cluster, *m_graph, *m_graph_plan); + } + + std::vector PackageGraph::serialize() const + { + Graphs::GraphAdjacencyProvider adjacency_remove_graph(m_graph_plan->remove_graph.adjacency_list()); + auto remove_vertex_list = m_graph_plan->remove_graph.vertex_list(); auto remove_toposort = Graphs::topological_sort(remove_vertex_list, adjacency_remove_graph); - Graphs::GraphAdjacencyProvider adjacency_install_graph(graph_plan.install_graph.adjacency_list()); - auto insert_vertex_list = graph_plan.install_graph.vertex_list(); + Graphs::GraphAdjacencyProvider adjacency_install_graph( + m_graph_plan->install_graph.adjacency_list()); + auto insert_vertex_list = m_graph_plan->install_graph.vertex_list(); auto insert_toposort = Graphs::topological_sort(insert_vertex_list, adjacency_install_graph); std::vector plan; @@ -705,4 +646,162 @@ namespace vcpkg::Dependencies return plan; } + + static std::unique_ptr create_feature_install_graph(const PortFileProvider& map, + const StatusParagraphs& status_db) + { + std::unique_ptr graph = std::make_unique(map); + + auto installed_ports = get_installed_ports(status_db); + + for (auto&& status_paragraph : installed_ports) + { + Cluster& cluster = graph->get(status_paragraph->package.spec); + + cluster.transient_uninstalled = false; + + cluster.status_paragraphs.emplace_back(status_paragraph); + + auto& status_paragraph_feature = status_paragraph->package.feature; + // In this case, empty string indicates the "core" paragraph for a package. + if (status_paragraph_feature.empty()) + { + cluster.original_features.insert("core"); + } + else + { + cluster.original_features.insert(status_paragraph_feature); + } + } + + // Populate the graph with "remove edges", which are the reverse of the Build-Depends edges. + for (auto&& status_paragraph : installed_ports) + { + auto& spec = status_paragraph->package.spec; + auto& status_paragraph_feature = status_paragraph->package.feature; + auto reverse_edges = FeatureSpec::from_strings_and_triplet(status_paragraph->package.depends, + status_paragraph->package.spec.triplet()); + + for (auto&& dependency : reverse_edges) + { + auto& dep_cluster = graph->get(dependency.spec()); + + auto depends_name = dependency.feature(); + if (depends_name.empty()) depends_name = "core"; + + auto& target_node = dep_cluster.edges[depends_name]; + target_node.remove_edges.emplace_back(FeatureSpec{spec, status_paragraph_feature}); + } + } + return graph; + } + + PackageGraph::PackageGraph(const PortFileProvider& provider, const StatusParagraphs& status_db) + : m_graph(create_feature_install_graph(provider, status_db)), m_graph_plan(std::make_unique()) + { + } + + PackageGraph::~PackageGraph() {} + + void print_plan(const std::vector& action_plan, const bool is_recursive) + { + std::vector remove_plans; + std::vector rebuilt_plans; + std::vector only_install_plans; + std::vector new_plans; + std::vector already_installed_plans; + std::vector excluded; + + const bool has_non_user_requested_packages = Util::find_if(action_plan, [](const AnyAction& package) -> bool { + if (auto iplan = package.install_action.get()) + return iplan->request_type != RequestType::USER_REQUESTED; + else + return false; + }) != action_plan.cend(); + + for (auto&& action : action_plan) + { + if (auto install_action = action.install_action.get()) + { + // remove plans are guaranteed to come before install plans, so we know the plan will be contained if at + // all. + auto it = Util::find_if( + remove_plans, [&](const RemovePlanAction* plan) { return plan->spec == install_action->spec; }); + if (it != remove_plans.end()) + { + rebuilt_plans.emplace_back(install_action); + } + else + { + switch (install_action->plan_type) + { + case InstallPlanType::INSTALL: only_install_plans.emplace_back(install_action); break; + case InstallPlanType::ALREADY_INSTALLED: + if (install_action->request_type == RequestType::USER_REQUESTED) + already_installed_plans.emplace_back(install_action); + break; + case InstallPlanType::BUILD_AND_INSTALL: new_plans.emplace_back(install_action); break; + case InstallPlanType::EXCLUDED: excluded.emplace_back(install_action); break; + default: Checks::unreachable(VCPKG_LINE_INFO); + } + } + } + else if (auto remove_action = action.remove_action.get()) + { + remove_plans.emplace_back(remove_action); + } + } + + std::sort(remove_plans.begin(), remove_plans.end(), &RemovePlanAction::compare_by_name); + std::sort(rebuilt_plans.begin(), rebuilt_plans.end(), &InstallPlanAction::compare_by_name); + std::sort(only_install_plans.begin(), only_install_plans.end(), &InstallPlanAction::compare_by_name); + std::sort(new_plans.begin(), new_plans.end(), &InstallPlanAction::compare_by_name); + std::sort(already_installed_plans.begin(), already_installed_plans.end(), &InstallPlanAction::compare_by_name); + std::sort(excluded.begin(), excluded.end(), &InstallPlanAction::compare_by_name); + + static auto actions_to_output_string = [](const std::vector& v) { + return Strings::join("\n", v, [](const InstallPlanAction* p) { + return to_output_string(p->request_type, p->displayname(), p->build_options); + }); + }; + + if (excluded.size() > 0) + { + System::println("The following packages are excluded:\n%s", actions_to_output_string(excluded)); + } + + if (already_installed_plans.size() > 0) + { + System::println("The following packages are already installed:\n%s", + actions_to_output_string(already_installed_plans)); + } + + if (rebuilt_plans.size() > 0) + { + System::println("The following packages will be rebuilt:\n%s", actions_to_output_string(rebuilt_plans)); + } + + if (new_plans.size() > 0) + { + System::println("The following packages will be built and installed:\n%s", + actions_to_output_string(new_plans)); + } + + if (only_install_plans.size() > 0) + { + System::println("The following packages will be directly installed:\n%s", + actions_to_output_string(only_install_plans)); + } + + if (has_non_user_requested_packages) + System::println("Additional packages (*) will be modified to complete this operation."); + + if (remove_plans.size() > 0 && !is_recursive) + { + System::println(System::Color::warning, + "If you are sure you want to rebuild the above packages, run the command with the " + "--recurse option"); + Checks::exit_fail(VCPKG_LINE_INFO); + } + } } diff --git a/toolsrc/src/vcpkg/help.cpp b/toolsrc/src/vcpkg/help.cpp index c83f0277b..b7d355742 100644 --- a/toolsrc/src/vcpkg/help.cpp +++ b/toolsrc/src/vcpkg/help.cpp @@ -85,6 +85,7 @@ namespace vcpkg::Help " vcpkg remove --outdated Uninstall all out-of-date packages\n" " vcpkg list List installed packages\n" " vcpkg update Display list of packages for updating\n" + " vcpkg upgrade Rebuild all outdated packages\n" " vcpkg hash [alg] Hash a file by specific algorithm, default SHA512\n" " vcpkg help topics Display the list of help topics\n" " vcpkg help Display help for a specific topic\n" diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp index 76dc7a527..08cfc2e73 100644 --- a/toolsrc/src/vcpkg/install.cpp +++ b/toolsrc/src/vcpkg/install.cpp @@ -348,108 +348,6 @@ namespace vcpkg::Install Checks::unreachable(VCPKG_LINE_INFO); } - static void print_plan(const std::vector& action_plan, const bool is_recursive) - { - std::vector remove_plans; - std::vector rebuilt_plans; - std::vector only_install_plans; - std::vector new_plans; - std::vector already_installed_plans; - std::vector excluded; - - const bool has_non_user_requested_packages = Util::find_if(action_plan, [](const AnyAction& package) -> bool { - if (auto iplan = package.install_plan.get()) - return iplan->request_type != RequestType::USER_REQUESTED; - else - return false; - }) != action_plan.cend(); - - for (auto&& action : action_plan) - { - if (auto install_action = action.install_plan.get()) - { - // remove plans are guaranteed to come before install plans, so we know the plan will be contained if at - // all. - auto it = Util::find_if( - remove_plans, [&](const RemovePlanAction* plan) { return plan->spec == install_action->spec; }); - if (it != remove_plans.end()) - { - rebuilt_plans.emplace_back(install_action); - } - else - { - switch (install_action->plan_type) - { - case InstallPlanType::INSTALL: only_install_plans.emplace_back(install_action); break; - case InstallPlanType::ALREADY_INSTALLED: - if (install_action->request_type == RequestType::USER_REQUESTED) - already_installed_plans.emplace_back(install_action); - break; - case InstallPlanType::BUILD_AND_INSTALL: new_plans.emplace_back(install_action); break; - case InstallPlanType::EXCLUDED: excluded.emplace_back(install_action); break; - default: Checks::unreachable(VCPKG_LINE_INFO); - } - } - } - else if (auto remove_action = action.remove_plan.get()) - { - remove_plans.emplace_back(remove_action); - } - } - - std::sort(remove_plans.begin(), remove_plans.end(), &RemovePlanAction::compare_by_name); - std::sort(rebuilt_plans.begin(), rebuilt_plans.end(), &InstallPlanAction::compare_by_name); - std::sort(only_install_plans.begin(), only_install_plans.end(), &InstallPlanAction::compare_by_name); - std::sort(new_plans.begin(), new_plans.end(), &InstallPlanAction::compare_by_name); - std::sort(already_installed_plans.begin(), already_installed_plans.end(), &InstallPlanAction::compare_by_name); - std::sort(excluded.begin(), excluded.end(), &InstallPlanAction::compare_by_name); - - static auto actions_to_output_string = [](const std::vector& v) { - return Strings::join("\n", v, [](const InstallPlanAction* p) { - return to_output_string(p->request_type, p->displayname(), p->build_options); - }); - }; - - if (excluded.size() > 0) - { - System::println("The following packages are excluded:\n%s", actions_to_output_string(excluded)); - } - - if (already_installed_plans.size() > 0) - { - System::println("The following packages are already installed:\n%s", - actions_to_output_string(already_installed_plans)); - } - - if (rebuilt_plans.size() > 0) - { - System::println("The following packages will be rebuilt:\n%s", actions_to_output_string(rebuilt_plans)); - } - - if (new_plans.size() > 0) - { - System::println("The following packages will be built and installed:\n%s", - actions_to_output_string(new_plans)); - } - - if (only_install_plans.size() > 0) - { - System::println("The following packages will be directly installed:\n%s", - actions_to_output_string(only_install_plans)); - } - - if (has_non_user_requested_packages) - System::println("Additional packages (*) will be installed to complete this operation."); - - if (remove_plans.size() > 0 && !is_recursive) - { - System::println(System::Color::warning, - "If you are sure you want to rebuild the above packages, run the command with the " - "--recurse option"); - Checks::exit_fail(VCPKG_LINE_INFO); - } - } - void InstallSummary::print() const { System::println("RESULTS"); @@ -499,7 +397,7 @@ namespace vcpkg::Install results.emplace_back(spec, &action); - if (const auto install_action = action.install_plan.get()) + if (const auto install_action = action.install_action.get()) { auto result = perform_install_plan_action(paths, *install_action, status_db); @@ -511,7 +409,7 @@ namespace vcpkg::Install results.back().build_result = std::move(result); } - else if (const auto remove_action = action.remove_plan.get()) + else if (const auto remove_action = action.remove_action.get()) { Checks::check_exit(VCPKG_LINE_INFO, GlobalState::feature_packages); Remove::perform_remove_plan_action(paths, *remove_action, Remove::Purge::YES, status_db); @@ -690,7 +588,7 @@ namespace vcpkg::Install } else { - Dependencies::PathsPortFile paths_port_file(paths); + Dependencies::PathsPortFileProvider paths_port_file(paths); auto install_plan = Dependencies::create_install_plan( paths_port_file, Util::fmap(specs, [](auto&& spec) { return spec.package_spec; }), status_db); @@ -700,7 +598,7 @@ namespace vcpkg::Install for (auto&& action : action_plan) { - if (auto p_install = action.install_plan.get()) + if (auto p_install = action.install_action.get()) { p_install->build_options = install_plan_options; if (p_install->request_type != RequestType::USER_REQUESTED) @@ -713,16 +611,16 @@ namespace vcpkg::Install // log the plan const std::string specs_string = Strings::join(",", action_plan, [](const AnyAction& action) { - if (auto iaction = action.install_plan.get()) + if (auto iaction = action.install_action.get()) return iaction->spec.to_string(); - else if (auto raction = action.remove_plan.get()) + else if (auto raction = action.remove_action.get()) return "R$" + raction->spec.to_string(); Checks::unreachable(VCPKG_LINE_INFO); }); Metrics::g_metrics.lock()->track_property("installplan", specs_string); - print_plan(action_plan, is_recursive); + Dependencies::print_plan(action_plan, is_recursive); if (dry_run) { @@ -752,7 +650,7 @@ namespace vcpkg::Install for (auto&& result : summary.results) { if (!result.action) continue; - if (auto p_install_action = result.action->install_plan.get()) + if (auto p_install_action = result.action->install_action.get()) { if (p_install_action->request_type != RequestType::USER_REQUESTED) continue; auto bpgh = result.get_binary_paragraph(); @@ -773,7 +671,7 @@ namespace vcpkg::Install { if (build_result.binary_control_file) return &build_result.binary_control_file->core_paragraph; if (action) - if (auto p_install_plan = action->install_plan.get()) + if (auto p_install_plan = action->install_action.get()) { if (auto p_bcf = p_install_plan->any_paragraph.binary_control_file.get()) return &p_bcf->core_paragraph; diff --git a/toolsrc/src/vcpkg/paragraphs.cpp b/toolsrc/src/vcpkg/paragraphs.cpp index b93de190c..b66d53994 100644 --- a/toolsrc/src/vcpkg/paragraphs.cpp +++ b/toolsrc/src/vcpkg/paragraphs.cpp @@ -289,16 +289,4 @@ namespace vcpkg::Paragraphs } return std::move(results.paragraphs); } - - std::map load_all_port_names_and_versions(const Files::Filesystem& fs, - const fs::path& ports_dir) - { - auto all_ports = load_all_ports(fs, ports_dir); - - std::map names_and_versions; - for (auto&& port : all_ports) - names_and_versions.emplace(port->core_paragraph->name, port->core_paragraph->version); - - return names_and_versions; - } } diff --git a/toolsrc/src/vcpkg/remove.cpp b/toolsrc/src/vcpkg/remove.cpp index 8ae0bc881..4079d60c1 100644 --- a/toolsrc/src/vcpkg/remove.cpp +++ b/toolsrc/src/vcpkg/remove.cpp @@ -207,10 +207,11 @@ namespace vcpkg::Remove System::println(System::Color::error, "Error: 'remove' accepts either libraries or '--outdated'"); Checks::exit_fail(VCPKG_LINE_INFO); } - specs = Util::fmap( - Update::find_outdated_packages( - Paragraphs::load_all_port_names_and_versions(paths.get_filesystem(), paths.ports), status_db), - [](auto&& outdated) { return outdated.spec; }); + + Dependencies::PathsPortFileProvider provider(paths); + + specs = Util::fmap(Update::find_outdated_packages(provider, status_db), + [](auto&& outdated) { return outdated.spec; }); if (specs.empty()) { diff --git a/toolsrc/src/vcpkg/update.cpp b/toolsrc/src/vcpkg/update.cpp index 29baef91e..d6c5614ed 100644 --- a/toolsrc/src/vcpkg/update.cpp +++ b/toolsrc/src/vcpkg/update.cpp @@ -14,7 +14,7 @@ namespace vcpkg::Update return left.spec.name() < right.spec.name(); } - std::vector find_outdated_packages(const std::map& src_names_to_versions, + std::vector find_outdated_packages(const Dependencies::PortFileProvider& provider, const StatusParagraphs& status_db) { const std::vector installed_packages = get_installed_ports(status_db); @@ -24,19 +24,23 @@ namespace vcpkg::Update { if (!pgh->package.feature.empty()) { - // Skip feature packages; only consider master packages for needing updates. + // Skip feature paragraphs; only consider master paragraphs for needing updates. continue; } - const auto it = src_names_to_versions.find(pgh->package.spec.name()); - if (it == src_names_to_versions.end()) + auto maybe_scf = provider.get_control_file(pgh->package.spec.name()); + if (auto p_scf = maybe_scf.get()) { - // Package was not installed from portfile - continue; + auto&& port_version = p_scf->core_paragraph->version; + auto&& installed_version = pgh->package.version; + if (installed_version != port_version) + { + output.push_back({pgh->package.spec, VersionDiff(installed_version, port_version)}); + } } - if (it->second != pgh->package.version) + else { - output.push_back({pgh->package.spec, VersionDiff(pgh->package.version, it->second)}); + // No portfile available } } @@ -58,10 +62,10 @@ namespace vcpkg::Update const StatusParagraphs status_db = database_load_check(paths); - const auto outdated_packages = SortedVector( - find_outdated_packages(Paragraphs::load_all_port_names_and_versions(paths.get_filesystem(), paths.ports), - status_db), - &OutdatedPackage::compare_by_name); + Dependencies::PathsPortFileProvider provider(paths); + + const auto outdated_packages = SortedVector(find_outdated_packages(provider, status_db), + &OutdatedPackage::compare_by_name); if (outdated_packages.empty()) { @@ -69,19 +73,17 @@ namespace vcpkg::Update } else { - std::string install_line; System::println("The following packages differ from their port versions:"); for (auto&& package : outdated_packages) { - install_line += package.spec.to_string(); - install_line += " "; System::println(" %-32s %s", package.spec, package.version_diff.to_string()); } System::println("\n" - "To update these packages, run\n" - " .\\vcpkg remove --outdated\n" - " .\\vcpkg install " + - install_line); + "To update these packages and all dependencies, run\n" + " .\\vcpkg upgrade\n" + "\n" + "To only remove outdated packages, run\n" + " .\\vcpkg remove --outdated\n"); } Checks::exit_success(VCPKG_LINE_INFO); diff --git a/toolsrc/vcpkglib/vcpkglib.vcxproj b/toolsrc/vcpkglib/vcpkglib.vcxproj index 9a7ad6dc0..68345ca85 100644 --- a/toolsrc/vcpkglib/vcpkglib.vcxproj +++ b/toolsrc/vcpkglib/vcpkglib.vcxproj @@ -185,6 +185,7 @@ + Create Create diff --git a/toolsrc/vcpkglib/vcpkglib.vcxproj.filters b/toolsrc/vcpkglib/vcpkglib.vcxproj.filters index 966fc7fb9..dfbcf0c7e 100644 --- a/toolsrc/vcpkglib/vcpkglib.vcxproj.filters +++ b/toolsrc/vcpkglib/vcpkglib.vcxproj.filters @@ -195,6 +195,9 @@ Source Files\vcpkg + + Source Files\vcpkg + -- cgit v1.2.3 From d88563cd095b9aaad81d57f1c0a254d7e17cf859 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Wed, 13 Dec 2017 03:01:50 -0800 Subject: [vcpkg-upgrade] Accept list of packages to specifically upgrade. --- toolsrc/include/vcpkg/packagespec.h | 7 +++ toolsrc/src/commands.upgrade.cpp | 108 ++++++++++++++++++++++++++++++++---- toolsrc/src/vcpkg/base/checks.cpp | 9 ++- 3 files changed, 108 insertions(+), 16 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/packagespec.h b/toolsrc/include/vcpkg/packagespec.h index 071487e1a..f1119e2f3 100644 --- a/toolsrc/include/vcpkg/packagespec.h +++ b/toolsrc/include/vcpkg/packagespec.h @@ -34,6 +34,13 @@ namespace vcpkg std::string to_string() const; + bool operator<(const PackageSpec& other) const + { + if (name() < other.name()) return true; + if (name() > other.name()) return false; + return triplet() < other.triplet(); + } + private: std::string m_name; Triplet m_triplet; diff --git a/toolsrc/src/commands.upgrade.cpp b/toolsrc/src/commands.upgrade.cpp index 7a3210042..2ce04faa9 100644 --- a/toolsrc/src/commands.upgrade.cpp +++ b/toolsrc/src/commands.upgrade.cpp @@ -1,8 +1,10 @@ #include "pch.h" +#include #include #include #include +#include #include #include #include @@ -24,37 +26,121 @@ namespace vcpkg::Commands::Upgrade const CommandStructure COMMAND_STRUCTURE = { Help::create_example_string("upgrade --no-dry-run"), 0, - 0, + SIZE_MAX, {INSTALL_SWITCHES, {}}, nullptr, }; - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet&) + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) { - // input sanitization const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE); const bool no_dry_run = Util::Sets::contains(options.switches, OPTION_NO_DRY_RUN); const KeepGoing keep_going = to_keep_going(Util::Sets::contains(options.switches, OPTION_KEEP_GOING)); - // create the plan StatusParagraphs status_db = database_load_check(paths); Dependencies::PathsPortFileProvider provider(paths); Dependencies::PackageGraph graph(provider, status_db); - auto outdated_packages = Update::find_outdated_packages(provider, status_db); - for (auto&& outdated_package : outdated_packages) - graph.upgrade(outdated_package.spec); + // input sanitization + const std::vector specs = Util::fmap(args.command_arguments, [&](auto&& arg) { + return Input::check_and_get_package_spec(arg, default_triplet, COMMAND_STRUCTURE.example_text); + }); - auto plan = graph.serialize(); + for (auto&& spec : specs) + { + Input::check_triplet(spec.triplet(), paths); + } - if (plan.empty()) + if (specs.empty()) { - System::println("All packages are up-to-date."); - Checks::exit_success(VCPKG_LINE_INFO); + // If no packages specified, upgrade all outdated packages. + auto outdated_packages = Update::find_outdated_packages(provider, status_db); + + if (outdated_packages.empty()) + { + System::println("All installed packages are up-to-date with the local portfiles."); + Checks::exit_success(VCPKG_LINE_INFO); + } + + for (auto&& outdated_package : outdated_packages) + graph.upgrade(outdated_package.spec); + } + else + { + std::vector not_installed; + std::vector no_portfile; + std::vector to_upgrade; + std::vector up_to_date; + + for (auto&& spec : specs) + { + auto it = status_db.find_installed(spec); + if (it == status_db.end()) + { + not_installed.push_back(spec); + } + + auto maybe_scf = provider.get_control_file(spec.name()); + if (auto p_scf = maybe_scf.get()) + { + if (it != status_db.end()) + { + if (p_scf->core_paragraph->version != (*it)->package.version) + { + to_upgrade.push_back(spec); + } + else + { + up_to_date.push_back(spec); + } + } + } + else + { + no_portfile.push_back(spec); + } + } + + Util::sort(not_installed); + Util::sort(no_portfile); + Util::sort(up_to_date); + Util::sort(to_upgrade); + + if (!up_to_date.empty()) + { + System::println(System::Color::success, "The following packages are up-to-date:"); + System::println(Strings::join( + "", up_to_date, [](const PackageSpec& spec) { return " " + spec.to_string() + "\n"; })); + } + + if (!not_installed.empty()) + { + System::println(System::Color::error, "The following packages are not installed:"); + System::println(Strings::join( + "", not_installed, [](const PackageSpec& spec) { return " " + spec.to_string() + "\n"; })); + } + + if (!no_portfile.empty()) + { + System::println(System::Color::error, "The following packages do not have a valid portfile:"); + System::println(Strings::join( + "", no_portfile, [](const PackageSpec& spec) { return " " + spec.to_string() + "\n"; })); + } + + Checks::check_exit(VCPKG_LINE_INFO, not_installed.empty() && no_portfile.empty()); + + if (to_upgrade.empty()) Checks::exit_success(VCPKG_LINE_INFO); + + for (auto&& spec : to_upgrade) + graph.upgrade(spec); } + auto plan = graph.serialize(); + + Checks::check_exit(VCPKG_LINE_INFO, !plan.empty()); + Dependencies::print_plan(plan, true); if (!no_dry_run) diff --git a/toolsrc/src/vcpkg/base/checks.cpp b/toolsrc/src/vcpkg/base/checks.cpp index ed28d6e2b..23f2cc630 100644 --- a/toolsrc/src/vcpkg/base/checks.cpp +++ b/toolsrc/src/vcpkg/base/checks.cpp @@ -49,8 +49,7 @@ namespace vcpkg::Checks #else void register_console_ctrl_handler() {} #endif - - [[noreturn]] void unreachable(const LineInfo& line_info) + void unreachable(const LineInfo& line_info) { System::println(System::Color::error, "Error: Unreachable code was reached"); System::println(System::Color::error, line_info.to_string()); // Always print line_info here @@ -61,13 +60,13 @@ namespace vcpkg::Checks #endif } - [[noreturn]] void exit_with_code(const LineInfo& line_info, const int exit_code) + void exit_with_code(const LineInfo& line_info, const int exit_code) { Debug::println(System::Color::error, line_info.to_string()); cleanup_and_exit(exit_code); } - [[noreturn]] void exit_with_message(const LineInfo& line_info, const CStringView error_message) + void exit_with_message(const LineInfo& line_info, const CStringView error_message) { System::println(System::Color::error, error_message); exit_fail(line_info); @@ -77,7 +76,7 @@ namespace vcpkg::Checks { if (!expression) { - exit_with_message(line_info, ""); + exit_fail(line_info); } } -- cgit v1.2.3 From e6b16165e7d69feab3f4841ab702e6072199b9d4 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Wed, 13 Dec 2017 04:47:59 -0800 Subject: Revert "[vcpkg-upgrade] Accept list of packages to specifically upgrade." This reverts commit d88563cd095b9aaad81d57f1c0a254d7e17cf859. --- toolsrc/include/vcpkg/packagespec.h | 7 --- toolsrc/src/commands.upgrade.cpp | 108 ++++-------------------------------- toolsrc/src/vcpkg/base/checks.cpp | 9 +-- 3 files changed, 16 insertions(+), 108 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/packagespec.h b/toolsrc/include/vcpkg/packagespec.h index f1119e2f3..071487e1a 100644 --- a/toolsrc/include/vcpkg/packagespec.h +++ b/toolsrc/include/vcpkg/packagespec.h @@ -34,13 +34,6 @@ namespace vcpkg std::string to_string() const; - bool operator<(const PackageSpec& other) const - { - if (name() < other.name()) return true; - if (name() > other.name()) return false; - return triplet() < other.triplet(); - } - private: std::string m_name; Triplet m_triplet; diff --git a/toolsrc/src/commands.upgrade.cpp b/toolsrc/src/commands.upgrade.cpp index 2ce04faa9..7a3210042 100644 --- a/toolsrc/src/commands.upgrade.cpp +++ b/toolsrc/src/commands.upgrade.cpp @@ -1,10 +1,8 @@ #include "pch.h" -#include #include #include #include -#include #include #include #include @@ -26,121 +24,37 @@ namespace vcpkg::Commands::Upgrade const CommandStructure COMMAND_STRUCTURE = { Help::create_example_string("upgrade --no-dry-run"), 0, - SIZE_MAX, + 0, {INSTALL_SWITCHES, {}}, nullptr, }; - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet&) { + // input sanitization const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE); const bool no_dry_run = Util::Sets::contains(options.switches, OPTION_NO_DRY_RUN); const KeepGoing keep_going = to_keep_going(Util::Sets::contains(options.switches, OPTION_KEEP_GOING)); + // create the plan StatusParagraphs status_db = database_load_check(paths); Dependencies::PathsPortFileProvider provider(paths); Dependencies::PackageGraph graph(provider, status_db); - // input sanitization - const std::vector specs = Util::fmap(args.command_arguments, [&](auto&& arg) { - return Input::check_and_get_package_spec(arg, default_triplet, COMMAND_STRUCTURE.example_text); - }); + auto outdated_packages = Update::find_outdated_packages(provider, status_db); + for (auto&& outdated_package : outdated_packages) + graph.upgrade(outdated_package.spec); - for (auto&& spec : specs) - { - Input::check_triplet(spec.triplet(), paths); - } - - if (specs.empty()) - { - // If no packages specified, upgrade all outdated packages. - auto outdated_packages = Update::find_outdated_packages(provider, status_db); - - if (outdated_packages.empty()) - { - System::println("All installed packages are up-to-date with the local portfiles."); - Checks::exit_success(VCPKG_LINE_INFO); - } + auto plan = graph.serialize(); - for (auto&& outdated_package : outdated_packages) - graph.upgrade(outdated_package.spec); - } - else + if (plan.empty()) { - std::vector not_installed; - std::vector no_portfile; - std::vector to_upgrade; - std::vector up_to_date; - - for (auto&& spec : specs) - { - auto it = status_db.find_installed(spec); - if (it == status_db.end()) - { - not_installed.push_back(spec); - } - - auto maybe_scf = provider.get_control_file(spec.name()); - if (auto p_scf = maybe_scf.get()) - { - if (it != status_db.end()) - { - if (p_scf->core_paragraph->version != (*it)->package.version) - { - to_upgrade.push_back(spec); - } - else - { - up_to_date.push_back(spec); - } - } - } - else - { - no_portfile.push_back(spec); - } - } - - Util::sort(not_installed); - Util::sort(no_portfile); - Util::sort(up_to_date); - Util::sort(to_upgrade); - - if (!up_to_date.empty()) - { - System::println(System::Color::success, "The following packages are up-to-date:"); - System::println(Strings::join( - "", up_to_date, [](const PackageSpec& spec) { return " " + spec.to_string() + "\n"; })); - } - - if (!not_installed.empty()) - { - System::println(System::Color::error, "The following packages are not installed:"); - System::println(Strings::join( - "", not_installed, [](const PackageSpec& spec) { return " " + spec.to_string() + "\n"; })); - } - - if (!no_portfile.empty()) - { - System::println(System::Color::error, "The following packages do not have a valid portfile:"); - System::println(Strings::join( - "", no_portfile, [](const PackageSpec& spec) { return " " + spec.to_string() + "\n"; })); - } - - Checks::check_exit(VCPKG_LINE_INFO, not_installed.empty() && no_portfile.empty()); - - if (to_upgrade.empty()) Checks::exit_success(VCPKG_LINE_INFO); - - for (auto&& spec : to_upgrade) - graph.upgrade(spec); + System::println("All packages are up-to-date."); + Checks::exit_success(VCPKG_LINE_INFO); } - auto plan = graph.serialize(); - - Checks::check_exit(VCPKG_LINE_INFO, !plan.empty()); - Dependencies::print_plan(plan, true); if (!no_dry_run) diff --git a/toolsrc/src/vcpkg/base/checks.cpp b/toolsrc/src/vcpkg/base/checks.cpp index 23f2cc630..ed28d6e2b 100644 --- a/toolsrc/src/vcpkg/base/checks.cpp +++ b/toolsrc/src/vcpkg/base/checks.cpp @@ -49,7 +49,8 @@ namespace vcpkg::Checks #else void register_console_ctrl_handler() {} #endif - void unreachable(const LineInfo& line_info) + + [[noreturn]] void unreachable(const LineInfo& line_info) { System::println(System::Color::error, "Error: Unreachable code was reached"); System::println(System::Color::error, line_info.to_string()); // Always print line_info here @@ -60,13 +61,13 @@ namespace vcpkg::Checks #endif } - void exit_with_code(const LineInfo& line_info, const int exit_code) + [[noreturn]] void exit_with_code(const LineInfo& line_info, const int exit_code) { Debug::println(System::Color::error, line_info.to_string()); cleanup_and_exit(exit_code); } - void exit_with_message(const LineInfo& line_info, const CStringView error_message) + [[noreturn]] void exit_with_message(const LineInfo& line_info, const CStringView error_message) { System::println(System::Color::error, error_message); exit_fail(line_info); @@ -76,7 +77,7 @@ namespace vcpkg::Checks { if (!expression) { - exit_fail(line_info); + exit_with_message(line_info, ""); } } -- cgit v1.2.3 From 7a6ffdc75c6634e0df3c158e871426190511a096 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Wed, 13 Dec 2017 04:48:13 -0800 Subject: Revert "[vcpkg-upgrade] Initial commit of upgrade command." This reverts commit 803347a0c545687f6e6b8b3594b52d11435491b3. --- toolsrc/include/tests.utils.h | 16 +- toolsrc/include/vcpkg/commands.h | 6 - toolsrc/include/vcpkg/dependencies.h | 50 +--- toolsrc/include/vcpkg/paragraphs.h | 3 + toolsrc/include/vcpkg/update.h | 6 +- toolsrc/src/commands.upgrade.cpp | 79 ------ toolsrc/src/tests.plan.cpp | 150 +----------- toolsrc/src/tests.update.cpp | 34 +-- toolsrc/src/vcpkg/commands.ci.cpp | 2 +- toolsrc/src/vcpkg/commands.cpp | 3 +- toolsrc/src/vcpkg/commands.portsdiff.cpp | 7 +- toolsrc/src/vcpkg/dependencies.cpp | 391 +++++++++++------------------- toolsrc/src/vcpkg/help.cpp | 1 - toolsrc/src/vcpkg/install.cpp | 120 ++++++++- toolsrc/src/vcpkg/paragraphs.cpp | 12 + toolsrc/src/vcpkg/remove.cpp | 9 +- toolsrc/src/vcpkg/update.cpp | 40 ++- toolsrc/vcpkglib/vcpkglib.vcxproj | 1 - toolsrc/vcpkglib/vcpkglib.vcxproj.filters | 3 - 19 files changed, 333 insertions(+), 600 deletions(-) delete mode 100644 toolsrc/src/commands.upgrade.cpp (limited to 'toolsrc') diff --git a/toolsrc/include/tests.utils.h b/toolsrc/include/tests.utils.h index 0c0add7ab..485b8c294 100644 --- a/toolsrc/include/tests.utils.h +++ b/toolsrc/include/tests.utils.h @@ -23,18 +23,4 @@ std::unique_ptr make_status_pgh(const char* name, std::unique_ptr make_status_feature_pgh(const char* name, const char* feature, const char* depends = "", - const char* triplet = "x86-windows"); - -template -T&& unwrap(vcpkg::ExpectedT&& p) -{ - Assert::IsTrue(p.has_value()); - return std::move(*p.get()); -} - -template -T&& unwrap(vcpkg::Optional&& opt) -{ - Assert::IsTrue(opt.has_value()); - return std::move(*opt.get()); -} + const char* triplet = "x86-windows"); \ No newline at end of file diff --git a/toolsrc/include/vcpkg/commands.h b/toolsrc/include/vcpkg/commands.h index b852a973e..74fd80c03 100644 --- a/toolsrc/include/vcpkg/commands.h +++ b/toolsrc/include/vcpkg/commands.h @@ -39,12 +39,6 @@ namespace vcpkg::Commands void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); } - namespace Upgrade - { - extern const CommandStructure COMMAND_STRUCTURE; - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet); - } - namespace Edit { extern const CommandStructure COMMAND_STRUCTURE; diff --git a/toolsrc/include/vcpkg/dependencies.h b/toolsrc/include/vcpkg/dependencies.h index f1249dc88..5411ee166 100644 --- a/toolsrc/include/vcpkg/dependencies.h +++ b/toolsrc/include/vcpkg/dependencies.h @@ -92,11 +92,11 @@ namespace vcpkg::Dependencies struct AnyAction { - AnyAction(InstallPlanAction&& iplan) : install_action(std::move(iplan)) {} - AnyAction(RemovePlanAction&& rplan) : remove_action(std::move(rplan)) {} + AnyAction(InstallPlanAction&& iplan) : install_plan(std::move(iplan)) {} + AnyAction(RemovePlanAction&& rplan) : remove_plan(std::move(rplan)) {} - Optional install_action; - Optional remove_action; + Optional install_plan; + Optional remove_plan; const PackageSpec& spec() const; }; @@ -123,44 +123,22 @@ namespace vcpkg::Dependencies struct PortFileProvider { - virtual Optional get_control_file(const std::string& src_name) const = 0; + virtual const SourceControlFile& get_control_file(const std::string& spec) const = 0; }; - struct MapPortFileProvider : Util::ResourceBase, PortFileProvider + struct MapPortFile : Util::ResourceBase, PortFileProvider { - explicit MapPortFileProvider(const std::unordered_map& map); - Optional get_control_file(const std::string& src_name) const override; - - private: const std::unordered_map& ports; + explicit MapPortFile(const std::unordered_map& map); + const SourceControlFile& get_control_file(const std::string& spec) const override; }; - struct PathsPortFileProvider : Util::ResourceBase, PortFileProvider + struct PathsPortFile : Util::ResourceBase, PortFileProvider { - explicit PathsPortFileProvider(const VcpkgPaths& paths); - Optional get_control_file(const std::string& src_name) const override; - - private: const VcpkgPaths& ports; mutable std::unordered_map cache; - }; - - struct ClusterGraph; - struct GraphPlan; - - struct PackageGraph - { - PackageGraph(const PortFileProvider& provider, const StatusParagraphs& status_db); - ~PackageGraph(); - - void install(const FeatureSpec& spec); - void upgrade(const PackageSpec& spec); - - std::vector serialize() const; - - private: - std::unique_ptr m_graph_plan; - std::unique_ptr m_graph; + explicit PathsPortFile(const VcpkgPaths& paths); + const SourceControlFile& get_control_file(const std::string& spec) const override; }; std::vector create_install_plan(const PortFileProvider& port_file_provider, @@ -177,10 +155,4 @@ namespace vcpkg::Dependencies std::vector create_feature_install_plan(const std::unordered_map& map, const std::vector& specs, const StatusParagraphs& status_db); - - std::vector create_feature_install_plan(const PortFileProvider& port_file_provider, - const std::vector& specs, - const StatusParagraphs& status_db); - - void print_plan(const std::vector& action_plan, const bool is_recursive = true); } diff --git a/toolsrc/include/vcpkg/paragraphs.h b/toolsrc/include/vcpkg/paragraphs.h index e2c7f2d99..c8dbea646 100644 --- a/toolsrc/include/vcpkg/paragraphs.h +++ b/toolsrc/include/vcpkg/paragraphs.h @@ -32,4 +32,7 @@ namespace vcpkg::Paragraphs std::vector> load_all_ports(const Files::Filesystem& fs, const fs::path& ports_dir); + + std::map load_all_port_names_and_versions(const Files::Filesystem& fs, + const fs::path& ports_dir); } diff --git a/toolsrc/include/vcpkg/update.h b/toolsrc/include/vcpkg/update.h index b85f7b2b3..7587b9eb2 100644 --- a/toolsrc/include/vcpkg/update.h +++ b/toolsrc/include/vcpkg/update.h @@ -1,6 +1,5 @@ #pragma once -#include #include #include #include @@ -17,8 +16,7 @@ namespace vcpkg::Update VersionDiff version_diff; }; - std::vector find_outdated_packages(const Dependencies::PortFileProvider& provider, + std::vector find_outdated_packages(const std::map& src_names_to_versions, const StatusParagraphs& status_db); - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); -} +} \ No newline at end of file diff --git a/toolsrc/src/commands.upgrade.cpp b/toolsrc/src/commands.upgrade.cpp deleted file mode 100644 index 7a3210042..000000000 --- a/toolsrc/src/commands.upgrade.cpp +++ /dev/null @@ -1,79 +0,0 @@ -#include "pch.h" - -#include -#include -#include -#include -#include -#include -#include - -namespace vcpkg::Commands::Upgrade -{ - using Install::KeepGoing; - using Install::to_keep_going; - - static const std::string OPTION_NO_DRY_RUN = "--no-dry-run"; - static const std::string OPTION_KEEP_GOING = "--keep-going"; - - static const std::array INSTALL_SWITCHES = {{ - {OPTION_NO_DRY_RUN, "Actually upgrade"}, - {OPTION_KEEP_GOING, "Continue installing packages on failure"}, - }}; - - const CommandStructure COMMAND_STRUCTURE = { - Help::create_example_string("upgrade --no-dry-run"), - 0, - 0, - {INSTALL_SWITCHES, {}}, - nullptr, - }; - - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet&) - { - // input sanitization - const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE); - - const bool no_dry_run = Util::Sets::contains(options.switches, OPTION_NO_DRY_RUN); - const KeepGoing keep_going = to_keep_going(Util::Sets::contains(options.switches, OPTION_KEEP_GOING)); - - // create the plan - StatusParagraphs status_db = database_load_check(paths); - - Dependencies::PathsPortFileProvider provider(paths); - Dependencies::PackageGraph graph(provider, status_db); - - auto outdated_packages = Update::find_outdated_packages(provider, status_db); - for (auto&& outdated_package : outdated_packages) - graph.upgrade(outdated_package.spec); - - auto plan = graph.serialize(); - - if (plan.empty()) - { - System::println("All packages are up-to-date."); - Checks::exit_success(VCPKG_LINE_INFO); - } - - Dependencies::print_plan(plan, true); - - if (!no_dry_run) - { - System::println(System::Color::warning, - "If you are sure you want to rebuild the above packages, run this command with the " - "--no-dry-run option."); - Checks::exit_fail(VCPKG_LINE_INFO); - } - - const Install::InstallSummary summary = Install::perform(plan, keep_going, paths, status_db); - - System::println("\nTotal elapsed time: %s\n", summary.total_elapsed_time); - - if (keep_going == KeepGoing::YES) - { - summary.print(); - } - - Checks::exit_success(VCPKG_LINE_INFO); - } -} diff --git a/toolsrc/src/tests.plan.cpp b/toolsrc/src/tests.plan.cpp index 781588c91..122a4ffef 100644 --- a/toolsrc/src/tests.plan.cpp +++ b/toolsrc/src/tests.plan.cpp @@ -36,7 +36,7 @@ namespace UnitTest1 std::vector vec, const Triplet& triplet = Triplet::X86_WINDOWS) { - const auto& plan = install_action->install_action.value_or_exit(VCPKG_LINE_INFO); + const auto& plan = install_action->install_plan.value_or_exit(VCPKG_LINE_INFO); const auto& feature_list = plan.feature_list; Assert::AreEqual(plan.spec.triplet().to_string().c_str(), triplet.to_string().c_str()); @@ -61,7 +61,7 @@ namespace UnitTest1 std::string pkg_name, const Triplet& triplet = Triplet::X86_WINDOWS) { - const auto& plan = remove_action->remove_action.value_or_exit(VCPKG_LINE_INFO); + const auto& plan = remove_action->remove_plan.value_or_exit(VCPKG_LINE_INFO); Assert::AreEqual(plan.spec.triplet().to_string().c_str(), triplet.to_string().c_str()); Assert::AreEqual(pkg_name.c_str(), plan.spec.name().c_str()); } @@ -98,7 +98,7 @@ namespace UnitTest1 auto spec_b = spec_map.emplace("b", "c"); auto spec_c = spec_map.emplace("c"); - Dependencies::MapPortFileProvider map_port(spec_map.map); + Dependencies::MapPortFile map_port(spec_map.map); auto install_plan = Dependencies::create_install_plan(map_port, {spec_a}, StatusParagraphs(std::move(status_paragraphs))); @@ -122,7 +122,7 @@ namespace UnitTest1 auto spec_g = spec_map.emplace("g"); auto spec_h = spec_map.emplace("h"); - Dependencies::MapPortFileProvider map_port(spec_map.map); + Dependencies::MapPortFile map_port(spec_map.map); auto install_plan = Dependencies::create_install_plan( map_port, {spec_a, spec_b, spec_c}, StatusParagraphs(std::move(status_paragraphs))); @@ -162,7 +162,7 @@ namespace UnitTest1 StatusParagraphs(std::move(status_paragraphs))); Assert::AreEqual(size_t(1), install_plan.size()); - auto p = install_plan[0].install_action.get(); + auto p = install_plan[0].install_plan.get(); Assert::IsNotNull(p); Assert::AreEqual("a", p->spec.name().c_str()); Assert::AreEqual(Dependencies::InstallPlanType::ALREADY_INSTALLED, p->plan_type); @@ -183,13 +183,13 @@ namespace UnitTest1 StatusParagraphs(std::move(status_paragraphs))); Assert::AreEqual(size_t(2), install_plan.size()); - auto p = install_plan[0].install_action.get(); + auto p = install_plan[0].install_plan.get(); Assert::IsNotNull(p); Assert::AreEqual("b", p->spec.name().c_str()); Assert::AreEqual(Dependencies::InstallPlanType::BUILD_AND_INSTALL, p->plan_type); Assert::AreEqual(Dependencies::RequestType::AUTO_SELECTED, p->request_type); - auto p2 = install_plan[1].install_action.get(); + auto p2 = install_plan[1].install_plan.get(); Assert::IsNotNull(p2); Assert::AreEqual("a", p2->spec.name().c_str()); Assert::AreEqual(Dependencies::InstallPlanType::BUILD_AND_INSTALL, p2->plan_type); @@ -215,7 +215,7 @@ namespace UnitTest1 auto spec_j = spec_map.emplace("j", "k"); auto spec_k = spec_map.emplace("k"); - Dependencies::MapPortFileProvider map_port(spec_map.map); + Dependencies::MapPortFile map_port(spec_map.map); auto install_plan = Dependencies::create_install_plan(map_port, {spec_a}, StatusParagraphs(std::move(status_paragraphs))); @@ -521,138 +521,4 @@ namespace UnitTest1 Assert::AreEqual("expat", remove_plan[2].spec.name().c_str()); } }; - - class UpgradePlanTests : public TestClass - { - TEST_METHOD(basic_upgrade_scheme) - { - std::vector> pghs; - pghs.push_back(make_status_pgh("a")); - StatusParagraphs status_db(std::move(pghs)); - - PackageSpecMap spec_map(Triplet::X86_WINDOWS); - auto spec_a = spec_map.emplace("a"); - - Dependencies::MapPortFileProvider provider(spec_map.map); - Dependencies::PackageGraph graph(provider, status_db); - - graph.upgrade(spec_a); - - auto plan = graph.serialize(); - - Assert::AreEqual(size_t(2), plan.size()); - Assert::AreEqual("a", plan[0].spec().name().c_str()); - Assert::IsTrue(plan[0].remove_action.has_value()); - Assert::AreEqual("a", plan[1].spec().name().c_str()); - Assert::IsTrue(plan[1].install_action.has_value()); - } - - TEST_METHOD(basic_upgrade_scheme_with_recurse) - { - std::vector> pghs; - pghs.push_back(make_status_pgh("a")); - pghs.push_back(make_status_pgh("b", "a")); - StatusParagraphs status_db(std::move(pghs)); - - PackageSpecMap spec_map(Triplet::X86_WINDOWS); - auto spec_a = spec_map.emplace("a"); - spec_map.emplace("b", "a"); - - Dependencies::MapPortFileProvider provider(spec_map.map); - Dependencies::PackageGraph graph(provider, status_db); - - graph.upgrade(spec_a); - - auto plan = graph.serialize(); - - Assert::AreEqual(size_t(4), plan.size()); - Assert::AreEqual("b", plan[0].spec().name().c_str()); - Assert::IsTrue(plan[0].remove_action.has_value()); - - Assert::AreEqual("a", plan[1].spec().name().c_str()); - Assert::IsTrue(plan[1].remove_action.has_value()); - - Assert::AreEqual("a", plan[2].spec().name().c_str()); - Assert::IsTrue(plan[2].install_action.has_value()); - - Assert::AreEqual("b", plan[3].spec().name().c_str()); - Assert::IsTrue(plan[3].install_action.has_value()); - } - - TEST_METHOD(basic_upgrade_scheme_with_bystander) - { - std::vector> pghs; - pghs.push_back(make_status_pgh("a")); - pghs.push_back(make_status_pgh("b")); - StatusParagraphs status_db(std::move(pghs)); - - PackageSpecMap spec_map(Triplet::X86_WINDOWS); - auto spec_a = spec_map.emplace("a"); - spec_map.emplace("b", "a"); - - Dependencies::MapPortFileProvider provider(spec_map.map); - Dependencies::PackageGraph graph(provider, status_db); - - graph.upgrade(spec_a); - - auto plan = graph.serialize(); - - Assert::AreEqual(size_t(2), plan.size()); - Assert::AreEqual("a", plan[0].spec().name().c_str()); - Assert::IsTrue(plan[0].remove_action.has_value()); - Assert::AreEqual("a", plan[1].spec().name().c_str()); - Assert::IsTrue(plan[1].install_action.has_value()); - } - - TEST_METHOD(basic_upgrade_scheme_with_new_dep) - { - std::vector> pghs; - pghs.push_back(make_status_pgh("a")); - StatusParagraphs status_db(std::move(pghs)); - - PackageSpecMap spec_map(Triplet::X86_WINDOWS); - auto spec_a = spec_map.emplace("a", "b"); - spec_map.emplace("b"); - - Dependencies::MapPortFileProvider provider(spec_map.map); - Dependencies::PackageGraph graph(provider, status_db); - - graph.upgrade(spec_a); - - auto plan = graph.serialize(); - - Assert::AreEqual(size_t(3), plan.size()); - Assert::AreEqual("a", plan[0].spec().name().c_str()); - Assert::IsTrue(plan[0].remove_action.has_value()); - Assert::AreEqual("b", plan[1].spec().name().c_str()); - Assert::IsTrue(plan[1].install_action.has_value()); - Assert::AreEqual("a", plan[2].spec().name().c_str()); - Assert::IsTrue(plan[2].install_action.has_value()); - } - - TEST_METHOD(basic_upgrade_scheme_with_features) - { - std::vector> pghs; - pghs.push_back(make_status_pgh("a")); - pghs.push_back(make_status_feature_pgh("a", "a1")); - StatusParagraphs status_db(std::move(pghs)); - - PackageSpecMap spec_map(Triplet::X86_WINDOWS); - auto spec_a = spec_map.emplace("a", "", {{"a1", ""}}); - - Dependencies::MapPortFileProvider provider(spec_map.map); - Dependencies::PackageGraph graph(provider, status_db); - - graph.upgrade(spec_a); - - auto plan = graph.serialize(); - - Assert::AreEqual(size_t(2), plan.size()); - - Assert::AreEqual("a", plan[0].spec().name().c_str()); - Assert::IsTrue(plan[0].remove_action.has_value()); - - features_check(&plan[1], "a", {"core", "a1"}); - } - }; } diff --git a/toolsrc/src/tests.update.cpp b/toolsrc/src/tests.update.cpp index b6e487c17..06ae797f4 100644 --- a/toolsrc/src/tests.update.cpp +++ b/toolsrc/src/tests.update.cpp @@ -9,8 +9,6 @@ using namespace vcpkg::Update; namespace UnitTest1 { - using Pgh = std::vector>; - class UpdateTests : public TestClass { TEST_METHOD(find_outdated_packages_basic) @@ -21,12 +19,10 @@ namespace UnitTest1 StatusParagraphs status_db(std::move(status_paragraphs)); - std::unordered_map map; - auto scf = unwrap(SourceControlFile::parse_control_file(Pgh{{{"Source", "a"}, {"Version", "0"}}})); - map.emplace("a", std::move(*scf)); - Dependencies::MapPortFileProvider provider(map); + std::map port_versions; + port_versions["a"] = VersionT("0"); - auto pkgs = SortedVector(Update::find_outdated_packages(provider, status_db), + auto pkgs = SortedVector(Update::find_outdated_packages(port_versions, status_db), &OutdatedPackage::compare_by_name); Assert::AreEqual(size_t(1), pkgs.size()); @@ -45,12 +41,10 @@ namespace UnitTest1 StatusParagraphs status_db(std::move(status_paragraphs)); - std::unordered_map map; - auto scf = unwrap(SourceControlFile::parse_control_file(Pgh{{{"Source", "a"}, {"Version", "0"}}})); - map.emplace("a", std::move(*scf)); - Dependencies::MapPortFileProvider provider(map); + std::map port_versions; + port_versions["a"] = VersionT("0"); - auto pkgs = SortedVector(Update::find_outdated_packages(provider, status_db), + auto pkgs = SortedVector(Update::find_outdated_packages(port_versions, status_db), &OutdatedPackage::compare_by_name); Assert::AreEqual(size_t(1), pkgs.size()); @@ -71,12 +65,10 @@ namespace UnitTest1 StatusParagraphs status_db(std::move(status_paragraphs)); - std::unordered_map map; - auto scf = unwrap(SourceControlFile::parse_control_file(Pgh{{{"Source", "a"}, {"Version", "0"}}})); - map.emplace("a", std::move(*scf)); - Dependencies::MapPortFileProvider provider(map); + std::map port_versions; + port_versions["a"] = VersionT("0"); - auto pkgs = SortedVector(Update::find_outdated_packages(provider, status_db), + auto pkgs = SortedVector(Update::find_outdated_packages(port_versions, status_db), &OutdatedPackage::compare_by_name); Assert::AreEqual(size_t(1), pkgs.size()); @@ -92,12 +84,10 @@ namespace UnitTest1 StatusParagraphs status_db(std::move(status_paragraphs)); - std::unordered_map map; - auto scf = unwrap(SourceControlFile::parse_control_file(Pgh{{{"Source", "a"}, {"Version", "2"}}})); - map.emplace("a", std::move(*scf)); - Dependencies::MapPortFileProvider provider(map); + std::map port_versions; + port_versions["a"] = VersionT("2"); - auto pkgs = SortedVector(Update::find_outdated_packages(provider, status_db), + auto pkgs = SortedVector(Update::find_outdated_packages(port_versions, status_db), &OutdatedPackage::compare_by_name); Assert::AreEqual(size_t(0), pkgs.size()); diff --git a/toolsrc/src/vcpkg/commands.ci.cpp b/toolsrc/src/vcpkg/commands.ci.cpp index 1a2f9b47f..f2e984bf8 100644 --- a/toolsrc/src/vcpkg/commands.ci.cpp +++ b/toolsrc/src/vcpkg/commands.ci.cpp @@ -27,7 +27,7 @@ namespace vcpkg::Commands::CI const std::vector specs = PackageSpec::to_package_specs(ports, triplet); StatusParagraphs status_db = database_load_check(paths); - const auto& paths_port_file = Dependencies::PathsPortFileProvider(paths); + const auto& paths_port_file = Dependencies::PathsPortFile(paths); std::vector install_plan = Dependencies::create_install_plan(paths_port_file, specs, status_db); diff --git a/toolsrc/src/vcpkg/commands.cpp b/toolsrc/src/vcpkg/commands.cpp index ccf6fa729..15b10c7ea 100644 --- a/toolsrc/src/vcpkg/commands.cpp +++ b/toolsrc/src/vcpkg/commands.cpp @@ -13,10 +13,9 @@ namespace vcpkg::Commands Span> get_available_commands_type_a() { static std::vector> t = { - {"install", &Install::perform_and_exit}, + PackageNameAndFunction{"install", &Install::perform_and_exit}, {"ci", &CI::perform_and_exit}, {"remove", &Remove::perform_and_exit}, - {"upgrade", &Upgrade::perform_and_exit}, {"build", &Build::Command::perform_and_exit}, {"env", &Env::perform_and_exit}, {"build-external", &BuildExternal::perform_and_exit}, diff --git a/toolsrc/src/vcpkg/commands.portsdiff.cpp b/toolsrc/src/vcpkg/commands.portsdiff.cpp index dba04ce5b..6752715e4 100644 --- a/toolsrc/src/vcpkg/commands.portsdiff.cpp +++ b/toolsrc/src/vcpkg/commands.portsdiff.cpp @@ -98,11 +98,8 @@ namespace vcpkg::Commands::PortsDiff ".vcpkg-root", git_exe.u8string()); System::cmd_execute_clean(cmd); - const auto all_ports = - Paragraphs::load_all_ports(paths.get_filesystem(), temp_checkout_path / ports_dir_name_as_string); - std::map names_and_versions; - for (auto&& port : all_ports) - names_and_versions.emplace(port->core_paragraph->name, port->core_paragraph->version); + const std::map names_and_versions = Paragraphs::load_all_port_names_and_versions( + paths.get_filesystem(), temp_checkout_path / ports_dir_name_as_string); fs.remove_all(temp_checkout_path, ec); return names_and_versions; } diff --git a/toolsrc/src/vcpkg/dependencies.cpp b/toolsrc/src/vcpkg/dependencies.cpp index 5148a10f5..0a1f79834 100644 --- a/toolsrc/src/vcpkg/dependencies.cpp +++ b/toolsrc/src/vcpkg/dependencies.cpp @@ -65,19 +65,26 @@ namespace vcpkg::Dependencies struct ClusterGraph : Util::MoveOnlyBase { - explicit ClusterGraph(const PortFileProvider& provider) : m_provider(provider) {} + explicit ClusterGraph(std::unordered_map&& ports) + : m_ports(std::move(ports)) + { + } Cluster& get(const PackageSpec& spec) { auto it = m_graph.find(spec); if (it == m_graph.end()) { - // Load on-demand from m_provider - auto maybe_scf = m_provider.get_control_file(spec.name()); - auto& clust = m_graph[spec]; - clust.spec = spec; - if (auto p_scf = maybe_scf.get()) cluster_from_scf(*p_scf, clust); - return clust; + // Load on-demand from m_ports + auto it_ports = m_ports.find(spec.name()); + if (it_ports != m_ports.end()) + { + auto& clust = m_graph[spec]; + clust.spec = spec; + cluster_from_scf(*it_ports->second, clust); + return clust; + } + return m_graph[spec]; } return it->second; } @@ -100,7 +107,7 @@ namespace vcpkg::Dependencies } std::unordered_map m_graph; - const PortFileProvider& m_provider; + std::unordered_map m_ports; }; std::vector AnyParagraph::dependencies(const Triplet& triplet) const @@ -219,12 +226,12 @@ namespace vcpkg::Dependencies const PackageSpec& AnyAction::spec() const { - if (const auto p = install_action.get()) + if (const auto p = install_plan.get()) { return p->spec; } - if (const auto p = remove_action.get()) + if (const auto p = remove_plan.get()) { return p->spec; } @@ -262,20 +269,21 @@ namespace vcpkg::Dependencies return left->spec.name() < right->spec.name(); } - MapPortFileProvider::MapPortFileProvider(const std::unordered_map& map) : ports(map) - { - } + MapPortFile::MapPortFile(const std::unordered_map& map) : ports(map) {} - Optional MapPortFileProvider::get_control_file(const std::string& spec) const + const SourceControlFile& MapPortFile::get_control_file(const std::string& spec) const { auto scf = ports.find(spec); - if (scf == ports.end()) return nullopt; + if (scf == ports.end()) + { + Checks::exit_fail(VCPKG_LINE_INFO); + } return scf->second; } - PathsPortFileProvider::PathsPortFileProvider(const VcpkgPaths& paths) : ports(paths) {} + PathsPortFile::PathsPortFile(const VcpkgPaths& paths) : ports(paths) {} - Optional PathsPortFileProvider::get_control_file(const std::string& spec) const + const SourceControlFile& PathsPortFile::get_control_file(const std::string& spec) const { auto cache_it = cache.find(spec); if (cache_it != cache.end()) @@ -290,34 +298,56 @@ namespace vcpkg::Dependencies auto it = cache.emplace(spec, std::move(*scf->get())); return it.first->second; } - return nullopt; + print_error_message(source_control_file.error()); + Checks::exit_fail(VCPKG_LINE_INFO); } std::vector create_install_plan(const PortFileProvider& port_file_provider, const std::vector& specs, const StatusParagraphs& status_db) { - auto fspecs = Util::fmap(specs, [](const PackageSpec& spec) { return FeatureSpec(spec, ""); }); - auto plan = create_feature_install_plan(port_file_provider, fspecs, status_db); + struct InstallAdjacencyProvider final : Graphs::AdjacencyProvider + { + const PortFileProvider& port_file_provider; + const StatusParagraphs& status_db; + const std::unordered_set& specs_as_set; - std::vector ret; - ret.reserve(plan.size()); + InstallAdjacencyProvider(const PortFileProvider& port_file_provider, + const StatusParagraphs& s, + const std::unordered_set& specs_as_set) + : port_file_provider(port_file_provider), status_db(s), specs_as_set(specs_as_set) + { + } - for (auto&& action : plan) - { - if (auto p_install = action.install_action.get()) + std::vector adjacency_list(const InstallPlanAction& plan) const override { - ret.push_back(std::move(*p_install)); + if (plan.any_paragraph.status_paragraph.get()) return std::vector{}; + return plan.any_paragraph.dependencies(plan.spec.triplet()); } - else + + InstallPlanAction load_vertex_data(const PackageSpec& spec) const override { - Checks::exit_with_message(VCPKG_LINE_INFO, - "The installation plan requires feature packages support. Please re-run the " - "command with --featurepackages."); + const RequestType request_type = specs_as_set.find(spec) != specs_as_set.end() + ? RequestType::USER_REQUESTED + : RequestType::AUTO_SELECTED; + auto it = status_db.find_installed(spec); + if (it != status_db.end()) return InstallPlanAction{spec, {*it->get(), nullopt, nullopt}, request_type}; + return InstallPlanAction{ + spec, + {nullopt, nullopt, *port_file_provider.get_control_file(spec.name()).core_paragraph}, + request_type}; } - } + }; - return ret; + const std::unordered_set specs_as_set(specs.cbegin(), specs.cend()); + std::vector toposort = + Graphs::topological_sort(specs, InstallAdjacencyProvider{port_file_provider, status_db, specs_as_set}); + Util::erase_remove_if(toposort, [](const InstallPlanAction& plan) { + return plan.request_type == RequestType::AUTO_SELECTED && + plan.plan_type == InstallPlanType::ALREADY_INSTALLED; + }); + + return toposort; } std::vector create_remove_plan(const std::vector& specs, @@ -431,12 +461,11 @@ namespace vcpkg::Dependencies SUCCESS, }; - static MarkPlusResult mark_plus(const std::string& feature, - Cluster& cluster, - ClusterGraph& pkg_to_cluster, - GraphPlan& graph_plan); - - static void mark_minus(Cluster& cluster, ClusterGraph& pkg_to_cluster, GraphPlan& graph_plan); + MarkPlusResult mark_plus(const std::string& feature, + Cluster& cluster, + ClusterGraph& pkg_to_cluster, + GraphPlan& graph_plan); + void mark_minus(Cluster& cluster, ClusterGraph& pkg_to_cluster, GraphPlan& graph_plan); MarkPlusResult mark_plus(const std::string& feature, Cluster& cluster, ClusterGraph& graph, GraphPlan& graph_plan) { @@ -528,80 +557,110 @@ namespace vcpkg::Dependencies } } - std::vector create_feature_install_plan(const PortFileProvider& provider, - const std::vector& specs, - const StatusParagraphs& status_db) + static ClusterGraph create_feature_install_graph(const std::unordered_map& map, + const StatusParagraphs& status_db) { - PackageGraph pgraph(provider, status_db); - for (auto&& spec : specs) - pgraph.install(spec); + std::unordered_map ptr_map; + for (auto&& p : map) + ptr_map.emplace(p.first, &p.second); + ClusterGraph graph(std::move(ptr_map)); + + auto installed_ports = get_installed_ports(status_db); - return pgraph.serialize(); + for (auto&& status_paragraph : installed_ports) + { + Cluster& cluster = graph.get(status_paragraph->package.spec); + + cluster.transient_uninstalled = false; + + cluster.status_paragraphs.emplace_back(status_paragraph); + + auto& status_paragraph_feature = status_paragraph->package.feature; + // In this case, empty string indicates the "core" paragraph for a package. + if (status_paragraph_feature.empty()) + { + cluster.original_features.insert("core"); + } + else + { + cluster.original_features.insert(status_paragraph_feature); + } + } + + for (auto&& status_paragraph : installed_ports) + { + auto& spec = status_paragraph->package.spec; + auto& status_paragraph_feature = status_paragraph->package.feature; + auto reverse_edges = FeatureSpec::from_strings_and_triplet(status_paragraph->package.depends, + status_paragraph->package.spec.triplet()); + + for (auto&& dependency : reverse_edges) + { + auto& dep_cluster = graph.get(dependency.spec()); + + auto depends_name = dependency.feature(); + if (depends_name.empty()) depends_name = "core"; + + auto& target_node = dep_cluster.edges[depends_name]; + target_node.remove_edges.emplace_back(FeatureSpec{spec, status_paragraph_feature}); + } + } + return graph; } std::vector create_feature_install_plan(const std::unordered_map& map, const std::vector& specs, const StatusParagraphs& status_db) { - MapPortFileProvider provider(map); - return create_feature_install_plan(provider, specs, status_db); - } + ClusterGraph graph = create_feature_install_graph(map, status_db); - void PackageGraph::install(const FeatureSpec& spec) - { - Cluster& spec_cluster = m_graph->get(spec.spec()); - spec_cluster.request_type = RequestType::USER_REQUESTED; - if (spec.feature() == "*") + GraphPlan graph_plan; + for (auto&& spec : specs) { - if (auto p_scf = spec_cluster.source_control_file.value_or(nullptr)) + Cluster& spec_cluster = graph.get(spec.spec()); + spec_cluster.request_type = RequestType::USER_REQUESTED; + if (spec.feature() == "*") { - for (auto&& feature : p_scf->feature_paragraphs) + if (auto p_scf = spec_cluster.source_control_file.value_or(nullptr)) { - auto res = mark_plus(feature->name, spec_cluster, *m_graph, *m_graph_plan); + for (auto&& feature : p_scf->feature_paragraphs) + { + auto res = mark_plus(feature->name, spec_cluster, graph, graph_plan); + + Checks::check_exit(VCPKG_LINE_INFO, + res == MarkPlusResult::SUCCESS, + "Error: Unable to locate feature %s", + spec); + } + + auto res = mark_plus("core", spec_cluster, graph, graph_plan); Checks::check_exit( VCPKG_LINE_INFO, res == MarkPlusResult::SUCCESS, "Error: Unable to locate feature %s", spec); } - - auto res = mark_plus("core", spec_cluster, *m_graph, *m_graph_plan); - - Checks::check_exit( - VCPKG_LINE_INFO, res == MarkPlusResult::SUCCESS, "Error: Unable to locate feature %s", spec); + else + { + Checks::exit_with_message( + VCPKG_LINE_INFO, "Error: Unable to handle '*' because can't find CONTROL for %s", spec.spec()); + } } else { - Checks::exit_with_message( - VCPKG_LINE_INFO, "Error: Unable to handle '*' because can't find CONTROL for %s", spec.spec()); + auto res = mark_plus(spec.feature(), spec_cluster, graph, graph_plan); + + Checks::check_exit( + VCPKG_LINE_INFO, res == MarkPlusResult::SUCCESS, "Error: Unable to locate feature %s", spec); } - } - else - { - auto res = mark_plus(spec.feature(), spec_cluster, *m_graph, *m_graph_plan); - Checks::check_exit( - VCPKG_LINE_INFO, res == MarkPlusResult::SUCCESS, "Error: Unable to locate feature %s", spec); + graph_plan.install_graph.add_vertex(ClusterPtr{&spec_cluster}); } - m_graph_plan->install_graph.add_vertex(ClusterPtr{&spec_cluster}); - } - - void PackageGraph::upgrade(const PackageSpec& spec) - { - Cluster& spec_cluster = m_graph->get(spec); - spec_cluster.request_type = RequestType::USER_REQUESTED; - - mark_minus(spec_cluster, *m_graph, *m_graph_plan); - } - - std::vector PackageGraph::serialize() const - { - Graphs::GraphAdjacencyProvider adjacency_remove_graph(m_graph_plan->remove_graph.adjacency_list()); - auto remove_vertex_list = m_graph_plan->remove_graph.vertex_list(); + Graphs::GraphAdjacencyProvider adjacency_remove_graph(graph_plan.remove_graph.adjacency_list()); + auto remove_vertex_list = graph_plan.remove_graph.vertex_list(); auto remove_toposort = Graphs::topological_sort(remove_vertex_list, adjacency_remove_graph); - Graphs::GraphAdjacencyProvider adjacency_install_graph( - m_graph_plan->install_graph.adjacency_list()); - auto insert_vertex_list = m_graph_plan->install_graph.vertex_list(); + Graphs::GraphAdjacencyProvider adjacency_install_graph(graph_plan.install_graph.adjacency_list()); + auto insert_vertex_list = graph_plan.install_graph.vertex_list(); auto insert_toposort = Graphs::topological_sort(insert_vertex_list, adjacency_install_graph); std::vector plan; @@ -646,162 +705,4 @@ namespace vcpkg::Dependencies return plan; } - - static std::unique_ptr create_feature_install_graph(const PortFileProvider& map, - const StatusParagraphs& status_db) - { - std::unique_ptr graph = std::make_unique(map); - - auto installed_ports = get_installed_ports(status_db); - - for (auto&& status_paragraph : installed_ports) - { - Cluster& cluster = graph->get(status_paragraph->package.spec); - - cluster.transient_uninstalled = false; - - cluster.status_paragraphs.emplace_back(status_paragraph); - - auto& status_paragraph_feature = status_paragraph->package.feature; - // In this case, empty string indicates the "core" paragraph for a package. - if (status_paragraph_feature.empty()) - { - cluster.original_features.insert("core"); - } - else - { - cluster.original_features.insert(status_paragraph_feature); - } - } - - // Populate the graph with "remove edges", which are the reverse of the Build-Depends edges. - for (auto&& status_paragraph : installed_ports) - { - auto& spec = status_paragraph->package.spec; - auto& status_paragraph_feature = status_paragraph->package.feature; - auto reverse_edges = FeatureSpec::from_strings_and_triplet(status_paragraph->package.depends, - status_paragraph->package.spec.triplet()); - - for (auto&& dependency : reverse_edges) - { - auto& dep_cluster = graph->get(dependency.spec()); - - auto depends_name = dependency.feature(); - if (depends_name.empty()) depends_name = "core"; - - auto& target_node = dep_cluster.edges[depends_name]; - target_node.remove_edges.emplace_back(FeatureSpec{spec, status_paragraph_feature}); - } - } - return graph; - } - - PackageGraph::PackageGraph(const PortFileProvider& provider, const StatusParagraphs& status_db) - : m_graph(create_feature_install_graph(provider, status_db)), m_graph_plan(std::make_unique()) - { - } - - PackageGraph::~PackageGraph() {} - - void print_plan(const std::vector& action_plan, const bool is_recursive) - { - std::vector remove_plans; - std::vector rebuilt_plans; - std::vector only_install_plans; - std::vector new_plans; - std::vector already_installed_plans; - std::vector excluded; - - const bool has_non_user_requested_packages = Util::find_if(action_plan, [](const AnyAction& package) -> bool { - if (auto iplan = package.install_action.get()) - return iplan->request_type != RequestType::USER_REQUESTED; - else - return false; - }) != action_plan.cend(); - - for (auto&& action : action_plan) - { - if (auto install_action = action.install_action.get()) - { - // remove plans are guaranteed to come before install plans, so we know the plan will be contained if at - // all. - auto it = Util::find_if( - remove_plans, [&](const RemovePlanAction* plan) { return plan->spec == install_action->spec; }); - if (it != remove_plans.end()) - { - rebuilt_plans.emplace_back(install_action); - } - else - { - switch (install_action->plan_type) - { - case InstallPlanType::INSTALL: only_install_plans.emplace_back(install_action); break; - case InstallPlanType::ALREADY_INSTALLED: - if (install_action->request_type == RequestType::USER_REQUESTED) - already_installed_plans.emplace_back(install_action); - break; - case InstallPlanType::BUILD_AND_INSTALL: new_plans.emplace_back(install_action); break; - case InstallPlanType::EXCLUDED: excluded.emplace_back(install_action); break; - default: Checks::unreachable(VCPKG_LINE_INFO); - } - } - } - else if (auto remove_action = action.remove_action.get()) - { - remove_plans.emplace_back(remove_action); - } - } - - std::sort(remove_plans.begin(), remove_plans.end(), &RemovePlanAction::compare_by_name); - std::sort(rebuilt_plans.begin(), rebuilt_plans.end(), &InstallPlanAction::compare_by_name); - std::sort(only_install_plans.begin(), only_install_plans.end(), &InstallPlanAction::compare_by_name); - std::sort(new_plans.begin(), new_plans.end(), &InstallPlanAction::compare_by_name); - std::sort(already_installed_plans.begin(), already_installed_plans.end(), &InstallPlanAction::compare_by_name); - std::sort(excluded.begin(), excluded.end(), &InstallPlanAction::compare_by_name); - - static auto actions_to_output_string = [](const std::vector& v) { - return Strings::join("\n", v, [](const InstallPlanAction* p) { - return to_output_string(p->request_type, p->displayname(), p->build_options); - }); - }; - - if (excluded.size() > 0) - { - System::println("The following packages are excluded:\n%s", actions_to_output_string(excluded)); - } - - if (already_installed_plans.size() > 0) - { - System::println("The following packages are already installed:\n%s", - actions_to_output_string(already_installed_plans)); - } - - if (rebuilt_plans.size() > 0) - { - System::println("The following packages will be rebuilt:\n%s", actions_to_output_string(rebuilt_plans)); - } - - if (new_plans.size() > 0) - { - System::println("The following packages will be built and installed:\n%s", - actions_to_output_string(new_plans)); - } - - if (only_install_plans.size() > 0) - { - System::println("The following packages will be directly installed:\n%s", - actions_to_output_string(only_install_plans)); - } - - if (has_non_user_requested_packages) - System::println("Additional packages (*) will be modified to complete this operation."); - - if (remove_plans.size() > 0 && !is_recursive) - { - System::println(System::Color::warning, - "If you are sure you want to rebuild the above packages, run the command with the " - "--recurse option"); - Checks::exit_fail(VCPKG_LINE_INFO); - } - } } diff --git a/toolsrc/src/vcpkg/help.cpp b/toolsrc/src/vcpkg/help.cpp index b7d355742..c83f0277b 100644 --- a/toolsrc/src/vcpkg/help.cpp +++ b/toolsrc/src/vcpkg/help.cpp @@ -85,7 +85,6 @@ namespace vcpkg::Help " vcpkg remove --outdated Uninstall all out-of-date packages\n" " vcpkg list List installed packages\n" " vcpkg update Display list of packages for updating\n" - " vcpkg upgrade Rebuild all outdated packages\n" " vcpkg hash [alg] Hash a file by specific algorithm, default SHA512\n" " vcpkg help topics Display the list of help topics\n" " vcpkg help Display help for a specific topic\n" diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp index 08cfc2e73..76dc7a527 100644 --- a/toolsrc/src/vcpkg/install.cpp +++ b/toolsrc/src/vcpkg/install.cpp @@ -348,6 +348,108 @@ namespace vcpkg::Install Checks::unreachable(VCPKG_LINE_INFO); } + static void print_plan(const std::vector& action_plan, const bool is_recursive) + { + std::vector remove_plans; + std::vector rebuilt_plans; + std::vector only_install_plans; + std::vector new_plans; + std::vector already_installed_plans; + std::vector excluded; + + const bool has_non_user_requested_packages = Util::find_if(action_plan, [](const AnyAction& package) -> bool { + if (auto iplan = package.install_plan.get()) + return iplan->request_type != RequestType::USER_REQUESTED; + else + return false; + }) != action_plan.cend(); + + for (auto&& action : action_plan) + { + if (auto install_action = action.install_plan.get()) + { + // remove plans are guaranteed to come before install plans, so we know the plan will be contained if at + // all. + auto it = Util::find_if( + remove_plans, [&](const RemovePlanAction* plan) { return plan->spec == install_action->spec; }); + if (it != remove_plans.end()) + { + rebuilt_plans.emplace_back(install_action); + } + else + { + switch (install_action->plan_type) + { + case InstallPlanType::INSTALL: only_install_plans.emplace_back(install_action); break; + case InstallPlanType::ALREADY_INSTALLED: + if (install_action->request_type == RequestType::USER_REQUESTED) + already_installed_plans.emplace_back(install_action); + break; + case InstallPlanType::BUILD_AND_INSTALL: new_plans.emplace_back(install_action); break; + case InstallPlanType::EXCLUDED: excluded.emplace_back(install_action); break; + default: Checks::unreachable(VCPKG_LINE_INFO); + } + } + } + else if (auto remove_action = action.remove_plan.get()) + { + remove_plans.emplace_back(remove_action); + } + } + + std::sort(remove_plans.begin(), remove_plans.end(), &RemovePlanAction::compare_by_name); + std::sort(rebuilt_plans.begin(), rebuilt_plans.end(), &InstallPlanAction::compare_by_name); + std::sort(only_install_plans.begin(), only_install_plans.end(), &InstallPlanAction::compare_by_name); + std::sort(new_plans.begin(), new_plans.end(), &InstallPlanAction::compare_by_name); + std::sort(already_installed_plans.begin(), already_installed_plans.end(), &InstallPlanAction::compare_by_name); + std::sort(excluded.begin(), excluded.end(), &InstallPlanAction::compare_by_name); + + static auto actions_to_output_string = [](const std::vector& v) { + return Strings::join("\n", v, [](const InstallPlanAction* p) { + return to_output_string(p->request_type, p->displayname(), p->build_options); + }); + }; + + if (excluded.size() > 0) + { + System::println("The following packages are excluded:\n%s", actions_to_output_string(excluded)); + } + + if (already_installed_plans.size() > 0) + { + System::println("The following packages are already installed:\n%s", + actions_to_output_string(already_installed_plans)); + } + + if (rebuilt_plans.size() > 0) + { + System::println("The following packages will be rebuilt:\n%s", actions_to_output_string(rebuilt_plans)); + } + + if (new_plans.size() > 0) + { + System::println("The following packages will be built and installed:\n%s", + actions_to_output_string(new_plans)); + } + + if (only_install_plans.size() > 0) + { + System::println("The following packages will be directly installed:\n%s", + actions_to_output_string(only_install_plans)); + } + + if (has_non_user_requested_packages) + System::println("Additional packages (*) will be installed to complete this operation."); + + if (remove_plans.size() > 0 && !is_recursive) + { + System::println(System::Color::warning, + "If you are sure you want to rebuild the above packages, run the command with the " + "--recurse option"); + Checks::exit_fail(VCPKG_LINE_INFO); + } + } + void InstallSummary::print() const { System::println("RESULTS"); @@ -397,7 +499,7 @@ namespace vcpkg::Install results.emplace_back(spec, &action); - if (const auto install_action = action.install_action.get()) + if (const auto install_action = action.install_plan.get()) { auto result = perform_install_plan_action(paths, *install_action, status_db); @@ -409,7 +511,7 @@ namespace vcpkg::Install results.back().build_result = std::move(result); } - else if (const auto remove_action = action.remove_action.get()) + else if (const auto remove_action = action.remove_plan.get()) { Checks::check_exit(VCPKG_LINE_INFO, GlobalState::feature_packages); Remove::perform_remove_plan_action(paths, *remove_action, Remove::Purge::YES, status_db); @@ -588,7 +690,7 @@ namespace vcpkg::Install } else { - Dependencies::PathsPortFileProvider paths_port_file(paths); + Dependencies::PathsPortFile paths_port_file(paths); auto install_plan = Dependencies::create_install_plan( paths_port_file, Util::fmap(specs, [](auto&& spec) { return spec.package_spec; }), status_db); @@ -598,7 +700,7 @@ namespace vcpkg::Install for (auto&& action : action_plan) { - if (auto p_install = action.install_action.get()) + if (auto p_install = action.install_plan.get()) { p_install->build_options = install_plan_options; if (p_install->request_type != RequestType::USER_REQUESTED) @@ -611,16 +713,16 @@ namespace vcpkg::Install // log the plan const std::string specs_string = Strings::join(",", action_plan, [](const AnyAction& action) { - if (auto iaction = action.install_action.get()) + if (auto iaction = action.install_plan.get()) return iaction->spec.to_string(); - else if (auto raction = action.remove_action.get()) + else if (auto raction = action.remove_plan.get()) return "R$" + raction->spec.to_string(); Checks::unreachable(VCPKG_LINE_INFO); }); Metrics::g_metrics.lock()->track_property("installplan", specs_string); - Dependencies::print_plan(action_plan, is_recursive); + print_plan(action_plan, is_recursive); if (dry_run) { @@ -650,7 +752,7 @@ namespace vcpkg::Install for (auto&& result : summary.results) { if (!result.action) continue; - if (auto p_install_action = result.action->install_action.get()) + if (auto p_install_action = result.action->install_plan.get()) { if (p_install_action->request_type != RequestType::USER_REQUESTED) continue; auto bpgh = result.get_binary_paragraph(); @@ -671,7 +773,7 @@ namespace vcpkg::Install { if (build_result.binary_control_file) return &build_result.binary_control_file->core_paragraph; if (action) - if (auto p_install_plan = action->install_action.get()) + if (auto p_install_plan = action->install_plan.get()) { if (auto p_bcf = p_install_plan->any_paragraph.binary_control_file.get()) return &p_bcf->core_paragraph; diff --git a/toolsrc/src/vcpkg/paragraphs.cpp b/toolsrc/src/vcpkg/paragraphs.cpp index b66d53994..b93de190c 100644 --- a/toolsrc/src/vcpkg/paragraphs.cpp +++ b/toolsrc/src/vcpkg/paragraphs.cpp @@ -289,4 +289,16 @@ namespace vcpkg::Paragraphs } return std::move(results.paragraphs); } + + std::map load_all_port_names_and_versions(const Files::Filesystem& fs, + const fs::path& ports_dir) + { + auto all_ports = load_all_ports(fs, ports_dir); + + std::map names_and_versions; + for (auto&& port : all_ports) + names_and_versions.emplace(port->core_paragraph->name, port->core_paragraph->version); + + return names_and_versions; + } } diff --git a/toolsrc/src/vcpkg/remove.cpp b/toolsrc/src/vcpkg/remove.cpp index 4079d60c1..8ae0bc881 100644 --- a/toolsrc/src/vcpkg/remove.cpp +++ b/toolsrc/src/vcpkg/remove.cpp @@ -207,11 +207,10 @@ namespace vcpkg::Remove System::println(System::Color::error, "Error: 'remove' accepts either libraries or '--outdated'"); Checks::exit_fail(VCPKG_LINE_INFO); } - - Dependencies::PathsPortFileProvider provider(paths); - - specs = Util::fmap(Update::find_outdated_packages(provider, status_db), - [](auto&& outdated) { return outdated.spec; }); + specs = Util::fmap( + Update::find_outdated_packages( + Paragraphs::load_all_port_names_and_versions(paths.get_filesystem(), paths.ports), status_db), + [](auto&& outdated) { return outdated.spec; }); if (specs.empty()) { diff --git a/toolsrc/src/vcpkg/update.cpp b/toolsrc/src/vcpkg/update.cpp index d6c5614ed..29baef91e 100644 --- a/toolsrc/src/vcpkg/update.cpp +++ b/toolsrc/src/vcpkg/update.cpp @@ -14,7 +14,7 @@ namespace vcpkg::Update return left.spec.name() < right.spec.name(); } - std::vector find_outdated_packages(const Dependencies::PortFileProvider& provider, + std::vector find_outdated_packages(const std::map& src_names_to_versions, const StatusParagraphs& status_db) { const std::vector installed_packages = get_installed_ports(status_db); @@ -24,23 +24,19 @@ namespace vcpkg::Update { if (!pgh->package.feature.empty()) { - // Skip feature paragraphs; only consider master paragraphs for needing updates. + // Skip feature packages; only consider master packages for needing updates. continue; } - auto maybe_scf = provider.get_control_file(pgh->package.spec.name()); - if (auto p_scf = maybe_scf.get()) + const auto it = src_names_to_versions.find(pgh->package.spec.name()); + if (it == src_names_to_versions.end()) { - auto&& port_version = p_scf->core_paragraph->version; - auto&& installed_version = pgh->package.version; - if (installed_version != port_version) - { - output.push_back({pgh->package.spec, VersionDiff(installed_version, port_version)}); - } + // Package was not installed from portfile + continue; } - else + if (it->second != pgh->package.version) { - // No portfile available + output.push_back({pgh->package.spec, VersionDiff(pgh->package.version, it->second)}); } } @@ -62,10 +58,10 @@ namespace vcpkg::Update const StatusParagraphs status_db = database_load_check(paths); - Dependencies::PathsPortFileProvider provider(paths); - - const auto outdated_packages = SortedVector(find_outdated_packages(provider, status_db), - &OutdatedPackage::compare_by_name); + const auto outdated_packages = SortedVector( + find_outdated_packages(Paragraphs::load_all_port_names_and_versions(paths.get_filesystem(), paths.ports), + status_db), + &OutdatedPackage::compare_by_name); if (outdated_packages.empty()) { @@ -73,17 +69,19 @@ namespace vcpkg::Update } else { + std::string install_line; System::println("The following packages differ from their port versions:"); for (auto&& package : outdated_packages) { + install_line += package.spec.to_string(); + install_line += " "; System::println(" %-32s %s", package.spec, package.version_diff.to_string()); } System::println("\n" - "To update these packages and all dependencies, run\n" - " .\\vcpkg upgrade\n" - "\n" - "To only remove outdated packages, run\n" - " .\\vcpkg remove --outdated\n"); + "To update these packages, run\n" + " .\\vcpkg remove --outdated\n" + " .\\vcpkg install " + + install_line); } Checks::exit_success(VCPKG_LINE_INFO); diff --git a/toolsrc/vcpkglib/vcpkglib.vcxproj b/toolsrc/vcpkglib/vcpkglib.vcxproj index 68345ca85..9a7ad6dc0 100644 --- a/toolsrc/vcpkglib/vcpkglib.vcxproj +++ b/toolsrc/vcpkglib/vcpkglib.vcxproj @@ -185,7 +185,6 @@ - Create Create diff --git a/toolsrc/vcpkglib/vcpkglib.vcxproj.filters b/toolsrc/vcpkglib/vcpkglib.vcxproj.filters index dfbcf0c7e..966fc7fb9 100644 --- a/toolsrc/vcpkglib/vcpkglib.vcxproj.filters +++ b/toolsrc/vcpkglib/vcpkglib.vcxproj.filters @@ -195,9 +195,6 @@ Source Files\vcpkg - - Source Files\vcpkg - -- cgit v1.2.3 From eb1a7b099eb347b195491dfa2949d8aa92677276 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Wed, 13 Dec 2017 05:43:00 -0800 Subject: [vcpkg] Fix regressions introduced with update command. Fixed issue with upgrade where it assumed downloads were not allowed. --- toolsrc/include/tests.utils.h | 16 +- toolsrc/include/vcpkg/build.h | 23 +- toolsrc/include/vcpkg/commands.h | 6 + toolsrc/include/vcpkg/dependencies.h | 54 +++- toolsrc/include/vcpkg/packagespec.h | 7 + toolsrc/include/vcpkg/paragraphs.h | 3 - toolsrc/include/vcpkg/update.h | 6 +- toolsrc/src/commands.upgrade.cpp | 180 +++++++++++++ toolsrc/src/tests.plan.cpp | 150 ++++++++++- toolsrc/src/tests.update.cpp | 34 ++- toolsrc/src/vcpkg/base/checks.cpp | 9 +- toolsrc/src/vcpkg/build.cpp | 38 ++- toolsrc/src/vcpkg/commands.ci.cpp | 2 +- toolsrc/src/vcpkg/commands.cpp | 3 +- toolsrc/src/vcpkg/commands.portsdiff.cpp | 7 +- toolsrc/src/vcpkg/dependencies.cpp | 420 +++++++++++++++++++----------- toolsrc/src/vcpkg/export.cpp | 4 +- toolsrc/src/vcpkg/help.cpp | 1 + toolsrc/src/vcpkg/install.cpp | 177 +++---------- toolsrc/src/vcpkg/paragraphs.cpp | 12 - toolsrc/src/vcpkg/remove.cpp | 9 +- toolsrc/src/vcpkg/update.cpp | 40 +-- toolsrc/vcpkglib/vcpkglib.vcxproj | 1 + toolsrc/vcpkglib/vcpkglib.vcxproj.filters | 3 + 24 files changed, 776 insertions(+), 429 deletions(-) create mode 100644 toolsrc/src/commands.upgrade.cpp (limited to 'toolsrc') diff --git a/toolsrc/include/tests.utils.h b/toolsrc/include/tests.utils.h index 485b8c294..0c0add7ab 100644 --- a/toolsrc/include/tests.utils.h +++ b/toolsrc/include/tests.utils.h @@ -23,4 +23,18 @@ std::unique_ptr make_status_pgh(const char* name, std::unique_ptr make_status_feature_pgh(const char* name, const char* feature, const char* depends = "", - const char* triplet = "x86-windows"); \ No newline at end of file + const char* triplet = "x86-windows"); + +template +T&& unwrap(vcpkg::ExpectedT&& p) +{ + Assert::IsTrue(p.has_value()); + return std::move(*p.get()); +} + +template +T&& unwrap(vcpkg::Optional&& opt) +{ + Assert::IsTrue(opt.has_value()); + return std::move(*opt.get()); +} diff --git a/toolsrc/include/vcpkg/build.h b/toolsrc/include/vcpkg/build.h index 18408e207..e3f8bf79e 100644 --- a/toolsrc/include/vcpkg/build.h +++ b/toolsrc/include/vcpkg/build.h @@ -114,39 +114,24 @@ namespace vcpkg::Build struct BuildPackageConfig { - BuildPackageConfig(const SourceParagraph& src, - const Triplet& triplet, - fs::path&& port_dir, - const BuildPackageOptions& build_package_options) - : src(src) - , scf(nullptr) - , triplet(triplet) - , port_dir(std::move(port_dir)) - , build_package_options(build_package_options) - , feature_list(nullptr) - { - } - BuildPackageConfig(const SourceControlFile& src, const Triplet& triplet, fs::path&& port_dir, const BuildPackageOptions& build_package_options, const std::unordered_set& feature_list) - : src(*src.core_paragraph) - , scf(&src) + : scf(src) , triplet(triplet) , port_dir(std::move(port_dir)) , build_package_options(build_package_options) - , feature_list(&feature_list) + , feature_list(feature_list) { } - const SourceParagraph& src; - const SourceControlFile* scf; + const SourceControlFile& scf; const Triplet& triplet; fs::path port_dir; const BuildPackageOptions& build_package_options; - const std::unordered_set* feature_list; + const std::unordered_set& feature_list; }; ExtendedBuildResult build_package(const VcpkgPaths& paths, diff --git a/toolsrc/include/vcpkg/commands.h b/toolsrc/include/vcpkg/commands.h index 74fd80c03..b852a973e 100644 --- a/toolsrc/include/vcpkg/commands.h +++ b/toolsrc/include/vcpkg/commands.h @@ -39,6 +39,12 @@ namespace vcpkg::Commands void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); } + namespace Upgrade + { + extern const CommandStructure COMMAND_STRUCTURE; + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet); + } + namespace Edit { extern const CommandStructure COMMAND_STRUCTURE; diff --git a/toolsrc/include/vcpkg/dependencies.h b/toolsrc/include/vcpkg/dependencies.h index 5411ee166..8a082efca 100644 --- a/toolsrc/include/vcpkg/dependencies.h +++ b/toolsrc/include/vcpkg/dependencies.h @@ -30,7 +30,6 @@ namespace vcpkg::Dependencies Optional status_paragraph; Optional binary_control_file; - Optional source_paragraph; Optional source_control_file; }; } @@ -92,11 +91,11 @@ namespace vcpkg::Dependencies struct AnyAction { - AnyAction(InstallPlanAction&& iplan) : install_plan(std::move(iplan)) {} - AnyAction(RemovePlanAction&& rplan) : remove_plan(std::move(rplan)) {} + AnyAction(InstallPlanAction&& iplan) : install_action(std::move(iplan)) {} + AnyAction(RemovePlanAction&& rplan) : remove_action(std::move(rplan)) {} - Optional install_plan; - Optional remove_plan; + Optional install_action; + Optional remove_action; const PackageSpec& spec() const; }; @@ -123,22 +122,44 @@ namespace vcpkg::Dependencies struct PortFileProvider { - virtual const SourceControlFile& get_control_file(const std::string& spec) const = 0; + virtual Optional get_control_file(const std::string& src_name) const = 0; }; - struct MapPortFile : Util::ResourceBase, PortFileProvider + struct MapPortFileProvider : Util::ResourceBase, PortFileProvider { + explicit MapPortFileProvider(const std::unordered_map& map); + Optional get_control_file(const std::string& src_name) const override; + + private: const std::unordered_map& ports; - explicit MapPortFile(const std::unordered_map& map); - const SourceControlFile& get_control_file(const std::string& spec) const override; }; - struct PathsPortFile : Util::ResourceBase, PortFileProvider + struct PathsPortFileProvider : Util::ResourceBase, PortFileProvider { + explicit PathsPortFileProvider(const VcpkgPaths& paths); + Optional get_control_file(const std::string& src_name) const override; + + private: const VcpkgPaths& ports; mutable std::unordered_map cache; - explicit PathsPortFile(const VcpkgPaths& paths); - const SourceControlFile& get_control_file(const std::string& spec) const override; + }; + + struct ClusterGraph; + struct GraphPlan; + + struct PackageGraph + { + PackageGraph(const PortFileProvider& provider, const StatusParagraphs& status_db); + ~PackageGraph(); + + void install(const FeatureSpec& spec); + void upgrade(const PackageSpec& spec); + + std::vector serialize() const; + + private: + std::unique_ptr m_graph_plan; + std::unique_ptr m_graph; }; std::vector create_install_plan(const PortFileProvider& port_file_provider, @@ -148,11 +169,18 @@ namespace vcpkg::Dependencies std::vector create_remove_plan(const std::vector& specs, const StatusParagraphs& status_db); - std::vector create_export_plan(const VcpkgPaths& paths, + std::vector create_export_plan(const PortFileProvider& port_file_provider, + const VcpkgPaths& paths, const std::vector& specs, const StatusParagraphs& status_db); std::vector create_feature_install_plan(const std::unordered_map& map, const std::vector& specs, const StatusParagraphs& status_db); + + std::vector create_feature_install_plan(const PortFileProvider& port_file_provider, + const std::vector& specs, + const StatusParagraphs& status_db); + + void print_plan(const std::vector& action_plan, const bool is_recursive = true); } diff --git a/toolsrc/include/vcpkg/packagespec.h b/toolsrc/include/vcpkg/packagespec.h index 071487e1a..f1119e2f3 100644 --- a/toolsrc/include/vcpkg/packagespec.h +++ b/toolsrc/include/vcpkg/packagespec.h @@ -34,6 +34,13 @@ namespace vcpkg std::string to_string() const; + bool operator<(const PackageSpec& other) const + { + if (name() < other.name()) return true; + if (name() > other.name()) return false; + return triplet() < other.triplet(); + } + private: std::string m_name; Triplet m_triplet; diff --git a/toolsrc/include/vcpkg/paragraphs.h b/toolsrc/include/vcpkg/paragraphs.h index c8dbea646..e2c7f2d99 100644 --- a/toolsrc/include/vcpkg/paragraphs.h +++ b/toolsrc/include/vcpkg/paragraphs.h @@ -32,7 +32,4 @@ namespace vcpkg::Paragraphs std::vector> load_all_ports(const Files::Filesystem& fs, const fs::path& ports_dir); - - std::map load_all_port_names_and_versions(const Files::Filesystem& fs, - const fs::path& ports_dir); } diff --git a/toolsrc/include/vcpkg/update.h b/toolsrc/include/vcpkg/update.h index 7587b9eb2..b85f7b2b3 100644 --- a/toolsrc/include/vcpkg/update.h +++ b/toolsrc/include/vcpkg/update.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -16,7 +17,8 @@ namespace vcpkg::Update VersionDiff version_diff; }; - std::vector find_outdated_packages(const std::map& src_names_to_versions, + std::vector find_outdated_packages(const Dependencies::PortFileProvider& provider, const StatusParagraphs& status_db); + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); -} \ No newline at end of file +} diff --git a/toolsrc/src/commands.upgrade.cpp b/toolsrc/src/commands.upgrade.cpp new file mode 100644 index 000000000..d2c868870 --- /dev/null +++ b/toolsrc/src/commands.upgrade.cpp @@ -0,0 +1,180 @@ +#include "pch.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace vcpkg::Commands::Upgrade +{ + using Install::KeepGoing; + using Install::to_keep_going; + + static const std::string OPTION_NO_DRY_RUN = "--no-dry-run"; + static const std::string OPTION_KEEP_GOING = "--keep-going"; + + static const std::array INSTALL_SWITCHES = {{ + {OPTION_NO_DRY_RUN, "Actually upgrade"}, + {OPTION_KEEP_GOING, "Continue installing packages on failure"}, + }}; + + const CommandStructure COMMAND_STRUCTURE = { + Help::create_example_string("upgrade --no-dry-run"), + 0, + SIZE_MAX, + {INSTALL_SWITCHES, {}}, + nullptr, + }; + + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) + { + const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE); + + const bool no_dry_run = Util::Sets::contains(options.switches, OPTION_NO_DRY_RUN); + const KeepGoing keep_going = to_keep_going(Util::Sets::contains(options.switches, OPTION_KEEP_GOING)); + + StatusParagraphs status_db = database_load_check(paths); + + Dependencies::PathsPortFileProvider provider(paths); + Dependencies::PackageGraph graph(provider, status_db); + + // input sanitization + const std::vector specs = Util::fmap(args.command_arguments, [&](auto&& arg) { + return Input::check_and_get_package_spec(arg, default_triplet, COMMAND_STRUCTURE.example_text); + }); + + for (auto&& spec : specs) + { + Input::check_triplet(spec.triplet(), paths); + } + + if (specs.empty()) + { + // If no packages specified, upgrade all outdated packages. + auto outdated_packages = Update::find_outdated_packages(provider, status_db); + + if (outdated_packages.empty()) + { + System::println("All installed packages are up-to-date with the local portfiles."); + Checks::exit_success(VCPKG_LINE_INFO); + } + + for (auto&& outdated_package : outdated_packages) + graph.upgrade(outdated_package.spec); + } + else + { + std::vector not_installed; + std::vector no_portfile; + std::vector to_upgrade; + std::vector up_to_date; + + for (auto&& spec : specs) + { + auto it = status_db.find_installed(spec); + if (it == status_db.end()) + { + not_installed.push_back(spec); + } + + auto maybe_scf = provider.get_control_file(spec.name()); + if (auto p_scf = maybe_scf.get()) + { + if (it != status_db.end()) + { + if (p_scf->core_paragraph->version != (*it)->package.version) + { + to_upgrade.push_back(spec); + } + else + { + up_to_date.push_back(spec); + } + } + } + else + { + no_portfile.push_back(spec); + } + } + + Util::sort(not_installed); + Util::sort(no_portfile); + Util::sort(up_to_date); + Util::sort(to_upgrade); + + if (!up_to_date.empty()) + { + System::println(System::Color::success, "The following packages are up-to-date:"); + System::println(Strings::join( + "", up_to_date, [](const PackageSpec& spec) { return " " + spec.to_string() + "\n"; })); + } + + if (!not_installed.empty()) + { + System::println(System::Color::error, "The following packages are not installed:"); + System::println(Strings::join( + "", not_installed, [](const PackageSpec& spec) { return " " + spec.to_string() + "\n"; })); + } + + if (!no_portfile.empty()) + { + System::println(System::Color::error, "The following packages do not have a valid portfile:"); + System::println(Strings::join( + "", no_portfile, [](const PackageSpec& spec) { return " " + spec.to_string() + "\n"; })); + } + + Checks::check_exit(VCPKG_LINE_INFO, not_installed.empty() && no_portfile.empty()); + + if (to_upgrade.empty()) Checks::exit_success(VCPKG_LINE_INFO); + + for (auto&& spec : to_upgrade) + graph.upgrade(spec); + } + + auto plan = graph.serialize(); + + Checks::check_exit(VCPKG_LINE_INFO, !plan.empty()); + + const Build::BuildPackageOptions install_plan_options = { + Build::UseHeadVersion::NO, + Build::AllowDownloads::YES, + Build::CleanBuildtrees::NO, + }; + + // Set build settings for all install actions + for (auto&& action : plan) + { + if (auto p_install = action.install_action.get()) + { + p_install->build_options = install_plan_options; + } + } + + Dependencies::print_plan(plan, true); + + if (!no_dry_run) + { + System::println(System::Color::warning, + "If you are sure you want to rebuild the above packages, run this command with the " + "--no-dry-run option."); + Checks::exit_fail(VCPKG_LINE_INFO); + } + + const Install::InstallSummary summary = Install::perform(plan, keep_going, paths, status_db); + + System::println("\nTotal elapsed time: %s\n", summary.total_elapsed_time); + + if (keep_going == KeepGoing::YES) + { + summary.print(); + } + + Checks::exit_success(VCPKG_LINE_INFO); + } +} diff --git a/toolsrc/src/tests.plan.cpp b/toolsrc/src/tests.plan.cpp index 122a4ffef..781588c91 100644 --- a/toolsrc/src/tests.plan.cpp +++ b/toolsrc/src/tests.plan.cpp @@ -36,7 +36,7 @@ namespace UnitTest1 std::vector vec, const Triplet& triplet = Triplet::X86_WINDOWS) { - const auto& plan = install_action->install_plan.value_or_exit(VCPKG_LINE_INFO); + const auto& plan = install_action->install_action.value_or_exit(VCPKG_LINE_INFO); const auto& feature_list = plan.feature_list; Assert::AreEqual(plan.spec.triplet().to_string().c_str(), triplet.to_string().c_str()); @@ -61,7 +61,7 @@ namespace UnitTest1 std::string pkg_name, const Triplet& triplet = Triplet::X86_WINDOWS) { - const auto& plan = remove_action->remove_plan.value_or_exit(VCPKG_LINE_INFO); + const auto& plan = remove_action->remove_action.value_or_exit(VCPKG_LINE_INFO); Assert::AreEqual(plan.spec.triplet().to_string().c_str(), triplet.to_string().c_str()); Assert::AreEqual(pkg_name.c_str(), plan.spec.name().c_str()); } @@ -98,7 +98,7 @@ namespace UnitTest1 auto spec_b = spec_map.emplace("b", "c"); auto spec_c = spec_map.emplace("c"); - Dependencies::MapPortFile map_port(spec_map.map); + Dependencies::MapPortFileProvider map_port(spec_map.map); auto install_plan = Dependencies::create_install_plan(map_port, {spec_a}, StatusParagraphs(std::move(status_paragraphs))); @@ -122,7 +122,7 @@ namespace UnitTest1 auto spec_g = spec_map.emplace("g"); auto spec_h = spec_map.emplace("h"); - Dependencies::MapPortFile map_port(spec_map.map); + Dependencies::MapPortFileProvider map_port(spec_map.map); auto install_plan = Dependencies::create_install_plan( map_port, {spec_a, spec_b, spec_c}, StatusParagraphs(std::move(status_paragraphs))); @@ -162,7 +162,7 @@ namespace UnitTest1 StatusParagraphs(std::move(status_paragraphs))); Assert::AreEqual(size_t(1), install_plan.size()); - auto p = install_plan[0].install_plan.get(); + auto p = install_plan[0].install_action.get(); Assert::IsNotNull(p); Assert::AreEqual("a", p->spec.name().c_str()); Assert::AreEqual(Dependencies::InstallPlanType::ALREADY_INSTALLED, p->plan_type); @@ -183,13 +183,13 @@ namespace UnitTest1 StatusParagraphs(std::move(status_paragraphs))); Assert::AreEqual(size_t(2), install_plan.size()); - auto p = install_plan[0].install_plan.get(); + auto p = install_plan[0].install_action.get(); Assert::IsNotNull(p); Assert::AreEqual("b", p->spec.name().c_str()); Assert::AreEqual(Dependencies::InstallPlanType::BUILD_AND_INSTALL, p->plan_type); Assert::AreEqual(Dependencies::RequestType::AUTO_SELECTED, p->request_type); - auto p2 = install_plan[1].install_plan.get(); + auto p2 = install_plan[1].install_action.get(); Assert::IsNotNull(p2); Assert::AreEqual("a", p2->spec.name().c_str()); Assert::AreEqual(Dependencies::InstallPlanType::BUILD_AND_INSTALL, p2->plan_type); @@ -215,7 +215,7 @@ namespace UnitTest1 auto spec_j = spec_map.emplace("j", "k"); auto spec_k = spec_map.emplace("k"); - Dependencies::MapPortFile map_port(spec_map.map); + Dependencies::MapPortFileProvider map_port(spec_map.map); auto install_plan = Dependencies::create_install_plan(map_port, {spec_a}, StatusParagraphs(std::move(status_paragraphs))); @@ -521,4 +521,138 @@ namespace UnitTest1 Assert::AreEqual("expat", remove_plan[2].spec.name().c_str()); } }; + + class UpgradePlanTests : public TestClass + { + TEST_METHOD(basic_upgrade_scheme) + { + std::vector> pghs; + pghs.push_back(make_status_pgh("a")); + StatusParagraphs status_db(std::move(pghs)); + + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + auto spec_a = spec_map.emplace("a"); + + Dependencies::MapPortFileProvider provider(spec_map.map); + Dependencies::PackageGraph graph(provider, status_db); + + graph.upgrade(spec_a); + + auto plan = graph.serialize(); + + Assert::AreEqual(size_t(2), plan.size()); + Assert::AreEqual("a", plan[0].spec().name().c_str()); + Assert::IsTrue(plan[0].remove_action.has_value()); + Assert::AreEqual("a", plan[1].spec().name().c_str()); + Assert::IsTrue(plan[1].install_action.has_value()); + } + + TEST_METHOD(basic_upgrade_scheme_with_recurse) + { + std::vector> pghs; + pghs.push_back(make_status_pgh("a")); + pghs.push_back(make_status_pgh("b", "a")); + StatusParagraphs status_db(std::move(pghs)); + + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + auto spec_a = spec_map.emplace("a"); + spec_map.emplace("b", "a"); + + Dependencies::MapPortFileProvider provider(spec_map.map); + Dependencies::PackageGraph graph(provider, status_db); + + graph.upgrade(spec_a); + + auto plan = graph.serialize(); + + Assert::AreEqual(size_t(4), plan.size()); + Assert::AreEqual("b", plan[0].spec().name().c_str()); + Assert::IsTrue(plan[0].remove_action.has_value()); + + Assert::AreEqual("a", plan[1].spec().name().c_str()); + Assert::IsTrue(plan[1].remove_action.has_value()); + + Assert::AreEqual("a", plan[2].spec().name().c_str()); + Assert::IsTrue(plan[2].install_action.has_value()); + + Assert::AreEqual("b", plan[3].spec().name().c_str()); + Assert::IsTrue(plan[3].install_action.has_value()); + } + + TEST_METHOD(basic_upgrade_scheme_with_bystander) + { + std::vector> pghs; + pghs.push_back(make_status_pgh("a")); + pghs.push_back(make_status_pgh("b")); + StatusParagraphs status_db(std::move(pghs)); + + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + auto spec_a = spec_map.emplace("a"); + spec_map.emplace("b", "a"); + + Dependencies::MapPortFileProvider provider(spec_map.map); + Dependencies::PackageGraph graph(provider, status_db); + + graph.upgrade(spec_a); + + auto plan = graph.serialize(); + + Assert::AreEqual(size_t(2), plan.size()); + Assert::AreEqual("a", plan[0].spec().name().c_str()); + Assert::IsTrue(plan[0].remove_action.has_value()); + Assert::AreEqual("a", plan[1].spec().name().c_str()); + Assert::IsTrue(plan[1].install_action.has_value()); + } + + TEST_METHOD(basic_upgrade_scheme_with_new_dep) + { + std::vector> pghs; + pghs.push_back(make_status_pgh("a")); + StatusParagraphs status_db(std::move(pghs)); + + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + auto spec_a = spec_map.emplace("a", "b"); + spec_map.emplace("b"); + + Dependencies::MapPortFileProvider provider(spec_map.map); + Dependencies::PackageGraph graph(provider, status_db); + + graph.upgrade(spec_a); + + auto plan = graph.serialize(); + + Assert::AreEqual(size_t(3), plan.size()); + Assert::AreEqual("a", plan[0].spec().name().c_str()); + Assert::IsTrue(plan[0].remove_action.has_value()); + Assert::AreEqual("b", plan[1].spec().name().c_str()); + Assert::IsTrue(plan[1].install_action.has_value()); + Assert::AreEqual("a", plan[2].spec().name().c_str()); + Assert::IsTrue(plan[2].install_action.has_value()); + } + + TEST_METHOD(basic_upgrade_scheme_with_features) + { + std::vector> pghs; + pghs.push_back(make_status_pgh("a")); + pghs.push_back(make_status_feature_pgh("a", "a1")); + StatusParagraphs status_db(std::move(pghs)); + + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + auto spec_a = spec_map.emplace("a", "", {{"a1", ""}}); + + Dependencies::MapPortFileProvider provider(spec_map.map); + Dependencies::PackageGraph graph(provider, status_db); + + graph.upgrade(spec_a); + + auto plan = graph.serialize(); + + Assert::AreEqual(size_t(2), plan.size()); + + Assert::AreEqual("a", plan[0].spec().name().c_str()); + Assert::IsTrue(plan[0].remove_action.has_value()); + + features_check(&plan[1], "a", {"core", "a1"}); + } + }; } diff --git a/toolsrc/src/tests.update.cpp b/toolsrc/src/tests.update.cpp index 06ae797f4..b6e487c17 100644 --- a/toolsrc/src/tests.update.cpp +++ b/toolsrc/src/tests.update.cpp @@ -9,6 +9,8 @@ using namespace vcpkg::Update; namespace UnitTest1 { + using Pgh = std::vector>; + class UpdateTests : public TestClass { TEST_METHOD(find_outdated_packages_basic) @@ -19,10 +21,12 @@ namespace UnitTest1 StatusParagraphs status_db(std::move(status_paragraphs)); - std::map port_versions; - port_versions["a"] = VersionT("0"); + std::unordered_map map; + auto scf = unwrap(SourceControlFile::parse_control_file(Pgh{{{"Source", "a"}, {"Version", "0"}}})); + map.emplace("a", std::move(*scf)); + Dependencies::MapPortFileProvider provider(map); - auto pkgs = SortedVector(Update::find_outdated_packages(port_versions, status_db), + auto pkgs = SortedVector(Update::find_outdated_packages(provider, status_db), &OutdatedPackage::compare_by_name); Assert::AreEqual(size_t(1), pkgs.size()); @@ -41,10 +45,12 @@ namespace UnitTest1 StatusParagraphs status_db(std::move(status_paragraphs)); - std::map port_versions; - port_versions["a"] = VersionT("0"); + std::unordered_map map; + auto scf = unwrap(SourceControlFile::parse_control_file(Pgh{{{"Source", "a"}, {"Version", "0"}}})); + map.emplace("a", std::move(*scf)); + Dependencies::MapPortFileProvider provider(map); - auto pkgs = SortedVector(Update::find_outdated_packages(port_versions, status_db), + auto pkgs = SortedVector(Update::find_outdated_packages(provider, status_db), &OutdatedPackage::compare_by_name); Assert::AreEqual(size_t(1), pkgs.size()); @@ -65,10 +71,12 @@ namespace UnitTest1 StatusParagraphs status_db(std::move(status_paragraphs)); - std::map port_versions; - port_versions["a"] = VersionT("0"); + std::unordered_map map; + auto scf = unwrap(SourceControlFile::parse_control_file(Pgh{{{"Source", "a"}, {"Version", "0"}}})); + map.emplace("a", std::move(*scf)); + Dependencies::MapPortFileProvider provider(map); - auto pkgs = SortedVector(Update::find_outdated_packages(port_versions, status_db), + auto pkgs = SortedVector(Update::find_outdated_packages(provider, status_db), &OutdatedPackage::compare_by_name); Assert::AreEqual(size_t(1), pkgs.size()); @@ -84,10 +92,12 @@ namespace UnitTest1 StatusParagraphs status_db(std::move(status_paragraphs)); - std::map port_versions; - port_versions["a"] = VersionT("2"); + std::unordered_map map; + auto scf = unwrap(SourceControlFile::parse_control_file(Pgh{{{"Source", "a"}, {"Version", "2"}}})); + map.emplace("a", std::move(*scf)); + Dependencies::MapPortFileProvider provider(map); - auto pkgs = SortedVector(Update::find_outdated_packages(port_versions, status_db), + auto pkgs = SortedVector(Update::find_outdated_packages(provider, status_db), &OutdatedPackage::compare_by_name); Assert::AreEqual(size_t(0), pkgs.size()); diff --git a/toolsrc/src/vcpkg/base/checks.cpp b/toolsrc/src/vcpkg/base/checks.cpp index ed28d6e2b..23f2cc630 100644 --- a/toolsrc/src/vcpkg/base/checks.cpp +++ b/toolsrc/src/vcpkg/base/checks.cpp @@ -49,8 +49,7 @@ namespace vcpkg::Checks #else void register_console_ctrl_handler() {} #endif - - [[noreturn]] void unreachable(const LineInfo& line_info) + void unreachable(const LineInfo& line_info) { System::println(System::Color::error, "Error: Unreachable code was reached"); System::println(System::Color::error, line_info.to_string()); // Always print line_info here @@ -61,13 +60,13 @@ namespace vcpkg::Checks #endif } - [[noreturn]] void exit_with_code(const LineInfo& line_info, const int exit_code) + void exit_with_code(const LineInfo& line_info, const int exit_code) { Debug::println(System::Color::error, line_info.to_string()); cleanup_and_exit(exit_code); } - [[noreturn]] void exit_with_message(const LineInfo& line_info, const CStringView error_message) + void exit_with_message(const LineInfo& line_info, const CStringView error_message) { System::println(System::Color::error, error_message); exit_fail(line_info); @@ -77,7 +76,7 @@ namespace vcpkg::Checks { if (!expression) { - exit_with_message(line_info, ""); + exit_fail(line_info); } } diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index b8f122b27..f43d8788e 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -260,13 +260,13 @@ namespace vcpkg::Build const BuildPackageConfig& config, const StatusParagraphs& status_db) { - const PackageSpec spec = - PackageSpec::from_name_and_triplet(config.src.name, config.triplet).value_or_exit(VCPKG_LINE_INFO); + const PackageSpec spec = PackageSpec::from_name_and_triplet(config.scf.core_paragraph->name, config.triplet) + .value_or_exit(VCPKG_LINE_INFO); const Triplet& triplet = config.triplet; { std::vector missing_specs; - for (auto&& dep : filter_dependencies(config.src.depends, triplet)) + for (auto&& dep : filter_dependencies(config.scf.core_paragraph->depends, triplet)) { if (status_db.find_installed(dep, triplet) == status_db.end()) { @@ -290,16 +290,13 @@ namespace vcpkg::Build std::string features; if (GlobalState::feature_packages) { - if (config.feature_list) + for (auto&& feature : config.feature_list) { - for (auto&& feature : *config.feature_list) - { - features.append(feature + ";"); - } - if (features.size() > 0) - { - features.pop_back(); - } + features.append(feature + ";"); + } + if (features.size() > 0) + { + features.pop_back(); } } @@ -309,7 +306,7 @@ namespace vcpkg::Build ports_cmake_script_path, { {"CMD", "BUILD"}, - {"PORT", config.src.name}, + {"PORT", config.scf.core_paragraph->name}, {"CURRENT_PORT_DIR", config.port_dir / "/."}, {"TARGET_TRIPLET", triplet.canonical_name()}, {"VCPKG_PLATFORM_TOOLSET", toolset.version.c_str()}, @@ -343,7 +340,7 @@ namespace vcpkg::Build const BuildInfo build_info = read_build_info(paths.get_filesystem(), paths.build_info_file_path(spec)); const size_t error_count = PostBuildLint::perform_all_checks(spec, paths, pre_build_info, build_info); - auto bcf = create_binary_control_file(config.src, triplet, build_info); + auto bcf = create_binary_control_file(*config.scf.core_paragraph, triplet, build_info); if (error_count != 0) { @@ -351,16 +348,13 @@ namespace vcpkg::Build } if (GlobalState::feature_packages) { - if (config.feature_list) + for (auto&& feature : config.feature_list) { - for (auto&& feature : *config.feature_list) + for (auto&& f_pgh : config.scf.feature_paragraphs) { - for (auto&& f_pgh : config.scf->feature_paragraphs) - { - if (f_pgh->name == feature) - bcf->features.push_back( - create_binary_feature_control_file(*config.scf->core_paragraph, *f_pgh, triplet)); - } + if (f_pgh->name == feature) + bcf->features.push_back( + create_binary_feature_control_file(*config.scf.core_paragraph, *f_pgh, triplet)); } } } diff --git a/toolsrc/src/vcpkg/commands.ci.cpp b/toolsrc/src/vcpkg/commands.ci.cpp index f2e984bf8..1a2f9b47f 100644 --- a/toolsrc/src/vcpkg/commands.ci.cpp +++ b/toolsrc/src/vcpkg/commands.ci.cpp @@ -27,7 +27,7 @@ namespace vcpkg::Commands::CI const std::vector specs = PackageSpec::to_package_specs(ports, triplet); StatusParagraphs status_db = database_load_check(paths); - const auto& paths_port_file = Dependencies::PathsPortFile(paths); + const auto& paths_port_file = Dependencies::PathsPortFileProvider(paths); std::vector install_plan = Dependencies::create_install_plan(paths_port_file, specs, status_db); diff --git a/toolsrc/src/vcpkg/commands.cpp b/toolsrc/src/vcpkg/commands.cpp index 15b10c7ea..ccf6fa729 100644 --- a/toolsrc/src/vcpkg/commands.cpp +++ b/toolsrc/src/vcpkg/commands.cpp @@ -13,9 +13,10 @@ namespace vcpkg::Commands Span> get_available_commands_type_a() { static std::vector> t = { - PackageNameAndFunction{"install", &Install::perform_and_exit}, + {"install", &Install::perform_and_exit}, {"ci", &CI::perform_and_exit}, {"remove", &Remove::perform_and_exit}, + {"upgrade", &Upgrade::perform_and_exit}, {"build", &Build::Command::perform_and_exit}, {"env", &Env::perform_and_exit}, {"build-external", &BuildExternal::perform_and_exit}, diff --git a/toolsrc/src/vcpkg/commands.portsdiff.cpp b/toolsrc/src/vcpkg/commands.portsdiff.cpp index 6752715e4..dba04ce5b 100644 --- a/toolsrc/src/vcpkg/commands.portsdiff.cpp +++ b/toolsrc/src/vcpkg/commands.portsdiff.cpp @@ -98,8 +98,11 @@ namespace vcpkg::Commands::PortsDiff ".vcpkg-root", git_exe.u8string()); System::cmd_execute_clean(cmd); - const std::map names_and_versions = Paragraphs::load_all_port_names_and_versions( - paths.get_filesystem(), temp_checkout_path / ports_dir_name_as_string); + const auto all_ports = + Paragraphs::load_all_ports(paths.get_filesystem(), temp_checkout_path / ports_dir_name_as_string); + std::map names_and_versions; + for (auto&& port : all_ports) + names_and_versions.emplace(port->core_paragraph->name, port->core_paragraph->version); fs.remove_all(temp_checkout_path, ec); return names_and_versions; } diff --git a/toolsrc/src/vcpkg/dependencies.cpp b/toolsrc/src/vcpkg/dependencies.cpp index 0a1f79834..a48f3f1d8 100644 --- a/toolsrc/src/vcpkg/dependencies.cpp +++ b/toolsrc/src/vcpkg/dependencies.cpp @@ -65,26 +65,19 @@ namespace vcpkg::Dependencies struct ClusterGraph : Util::MoveOnlyBase { - explicit ClusterGraph(std::unordered_map&& ports) - : m_ports(std::move(ports)) - { - } + explicit ClusterGraph(const PortFileProvider& provider) : m_provider(provider) {} Cluster& get(const PackageSpec& spec) { auto it = m_graph.find(spec); if (it == m_graph.end()) { - // Load on-demand from m_ports - auto it_ports = m_ports.find(spec.name()); - if (it_ports != m_ports.end()) - { - auto& clust = m_graph[spec]; - clust.spec = spec; - cluster_from_scf(*it_ports->second, clust); - return clust; - } - return m_graph[spec]; + // Load on-demand from m_provider + auto maybe_scf = m_provider.get_control_file(spec.name()); + auto& clust = m_graph[spec]; + clust.spec = spec; + if (auto p_scf = maybe_scf.get()) cluster_from_scf(*p_scf, clust); + return clust; } return it->second; } @@ -107,7 +100,7 @@ namespace vcpkg::Dependencies } std::unordered_map m_graph; - std::unordered_map m_ports; + const PortFileProvider& m_provider; }; std::vector AnyParagraph::dependencies(const Triplet& triplet) const @@ -124,9 +117,10 @@ namespace vcpkg::Dependencies return PackageSpec::from_dependencies_of_port(p->core_paragraph.spec.name(), deps, triplet); } - if (const auto p = this->source_paragraph.get()) + if (const auto p = this->source_control_file.value_or(nullptr)) { - return PackageSpec::from_dependencies_of_port(p->name, filter_dependencies(p->depends, triplet), triplet); + return PackageSpec::from_dependencies_of_port( + p->core_paragraph->name, filter_dependencies(p->core_paragraph->depends, triplet), triplet); } Checks::exit_with_message(VCPKG_LINE_INFO, @@ -192,11 +186,13 @@ namespace vcpkg::Dependencies return; } - if (auto p = any_paragraph.source_paragraph.get()) + if (auto p = any_paragraph.source_control_file.get()) { this->plan_type = InstallPlanType::BUILD_AND_INSTALL; return; } + + Checks::unreachable(VCPKG_LINE_INFO); } std::string InstallPlanAction::displayname() const @@ -226,12 +222,12 @@ namespace vcpkg::Dependencies const PackageSpec& AnyAction::spec() const { - if (const auto p = install_plan.get()) + if (const auto p = install_action.get()) { return p->spec; } - if (const auto p = remove_plan.get()) + if (const auto p = remove_action.get()) { return p->spec; } @@ -257,7 +253,7 @@ namespace vcpkg::Dependencies return; } - if (auto p = any_paragraph.source_paragraph.get()) + if (auto p = any_paragraph.source_control_file.get()) { this->plan_type = ExportPlanType::PORT_AVAILABLE_BUT_NOT_BUILT; return; @@ -269,21 +265,20 @@ namespace vcpkg::Dependencies return left->spec.name() < right->spec.name(); } - MapPortFile::MapPortFile(const std::unordered_map& map) : ports(map) {} + MapPortFileProvider::MapPortFileProvider(const std::unordered_map& map) : ports(map) + { + } - const SourceControlFile& MapPortFile::get_control_file(const std::string& spec) const + Optional MapPortFileProvider::get_control_file(const std::string& spec) const { auto scf = ports.find(spec); - if (scf == ports.end()) - { - Checks::exit_fail(VCPKG_LINE_INFO); - } + if (scf == ports.end()) return nullopt; return scf->second; } - PathsPortFile::PathsPortFile(const VcpkgPaths& paths) : ports(paths) {} + PathsPortFileProvider::PathsPortFileProvider(const VcpkgPaths& paths) : ports(paths) {} - const SourceControlFile& PathsPortFile::get_control_file(const std::string& spec) const + Optional PathsPortFileProvider::get_control_file(const std::string& spec) const { auto cache_it = cache.find(spec); if (cache_it != cache.end()) @@ -298,56 +293,34 @@ namespace vcpkg::Dependencies auto it = cache.emplace(spec, std::move(*scf->get())); return it.first->second; } - print_error_message(source_control_file.error()); - Checks::exit_fail(VCPKG_LINE_INFO); + return nullopt; } std::vector create_install_plan(const PortFileProvider& port_file_provider, const std::vector& specs, const StatusParagraphs& status_db) { - struct InstallAdjacencyProvider final : Graphs::AdjacencyProvider - { - const PortFileProvider& port_file_provider; - const StatusParagraphs& status_db; - const std::unordered_set& specs_as_set; + auto fspecs = Util::fmap(specs, [](const PackageSpec& spec) { return FeatureSpec(spec, ""); }); + auto plan = create_feature_install_plan(port_file_provider, fspecs, status_db); - InstallAdjacencyProvider(const PortFileProvider& port_file_provider, - const StatusParagraphs& s, - const std::unordered_set& specs_as_set) - : port_file_provider(port_file_provider), status_db(s), specs_as_set(specs_as_set) - { - } + std::vector ret; + ret.reserve(plan.size()); - std::vector adjacency_list(const InstallPlanAction& plan) const override + for (auto&& action : plan) + { + if (auto p_install = action.install_action.get()) { - if (plan.any_paragraph.status_paragraph.get()) return std::vector{}; - return plan.any_paragraph.dependencies(plan.spec.triplet()); + ret.push_back(std::move(*p_install)); } - - InstallPlanAction load_vertex_data(const PackageSpec& spec) const override + else { - const RequestType request_type = specs_as_set.find(spec) != specs_as_set.end() - ? RequestType::USER_REQUESTED - : RequestType::AUTO_SELECTED; - auto it = status_db.find_installed(spec); - if (it != status_db.end()) return InstallPlanAction{spec, {*it->get(), nullopt, nullopt}, request_type}; - return InstallPlanAction{ - spec, - {nullopt, nullopt, *port_file_provider.get_control_file(spec.name()).core_paragraph}, - request_type}; + Checks::exit_with_message(VCPKG_LINE_INFO, + "The installation plan requires feature packages support. Please re-run the " + "command with --featurepackages."); } - }; - - const std::unordered_set specs_as_set(specs.cbegin(), specs.cend()); - std::vector toposort = - Graphs::topological_sort(specs, InstallAdjacencyProvider{port_file_provider, status_db, specs_as_set}); - Util::erase_remove_if(toposort, [](const InstallPlanAction& plan) { - return plan.request_type == RequestType::AUTO_SELECTED && - plan.plan_type == InstallPlanType::ALREADY_INSTALLED; - }); + } - return toposort; + return ret; } std::vector create_remove_plan(const std::vector& specs, @@ -407,7 +380,8 @@ namespace vcpkg::Dependencies return Graphs::topological_sort(specs, RemoveAdjacencyProvider{status_db, installed_ports, specs_as_set}); } - std::vector create_export_plan(const VcpkgPaths& paths, + std::vector create_export_plan(const PortFileProvider& port_file_provider, + const VcpkgPaths& paths, const std::vector& specs, const StatusParagraphs& status_db) { @@ -415,12 +389,14 @@ namespace vcpkg::Dependencies { const VcpkgPaths& paths; const StatusParagraphs& status_db; + const PortFileProvider& provider; const std::unordered_set& specs_as_set; ExportAdjacencyProvider(const VcpkgPaths& p, const StatusParagraphs& s, + const PortFileProvider& prov, const std::unordered_set& specs_as_set) - : paths(p), status_db(s), specs_as_set(specs_as_set) + : paths(p), status_db(s), provider(prov), specs_as_set(specs_as_set) { } @@ -439,19 +415,16 @@ namespace vcpkg::Dependencies if (auto bcf = maybe_bpgh.get()) return ExportPlanAction{spec, AnyParagraph{nullopt, std::move(*bcf), nullopt}, request_type}; - auto maybe_scf = Paragraphs::try_load_port(paths.get_filesystem(), paths.port_dir(spec)); - if (auto scf = maybe_scf.get()) - return ExportPlanAction{spec, {nullopt, nullopt, *scf->get()->core_paragraph}, request_type}; - else - print_error_message(maybe_scf.error()); + auto maybe_scf = provider.get_control_file(spec.name()); + if (auto scf = maybe_scf.get()) return ExportPlanAction{spec, {nullopt, nullopt, scf}, request_type}; Checks::exit_with_message(VCPKG_LINE_INFO, "Could not find package %s", spec); } }; const std::unordered_set specs_as_set(specs.cbegin(), specs.cend()); - std::vector toposort = - Graphs::topological_sort(specs, ExportAdjacencyProvider{paths, status_db, specs_as_set}); + std::vector toposort = Graphs::topological_sort( + specs, ExportAdjacencyProvider{paths, status_db, port_file_provider, specs_as_set}); return toposort; } @@ -461,11 +434,12 @@ namespace vcpkg::Dependencies SUCCESS, }; - MarkPlusResult mark_plus(const std::string& feature, - Cluster& cluster, - ClusterGraph& pkg_to_cluster, - GraphPlan& graph_plan); - void mark_minus(Cluster& cluster, ClusterGraph& pkg_to_cluster, GraphPlan& graph_plan); + static MarkPlusResult mark_plus(const std::string& feature, + Cluster& cluster, + ClusterGraph& pkg_to_cluster, + GraphPlan& graph_plan); + + static void mark_minus(Cluster& cluster, ClusterGraph& pkg_to_cluster, GraphPlan& graph_plan); MarkPlusResult mark_plus(const std::string& feature, Cluster& cluster, ClusterGraph& graph, GraphPlan& graph_plan) { @@ -557,110 +531,80 @@ namespace vcpkg::Dependencies } } - static ClusterGraph create_feature_install_graph(const std::unordered_map& map, - const StatusParagraphs& status_db) + std::vector create_feature_install_plan(const PortFileProvider& provider, + const std::vector& specs, + const StatusParagraphs& status_db) { - std::unordered_map ptr_map; - for (auto&& p : map) - ptr_map.emplace(p.first, &p.second); - ClusterGraph graph(std::move(ptr_map)); - - auto installed_ports = get_installed_ports(status_db); - - for (auto&& status_paragraph : installed_ports) - { - Cluster& cluster = graph.get(status_paragraph->package.spec); - - cluster.transient_uninstalled = false; - - cluster.status_paragraphs.emplace_back(status_paragraph); - - auto& status_paragraph_feature = status_paragraph->package.feature; - // In this case, empty string indicates the "core" paragraph for a package. - if (status_paragraph_feature.empty()) - { - cluster.original_features.insert("core"); - } - else - { - cluster.original_features.insert(status_paragraph_feature); - } - } - - for (auto&& status_paragraph : installed_ports) - { - auto& spec = status_paragraph->package.spec; - auto& status_paragraph_feature = status_paragraph->package.feature; - auto reverse_edges = FeatureSpec::from_strings_and_triplet(status_paragraph->package.depends, - status_paragraph->package.spec.triplet()); - - for (auto&& dependency : reverse_edges) - { - auto& dep_cluster = graph.get(dependency.spec()); - - auto depends_name = dependency.feature(); - if (depends_name.empty()) depends_name = "core"; + PackageGraph pgraph(provider, status_db); + for (auto&& spec : specs) + pgraph.install(spec); - auto& target_node = dep_cluster.edges[depends_name]; - target_node.remove_edges.emplace_back(FeatureSpec{spec, status_paragraph_feature}); - } - } - return graph; + return pgraph.serialize(); } std::vector create_feature_install_plan(const std::unordered_map& map, const std::vector& specs, const StatusParagraphs& status_db) { - ClusterGraph graph = create_feature_install_graph(map, status_db); + MapPortFileProvider provider(map); + return create_feature_install_plan(provider, specs, status_db); + } - GraphPlan graph_plan; - for (auto&& spec : specs) + void PackageGraph::install(const FeatureSpec& spec) + { + Cluster& spec_cluster = m_graph->get(spec.spec()); + spec_cluster.request_type = RequestType::USER_REQUESTED; + if (spec.feature() == "*") { - Cluster& spec_cluster = graph.get(spec.spec()); - spec_cluster.request_type = RequestType::USER_REQUESTED; - if (spec.feature() == "*") + if (auto p_scf = spec_cluster.source_control_file.value_or(nullptr)) { - if (auto p_scf = spec_cluster.source_control_file.value_or(nullptr)) + for (auto&& feature : p_scf->feature_paragraphs) { - for (auto&& feature : p_scf->feature_paragraphs) - { - auto res = mark_plus(feature->name, spec_cluster, graph, graph_plan); - - Checks::check_exit(VCPKG_LINE_INFO, - res == MarkPlusResult::SUCCESS, - "Error: Unable to locate feature %s", - spec); - } - - auto res = mark_plus("core", spec_cluster, graph, graph_plan); + auto res = mark_plus(feature->name, spec_cluster, *m_graph, *m_graph_plan); Checks::check_exit( VCPKG_LINE_INFO, res == MarkPlusResult::SUCCESS, "Error: Unable to locate feature %s", spec); } - else - { - Checks::exit_with_message( - VCPKG_LINE_INFO, "Error: Unable to handle '*' because can't find CONTROL for %s", spec.spec()); - } - } - else - { - auto res = mark_plus(spec.feature(), spec_cluster, graph, graph_plan); + + auto res = mark_plus("core", spec_cluster, *m_graph, *m_graph_plan); Checks::check_exit( VCPKG_LINE_INFO, res == MarkPlusResult::SUCCESS, "Error: Unable to locate feature %s", spec); } + else + { + Checks::exit_with_message( + VCPKG_LINE_INFO, "Error: Unable to handle '*' because can't find CONTROL for %s", spec.spec()); + } + } + else + { + auto res = mark_plus(spec.feature(), spec_cluster, *m_graph, *m_graph_plan); - graph_plan.install_graph.add_vertex(ClusterPtr{&spec_cluster}); + Checks::check_exit( + VCPKG_LINE_INFO, res == MarkPlusResult::SUCCESS, "Error: Unable to locate feature %s", spec); } - Graphs::GraphAdjacencyProvider adjacency_remove_graph(graph_plan.remove_graph.adjacency_list()); - auto remove_vertex_list = graph_plan.remove_graph.vertex_list(); + m_graph_plan->install_graph.add_vertex(ClusterPtr{&spec_cluster}); + } + + void PackageGraph::upgrade(const PackageSpec& spec) + { + Cluster& spec_cluster = m_graph->get(spec); + spec_cluster.request_type = RequestType::USER_REQUESTED; + + mark_minus(spec_cluster, *m_graph, *m_graph_plan); + } + + std::vector PackageGraph::serialize() const + { + Graphs::GraphAdjacencyProvider adjacency_remove_graph(m_graph_plan->remove_graph.adjacency_list()); + auto remove_vertex_list = m_graph_plan->remove_graph.vertex_list(); auto remove_toposort = Graphs::topological_sort(remove_vertex_list, adjacency_remove_graph); - Graphs::GraphAdjacencyProvider adjacency_install_graph(graph_plan.install_graph.adjacency_list()); - auto insert_vertex_list = graph_plan.install_graph.vertex_list(); + Graphs::GraphAdjacencyProvider adjacency_install_graph( + m_graph_plan->install_graph.adjacency_list()); + auto insert_vertex_list = m_graph_plan->install_graph.vertex_list(); auto insert_toposort = Graphs::topological_sort(insert_vertex_list, adjacency_install_graph); std::vector plan; @@ -705,4 +649,162 @@ namespace vcpkg::Dependencies return plan; } + + static std::unique_ptr create_feature_install_graph(const PortFileProvider& map, + const StatusParagraphs& status_db) + { + std::unique_ptr graph = std::make_unique(map); + + auto installed_ports = get_installed_ports(status_db); + + for (auto&& status_paragraph : installed_ports) + { + Cluster& cluster = graph->get(status_paragraph->package.spec); + + cluster.transient_uninstalled = false; + + cluster.status_paragraphs.emplace_back(status_paragraph); + + auto& status_paragraph_feature = status_paragraph->package.feature; + // In this case, empty string indicates the "core" paragraph for a package. + if (status_paragraph_feature.empty()) + { + cluster.original_features.insert("core"); + } + else + { + cluster.original_features.insert(status_paragraph_feature); + } + } + + // Populate the graph with "remove edges", which are the reverse of the Build-Depends edges. + for (auto&& status_paragraph : installed_ports) + { + auto& spec = status_paragraph->package.spec; + auto& status_paragraph_feature = status_paragraph->package.feature; + auto reverse_edges = FeatureSpec::from_strings_and_triplet(status_paragraph->package.depends, + status_paragraph->package.spec.triplet()); + + for (auto&& dependency : reverse_edges) + { + auto& dep_cluster = graph->get(dependency.spec()); + + auto depends_name = dependency.feature(); + if (depends_name.empty()) depends_name = "core"; + + auto& target_node = dep_cluster.edges[depends_name]; + target_node.remove_edges.emplace_back(FeatureSpec{spec, status_paragraph_feature}); + } + } + return graph; + } + + PackageGraph::PackageGraph(const PortFileProvider& provider, const StatusParagraphs& status_db) + : m_graph(create_feature_install_graph(provider, status_db)), m_graph_plan(std::make_unique()) + { + } + + PackageGraph::~PackageGraph() {} + + void print_plan(const std::vector& action_plan, const bool is_recursive) + { + std::vector remove_plans; + std::vector rebuilt_plans; + std::vector only_install_plans; + std::vector new_plans; + std::vector already_installed_plans; + std::vector excluded; + + const bool has_non_user_requested_packages = Util::find_if(action_plan, [](const AnyAction& package) -> bool { + if (auto iplan = package.install_action.get()) + return iplan->request_type != RequestType::USER_REQUESTED; + else + return false; + }) != action_plan.cend(); + + for (auto&& action : action_plan) + { + if (auto install_action = action.install_action.get()) + { + // remove plans are guaranteed to come before install plans, so we know the plan will be contained if at + // all. + auto it = Util::find_if( + remove_plans, [&](const RemovePlanAction* plan) { return plan->spec == install_action->spec; }); + if (it != remove_plans.end()) + { + rebuilt_plans.emplace_back(install_action); + } + else + { + switch (install_action->plan_type) + { + case InstallPlanType::INSTALL: only_install_plans.emplace_back(install_action); break; + case InstallPlanType::ALREADY_INSTALLED: + if (install_action->request_type == RequestType::USER_REQUESTED) + already_installed_plans.emplace_back(install_action); + break; + case InstallPlanType::BUILD_AND_INSTALL: new_plans.emplace_back(install_action); break; + case InstallPlanType::EXCLUDED: excluded.emplace_back(install_action); break; + default: Checks::unreachable(VCPKG_LINE_INFO); + } + } + } + else if (auto remove_action = action.remove_action.get()) + { + remove_plans.emplace_back(remove_action); + } + } + + std::sort(remove_plans.begin(), remove_plans.end(), &RemovePlanAction::compare_by_name); + std::sort(rebuilt_plans.begin(), rebuilt_plans.end(), &InstallPlanAction::compare_by_name); + std::sort(only_install_plans.begin(), only_install_plans.end(), &InstallPlanAction::compare_by_name); + std::sort(new_plans.begin(), new_plans.end(), &InstallPlanAction::compare_by_name); + std::sort(already_installed_plans.begin(), already_installed_plans.end(), &InstallPlanAction::compare_by_name); + std::sort(excluded.begin(), excluded.end(), &InstallPlanAction::compare_by_name); + + static auto actions_to_output_string = [](const std::vector& v) { + return Strings::join("\n", v, [](const InstallPlanAction* p) { + return to_output_string(p->request_type, p->displayname(), p->build_options); + }); + }; + + if (excluded.size() > 0) + { + System::println("The following packages are excluded:\n%s", actions_to_output_string(excluded)); + } + + if (already_installed_plans.size() > 0) + { + System::println("The following packages are already installed:\n%s", + actions_to_output_string(already_installed_plans)); + } + + if (rebuilt_plans.size() > 0) + { + System::println("The following packages will be rebuilt:\n%s", actions_to_output_string(rebuilt_plans)); + } + + if (new_plans.size() > 0) + { + System::println("The following packages will be built and installed:\n%s", + actions_to_output_string(new_plans)); + } + + if (only_install_plans.size() > 0) + { + System::println("The following packages will be directly installed:\n%s", + actions_to_output_string(only_install_plans)); + } + + if (has_non_user_requested_packages) + System::println("Additional packages (*) will be modified to complete this operation."); + + if (remove_plans.size() > 0 && !is_recursive) + { + System::println(System::Color::warning, + "If you are sure you want to rebuild the above packages, run the command with the " + "--recurse option"); + Checks::exit_fail(VCPKG_LINE_INFO); + } + } } diff --git a/toolsrc/src/vcpkg/export.cpp b/toolsrc/src/vcpkg/export.cpp index 32cb6f03e..e3221a12f 100644 --- a/toolsrc/src/vcpkg/export.cpp +++ b/toolsrc/src/vcpkg/export.cpp @@ -478,7 +478,9 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console // create the plan const StatusParagraphs status_db = database_load_check(paths); - std::vector export_plan = Dependencies::create_export_plan(paths, opts.specs, status_db); + Dependencies::PathsPortFileProvider provider(paths); + std::vector export_plan = + Dependencies::create_export_plan(provider, paths, opts.specs, status_db); Checks::check_exit(VCPKG_LINE_INFO, !export_plan.empty(), "Export plan cannot be empty"); std::map> group_by_plan_type; diff --git a/toolsrc/src/vcpkg/help.cpp b/toolsrc/src/vcpkg/help.cpp index c83f0277b..b7d355742 100644 --- a/toolsrc/src/vcpkg/help.cpp +++ b/toolsrc/src/vcpkg/help.cpp @@ -85,6 +85,7 @@ namespace vcpkg::Help " vcpkg remove --outdated Uninstall all out-of-date packages\n" " vcpkg list List installed packages\n" " vcpkg update Display list of packages for updating\n" + " vcpkg upgrade Rebuild all outdated packages\n" " vcpkg hash [alg] Hash a file by specific algorithm, default SHA512\n" " vcpkg help topics Display the list of help topics\n" " vcpkg help Display help for a specific topic\n" diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp index 76dc7a527..dcc130be3 100644 --- a/toolsrc/src/vcpkg/install.cpp +++ b/toolsrc/src/vcpkg/install.cpp @@ -292,25 +292,13 @@ namespace vcpkg::Install System::println("Building package %s... ", display_name_with_features); auto result = [&]() -> Build::ExtendedBuildResult { - if (GlobalState::feature_packages) - { - const Build::BuildPackageConfig build_config{ - *action.any_paragraph.source_control_file.value_or_exit(VCPKG_LINE_INFO), - action.spec.triplet(), - paths.port_dir(action.spec), - action.build_options, - action.feature_list}; - return Build::build_package(paths, build_config, status_db); - } - else - { - const Build::BuildPackageConfig build_config{ - action.any_paragraph.source_paragraph.value_or_exit(VCPKG_LINE_INFO), - action.spec.triplet(), - paths.port_dir(action.spec), - action.build_options}; - return Build::build_package(paths, build_config, status_db); - } + const Build::BuildPackageConfig build_config{ + *action.any_paragraph.source_control_file.value_or_exit(VCPKG_LINE_INFO), + action.spec.triplet(), + paths.port_dir(action.spec), + action.build_options, + action.feature_list}; + return Build::build_package(paths, build_config, status_db); }(); if (result.code != Build::BuildResult::SUCCEEDED) @@ -348,108 +336,6 @@ namespace vcpkg::Install Checks::unreachable(VCPKG_LINE_INFO); } - static void print_plan(const std::vector& action_plan, const bool is_recursive) - { - std::vector remove_plans; - std::vector rebuilt_plans; - std::vector only_install_plans; - std::vector new_plans; - std::vector already_installed_plans; - std::vector excluded; - - const bool has_non_user_requested_packages = Util::find_if(action_plan, [](const AnyAction& package) -> bool { - if (auto iplan = package.install_plan.get()) - return iplan->request_type != RequestType::USER_REQUESTED; - else - return false; - }) != action_plan.cend(); - - for (auto&& action : action_plan) - { - if (auto install_action = action.install_plan.get()) - { - // remove plans are guaranteed to come before install plans, so we know the plan will be contained if at - // all. - auto it = Util::find_if( - remove_plans, [&](const RemovePlanAction* plan) { return plan->spec == install_action->spec; }); - if (it != remove_plans.end()) - { - rebuilt_plans.emplace_back(install_action); - } - else - { - switch (install_action->plan_type) - { - case InstallPlanType::INSTALL: only_install_plans.emplace_back(install_action); break; - case InstallPlanType::ALREADY_INSTALLED: - if (install_action->request_type == RequestType::USER_REQUESTED) - already_installed_plans.emplace_back(install_action); - break; - case InstallPlanType::BUILD_AND_INSTALL: new_plans.emplace_back(install_action); break; - case InstallPlanType::EXCLUDED: excluded.emplace_back(install_action); break; - default: Checks::unreachable(VCPKG_LINE_INFO); - } - } - } - else if (auto remove_action = action.remove_plan.get()) - { - remove_plans.emplace_back(remove_action); - } - } - - std::sort(remove_plans.begin(), remove_plans.end(), &RemovePlanAction::compare_by_name); - std::sort(rebuilt_plans.begin(), rebuilt_plans.end(), &InstallPlanAction::compare_by_name); - std::sort(only_install_plans.begin(), only_install_plans.end(), &InstallPlanAction::compare_by_name); - std::sort(new_plans.begin(), new_plans.end(), &InstallPlanAction::compare_by_name); - std::sort(already_installed_plans.begin(), already_installed_plans.end(), &InstallPlanAction::compare_by_name); - std::sort(excluded.begin(), excluded.end(), &InstallPlanAction::compare_by_name); - - static auto actions_to_output_string = [](const std::vector& v) { - return Strings::join("\n", v, [](const InstallPlanAction* p) { - return to_output_string(p->request_type, p->displayname(), p->build_options); - }); - }; - - if (excluded.size() > 0) - { - System::println("The following packages are excluded:\n%s", actions_to_output_string(excluded)); - } - - if (already_installed_plans.size() > 0) - { - System::println("The following packages are already installed:\n%s", - actions_to_output_string(already_installed_plans)); - } - - if (rebuilt_plans.size() > 0) - { - System::println("The following packages will be rebuilt:\n%s", actions_to_output_string(rebuilt_plans)); - } - - if (new_plans.size() > 0) - { - System::println("The following packages will be built and installed:\n%s", - actions_to_output_string(new_plans)); - } - - if (only_install_plans.size() > 0) - { - System::println("The following packages will be directly installed:\n%s", - actions_to_output_string(only_install_plans)); - } - - if (has_non_user_requested_packages) - System::println("Additional packages (*) will be installed to complete this operation."); - - if (remove_plans.size() > 0 && !is_recursive) - { - System::println(System::Color::warning, - "If you are sure you want to rebuild the above packages, run the command with the " - "--recurse option"); - Checks::exit_fail(VCPKG_LINE_INFO); - } - } - void InstallSummary::print() const { System::println("RESULTS"); @@ -499,7 +385,7 @@ namespace vcpkg::Install results.emplace_back(spec, &action); - if (const auto install_action = action.install_plan.get()) + if (const auto install_action = action.install_action.get()) { auto result = perform_install_plan_action(paths, *install_action, status_db); @@ -511,9 +397,8 @@ namespace vcpkg::Install results.back().build_result = std::move(result); } - else if (const auto remove_action = action.remove_plan.get()) + else if (const auto remove_action = action.remove_action.get()) { - Checks::check_exit(VCPKG_LINE_INFO, GlobalState::feature_packages); Remove::perform_remove_plan_action(paths, *remove_action, Remove::Purge::YES, status_db); } else @@ -676,31 +561,33 @@ namespace vcpkg::Install }; // Note: action_plan will hold raw pointers to SourceControlFiles from this map - std::unordered_map scf_map; std::vector action_plan; - if (GlobalState::feature_packages) + auto all_ports = Paragraphs::load_all_ports(paths.get_filesystem(), paths.ports); + std::unordered_map scf_map; + for (auto&& port : all_ports) + scf_map[port->core_paragraph->name] = std::move(*port); + MapPortFileProvider provider(scf_map); + + action_plan = create_feature_install_plan(provider, FullPackageSpec::to_feature_specs(specs), status_db); + + if (!GlobalState::feature_packages) { - auto all_ports = Paragraphs::load_all_ports(paths.get_filesystem(), paths.ports); - for (auto&& port : all_ports) + for (auto&& action : action_plan) { - scf_map[port->core_paragraph->name] = std::move(*port); + if (action.remove_action.has_value()) + { + Checks::exit_with_message( + VCPKG_LINE_INFO, + "The installation plan requires feature packages support. Please re-run the " + "command with --featurepackages."); + } } - action_plan = create_feature_install_plan(scf_map, FullPackageSpec::to_feature_specs(specs), status_db); - } - else - { - Dependencies::PathsPortFile paths_port_file(paths); - auto install_plan = Dependencies::create_install_plan( - paths_port_file, Util::fmap(specs, [](auto&& spec) { return spec.package_spec; }), status_db); - - action_plan = Util::fmap( - install_plan, [](InstallPlanAction& install_action) { return AnyAction(std::move(install_action)); }); } for (auto&& action : action_plan) { - if (auto p_install = action.install_plan.get()) + if (auto p_install = action.install_action.get()) { p_install->build_options = install_plan_options; if (p_install->request_type != RequestType::USER_REQUESTED) @@ -713,16 +600,16 @@ namespace vcpkg::Install // log the plan const std::string specs_string = Strings::join(",", action_plan, [](const AnyAction& action) { - if (auto iaction = action.install_plan.get()) + if (auto iaction = action.install_action.get()) return iaction->spec.to_string(); - else if (auto raction = action.remove_plan.get()) + else if (auto raction = action.remove_action.get()) return "R$" + raction->spec.to_string(); Checks::unreachable(VCPKG_LINE_INFO); }); Metrics::g_metrics.lock()->track_property("installplan", specs_string); - print_plan(action_plan, is_recursive); + Dependencies::print_plan(action_plan, is_recursive); if (dry_run) { @@ -752,7 +639,7 @@ namespace vcpkg::Install for (auto&& result : summary.results) { if (!result.action) continue; - if (auto p_install_action = result.action->install_plan.get()) + if (auto p_install_action = result.action->install_action.get()) { if (p_install_action->request_type != RequestType::USER_REQUESTED) continue; auto bpgh = result.get_binary_paragraph(); @@ -773,7 +660,7 @@ namespace vcpkg::Install { if (build_result.binary_control_file) return &build_result.binary_control_file->core_paragraph; if (action) - if (auto p_install_plan = action->install_plan.get()) + if (auto p_install_plan = action->install_action.get()) { if (auto p_bcf = p_install_plan->any_paragraph.binary_control_file.get()) return &p_bcf->core_paragraph; diff --git a/toolsrc/src/vcpkg/paragraphs.cpp b/toolsrc/src/vcpkg/paragraphs.cpp index b93de190c..b66d53994 100644 --- a/toolsrc/src/vcpkg/paragraphs.cpp +++ b/toolsrc/src/vcpkg/paragraphs.cpp @@ -289,16 +289,4 @@ namespace vcpkg::Paragraphs } return std::move(results.paragraphs); } - - std::map load_all_port_names_and_versions(const Files::Filesystem& fs, - const fs::path& ports_dir) - { - auto all_ports = load_all_ports(fs, ports_dir); - - std::map names_and_versions; - for (auto&& port : all_ports) - names_and_versions.emplace(port->core_paragraph->name, port->core_paragraph->version); - - return names_and_versions; - } } diff --git a/toolsrc/src/vcpkg/remove.cpp b/toolsrc/src/vcpkg/remove.cpp index 8ae0bc881..4079d60c1 100644 --- a/toolsrc/src/vcpkg/remove.cpp +++ b/toolsrc/src/vcpkg/remove.cpp @@ -207,10 +207,11 @@ namespace vcpkg::Remove System::println(System::Color::error, "Error: 'remove' accepts either libraries or '--outdated'"); Checks::exit_fail(VCPKG_LINE_INFO); } - specs = Util::fmap( - Update::find_outdated_packages( - Paragraphs::load_all_port_names_and_versions(paths.get_filesystem(), paths.ports), status_db), - [](auto&& outdated) { return outdated.spec; }); + + Dependencies::PathsPortFileProvider provider(paths); + + specs = Util::fmap(Update::find_outdated_packages(provider, status_db), + [](auto&& outdated) { return outdated.spec; }); if (specs.empty()) { diff --git a/toolsrc/src/vcpkg/update.cpp b/toolsrc/src/vcpkg/update.cpp index 29baef91e..d6c5614ed 100644 --- a/toolsrc/src/vcpkg/update.cpp +++ b/toolsrc/src/vcpkg/update.cpp @@ -14,7 +14,7 @@ namespace vcpkg::Update return left.spec.name() < right.spec.name(); } - std::vector find_outdated_packages(const std::map& src_names_to_versions, + std::vector find_outdated_packages(const Dependencies::PortFileProvider& provider, const StatusParagraphs& status_db) { const std::vector installed_packages = get_installed_ports(status_db); @@ -24,19 +24,23 @@ namespace vcpkg::Update { if (!pgh->package.feature.empty()) { - // Skip feature packages; only consider master packages for needing updates. + // Skip feature paragraphs; only consider master paragraphs for needing updates. continue; } - const auto it = src_names_to_versions.find(pgh->package.spec.name()); - if (it == src_names_to_versions.end()) + auto maybe_scf = provider.get_control_file(pgh->package.spec.name()); + if (auto p_scf = maybe_scf.get()) { - // Package was not installed from portfile - continue; + auto&& port_version = p_scf->core_paragraph->version; + auto&& installed_version = pgh->package.version; + if (installed_version != port_version) + { + output.push_back({pgh->package.spec, VersionDiff(installed_version, port_version)}); + } } - if (it->second != pgh->package.version) + else { - output.push_back({pgh->package.spec, VersionDiff(pgh->package.version, it->second)}); + // No portfile available } } @@ -58,10 +62,10 @@ namespace vcpkg::Update const StatusParagraphs status_db = database_load_check(paths); - const auto outdated_packages = SortedVector( - find_outdated_packages(Paragraphs::load_all_port_names_and_versions(paths.get_filesystem(), paths.ports), - status_db), - &OutdatedPackage::compare_by_name); + Dependencies::PathsPortFileProvider provider(paths); + + const auto outdated_packages = SortedVector(find_outdated_packages(provider, status_db), + &OutdatedPackage::compare_by_name); if (outdated_packages.empty()) { @@ -69,19 +73,17 @@ namespace vcpkg::Update } else { - std::string install_line; System::println("The following packages differ from their port versions:"); for (auto&& package : outdated_packages) { - install_line += package.spec.to_string(); - install_line += " "; System::println(" %-32s %s", package.spec, package.version_diff.to_string()); } System::println("\n" - "To update these packages, run\n" - " .\\vcpkg remove --outdated\n" - " .\\vcpkg install " + - install_line); + "To update these packages and all dependencies, run\n" + " .\\vcpkg upgrade\n" + "\n" + "To only remove outdated packages, run\n" + " .\\vcpkg remove --outdated\n"); } Checks::exit_success(VCPKG_LINE_INFO); diff --git a/toolsrc/vcpkglib/vcpkglib.vcxproj b/toolsrc/vcpkglib/vcpkglib.vcxproj index 9a7ad6dc0..68345ca85 100644 --- a/toolsrc/vcpkglib/vcpkglib.vcxproj +++ b/toolsrc/vcpkglib/vcpkglib.vcxproj @@ -185,6 +185,7 @@ + Create Create diff --git a/toolsrc/vcpkglib/vcpkglib.vcxproj.filters b/toolsrc/vcpkglib/vcpkglib.vcxproj.filters index 966fc7fb9..dfbcf0c7e 100644 --- a/toolsrc/vcpkglib/vcpkglib.vcxproj.filters +++ b/toolsrc/vcpkglib/vcpkglib.vcxproj.filters @@ -195,6 +195,9 @@ Source Files\vcpkg + + Source Files\vcpkg + -- cgit v1.2.3 From 0ba4b66293085601d458b52ddf30deb07b279fa1 Mon Sep 17 00:00:00 2001 From: JUAN DENT Date: Wed, 13 Dec 2017 11:55:22 -0600 Subject: Add quotation marks to support user profiles with spaces in them --- toolsrc/src/vcpkg/metrics.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/metrics.cpp b/toolsrc/src/vcpkg/metrics.cpp index a0d40e7d3..dc7bf824c 100644 --- a/toolsrc/src/vcpkg/metrics.cpp +++ b/toolsrc/src/vcpkg/metrics.cpp @@ -403,7 +403,7 @@ namespace vcpkg::Metrics fs.write_contents(vcpkg_metrics_txt_path, payload); const std::string cmd_line = - Strings::format("start %s %s", temp_folder_path_exe.u8string(), vcpkg_metrics_txt_path.u8string()); + Strings::format("start \"%s\" \"%s\"", temp_folder_path_exe.u8string(), vcpkg_metrics_txt_path.u8string()); System::cmd_execute_clean(cmd_line); #endif } -- cgit v1.2.3 From e44da2345681f60ea6d1b923672cb5042a336d12 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Wed, 13 Dec 2017 10:46:10 -0800 Subject: Revert "Add quotation marks to support user profiles with spaces in them" This reverts commit 0ba4b66293085601d458b52ddf30deb07b279fa1. --- toolsrc/src/vcpkg/metrics.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/metrics.cpp b/toolsrc/src/vcpkg/metrics.cpp index dc7bf824c..a0d40e7d3 100644 --- a/toolsrc/src/vcpkg/metrics.cpp +++ b/toolsrc/src/vcpkg/metrics.cpp @@ -403,7 +403,7 @@ namespace vcpkg::Metrics fs.write_contents(vcpkg_metrics_txt_path, payload); const std::string cmd_line = - Strings::format("start \"%s\" \"%s\"", temp_folder_path_exe.u8string(), vcpkg_metrics_txt_path.u8string()); + Strings::format("start %s %s", temp_folder_path_exe.u8string(), vcpkg_metrics_txt_path.u8string()); System::cmd_execute_clean(cmd_line); #endif } -- cgit v1.2.3 From 7a2120dba1fb606b06f555965908db438d10e019 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Wed, 13 Dec 2017 11:02:04 -0800 Subject: [vcpkg] Revert revert of #2369. --- toolsrc/include/vcpkg/commands.h | 1 + toolsrc/src/vcpkg/commands.version.cpp | 7 +++++++ toolsrc/src/vcpkg/metrics.cpp | 13 +++++++++---- 3 files changed, 17 insertions(+), 4 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/commands.h b/toolsrc/include/vcpkg/commands.h index b852a973e..c82f504e0 100644 --- a/toolsrc/include/vcpkg/commands.h +++ b/toolsrc/include/vcpkg/commands.h @@ -104,6 +104,7 @@ namespace vcpkg::Commands namespace Version { + const char* base_version(); const std::string& version(); void warn_if_vcpkg_version_mismatch(const VcpkgPaths& paths); void perform_and_exit(const VcpkgCmdArguments& args); diff --git a/toolsrc/src/vcpkg/commands.version.cpp b/toolsrc/src/vcpkg/commands.version.cpp index 3f44cf1a2..c21e8cafd 100644 --- a/toolsrc/src/vcpkg/commands.version.cpp +++ b/toolsrc/src/vcpkg/commands.version.cpp @@ -12,6 +12,13 @@ namespace vcpkg::Commands::Version { + const char* base_version() + { + return +#include "../VERSION.txt" + ; + } + const std::string& version() { static const std::string S_VERSION = diff --git a/toolsrc/src/vcpkg/metrics.cpp b/toolsrc/src/vcpkg/metrics.cpp index a0d40e7d3..cdb21d260 100644 --- a/toolsrc/src/vcpkg/metrics.cpp +++ b/toolsrc/src/vcpkg/metrics.cpp @@ -1,5 +1,6 @@ #include "pch.h" +#include #include #include @@ -376,8 +377,9 @@ namespace vcpkg::Metrics wchar_t temp_folder[MAX_PATH]; GetTempPathW(MAX_PATH, temp_folder); - const fs::path temp_folder_path = temp_folder; - const fs::path temp_folder_path_exe = temp_folder_path / "vcpkgmetricsuploader.exe"; + const fs::path temp_folder_path = fs::path(temp_folder) / "vcpkg"; + const fs::path temp_folder_path_exe = + temp_folder_path / Strings::format("vcpkgmetricsuploader-%s.exe", Commands::Version::base_version()); auto& fs = Files::get_real_filesystem(); @@ -395,6 +397,8 @@ namespace vcpkg::Metrics }(); std::error_code ec; + fs.create_directories(temp_folder_path, ec); + if (ec) return; fs.copy_file(exe_path, temp_folder_path_exe, fs::copy_options::skip_existing, ec); if (ec) return; } @@ -402,8 +406,9 @@ namespace vcpkg::Metrics const fs::path vcpkg_metrics_txt_path = temp_folder_path / ("vcpkg" + generate_random_UUID() + ".txt"); fs.write_contents(vcpkg_metrics_txt_path, payload); - const std::string cmd_line = - Strings::format("start %s %s", temp_folder_path_exe.u8string(), vcpkg_metrics_txt_path.u8string()); + const std::string cmd_line = Strings::format("start \"vcpkgmetricsuploader.exe\" \"%s\" \"%s\"", + temp_folder_path_exe.u8string(), + vcpkg_metrics_txt_path.u8string()); System::cmd_execute_clean(cmd_line); #endif } -- cgit v1.2.3 From 63a23cf0cad4da12eed69883f37c21d319461187 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Thu, 14 Dec 2017 14:31:16 -0800 Subject: [vcpkg] Fix regressions in WSL build. --- toolsrc/CMakeLists.txt | 4 +- toolsrc/include/vcpkg/base/optional.h | 6 +- toolsrc/src/commands.upgrade.cpp | 180 ------------------------------ toolsrc/src/vcpkg/base/chrono.cpp | 22 ++-- toolsrc/src/vcpkg/commands.upgrade.cpp | 180 ++++++++++++++++++++++++++++++ toolsrc/src/vcpkg/userconfig.cpp | 7 +- toolsrc/vcpkglib/vcpkglib.vcxproj | 2 +- toolsrc/vcpkglib/vcpkglib.vcxproj.filters | 2 +- 8 files changed, 207 insertions(+), 196 deletions(-) delete mode 100644 toolsrc/src/commands.upgrade.cpp create mode 100644 toolsrc/src/vcpkg/commands.upgrade.cpp (limited to 'toolsrc') diff --git a/toolsrc/CMakeLists.txt b/toolsrc/CMakeLists.txt index 51578e4e4..0168e2de2 100644 --- a/toolsrc/CMakeLists.txt +++ b/toolsrc/CMakeLists.txt @@ -3,10 +3,12 @@ project(vcpkg CXX) add_compile_options(-std=c++1z) -if(CMAKE_COMPILER_IS_GNUXX) +if(CMAKE_COMPILER_IS_GNUXX OR CMAKE_CXX_COMPILER_ID MATCHES "GNU") set(GCC 1) elseif(CMAKE_CXX_COMPILER_ID MATCHES "[Cc]lang") set(CLANG 1) +else() + message(FATAL_ERROR "Unknown compiler: ${CMAKE_CXX_COMPILER_ID}") endif() file(GLOB_RECURSE VCPKGLIB_SOURCES src/vcpkg/*.cpp) diff --git a/toolsrc/include/vcpkg/base/optional.h b/toolsrc/include/vcpkg/base/optional.h index aa9e480fd..af2d297a6 100644 --- a/toolsrc/include/vcpkg/base/optional.h +++ b/toolsrc/include/vcpkg/base/optional.h @@ -53,10 +53,8 @@ namespace vcpkg // Constructors are intentionally implicit constexpr Optional(NullOpt) {} - Optional(const T& t) : m_base(t) {} - - template::value>> - Optional(T&& t) : m_base(std::move(t)) + template + Optional(U&& t) : m_base(std::forward(t)) { } diff --git a/toolsrc/src/commands.upgrade.cpp b/toolsrc/src/commands.upgrade.cpp deleted file mode 100644 index d2c868870..000000000 --- a/toolsrc/src/commands.upgrade.cpp +++ /dev/null @@ -1,180 +0,0 @@ -#include "pch.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace vcpkg::Commands::Upgrade -{ - using Install::KeepGoing; - using Install::to_keep_going; - - static const std::string OPTION_NO_DRY_RUN = "--no-dry-run"; - static const std::string OPTION_KEEP_GOING = "--keep-going"; - - static const std::array INSTALL_SWITCHES = {{ - {OPTION_NO_DRY_RUN, "Actually upgrade"}, - {OPTION_KEEP_GOING, "Continue installing packages on failure"}, - }}; - - const CommandStructure COMMAND_STRUCTURE = { - Help::create_example_string("upgrade --no-dry-run"), - 0, - SIZE_MAX, - {INSTALL_SWITCHES, {}}, - nullptr, - }; - - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) - { - const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE); - - const bool no_dry_run = Util::Sets::contains(options.switches, OPTION_NO_DRY_RUN); - const KeepGoing keep_going = to_keep_going(Util::Sets::contains(options.switches, OPTION_KEEP_GOING)); - - StatusParagraphs status_db = database_load_check(paths); - - Dependencies::PathsPortFileProvider provider(paths); - Dependencies::PackageGraph graph(provider, status_db); - - // input sanitization - const std::vector specs = Util::fmap(args.command_arguments, [&](auto&& arg) { - return Input::check_and_get_package_spec(arg, default_triplet, COMMAND_STRUCTURE.example_text); - }); - - for (auto&& spec : specs) - { - Input::check_triplet(spec.triplet(), paths); - } - - if (specs.empty()) - { - // If no packages specified, upgrade all outdated packages. - auto outdated_packages = Update::find_outdated_packages(provider, status_db); - - if (outdated_packages.empty()) - { - System::println("All installed packages are up-to-date with the local portfiles."); - Checks::exit_success(VCPKG_LINE_INFO); - } - - for (auto&& outdated_package : outdated_packages) - graph.upgrade(outdated_package.spec); - } - else - { - std::vector not_installed; - std::vector no_portfile; - std::vector to_upgrade; - std::vector up_to_date; - - for (auto&& spec : specs) - { - auto it = status_db.find_installed(spec); - if (it == status_db.end()) - { - not_installed.push_back(spec); - } - - auto maybe_scf = provider.get_control_file(spec.name()); - if (auto p_scf = maybe_scf.get()) - { - if (it != status_db.end()) - { - if (p_scf->core_paragraph->version != (*it)->package.version) - { - to_upgrade.push_back(spec); - } - else - { - up_to_date.push_back(spec); - } - } - } - else - { - no_portfile.push_back(spec); - } - } - - Util::sort(not_installed); - Util::sort(no_portfile); - Util::sort(up_to_date); - Util::sort(to_upgrade); - - if (!up_to_date.empty()) - { - System::println(System::Color::success, "The following packages are up-to-date:"); - System::println(Strings::join( - "", up_to_date, [](const PackageSpec& spec) { return " " + spec.to_string() + "\n"; })); - } - - if (!not_installed.empty()) - { - System::println(System::Color::error, "The following packages are not installed:"); - System::println(Strings::join( - "", not_installed, [](const PackageSpec& spec) { return " " + spec.to_string() + "\n"; })); - } - - if (!no_portfile.empty()) - { - System::println(System::Color::error, "The following packages do not have a valid portfile:"); - System::println(Strings::join( - "", no_portfile, [](const PackageSpec& spec) { return " " + spec.to_string() + "\n"; })); - } - - Checks::check_exit(VCPKG_LINE_INFO, not_installed.empty() && no_portfile.empty()); - - if (to_upgrade.empty()) Checks::exit_success(VCPKG_LINE_INFO); - - for (auto&& spec : to_upgrade) - graph.upgrade(spec); - } - - auto plan = graph.serialize(); - - Checks::check_exit(VCPKG_LINE_INFO, !plan.empty()); - - const Build::BuildPackageOptions install_plan_options = { - Build::UseHeadVersion::NO, - Build::AllowDownloads::YES, - Build::CleanBuildtrees::NO, - }; - - // Set build settings for all install actions - for (auto&& action : plan) - { - if (auto p_install = action.install_action.get()) - { - p_install->build_options = install_plan_options; - } - } - - Dependencies::print_plan(plan, true); - - if (!no_dry_run) - { - System::println(System::Color::warning, - "If you are sure you want to rebuild the above packages, run this command with the " - "--no-dry-run option."); - Checks::exit_fail(VCPKG_LINE_INFO); - } - - const Install::InstallSummary summary = Install::perform(plan, keep_going, paths, status_db); - - System::println("\nTotal elapsed time: %s\n", summary.total_elapsed_time); - - if (keep_going == KeepGoing::YES) - { - summary.print(); - } - - Checks::exit_success(VCPKG_LINE_INFO); - } -} diff --git a/toolsrc/src/vcpkg/base/chrono.cpp b/toolsrc/src/vcpkg/base/chrono.cpp index 03c1ecce9..00f8ba3f1 100644 --- a/toolsrc/src/vcpkg/base/chrono.cpp +++ b/toolsrc/src/vcpkg/base/chrono.cpp @@ -92,14 +92,20 @@ namespace vcpkg::Chrono Optional CTime::parse(CStringView str) { CTime ret; - auto assigned = sscanf_s(str.c_str(), - "%d-%d-%dT%d:%d:%d.", - &ret.m_tm.tm_year, - &ret.m_tm.tm_mon, - &ret.m_tm.tm_mday, - &ret.m_tm.tm_hour, - &ret.m_tm.tm_min, - &ret.m_tm.tm_sec); + auto assigned = +#if defined(_WIN32) + sscanf_s +#else + sscanf +#endif + (str.c_str(), + "%d-%d-%dT%d:%d:%d.", + &ret.m_tm.tm_year, + &ret.m_tm.tm_mon, + &ret.m_tm.tm_mday, + &ret.m_tm.tm_hour, + &ret.m_tm.tm_min, + &ret.m_tm.tm_sec); if (assigned != 6) return nullopt; if (ret.m_tm.tm_year < 1900) return nullopt; ret.m_tm.tm_year -= 1900; diff --git a/toolsrc/src/vcpkg/commands.upgrade.cpp b/toolsrc/src/vcpkg/commands.upgrade.cpp new file mode 100644 index 000000000..d2c868870 --- /dev/null +++ b/toolsrc/src/vcpkg/commands.upgrade.cpp @@ -0,0 +1,180 @@ +#include "pch.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace vcpkg::Commands::Upgrade +{ + using Install::KeepGoing; + using Install::to_keep_going; + + static const std::string OPTION_NO_DRY_RUN = "--no-dry-run"; + static const std::string OPTION_KEEP_GOING = "--keep-going"; + + static const std::array INSTALL_SWITCHES = {{ + {OPTION_NO_DRY_RUN, "Actually upgrade"}, + {OPTION_KEEP_GOING, "Continue installing packages on failure"}, + }}; + + const CommandStructure COMMAND_STRUCTURE = { + Help::create_example_string("upgrade --no-dry-run"), + 0, + SIZE_MAX, + {INSTALL_SWITCHES, {}}, + nullptr, + }; + + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) + { + const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE); + + const bool no_dry_run = Util::Sets::contains(options.switches, OPTION_NO_DRY_RUN); + const KeepGoing keep_going = to_keep_going(Util::Sets::contains(options.switches, OPTION_KEEP_GOING)); + + StatusParagraphs status_db = database_load_check(paths); + + Dependencies::PathsPortFileProvider provider(paths); + Dependencies::PackageGraph graph(provider, status_db); + + // input sanitization + const std::vector specs = Util::fmap(args.command_arguments, [&](auto&& arg) { + return Input::check_and_get_package_spec(arg, default_triplet, COMMAND_STRUCTURE.example_text); + }); + + for (auto&& spec : specs) + { + Input::check_triplet(spec.triplet(), paths); + } + + if (specs.empty()) + { + // If no packages specified, upgrade all outdated packages. + auto outdated_packages = Update::find_outdated_packages(provider, status_db); + + if (outdated_packages.empty()) + { + System::println("All installed packages are up-to-date with the local portfiles."); + Checks::exit_success(VCPKG_LINE_INFO); + } + + for (auto&& outdated_package : outdated_packages) + graph.upgrade(outdated_package.spec); + } + else + { + std::vector not_installed; + std::vector no_portfile; + std::vector to_upgrade; + std::vector up_to_date; + + for (auto&& spec : specs) + { + auto it = status_db.find_installed(spec); + if (it == status_db.end()) + { + not_installed.push_back(spec); + } + + auto maybe_scf = provider.get_control_file(spec.name()); + if (auto p_scf = maybe_scf.get()) + { + if (it != status_db.end()) + { + if (p_scf->core_paragraph->version != (*it)->package.version) + { + to_upgrade.push_back(spec); + } + else + { + up_to_date.push_back(spec); + } + } + } + else + { + no_portfile.push_back(spec); + } + } + + Util::sort(not_installed); + Util::sort(no_portfile); + Util::sort(up_to_date); + Util::sort(to_upgrade); + + if (!up_to_date.empty()) + { + System::println(System::Color::success, "The following packages are up-to-date:"); + System::println(Strings::join( + "", up_to_date, [](const PackageSpec& spec) { return " " + spec.to_string() + "\n"; })); + } + + if (!not_installed.empty()) + { + System::println(System::Color::error, "The following packages are not installed:"); + System::println(Strings::join( + "", not_installed, [](const PackageSpec& spec) { return " " + spec.to_string() + "\n"; })); + } + + if (!no_portfile.empty()) + { + System::println(System::Color::error, "The following packages do not have a valid portfile:"); + System::println(Strings::join( + "", no_portfile, [](const PackageSpec& spec) { return " " + spec.to_string() + "\n"; })); + } + + Checks::check_exit(VCPKG_LINE_INFO, not_installed.empty() && no_portfile.empty()); + + if (to_upgrade.empty()) Checks::exit_success(VCPKG_LINE_INFO); + + for (auto&& spec : to_upgrade) + graph.upgrade(spec); + } + + auto plan = graph.serialize(); + + Checks::check_exit(VCPKG_LINE_INFO, !plan.empty()); + + const Build::BuildPackageOptions install_plan_options = { + Build::UseHeadVersion::NO, + Build::AllowDownloads::YES, + Build::CleanBuildtrees::NO, + }; + + // Set build settings for all install actions + for (auto&& action : plan) + { + if (auto p_install = action.install_action.get()) + { + p_install->build_options = install_plan_options; + } + } + + Dependencies::print_plan(plan, true); + + if (!no_dry_run) + { + System::println(System::Color::warning, + "If you are sure you want to rebuild the above packages, run this command with the " + "--no-dry-run option."); + Checks::exit_fail(VCPKG_LINE_INFO); + } + + const Install::InstallSummary summary = Install::perform(plan, keep_going, paths, status_db); + + System::println("\nTotal elapsed time: %s\n", summary.total_elapsed_time); + + if (keep_going == KeepGoing::YES) + { + summary.print(); + } + + Checks::exit_success(VCPKG_LINE_INFO); + } +} diff --git a/toolsrc/src/vcpkg/userconfig.cpp b/toolsrc/src/vcpkg/userconfig.cpp index d13a46f41..906594691 100644 --- a/toolsrc/src/vcpkg/userconfig.cpp +++ b/toolsrc/src/vcpkg/userconfig.cpp @@ -5,6 +5,7 @@ #include #include +#if defined(_WIN32) namespace { static vcpkg::Lazy s_localappdata; @@ -24,13 +25,14 @@ namespace }); } } +#endif namespace vcpkg { UserConfig UserConfig::try_read_data(const Files::Filesystem& fs) { UserConfig ret; - +#if defined(_WIN32) try { auto maybe_pghs = Paragraphs::get_paragraphs(fs, get_localappdata() / "vcpkg" / "config"); @@ -56,12 +58,14 @@ namespace vcpkg catch (...) { } +#endif return ret; } void UserConfig::try_write_data(Files::Filesystem& fs) const { +#if defined(_WIN32) try { std::error_code ec; @@ -79,5 +83,6 @@ namespace vcpkg catch (...) { } +#endif } } diff --git a/toolsrc/vcpkglib/vcpkglib.vcxproj b/toolsrc/vcpkglib/vcpkglib.vcxproj index 68345ca85..455891f85 100644 --- a/toolsrc/vcpkglib/vcpkglib.vcxproj +++ b/toolsrc/vcpkglib/vcpkglib.vcxproj @@ -185,7 +185,6 @@ - Create Create @@ -221,6 +220,7 @@ + diff --git a/toolsrc/vcpkglib/vcpkglib.vcxproj.filters b/toolsrc/vcpkglib/vcpkglib.vcxproj.filters index dfbcf0c7e..f8f517ad7 100644 --- a/toolsrc/vcpkglib/vcpkglib.vcxproj.filters +++ b/toolsrc/vcpkglib/vcpkglib.vcxproj.filters @@ -195,7 +195,7 @@ Source Files\vcpkg - + Source Files\vcpkg -- cgit v1.2.3 From 5ac69dd02bef426d71ed1e58923345c9042c37dc Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Mon, 18 Dec 2017 23:00:11 -0800 Subject: [vcpkg] Improve error message upon graph cycle detected. --- toolsrc/include/vcpkg/base/graphs.h | 155 +++++++++++++---------------------- toolsrc/include/vcpkg/dependencies.h | 1 - toolsrc/src/vcpkg/dependencies.cpp | 11 +-- 3 files changed, 63 insertions(+), 104 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/base/graphs.h b/toolsrc/include/vcpkg/base/graphs.h index b585d2bb9..bd22bbcb0 100644 --- a/toolsrc/include/vcpkg/base/graphs.h +++ b/toolsrc/include/vcpkg/base/graphs.h @@ -4,6 +4,7 @@ #include #include +#include namespace vcpkg::Graphs { @@ -23,139 +24,97 @@ namespace vcpkg::Graphs struct AdjacencyProvider { virtual std::vector adjacency_list(const U& vertex) const = 0; - + virtual std::string to_string(const V& vertex) const = 0; virtual U load_vertex_data(const V& vertex) const = 0; }; - template - static void topological_sort_internal(const V& vertex, - const AdjacencyProvider& f, - std::unordered_map& exploration_status, - std::vector& sorted) + namespace details { - ExplorationStatus& status = exploration_status[vertex]; - switch (status) + template + void topological_sort_internal(const V& vertex, + const AdjacencyProvider& f, + std::unordered_map& exploration_status, + std::vector& sorted) { - case ExplorationStatus::FULLY_EXPLORED: return; - case ExplorationStatus::PARTIALLY_EXPLORED: Checks::exit_with_message(VCPKG_LINE_INFO, "cycle in graph"); - case ExplorationStatus::NOT_EXPLORED: + ExplorationStatus& status = exploration_status[vertex]; + switch (status) { - status = ExplorationStatus::PARTIALLY_EXPLORED; - U vertex_data = f.load_vertex_data(vertex); - for (const V& neighbour : f.adjacency_list(vertex_data)) - topological_sort_internal(neighbour, f, exploration_status, sorted); - - sorted.push_back(std::move(vertex_data)); - status = ExplorationStatus::FULLY_EXPLORED; - return; + case ExplorationStatus::FULLY_EXPLORED: return; + case ExplorationStatus::PARTIALLY_EXPLORED: + { + System::println("Cycle detected within graph:"); + for (auto&& node : exploration_status) + { + if (node.second == ExplorationStatus::PARTIALLY_EXPLORED) + { + System::println(" %s", f.to_string(node.first)); + } + } + Checks::exit_fail(VCPKG_LINE_INFO); + } + case ExplorationStatus::NOT_EXPLORED: + { + status = ExplorationStatus::PARTIALLY_EXPLORED; + U vertex_data = f.load_vertex_data(vertex); + for (const V& neighbour : f.adjacency_list(vertex_data)) + topological_sort_internal(neighbour, f, exploration_status, sorted); + + sorted.push_back(std::move(vertex_data)); + status = ExplorationStatus::FULLY_EXPLORED; + return; + } + default: Checks::unreachable(VCPKG_LINE_INFO); } - default: Checks::unreachable(VCPKG_LINE_INFO); } } - template - std::vector topological_sort(const std::vector& starting_vertices, const AdjacencyProvider& f) + template + std::vector topological_sort(const VertexRange& starting_vertices, const AdjacencyProvider& f) { std::vector sorted; std::unordered_map exploration_status; - for (auto& vertex : starting_vertices) + for (auto&& vertex : starting_vertices) { - topological_sort_internal(vertex, f, exploration_status, sorted); + details::topological_sort_internal(vertex, f, exploration_status, sorted); } return sorted; } template - struct GraphAdjacencyProvider final : AdjacencyProvider - { - const std::unordered_map>& vertices; - - GraphAdjacencyProvider(const std::unordered_map>& vertices) : vertices(vertices) {} - - std::vector adjacency_list(const V& vertex) const override - { - const std::unordered_set& as_set = this->vertices.at(vertex); - return std::vector(as_set.cbegin(), as_set.cend()); // TODO: Avoid redundant copy - } - - V load_vertex_data(const V& vertex) const override { return vertex; } - }; - - template - struct Graph + struct Graph final : AdjacencyProvider { public: - void add_vertex(V v) { this->vertices[v]; } + void add_vertex(const V& v) { this->m_edges[v]; } - // TODO: Change with iterators - void add_vertices(const std::vector& vs) + void add_edge(const V& u, const V& v) { - for (const V& v : vs) - { - this->vertices[v]; - } + this->m_edges[v]; + this->m_edges[u].insert(v); } - void add_edge(V u, V v) + std::vector vertex_list() const { - this->vertices[v]; - this->vertices[u].insert(v); + std::vector vertex_list; + for (auto&& vertex : this->m_edges) + vertex_list.emplace_back(vertex.first); + return vertex_list; } - std::vector topological_sort() const + std::vector adjacency_list(const V& vertex) const override { - GraphAdjacencyProvider adjacency_provider{this->vertices}; - std::unordered_map indegrees = count_indegrees(); - - std::vector sorted; - sorted.reserve(indegrees.size()); - - std::unordered_map exploration_status; - exploration_status.reserve(indegrees.size()); - - for (auto& pair : indegrees) - { - if (pair.second == 0) // Starting from vertices with indegree == 0. Not required. - { - V vertex = pair.first; - topological_sort_internal(vertex, adjacency_provider, exploration_status, sorted); - } - } - - return sorted; + const std::unordered_set& as_set = this->m_edges.at(vertex); + return std::vector(as_set.cbegin(), as_set.cend()); // TODO: Avoid redundant copy } - std::unordered_map count_indegrees() const - { - std::unordered_map indegrees; - - for (auto& pair : this->vertices) - { - indegrees[pair.first]; - for (V neighbour : pair.second) - { - ++indegrees[neighbour]; - } - } - - return indegrees; - } + V load_vertex_data(const V& vertex) const override { return vertex; } - const std::unordered_map>& adjacency_list() const { return this->vertices; } - std::vector vertex_list() const - { - // why no &? it returns 0 - std::vector vertex_list; - for (const auto& vertex : this->vertices) - { - vertex_list.emplace_back(vertex.first); - } - return vertex_list; - } + // Note: this function indicates how tied this template is to the exact type it will be templated upon. + // Possible fix: This type shouldn't implement to_string() and should instead be derived from? + std::string to_string(const V& spec) const override { return spec->spec.to_string(); } private: - std::unordered_map> vertices; + std::unordered_map> m_edges; }; } diff --git a/toolsrc/include/vcpkg/dependencies.h b/toolsrc/include/vcpkg/dependencies.h index 8a082efca..8902a7b08 100644 --- a/toolsrc/include/vcpkg/dependencies.h +++ b/toolsrc/include/vcpkg/dependencies.h @@ -1,6 +1,5 @@ #pragma once -#include #include #include #include diff --git a/toolsrc/src/vcpkg/dependencies.cpp b/toolsrc/src/vcpkg/dependencies.cpp index a48f3f1d8..76aeb0eaa 100644 --- a/toolsrc/src/vcpkg/dependencies.cpp +++ b/toolsrc/src/vcpkg/dependencies.cpp @@ -373,6 +373,8 @@ namespace vcpkg::Dependencies } return RemovePlanAction{spec, RemovePlanType::REMOVE, request_type}; } + + std::string to_string(const PackageSpec& spec) const override { return spec.to_string(); } }; const std::vector& installed_ports = get_installed_ports(status_db); @@ -420,6 +422,8 @@ namespace vcpkg::Dependencies Checks::exit_with_message(VCPKG_LINE_INFO, "Could not find package %s", spec); } + + std::string to_string(const PackageSpec& spec) const override { return spec.to_string(); } }; const std::unordered_set specs_as_set(specs.cbegin(), specs.cend()); @@ -598,14 +602,11 @@ namespace vcpkg::Dependencies std::vector PackageGraph::serialize() const { - Graphs::GraphAdjacencyProvider adjacency_remove_graph(m_graph_plan->remove_graph.adjacency_list()); auto remove_vertex_list = m_graph_plan->remove_graph.vertex_list(); - auto remove_toposort = Graphs::topological_sort(remove_vertex_list, adjacency_remove_graph); + auto remove_toposort = Graphs::topological_sort(remove_vertex_list, m_graph_plan->remove_graph); - Graphs::GraphAdjacencyProvider adjacency_install_graph( - m_graph_plan->install_graph.adjacency_list()); auto insert_vertex_list = m_graph_plan->install_graph.vertex_list(); - auto insert_toposort = Graphs::topological_sort(insert_vertex_list, adjacency_install_graph); + auto insert_toposort = Graphs::topological_sort(insert_vertex_list, m_graph_plan->install_graph); std::vector plan; -- cgit v1.2.3 From a6ee2c145fca2006848ef9afbf580ea88bee7dd1 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Tue, 19 Dec 2017 10:22:43 -0800 Subject: [vcpkg-list] Improve list output for long triplets --- toolsrc/src/vcpkg/binaryparagraph.cpp | 5 +++-- toolsrc/src/vcpkg/commands.list.cpp | 8 ++++---- 2 files changed, 7 insertions(+), 6 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/binaryparagraph.cpp b/toolsrc/src/vcpkg/binaryparagraph.cpp index c7136b713..7c9e905e8 100644 --- a/toolsrc/src/vcpkg/binaryparagraph.cpp +++ b/toolsrc/src/vcpkg/binaryparagraph.cpp @@ -92,8 +92,9 @@ namespace vcpkg std::string BinaryParagraph::displayname() const { - const auto f = this->feature.empty() ? "core" : this->feature; - return Strings::format("%s[%s]:%s", this->spec.name(), f, this->spec.triplet()); + if (this->feature.empty() || this->feature == "core") + return Strings::format("%s:%s", this->spec.name(), this->spec.triplet()); + return Strings::format("%s[%s]:%s", this->spec.name(), this->feature, this->spec.triplet()); } std::string BinaryParagraph::dir() const { return this->spec.dir(); } diff --git a/toolsrc/src/vcpkg/commands.list.cpp b/toolsrc/src/vcpkg/commands.list.cpp index 1f2387843..960c57225 100644 --- a/toolsrc/src/vcpkg/commands.list.cpp +++ b/toolsrc/src/vcpkg/commands.list.cpp @@ -13,14 +13,14 @@ namespace vcpkg::Commands::List { if (full_desc) { - System::println("%-30s %-16s %s", pgh.package.displayname(), pgh.package.version, pgh.package.description); + System::println("%-50s %-16s %s", pgh.package.displayname(), pgh.package.version, pgh.package.description); } else { - System::println("%-30s %-16s %s", - vcpkg::shorten_text(pgh.package.displayname(), 30), + System::println("%-50s %-16s %s", + vcpkg::shorten_text(pgh.package.displayname(), 50), vcpkg::shorten_text(pgh.package.version, 16), - vcpkg::shorten_text(pgh.package.description, 71)); + vcpkg::shorten_text(pgh.package.description, 51)); } } -- cgit v1.2.3 From a24ccdfc01aba83b833af528b8f1a6ec6db020a4 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Thu, 19 Oct 2017 17:19:11 -0700 Subject: [vcpkg-build-cmake] Build at IDLE priority. Try to detect out-of-memory issues in the linker, and restart the build once. --- toolsrc/src/vcpkg/base/system.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/base/system.cpp b/toolsrc/src/vcpkg/base/system.cpp index 625ee6ce0..84721bf6e 100644 --- a/toolsrc/src/vcpkg/base/system.cpp +++ b/toolsrc/src/vcpkg/base/system.cpp @@ -220,7 +220,7 @@ namespace vcpkg::System nullptr, nullptr, FALSE, - BELOW_NORMAL_PRIORITY_CLASS | CREATE_UNICODE_ENVIRONMENT, + IDLE_PRIORITY_CLASS | CREATE_UNICODE_ENVIRONMENT, env_cstr.data(), nullptr, &startup_info, -- cgit v1.2.3 From 2d0a76370ead152896411d17aa19934235b93d1c Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 21 Dec 2017 16:28:13 -0800 Subject: clang-tidy fixes --- toolsrc/include/vcpkg/sourceparagraph.h | 3 ++- toolsrc/include/vcpkg/versiont.h | 2 +- toolsrc/src/vcpkg.cpp | 14 +++++----- toolsrc/src/vcpkg/base/chrono.cpp | 2 +- toolsrc/src/vcpkg/base/cofffilereader.cpp | 2 +- toolsrc/src/vcpkg/base/files.cpp | 4 +-- toolsrc/src/vcpkg/build.cpp | 11 ++++---- toolsrc/src/vcpkg/commands.cache.cpp | 2 +- toolsrc/src/vcpkg/commands.create.cpp | 2 +- toolsrc/src/vcpkg/commands.exportifw.cpp | 6 ++--- toolsrc/src/vcpkg/commands.integrate.cpp | 2 +- toolsrc/src/vcpkg/commands.list.cpp | 2 +- toolsrc/src/vcpkg/export.cpp | 4 +-- toolsrc/src/vcpkg/install.cpp | 2 +- toolsrc/src/vcpkg/metrics.cpp | 43 ++++++++++++++----------------- toolsrc/src/vcpkg/remove.cpp | 4 +-- toolsrc/src/vcpkg/sourceparagraph.cpp | 6 ++--- toolsrc/src/vcpkg/statusparagraphs.cpp | 2 +- toolsrc/src/vcpkg/update.cpp | 3 ++- toolsrc/src/vcpkg/userconfig.cpp | 2 +- toolsrc/src/vcpkg/vcpkgpaths.cpp | 4 +-- toolsrc/src/vcpkg/versiont.cpp | 2 +- 22 files changed, 61 insertions(+), 63 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/sourceparagraph.h b/toolsrc/include/vcpkg/sourceparagraph.h index dcbbc1c3b..58e76b7b1 100644 --- a/toolsrc/include/vcpkg/sourceparagraph.h +++ b/toolsrc/include/vcpkg/sourceparagraph.h @@ -14,11 +14,12 @@ namespace vcpkg { struct Dependency { + static Dependency parse_dependency(std::string&& name, std::string&& qualifier); + Features depend; std::string qualifier; std::string name() const; - static Dependency parse_dependency(std::string name, std::string qualifier); }; std::vector filter_dependencies(const std::vector& deps, const Triplet& t); diff --git a/toolsrc/include/vcpkg/versiont.h b/toolsrc/include/vcpkg/versiont.h index 6d8332521..0ffb4d602 100644 --- a/toolsrc/include/vcpkg/versiont.h +++ b/toolsrc/include/vcpkg/versiont.h @@ -6,7 +6,7 @@ namespace vcpkg struct VersionT { VersionT(); - VersionT(const std::string& value); + VersionT(std::string&& value); const std::string& to_string() const; diff --git a/toolsrc/src/vcpkg.cpp b/toolsrc/src/vcpkg.cpp index 094ea1dc5..08dd3fcf6 100644 --- a/toolsrc/src/vcpkg.cpp +++ b/toolsrc/src/vcpkg.cpp @@ -4,7 +4,7 @@ #pragma warning(push) #pragma warning(disable : 4768) -#include +#include #pragma warning(pop) #else #include @@ -21,10 +21,8 @@ #include #include #include -#include #include -#include #include #include @@ -49,7 +47,7 @@ static void inner(const VcpkgCmdArguments& args) Checks::exit_fail(VCPKG_LINE_INFO); } - static const auto find_command = [&](auto&& commands) { + static const auto FIND_COMMAND = [&](auto&& commands) { auto it = Util::find_if(commands, [&](auto&& commandc) { return Strings::case_insensitive_ascii_equals(commandc.name, args.command); }); @@ -62,7 +60,7 @@ static void inner(const VcpkgCmdArguments& args) return static_cast(nullptr); }; - if (const auto command_function = find_command(Commands::get_available_commands_type_c())) + if (const auto command_function = FIND_COMMAND(Commands::get_available_commands_type_c())) { return command_function->function(args); } @@ -136,7 +134,7 @@ static void inner(const VcpkgCmdArguments& args) } } - if (const auto command_function = find_command(Commands::get_available_commands_type_b())) + if (const auto command_function = FIND_COMMAND(Commands::get_available_commands_type_b())) { return command_function->function(args, paths); } @@ -161,7 +159,7 @@ static void inner(const VcpkgCmdArguments& args) Input::check_triplet(default_triplet, paths); - if (const auto command_function = find_command(Commands::get_available_commands_type_a())) + if (const auto command_function = FIND_COMMAND(Commands::get_available_commands_type_a())) { return command_function->function(args, paths, default_triplet); } @@ -214,7 +212,7 @@ static void load_config() static std::string trim_path_from_command_line(const std::string& full_command_line) { Checks::check_exit( - VCPKG_LINE_INFO, full_command_line.size() > 0, "Internal failure - cannot have empty command line"); + VCPKG_LINE_INFO, !full_command_line.empty(), "Internal failure - cannot have empty command line"); if (full_command_line[0] == '"') { diff --git a/toolsrc/src/vcpkg/base/chrono.cpp b/toolsrc/src/vcpkg/base/chrono.cpp index 00f8ba3f1..d83106c8b 100644 --- a/toolsrc/src/vcpkg/base/chrono.cpp +++ b/toolsrc/src/vcpkg/base/chrono.cpp @@ -15,7 +15,7 @@ namespace vcpkg::Chrono using std::chrono::nanoseconds; using std::chrono::seconds; - const double nanos_as_double = static_cast(nanos.count()); + const auto nanos_as_double = static_cast(nanos.count()); if (duration_cast(nanos) > hours()) { diff --git a/toolsrc/src/vcpkg/base/cofffilereader.cpp b/toolsrc/src/vcpkg/base/cofffilereader.cpp index 1927e0b5e..27426eb0a 100644 --- a/toolsrc/src/vcpkg/base/cofffilereader.cpp +++ b/toolsrc/src/vcpkg/base/cofffilereader.cpp @@ -223,7 +223,7 @@ namespace vcpkg::CoffFileReader static const char* FILE_START = "!\n"; static const size_t FILE_START_SIZE = 8; - fs.seekg(fs.beg); + fs.seekg(fstream::beg); char file_start[FILE_START_SIZE]; fs.read(file_start, FILE_START_SIZE); diff --git a/toolsrc/src/vcpkg/base/files.cpp b/toolsrc/src/vcpkg/base/files.cpp index 8c9e137ed..7e4cfbf6a 100644 --- a/toolsrc/src/vcpkg/base/files.cpp +++ b/toolsrc/src/vcpkg/base/files.cpp @@ -18,9 +18,9 @@ namespace vcpkg::Files return std::make_error_code(std::errc::no_such_file_or_directory); } - file_stream.seekg(0, file_stream.end); + file_stream.seekg(0, std::fstream::end); auto length = file_stream.tellg(); - file_stream.seekg(0, file_stream.beg); + file_stream.seekg(0, std::fstream::beg); if (length > SIZE_MAX) { diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index f43d8788e..16f7a400f 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -60,7 +60,8 @@ namespace vcpkg::Build::Command spec.name()); const StatusParagraphs status_db = database_load_check(paths); - const Build::BuildPackageOptions build_package_options{Build::UseHeadVersion::NO, Build::AllowDownloads::YES}; + const Build::BuildPackageOptions build_package_options{ + Build::UseHeadVersion::NO, Build::AllowDownloads::YES, Build::CleanBuildtrees::NO}; const std::unordered_set features_as_set(full_spec.features.begin(), full_spec.features.end()); @@ -192,7 +193,7 @@ namespace vcpkg::Build for (auto&& host : host_architectures) { - auto it = Util::find_if(toolset.supported_architectures, [&](const ToolsetArchOption& opt) { + const auto it = Util::find_if(toolset.supported_architectures, [&](const ToolsetArchOption& opt) { return host == opt.host_arch && target_arch == opt.target_arch; }); if (it != toolset.supported_architectures.end()) return it->name; @@ -294,7 +295,7 @@ namespace vcpkg::Build { features.append(feature + ";"); } - if (features.size() > 0) + if (!features.empty()) { features.pop_back(); } @@ -364,7 +365,7 @@ namespace vcpkg::Build if (config.build_package_options.clean_buildtrees == CleanBuildtrees::YES) { auto& fs = paths.get_filesystem(); - auto buildtrees_dir = paths.buildtrees / spec.name(); + const auto buildtrees_dir = paths.buildtrees / spec.name(); auto buildtree_files = fs.get_files_non_recursive(buildtrees_dir); for (auto&& file : buildtree_files) { @@ -500,7 +501,7 @@ namespace vcpkg::Build const std::vector lines = Strings::split(ec_data.output, "\n"); - PreBuildInfo pre_build_info; + PreBuildInfo pre_build_info{}; const auto e = lines.cend(); auto cur = std::find(lines.cbegin(), e, FLAG_GUID); diff --git a/toolsrc/src/vcpkg/commands.cache.cpp b/toolsrc/src/vcpkg/commands.cache.cpp index 6fd123b7c..85bf5fb4d 100644 --- a/toolsrc/src/vcpkg/commands.cache.cpp +++ b/toolsrc/src/vcpkg/commands.cache.cpp @@ -47,7 +47,7 @@ namespace vcpkg::Commands::Cache Checks::exit_success(VCPKG_LINE_INFO); } - if (args.command_arguments.size() == 0) + if (args.command_arguments.empty()) { for (const BinaryParagraph& binary_paragraph : binary_paragraphs) { diff --git a/toolsrc/src/vcpkg/commands.create.cpp b/toolsrc/src/vcpkg/commands.create.cpp index 44f5f7928..25c34cf09 100644 --- a/toolsrc/src/vcpkg/commands.create.cpp +++ b/toolsrc/src/vcpkg/commands.create.cpp @@ -34,7 +34,7 @@ namespace vcpkg::Commands::Create R"(Filename cannot contain invalid chars %s, but was %s)", Files::FILESYSTEM_INVALID_CHARACTERS, zip_file_name); - cmake_args.push_back({"FILENAME", zip_file_name}); + cmake_args.emplace_back("FILENAME", zip_file_name); } const std::string cmd_launch_cmake = make_cmake_cmd(cmake_exe, paths.ports_cmake, cmake_args); diff --git a/toolsrc/src/vcpkg/commands.exportifw.cpp b/toolsrc/src/vcpkg/commands.exportifw.cpp index 682267acb..96c0e2215 100644 --- a/toolsrc/src/vcpkg/commands.exportifw.cpp +++ b/toolsrc/src/vcpkg/commands.exportifw.cpp @@ -139,14 +139,14 @@ namespace vcpkg::Export::IFW )###", create_release_date())); - for (auto package = unique_packages.begin(); package != unique_packages.end(); ++package) + for (const auto& unique_package : unique_packages) { - const ExportPlanAction& action = *(package->second); + const ExportPlanAction& action = *(unique_package.second); const BinaryParagraph& binary_paragraph = action.any_paragraph.binary_control_file.value_or_exit(VCPKG_LINE_INFO).core_paragraph; package_xml_file_path = - raw_exported_dir_path / Strings::format("packages.%s", package->first) / "meta" / "package.xml"; + raw_exported_dir_path / Strings::format("packages.%s", unique_package.first) / "meta" / "package.xml"; package_xml_dir_path = package_xml_file_path.parent_path(); fs.create_directories(package_xml_dir_path, ec); Checks::check_exit(VCPKG_LINE_INFO, diff --git a/toolsrc/src/vcpkg/commands.integrate.cpp b/toolsrc/src/vcpkg/commands.integrate.cpp index 460e99b88..0f647a40f 100644 --- a/toolsrc/src/vcpkg/commands.integrate.cpp +++ b/toolsrc/src/vcpkg/commands.integrate.cpp @@ -191,7 +191,7 @@ namespace vcpkg::Commands::Integrate const auto found = std::regex_search(*contents_data, match, RE); if (found) { - const int ver = atoi(match[1].str().c_str()); + const auto ver = strtol(match[1].str().c_str(), nullptr, 10); if (ver >= 1) should_install_system = false; } } diff --git a/toolsrc/src/vcpkg/commands.list.cpp b/toolsrc/src/vcpkg/commands.list.cpp index 960c57225..66939a68a 100644 --- a/toolsrc/src/vcpkg/commands.list.cpp +++ b/toolsrc/src/vcpkg/commands.list.cpp @@ -57,7 +57,7 @@ namespace vcpkg::Commands::List return lhs->package.displayname() < rhs->package.displayname(); }); - if (args.command_arguments.size() == 0) + if (args.command_arguments.empty()) { for (const StatusParagraph* status_paragraph : installed_packages) { diff --git a/toolsrc/src/vcpkg/export.cpp b/toolsrc/src/vcpkg/export.cpp index e3221a12f..11e810339 100644 --- a/toolsrc/src/vcpkg/export.cpp +++ b/toolsrc/src/vcpkg/export.cpp @@ -69,8 +69,8 @@ namespace vcpkg::Export { static constexpr std::array ORDER = {ExportPlanType::ALREADY_BUILT, ExportPlanType::PORT_AVAILABLE_BUT_NOT_BUILT}; - static constexpr Build::BuildPackageOptions build_options = {Build::UseHeadVersion::NO, - Build::AllowDownloads::YES}; + static constexpr Build::BuildPackageOptions build_options = { + Build::UseHeadVersion::NO, Build::AllowDownloads::YES, Build::CleanBuildtrees::NO}; for (const ExportPlanType plan_type : ORDER) { diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp index dcc130be3..88c9d8882 100644 --- a/toolsrc/src/vcpkg/install.cpp +++ b/toolsrc/src/vcpkg/install.cpp @@ -159,7 +159,7 @@ namespace vcpkg::Install auto package_files = Util::fmap(package_file_paths, [package_remove_char_count](const fs::path& path) { std::string as_string = path.generic_string(); as_string.erase(0, package_remove_char_count); - return std::move(as_string); + return as_string; }); return SortedVector(std::move(package_files)); diff --git a/toolsrc/src/vcpkg/metrics.cpp b/toolsrc/src/vcpkg/metrics.cpp index cdb21d260..818a9066c 100644 --- a/toolsrc/src/vcpkg/metrics.cpp +++ b/toolsrc/src/vcpkg/metrics.cpp @@ -152,7 +152,7 @@ namespace vcpkg::Metrics void track_property(const std::string& name, const std::string& value) { - if (properties.size() != 0) properties.push_back(','); + if (!properties.empty()) properties.push_back(','); properties.append(to_json_string(name)); properties.push_back(':'); properties.append(to_json_string(value)); @@ -160,7 +160,7 @@ namespace vcpkg::Metrics void track_metric(const std::string& name, double value) { - if (measurements.size() != 0) measurements.push_back(','); + if (!measurements.empty()) measurements.push_back(','); measurements.append(to_json_string(name)); measurements.push_back(':'); measurements.append(std::to_string(value)); @@ -302,7 +302,7 @@ namespace vcpkg::Metrics { if (MAXDWORD <= payload.size()) abort(); std::wstring hdrs = L"Content-Type: application/json\r\n"; - std::string& p = const_cast(payload); + auto& p = const_cast(payload); results = WinHttpSendRequest(request, hdrs.c_str(), static_cast(hdrs.size()), @@ -383,30 +383,27 @@ namespace vcpkg::Metrics auto& fs = Files::get_real_filesystem(); - if (true) - { - const fs::path exe_path = [&fs]() -> fs::path { - auto vcpkgdir = System::get_exe_path_of_current_process().parent_path(); - auto path = vcpkgdir / "vcpkgmetricsuploader.exe"; - if (fs.exists(path)) return path; - - path = vcpkgdir / "scripts" / "vcpkgmetricsuploader.exe"; - if (fs.exists(path)) return path; - - return ""; - }(); - - std::error_code ec; - fs.create_directories(temp_folder_path, ec); - if (ec) return; - fs.copy_file(exe_path, temp_folder_path_exe, fs::copy_options::skip_existing, ec); - if (ec) return; - } + const fs::path exe_path = [&fs]() -> fs::path { + auto vcpkgdir = System::get_exe_path_of_current_process().parent_path(); + auto path = vcpkgdir / "vcpkgmetricsuploader.exe"; + if (fs.exists(path)) return path; + + path = vcpkgdir / "scripts" / "vcpkgmetricsuploader.exe"; + if (fs.exists(path)) return path; + + return ""; + }(); + + std::error_code ec; + fs.create_directories(temp_folder_path, ec); + if (ec) return; + 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"); fs.write_contents(vcpkg_metrics_txt_path, payload); - const std::string cmd_line = Strings::format("start \"vcpkgmetricsuploader.exe\" \"%s\" \"%s\"", + const std::string cmd_line = Strings::format(R"(start "vcpkgmetricsuploader.exe" "%s" "%s")", temp_folder_path_exe.u8string(), vcpkg_metrics_txt_path.u8string()); System::cmd_execute_clean(cmd_line); diff --git a/toolsrc/src/vcpkg/remove.cpp b/toolsrc/src/vcpkg/remove.cpp index 4079d60c1..ed2c02b9f 100644 --- a/toolsrc/src/vcpkg/remove.cpp +++ b/toolsrc/src/vcpkg/remove.cpp @@ -202,7 +202,7 @@ namespace vcpkg::Remove std::vector specs; if (Util::Sets::contains(options.switches, OPTION_OUTDATED)) { - if (args.command_arguments.size() != 0) + if (!args.command_arguments.empty()) { System::println(System::Color::error, "Error: 'remove' accepts either libraries or '--outdated'"); Checks::exit_fail(VCPKG_LINE_INFO); @@ -221,7 +221,7 @@ namespace vcpkg::Remove } else { - if (args.command_arguments.size() < 1) + if (args.command_arguments.empty()) { System::println(System::Color::error, "Error: 'remove' accepts either libraries or '--outdated'"); Checks::exit_fail(VCPKG_LINE_INFO); diff --git a/toolsrc/src/vcpkg/sourceparagraph.cpp b/toolsrc/src/vcpkg/sourceparagraph.cpp index 2a9480538..4da0cfcfc 100644 --- a/toolsrc/src/vcpkg/sourceparagraph.cpp +++ b/toolsrc/src/vcpkg/sourceparagraph.cpp @@ -158,7 +158,7 @@ namespace vcpkg return std::move(control_file); } - Dependency Dependency::parse_dependency(std::string name, std::string qualifier) + Dependency Dependency::parse_dependency(std::string&& name, std::string&& qualifier) { Dependency dep; dep.qualifier = qualifier; @@ -182,7 +182,7 @@ namespace vcpkg { return Util::fmap(depends, [&](const std::string& depend_string) -> Dependency { auto pos = depend_string.find(' '); - if (pos == std::string::npos) return Dependency::parse_dependency(depend_string, ""); + if (pos == std::string::npos) return Dependency::parse_dependency(std::string{depend_string}, ""); // expect of the form "\w+ \[\w+\]" Dependency dep; @@ -190,7 +190,7 @@ namespace vcpkg if (depend_string.c_str()[pos + 1] != '(' || depend_string[depend_string.size() - 1] != ')') { // Error, but for now just slurp the entire string. - return Dependency::parse_dependency(depend_string, ""); + return Dependency::parse_dependency(std::string{depend_string}, ""); } dep.qualifier = depend_string.substr(pos + 2, depend_string.size() - pos - 3); return dep; diff --git a/toolsrc/src/vcpkg/statusparagraphs.cpp b/toolsrc/src/vcpkg/statusparagraphs.cpp index d4afc0427..d516b6284 100644 --- a/toolsrc/src/vcpkg/statusparagraphs.cpp +++ b/toolsrc/src/vcpkg/statusparagraphs.cpp @@ -47,7 +47,7 @@ namespace vcpkg StatusParagraphs::const_iterator StatusParagraphs::find_installed(const std::string& name, const Triplet& triplet) const { - const const_iterator it = find(name, triplet); + const auto it = find(name, triplet); if (it != end() && (*it)->want == Want::INSTALL && (*it)->state == InstallState::INSTALLED) { return it; diff --git a/toolsrc/src/vcpkg/update.cpp b/toolsrc/src/vcpkg/update.cpp index d6c5614ed..9f89da13c 100644 --- a/toolsrc/src/vcpkg/update.cpp +++ b/toolsrc/src/vcpkg/update.cpp @@ -35,7 +35,8 @@ namespace vcpkg::Update auto&& installed_version = pgh->package.version; if (installed_version != port_version) { - output.push_back({pgh->package.spec, VersionDiff(installed_version, port_version)}); + output.push_back( + {pgh->package.spec, VersionDiff(std::string{installed_version}, std::string{port_version})}); } } else diff --git a/toolsrc/src/vcpkg/userconfig.cpp b/toolsrc/src/vcpkg/userconfig.cpp index 906594691..45ed01ec6 100644 --- a/toolsrc/src/vcpkg/userconfig.cpp +++ b/toolsrc/src/vcpkg/userconfig.cpp @@ -41,7 +41,7 @@ namespace vcpkg const auto& pghs = *p_pghs; std::unordered_map keys; - if (pghs.size() > 0) keys = pghs[0]; + if (!pghs.empty()) keys = pghs[0]; for (size_t x = 1; x < pghs.size(); ++x) { diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index e64a681e2..cbf1e97e1 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -50,14 +50,14 @@ namespace vcpkg const std::string& version_check_arguments, const std::array& expected_version) { - auto it = Util::find_if(candidate_paths, [&](const fs::path& p) { + const auto it = Util::find_if(candidate_paths, [&](const fs::path& p) { const std::string cmd = Strings::format(R"("%s" %s)", p.u8string(), version_check_arguments); return exists_and_has_equal_or_greater_version(cmd, expected_version); }); if (it != candidate_paths.cend()) { - return std::move(*it); + return *it; } return nullopt; diff --git a/toolsrc/src/vcpkg/versiont.cpp b/toolsrc/src/vcpkg/versiont.cpp index 91f7e23ef..cff49d9e8 100644 --- a/toolsrc/src/vcpkg/versiont.cpp +++ b/toolsrc/src/vcpkg/versiont.cpp @@ -6,7 +6,7 @@ namespace vcpkg { VersionT::VersionT() : value("0.0.0") {} - VersionT::VersionT(const std::string& value) : value(value) {} + VersionT::VersionT(std::string&& value) : value(std::move(value)) {} const std::string& VersionT::to_string() const { return value; } bool operator==(const VersionT& left, const VersionT& right) { return left.to_string() == right.to_string(); } bool operator!=(const VersionT& left, const VersionT& right) { return left.to_string() != right.to_string(); } -- cgit v1.2.3 From 7cc7c28e209b6fe7b037c59c9fa83a763e337bb8 Mon Sep 17 00:00:00 2001 From: Stanislav Ershov Date: Sat, 23 Dec 2017 17:26:05 +0300 Subject: [vcpkg-hash] Replace certutil.exe with cmake built-in hash commands --- toolsrc/include/vcpkg/commands.h | 2 +- toolsrc/src/vcpkg/commands.cpp | 7 ++++--- toolsrc/src/vcpkg/commands.hash.cpp | 16 +++++++++------- 3 files changed, 14 insertions(+), 11 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/commands.h b/toolsrc/include/vcpkg/commands.h index c82f504e0..31c750b38 100644 --- a/toolsrc/include/vcpkg/commands.h +++ b/toolsrc/include/vcpkg/commands.h @@ -119,7 +119,7 @@ namespace vcpkg::Commands namespace Hash { - void perform_and_exit(const VcpkgCmdArguments& args); + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); } template diff --git a/toolsrc/src/vcpkg/commands.cpp b/toolsrc/src/vcpkg/commands.cpp index ccf6fa729..d9c0e54cd 100644 --- a/toolsrc/src/vcpkg/commands.cpp +++ b/toolsrc/src/vcpkg/commands.cpp @@ -41,7 +41,9 @@ namespace vcpkg::Commands {"import", &Import::perform_and_exit}, {"cache", &Cache::perform_and_exit}, {"portsdiff", &PortsDiff::perform_and_exit}, - {"autocomplete", &Autocomplete::perform_and_exit}}; + {"autocomplete", &Autocomplete::perform_and_exit}, + {"hash", &Hash::perform_and_exit}, + }; return t; } @@ -49,8 +51,7 @@ namespace vcpkg::Commands { static std::vector> t = { {"version", &Version::perform_and_exit}, - {"contact", &Contact::perform_and_exit}, - {"hash", &Hash::perform_and_exit}, + {"contact", &Contact::perform_and_exit} }; return t; } diff --git a/toolsrc/src/vcpkg/commands.hash.cpp b/toolsrc/src/vcpkg/commands.hash.cpp index a5940ea1e..1e3e5b23d 100644 --- a/toolsrc/src/vcpkg/commands.hash.cpp +++ b/toolsrc/src/vcpkg/commands.hash.cpp @@ -7,15 +7,17 @@ namespace vcpkg::Commands::Hash { - static void do_file_hash(fs::path const& path, std::string const& hash_type) + static void do_file_hash(fs::path const &cmake_exe_path, fs::path const& path, std::string const& hash_type) { - const auto cmd_line = Strings::format(R"(CertUtil.exe -hashfile "%s" %s)", path.u8string().c_str(), hash_type); + const std::string cmd_line = Strings::format( + R"("%s" -E %ssum %s)", cmake_exe_path.u8string(), Strings::ascii_to_lowercase(hash_type), path.u8string()); + const auto ec_data = System::cmd_execute_and_capture_output(cmd_line); Checks::check_exit(VCPKG_LINE_INFO, ec_data.exit_code == 0, "Running command:\n %s\n failed", cmd_line); std::string const& output = ec_data.output; - const auto start = output.find_first_of("\r\n"); + const auto start = output.find_first_of(" "); Checks::check_exit( VCPKG_LINE_INFO, start != std::string::npos, "Unexpected output format from command: %s", cmd_line); @@ -23,7 +25,7 @@ namespace vcpkg::Commands::Hash Checks::check_exit( VCPKG_LINE_INFO, end != std::string::npos, "Unexpected output format from command: %s", cmd_line); - auto hash = output.substr(start, end - start); + auto hash = output.substr(0, start); Util::erase_remove_if(hash, isspace); System::println(hash); } @@ -37,17 +39,17 @@ namespace vcpkg::Commands::Hash nullptr, }; - void perform_and_exit(const VcpkgCmdArguments& args) + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { args.parse_arguments(COMMAND_STRUCTURE); if (args.command_arguments.size() == 1) { - do_file_hash(args.command_arguments[0], "SHA512"); + do_file_hash(paths.get_cmake_exe(), args.command_arguments[0], "SHA512"); } if (args.command_arguments.size() == 2) { - do_file_hash(args.command_arguments[0], args.command_arguments[1]); + do_file_hash(paths.get_cmake_exe(), args.command_arguments[0], args.command_arguments[1]); } Checks::exit_success(VCPKG_LINE_INFO); -- cgit v1.2.3 From 332414111dcc1eee316aa93c1c5e74699a521709 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Sat, 23 Dec 2017 07:29:12 -0800 Subject: Revert "clang-tidy fixes" This reverts commit 2d0a76370ead152896411d17aa19934235b93d1c. --- toolsrc/include/vcpkg/sourceparagraph.h | 3 +-- toolsrc/include/vcpkg/versiont.h | 2 +- toolsrc/src/vcpkg.cpp | 14 +++++----- toolsrc/src/vcpkg/base/chrono.cpp | 2 +- toolsrc/src/vcpkg/base/cofffilereader.cpp | 2 +- toolsrc/src/vcpkg/base/files.cpp | 4 +-- toolsrc/src/vcpkg/build.cpp | 11 ++++---- toolsrc/src/vcpkg/commands.cache.cpp | 2 +- toolsrc/src/vcpkg/commands.create.cpp | 2 +- toolsrc/src/vcpkg/commands.exportifw.cpp | 6 ++--- toolsrc/src/vcpkg/commands.integrate.cpp | 2 +- toolsrc/src/vcpkg/commands.list.cpp | 2 +- toolsrc/src/vcpkg/export.cpp | 4 +-- toolsrc/src/vcpkg/install.cpp | 2 +- toolsrc/src/vcpkg/metrics.cpp | 43 +++++++++++++++++-------------- toolsrc/src/vcpkg/remove.cpp | 4 +-- toolsrc/src/vcpkg/sourceparagraph.cpp | 6 ++--- toolsrc/src/vcpkg/statusparagraphs.cpp | 2 +- toolsrc/src/vcpkg/update.cpp | 3 +-- toolsrc/src/vcpkg/userconfig.cpp | 2 +- toolsrc/src/vcpkg/vcpkgpaths.cpp | 4 +-- toolsrc/src/vcpkg/versiont.cpp | 2 +- 22 files changed, 63 insertions(+), 61 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/sourceparagraph.h b/toolsrc/include/vcpkg/sourceparagraph.h index 58e76b7b1..dcbbc1c3b 100644 --- a/toolsrc/include/vcpkg/sourceparagraph.h +++ b/toolsrc/include/vcpkg/sourceparagraph.h @@ -14,12 +14,11 @@ namespace vcpkg { struct Dependency { - static Dependency parse_dependency(std::string&& name, std::string&& qualifier); - Features depend; std::string qualifier; std::string name() const; + static Dependency parse_dependency(std::string name, std::string qualifier); }; std::vector filter_dependencies(const std::vector& deps, const Triplet& t); diff --git a/toolsrc/include/vcpkg/versiont.h b/toolsrc/include/vcpkg/versiont.h index 0ffb4d602..6d8332521 100644 --- a/toolsrc/include/vcpkg/versiont.h +++ b/toolsrc/include/vcpkg/versiont.h @@ -6,7 +6,7 @@ namespace vcpkg struct VersionT { VersionT(); - VersionT(std::string&& value); + VersionT(const std::string& value); const std::string& to_string() const; diff --git a/toolsrc/src/vcpkg.cpp b/toolsrc/src/vcpkg.cpp index 08dd3fcf6..094ea1dc5 100644 --- a/toolsrc/src/vcpkg.cpp +++ b/toolsrc/src/vcpkg.cpp @@ -4,7 +4,7 @@ #pragma warning(push) #pragma warning(disable : 4768) -#include +#include #pragma warning(pop) #else #include @@ -21,8 +21,10 @@ #include #include #include +#include #include +#include #include #include @@ -47,7 +49,7 @@ static void inner(const VcpkgCmdArguments& args) Checks::exit_fail(VCPKG_LINE_INFO); } - static const auto FIND_COMMAND = [&](auto&& commands) { + static const auto find_command = [&](auto&& commands) { auto it = Util::find_if(commands, [&](auto&& commandc) { return Strings::case_insensitive_ascii_equals(commandc.name, args.command); }); @@ -60,7 +62,7 @@ static void inner(const VcpkgCmdArguments& args) return static_cast(nullptr); }; - if (const auto command_function = FIND_COMMAND(Commands::get_available_commands_type_c())) + if (const auto command_function = find_command(Commands::get_available_commands_type_c())) { return command_function->function(args); } @@ -134,7 +136,7 @@ static void inner(const VcpkgCmdArguments& args) } } - if (const auto command_function = FIND_COMMAND(Commands::get_available_commands_type_b())) + if (const auto command_function = find_command(Commands::get_available_commands_type_b())) { return command_function->function(args, paths); } @@ -159,7 +161,7 @@ static void inner(const VcpkgCmdArguments& args) Input::check_triplet(default_triplet, paths); - if (const auto command_function = FIND_COMMAND(Commands::get_available_commands_type_a())) + if (const auto command_function = find_command(Commands::get_available_commands_type_a())) { return command_function->function(args, paths, default_triplet); } @@ -212,7 +214,7 @@ static void load_config() static std::string trim_path_from_command_line(const std::string& full_command_line) { Checks::check_exit( - VCPKG_LINE_INFO, !full_command_line.empty(), "Internal failure - cannot have empty command line"); + VCPKG_LINE_INFO, full_command_line.size() > 0, "Internal failure - cannot have empty command line"); if (full_command_line[0] == '"') { diff --git a/toolsrc/src/vcpkg/base/chrono.cpp b/toolsrc/src/vcpkg/base/chrono.cpp index d83106c8b..00f8ba3f1 100644 --- a/toolsrc/src/vcpkg/base/chrono.cpp +++ b/toolsrc/src/vcpkg/base/chrono.cpp @@ -15,7 +15,7 @@ namespace vcpkg::Chrono using std::chrono::nanoseconds; using std::chrono::seconds; - const auto nanos_as_double = static_cast(nanos.count()); + const double nanos_as_double = static_cast(nanos.count()); if (duration_cast(nanos) > hours()) { diff --git a/toolsrc/src/vcpkg/base/cofffilereader.cpp b/toolsrc/src/vcpkg/base/cofffilereader.cpp index 27426eb0a..1927e0b5e 100644 --- a/toolsrc/src/vcpkg/base/cofffilereader.cpp +++ b/toolsrc/src/vcpkg/base/cofffilereader.cpp @@ -223,7 +223,7 @@ namespace vcpkg::CoffFileReader static const char* FILE_START = "!\n"; static const size_t FILE_START_SIZE = 8; - fs.seekg(fstream::beg); + fs.seekg(fs.beg); char file_start[FILE_START_SIZE]; fs.read(file_start, FILE_START_SIZE); diff --git a/toolsrc/src/vcpkg/base/files.cpp b/toolsrc/src/vcpkg/base/files.cpp index 7e4cfbf6a..8c9e137ed 100644 --- a/toolsrc/src/vcpkg/base/files.cpp +++ b/toolsrc/src/vcpkg/base/files.cpp @@ -18,9 +18,9 @@ namespace vcpkg::Files return std::make_error_code(std::errc::no_such_file_or_directory); } - file_stream.seekg(0, std::fstream::end); + file_stream.seekg(0, file_stream.end); auto length = file_stream.tellg(); - file_stream.seekg(0, std::fstream::beg); + file_stream.seekg(0, file_stream.beg); if (length > SIZE_MAX) { diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index 16f7a400f..f43d8788e 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -60,8 +60,7 @@ namespace vcpkg::Build::Command spec.name()); const StatusParagraphs status_db = database_load_check(paths); - const Build::BuildPackageOptions build_package_options{ - Build::UseHeadVersion::NO, Build::AllowDownloads::YES, Build::CleanBuildtrees::NO}; + const Build::BuildPackageOptions build_package_options{Build::UseHeadVersion::NO, Build::AllowDownloads::YES}; const std::unordered_set features_as_set(full_spec.features.begin(), full_spec.features.end()); @@ -193,7 +192,7 @@ namespace vcpkg::Build for (auto&& host : host_architectures) { - const auto it = Util::find_if(toolset.supported_architectures, [&](const ToolsetArchOption& opt) { + auto it = Util::find_if(toolset.supported_architectures, [&](const ToolsetArchOption& opt) { return host == opt.host_arch && target_arch == opt.target_arch; }); if (it != toolset.supported_architectures.end()) return it->name; @@ -295,7 +294,7 @@ namespace vcpkg::Build { features.append(feature + ";"); } - if (!features.empty()) + if (features.size() > 0) { features.pop_back(); } @@ -365,7 +364,7 @@ namespace vcpkg::Build if (config.build_package_options.clean_buildtrees == CleanBuildtrees::YES) { auto& fs = paths.get_filesystem(); - const auto buildtrees_dir = paths.buildtrees / spec.name(); + auto buildtrees_dir = paths.buildtrees / spec.name(); auto buildtree_files = fs.get_files_non_recursive(buildtrees_dir); for (auto&& file : buildtree_files) { @@ -501,7 +500,7 @@ namespace vcpkg::Build const std::vector lines = Strings::split(ec_data.output, "\n"); - PreBuildInfo pre_build_info{}; + PreBuildInfo pre_build_info; const auto e = lines.cend(); auto cur = std::find(lines.cbegin(), e, FLAG_GUID); diff --git a/toolsrc/src/vcpkg/commands.cache.cpp b/toolsrc/src/vcpkg/commands.cache.cpp index 85bf5fb4d..6fd123b7c 100644 --- a/toolsrc/src/vcpkg/commands.cache.cpp +++ b/toolsrc/src/vcpkg/commands.cache.cpp @@ -47,7 +47,7 @@ namespace vcpkg::Commands::Cache Checks::exit_success(VCPKG_LINE_INFO); } - if (args.command_arguments.empty()) + if (args.command_arguments.size() == 0) { for (const BinaryParagraph& binary_paragraph : binary_paragraphs) { diff --git a/toolsrc/src/vcpkg/commands.create.cpp b/toolsrc/src/vcpkg/commands.create.cpp index 25c34cf09..44f5f7928 100644 --- a/toolsrc/src/vcpkg/commands.create.cpp +++ b/toolsrc/src/vcpkg/commands.create.cpp @@ -34,7 +34,7 @@ namespace vcpkg::Commands::Create R"(Filename cannot contain invalid chars %s, but was %s)", Files::FILESYSTEM_INVALID_CHARACTERS, zip_file_name); - cmake_args.emplace_back("FILENAME", zip_file_name); + cmake_args.push_back({"FILENAME", zip_file_name}); } const std::string cmd_launch_cmake = make_cmake_cmd(cmake_exe, paths.ports_cmake, cmake_args); diff --git a/toolsrc/src/vcpkg/commands.exportifw.cpp b/toolsrc/src/vcpkg/commands.exportifw.cpp index 96c0e2215..682267acb 100644 --- a/toolsrc/src/vcpkg/commands.exportifw.cpp +++ b/toolsrc/src/vcpkg/commands.exportifw.cpp @@ -139,14 +139,14 @@ namespace vcpkg::Export::IFW )###", create_release_date())); - for (const auto& unique_package : unique_packages) + for (auto package = unique_packages.begin(); package != unique_packages.end(); ++package) { - const ExportPlanAction& action = *(unique_package.second); + const ExportPlanAction& action = *(package->second); const BinaryParagraph& binary_paragraph = action.any_paragraph.binary_control_file.value_or_exit(VCPKG_LINE_INFO).core_paragraph; package_xml_file_path = - raw_exported_dir_path / Strings::format("packages.%s", unique_package.first) / "meta" / "package.xml"; + raw_exported_dir_path / Strings::format("packages.%s", package->first) / "meta" / "package.xml"; package_xml_dir_path = package_xml_file_path.parent_path(); fs.create_directories(package_xml_dir_path, ec); Checks::check_exit(VCPKG_LINE_INFO, diff --git a/toolsrc/src/vcpkg/commands.integrate.cpp b/toolsrc/src/vcpkg/commands.integrate.cpp index 0f647a40f..460e99b88 100644 --- a/toolsrc/src/vcpkg/commands.integrate.cpp +++ b/toolsrc/src/vcpkg/commands.integrate.cpp @@ -191,7 +191,7 @@ namespace vcpkg::Commands::Integrate const auto found = std::regex_search(*contents_data, match, RE); if (found) { - const auto ver = strtol(match[1].str().c_str(), nullptr, 10); + const int ver = atoi(match[1].str().c_str()); if (ver >= 1) should_install_system = false; } } diff --git a/toolsrc/src/vcpkg/commands.list.cpp b/toolsrc/src/vcpkg/commands.list.cpp index 66939a68a..960c57225 100644 --- a/toolsrc/src/vcpkg/commands.list.cpp +++ b/toolsrc/src/vcpkg/commands.list.cpp @@ -57,7 +57,7 @@ namespace vcpkg::Commands::List return lhs->package.displayname() < rhs->package.displayname(); }); - if (args.command_arguments.empty()) + if (args.command_arguments.size() == 0) { for (const StatusParagraph* status_paragraph : installed_packages) { diff --git a/toolsrc/src/vcpkg/export.cpp b/toolsrc/src/vcpkg/export.cpp index 11e810339..e3221a12f 100644 --- a/toolsrc/src/vcpkg/export.cpp +++ b/toolsrc/src/vcpkg/export.cpp @@ -69,8 +69,8 @@ namespace vcpkg::Export { static constexpr std::array ORDER = {ExportPlanType::ALREADY_BUILT, ExportPlanType::PORT_AVAILABLE_BUT_NOT_BUILT}; - static constexpr Build::BuildPackageOptions build_options = { - Build::UseHeadVersion::NO, Build::AllowDownloads::YES, Build::CleanBuildtrees::NO}; + static constexpr Build::BuildPackageOptions build_options = {Build::UseHeadVersion::NO, + Build::AllowDownloads::YES}; for (const ExportPlanType plan_type : ORDER) { diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp index 88c9d8882..dcc130be3 100644 --- a/toolsrc/src/vcpkg/install.cpp +++ b/toolsrc/src/vcpkg/install.cpp @@ -159,7 +159,7 @@ namespace vcpkg::Install auto package_files = Util::fmap(package_file_paths, [package_remove_char_count](const fs::path& path) { std::string as_string = path.generic_string(); as_string.erase(0, package_remove_char_count); - return as_string; + return std::move(as_string); }); return SortedVector(std::move(package_files)); diff --git a/toolsrc/src/vcpkg/metrics.cpp b/toolsrc/src/vcpkg/metrics.cpp index 818a9066c..cdb21d260 100644 --- a/toolsrc/src/vcpkg/metrics.cpp +++ b/toolsrc/src/vcpkg/metrics.cpp @@ -152,7 +152,7 @@ namespace vcpkg::Metrics void track_property(const std::string& name, const std::string& value) { - if (!properties.empty()) properties.push_back(','); + if (properties.size() != 0) properties.push_back(','); properties.append(to_json_string(name)); properties.push_back(':'); properties.append(to_json_string(value)); @@ -160,7 +160,7 @@ namespace vcpkg::Metrics void track_metric(const std::string& name, double value) { - if (!measurements.empty()) measurements.push_back(','); + if (measurements.size() != 0) measurements.push_back(','); measurements.append(to_json_string(name)); measurements.push_back(':'); measurements.append(std::to_string(value)); @@ -302,7 +302,7 @@ namespace vcpkg::Metrics { if (MAXDWORD <= payload.size()) abort(); std::wstring hdrs = L"Content-Type: application/json\r\n"; - auto& p = const_cast(payload); + std::string& p = const_cast(payload); results = WinHttpSendRequest(request, hdrs.c_str(), static_cast(hdrs.size()), @@ -383,27 +383,30 @@ namespace vcpkg::Metrics auto& fs = Files::get_real_filesystem(); - const fs::path exe_path = [&fs]() -> fs::path { - auto vcpkgdir = System::get_exe_path_of_current_process().parent_path(); - auto path = vcpkgdir / "vcpkgmetricsuploader.exe"; - if (fs.exists(path)) return path; - - path = vcpkgdir / "scripts" / "vcpkgmetricsuploader.exe"; - if (fs.exists(path)) return path; - - return ""; - }(); - - std::error_code ec; - fs.create_directories(temp_folder_path, ec); - if (ec) return; - fs.copy_file(exe_path, temp_folder_path_exe, fs::copy_options::skip_existing, ec); - if (ec) return; + if (true) + { + const fs::path exe_path = [&fs]() -> fs::path { + auto vcpkgdir = System::get_exe_path_of_current_process().parent_path(); + auto path = vcpkgdir / "vcpkgmetricsuploader.exe"; + if (fs.exists(path)) return path; + + path = vcpkgdir / "scripts" / "vcpkgmetricsuploader.exe"; + if (fs.exists(path)) return path; + + return ""; + }(); + + std::error_code ec; + fs.create_directories(temp_folder_path, ec); + if (ec) return; + 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"); fs.write_contents(vcpkg_metrics_txt_path, payload); - const std::string cmd_line = Strings::format(R"(start "vcpkgmetricsuploader.exe" "%s" "%s")", + const std::string cmd_line = Strings::format("start \"vcpkgmetricsuploader.exe\" \"%s\" \"%s\"", temp_folder_path_exe.u8string(), vcpkg_metrics_txt_path.u8string()); System::cmd_execute_clean(cmd_line); diff --git a/toolsrc/src/vcpkg/remove.cpp b/toolsrc/src/vcpkg/remove.cpp index ed2c02b9f..4079d60c1 100644 --- a/toolsrc/src/vcpkg/remove.cpp +++ b/toolsrc/src/vcpkg/remove.cpp @@ -202,7 +202,7 @@ namespace vcpkg::Remove std::vector specs; if (Util::Sets::contains(options.switches, OPTION_OUTDATED)) { - if (!args.command_arguments.empty()) + if (args.command_arguments.size() != 0) { System::println(System::Color::error, "Error: 'remove' accepts either libraries or '--outdated'"); Checks::exit_fail(VCPKG_LINE_INFO); @@ -221,7 +221,7 @@ namespace vcpkg::Remove } else { - if (args.command_arguments.empty()) + if (args.command_arguments.size() < 1) { System::println(System::Color::error, "Error: 'remove' accepts either libraries or '--outdated'"); Checks::exit_fail(VCPKG_LINE_INFO); diff --git a/toolsrc/src/vcpkg/sourceparagraph.cpp b/toolsrc/src/vcpkg/sourceparagraph.cpp index 4da0cfcfc..2a9480538 100644 --- a/toolsrc/src/vcpkg/sourceparagraph.cpp +++ b/toolsrc/src/vcpkg/sourceparagraph.cpp @@ -158,7 +158,7 @@ namespace vcpkg return std::move(control_file); } - Dependency Dependency::parse_dependency(std::string&& name, std::string&& qualifier) + Dependency Dependency::parse_dependency(std::string name, std::string qualifier) { Dependency dep; dep.qualifier = qualifier; @@ -182,7 +182,7 @@ namespace vcpkg { return Util::fmap(depends, [&](const std::string& depend_string) -> Dependency { auto pos = depend_string.find(' '); - if (pos == std::string::npos) return Dependency::parse_dependency(std::string{depend_string}, ""); + if (pos == std::string::npos) return Dependency::parse_dependency(depend_string, ""); // expect of the form "\w+ \[\w+\]" Dependency dep; @@ -190,7 +190,7 @@ namespace vcpkg if (depend_string.c_str()[pos + 1] != '(' || depend_string[depend_string.size() - 1] != ')') { // Error, but for now just slurp the entire string. - return Dependency::parse_dependency(std::string{depend_string}, ""); + return Dependency::parse_dependency(depend_string, ""); } dep.qualifier = depend_string.substr(pos + 2, depend_string.size() - pos - 3); return dep; diff --git a/toolsrc/src/vcpkg/statusparagraphs.cpp b/toolsrc/src/vcpkg/statusparagraphs.cpp index d516b6284..d4afc0427 100644 --- a/toolsrc/src/vcpkg/statusparagraphs.cpp +++ b/toolsrc/src/vcpkg/statusparagraphs.cpp @@ -47,7 +47,7 @@ namespace vcpkg StatusParagraphs::const_iterator StatusParagraphs::find_installed(const std::string& name, const Triplet& triplet) const { - const auto it = find(name, triplet); + const const_iterator it = find(name, triplet); if (it != end() && (*it)->want == Want::INSTALL && (*it)->state == InstallState::INSTALLED) { return it; diff --git a/toolsrc/src/vcpkg/update.cpp b/toolsrc/src/vcpkg/update.cpp index 9f89da13c..d6c5614ed 100644 --- a/toolsrc/src/vcpkg/update.cpp +++ b/toolsrc/src/vcpkg/update.cpp @@ -35,8 +35,7 @@ namespace vcpkg::Update auto&& installed_version = pgh->package.version; if (installed_version != port_version) { - output.push_back( - {pgh->package.spec, VersionDiff(std::string{installed_version}, std::string{port_version})}); + output.push_back({pgh->package.spec, VersionDiff(installed_version, port_version)}); } } else diff --git a/toolsrc/src/vcpkg/userconfig.cpp b/toolsrc/src/vcpkg/userconfig.cpp index 45ed01ec6..906594691 100644 --- a/toolsrc/src/vcpkg/userconfig.cpp +++ b/toolsrc/src/vcpkg/userconfig.cpp @@ -41,7 +41,7 @@ namespace vcpkg const auto& pghs = *p_pghs; std::unordered_map keys; - if (!pghs.empty()) keys = pghs[0]; + if (pghs.size() > 0) keys = pghs[0]; for (size_t x = 1; x < pghs.size(); ++x) { diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index cbf1e97e1..e64a681e2 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -50,14 +50,14 @@ namespace vcpkg const std::string& version_check_arguments, const std::array& expected_version) { - const auto it = Util::find_if(candidate_paths, [&](const fs::path& p) { + auto it = Util::find_if(candidate_paths, [&](const fs::path& p) { const std::string cmd = Strings::format(R"("%s" %s)", p.u8string(), version_check_arguments); return exists_and_has_equal_or_greater_version(cmd, expected_version); }); if (it != candidate_paths.cend()) { - return *it; + return std::move(*it); } return nullopt; diff --git a/toolsrc/src/vcpkg/versiont.cpp b/toolsrc/src/vcpkg/versiont.cpp index cff49d9e8..91f7e23ef 100644 --- a/toolsrc/src/vcpkg/versiont.cpp +++ b/toolsrc/src/vcpkg/versiont.cpp @@ -6,7 +6,7 @@ namespace vcpkg { VersionT::VersionT() : value("0.0.0") {} - VersionT::VersionT(std::string&& value) : value(std::move(value)) {} + VersionT::VersionT(const std::string& value) : value(value) {} const std::string& VersionT::to_string() const { return value; } bool operator==(const VersionT& left, const VersionT& right) { return left.to_string() == right.to_string(); } bool operator!=(const VersionT& left, const VersionT& right) { return left.to_string() != right.to_string(); } -- cgit v1.2.3 From be5e529bb3e8483e5675488232d936e7d7d29ceb Mon Sep 17 00:00:00 2001 From: Albert Ziegenhagel Date: Wed, 3 Jan 2018 10:57:46 +0100 Subject: Update cmake to 3.10.1 --- toolsrc/src/vcpkg/vcpkgpaths.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index e64a681e2..70d64de45 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -115,7 +115,7 @@ namespace vcpkg static fs::path get_cmake_path(const fs::path& downloads_folder, const fs::path& scripts_folder) { #if defined(_WIN32) - static constexpr std::array EXPECTED_VERSION = {3, 10, 0}; + static constexpr std::array EXPECTED_VERSION = {3, 10, 1}; #else static constexpr std::array EXPECTED_VERSION = {3, 5, 1}; #endif @@ -124,7 +124,7 @@ namespace vcpkg const std::vector from_path = Files::find_from_PATH("cmake"); std::vector candidate_paths; - const fs::path downloaded_copy = downloads_folder / "cmake-3.10.0-win32-x86" / "bin" / "cmake.exe"; + const fs::path downloaded_copy = downloads_folder / "cmake-3.10.1-win32-x86" / "bin" / "cmake.exe"; #if defined(_WIN32) candidate_paths.push_back(downloaded_copy); #endif -- cgit v1.2.3 From a28138eb9ef8d2986227b7cd784be9ffa8492a46 Mon Sep 17 00:00:00 2001 From: Jacek Blaszczynski Date: Thu, 4 Jan 2018 00:19:52 +0100 Subject: Add preliminary support for arm-windows and arm64-windows triplets (#2371) * Add preliminary support for arm-windows and arm64-windows triplets Visual Studio 15.4 shipped with new VC tools targeting arm and arm64 for desktop. This change allows for recognition and usage of new triplets supporting arm and arm64 Windows desktop and server targets. * Remove unnecessary changes * Part 2 * Part 3 * Make detection of Arm64 _VCPKG_TARGET_ARCHITECTURE precise * Enforce usage of Visual Studio CMake generatorfor arm and temporarily arm64 targets * Address code review feedback, clean libjpeg-turbo port.cmake * [libjpeg-turbo][tiff] Reduce changes to existing libraries. * [vcpkg-cmake] Simplify toolchain selection logic and improve comments --- toolsrc/include/vcpkg/triplet.h | 3 +++ toolsrc/src/vcpkg/triplet.cpp | 3 +++ 2 files changed, 6 insertions(+) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/triplet.h b/toolsrc/include/vcpkg/triplet.h index 2cfc2d02a..10464dc2c 100644 --- a/toolsrc/include/vcpkg/triplet.h +++ b/toolsrc/include/vcpkg/triplet.h @@ -18,6 +18,9 @@ namespace vcpkg static const Triplet X86_UWP; static const Triplet X64_UWP; static const Triplet ARM_UWP; + static const Triplet ARM64_UWP; + static const Triplet ARM_WINDOWS; + static const Triplet ARM64_WINDOWS; const std::string& canonical_name() const; const std::string& to_string() const; diff --git a/toolsrc/src/vcpkg/triplet.cpp b/toolsrc/src/vcpkg/triplet.cpp index 4cba1523d..ef0fab183 100644 --- a/toolsrc/src/vcpkg/triplet.cpp +++ b/toolsrc/src/vcpkg/triplet.cpp @@ -36,6 +36,9 @@ namespace vcpkg const Triplet Triplet::X86_UWP = from_canonical_name("x86-uwp"); const Triplet Triplet::X64_UWP = from_canonical_name("x64-uwp"); const Triplet Triplet::ARM_UWP = from_canonical_name("arm-uwp"); + const Triplet Triplet::ARM64_UWP = from_canonical_name("arm64-uwp"); + const Triplet Triplet::ARM_WINDOWS = from_canonical_name("arm-windows"); + const Triplet Triplet::ARM64_WINDOWS = from_canonical_name("arm64-windows"); bool Triplet::operator==(const Triplet& other) const { return this->m_instance == other.m_instance; } -- cgit v1.2.3 From aa8883f71a3cdef460df6eda7fd6db7bca242db4 Mon Sep 17 00:00:00 2001 From: Stanislav Ershov Date: Sat, 6 Jan 2018 13:01:06 +0300 Subject: [vcpkg] fix typos in error messages --- toolsrc/src/vcpkg/vcpkgpaths.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index 70d64de45..fa5fb128c 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -583,7 +583,7 @@ namespace vcpkg candidates, [&](const Toolset* t) { return *tsv == t->version && *vsp == t->visual_studio_root_path; }); Checks::check_exit(VCPKG_LINE_INFO, !candidates.empty(), - "Could not find Visual Studio instace at %s with %s toolset.", + "Could not find Visual Studio instance at %s with %s toolset.", vsp->u8string(), *tsv); @@ -595,7 +595,7 @@ namespace vcpkg { Util::stable_keep_if(candidates, [&](const Toolset* t) { return *tsv == t->version; }); Checks::check_exit( - VCPKG_LINE_INFO, !candidates.empty(), "Could not find Visual Studio instace with %s toolset.", *tsv); + VCPKG_LINE_INFO, !candidates.empty(), "Could not find Visual Studio instance with %s toolset.", *tsv); } if (vsp) @@ -605,7 +605,7 @@ namespace vcpkg [&](const Toolset* t) { return vs_root_path == t->visual_studio_root_path; }); Checks::check_exit(VCPKG_LINE_INFO, !candidates.empty(), - "Could not find Visual Studio instace at %s.", + "Could not find Visual Studio instance at %s.", vs_root_path.generic_string()); } -- cgit v1.2.3 From 3011064df2497e8a02d3aae30d75a3b537498ae0 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 10 Jan 2018 16:56:36 -0800 Subject: Update CHANGELOG and bump version to v0.0.101 --- toolsrc/VERSION.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/VERSION.txt b/toolsrc/VERSION.txt index e45ea373f..d78a54a5e 100644 --- a/toolsrc/VERSION.txt +++ b/toolsrc/VERSION.txt @@ -1 +1 @@ -"0.0.100" \ No newline at end of file +"0.0.101" \ No newline at end of file -- cgit v1.2.3 From c14f2b36e44526300f0ea7f828d09eefb77a3ad5 Mon Sep 17 00:00:00 2001 From: Ryan Fitzsimon Date: Fri, 12 Jan 2018 14:14:23 +1000 Subject: Add output option to export - The '--output=...' option allows the date/time string used in exported filenames to be overridden --- toolsrc/src/vcpkg/export.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/export.cpp b/toolsrc/src/vcpkg/export.cpp index e3221a12f..66e6af5b6 100644 --- a/toolsrc/src/vcpkg/export.cpp +++ b/toolsrc/src/vcpkg/export.cpp @@ -251,6 +251,8 @@ namespace vcpkg::Export bool zip; bool seven_zip; + Optional maybe_output; + Optional maybe_nuget_id; Optional maybe_nuget_version; @@ -258,6 +260,7 @@ namespace vcpkg::Export std::vector specs; }; + static const std::string OPTION_OUTPUT = "--output"; static const std::string OPTION_DRY_RUN = "--dry-run"; static const std::string OPTION_RAW = "--raw"; static const std::string OPTION_NUGET = "--nuget"; @@ -280,8 +283,9 @@ namespace vcpkg::Export {OPTION_ZIP, "Export to a zip file"}, {OPTION_SEVEN_ZIP, "Export to a 7zip (.7z) file"}, }}; - static const std::array EXPORT_SETTINGS = {{ - {OPTION_NUGET_ID, "Specify the id for the exported NuGet package"}, + static const std::array EXPORT_SETTINGS = {{ + {OPTION_OUTPUT, "Specify the output name (used to construct filename)"}, + {OPTION_NUGET_ID, "Specify the id for the exported NuGet package (overrides " + OPTION_OUTPUT + ")"}, {OPTION_NUGET_VERSION, "Specify the version for the exported NuGet package"}, {OPTION_IFW_REPOSITORY_URL, "Specify the remote repository URL for the online installer"}, {OPTION_IFW_PACKAGES_DIR_PATH, "Specify the temporary directory path for the repacked packages"}, @@ -316,6 +320,8 @@ namespace vcpkg::Export ret.zip = options.switches.find(OPTION_ZIP) != options.switches.cend(); ret.seven_zip = options.switches.find(OPTION_SEVEN_ZIP) != options.switches.cend(); + ret.maybe_output = maybe_lookup(options.settings, OPTION_OUTPUT); + if (!ret.raw && !ret.nuget && !ret.ifw && !ret.zip && !ret.seven_zip && !ret.dry_run) { System::println(System::Color::error, @@ -520,7 +526,7 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console Checks::exit_success(VCPKG_LINE_INFO); } - std::string export_id = create_export_id(); + std::string export_id = opts.maybe_output.value_or(create_export_id()); if (opts.raw || opts.nuget || opts.zip || opts.seven_zip) { -- cgit v1.2.3 From 0fde60e467ba756ddaaae389f1969a826268dc5d Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 17 Jan 2018 12:32:38 -0800 Subject: Fix variable lifetime issue --- toolsrc/src/vcpkg/export.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/export.cpp b/toolsrc/src/vcpkg/export.cpp index 66e6af5b6..d15df95d2 100644 --- a/toolsrc/src/vcpkg/export.cpp +++ b/toolsrc/src/vcpkg/export.cpp @@ -283,9 +283,13 @@ namespace vcpkg::Export {OPTION_ZIP, "Export to a zip file"}, {OPTION_SEVEN_ZIP, "Export to a 7zip (.7z) file"}, }}; + + static const std::string EXPORT_SETTINGS_NUGET_ID_HELP_TEXT = + Strings::format("Specify the id for the exported NuGet package (overrides %s)", OPTION_OUTPUT); + static const std::array EXPORT_SETTINGS = {{ {OPTION_OUTPUT, "Specify the output name (used to construct filename)"}, - {OPTION_NUGET_ID, "Specify the id for the exported NuGet package (overrides " + OPTION_OUTPUT + ")"}, + {OPTION_NUGET_ID, EXPORT_SETTINGS_NUGET_ID_HELP_TEXT}, {OPTION_NUGET_VERSION, "Specify the version for the exported NuGet package"}, {OPTION_IFW_REPOSITORY_URL, "Specify the remote repository URL for the online installer"}, {OPTION_IFW_PACKAGES_DIR_PATH, "Specify the temporary directory path for the repacked packages"}, -- cgit v1.2.3 From 458dafc812a1bc4f3290397601457e93f53b2dea Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 17 Jan 2018 19:35:31 -0800 Subject: Add new struct: StringLiteral --- toolsrc/include/vcpkg/base/stringliteral.h | 26 ++++++++++++++++++++++++++ toolsrc/vcpkglib/vcpkglib.vcxproj | 1 + toolsrc/vcpkglib/vcpkglib.vcxproj.filters | 3 +++ 3 files changed, 30 insertions(+) create mode 100644 toolsrc/include/vcpkg/base/stringliteral.h (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/base/stringliteral.h b/toolsrc/include/vcpkg/base/stringliteral.h new file mode 100644 index 000000000..c07f04cec --- /dev/null +++ b/toolsrc/include/vcpkg/base/stringliteral.h @@ -0,0 +1,26 @@ +#pragma once + +#include + +namespace vcpkg +{ + struct StringLiteral + { + template + constexpr StringLiteral(const char (&str)[N]) : m_size(N), m_cstr(str) + { + } + + constexpr const char* c_str() const { return m_cstr; } + constexpr size_t size() const { return m_size; } + + operator CStringView() const { return m_cstr; } + operator std::string() const { return m_cstr; } + + private: + size_t m_size; + const char* m_cstr; + }; + + inline const char* to_printf_arg(const StringLiteral str) { return str.c_str(); } +} diff --git a/toolsrc/vcpkglib/vcpkglib.vcxproj b/toolsrc/vcpkglib/vcpkglib.vcxproj index 455891f85..c2bc6b6fd 100644 --- a/toolsrc/vcpkglib/vcpkglib.vcxproj +++ b/toolsrc/vcpkglib/vcpkglib.vcxproj @@ -151,6 +151,7 @@ + diff --git a/toolsrc/vcpkglib/vcpkglib.vcxproj.filters b/toolsrc/vcpkglib/vcpkglib.vcxproj.filters index f8f517ad7..24f943e4a 100644 --- a/toolsrc/vcpkglib/vcpkglib.vcxproj.filters +++ b/toolsrc/vcpkglib/vcpkglib.vcxproj.filters @@ -341,5 +341,8 @@ Header Files\vcpkg + + Header Files\vcpkg\base + \ No newline at end of file -- cgit v1.2.3 From f563d2b58849d8ae6a04be0ad531cb2e20313fe0 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 17 Jan 2018 19:39:46 -0800 Subject: Use StringLiteral and constexpr for options/switches --- toolsrc/include/vcpkg/vcpkgcmdarguments.h | 19 +++++++++++--- toolsrc/src/vcpkg/build.cpp | 5 ++-- toolsrc/src/vcpkg/commands.autocomplete.cpp | 6 +++-- toolsrc/src/vcpkg/commands.ci.cpp | 7 ++--- toolsrc/src/vcpkg/commands.edit.cpp | 4 +-- toolsrc/src/vcpkg/commands.list.cpp | 5 ++-- toolsrc/src/vcpkg/commands.search.cpp | 7 ++--- toolsrc/src/vcpkg/commands.upgrade.cpp | 6 ++--- toolsrc/src/vcpkg/export.cpp | 40 ++++++++++++++--------------- toolsrc/src/vcpkg/install.cpp | 18 ++++++------- toolsrc/src/vcpkg/remove.cpp | 12 ++++----- 11 files changed, 72 insertions(+), 57 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/vcpkgcmdarguments.h b/toolsrc/include/vcpkg/vcpkgcmdarguments.h index 93eeb6ef5..d84be9c22 100644 --- a/toolsrc/include/vcpkg/vcpkgcmdarguments.h +++ b/toolsrc/include/vcpkg/vcpkgcmdarguments.h @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -21,14 +22,24 @@ namespace vcpkg struct CommandSwitch { - std::string name; - CStringView short_help_text; + constexpr CommandSwitch(const StringLiteral& name, const StringLiteral& short_help_text) + : name(name), short_help_text(short_help_text) + { + } + + StringLiteral name; + StringLiteral short_help_text; }; struct CommandSetting { - std::string name; - CStringView short_help_text; + constexpr CommandSetting(const StringLiteral& name, const StringLiteral& short_help_text) + : name(name), short_help_text(short_help_text) + { + } + + StringLiteral name; + StringLiteral short_help_text; }; struct CommandOptionsStructure diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index f43d8788e..960ba0400 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -26,7 +27,7 @@ namespace vcpkg::Build::Command using Dependencies::InstallPlanAction; using Dependencies::InstallPlanType; - static const std::string OPTION_CHECKS_ONLY = "--checks-only"; + static constexpr StringLiteral OPTION_CHECKS_ONLY = "--checks-only"; void perform_and_exit_ex(const FullPackageSpec& full_spec, const fs::path& port_dir, @@ -97,7 +98,7 @@ namespace vcpkg::Build::Command Checks::exit_success(VCPKG_LINE_INFO); } - static const std::array BUILD_SWITCHES = {{ + static constexpr std::array BUILD_SWITCHES = {{ {OPTION_CHECKS_ONLY, "Only run checks, do not rebuild package"}, }}; diff --git a/toolsrc/src/vcpkg/commands.autocomplete.cpp b/toolsrc/src/vcpkg/commands.autocomplete.cpp index 0df7ec5eb..564404421 100644 --- a/toolsrc/src/vcpkg/commands.autocomplete.cpp +++ b/toolsrc/src/vcpkg/commands.autocomplete.cpp @@ -136,8 +136,8 @@ namespace vcpkg::Commands::Autocomplete const bool is_option = Strings::case_insensitive_ascii_starts_with(prefix, "-"); if (is_option) { - results = - Util::fmap(command.structure.options.switches, [](const CommandSwitch& s) { return s.name; }); + results = Util::fmap(command.structure.options.switches, + [](const CommandSwitch& s) -> std::string { return s.name; }); auto settings = Util::fmap(command.structure.options.settings, [](auto&& s) { return s.name; }); results.insert(results.end(), settings.begin(), settings.end()); @@ -145,7 +145,9 @@ namespace vcpkg::Commands::Autocomplete else { if (command.structure.valid_arguments != nullptr) + { results = command.structure.valid_arguments(paths); + } } Util::unstable_keep_if(results, [&](const std::string& s) { diff --git a/toolsrc/src/vcpkg/commands.ci.cpp b/toolsrc/src/vcpkg/commands.ci.cpp index 1a2f9b47f..4636a5738 100644 --- a/toolsrc/src/vcpkg/commands.ci.cpp +++ b/toolsrc/src/vcpkg/commands.ci.cpp @@ -1,6 +1,7 @@ #include "pch.h" #include +#include #include #include #include @@ -62,10 +63,10 @@ namespace vcpkg::Commands::CI Install::InstallSummary summary; }; - static const std::string OPTION_EXCLUDE = "--exclude"; - static const std::string OPTION_XUNIT = "--x-xunit"; + static constexpr StringLiteral OPTION_EXCLUDE = "--exclude"; + static constexpr StringLiteral OPTION_XUNIT = "--x-xunit"; - static const std::array CI_SETTINGS = {{ + static constexpr std::array CI_SETTINGS = {{ {OPTION_EXCLUDE, "Comma separated list of ports to skip"}, {OPTION_XUNIT, "File to output results in XUnit format (internal)"}, }}; diff --git a/toolsrc/src/vcpkg/commands.edit.cpp b/toolsrc/src/vcpkg/commands.edit.cpp index e40e394fb..3e5d08956 100644 --- a/toolsrc/src/vcpkg/commands.edit.cpp +++ b/toolsrc/src/vcpkg/commands.edit.cpp @@ -32,7 +32,7 @@ namespace vcpkg::Commands::Edit return output; } - static const std::string OPTION_BUILDTREES = "--buildtrees"; + static constexpr StringLiteral OPTION_BUILDTREES = "--buildtrees"; static std::vector valid_arguments(const VcpkgPaths& paths) { @@ -42,7 +42,7 @@ namespace vcpkg::Commands::Edit [](auto&& pgh) -> std::string { return pgh->core_paragraph->name; }); } - static const std::array EDIT_SWITCHES = {{ + static constexpr std::array EDIT_SWITCHES = {{ {OPTION_BUILDTREES, "Open editor into the port-specific buildtree subfolder"}, }}; diff --git a/toolsrc/src/vcpkg/commands.list.cpp b/toolsrc/src/vcpkg/commands.list.cpp index 960c57225..2570c8a6d 100644 --- a/toolsrc/src/vcpkg/commands.list.cpp +++ b/toolsrc/src/vcpkg/commands.list.cpp @@ -7,7 +7,8 @@ namespace vcpkg::Commands::List { - static const std::string OPTION_FULLDESC = "--x-full-desc"; // TODO: This should find a better home, eventually + static constexpr StringLiteral OPTION_FULLDESC = + "--x-full-desc"; // TODO: This should find a better home, eventually static void do_print(const StatusParagraph& pgh, bool full_desc) { @@ -24,7 +25,7 @@ namespace vcpkg::Commands::List } } - static const std::array LIST_SWITCHES = {{ + static constexpr std::array LIST_SWITCHES = {{ {OPTION_FULLDESC, "Do not truncate long text"}, }}; diff --git a/toolsrc/src/vcpkg/commands.search.cpp b/toolsrc/src/vcpkg/commands.search.cpp index 01291ddfb..33a642e40 100644 --- a/toolsrc/src/vcpkg/commands.search.cpp +++ b/toolsrc/src/vcpkg/commands.search.cpp @@ -10,8 +10,9 @@ namespace vcpkg::Commands::Search { - static const std::string OPTION_GRAPH = "--graph"; // TODO: This should find a better home, eventually - static const std::string OPTION_FULLDESC = "--x-full-desc"; // TODO: This should find a better home, eventually + static constexpr StringLiteral OPTION_GRAPH = "--graph"; // TODO: This should find a better home, eventually + static constexpr StringLiteral OPTION_FULLDESC = + "--x-full-desc"; // TODO: This should find a better home, eventually static std::string replace_dashes_with_underscore(const std::string& input) { @@ -79,7 +80,7 @@ namespace vcpkg::Commands::Search } } - static std::array SEARCH_SWITCHES = {{ + static constexpr std::array SEARCH_SWITCHES = {{ {OPTION_GRAPH, "Open editor into the port-specific buildtree subfolder"}, {OPTION_FULLDESC, "Do not truncate long text"}, }}; diff --git a/toolsrc/src/vcpkg/commands.upgrade.cpp b/toolsrc/src/vcpkg/commands.upgrade.cpp index d2c868870..bb26dc735 100644 --- a/toolsrc/src/vcpkg/commands.upgrade.cpp +++ b/toolsrc/src/vcpkg/commands.upgrade.cpp @@ -15,10 +15,10 @@ namespace vcpkg::Commands::Upgrade using Install::KeepGoing; using Install::to_keep_going; - static const std::string OPTION_NO_DRY_RUN = "--no-dry-run"; - static const std::string OPTION_KEEP_GOING = "--keep-going"; + static constexpr StringLiteral OPTION_NO_DRY_RUN = "--no-dry-run"; + static constexpr StringLiteral OPTION_KEEP_GOING = "--keep-going"; - static const std::array INSTALL_SWITCHES = {{ + static constexpr std::array INSTALL_SWITCHES = {{ {OPTION_NO_DRY_RUN, "Actually upgrade"}, {OPTION_KEEP_GOING, "Continue installing packages on failure"}, }}; diff --git a/toolsrc/src/vcpkg/export.cpp b/toolsrc/src/vcpkg/export.cpp index d15df95d2..64cb3c804 100644 --- a/toolsrc/src/vcpkg/export.cpp +++ b/toolsrc/src/vcpkg/export.cpp @@ -1,5 +1,6 @@ #include "pch.h" +#include #include #include #include @@ -260,22 +261,22 @@ namespace vcpkg::Export std::vector specs; }; - static const std::string OPTION_OUTPUT = "--output"; - static const std::string OPTION_DRY_RUN = "--dry-run"; - static const std::string OPTION_RAW = "--raw"; - static const std::string OPTION_NUGET = "--nuget"; - static const std::string OPTION_IFW = "--ifw"; - static const std::string OPTION_ZIP = "--zip"; - static const std::string OPTION_SEVEN_ZIP = "--7zip"; - static const std::string OPTION_NUGET_ID = "--nuget-id"; - static const std::string OPTION_NUGET_VERSION = "--nuget-version"; - static const std::string OPTION_IFW_REPOSITORY_URL = "--ifw-repository-url"; - static const std::string OPTION_IFW_PACKAGES_DIR_PATH = "--ifw-packages-directory-path"; - static const std::string OPTION_IFW_REPOSITORY_DIR_PATH = "--ifw-repository-directory-path"; - static const std::string OPTION_IFW_CONFIG_FILE_PATH = "--ifw-configuration-file-path"; - static const std::string OPTION_IFW_INSTALLER_FILE_PATH = "--ifw-installer-file-path"; - - static const std::array EXPORT_SWITCHES = {{ + static constexpr StringLiteral OPTION_OUTPUT = "--output"; + static constexpr StringLiteral OPTION_DRY_RUN = "--dry-run"; + static constexpr StringLiteral OPTION_RAW = "--raw"; + static constexpr StringLiteral OPTION_NUGET = "--nuget"; + static constexpr StringLiteral OPTION_IFW = "--ifw"; + static constexpr StringLiteral OPTION_ZIP = "--zip"; + static constexpr StringLiteral OPTION_SEVEN_ZIP = "--7zip"; + static constexpr StringLiteral OPTION_NUGET_ID = "--nuget-id"; + static constexpr StringLiteral OPTION_NUGET_VERSION = "--nuget-version"; + static constexpr StringLiteral OPTION_IFW_REPOSITORY_URL = "--ifw-repository-url"; + static constexpr StringLiteral OPTION_IFW_PACKAGES_DIR_PATH = "--ifw-packages-directory-path"; + static constexpr StringLiteral OPTION_IFW_REPOSITORY_DIR_PATH = "--ifw-repository-directory-path"; + static constexpr StringLiteral OPTION_IFW_CONFIG_FILE_PATH = "--ifw-configuration-file-path"; + static constexpr StringLiteral OPTION_IFW_INSTALLER_FILE_PATH = "--ifw-installer-file-path"; + + static constexpr std::array EXPORT_SWITCHES = {{ {OPTION_DRY_RUN, "Do not actually export"}, {OPTION_RAW, "Export to an uncompressed directory"}, {OPTION_NUGET, "Export a NuGet package"}, @@ -284,12 +285,9 @@ namespace vcpkg::Export {OPTION_SEVEN_ZIP, "Export to a 7zip (.7z) file"}, }}; - static const std::string EXPORT_SETTINGS_NUGET_ID_HELP_TEXT = - Strings::format("Specify the id for the exported NuGet package (overrides %s)", OPTION_OUTPUT); - - static const std::array EXPORT_SETTINGS = {{ + static constexpr std::array EXPORT_SETTINGS = {{ {OPTION_OUTPUT, "Specify the output name (used to construct filename)"}, - {OPTION_NUGET_ID, EXPORT_SETTINGS_NUGET_ID_HELP_TEXT}, + {OPTION_NUGET_ID, "Specify the id for the exported NuGet package (overrides --output)"}, {OPTION_NUGET_VERSION, "Specify the version for the exported NuGet package"}, {OPTION_IFW_REPOSITORY_URL, "Specify the remote repository URL for the online installer"}, {OPTION_IFW_PACKAGES_DIR_PATH, "Specify the temporary directory path for the repacked packages"}, diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp index dcc130be3..d6a28d57c 100644 --- a/toolsrc/src/vcpkg/install.cpp +++ b/toolsrc/src/vcpkg/install.cpp @@ -413,21 +413,21 @@ namespace vcpkg::Install return InstallSummary{std::move(results), timer.to_string()}; } - static const std::string OPTION_DRY_RUN = "--dry-run"; - static const std::string OPTION_USE_HEAD_VERSION = "--head"; - static const std::string OPTION_NO_DOWNLOADS = "--no-downloads"; - static const std::string OPTION_RECURSE = "--recurse"; - static const std::string OPTION_KEEP_GOING = "--keep-going"; - static const std::string OPTION_XUNIT = "--x-xunit"; - - static const std::array INSTALL_SWITCHES = {{ + static constexpr StringLiteral OPTION_DRY_RUN = "--dry-run"; + static constexpr StringLiteral OPTION_USE_HEAD_VERSION = "--head"; + static constexpr StringLiteral OPTION_NO_DOWNLOADS = "--no-downloads"; + static constexpr StringLiteral OPTION_RECURSE = "--recurse"; + static constexpr StringLiteral OPTION_KEEP_GOING = "--keep-going"; + static constexpr StringLiteral OPTION_XUNIT = "--x-xunit"; + + static constexpr std::array INSTALL_SWITCHES = {{ {OPTION_DRY_RUN, "Do not actually build or install"}, {OPTION_USE_HEAD_VERSION, "Install the libraries on the command line using the latest upstream sources"}, {OPTION_NO_DOWNLOADS, "Do not download new sources"}, {OPTION_RECURSE, "Allow removal of packages as part of installation"}, {OPTION_KEEP_GOING, "Continue installing packages on failure"}, }}; - static const std::array INSTALL_SETTINGS = {{ + static constexpr std::array INSTALL_SETTINGS = {{ {OPTION_XUNIT, "File to output results in XUnit format (Internal use)"}, }}; diff --git a/toolsrc/src/vcpkg/remove.cpp b/toolsrc/src/vcpkg/remove.cpp index 4079d60c1..e03df2ed2 100644 --- a/toolsrc/src/vcpkg/remove.cpp +++ b/toolsrc/src/vcpkg/remove.cpp @@ -164,13 +164,13 @@ namespace vcpkg::Remove } } - static const std::string OPTION_PURGE = "--purge"; - static const std::string OPTION_NO_PURGE = "--no-purge"; - static const std::string OPTION_RECURSE = "--recurse"; - static const std::string OPTION_DRY_RUN = "--dry-run"; - static const std::string OPTION_OUTDATED = "--outdated"; + static constexpr StringLiteral OPTION_PURGE = "--purge"; + static constexpr StringLiteral OPTION_NO_PURGE = "--no-purge"; + static constexpr StringLiteral OPTION_RECURSE = "--recurse"; + static constexpr StringLiteral OPTION_DRY_RUN = "--dry-run"; + static constexpr StringLiteral OPTION_OUTDATED = "--outdated"; - static const std::array SWITCHES = {{ + static constexpr std::array SWITCHES = {{ {OPTION_PURGE, "Remove the cached copy of the package (default)"}, {OPTION_NO_PURGE, "Do not remove the cached copy of the package"}, {OPTION_RECURSE, "Allow removal of packages not explicitly specified on the command line"}, -- cgit v1.2.3 From 14650ddfb8d31a0e075b4684e8c1ebc9976319bc Mon Sep 17 00:00:00 2001 From: Jonathan Hale Date: Thu, 18 Jan 2018 10:09:53 +0100 Subject: [vkpkg] Fix edit command not considering EDITOR environment variable (#2597) * [vkpkg] Fix edit command not considering EDITOR environment variable Signed-off-by: Squareys * [vcpkg-edit] Reformat and improve code consistency --- toolsrc/src/vcpkg/commands.edit.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/commands.edit.cpp b/toolsrc/src/vcpkg/commands.edit.cpp index 3e5d08956..41f261a53 100644 --- a/toolsrc/src/vcpkg/commands.edit.cpp +++ b/toolsrc/src/vcpkg/commands.edit.cpp @@ -68,8 +68,11 @@ namespace vcpkg::Commands::Edit Checks::check_exit(VCPKG_LINE_INFO, fs.is_directory(portpath), R"(Could not find port named "%s")", port_name); std::vector candidate_paths; - const std::vector from_path = Files::find_from_PATH("EDITOR"); - candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); + auto maybe_editor_path = System::get_environment_variable("EDITOR"); + if (auto editor_path = maybe_editor_path.get()) + { + candidate_paths.emplace_back(*editor_path); + } candidate_paths.push_back(System::get_program_files_platform_bitness() / VS_CODE_INSIDERS); candidate_paths.push_back(System::get_program_files_32_bit() / VS_CODE_INSIDERS); candidate_paths.push_back(System::get_program_files_platform_bitness() / VS_CODE); @@ -81,8 +84,9 @@ namespace vcpkg::Commands::Edit auto it = Util::find_if(candidate_paths, [&](const fs::path& p) { return fs.exists(p); }); if (it == candidate_paths.cend()) { - System::println(System::Color::error, - "Error: Visual Studio Code was not found and the environment variable EDITOR is not set."); + System::println( + System::Color::error, + "Error: Visual Studio Code was not found and the environment variable EDITOR is not set or invalid."); System::println("The following paths were examined:"); Files::print_paths(candidate_paths); System::println("You can also set the environmental variable EDITOR to your editor of choice."); -- cgit v1.2.3 From 228eebfbecf2e5d0a4c901820b26659137707d7a Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Fri, 19 Jan 2018 15:23:47 -0800 Subject: [vcpkg] Add additional tests. Enable featurepackages by default. --- toolsrc/src/tests.plan.cpp | 69 +++++++++++++++++++++++++++++++++ toolsrc/src/vcpkg/globalstate.cpp | 2 +- toolsrc/src/vcpkg/vcpkgcmdarguments.cpp | 5 +++ 3 files changed, 75 insertions(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/tests.plan.cpp b/toolsrc/src/tests.plan.cpp index 781588c91..593003b80 100644 --- a/toolsrc/src/tests.plan.cpp +++ b/toolsrc/src/tests.plan.cpp @@ -434,6 +434,75 @@ namespace UnitTest1 Assert::IsTrue(install_plan.size() == 1); features_check(&install_plan[0], "a", {"0", "1", "core"}, Triplet::X64_WINDOWS); } + + TEST_METHOD(transitive_features_test) + { + std::vector> status_paragraphs; + + PackageSpecMap spec_map(Triplet::X64_WINDOWS); + auto spec_a_64 = FullPackageSpec{spec_map.emplace("a", "b", {{"0", "b[0]"}}), {"core"}}; + auto spec_b_64 = FullPackageSpec{spec_map.emplace("b", "c", {{"0", "c[0]"}}), {"core"}}; + auto spec_c_64 = FullPackageSpec{spec_map.emplace("c", "", {{"0", ""}}), {"core"}}; + + auto install_specs = FullPackageSpec::from_string("a[*]", Triplet::X64_WINDOWS); + Assert::IsTrue(install_specs.has_value()); + if (!install_specs.has_value()) return; + auto install_plan = Dependencies::create_feature_install_plan( + spec_map.map, + FullPackageSpec::to_feature_specs({install_specs.value_or_exit(VCPKG_LINE_INFO)}), + StatusParagraphs(std::move(status_paragraphs))); + + Assert::IsTrue(install_plan.size() == 3); + features_check(&install_plan[0], "c", {"0", "core"}, Triplet::X64_WINDOWS); + features_check(&install_plan[1], "b", {"0", "core"}, Triplet::X64_WINDOWS); + features_check(&install_plan[2], "a", {"0", "core"}, Triplet::X64_WINDOWS); + } + + TEST_METHOD(no_transitive_features_test) + { + std::vector> status_paragraphs; + + PackageSpecMap spec_map(Triplet::X64_WINDOWS); + auto spec_a_64 = FullPackageSpec{spec_map.emplace("a", "b", {{"0", ""}}), {"core"}}; + auto spec_b_64 = FullPackageSpec{spec_map.emplace("b", "c", {{"0", ""}}), {"core"}}; + auto spec_c_64 = FullPackageSpec{spec_map.emplace("c", "", {{"0", ""}}), {"core"}}; + + auto install_specs = FullPackageSpec::from_string("a[*]", Triplet::X64_WINDOWS); + Assert::IsTrue(install_specs.has_value()); + if (!install_specs.has_value()) return; + auto install_plan = Dependencies::create_feature_install_plan( + spec_map.map, + FullPackageSpec::to_feature_specs({install_specs.value_or_exit(VCPKG_LINE_INFO)}), + StatusParagraphs(std::move(status_paragraphs))); + + Assert::IsTrue(install_plan.size() == 3); + features_check(&install_plan[0], "c", {"core"}, Triplet::X64_WINDOWS); + features_check(&install_plan[1], "b", {"core"}, Triplet::X64_WINDOWS); + features_check(&install_plan[2], "a", {"0", "core"}, Triplet::X64_WINDOWS); + } + + TEST_METHOD(only_transitive_features_test) + { + std::vector> status_paragraphs; + + PackageSpecMap spec_map(Triplet::X64_WINDOWS); + auto spec_a_64 = FullPackageSpec{spec_map.emplace("a", "", {{"0", "b[0]"}}), {"core"}}; + auto spec_b_64 = FullPackageSpec{spec_map.emplace("b", "", {{"0", "c[0]"}}), {"core"}}; + auto spec_c_64 = FullPackageSpec{spec_map.emplace("c", "", {{"0", ""}}), {"core"}}; + + auto install_specs = FullPackageSpec::from_string("a[*]", Triplet::X64_WINDOWS); + Assert::IsTrue(install_specs.has_value()); + if (!install_specs.has_value()) return; + auto install_plan = Dependencies::create_feature_install_plan( + spec_map.map, + FullPackageSpec::to_feature_specs({install_specs.value_or_exit(VCPKG_LINE_INFO)}), + StatusParagraphs(std::move(status_paragraphs))); + + Assert::IsTrue(install_plan.size() == 3); + features_check(&install_plan[0], "c", {"0", "core"}, Triplet::X64_WINDOWS); + features_check(&install_plan[1], "b", {"0", "core"}, Triplet::X64_WINDOWS); + features_check(&install_plan[2], "a", {"0", "core"}, Triplet::X64_WINDOWS); + } }; static PackageSpec unsafe_pspec(std::string name, Triplet t = Triplet::X86_WINDOWS) diff --git a/toolsrc/src/vcpkg/globalstate.cpp b/toolsrc/src/vcpkg/globalstate.cpp index 123c77d46..eac69d9f5 100644 --- a/toolsrc/src/vcpkg/globalstate.cpp +++ b/toolsrc/src/vcpkg/globalstate.cpp @@ -8,7 +8,7 @@ namespace vcpkg Util::LockGuarded GlobalState::g_surveydate; std::atomic GlobalState::debugging(false); - std::atomic GlobalState::feature_packages(false); + std::atomic GlobalState::feature_packages(true); std::atomic GlobalState::g_init_console_cp(0); std::atomic GlobalState::g_init_console_output_cp(0); diff --git a/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp b/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp index 671a89892..84ad17fe3 100644 --- a/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp +++ b/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp @@ -129,6 +129,11 @@ namespace vcpkg GlobalState::feature_packages = true; continue; } + if (arg == "--no-featurepackages") + { + GlobalState::feature_packages = false; + continue; + } const auto eq_pos = arg.find('='); if (eq_pos != std::string::npos) -- cgit v1.2.3 From 0682bb734d5f8667d5aa1a8c2448d69fc042c53f Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Mon, 22 Jan 2018 23:40:41 -0800 Subject: [vcpkg] Store Optional<&> instead of Optional<*> --- toolsrc/include/vcpkg/dependencies.h | 2 +- toolsrc/src/tests.plan.cpp | 3 +-- toolsrc/src/vcpkg/dependencies.cpp | 6 +++--- toolsrc/src/vcpkg/install.cpp | 2 +- 4 files changed, 6 insertions(+), 7 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/dependencies.h b/toolsrc/include/vcpkg/dependencies.h index 8902a7b08..84886c8dc 100644 --- a/toolsrc/include/vcpkg/dependencies.h +++ b/toolsrc/include/vcpkg/dependencies.h @@ -29,7 +29,7 @@ namespace vcpkg::Dependencies Optional status_paragraph; Optional binary_control_file; - Optional source_control_file; + Optional source_control_file; }; } diff --git a/toolsrc/src/tests.plan.cpp b/toolsrc/src/tests.plan.cpp index 593003b80..0916e66c8 100644 --- a/toolsrc/src/tests.plan.cpp +++ b/toolsrc/src/tests.plan.cpp @@ -41,8 +41,7 @@ namespace UnitTest1 Assert::AreEqual(plan.spec.triplet().to_string().c_str(), triplet.to_string().c_str()); - Assert::AreEqual(pkg_name.c_str(), - (*plan.any_paragraph.source_control_file.get())->core_paragraph->name.c_str()); + Assert::AreEqual(pkg_name.c_str(), plan.any_paragraph.source_control_file.get()->core_paragraph->name.c_str()); Assert::AreEqual(size_t(vec.size()), feature_list.size()); for (auto&& feature_name : vec) diff --git a/toolsrc/src/vcpkg/dependencies.cpp b/toolsrc/src/vcpkg/dependencies.cpp index 76aeb0eaa..e48d85885 100644 --- a/toolsrc/src/vcpkg/dependencies.cpp +++ b/toolsrc/src/vcpkg/dependencies.cpp @@ -117,7 +117,7 @@ namespace vcpkg::Dependencies return PackageSpec::from_dependencies_of_port(p->core_paragraph.spec.name(), deps, triplet); } - if (const auto p = this->source_control_file.value_or(nullptr)) + if (const auto p = this->source_control_file.get()) { return PackageSpec::from_dependencies_of_port( p->core_paragraph->name, filter_dependencies(p->core_paragraph->depends, triplet), triplet); @@ -159,7 +159,7 @@ namespace vcpkg::Dependencies const RequestType& request_type) : spec(spec), plan_type(InstallPlanType::BUILD_AND_INSTALL), request_type(request_type), feature_list(features) { - this->any_paragraph.source_control_file = &any_paragraph; + this->any_paragraph.source_control_file = any_paragraph; } InstallPlanAction::InstallPlanAction(const PackageSpec& spec, @@ -418,7 +418,7 @@ namespace vcpkg::Dependencies return ExportPlanAction{spec, AnyParagraph{nullopt, std::move(*bcf), nullopt}, request_type}; auto maybe_scf = provider.get_control_file(spec.name()); - if (auto scf = maybe_scf.get()) return ExportPlanAction{spec, {nullopt, nullopt, scf}, request_type}; + if (auto scf = maybe_scf.get()) return ExportPlanAction{spec, {nullopt, nullopt, *scf}, request_type}; Checks::exit_with_message(VCPKG_LINE_INFO, "Could not find package %s", spec); } diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp index d6a28d57c..3ecb627f5 100644 --- a/toolsrc/src/vcpkg/install.cpp +++ b/toolsrc/src/vcpkg/install.cpp @@ -293,7 +293,7 @@ namespace vcpkg::Install auto result = [&]() -> Build::ExtendedBuildResult { const Build::BuildPackageConfig build_config{ - *action.any_paragraph.source_control_file.value_or_exit(VCPKG_LINE_INFO), + action.any_paragraph.source_control_file.value_or_exit(VCPKG_LINE_INFO), action.spec.triplet(), paths.port_dir(action.spec), action.build_options, -- cgit v1.2.3 From 3e42585f47a7c6abaa516cf2ed7b1e702ffd38ca Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Tue, 23 Jan 2018 01:54:31 -0800 Subject: [vcpkg] Span usage improvements. --- toolsrc/include/vcpkg/base/span.h | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/base/span.h b/toolsrc/include/vcpkg/base/span.h index 158f1ac74..c9ac18afe 100644 --- a/toolsrc/include/vcpkg/base/span.h +++ b/toolsrc/include/vcpkg/base/span.h @@ -11,15 +11,17 @@ namespace vcpkg struct Span { public: + static_assert(!std::is_reference::value, "Span<&> is illegal"); + using element_type = T; - using pointer = T*; - using reference = T&; - using iterator = T*; + using pointer = std::add_pointer_t; + using reference = std::add_lvalue_reference_t; + using iterator = pointer; constexpr Span() noexcept : m_ptr(nullptr), m_count(0) {} constexpr Span(std::nullptr_t) noexcept : Span() {} - constexpr Span(T* ptr, size_t count) noexcept : m_ptr(ptr), m_count(count) {} - constexpr Span(T* ptr_begin, T* ptr_end) noexcept : m_ptr(ptr_begin), m_count(ptr_end - ptr_begin) {} + constexpr Span(pointer ptr, size_t count) noexcept : m_ptr(ptr), m_count(count) {} + constexpr Span(pointer ptr_begin, pointer ptr_end) noexcept : m_ptr(ptr_begin), m_count(ptr_end - ptr_begin) {} constexpr Span(std::initializer_list l) noexcept : m_ptr(l.begin()), m_count(l.size()) {} template @@ -69,4 +71,4 @@ namespace vcpkg { return sp.end(); } -} \ No newline at end of file +} -- cgit v1.2.3 From 10d712ed018fe3b2cd8d485e41f32ad555d9a1f1 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Tue, 23 Jan 2018 01:56:25 -0800 Subject: [vcpkg] Added StatusParagraph::is_installed() --- toolsrc/include/vcpkg/statusparagraph.h | 2 ++ toolsrc/src/vcpkg/statusparagraphs.cpp | 2 +- toolsrc/src/vcpkg/vcpkglib.cpp | 4 ++-- 3 files changed, 5 insertions(+), 3 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/statusparagraph.h b/toolsrc/include/vcpkg/statusparagraph.h index ca84b1bb7..051acf95f 100644 --- a/toolsrc/include/vcpkg/statusparagraph.h +++ b/toolsrc/include/vcpkg/statusparagraph.h @@ -32,6 +32,8 @@ namespace vcpkg StatusParagraph(); explicit StatusParagraph(std::unordered_map&& fields); + bool is_installed() const { return want == Want::INSTALL && state == InstallState::INSTALLED; } + BinaryParagraph package; Want want; InstallState state; diff --git a/toolsrc/src/vcpkg/statusparagraphs.cpp b/toolsrc/src/vcpkg/statusparagraphs.cpp index d4afc0427..19919b76f 100644 --- a/toolsrc/src/vcpkg/statusparagraphs.cpp +++ b/toolsrc/src/vcpkg/statusparagraphs.cpp @@ -48,7 +48,7 @@ namespace vcpkg const Triplet& triplet) const { const const_iterator it = find(name, triplet); - if (it != end() && (*it)->want == Want::INSTALL && (*it)->state == InstallState::INSTALLED) + if (it != end() && (*it)->is_installed()) { return it; } diff --git a/toolsrc/src/vcpkg/vcpkglib.cpp b/toolsrc/src/vcpkg/vcpkglib.cpp index 5b2cec4d0..de6ffefed 100644 --- a/toolsrc/src/vcpkg/vcpkglib.cpp +++ b/toolsrc/src/vcpkg/vcpkglib.cpp @@ -173,7 +173,7 @@ namespace vcpkg std::vector installed_packages; for (auto&& pgh : status_db) { - if (pgh->state != InstallState::INSTALLED || pgh->want != Want::INSTALL) continue; + if (!pgh->is_installed()) continue; installed_packages.push_back(pgh.get()); } @@ -189,7 +189,7 @@ namespace vcpkg for (const std::unique_ptr& pgh : status_db) { - if (pgh->state != InstallState::INSTALLED || !pgh->package.feature.empty()) + if (!pgh->is_installed() || !pgh->package.feature.empty()) { continue; } -- cgit v1.2.3 From ff8a2d17266f1c601d04ac7b3c3e85ad674c8491 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Tue, 23 Jan 2018 02:21:47 -0800 Subject: [vcpkg] Remove AnyParagraph and InstallPlanType::INSTALL --- toolsrc/include/vcpkg/dependencies.h | 36 ++++----- toolsrc/include/vcpkg/statusparagraphs.h | 2 + toolsrc/src/tests.plan.cpp | 2 +- toolsrc/src/tests.utils.cpp | 1 - toolsrc/src/vcpkg/commands.exportifw.cpp | 9 +-- toolsrc/src/vcpkg/dependencies.cpp | 132 ++++++++++++++----------------- toolsrc/src/vcpkg/export.cpp | 5 +- toolsrc/src/vcpkg/install.cpp | 30 ++----- toolsrc/src/vcpkg/statusparagraphs.cpp | 23 +++++- 9 files changed, 116 insertions(+), 124 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/dependencies.h b/toolsrc/include/vcpkg/dependencies.h index 84886c8dc..14f51c216 100644 --- a/toolsrc/include/vcpkg/dependencies.h +++ b/toolsrc/include/vcpkg/dependencies.h @@ -23,23 +23,10 @@ namespace vcpkg::Dependencies const Build::BuildPackageOptions& options); std::string to_output_string(RequestType request_type, const CStringView s); - struct AnyParagraph - { - std::vector dependencies(const Triplet& triplet) const; - - Optional status_paragraph; - Optional binary_control_file; - Optional source_control_file; - }; -} - -namespace vcpkg::Dependencies -{ enum class InstallPlanType { UNKNOWN, BUILD_AND_INSTALL, - INSTALL, ALREADY_INSTALLED, EXCLUDED }; @@ -51,18 +38,22 @@ namespace vcpkg::Dependencies InstallPlanAction(); InstallPlanAction(const PackageSpec& spec, + std::vector&& spghs, const std::unordered_set& features, const RequestType& request_type); - InstallPlanAction(const PackageSpec& spec, const AnyParagraph& any_paragraph, const RequestType& request_type); + InstallPlanAction(const PackageSpec& spec, - const SourceControlFile& any_paragraph, + const SourceControlFile& scf, const std::unordered_set& features, const RequestType& request_type); std::string displayname() const; PackageSpec spec; - AnyParagraph any_paragraph; + + Optional source_control_file; + Optional> status_paragraphs; + InstallPlanType plan_type; RequestType request_type; Build::BuildPackageOptions build_options; @@ -111,12 +102,21 @@ namespace vcpkg::Dependencies static bool compare_by_name(const ExportPlanAction* left, const ExportPlanAction* right); ExportPlanAction(); - ExportPlanAction(const PackageSpec& spec, const AnyParagraph& any_paragraph, const RequestType& request_type); + ExportPlanAction(const PackageSpec& spec, + std::vector&& status_paragraphs, + const RequestType& request_type); + + ExportPlanAction(const PackageSpec& spec, const RequestType& request_type); PackageSpec spec; - AnyParagraph any_paragraph; ExportPlanType plan_type; RequestType request_type; + + Optional core_paragraph() const; + std::vector dependencies(const Triplet& triplet) const; + + private: + std::vector m_spghs; }; struct PortFileProvider diff --git a/toolsrc/include/vcpkg/statusparagraphs.h b/toolsrc/include/vcpkg/statusparagraphs.h index 747a0c1ab..51fbd14dd 100644 --- a/toolsrc/include/vcpkg/statusparagraphs.h +++ b/toolsrc/include/vcpkg/statusparagraphs.h @@ -21,6 +21,8 @@ namespace vcpkg std::vector*> find_all(const std::string& name, const Triplet& triplet); + std::vector*> find_all_installed(const PackageSpec& spec) const; + const_iterator find_installed(const PackageSpec& spec) const { return find_installed(spec.name(), spec.triplet()); diff --git a/toolsrc/src/tests.plan.cpp b/toolsrc/src/tests.plan.cpp index 0916e66c8..67abf8de0 100644 --- a/toolsrc/src/tests.plan.cpp +++ b/toolsrc/src/tests.plan.cpp @@ -41,7 +41,7 @@ namespace UnitTest1 Assert::AreEqual(plan.spec.triplet().to_string().c_str(), triplet.to_string().c_str()); - Assert::AreEqual(pkg_name.c_str(), plan.any_paragraph.source_control_file.get()->core_paragraph->name.c_str()); + Assert::AreEqual(pkg_name.c_str(), plan.source_control_file.get()->core_paragraph->name.c_str()); Assert::AreEqual(size_t(vec.size()), feature_list.size()); for (auto&& feature_name : vec) diff --git a/toolsrc/src/tests.utils.cpp b/toolsrc/src/tests.utils.cpp index b9fb51a59..d155c7238 100644 --- a/toolsrc/src/tests.utils.cpp +++ b/toolsrc/src/tests.utils.cpp @@ -13,7 +13,6 @@ namespace Microsoft::VisualStudio::CppUnitTestFramework { case Dependencies::InstallPlanType::ALREADY_INSTALLED: return L"ALREADY_INSTALLED"; case Dependencies::InstallPlanType::BUILD_AND_INSTALL: return L"BUILD_AND_INSTALL"; - case Dependencies::InstallPlanType::INSTALL: return L"INSTALL"; case Dependencies::InstallPlanType::EXCLUDED: return L"EXCLUDED"; case Dependencies::InstallPlanType::UNKNOWN: return L"UNKNOWN"; default: return ToString(static_cast(t)); diff --git a/toolsrc/src/vcpkg/commands.exportifw.cpp b/toolsrc/src/vcpkg/commands.exportifw.cpp index 682267acb..b25982e4b 100644 --- a/toolsrc/src/vcpkg/commands.exportifw.cpp +++ b/toolsrc/src/vcpkg/commands.exportifw.cpp @@ -69,8 +69,7 @@ namespace vcpkg::Export::IFW { std::error_code ec; - const BinaryParagraph& binary_paragraph = - action.any_paragraph.binary_control_file.value_or_exit(VCPKG_LINE_INFO).core_paragraph; + const BinaryParagraph& binary_paragraph = action.core_paragraph().value_or_exit(VCPKG_LINE_INFO); // Prepare meta dir const fs::path package_xml_file_path = @@ -142,8 +141,7 @@ namespace vcpkg::Export::IFW for (auto package = unique_packages.begin(); package != unique_packages.end(); ++package) { const ExportPlanAction& action = *(package->second); - const BinaryParagraph& binary_paragraph = - action.any_paragraph.binary_control_file.value_or_exit(VCPKG_LINE_INFO).core_paragraph; + const BinaryParagraph& binary_paragraph = action.core_paragraph().value_or_exit(VCPKG_LINE_INFO); package_xml_file_path = raw_exported_dir_path / Strings::format("packages.%s", package->first) / "meta" / "package.xml"; @@ -436,8 +434,7 @@ namespace vcpkg::Export::IFW const std::string display_name = action.spec.to_string(); System::println("Exporting package %s... ", display_name); - const BinaryParagraph& binary_paragraph = - action.any_paragraph.binary_control_file.value_or_exit(VCPKG_LINE_INFO).core_paragraph; + const BinaryParagraph& binary_paragraph = action.core_paragraph().value_or_exit(VCPKG_LINE_INFO); unique_packages[action.spec.name()] = &action; unique_triplets.insert(action.spec.triplet().canonical_name()); diff --git a/toolsrc/src/vcpkg/dependencies.cpp b/toolsrc/src/vcpkg/dependencies.cpp index e48d85885..277de0557 100644 --- a/toolsrc/src/vcpkg/dependencies.cpp +++ b/toolsrc/src/vcpkg/dependencies.cpp @@ -103,28 +103,15 @@ namespace vcpkg::Dependencies const PortFileProvider& m_provider; }; - std::vector AnyParagraph::dependencies(const Triplet& triplet) const + static std::vector source_paragraphs_dependencies(Span spghs) { - if (const auto p = this->status_paragraph.get()) - { - return PackageSpec::from_dependencies_of_port(p->package.spec.name(), p->package.depends, triplet); - } + if (spghs.size() == 0) return {}; - if (const auto p = this->binary_control_file.get()) - { - auto deps = Util::fmap_flatten(p->features, [](const BinaryParagraph& pgh) { return pgh.depends; }); - deps.insert(deps.end(), p->core_paragraph.depends.cbegin(), p->core_paragraph.depends.cend()); - return PackageSpec::from_dependencies_of_port(p->core_paragraph.spec.name(), deps, triplet); - } + auto deps = Util::fmap_flatten( + spghs, [](const StatusParagraph* pgh) -> std::vector const& { return pgh->package.depends; }); - if (const auto p = this->source_control_file.get()) - { - return PackageSpec::from_dependencies_of_port( - p->core_paragraph->name, filter_dependencies(p->core_paragraph->depends, triplet), triplet); - } - - Checks::exit_with_message(VCPKG_LINE_INFO, - "Cannot get dependencies because there was none of: source/binary/status paragraphs"); + auto&& spec = spghs[0]->package.spec; + return PackageSpec::from_dependencies_of_port(spec.name(), deps, spec.triplet()); } std::string to_output_string(RequestType request_type, @@ -154,45 +141,28 @@ namespace vcpkg::Dependencies InstallPlanAction::InstallPlanAction() : plan_type(InstallPlanType::UNKNOWN), request_type(RequestType::UNKNOWN) {} InstallPlanAction::InstallPlanAction(const PackageSpec& spec, - const SourceControlFile& any_paragraph, + const SourceControlFile& scf, const std::unordered_set& features, const RequestType& request_type) - : spec(spec), plan_type(InstallPlanType::BUILD_AND_INSTALL), request_type(request_type), feature_list(features) + : spec(spec) + , source_control_file(scf) + , plan_type(InstallPlanType::BUILD_AND_INSTALL) + , request_type(request_type) + , feature_list(features) { - this->any_paragraph.source_control_file = any_paragraph; } InstallPlanAction::InstallPlanAction(const PackageSpec& spec, + std::vector&& spghs, const std::unordered_set& features, const RequestType& request_type) - : spec(spec), plan_type(InstallPlanType::ALREADY_INSTALLED), request_type(request_type), feature_list(features) + : spec(spec) + , status_paragraphs(std::move(spghs)) + , plan_type(InstallPlanType::ALREADY_INSTALLED) + , request_type(request_type) + , feature_list(features) { - } - - InstallPlanAction::InstallPlanAction(const PackageSpec& spec, - const AnyParagraph& any_paragraph, - const RequestType& request_type) - : spec(spec), any_paragraph(any_paragraph), plan_type(InstallPlanType::UNKNOWN), request_type(request_type) - { - if (auto p = any_paragraph.status_paragraph.get()) - { - this->plan_type = InstallPlanType::ALREADY_INSTALLED; - return; - } - - if (auto p = any_paragraph.binary_control_file.get()) - { - this->plan_type = InstallPlanType::INSTALL; - return; - } - - if (auto p = any_paragraph.source_control_file.get()) - { - this->plan_type = InstallPlanType::BUILD_AND_INSTALL; - return; - } - - Checks::unreachable(VCPKG_LINE_INFO); + Checks::check_exit(VCPKG_LINE_INFO, status_paragraphs.get()->size() > 0); } std::string InstallPlanAction::displayname() const @@ -243,21 +213,30 @@ namespace vcpkg::Dependencies ExportPlanAction::ExportPlanAction() : plan_type(ExportPlanType::UNKNOWN), request_type(RequestType::UNKNOWN) {} ExportPlanAction::ExportPlanAction(const PackageSpec& spec, - const AnyParagraph& any_paragraph, + std::vector&& status_paragraphs, const RequestType& request_type) - : spec(spec), any_paragraph(any_paragraph), plan_type(ExportPlanType::UNKNOWN), request_type(request_type) + : spec(spec) + , plan_type(ExportPlanType::ALREADY_BUILT) + , request_type(request_type) + , m_spghs(std::move(status_paragraphs)) { - if (auto p = any_paragraph.binary_control_file.get()) - { - this->plan_type = ExportPlanType::ALREADY_BUILT; - return; - } + } - if (auto p = any_paragraph.source_control_file.get()) - { - this->plan_type = ExportPlanType::PORT_AVAILABLE_BUT_NOT_BUILT; - return; - } + ExportPlanAction::ExportPlanAction(const PackageSpec& spec, const RequestType& request_type) + : spec(spec), plan_type(ExportPlanType::PORT_AVAILABLE_BUT_NOT_BUILT), request_type(request_type) + { + } + + Optional ExportPlanAction::core_paragraph() const + { + auto it = m_spghs.begin(); + if (it == m_spghs.end()) return nullopt; + return (*it)->package; + } + + std::vector ExportPlanAction::dependencies(const Triplet&) const + { + return source_paragraphs_dependencies(m_spghs); } bool RemovePlanAction::compare_by_name(const RemovePlanAction* left, const RemovePlanAction* right) @@ -404,7 +383,7 @@ namespace vcpkg::Dependencies std::vector adjacency_list(const ExportPlanAction& plan) const override { - return plan.any_paragraph.dependencies(plan.spec.triplet()); + return plan.dependencies(plan.spec.triplet()); } ExportPlanAction load_vertex_data(const PackageSpec& spec) const override @@ -413,14 +392,22 @@ namespace vcpkg::Dependencies ? RequestType::USER_REQUESTED : RequestType::AUTO_SELECTED; - Expected maybe_bpgh = Paragraphs::try_load_cached_control_package(paths, spec); - if (auto bcf = maybe_bpgh.get()) - return ExportPlanAction{spec, AnyParagraph{nullopt, std::move(*bcf), nullopt}, request_type}; - - auto maybe_scf = provider.get_control_file(spec.name()); - if (auto scf = maybe_scf.get()) return ExportPlanAction{spec, {nullopt, nullopt, *scf}, request_type}; + auto spghs = status_db.find_all_installed(spec); - Checks::exit_with_message(VCPKG_LINE_INFO, "Could not find package %s", spec); + if (spghs.size() == 0) + { + return ExportPlanAction{spec, request_type}; + } + else + { + return ExportPlanAction{ + spec, + Util::fmap(spghs, + [](std::unique_ptr const* const& p) -> const StatusParagraph* { + return p->get(); + }), + request_type}; + } } std::string to_string(const PackageSpec& spec) const override { return spec.to_string(); } @@ -642,6 +629,7 @@ namespace vcpkg::Dependencies if (p_cluster->request_type != RequestType::USER_REQUESTED) continue; plan.emplace_back(InstallPlanAction{ p_cluster->spec, + {p_cluster->status_paragraphs.begin(), p_cluster->status_paragraphs.end()}, p_cluster->original_features, p_cluster->request_type, }); @@ -664,17 +652,18 @@ namespace vcpkg::Dependencies cluster.transient_uninstalled = false; - cluster.status_paragraphs.emplace_back(status_paragraph); - auto& status_paragraph_feature = status_paragraph->package.feature; + // In this case, empty string indicates the "core" paragraph for a package. if (status_paragraph_feature.empty()) { cluster.original_features.insert("core"); + cluster.status_paragraphs.emplace(cluster.status_paragraphs.begin(), status_paragraph); } else { cluster.original_features.insert(status_paragraph_feature); + cluster.status_paragraphs.emplace_back(status_paragraph); } } @@ -739,7 +728,6 @@ namespace vcpkg::Dependencies { switch (install_action->plan_type) { - case InstallPlanType::INSTALL: only_install_plans.emplace_back(install_action); break; case InstallPlanType::ALREADY_INSTALLED: if (install_action->request_type == RequestType::USER_REQUESTED) already_installed_plans.emplace_back(install_action); diff --git a/toolsrc/src/vcpkg/export.cpp b/toolsrc/src/vcpkg/export.cpp index 64cb3c804..a9c407dd8 100644 --- a/toolsrc/src/vcpkg/export.cpp +++ b/toolsrc/src/vcpkg/export.cpp @@ -385,7 +385,7 @@ namespace vcpkg::Export " %s" "\n", cmake_variable.s); - }; + } static void handle_raw_based_export(Span export_plan, const ExportArguments& opts, @@ -410,8 +410,7 @@ namespace vcpkg::Export const std::string display_name = action.spec.to_string(); System::println("Exporting package %s... ", display_name); - const BinaryParagraph& binary_paragraph = - action.any_paragraph.binary_control_file.value_or_exit(VCPKG_LINE_INFO).core_paragraph; + const BinaryParagraph& binary_paragraph = action.core_paragraph().value_or_exit(VCPKG_LINE_INFO); const InstallDir dirs = InstallDir::from_destination_root( raw_exported_dir_path / "installed", diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp index 3ecb627f5..368ca6487 100644 --- a/toolsrc/src/vcpkg/install.cpp +++ b/toolsrc/src/vcpkg/install.cpp @@ -292,12 +292,11 @@ namespace vcpkg::Install System::println("Building package %s... ", display_name_with_features); auto result = [&]() -> Build::ExtendedBuildResult { - const Build::BuildPackageConfig build_config{ - action.any_paragraph.source_control_file.value_or_exit(VCPKG_LINE_INFO), - action.spec.triplet(), - paths.port_dir(action.spec), - action.build_options, - action.feature_list}; + const Build::BuildPackageConfig build_config{action.source_control_file.value_or_exit(VCPKG_LINE_INFO), + action.spec.triplet(), + paths.port_dir(action.spec), + action.build_options, + action.feature_list}; return Build::build_package(paths, build_config, status_db); }(); @@ -315,18 +314,6 @@ namespace vcpkg::Install return {code, std::move(bcf)}; } - if (plan_type == InstallPlanType::INSTALL) - { - if (use_head_version && is_user_requested) - { - System::println( - System::Color::warning, "Package %s is already built -- not building from HEAD", display_name); - } - auto code = aux_install(display_name_with_features, - action.any_paragraph.binary_control_file.value_or_exit(VCPKG_LINE_INFO)); - return code; - } - if (plan_type == InstallPlanType::EXCLUDED) { System::println(System::Color::warning, "Package %s is excluded", display_name); @@ -662,11 +649,10 @@ namespace vcpkg::Install if (action) if (auto p_install_plan = action->install_action.get()) { - if (auto p_bcf = p_install_plan->any_paragraph.binary_control_file.get()) - return &p_bcf->core_paragraph; - else if (auto p_status = p_install_plan->any_paragraph.status_paragraph.get()) + if (auto p_status = p_install_plan->status_paragraphs.get()) { - return &p_status->package; + Checks::check_exit(VCPKG_LINE_INFO, p_status->size() > 0); + return &(*p_status->begin())->package; } } return nullptr; diff --git a/toolsrc/src/vcpkg/statusparagraphs.cpp b/toolsrc/src/vcpkg/statusparagraphs.cpp index 19919b76f..61c04d72a 100644 --- a/toolsrc/src/vcpkg/statusparagraphs.cpp +++ b/toolsrc/src/vcpkg/statusparagraphs.cpp @@ -18,7 +18,28 @@ namespace vcpkg { if (p->package.spec.name() == name && p->package.spec.triplet() == triplet) { - spghs.emplace_back(&p); + if (p->package.feature.empty()) + spghs.emplace(spghs.begin(), &p); + else + spghs.emplace_back(&p); + } + } + return spghs; + } + + std::vector*> StatusParagraphs::find_all_installed( + const PackageSpec& spec) const + { + std::vector*> spghs; + for (auto&& p : *this) + { + if (p->package.spec.name() == spec.name() && p->package.spec.triplet() == spec.triplet() && + p->is_installed()) + { + if (p->package.feature.empty()) + spghs.emplace(spghs.begin(), &p); + else + spghs.emplace_back(&p); } } return spghs; -- cgit v1.2.3 From 78d3302940f6c11a220008215b6f67daa8cc8bb7 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Tue, 23 Jan 2018 02:36:39 -0800 Subject: [vcpkg] Remove overload of StatusParagraphs::find_installed() --- toolsrc/include/tests.utils.h | 3 +++ toolsrc/include/vcpkg/statusparagraphs.h | 7 ++----- toolsrc/src/tests.plan.cpp | 7 ------- toolsrc/src/tests.statusparagraphs.cpp | 10 ++++++---- toolsrc/src/tests.utils.cpp | 7 +++++++ toolsrc/src/vcpkg/build.cpp | 6 +++--- toolsrc/src/vcpkg/statusparagraphs.cpp | 15 +++++++++++---- 7 files changed, 32 insertions(+), 23 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/tests.utils.h b/toolsrc/include/tests.utils.h index 0c0add7ab..b23abe4eb 100644 --- a/toolsrc/include/tests.utils.h +++ b/toolsrc/include/tests.utils.h @@ -6,6 +6,7 @@ #include #include #include +#include #include @@ -38,3 +39,5 @@ T&& unwrap(vcpkg::Optional&& opt) Assert::IsTrue(opt.has_value()); return std::move(*opt.get()); } + +vcpkg::PackageSpec unsafe_pspec(std::string name, vcpkg::Triplet t = vcpkg::Triplet::X86_WINDOWS); diff --git a/toolsrc/include/vcpkg/statusparagraphs.h b/toolsrc/include/vcpkg/statusparagraphs.h index 51fbd14dd..4e31b48d8 100644 --- a/toolsrc/include/vcpkg/statusparagraphs.h +++ b/toolsrc/include/vcpkg/statusparagraphs.h @@ -23,11 +23,8 @@ namespace vcpkg std::vector*> find_all_installed(const PackageSpec& spec) const; - const_iterator find_installed(const PackageSpec& spec) const - { - return find_installed(spec.name(), spec.triplet()); - } - const_iterator find_installed(const std::string& name, const Triplet& triplet) const; + const_iterator find_installed(const PackageSpec& spec) const; + bool is_installed(const PackageSpec& spec) const; iterator insert(std::unique_ptr); diff --git a/toolsrc/src/tests.plan.cpp b/toolsrc/src/tests.plan.cpp index 67abf8de0..86386be14 100644 --- a/toolsrc/src/tests.plan.cpp +++ b/toolsrc/src/tests.plan.cpp @@ -504,13 +504,6 @@ namespace UnitTest1 } }; - static PackageSpec unsafe_pspec(std::string name, Triplet t = Triplet::X86_WINDOWS) - { - auto m_ret = PackageSpec::from_name_and_triplet(name, t); - Assert::IsTrue(m_ret.has_value()); - return m_ret.value_or_exit(VCPKG_LINE_INFO); - } - class RemovePlanTests : public TestClass { TEST_METHOD(basic_remove_scheme) diff --git a/toolsrc/src/tests.statusparagraphs.cpp b/toolsrc/src/tests.statusparagraphs.cpp index ed6eaa764..0d5324a8c 100644 --- a/toolsrc/src/tests.statusparagraphs.cpp +++ b/toolsrc/src/tests.statusparagraphs.cpp @@ -1,5 +1,7 @@ #include "tests.pch.h" +#include + using namespace Microsoft::VisualStudio::CppUnitTestFramework; using namespace vcpkg; @@ -25,7 +27,7 @@ Status: install ok installed StatusParagraphs status_db(Util::fmap( *pghs.get(), [](RawParagraph& rpgh) { return std::make_unique(std::move(rpgh)); })); - auto it = status_db.find_installed("ffmpeg", Triplet::X64_WINDOWS); + auto it = status_db.find_installed(unsafe_pspec("ffmpeg", Triplet::X64_WINDOWS)); Assert::IsTrue(it != status_db.end()); } @@ -45,7 +47,7 @@ Status: purge ok not-installed StatusParagraphs status_db(Util::fmap( *pghs.get(), [](RawParagraph& rpgh) { return std::make_unique(std::move(rpgh)); })); - auto it = status_db.find_installed("ffmpeg", Triplet::X64_WINDOWS); + auto it = status_db.find_installed(unsafe_pspec("ffmpeg", Triplet::X64_WINDOWS)); Assert::IsTrue(it == status_db.end()); } @@ -73,8 +75,8 @@ Status: purge ok not-installed StatusParagraphs status_db(Util::fmap( *pghs.get(), [](RawParagraph& rpgh) { return std::make_unique(std::move(rpgh)); })); - auto it = status_db.find_installed("ffmpeg", Triplet::X64_WINDOWS); + auto it = status_db.find_installed(unsafe_pspec("ffmpeg", Triplet::X64_WINDOWS)); Assert::IsTrue(it != status_db.end()); } }; -} \ No newline at end of file +} diff --git a/toolsrc/src/tests.utils.cpp b/toolsrc/src/tests.utils.cpp index d155c7238..19e877920 100644 --- a/toolsrc/src/tests.utils.cpp +++ b/toolsrc/src/tests.utils.cpp @@ -59,3 +59,10 @@ std::unique_ptr make_status_feature_pgh(const char* name, {"Depends", depends}, {"Status", "install ok installed"}}); } + +PackageSpec unsafe_pspec(std::string name, Triplet t) +{ + auto m_ret = PackageSpec::from_name_and_triplet(name, t); + Assert::IsTrue(m_ret.has_value()); + return m_ret.value_or_exit(VCPKG_LINE_INFO); +} diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index 960ba0400..d583a409e 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -269,10 +269,10 @@ namespace vcpkg::Build std::vector missing_specs; for (auto&& dep : filter_dependencies(config.scf.core_paragraph->depends, triplet)) { - if (status_db.find_installed(dep, triplet) == status_db.end()) + auto spec = PackageSpec::from_name_and_triplet(dep, triplet).value_or_exit(VCPKG_LINE_INFO); + if (!status_db.is_installed(spec)) { - missing_specs.push_back( - PackageSpec::from_name_and_triplet(dep, triplet).value_or_exit(VCPKG_LINE_INFO)); + missing_specs.push_back(spec); } } // Fail the build if any dependencies were missing diff --git a/toolsrc/src/vcpkg/statusparagraphs.cpp b/toolsrc/src/vcpkg/statusparagraphs.cpp index 61c04d72a..fb5267b95 100644 --- a/toolsrc/src/vcpkg/statusparagraphs.cpp +++ b/toolsrc/src/vcpkg/statusparagraphs.cpp @@ -65,16 +65,23 @@ namespace vcpkg }); } - StatusParagraphs::const_iterator StatusParagraphs::find_installed(const std::string& name, - const Triplet& triplet) const + StatusParagraphs::const_iterator StatusParagraphs::find_installed(const PackageSpec& spec) const { - const const_iterator it = find(name, triplet); + auto it = find(spec); if (it != end() && (*it)->is_installed()) { return it; } + else + { + return end(); + } + } - return end(); + bool vcpkg::StatusParagraphs::is_installed(const PackageSpec& spec) const + { + auto it = find(spec); + return it != end() && (*it)->is_installed(); } StatusParagraphs::iterator StatusParagraphs::insert(std::unique_ptr pgh) -- cgit v1.2.3 From 3beeb94ec5ca73636d1a26bd9c2ec386b15df9b7 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Tue, 23 Jan 2018 06:50:24 -0800 Subject: [vcpkg] Use InstalledPackageView instead of unsorted raw vectors --- toolsrc/include/vcpkg/dependencies.h | 8 ++--- toolsrc/include/vcpkg/remove.h | 4 +-- toolsrc/include/vcpkg/statusparagraph.h | 15 +++++++++ toolsrc/include/vcpkg/statusparagraphs.h | 2 +- toolsrc/src/vcpkg/dependencies.cpp | 56 +++++++++++++------------------- toolsrc/src/vcpkg/install.cpp | 5 ++- toolsrc/src/vcpkg/remove.cpp | 39 +++++++++++++--------- toolsrc/src/vcpkg/statusparagraph.cpp | 12 +++++++ toolsrc/src/vcpkg/statusparagraphs.cpp | 17 ++++++---- 9 files changed, 92 insertions(+), 66 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/dependencies.h b/toolsrc/include/vcpkg/dependencies.h index 14f51c216..c3f00018d 100644 --- a/toolsrc/include/vcpkg/dependencies.h +++ b/toolsrc/include/vcpkg/dependencies.h @@ -38,7 +38,7 @@ namespace vcpkg::Dependencies InstallPlanAction(); InstallPlanAction(const PackageSpec& spec, - std::vector&& spghs, + InstalledPackageView&& spghs, const std::unordered_set& features, const RequestType& request_type); @@ -52,7 +52,7 @@ namespace vcpkg::Dependencies PackageSpec spec; Optional source_control_file; - Optional> status_paragraphs; + Optional installed_package; InstallPlanType plan_type; RequestType request_type; @@ -103,7 +103,7 @@ namespace vcpkg::Dependencies ExportPlanAction(); ExportPlanAction(const PackageSpec& spec, - std::vector&& status_paragraphs, + InstalledPackageView&& installed_package, const RequestType& request_type); ExportPlanAction(const PackageSpec& spec, const RequestType& request_type); @@ -116,7 +116,7 @@ namespace vcpkg::Dependencies std::vector dependencies(const Triplet& triplet) const; private: - std::vector m_spghs; + Optional m_installed_package; }; struct PortFileProvider diff --git a/toolsrc/include/vcpkg/remove.h b/toolsrc/include/vcpkg/remove.h index 6d8a3ebe9..0610bd127 100644 --- a/toolsrc/include/vcpkg/remove.h +++ b/toolsrc/include/vcpkg/remove.h @@ -17,10 +17,10 @@ namespace vcpkg::Remove void perform_remove_plan_action(const VcpkgPaths& paths, const Dependencies::RemovePlanAction& action, const Purge purge, - StatusParagraphs& status_db); + const StatusParagraphs& status_db); extern const CommandStructure COMMAND_STRUCTURE; void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet); - void remove_package(const VcpkgPaths& paths, const PackageSpec& spec, StatusParagraphs* status_db); + void remove_package(const VcpkgPaths& paths, const PackageSpec& spec, const StatusParagraphs& status_db); } diff --git a/toolsrc/include/vcpkg/statusparagraph.h b/toolsrc/include/vcpkg/statusparagraph.h index 051acf95f..0802de530 100644 --- a/toolsrc/include/vcpkg/statusparagraph.h +++ b/toolsrc/include/vcpkg/statusparagraph.h @@ -44,4 +44,19 @@ namespace vcpkg std::string to_string(InstallState f); std::string to_string(Want f); + + struct InstalledPackageView + { + InstalledPackageView() : core(nullptr) {} + + InstalledPackageView(const StatusParagraph* c, std::vector&& fs) + : core(c), features(std::move(fs)) + { + } + + std::vector dependencies() const; + + const StatusParagraph* core; + std::vector features; + }; } diff --git a/toolsrc/include/vcpkg/statusparagraphs.h b/toolsrc/include/vcpkg/statusparagraphs.h index 4e31b48d8..fd33f8094 100644 --- a/toolsrc/include/vcpkg/statusparagraphs.h +++ b/toolsrc/include/vcpkg/statusparagraphs.h @@ -21,7 +21,7 @@ namespace vcpkg std::vector*> find_all(const std::string& name, const Triplet& triplet); - std::vector*> find_all_installed(const PackageSpec& spec) const; + Optional find_all_installed(const PackageSpec& spec) const; const_iterator find_installed(const PackageSpec& spec) const; bool is_installed(const PackageSpec& spec) const; diff --git a/toolsrc/src/vcpkg/dependencies.cpp b/toolsrc/src/vcpkg/dependencies.cpp index 277de0557..5ce96a3e1 100644 --- a/toolsrc/src/vcpkg/dependencies.cpp +++ b/toolsrc/src/vcpkg/dependencies.cpp @@ -22,7 +22,8 @@ namespace vcpkg::Dependencies struct Cluster : Util::MoveOnlyBase { - std::vector status_paragraphs; + InstalledPackageView installed_package; + Optional source_control_file; PackageSpec spec; std::unordered_map edges; @@ -103,17 +104,6 @@ namespace vcpkg::Dependencies const PortFileProvider& m_provider; }; - static std::vector source_paragraphs_dependencies(Span spghs) - { - if (spghs.size() == 0) return {}; - - auto deps = Util::fmap_flatten( - spghs, [](const StatusParagraph* pgh) -> std::vector const& { return pgh->package.depends; }); - - auto&& spec = spghs[0]->package.spec; - return PackageSpec::from_dependencies_of_port(spec.name(), deps, spec.triplet()); - } - std::string to_output_string(RequestType request_type, const CStringView s, const Build::BuildPackageOptions& options) @@ -153,16 +143,15 @@ namespace vcpkg::Dependencies } InstallPlanAction::InstallPlanAction(const PackageSpec& spec, - std::vector&& spghs, + InstalledPackageView&& ipv, const std::unordered_set& features, const RequestType& request_type) : spec(spec) - , status_paragraphs(std::move(spghs)) + , installed_package(std::move(ipv)) , plan_type(InstallPlanType::ALREADY_INSTALLED) , request_type(request_type) , feature_list(features) { - Checks::check_exit(VCPKG_LINE_INFO, status_paragraphs.get()->size() > 0); } std::string InstallPlanAction::displayname() const @@ -213,12 +202,12 @@ namespace vcpkg::Dependencies ExportPlanAction::ExportPlanAction() : plan_type(ExportPlanType::UNKNOWN), request_type(RequestType::UNKNOWN) {} ExportPlanAction::ExportPlanAction(const PackageSpec& spec, - std::vector&& status_paragraphs, + InstalledPackageView&& installed_package, const RequestType& request_type) : spec(spec) , plan_type(ExportPlanType::ALREADY_BUILT) , request_type(request_type) - , m_spghs(std::move(status_paragraphs)) + , m_installed_package(std::move(installed_package)) { } @@ -229,14 +218,19 @@ namespace vcpkg::Dependencies Optional ExportPlanAction::core_paragraph() const { - auto it = m_spghs.begin(); - if (it == m_spghs.end()) return nullopt; - return (*it)->package; + if (auto p_ip = m_installed_package.get()) + { + return p_ip->core->package; + } + return nullopt; } std::vector ExportPlanAction::dependencies(const Triplet&) const { - return source_paragraphs_dependencies(m_spghs); + if (auto p_ip = m_installed_package.get()) + return p_ip->dependencies(); + else + return {}; } bool RemovePlanAction::compare_by_name(const RemovePlanAction* left, const RemovePlanAction* right) @@ -392,21 +386,15 @@ namespace vcpkg::Dependencies ? RequestType::USER_REQUESTED : RequestType::AUTO_SELECTED; - auto spghs = status_db.find_all_installed(spec); + auto maybe_ipv = status_db.find_all_installed(spec); - if (spghs.size() == 0) + if (auto p_ipv = maybe_ipv.get()) { - return ExportPlanAction{spec, request_type}; + return ExportPlanAction{spec, std::move(*p_ipv), request_type}; } else { - return ExportPlanAction{ - spec, - Util::fmap(spghs, - [](std::unique_ptr const* const& p) -> const StatusParagraph* { - return p->get(); - }), - request_type}; + return ExportPlanAction{spec, request_type}; } } @@ -629,7 +617,7 @@ namespace vcpkg::Dependencies if (p_cluster->request_type != RequestType::USER_REQUESTED) continue; plan.emplace_back(InstallPlanAction{ p_cluster->spec, - {p_cluster->status_paragraphs.begin(), p_cluster->status_paragraphs.end()}, + InstalledPackageView{p_cluster->installed_package}, p_cluster->original_features, p_cluster->request_type, }); @@ -658,12 +646,12 @@ namespace vcpkg::Dependencies if (status_paragraph_feature.empty()) { cluster.original_features.insert("core"); - cluster.status_paragraphs.emplace(cluster.status_paragraphs.begin(), status_paragraph); + cluster.installed_package.core = status_paragraph; } else { cluster.original_features.insert(status_paragraph_feature); - cluster.status_paragraphs.emplace_back(status_paragraph); + cluster.installed_package.features.emplace_back(status_paragraph); } } diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp index 368ca6487..7a1ba4698 100644 --- a/toolsrc/src/vcpkg/install.cpp +++ b/toolsrc/src/vcpkg/install.cpp @@ -649,10 +649,9 @@ namespace vcpkg::Install if (action) if (auto p_install_plan = action->install_action.get()) { - if (auto p_status = p_install_plan->status_paragraphs.get()) + if (auto p_status = p_install_plan->installed_package.get()) { - Checks::check_exit(VCPKG_LINE_INFO, p_status->size() > 0); - return &(*p_status->begin())->package; + return &p_status->core->package; } } return nullptr; diff --git a/toolsrc/src/vcpkg/remove.cpp b/toolsrc/src/vcpkg/remove.cpp index e03df2ed2..3815c3ce7 100644 --- a/toolsrc/src/vcpkg/remove.cpp +++ b/toolsrc/src/vcpkg/remove.cpp @@ -18,22 +18,31 @@ namespace vcpkg::Remove using Dependencies::RequestType; using Update::OutdatedPackage; - void remove_package(const VcpkgPaths& paths, const PackageSpec& spec, StatusParagraphs* status_db) + void remove_package(const VcpkgPaths& paths, const PackageSpec& spec, const StatusParagraphs& status_db) { auto& fs = paths.get_filesystem(); - auto spghs = status_db->find_all(spec.name(), spec.triplet()); - const auto core_pkg = **status_db->find(spec.name(), spec.triplet(), ""); + auto maybe_ipv = status_db.find_all_installed(spec); + + Checks::check_exit( + VCPKG_LINE_INFO, maybe_ipv.has_value(), "unable to remove package %s: already removed", spec); + + auto&& ipv = maybe_ipv.value_or_exit(VCPKG_LINE_INFO); + + std::vector spghs; + spghs.emplace_back(*ipv.core); + for (auto&& feature : ipv.features) + { + spghs.emplace_back(*feature); + } for (auto&& spgh : spghs) { - StatusParagraph& pkg = **spgh; - if (pkg.state != InstallState::INSTALLED) continue; - pkg.want = Want::PURGE; - pkg.state = InstallState::HALF_INSTALLED; - write_update(paths, pkg); + spgh.want = Want::PURGE; + spgh.state = InstallState::HALF_INSTALLED; + write_update(paths, spgh); } - auto maybe_lines = fs.read_lines(paths.listfile_path(core_pkg.package)); + auto maybe_lines = fs.read_lines(paths.listfile_path(ipv.core->package)); if (const auto lines = maybe_lines.get()) { @@ -90,15 +99,13 @@ namespace vcpkg::Remove } } - fs.remove(paths.listfile_path(core_pkg.package)); + fs.remove(paths.listfile_path(ipv.core->package)); } for (auto&& spgh : spghs) { - StatusParagraph& pkg = **spgh; - if (pkg.state != InstallState::HALF_INSTALLED) continue; - pkg.state = InstallState::NOT_INSTALLED; - write_update(paths, pkg); + spgh.state = InstallState::NOT_INSTALLED; + write_update(paths, spgh); } } @@ -136,7 +143,7 @@ namespace vcpkg::Remove void perform_remove_plan_action(const VcpkgPaths& paths, const RemovePlanAction& action, const Purge purge, - StatusParagraphs& status_db) + const StatusParagraphs& status_db) { const std::string display_name = action.spec.to_string(); @@ -147,7 +154,7 @@ namespace vcpkg::Remove break; case RemovePlanType::REMOVE: System::println("Removing package %s... ", display_name); - remove_package(paths, action.spec, &status_db); + remove_package(paths, action.spec, status_db); System::println(System::Color::success, "Removing package %s... done", display_name); break; case RemovePlanType::UNKNOWN: diff --git a/toolsrc/src/vcpkg/statusparagraph.cpp b/toolsrc/src/vcpkg/statusparagraph.cpp index 5f00825e1..05238ba8b 100644 --- a/toolsrc/src/vcpkg/statusparagraph.cpp +++ b/toolsrc/src/vcpkg/statusparagraph.cpp @@ -1,5 +1,6 @@ #include "pch.h" +#include #include using namespace vcpkg::Parse; @@ -83,4 +84,15 @@ namespace vcpkg default: return "error"; } } + std::vector InstalledPackageView::dependencies() const + { + auto deps = Util::fmap_flatten(features, [](const StatusParagraph* pgh) -> std::vector const& { + return pgh->package.depends; + }); + + deps.insert(deps.end(), core->package.depends.begin(), core->package.depends.end()); + + auto&& spec = core->package.spec; + return PackageSpec::from_dependencies_of_port(spec.name(), deps, spec.triplet()); + } } diff --git a/toolsrc/src/vcpkg/statusparagraphs.cpp b/toolsrc/src/vcpkg/statusparagraphs.cpp index fb5267b95..475f86279 100644 --- a/toolsrc/src/vcpkg/statusparagraphs.cpp +++ b/toolsrc/src/vcpkg/statusparagraphs.cpp @@ -27,22 +27,27 @@ namespace vcpkg return spghs; } - std::vector*> StatusParagraphs::find_all_installed( - const PackageSpec& spec) const + Optional StatusParagraphs::find_all_installed(const PackageSpec& spec) const { - std::vector*> spghs; + InstalledPackageView ipv; for (auto&& p : *this) { if (p->package.spec.name() == spec.name() && p->package.spec.triplet() == spec.triplet() && p->is_installed()) { if (p->package.feature.empty()) - spghs.emplace(spghs.begin(), &p); + { + Checks::check_exit(VCPKG_LINE_INFO, ipv.core == nullptr); + ipv.core = p.get(); + } else - spghs.emplace_back(&p); + ipv.features.emplace_back(p.get()); } } - return spghs; + if (ipv.core != nullptr) + return std::move(ipv); + else + return nullopt; } StatusParagraphs::iterator StatusParagraphs::find(const std::string& name, -- cgit v1.2.3 From 130fa279f968ad9661ff4614a2b87f1bb0c5aee2 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Tue, 23 Jan 2018 14:14:01 -0800 Subject: [vcpkg] Revert making remove_package() take status_db by const The in-memory database must be updated to communicate to future actions that they need to look at this package's files (or not) --- toolsrc/include/vcpkg/remove.h | 4 ++-- toolsrc/src/vcpkg/install.cpp | 2 +- toolsrc/src/vcpkg/remove.cpp | 10 ++++++---- 3 files changed, 9 insertions(+), 7 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/remove.h b/toolsrc/include/vcpkg/remove.h index 0610bd127..36aeda2ad 100644 --- a/toolsrc/include/vcpkg/remove.h +++ b/toolsrc/include/vcpkg/remove.h @@ -17,10 +17,10 @@ namespace vcpkg::Remove void perform_remove_plan_action(const VcpkgPaths& paths, const Dependencies::RemovePlanAction& action, const Purge purge, - const StatusParagraphs& status_db); + StatusParagraphs* status_db); extern const CommandStructure COMMAND_STRUCTURE; void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet); - void remove_package(const VcpkgPaths& paths, const PackageSpec& spec, const StatusParagraphs& status_db); + void remove_package(const VcpkgPaths& paths, const PackageSpec& spec, StatusParagraphs* status_db); } diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp index 7a1ba4698..081063633 100644 --- a/toolsrc/src/vcpkg/install.cpp +++ b/toolsrc/src/vcpkg/install.cpp @@ -386,7 +386,7 @@ namespace vcpkg::Install } else if (const auto remove_action = action.remove_action.get()) { - Remove::perform_remove_plan_action(paths, *remove_action, Remove::Purge::YES, status_db); + Remove::perform_remove_plan_action(paths, *remove_action, Remove::Purge::YES, &status_db); } else { diff --git a/toolsrc/src/vcpkg/remove.cpp b/toolsrc/src/vcpkg/remove.cpp index 3815c3ce7..3eaf991ce 100644 --- a/toolsrc/src/vcpkg/remove.cpp +++ b/toolsrc/src/vcpkg/remove.cpp @@ -18,10 +18,10 @@ namespace vcpkg::Remove using Dependencies::RequestType; using Update::OutdatedPackage; - void remove_package(const VcpkgPaths& paths, const PackageSpec& spec, const StatusParagraphs& status_db) + void remove_package(const VcpkgPaths& paths, const PackageSpec& spec, StatusParagraphs* status_db) { auto& fs = paths.get_filesystem(); - auto maybe_ipv = status_db.find_all_installed(spec); + auto maybe_ipv = status_db->find_all_installed(spec); Checks::check_exit( VCPKG_LINE_INFO, maybe_ipv.has_value(), "unable to remove package %s: already removed", spec); @@ -106,6 +106,8 @@ namespace vcpkg::Remove { spgh.state = InstallState::NOT_INSTALLED; write_update(paths, spgh); + + status_db->insert(std::make_unique(std::move(spgh))); } } @@ -143,7 +145,7 @@ namespace vcpkg::Remove void perform_remove_plan_action(const VcpkgPaths& paths, const RemovePlanAction& action, const Purge purge, - const StatusParagraphs& status_db) + StatusParagraphs* status_db) { const std::string display_name = action.spec.to_string(); @@ -285,7 +287,7 @@ namespace vcpkg::Remove for (const RemovePlanAction& action : remove_plan) { - perform_remove_plan_action(paths, action, purge, status_db); + perform_remove_plan_action(paths, action, purge, &status_db); } Checks::exit_success(VCPKG_LINE_INFO); -- cgit v1.2.3 From 3332326c655714fe2e1f740b5635a29c86581228 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 19 Jan 2018 15:12:21 -0800 Subject: Update CMake to 3.10.2 --- toolsrc/src/vcpkg/vcpkgpaths.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index fa5fb128c..e6daedcd4 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -115,7 +115,7 @@ namespace vcpkg static fs::path get_cmake_path(const fs::path& downloads_folder, const fs::path& scripts_folder) { #if defined(_WIN32) - static constexpr std::array EXPECTED_VERSION = {3, 10, 1}; + static constexpr std::array EXPECTED_VERSION = {3, 10, 2}; #else static constexpr std::array EXPECTED_VERSION = {3, 5, 1}; #endif @@ -124,7 +124,7 @@ namespace vcpkg const std::vector from_path = Files::find_from_PATH("cmake"); std::vector candidate_paths; - const fs::path downloaded_copy = downloads_folder / "cmake-3.10.1-win32-x86" / "bin" / "cmake.exe"; + const fs::path downloaded_copy = downloads_folder / "cmake-3.10.2-win32-x86" / "bin" / "cmake.exe"; #if defined(_WIN32) candidate_paths.push_back(downloaded_copy); #endif -- cgit v1.2.3 From 209452755be4e607864481a24eb6383f7e3e984d Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 23 Jan 2018 15:18:31 -0800 Subject: Fix #include casing --- toolsrc/src/vcpkg.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg.cpp b/toolsrc/src/vcpkg.cpp index 094ea1dc5..0af6bd76a 100644 --- a/toolsrc/src/vcpkg.cpp +++ b/toolsrc/src/vcpkg.cpp @@ -4,7 +4,7 @@ #pragma warning(push) #pragma warning(disable : 4768) -#include +#include #pragma warning(pop) #else #include -- cgit v1.2.3 From a413b523e2a4e96c2e2cc3eb4e24e11f7ac75b52 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 23 Jan 2018 15:19:51 -0800 Subject: Add missing initializer --- toolsrc/src/vcpkg/build.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index d583a409e..74b946775 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -61,7 +61,8 @@ namespace vcpkg::Build::Command spec.name()); const StatusParagraphs status_db = database_load_check(paths); - const Build::BuildPackageOptions build_package_options{Build::UseHeadVersion::NO, Build::AllowDownloads::YES}; + const Build::BuildPackageOptions build_package_options{ + Build::UseHeadVersion::NO, Build::AllowDownloads::YES, Build::CleanBuildtrees::NO}; const std::unordered_set features_as_set(full_spec.features.begin(), full_spec.features.end()); -- cgit v1.2.3 From 80f1563c6b6204d09b750944433d51047c46afba Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 23 Jan 2018 15:21:33 -0800 Subject: Use empty() instead of comparing with size() --- toolsrc/src/vcpkg.cpp | 2 +- toolsrc/src/vcpkg/build.cpp | 2 +- toolsrc/src/vcpkg/commands.cache.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg.cpp b/toolsrc/src/vcpkg.cpp index 0af6bd76a..9f29dcdd2 100644 --- a/toolsrc/src/vcpkg.cpp +++ b/toolsrc/src/vcpkg.cpp @@ -214,7 +214,7 @@ static void load_config() static std::string trim_path_from_command_line(const std::string& full_command_line) { Checks::check_exit( - VCPKG_LINE_INFO, full_command_line.size() > 0, "Internal failure - cannot have empty command line"); + VCPKG_LINE_INFO, !full_command_line.empty(), "Internal failure - cannot have empty command line"); if (full_command_line[0] == '"') { diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index 74b946775..4a6834443 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -296,7 +296,7 @@ namespace vcpkg::Build { features.append(feature + ";"); } - if (features.size() > 0) + if (!features.empty()) { features.pop_back(); } diff --git a/toolsrc/src/vcpkg/commands.cache.cpp b/toolsrc/src/vcpkg/commands.cache.cpp index 6fd123b7c..85bf5fb4d 100644 --- a/toolsrc/src/vcpkg/commands.cache.cpp +++ b/toolsrc/src/vcpkg/commands.cache.cpp @@ -47,7 +47,7 @@ namespace vcpkg::Commands::Cache Checks::exit_success(VCPKG_LINE_INFO); } - if (args.command_arguments.size() == 0) + if (args.command_arguments.empty()) { for (const BinaryParagraph& binary_paragraph : binary_paragraphs) { -- cgit v1.2.3 From 2f6e549223021b446b6b5c2942c665ee9a4b91d7 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 23 Jan 2018 15:23:21 -0800 Subject: Use emplace_back() instead of push_back() --- toolsrc/src/vcpkg/commands.create.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/commands.create.cpp b/toolsrc/src/vcpkg/commands.create.cpp index 44f5f7928..25c34cf09 100644 --- a/toolsrc/src/vcpkg/commands.create.cpp +++ b/toolsrc/src/vcpkg/commands.create.cpp @@ -34,7 +34,7 @@ namespace vcpkg::Commands::Create R"(Filename cannot contain invalid chars %s, but was %s)", Files::FILESYSTEM_INVALID_CHARACTERS, zip_file_name); - cmake_args.push_back({"FILENAME", zip_file_name}); + cmake_args.emplace_back("FILENAME", zip_file_name); } const std::string cmd_launch_cmake = make_cmake_cmd(cmake_exe, paths.ports_cmake, cmake_args); -- cgit v1.2.3 From adc8055a90b56cfc2bc45e39deea2d3ab95b8216 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 23 Jan 2018 15:23:38 -0800 Subject: Rename to avoid variable hiding. Move temp into vector --- toolsrc/src/vcpkg/build.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index 4a6834443..db1360ba0 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -270,10 +270,10 @@ namespace vcpkg::Build std::vector missing_specs; for (auto&& dep : filter_dependencies(config.scf.core_paragraph->depends, triplet)) { - auto spec = PackageSpec::from_name_and_triplet(dep, triplet).value_or_exit(VCPKG_LINE_INFO); - if (!status_db.is_installed(spec)) + auto dep_spec = PackageSpec::from_name_and_triplet(dep, triplet).value_or_exit(VCPKG_LINE_INFO); + if (!status_db.is_installed(dep_spec)) { - missing_specs.push_back(spec); + missing_specs.push_back(std::move(dep_spec)); } } // Fail the build if any dependencies were missing -- cgit v1.2.3 From bbf1a737b6da91a452d93579b5162bd7c6239316 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 23 Jan 2018 15:27:38 -0800 Subject: Use for-each loop --- toolsrc/src/vcpkg/commands.exportifw.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/commands.exportifw.cpp b/toolsrc/src/vcpkg/commands.exportifw.cpp index b25982e4b..58d9aa0be 100644 --- a/toolsrc/src/vcpkg/commands.exportifw.cpp +++ b/toolsrc/src/vcpkg/commands.exportifw.cpp @@ -138,13 +138,13 @@ namespace vcpkg::Export::IFW )###", create_release_date())); - for (auto package = unique_packages.begin(); package != unique_packages.end(); ++package) + for (const auto& unique_package : unique_packages) { - const ExportPlanAction& action = *(package->second); + const ExportPlanAction& action = *(unique_package.second); const BinaryParagraph& binary_paragraph = action.core_paragraph().value_or_exit(VCPKG_LINE_INFO); package_xml_file_path = - raw_exported_dir_path / Strings::format("packages.%s", package->first) / "meta" / "package.xml"; + raw_exported_dir_path / Strings::format("packages.%s", unique_package.first) / "meta" / "package.xml"; package_xml_dir_path = package_xml_file_path.parent_path(); fs.create_directories(package_xml_dir_path, ec); Checks::check_exit(VCPKG_LINE_INFO, -- cgit v1.2.3 From 9d85ed4c17bd871cfc4b267c3231fc207f4f0006 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 23 Jan 2018 15:28:20 -0800 Subject: Use char instead of string when string-searching for a single char --- toolsrc/src/vcpkg/commands.hash.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/commands.hash.cpp b/toolsrc/src/vcpkg/commands.hash.cpp index 1e3e5b23d..fa3d80f27 100644 --- a/toolsrc/src/vcpkg/commands.hash.cpp +++ b/toolsrc/src/vcpkg/commands.hash.cpp @@ -7,7 +7,7 @@ namespace vcpkg::Commands::Hash { - static void do_file_hash(fs::path const &cmake_exe_path, fs::path const& path, std::string const& hash_type) + static void do_file_hash(fs::path const& cmake_exe_path, fs::path const& path, std::string const& hash_type) { const std::string cmd_line = Strings::format( R"("%s" -E %ssum %s)", cmake_exe_path.u8string(), Strings::ascii_to_lowercase(hash_type), path.u8string()); @@ -17,7 +17,7 @@ namespace vcpkg::Commands::Hash std::string const& output = ec_data.output; - const auto start = output.find_first_of(" "); + const auto start = output.find_first_of(' '); Checks::check_exit( VCPKG_LINE_INFO, start != std::string::npos, "Unexpected output format from command: %s", cmd_line); -- cgit v1.2.3 From bff50291c209e7864ec1a58f8bc8d646ae7d7240 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 23 Jan 2018 15:28:55 -0800 Subject: Use empty() instead of size() == 0 --- toolsrc/src/vcpkg/commands.list.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/commands.list.cpp b/toolsrc/src/vcpkg/commands.list.cpp index 2570c8a6d..a5efd5442 100644 --- a/toolsrc/src/vcpkg/commands.list.cpp +++ b/toolsrc/src/vcpkg/commands.list.cpp @@ -58,7 +58,7 @@ namespace vcpkg::Commands::List return lhs->package.displayname() < rhs->package.displayname(); }); - if (args.command_arguments.size() == 0) + if (args.command_arguments.empty()) { for (const StatusParagraph* status_paragraph : installed_packages) { -- cgit v1.2.3 From 47833bb39310c0c76a02f3724faf07b41488c736 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 23 Jan 2018 15:31:39 -0800 Subject: Parameter name consistency between declaration and definition --- toolsrc/src/vcpkg/dependencies.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/dependencies.cpp b/toolsrc/src/vcpkg/dependencies.cpp index 5ce96a3e1..236d38bea 100644 --- a/toolsrc/src/vcpkg/dependencies.cpp +++ b/toolsrc/src/vcpkg/dependencies.cpp @@ -415,10 +415,10 @@ namespace vcpkg::Dependencies static MarkPlusResult mark_plus(const std::string& feature, Cluster& cluster, - ClusterGraph& pkg_to_cluster, + ClusterGraph& graph, GraphPlan& graph_plan); - static void mark_minus(Cluster& cluster, ClusterGraph& pkg_to_cluster, GraphPlan& graph_plan); + static void mark_minus(Cluster& cluster, ClusterGraph& graph, GraphPlan& graph_plan); MarkPlusResult mark_plus(const std::string& feature, Cluster& cluster, ClusterGraph& graph, GraphPlan& graph_plan) { -- cgit v1.2.3 From 5be6975cd53892479aae4ce5e9af6cc9ea88634e Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 23 Jan 2018 15:33:13 -0800 Subject: Use =default for trivial destructor --- toolsrc/src/vcpkg/dependencies.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/dependencies.cpp b/toolsrc/src/vcpkg/dependencies.cpp index 236d38bea..af2e8b431 100644 --- a/toolsrc/src/vcpkg/dependencies.cpp +++ b/toolsrc/src/vcpkg/dependencies.cpp @@ -682,7 +682,7 @@ namespace vcpkg::Dependencies { } - PackageGraph::~PackageGraph() {} + PackageGraph::~PackageGraph() = default; void print_plan(const std::vector& action_plan, const bool is_recursive) { -- cgit v1.2.3 From acf3f30d7a4b8cd4b568f6faa3314bcf1940521d Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 23 Jan 2018 15:33:47 -0800 Subject: Init order should match order of fields --- toolsrc/src/vcpkg/dependencies.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/dependencies.cpp b/toolsrc/src/vcpkg/dependencies.cpp index af2e8b431..26ee19e66 100644 --- a/toolsrc/src/vcpkg/dependencies.cpp +++ b/toolsrc/src/vcpkg/dependencies.cpp @@ -678,7 +678,7 @@ namespace vcpkg::Dependencies } PackageGraph::PackageGraph(const PortFileProvider& provider, const StatusParagraphs& status_db) - : m_graph(create_feature_install_graph(provider, status_db)), m_graph_plan(std::make_unique()) + : m_graph_plan(std::make_unique()), m_graph(create_feature_install_graph(provider, status_db)) { } -- cgit v1.2.3 From f3a43d98abecb61a7628f415d9bbe886c4bb26ec Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 23 Jan 2018 15:36:06 -0800 Subject: Remove unneeded else --- toolsrc/src/vcpkg/dependencies.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/dependencies.cpp b/toolsrc/src/vcpkg/dependencies.cpp index 26ee19e66..a4ef991fc 100644 --- a/toolsrc/src/vcpkg/dependencies.cpp +++ b/toolsrc/src/vcpkg/dependencies.cpp @@ -392,10 +392,8 @@ namespace vcpkg::Dependencies { return ExportPlanAction{spec, std::move(*p_ipv), request_type}; } - else - { - return ExportPlanAction{spec, request_type}; - } + + return ExportPlanAction{spec, request_type}; } std::string to_string(const PackageSpec& spec) const override { return spec.to_string(); } -- cgit v1.2.3 From 639f99379847a95a7dacd8874dc41276b6fe4862 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 23 Jan 2018 15:38:08 -0800 Subject: Add missing method const --- toolsrc/include/vcpkg/dependencies.h | 4 ++-- toolsrc/src/vcpkg/dependencies.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/dependencies.h b/toolsrc/include/vcpkg/dependencies.h index c3f00018d..014f004a2 100644 --- a/toolsrc/include/vcpkg/dependencies.h +++ b/toolsrc/include/vcpkg/dependencies.h @@ -151,8 +151,8 @@ namespace vcpkg::Dependencies PackageGraph(const PortFileProvider& provider, const StatusParagraphs& status_db); ~PackageGraph(); - void install(const FeatureSpec& spec); - void upgrade(const PackageSpec& spec); + void install(const FeatureSpec& spec) const; + void upgrade(const PackageSpec& spec) const; std::vector serialize() const; diff --git a/toolsrc/src/vcpkg/dependencies.cpp b/toolsrc/src/vcpkg/dependencies.cpp index a4ef991fc..71cfd52c1 100644 --- a/toolsrc/src/vcpkg/dependencies.cpp +++ b/toolsrc/src/vcpkg/dependencies.cpp @@ -527,7 +527,7 @@ namespace vcpkg::Dependencies return create_feature_install_plan(provider, specs, status_db); } - void PackageGraph::install(const FeatureSpec& spec) + void PackageGraph::install(const FeatureSpec& spec) const { Cluster& spec_cluster = m_graph->get(spec.spec()); spec_cluster.request_type = RequestType::USER_REQUESTED; @@ -565,7 +565,7 @@ namespace vcpkg::Dependencies m_graph_plan->install_graph.add_vertex(ClusterPtr{&spec_cluster}); } - void PackageGraph::upgrade(const PackageSpec& spec) + void PackageGraph::upgrade(const PackageSpec& spec) const { Cluster& spec_cluster = m_graph->get(spec); spec_cluster.request_type = RequestType::USER_REQUESTED; -- cgit v1.2.3 From 67755f9415cb8c7aae971084aa5313bfa71c97bb Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 23 Jan 2018 15:40:25 -0800 Subject: Use !empty() instead of size() > 0 --- toolsrc/src/vcpkg/dependencies.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/dependencies.cpp b/toolsrc/src/vcpkg/dependencies.cpp index 71cfd52c1..4842fde96 100644 --- a/toolsrc/src/vcpkg/dependencies.cpp +++ b/toolsrc/src/vcpkg/dependencies.cpp @@ -743,29 +743,29 @@ namespace vcpkg::Dependencies }); }; - if (excluded.size() > 0) + if (!excluded.empty()) { System::println("The following packages are excluded:\n%s", actions_to_output_string(excluded)); } - if (already_installed_plans.size() > 0) + if (!already_installed_plans.empty()) { System::println("The following packages are already installed:\n%s", actions_to_output_string(already_installed_plans)); } - if (rebuilt_plans.size() > 0) + if (!rebuilt_plans.empty()) { System::println("The following packages will be rebuilt:\n%s", actions_to_output_string(rebuilt_plans)); } - if (new_plans.size() > 0) + if (!new_plans.empty()) { System::println("The following packages will be built and installed:\n%s", actions_to_output_string(new_plans)); } - if (only_install_plans.size() > 0) + if (!only_install_plans.empty()) { System::println("The following packages will be directly installed:\n%s", actions_to_output_string(only_install_plans)); @@ -774,7 +774,7 @@ namespace vcpkg::Dependencies if (has_non_user_requested_packages) System::println("Additional packages (*) will be modified to complete this operation."); - if (remove_plans.size() > 0 && !is_recursive) + if (!remove_plans.empty() && !is_recursive) { System::println(System::Color::warning, "If you are sure you want to rebuild the above packages, run the command with the " -- cgit v1.2.3 From 2fa1ca162104193b36f0d9800b10afb1c4e82257 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 23 Jan 2018 16:59:10 -0800 Subject: Update CHANGELOG and bump version to v0.0.102 --- toolsrc/VERSION.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/VERSION.txt b/toolsrc/VERSION.txt index d78a54a5e..d2de8fba0 100644 --- a/toolsrc/VERSION.txt +++ b/toolsrc/VERSION.txt @@ -1 +1 @@ -"0.0.101" \ No newline at end of file +"0.0.102" \ No newline at end of file -- cgit v1.2.3 From 9eda2e04d161503672bf4250e304892e4ab39c03 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Wed, 24 Jan 2018 14:20:24 -0800 Subject: [vcpkg] Fix issue with any command executing more than 10 transactions with mixed types. Fixes #2600. Fixes #2582. --- toolsrc/src/vcpkg/vcpkglib.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/vcpkglib.cpp b/toolsrc/src/vcpkg/vcpkglib.cpp index de6ffefed..220c29720 100644 --- a/toolsrc/src/vcpkg/vcpkglib.cpp +++ b/toolsrc/src/vcpkg/vcpkglib.cpp @@ -92,7 +92,7 @@ namespace vcpkg const auto my_update_id = update_id++; const auto tmp_update_filename = paths.vcpkg_dir_updates / "incomplete"; - const auto update_filename = paths.vcpkg_dir_updates / std::to_string(my_update_id); + const auto update_filename = paths.vcpkg_dir_updates / Strings::format("%010d", my_update_id); fs.write_contents(tmp_update_filename, Strings::serialize(p)); fs.rename(tmp_update_filename, update_filename); -- cgit v1.2.3 From 0c67c35bccc61945cee6511721c302bdbbaaeb10 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 24 Jan 2018 14:31:37 -0800 Subject: Update CHANGELOG and bump version to v0.0.103 --- toolsrc/VERSION.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/VERSION.txt b/toolsrc/VERSION.txt index d2de8fba0..486716ae3 100644 --- a/toolsrc/VERSION.txt +++ b/toolsrc/VERSION.txt @@ -1 +1 @@ -"0.0.102" \ No newline at end of file +"0.0.103" \ No newline at end of file -- cgit v1.2.3 From 75f19a58ba27f79da4c57d22e4a9e92afcb55d4c Mon Sep 17 00:00:00 2001 From: atkawa7 Date: Sat, 27 Jan 2018 00:44:07 +0200 Subject: [vcpkg] Add string constructor (#2429) * [vcpkg] Add string constructor * Update versiont.h --- toolsrc/include/vcpkg/versiont.h | 1 + toolsrc/src/vcpkg/versiont.cpp | 1 + 2 files changed, 2 insertions(+) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/versiont.h b/toolsrc/include/vcpkg/versiont.h index 6d8332521..8427dfe3b 100644 --- a/toolsrc/include/vcpkg/versiont.h +++ b/toolsrc/include/vcpkg/versiont.h @@ -6,6 +6,7 @@ namespace vcpkg struct VersionT { VersionT(); + VersionT(std::string&& value); VersionT(const std::string& value); const std::string& to_string() const; diff --git a/toolsrc/src/vcpkg/versiont.cpp b/toolsrc/src/vcpkg/versiont.cpp index 91f7e23ef..0d4a39255 100644 --- a/toolsrc/src/vcpkg/versiont.cpp +++ b/toolsrc/src/vcpkg/versiont.cpp @@ -6,6 +6,7 @@ namespace vcpkg { VersionT::VersionT() : value("0.0.0") {} + VersionT::VersionT(std::string&& value) : value(std::move(value)) {} VersionT::VersionT(const std::string& value) : value(value) {} const std::string& VersionT::to_string() const { return value; } bool operator==(const VersionT& left, const VersionT& right) { return left.to_string() == right.to_string(); } -- cgit v1.2.3 From 41a0eee5d10c31c7c3a157454d251dda10bd20fe Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Thu, 1 Feb 2018 10:44:29 -0800 Subject: [vcpkg] Add missing include. Fixes #2700. --- toolsrc/include/vcpkg/base/graphs.h | 1 + 1 file changed, 1 insertion(+) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/base/graphs.h b/toolsrc/include/vcpkg/base/graphs.h index bd22bbcb0..1b0fa61c7 100644 --- a/toolsrc/include/vcpkg/base/graphs.h +++ b/toolsrc/include/vcpkg/base/graphs.h @@ -5,6 +5,7 @@ #include #include +#include namespace vcpkg::Graphs { -- cgit v1.2.3 From 99e5f4ac5090a9558dec13ad11d95024404005e1 Mon Sep 17 00:00:00 2001 From: Squareys Date: Sat, 3 Feb 2018 21:41:49 +0100 Subject: [vcpkg] Add cmake variable containing all features in the package Signed-off-by: Squareys --- toolsrc/src/vcpkg/build.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index db1360ba0..295bd240e 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -290,6 +290,7 @@ namespace vcpkg::Build const auto pre_build_info = PreBuildInfo::from_triplet_file(paths, triplet); std::string features; + std::string all_features; if (GlobalState::feature_packages) { for (auto&& feature : config.feature_list) @@ -300,6 +301,10 @@ namespace vcpkg::Build { features.pop_back(); } + for (auto& feature : config.scf.feature_paragraphs) + { + all_features.append(feature->name + ";"); + } } const Toolset& toolset = paths.get_toolset(pre_build_info); @@ -317,6 +322,7 @@ namespace vcpkg::Build {"_VCPKG_NO_DOWNLOADS", !Util::Enum::to_bool(config.build_package_options.allow_downloads) ? "1" : "0"}, {"GIT", git_exe_path}, {"FEATURES", features}, + {"ALL_FEATURES", all_features}, }); const auto cmd_set_environment = make_build_env_cmd(pre_build_info, toolset); -- cgit v1.2.3 From 0ef1bbb38cf187064e55bcab50de5012e502b3af Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Sat, 3 Feb 2018 21:24:30 -0800 Subject: [vcpkg] Fix crash when trying to enumerate nonexistent directory. --- toolsrc/src/vcpkg/base/files.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/base/files.cpp b/toolsrc/src/vcpkg/base/files.cpp index 8c9e137ed..060a14da3 100644 --- a/toolsrc/src/vcpkg/base/files.cpp +++ b/toolsrc/src/vcpkg/base/files.cpp @@ -74,6 +74,7 @@ namespace vcpkg::Files std::error_code ec; fs::stdfs::recursive_directory_iterator b(dir, ec), e{}; + if (ec) return ret; for (; b != e; ++b) { ret.push_back(b->path()); @@ -86,7 +87,9 @@ namespace vcpkg::Files { std::vector ret; - fs::stdfs::directory_iterator b(dir), e{}; + std::error_code ec; + fs::stdfs::directory_iterator b(dir, ec), e{}; + if (ec) return ret; for (; b != e; ++b) { ret.push_back(b->path()); -- cgit v1.2.3 From 815e3caf5573d1149e1f826b359beb9039293307 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 6 Feb 2018 15:44:59 -0800 Subject: Merge findFileRecursivelyUp into VcpkgPowershellUtils --- toolsrc/vcpkg.sln | 1 - 1 file changed, 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/vcpkg.sln b/toolsrc/vcpkg.sln index c2df757fc..6c429cff9 100644 --- a/toolsrc/vcpkg.sln +++ b/toolsrc/vcpkg.sln @@ -16,7 +16,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "scripts", "scripts", "{F589 ..\scripts\bootstrap.ps1 = ..\scripts\bootstrap.ps1 ..\scripts\fetchDependency.ps1 = ..\scripts\fetchDependency.ps1 ..\scripts\findAnyMSBuildWithCppPlatformToolset.ps1 = ..\scripts\findAnyMSBuildWithCppPlatformToolset.ps1 - ..\scripts\findFileRecursivelyUp.ps1 = ..\scripts\findFileRecursivelyUp.ps1 ..\scripts\findVisualStudioInstallationInstances.ps1 = ..\scripts\findVisualStudioInstallationInstances.ps1 ..\scripts\get_triplet_environment.cmake = ..\scripts\get_triplet_environment.cmake ..\scripts\getProgramFiles32bit.ps1 = ..\scripts\getProgramFiles32bit.ps1 -- cgit v1.2.3 From d503a55412b3fa1b2b96ae0719286ee593f3d732 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 7 Feb 2018 20:38:53 -0800 Subject: Update CHANGELOG and bump version to v0.0.104 --- toolsrc/VERSION.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/VERSION.txt b/toolsrc/VERSION.txt index 486716ae3..f4950aa0b 100644 --- a/toolsrc/VERSION.txt +++ b/toolsrc/VERSION.txt @@ -1 +1 @@ -"0.0.103" \ No newline at end of file +"0.0.104" \ No newline at end of file -- cgit v1.2.3 From b2465a175570df33730937c250357bd1f092b277 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 9 Feb 2018 19:46:43 -0800 Subject: [vcpkg-ci] Delete intermediate build folders even on unsuccesful builds --- toolsrc/src/vcpkg/build.cpp | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index 295bd240e..7de276f4f 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -258,9 +258,9 @@ namespace vcpkg::Build paths.get_filesystem().write_contents(binary_control_file, start); } - ExtendedBuildResult build_package(const VcpkgPaths& paths, - const BuildPackageConfig& config, - const StatusParagraphs& status_db) + static ExtendedBuildResult do_build_package(const VcpkgPaths& paths, + const BuildPackageConfig& config, + const StatusParagraphs& status_db) { const PackageSpec spec = PackageSpec::from_name_and_triplet(config.scf.core_paragraph->name, config.triplet) .value_or_exit(VCPKG_LINE_INFO); @@ -369,10 +369,19 @@ namespace vcpkg::Build write_binary_control_file(paths, *bcf); + return {BuildResult::SUCCEEDED, std::move(bcf)}; + } + + ExtendedBuildResult build_package(const VcpkgPaths& paths, + const BuildPackageConfig& config, + const StatusParagraphs& status_db) + { + ExtendedBuildResult result = do_build_package(paths, config, status_db); + if (config.build_package_options.clean_buildtrees == CleanBuildtrees::YES) { auto& fs = paths.get_filesystem(); - auto buildtrees_dir = paths.buildtrees / spec.name(); + auto buildtrees_dir = paths.buildtrees / config.scf.core_paragraph->name; auto buildtree_files = fs.get_files_non_recursive(buildtrees_dir); for (auto&& file : buildtree_files) { @@ -384,7 +393,7 @@ namespace vcpkg::Build } } - return {BuildResult::SUCCEEDED, std::move(bcf)}; + return result; } const std::string& to_string(const BuildResult build_result) -- cgit v1.2.3 From 9d97db3daa08168bcc4e9ac61af1df73d85ab649 Mon Sep 17 00:00:00 2001 From: ChrisBFX Date: Sat, 10 Feb 2018 23:05:50 +0100 Subject: fixed typo in warning message (#2773) --- toolsrc/src/vcpkg/vcpkgpaths.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index e6daedcd4..06e0c01ab 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -524,7 +524,7 @@ namespace vcpkg { System::println( System::Color::warning, - "Warning: The following VS instances are exluded because the English language pack is unavailable."); + "Warning: The following VS instances are excluded because the English language pack is unavailable."); for (const Toolset& toolset : excluded_toolsets) { System::println(" %s", toolset.visual_studio_root_path.u8string()); -- cgit v1.2.3 From 425d07ef7f82541e50cc8cb1e2716fc33bba7b12 Mon Sep 17 00:00:00 2001 From: Jonathan Hale Date: Thu, 15 Feb 2018 01:18:25 +0100 Subject: [vcpkg] Implement Default-Features (#2697) * [vcpkg] Add Default-Feature to make_status_pgh utility function Signed-off-by: Squareys * [vcpkg] Parse "Default-Features" as dependencies and add test for parsing Signed-off-by: Squareys * [vcpkg] Document some methods and structures Signed-off-by: Squareys * [vcpkg] Add install_default_features_test Signed-off-by: Squareys * [vcpkg] Change install_default_features_test to not have preinstalled package * [vcpkg] Test install behaviour of default features Signed-off-by: Squareys * [vcpkg] Implement default features Signed-off-by: Squareys * [vcpkg] Test default features upgrade behavior Signed-off-by: Squareys * [vcpkg] Implement upgrade with default features Signed-off-by: Squareys * [vcpkg] Test behaviour of upgrade with default features in dependencies Signed-off-by: Squareys * [vcpkg] Make upgrade install new default features Signed-off-by: Squareys * [vcpkg] Move collecting of packages for which to prevent defaults Further down the line to create_feature_install_plan. Signed-off-by: Squareys * [vcpkg] Fix core missing from default features and potential inf loop Signed-off-by: Squareys * [vcpkg] Rename, fix and move some tests Signed-off-by: Squareys --- toolsrc/include/tests.utils.h | 1 + toolsrc/include/vcpkg/dependencies.h | 3 +- toolsrc/include/vcpkg/packagespec.h | 23 +++ toolsrc/include/vcpkg/sourceparagraph.h | 9 +- toolsrc/include/vcpkg/statusparagraphs.h | 5 + toolsrc/src/tests.paragraph.cpp | 35 ++++- toolsrc/src/tests.plan.cpp | 245 +++++++++++++++++++++++++++++-- toolsrc/src/tests.utils.cpp | 6 +- toolsrc/src/vcpkg/dependencies.cpp | 129 ++++++++++++++-- toolsrc/src/vcpkg/install.cpp | 5 + 10 files changed, 434 insertions(+), 27 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/tests.utils.h b/toolsrc/include/tests.utils.h index b23abe4eb..970506663 100644 --- a/toolsrc/include/tests.utils.h +++ b/toolsrc/include/tests.utils.h @@ -20,6 +20,7 @@ namespace Microsoft::VisualStudio::CppUnitTestFramework std::unique_ptr make_status_pgh(const char* name, const char* depends = "", + const char* default_features = "", const char* triplet = "x86-windows"); std::unique_ptr make_status_feature_pgh(const char* name, const char* feature, diff --git a/toolsrc/include/vcpkg/dependencies.h b/toolsrc/include/vcpkg/dependencies.h index 014f004a2..4abeb678e 100644 --- a/toolsrc/include/vcpkg/dependencies.h +++ b/toolsrc/include/vcpkg/dependencies.h @@ -151,7 +151,8 @@ namespace vcpkg::Dependencies PackageGraph(const PortFileProvider& provider, const StatusParagraphs& status_db); ~PackageGraph(); - void install(const FeatureSpec& spec) const; + void install(const FeatureSpec& spec, + const std::unordered_set& prevent_default_features = {}) const; void upgrade(const PackageSpec& spec) const; std::vector serialize() const; diff --git a/toolsrc/include/vcpkg/packagespec.h b/toolsrc/include/vcpkg/packagespec.h index f1119e2f3..0a4347639 100644 --- a/toolsrc/include/vcpkg/packagespec.h +++ b/toolsrc/include/vcpkg/packagespec.h @@ -15,6 +15,12 @@ namespace vcpkg static ExpectedT from_string(const std::string& input); }; + /// + /// + /// Full specification of a package. Contains all information to reference + /// a specific package. + /// + /// struct PackageSpec { static ExpectedT from_name_and_triplet(const std::string& name, @@ -46,6 +52,12 @@ namespace vcpkg Triplet m_triplet; }; + /// + /// + /// Full specification of a feature. Contains all information to reference + /// a single feature in a specific package. + /// + /// struct FeatureSpec { FeatureSpec(const PackageSpec& spec, const std::string& feature) : m_spec(spec), m_feature(feature) {} @@ -82,6 +94,12 @@ namespace vcpkg std::string m_feature; }; + /// + /// + /// Full specification of a package. Contains all information to reference + /// a collection of features in a single package. + /// + /// struct FullPackageSpec { PackageSpec package_spec; @@ -93,6 +111,11 @@ namespace vcpkg const Triplet& default_triplet); }; + /// + /// + /// Contains all information to reference a collection of features in a single package by their names. + /// + /// struct Features { std::string name; diff --git a/toolsrc/include/vcpkg/sourceparagraph.h b/toolsrc/include/vcpkg/sourceparagraph.h index dcbbc1c3b..ea8e27a94 100644 --- a/toolsrc/include/vcpkg/sourceparagraph.h +++ b/toolsrc/include/vcpkg/sourceparagraph.h @@ -29,6 +29,9 @@ namespace vcpkg std::string to_string(const Dependency& dep); + /// + /// Port metadata of additional feature in a package (part of CONTROL file) + /// struct FeatureParagraph { std::string name; @@ -37,7 +40,7 @@ namespace vcpkg }; /// - /// Port metadata (CONTROL file) + /// Port metadata of the core feature of a package (part of CONTROL file) /// struct SourceParagraph { @@ -49,6 +52,10 @@ namespace vcpkg std::vector depends; std::vector default_features; }; + + /// + /// Full metadata of a package: core and other features. + /// struct SourceControlFile { static Parse::ParseExpected parse_control_file( diff --git a/toolsrc/include/vcpkg/statusparagraphs.h b/toolsrc/include/vcpkg/statusparagraphs.h index fd33f8094..b3eec266a 100644 --- a/toolsrc/include/vcpkg/statusparagraphs.h +++ b/toolsrc/include/vcpkg/statusparagraphs.h @@ -6,6 +6,11 @@ namespace vcpkg { + /// Status paragraphs + /// + /// Collection of , e.g. contains the information + /// about whether a package is installed or not. + /// struct StatusParagraphs { StatusParagraphs(); diff --git a/toolsrc/src/tests.paragraph.cpp b/toolsrc/src/tests.paragraph.cpp index 9cddd7bdb..dca89bc59 100644 --- a/toolsrc/src/tests.paragraph.cpp +++ b/toolsrc/src/tests.paragraph.cpp @@ -1,4 +1,4 @@ -#include "tests.pch.h" +#include "tests.pch.h" #pragma comment(lib, "version") #pragma comment(lib, "winhttp") @@ -47,6 +47,7 @@ namespace UnitTest1 {"Maintainer", "m"}, {"Description", "d"}, {"Build-Depends", "bd"}, + {"Default-Features", "df"}, {"Supports", "x64"}, }}); Assert::IsTrue(m_pgh.has_value()); @@ -58,6 +59,8 @@ namespace UnitTest1 Assert::AreEqual("d", pgh->core_paragraph->description.c_str()); Assert::AreEqual(size_t(1), pgh->core_paragraph->depends.size()); Assert::AreEqual("bd", pgh->core_paragraph->depends[0].name().c_str()); + Assert::AreEqual(size_t(1), pgh->core_paragraph->default_features.size()); + Assert::AreEqual("df", pgh->core_paragraph->default_features[0].c_str()); Assert::AreEqual(size_t(1), pgh->core_paragraph->supports.size()); Assert::AreEqual("x64", pgh->core_paragraph->supports[0].c_str()); } @@ -134,6 +137,21 @@ namespace UnitTest1 Assert::AreEqual("uwp", pgh->core_paragraph->depends[1].qualifier.c_str()); } + TEST_METHOD(SourceParagraph_Default_Features) + { + auto m_pgh = + vcpkg::SourceControlFile::parse_control_file(std::vector>{{ + {"Source", "a"}, + {"Version", "1.0"}, + {"Default-Features", "a1"}, + }}); + Assert::IsTrue(m_pgh.has_value()); + auto& pgh = *m_pgh.get(); + + Assert::AreEqual(size_t(1), pgh->core_paragraph->default_features.size()); + Assert::AreEqual("a1", pgh->core_paragraph->default_features[0].c_str()); + } + TEST_METHOD(BinaryParagraph_Construct_Minimum) { vcpkg::BinaryParagraph pgh({ @@ -200,6 +218,21 @@ namespace UnitTest1 Assert::IsTrue(pgh.abi == "abcd123"); } + TEST_METHOD(BinaryParagraph_Default_Features) + { + vcpkg::BinaryParagraph pgh({ + {"Package", "a"}, + {"Version", "1.0"}, + {"Architecture", "x86-windows"}, + {"Multi-Arch", "same"}, + {"Default-Features", "a1"}, + }); + + Assert::AreEqual(size_t(0), pgh.depends.size()); + Assert::AreEqual(size_t(1), pgh.default_features.size()); + Assert::IsTrue(pgh.default_features[0] == "a1"); + } + TEST_METHOD(parse_paragraphs_empty) { const char* str = ""; diff --git a/toolsrc/src/tests.plan.cpp b/toolsrc/src/tests.plan.cpp index 86386be14..a4c628bf6 100644 --- a/toolsrc/src/tests.plan.cpp +++ b/toolsrc/src/tests.plan.cpp @@ -9,15 +9,17 @@ using namespace vcpkg; namespace UnitTest1 { static std::unique_ptr make_control_file( - const char* name, const char* depends, const std::vector>& features = {}) + const char* name, + const char* depends, + const std::vector>& features = {}, + const std::vector& default_features = {}) { using Pgh = std::unordered_map; std::vector scf_pghs; - scf_pghs.push_back(Pgh{ - {"Source", name}, - {"Version", "0"}, - {"Build-Depends", depends}, - }); + scf_pghs.push_back(Pgh{{"Source", name}, + {"Version", "0"}, + {"Build-Depends", depends}, + {"Default-Features", Strings::join(", ", default_features)}}); for (auto&& feature : features) { scf_pghs.push_back(Pgh{ @@ -31,11 +33,15 @@ namespace UnitTest1 return std::move(*m_pgh.get()); } + /// + /// Assert that the given action an install of given features from given package. + /// static void features_check(Dependencies::AnyAction* install_action, std::string pkg_name, std::vector vec, const Triplet& triplet = Triplet::X86_WINDOWS) { + Assert::IsTrue(install_action->install_action.has_value()); const auto& plan = install_action->install_action.value_or_exit(VCPKG_LINE_INFO); const auto& feature_list = plan.feature_list; @@ -56,6 +62,9 @@ namespace UnitTest1 } } + /// + /// Assert that the given action is a remove of given package. + /// static void remove_plan_check(Dependencies::AnyAction* remove_action, std::string pkg_name, const Triplet& triplet = Triplet::X86_WINDOWS) @@ -65,6 +74,9 @@ namespace UnitTest1 Assert::AreEqual(pkg_name.c_str(), plan.spec.name().c_str()); } + /// + /// Map of source control files by their package name. + /// struct PackageSpecMap { std::unordered_map map; @@ -73,9 +85,10 @@ namespace UnitTest1 PackageSpec emplace(const char* name, const char* depends = "", - const std::vector>& features = {}) + const std::vector>& features = {}, + const std::vector& default_features = {}) { - return emplace(std::move(*make_control_file(name, depends, features))); + return emplace(std::move(*make_control_file(name, depends, features, default_features))); } PackageSpec emplace(vcpkg::SourceControlFile&& scf) { @@ -434,6 +447,190 @@ namespace UnitTest1 features_check(&install_plan[0], "a", {"0", "1", "core"}, Triplet::X64_WINDOWS); } + TEST_METHOD(install_default_features_test_1) + { + std::vector> status_paragraphs; + + // Add a port "a" with default features "1" and features "0" and "1". + PackageSpecMap spec_map(Triplet::X64_WINDOWS); + spec_map.emplace("a", "", {{"0", ""}, {"1", ""}}, {"1"}); + + // Install "a" (without explicit feature specification) + auto install_specs = FullPackageSpec::from_string("a", Triplet::X64_WINDOWS); + auto install_plan = Dependencies::create_feature_install_plan( + spec_map.map, + FullPackageSpec::to_feature_specs({install_specs.value_or_exit(VCPKG_LINE_INFO)}), + StatusParagraphs(std::move(status_paragraphs))); + + // Expect the default feature "1" to be installed, but not "0" + Assert::IsTrue(install_plan.size() == 1); + features_check(&install_plan[0], "a", {"1", "core"}, Triplet::X64_WINDOWS); + } + + TEST_METHOD(install_default_features_test_2) + { + std::vector> status_paragraphs; + status_paragraphs.push_back(make_status_pgh("a")); + status_paragraphs.back()->package.spec = + PackageSpec::from_name_and_triplet("a", Triplet::X64_WINDOWS).value_or_exit(VCPKG_LINE_INFO); + + // Add a port "a" of which "core" is already installed, but we will + // install the default features "explicitly" + // "a" has two features, of which "a1" is default. + PackageSpecMap spec_map(Triplet::X64_WINDOWS); + spec_map.emplace("a", "", {{"a0", ""}, {"a1", ""}}, {"a1"}); + + // Install "a" (without explicit feature specification) + auto install_specs = FullPackageSpec::from_string("a", Triplet::X64_WINDOWS); + auto install_plan = Dependencies::create_feature_install_plan( + spec_map.map, + FullPackageSpec::to_feature_specs({install_specs.value_or_exit(VCPKG_LINE_INFO)}), + StatusParagraphs(std::move(status_paragraphs))); + + // Expect "a" to get removed for rebuild and then installed with default + // features. + Assert::IsTrue(install_plan.size() == 2); + remove_plan_check(&install_plan[0], "a", Triplet::X64_WINDOWS); + features_check(&install_plan[1], "a", {"a1", "core"}, Triplet::X64_WINDOWS); + } + + TEST_METHOD(install_default_features_test_3) + { + std::vector> status_paragraphs; + + // "a" has two features, of which "a1" is default. + PackageSpecMap spec_map(Triplet::X64_WINDOWS); + spec_map.emplace("a", "", {{"a0", ""}, {"a1", ""}}, {"a1"}); + + // Explicitly install "a" without default features + auto install_specs = FullPackageSpec::from_string("a[core]", Triplet::X64_WINDOWS); + auto install_plan = Dependencies::create_feature_install_plan( + spec_map.map, + FullPackageSpec::to_feature_specs({install_specs.value_or_exit(VCPKG_LINE_INFO)}), + StatusParagraphs(std::move(status_paragraphs))); + + // Expect the default feature not to get installed. + Assert::IsTrue(install_plan.size() == 1); + features_check(&install_plan[0], "a", {"core"}, Triplet::X64_WINDOWS); + } + + TEST_METHOD(install_default_features_of_dependency_test_1) + { + std::vector> status_paragraphs; + + // Add a port "a" which depends on the core of "b" + PackageSpecMap spec_map(Triplet::X64_WINDOWS); + spec_map.emplace("a", "b[core]"); + // "b" has two features, of which "b1" is default. + spec_map.emplace("b", "", {{"b0", ""}, {"b1", ""}}, {"b1"}); + + // Install "a" (without explicit feature specification) + auto install_specs = FullPackageSpec::from_string("a", Triplet::X64_WINDOWS); + auto install_plan = Dependencies::create_feature_install_plan( + spec_map.map, + FullPackageSpec::to_feature_specs({install_specs.value_or_exit(VCPKG_LINE_INFO)}), + StatusParagraphs(std::move(status_paragraphs))); + + // Expect "a" to get installed and defaults of "b" through the dependency, + // as no explicit features of "b" are installed by the user. + Assert::IsTrue(install_plan.size() == 2); + features_check(&install_plan[1], "a", {"core"}, Triplet::X64_WINDOWS); + features_check(&install_plan[0], "b", {"b1", "core"}, Triplet::X64_WINDOWS); + } + + TEST_METHOD(install_default_features_of_dependency_test_2) + { + std::vector> status_paragraphs; + status_paragraphs.push_back(make_status_pgh("b")); + status_paragraphs.back()->package.spec = + PackageSpec::from_name_and_triplet("b", Triplet::X64_WINDOWS).value_or_exit(VCPKG_LINE_INFO); + + // Add a port "a" which depends on the core of "b", which was already + // installed explicitly + PackageSpecMap spec_map(Triplet::X64_WINDOWS); + spec_map.emplace("a", "b[core]"); + // "b" has two features, of which "b1" is default. + spec_map.emplace("b", "", {{"b0", ""}, {"b1", ""}}, {"b1"}); + + // Install "a" (without explicit feature specification) + auto install_specs = FullPackageSpec::from_string("a", Triplet::X64_WINDOWS); + auto install_plan = Dependencies::create_feature_install_plan( + spec_map.map, + FullPackageSpec::to_feature_specs({install_specs.value_or_exit(VCPKG_LINE_INFO)}), + StatusParagraphs(std::move(status_paragraphs))); + + // Expect "a" to get installed, not the defaults of "b", as the required + // dependencies are already there, installed explicitly by the user. + Assert::IsTrue(install_plan.size() == 1); + features_check(&install_plan[0], "a", {"core"}, Triplet::X64_WINDOWS); + } + + TEST_METHOD(upgrade_with_default_features_1) + { + std::vector> pghs; + pghs.push_back(make_status_pgh("a", "", "1")); + pghs.push_back(make_status_feature_pgh("a", "0")); + pghs.back()->package.spec = + PackageSpec::from_name_and_triplet("a", Triplet::X86_WINDOWS).value_or_exit(VCPKG_LINE_INFO); + StatusParagraphs status_db(std::move(pghs)); + + // Add a port "a" of which "core" and "0" are already installed. + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + auto spec_a = spec_map.emplace("a", "", {{"0", ""}, {"1", ""}}, {"1"}); + + Dependencies::MapPortFileProvider provider(spec_map.map); + Dependencies::PackageGraph graph(provider, status_db); + + graph.upgrade(spec_a); + auto plan = graph.serialize(); + + // The upgrade should not install the default feature + Assert::AreEqual(size_t(2), plan.size()); + + Assert::AreEqual("a", plan[0].spec().name().c_str()); + Assert::IsTrue(plan[0].remove_action.has_value()); + + Assert::AreEqual("a", plan[1].spec().name().c_str()); + Assert::IsTrue(plan[1].install_action.has_value()); + features_check(&plan[1], "a", {"core", "0"}, Triplet::X86_WINDOWS); + } + + TEST_METHOD(upgrade_with_default_features_2) + { + std::vector> pghs; + pghs.push_back(make_status_pgh("b")); + pghs.push_back(make_status_pgh("a", "b[core]")); + pghs.back()->package.spec = + PackageSpec::from_name_and_triplet("a", Triplet::X64_WINDOWS).value_or_exit(VCPKG_LINE_INFO); + + StatusParagraphs status_db(std::move(pghs)); + + // Add a port "a" of which "core" and "0" are already installed. + PackageSpecMap spec_map(Triplet::X64_WINDOWS); + auto spec_a = spec_map.emplace("a", "b[core]"); + spec_map.emplace("b", "", {{"b0", ""}, {"b1", ""}}, {"b0"}); + + Dependencies::MapPortFileProvider provider(spec_map.map); + Dependencies::PackageGraph graph(provider, status_db); + + graph.upgrade(spec_a); + auto plan = graph.serialize(); + + // The upgrade should not install the default feature + Assert::AreEqual(size_t(3), plan.size()); + + Assert::AreEqual("a", plan[0].spec().name().c_str()); + Assert::IsTrue(plan[0].remove_action.has_value()); + + Assert::AreEqual("b", plan[1].spec().name().c_str()); + Assert::IsTrue(plan[1].install_action.has_value()); + features_check(&plan[1], "b", {"b0", "core"}, Triplet::X64_WINDOWS); + + Assert::AreEqual("a", plan[2].spec().name().c_str()); + Assert::IsTrue(plan[2].install_action.has_value()); + features_check(&plan[2], "a", {"core"}, Triplet::X64_WINDOWS); + } + TEST_METHOD(transitive_features_test) { std::vector> status_paragraphs; @@ -567,9 +764,9 @@ namespace UnitTest1 TEST_METHOD(features_depend_remove_scheme_once_removed_x64) { std::vector> pghs; - pghs.push_back(make_status_pgh("expat", "", "x64")); - pghs.push_back(make_status_pgh("vtk", "expat", "x64")); - pghs.push_back(make_status_pgh("opencv", "", "x64")); + pghs.push_back(make_status_pgh("expat", "", "", "x64")); + pghs.push_back(make_status_pgh("vtk", "expat", "", "x64")); + pghs.push_back(make_status_pgh("opencv", "", "", "x64")); pghs.push_back(make_status_feature_pgh("opencv", "vtk", "vtk", "x64")); StatusParagraphs status_db(std::move(pghs)); @@ -715,5 +912,31 @@ namespace UnitTest1 features_check(&plan[1], "a", {"core", "a1"}); } + + TEST_METHOD(basic_upgrade_scheme_with_new_default_feature) + { + // only core of package "a" is installed + std::vector> pghs; + pghs.push_back(make_status_pgh("a")); + StatusParagraphs status_db(std::move(pghs)); + + // a1 was added as a default feature and should be installed in upgrade + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + auto spec_a = spec_map.emplace("a", "", {{"a1", ""}}, {"a1"}); + + Dependencies::MapPortFileProvider provider(spec_map.map); + Dependencies::PackageGraph graph(provider, status_db); + + graph.upgrade(spec_a); + + auto plan = graph.serialize(); + + Assert::AreEqual(size_t(2), plan.size()); + + Assert::AreEqual("a", plan[0].spec().name().c_str()); + Assert::IsTrue(plan[0].remove_action.has_value()); + + features_check(&plan[1], "a", {"core", "a1"}); + } }; } diff --git a/toolsrc/src/tests.utils.cpp b/toolsrc/src/tests.utils.cpp index 19e877920..a3d8ffc7d 100644 --- a/toolsrc/src/tests.utils.cpp +++ b/toolsrc/src/tests.utils.cpp @@ -35,7 +35,10 @@ namespace Microsoft::VisualStudio::CppUnitTestFramework std::wstring ToString(const vcpkg::PackageSpec& t) { return ToString(t.to_string()); } } -std::unique_ptr make_status_pgh(const char* name, const char* depends, const char* triplet) +std::unique_ptr make_status_pgh(const char* name, + const char* depends, + const char* default_features, + const char* triplet) { using Pgh = std::unordered_map; return std::make_unique(Pgh{{"Package", name}, @@ -43,6 +46,7 @@ std::unique_ptr make_status_pgh(const char* name, const char* d {"Architecture", triplet}, {"Multi-Arch", "same"}, {"Depends", depends}, + {"Default-Features", default_features}, {"Status", "install ok installed"}}); } std::unique_ptr make_status_feature_pgh(const char* name, diff --git a/toolsrc/src/vcpkg/dependencies.cpp b/toolsrc/src/vcpkg/dependencies.cpp index 4842fde96..307c779c8 100644 --- a/toolsrc/src/vcpkg/dependencies.cpp +++ b/toolsrc/src/vcpkg/dependencies.cpp @@ -20,6 +20,9 @@ namespace vcpkg::Dependencies bool plus = false; }; + /// + /// Representation of a package and its features in a ClusterGraph. + /// struct Cluster : Util::MoveOnlyBase { InstalledPackageView installed_package; @@ -64,10 +67,18 @@ namespace vcpkg::Dependencies Graphs::Graph install_graph; }; + /// + /// Directional graph representing a collection of packages with their features connected by their dependencies. + /// struct ClusterGraph : Util::MoveOnlyBase { explicit ClusterGraph(const PortFileProvider& provider) : m_provider(provider) {} + /// + /// Find the cluster associated with spec or if not found, create it from the PortFileProvider. + /// + /// Package spec to get the cluster for. + /// The cluster found or created for spec. Cluster& get(const PackageSpec& spec) { auto it = m_graph.find(spec); @@ -414,16 +425,52 @@ namespace vcpkg::Dependencies static MarkPlusResult mark_plus(const std::string& feature, Cluster& cluster, ClusterGraph& graph, - GraphPlan& graph_plan); + GraphPlan& graph_plan, + const std::unordered_set& prevent_default_features = {}); static void mark_minus(Cluster& cluster, ClusterGraph& graph, GraphPlan& graph_plan); - MarkPlusResult mark_plus(const std::string& feature, Cluster& cluster, ClusterGraph& graph, GraphPlan& graph_plan) + MarkPlusResult mark_plus(const std::string& feature, + Cluster& cluster, + ClusterGraph& graph, + GraphPlan& graph_plan, + const std::unordered_set& prevent_default_features) { if (feature.empty()) { - // Indicates that core was not specified in the reference - return mark_plus("core", cluster, graph, graph_plan); + if (prevent_default_features.find(cluster.spec.name()) == prevent_default_features.end()) + { + // Indicates that core was not specified in the reference + + // Add default features for this package, if this is the "core" feature and we + // are not supposed to prevent default features for this package + if (auto scf = cluster.source_control_file.value_or(nullptr)) + { + for (auto&& default_feature : scf->core_paragraph.get()->default_features) + { + auto res = mark_plus(default_feature, cluster, graph, graph_plan, prevent_default_features); + if (res != MarkPlusResult::SUCCESS) + { + return res; + } + } + + // "core" is always an implicit default feature. In case we did not add it as + // a dependency above (e.g. no default features), add it here. + auto res = mark_plus("core", cluster, graph, graph_plan, prevent_default_features); + if (res != MarkPlusResult::SUCCESS) + { + return res; + } + } + + return MarkPlusResult::SUCCESS; + } + else + { + // Skip adding the default features, as explicitly told not to. + return MarkPlusResult::SUCCESS; + } } auto it = cluster.edges.find(feature); @@ -454,16 +501,21 @@ namespace vcpkg::Dependencies if (feature != "core") { // All features implicitly depend on core - auto res = mark_plus("core", cluster, graph, graph_plan); + auto res = mark_plus("core", cluster, graph, graph_plan, prevent_default_features); // Should be impossible for "core" to not exist Checks::check_exit(VCPKG_LINE_INFO, res == MarkPlusResult::SUCCESS); } + else + { + // Add the default features of this package. + auto res = mark_plus("", cluster, graph, graph_plan, prevent_default_features); + } for (auto&& depend : cluster.edges[feature].build_edges) { auto& depend_cluster = graph.get(depend.spec()); - auto res = mark_plus(depend.feature(), depend_cluster, graph, graph_plan); + auto res = mark_plus(depend.feature(), depend_cluster, graph, graph_plan, prevent_default_features); Checks::check_exit(VCPKG_LINE_INFO, res == MarkPlusResult::SUCCESS, @@ -483,6 +535,18 @@ namespace vcpkg::Dependencies if (cluster.will_remove) return; cluster.will_remove = true; + std::unordered_set prevent_default_features; + + if (cluster.request_type == RequestType::USER_REQUESTED) + { + // Do not install default features for packages which the user + // installed explicitly. New default features for dependent + // clusters should still be upgraded. + prevent_default_features.insert(cluster.spec.name()); + + // For dependent packages this is handles through the recursion + } + graph_plan.remove_graph.add_vertex({&cluster}); for (auto&& pair : cluster.edges) { @@ -498,7 +562,7 @@ namespace vcpkg::Dependencies cluster.transient_uninstalled = true; for (auto&& original_feature : cluster.original_features) { - auto res = mark_plus(original_feature, cluster, graph, graph_plan); + auto res = mark_plus(original_feature, cluster, graph, graph_plan, prevent_default_features); if (res != MarkPlusResult::SUCCESS) { System::println(System::Color::warning, @@ -506,19 +570,54 @@ namespace vcpkg::Dependencies FeatureSpec{cluster.spec, original_feature}); } } + + // Check if any default features have been added + if (auto scf = cluster.source_control_file.value_or(nullptr)) + { + auto& previous_df = cluster.installed_package.core->package.default_features; + for (auto&& default_feature : scf->core_paragraph->default_features) + { + if (std::find(previous_df.begin(), previous_df.end(), default_feature) == previous_df.end()) + { + // this is a new default feature, mark it for installation + auto res = mark_plus(default_feature, cluster, graph, graph_plan); + if (res != MarkPlusResult::SUCCESS) + { + System::println(System::Color::warning, + "Warning: could not install new default feature %s", + FeatureSpec{cluster.spec, default_feature}); + } + } + } + } } + /// Figure out which actions are required to install features specifications in `specs`. + /// Contains the ports of the current environment. + /// Feature specifications to resolve dependencies for. + /// Status of installed packages in the current environment. std::vector create_feature_install_plan(const PortFileProvider& provider, const std::vector& specs, const StatusParagraphs& status_db) { + std::unordered_set prevent_default_features; + for (auto&& spec : specs) + { + // When "core" is explicitly listed, default features should not be installed. + if (spec.feature() == "core") prevent_default_features.insert(spec.name()); + } + PackageGraph pgraph(provider, status_db); for (auto&& spec : specs) - pgraph.install(spec); + pgraph.install(spec, prevent_default_features); return pgraph.serialize(); } + /// Figure out which actions are required to install features specifications in `specs`. + /// Map of all source files in the current environment. + /// Feature specifications to resolve dependencies for. + /// Status of installed packages in the current environment. std::vector create_feature_install_plan(const std::unordered_map& map, const std::vector& specs, const StatusParagraphs& status_db) @@ -527,7 +626,12 @@ namespace vcpkg::Dependencies return create_feature_install_plan(provider, specs, status_db); } - void PackageGraph::install(const FeatureSpec& spec) const + /// + /// List of package names for which default features should not be installed instead of the core package (e.g. if + /// the user is currently installing specific features of that package). + /// + void PackageGraph::install(const FeatureSpec& spec, + const std::unordered_set& prevent_default_features) const { Cluster& spec_cluster = m_graph->get(spec.spec()); spec_cluster.request_type = RequestType::USER_REQUESTED; @@ -537,13 +641,14 @@ namespace vcpkg::Dependencies { for (auto&& feature : p_scf->feature_paragraphs) { - auto res = mark_plus(feature->name, spec_cluster, *m_graph, *m_graph_plan); + auto res = + mark_plus(feature->name, spec_cluster, *m_graph, *m_graph_plan, prevent_default_features); Checks::check_exit( VCPKG_LINE_INFO, res == MarkPlusResult::SUCCESS, "Error: Unable to locate feature %s", spec); } - auto res = mark_plus("core", spec_cluster, *m_graph, *m_graph_plan); + auto res = mark_plus("core", spec_cluster, *m_graph, *m_graph_plan, prevent_default_features); Checks::check_exit( VCPKG_LINE_INFO, res == MarkPlusResult::SUCCESS, "Error: Unable to locate feature %s", spec); @@ -556,7 +661,7 @@ namespace vcpkg::Dependencies } else { - auto res = mark_plus(spec.feature(), spec_cluster, *m_graph, *m_graph_plan); + auto res = mark_plus(spec.feature(), spec_cluster, *m_graph, *m_graph_plan, prevent_default_features); Checks::check_exit( VCPKG_LINE_INFO, res == MarkPlusResult::SUCCESS, "Error: Unable to locate feature %s", spec); diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp index 081063633..595945d39 100644 --- a/toolsrc/src/vcpkg/install.cpp +++ b/toolsrc/src/vcpkg/install.cpp @@ -513,6 +513,11 @@ namespace vcpkg::Install } } + /// + /// + /// Run "install" command. + /// + /// void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) { // input sanitization -- cgit v1.2.3 From bfac7b57161168b8b54ea159bbf2c88794098c1c Mon Sep 17 00:00:00 2001 From: Fujii Hironori Date: Fri, 16 Feb 2018 21:25:12 +0900 Subject: [vcpkg] http_proxy and https_proxy should be lowercase (#2815) Pacman of Msys understands only lowercase environment variables http_proxy and https_proxy. --- toolsrc/src/vcpkg/base/system.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/base/system.cpp b/toolsrc/src/vcpkg/base/system.cpp index 84721bf6e..f71fd8445 100644 --- a/toolsrc/src/vcpkg/base/system.cpp +++ b/toolsrc/src/vcpkg/base/system.cpp @@ -175,8 +175,8 @@ namespace vcpkg::System L"USERPROFILE", L"windir", // Enables proxy information to be passed to Curl, the underlying download library in cmake.exe - L"HTTP_PROXY", - L"HTTPS_PROXY", + L"http_proxy", + L"https_proxy", // Enables find_package(CUDA) in CMake L"CUDA_PATH", // Environmental variable generated automatically by CUDA after installation -- cgit v1.2.3 From 16faed678540be37ea623fa7f0f2c2e7c442b147 Mon Sep 17 00:00:00 2001 From: Squareys Date: Fri, 16 Feb 2018 14:27:04 +0100 Subject: [vcpkg] Add find/find_installed/is_installed for FeatureSpec Signed-off-by: Squareys --- toolsrc/include/vcpkg/statusparagraphs.h | 31 ++++++++++++++++++++++++++++++ toolsrc/src/tests.statusparagraphs.cpp | 33 ++++++++++++++++++++++++++++++++ toolsrc/src/vcpkg/statusparagraphs.cpp | 19 ++++++++++++++++++ 3 files changed, 83 insertions(+) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/statusparagraphs.h b/toolsrc/include/vcpkg/statusparagraphs.h index b3eec266a..fa064de7e 100644 --- a/toolsrc/include/vcpkg/statusparagraphs.h +++ b/toolsrc/include/vcpkg/statusparagraphs.h @@ -20,7 +20,21 @@ namespace vcpkg using iterator = container::reverse_iterator; using const_iterator = container::const_reverse_iterator; + /// Find the StatusParagraph for given spec. + /// Package specification to find the status paragraph for + /// Iterator for found spec const_iterator find(const PackageSpec& spec) const { return find(spec.name(), spec.triplet()); } + + /// Find the StatusParagraph for given feature spec. + /// Feature specification to find the status paragraph for + /// Iterator for found spec + const_iterator find(const FeatureSpec& spec) const { return find(spec.name(), spec.triplet(), spec.feature()); } + + /// Find a StatusParagraph by name, triplet and feature. + /// Package name + /// Triplet + /// Feature name + /// Iterator for found spec iterator find(const std::string& name, const Triplet& triplet, const std::string& feature = ""); const_iterator find(const std::string& name, const Triplet& triplet, const std::string& feature = "") const; @@ -28,9 +42,26 @@ namespace vcpkg Optional find_all_installed(const PackageSpec& spec) const; + /// Find the StatusParagraph for given spec if installed + /// Package specification to find the status for + /// Iterator for found spec const_iterator find_installed(const PackageSpec& spec) const; + + /// Find the StatusParagraph for given feature spec if installed + /// Feature specification to find the status for + /// Iterator for found spec + const_iterator find_installed(const FeatureSpec& spec) const; + + /// Find the StatusParagraph for given spec and return its install status + /// Package specification to check if installed + /// `true` if installed, `false` if not or not found. bool is_installed(const PackageSpec& spec) const; + /// Find the StatusParagraph for given feature spec and return its install status + /// Feature specification to check if installed + /// `true` if installed, `false` if not or not found. + bool is_installed(const FeatureSpec& spec) const; + iterator insert(std::unique_ptr); friend void serialize(const StatusParagraphs& pgh, std::string& out_str); diff --git a/toolsrc/src/tests.statusparagraphs.cpp b/toolsrc/src/tests.statusparagraphs.cpp index 0d5324a8c..fa0d54fac 100644 --- a/toolsrc/src/tests.statusparagraphs.cpp +++ b/toolsrc/src/tests.statusparagraphs.cpp @@ -77,6 +77,39 @@ Status: purge ok not-installed auto it = status_db.find_installed(unsafe_pspec("ffmpeg", Triplet::X64_WINDOWS)); Assert::IsTrue(it != status_db.end()); + + // Feature "openssl" is not installed and should not be found + auto it1 = status_db.find_installed({unsafe_pspec("ffmpeg", Triplet::X64_WINDOWS), "openssl"}); + Assert::IsTrue(it1 == status_db.end()); + } + + TEST_METHOD(find_for_feature_packages) + { + auto pghs = parse_paragraphs(R"( +Package: ffmpeg +Version: 3.3.3 +Architecture: x64-windows +Multi-Arch: same +Description: +Status: install ok installed + +Package: ffmpeg +Feature: openssl +Depends: openssl +Architecture: x64-windows +Multi-Arch: same +Description: +Status: install ok installed +)"); + Assert::IsTrue(!!pghs); + if (!pghs) return; + + StatusParagraphs status_db(Util::fmap( + *pghs.get(), [](RawParagraph& rpgh) { return std::make_unique(std::move(rpgh)); })); + + // Feature "openssl" is installed and should therefore be found + auto it = status_db.find_installed({unsafe_pspec("ffmpeg", Triplet::X64_WINDOWS), "openssl"}); + Assert::IsTrue(it != status_db.end()); } }; } diff --git a/toolsrc/src/vcpkg/statusparagraphs.cpp b/toolsrc/src/vcpkg/statusparagraphs.cpp index 475f86279..b23d8b884 100644 --- a/toolsrc/src/vcpkg/statusparagraphs.cpp +++ b/toolsrc/src/vcpkg/statusparagraphs.cpp @@ -83,12 +83,31 @@ namespace vcpkg } } + StatusParagraphs::const_iterator StatusParagraphs::find_installed(const FeatureSpec& spec) const + { + auto it = find(spec); + if (it != end() && (*it)->is_installed()) + { + return it; + } + else + { + return end(); + } + } + bool vcpkg::StatusParagraphs::is_installed(const PackageSpec& spec) const { auto it = find(spec); return it != end() && (*it)->is_installed(); } + bool vcpkg::StatusParagraphs::is_installed(const FeatureSpec& spec) const + { + auto it = find(spec); + return it != end() && (*it)->is_installed(); + } + StatusParagraphs::iterator StatusParagraphs::insert(std::unique_ptr pgh) { Checks::check_exit(VCPKG_LINE_INFO, pgh != nullptr, "Inserted null paragraph"); -- cgit v1.2.3 From f1ce125a28c98fd5a87bf509ac965b06c219d8f3 Mon Sep 17 00:00:00 2001 From: Squareys Date: Fri, 16 Feb 2018 14:27:32 +0100 Subject: [vcpkg] Fix build command for packages that depend of features Signed-off-by: Squareys --- toolsrc/include/vcpkg/build.h | 4 ++-- toolsrc/src/vcpkg/build.cpp | 13 ++++++++----- 2 files changed, 10 insertions(+), 7 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/build.h b/toolsrc/include/vcpkg/build.h index e3f8bf79e..d7c5c8344 100644 --- a/toolsrc/include/vcpkg/build.h +++ b/toolsrc/include/vcpkg/build.h @@ -104,11 +104,11 @@ namespace vcpkg::Build struct ExtendedBuildResult { ExtendedBuildResult(BuildResult code); - ExtendedBuildResult(BuildResult code, std::vector&& unmet_deps); + ExtendedBuildResult(BuildResult code, std::vector&& unmet_deps); ExtendedBuildResult(BuildResult code, std::unique_ptr&& bcf); BuildResult code; - std::vector unmet_dependencies; + std::vector unmet_dependencies; std::unique_ptr binary_control_file; }; diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index 7de276f4f..cc376c773 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -267,13 +267,16 @@ namespace vcpkg::Build const Triplet& triplet = config.triplet; { - std::vector missing_specs; + std::vector missing_specs; for (auto&& dep : filter_dependencies(config.scf.core_paragraph->depends, triplet)) { - auto dep_spec = PackageSpec::from_name_and_triplet(dep, triplet).value_or_exit(VCPKG_LINE_INFO); - if (!status_db.is_installed(dep_spec)) + auto dep_specs = FeatureSpec::from_strings_and_triplet({dep}, triplet); + for (auto&& feature : dep_specs) { - missing_specs.push_back(std::move(dep_spec)); + if (!status_db.is_installed(feature)) + { + missing_specs.push_back(std::move(feature)); + } } } // Fail the build if any dependencies were missing @@ -600,7 +603,7 @@ namespace vcpkg::Build : code(code), binary_control_file(std::move(bcf)) { } - ExtendedBuildResult::ExtendedBuildResult(BuildResult code, std::vector&& unmet_deps) + ExtendedBuildResult::ExtendedBuildResult(BuildResult code, std::vector&& unmet_deps) : code(code), unmet_dependencies(std::move(unmet_deps)) { } -- cgit v1.2.3 From 72bc3647b61ad3e8df8d1e620daa7d919b5241d6 Mon Sep 17 00:00:00 2001 From: Jonathan Hale Date: Fri, 16 Feb 2018 23:50:36 +0100 Subject: [vcpkg] Fix bug with missing dependencies introduced in #2697 (#2819) When a package dependency was not found (has no source control file), install would exit with "Value was null" when trying to install its default features, as the dependency would be marked erroneously as found in this case. Signed-off-by: Squareys --- toolsrc/src/vcpkg/dependencies.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/dependencies.cpp b/toolsrc/src/vcpkg/dependencies.cpp index 307c779c8..fedda56ab 100644 --- a/toolsrc/src/vcpkg/dependencies.cpp +++ b/toolsrc/src/vcpkg/dependencies.cpp @@ -454,14 +454,14 @@ namespace vcpkg::Dependencies return res; } } + } - // "core" is always an implicit default feature. In case we did not add it as - // a dependency above (e.g. no default features), add it here. - auto res = mark_plus("core", cluster, graph, graph_plan, prevent_default_features); - if (res != MarkPlusResult::SUCCESS) - { - return res; - } + // "core" is always an implicit default feature. In case we did not add it as + // a dependency above (e.g. no default features), add it here. + auto res = mark_plus("core", cluster, graph, graph_plan, prevent_default_features); + if (res != MarkPlusResult::SUCCESS) + { + return res; } return MarkPlusResult::SUCCESS; -- cgit v1.2.3 From 452c8ba1ff4c06e5cf7b2f2c4ff449eaefb83f79 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Fri, 16 Feb 2018 15:40:22 -0800 Subject: [vcpkg] Avoid using s::status_known() -- it does not do what you think it does --- toolsrc/include/vcpkg/base/files.h | 1 + toolsrc/src/vcpkg/install.cpp | 61 ++++++++++++++++++-------------------- 2 files changed, 30 insertions(+), 32 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/base/files.h b/toolsrc/include/vcpkg/base/files.h index 51a12ceba..9bdc0aa4b 100644 --- a/toolsrc/include/vcpkg/base/files.h +++ b/toolsrc/include/vcpkg/base/files.h @@ -14,6 +14,7 @@ namespace fs using stdfs::copy_options; using stdfs::file_status; + using stdfs::file_type; using stdfs::path; using stdfs::u8path; diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp index 595945d39..631b16c59 100644 --- a/toolsrc/src/vcpkg/install.cpp +++ b/toolsrc/src/vcpkg/install.cpp @@ -69,7 +69,7 @@ namespace vcpkg::Install continue; } - const std::string filename = file.filename().generic_string(); + const std::string filename = file.filename().u8string(); if (fs::is_regular_file(status) && (Strings::case_insensitive_ascii_equals(filename.c_str(), "CONTROL") || Strings::case_insensitive_ascii_equals(filename.c_str(), "BUILD_INFO"))) { @@ -80,44 +80,41 @@ namespace vcpkg::Install const std::string suffix = file.generic_u8string().substr(prefix_length + 1); const fs::path target = destination / suffix; - if (fs::is_directory(status)) + switch (status.type()) { - fs.create_directory(target, ec); - if (ec) + case fs::file_type::directory: { - System::println(System::Color::error, "failed: %s: %s", target.u8string(), ec.message()); - } - - // Trailing backslash for directories - output.push_back(Strings::format(R"(%s/%s/)", destination_subdirectory, suffix)); - continue; - } + fs.create_directory(target, ec); + if (ec) + { + System::println(System::Color::error, "failed: %s: %s", target.u8string(), ec.message()); + } - if (fs::is_regular_file(status)) - { - if (fs.exists(target)) - { - System::println(System::Color::warning, - "File %s was already present and will be overwritten", - target.u8string(), - ec.message()); + // Trailing backslash for directories + output.push_back(Strings::format(R"(%s/%s/)", destination_subdirectory, suffix)); + break; } - fs.copy_file(file, target, fs::copy_options::overwrite_existing, ec); - if (ec) + case fs::file_type::regular: { - System::println(System::Color::error, "failed: %s: %s", target.u8string(), ec.message()); + 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(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)", destination_subdirectory, suffix)); + break; } - output.push_back(Strings::format(R"(%s/%s)", destination_subdirectory, suffix)); - continue; - } - - if (!fs::status_known(status)) - { - System::println(System::Color::error, "failed: %s: unknown status", file.u8string()); - continue; + default: + System::println(System::Color::error, "failed: %s: cannot handle file type", file.u8string()); + break; } - - System::println(System::Color::error, "failed: %s: cannot handle file type", file.u8string()); } std::sort(output.begin(), output.end()); -- cgit v1.2.3 From 12f19c7a30e14a89c0bac9279bb8bcda64158496 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Mon, 19 Feb 2018 07:11:30 -0800 Subject: [vcpkg] Remove create_install_plan in favor of create_feature_install_plan --- toolsrc/include/vcpkg/dependencies.h | 4 ---- toolsrc/src/tests.plan.cpp | 38 +++++++++++++++++++----------------- toolsrc/src/vcpkg/commands.ci.cpp | 38 ++++++++++++++---------------------- toolsrc/src/vcpkg/dependencies.cpp | 27 ------------------------- 4 files changed, 35 insertions(+), 72 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/dependencies.h b/toolsrc/include/vcpkg/dependencies.h index 4abeb678e..de68d06e9 100644 --- a/toolsrc/include/vcpkg/dependencies.h +++ b/toolsrc/include/vcpkg/dependencies.h @@ -162,10 +162,6 @@ namespace vcpkg::Dependencies std::unique_ptr m_graph; }; - std::vector create_install_plan(const PortFileProvider& port_file_provider, - const std::vector& specs, - const StatusParagraphs& status_db); - std::vector create_remove_plan(const std::vector& specs, const StatusParagraphs& status_db); diff --git a/toolsrc/src/tests.plan.cpp b/toolsrc/src/tests.plan.cpp index a4c628bf6..546e20b0d 100644 --- a/toolsrc/src/tests.plan.cpp +++ b/toolsrc/src/tests.plan.cpp @@ -111,13 +111,13 @@ namespace UnitTest1 auto spec_c = spec_map.emplace("c"); Dependencies::MapPortFileProvider map_port(spec_map.map); - auto install_plan = - Dependencies::create_install_plan(map_port, {spec_a}, StatusParagraphs(std::move(status_paragraphs))); + auto install_plan = Dependencies::create_feature_install_plan( + map_port, {FeatureSpec{spec_a, ""}}, StatusParagraphs(std::move(status_paragraphs))); Assert::AreEqual(size_t(3), install_plan.size()); - Assert::AreEqual("c", install_plan[0].spec.name().c_str()); - Assert::AreEqual("b", install_plan[1].spec.name().c_str()); - Assert::AreEqual("a", install_plan[2].spec.name().c_str()); + Assert::AreEqual("c", install_plan[0].spec().name().c_str()); + Assert::AreEqual("b", install_plan[1].spec().name().c_str()); + Assert::AreEqual("a", install_plan[2].spec().name().c_str()); } TEST_METHOD(multiple_install_scheme) @@ -135,12 +135,14 @@ namespace UnitTest1 auto spec_h = spec_map.emplace("h"); Dependencies::MapPortFileProvider map_port(spec_map.map); - auto install_plan = Dependencies::create_install_plan( - map_port, {spec_a, spec_b, spec_c}, StatusParagraphs(std::move(status_paragraphs))); + auto install_plan = Dependencies::create_feature_install_plan( + map_port, + {FeatureSpec{spec_a, ""}, FeatureSpec{spec_b, ""}, FeatureSpec{spec_c, ""}}, + StatusParagraphs(std::move(status_paragraphs))); auto iterator_pos = [&](const PackageSpec& spec) -> int { auto it = std::find_if( - install_plan.begin(), install_plan.end(), [&](auto& action) { return action.spec == spec; }); + install_plan.begin(), install_plan.end(), [&](auto& action) { return action.spec() == spec; }); Assert::IsTrue(it != install_plan.end()); return (int)(it - install_plan.begin()); }; @@ -228,18 +230,18 @@ namespace UnitTest1 auto spec_k = spec_map.emplace("k"); Dependencies::MapPortFileProvider map_port(spec_map.map); - auto install_plan = - Dependencies::create_install_plan(map_port, {spec_a}, StatusParagraphs(std::move(status_paragraphs))); + auto install_plan = Dependencies::create_feature_install_plan( + map_port, {FeatureSpec{spec_a, ""}}, StatusParagraphs(std::move(status_paragraphs))); Assert::AreEqual(size_t(8), install_plan.size()); - Assert::AreEqual("h", install_plan[0].spec.name().c_str()); - Assert::AreEqual("g", install_plan[1].spec.name().c_str()); - Assert::AreEqual("f", install_plan[2].spec.name().c_str()); - Assert::AreEqual("e", install_plan[3].spec.name().c_str()); - Assert::AreEqual("d", install_plan[4].spec.name().c_str()); - Assert::AreEqual("c", install_plan[5].spec.name().c_str()); - Assert::AreEqual("b", install_plan[6].spec.name().c_str()); - Assert::AreEqual("a", install_plan[7].spec.name().c_str()); + Assert::AreEqual("h", install_plan[0].spec().name().c_str()); + Assert::AreEqual("g", install_plan[1].spec().name().c_str()); + Assert::AreEqual("f", install_plan[2].spec().name().c_str()); + Assert::AreEqual("e", install_plan[3].spec().name().c_str()); + Assert::AreEqual("d", install_plan[4].spec().name().c_str()); + Assert::AreEqual("c", install_plan[5].spec().name().c_str()); + Assert::AreEqual("b", install_plan[6].spec().name().c_str()); + Assert::AreEqual("a", install_plan[7].spec().name().c_str()); } TEST_METHOD(basic_feature_test_1) diff --git a/toolsrc/src/vcpkg/commands.ci.cpp b/toolsrc/src/vcpkg/commands.ci.cpp index 4636a5738..7672755ba 100644 --- a/toolsrc/src/vcpkg/commands.ci.cpp +++ b/toolsrc/src/vcpkg/commands.ci.cpp @@ -20,27 +20,15 @@ namespace vcpkg::Commands::CI static Install::InstallSummary run_ci_on_triplet(const Triplet& triplet, const VcpkgPaths& paths, - const std::vector& ports, - const std::set& exclusions_set) + const std::vector& ports) { Input::check_triplet(triplet, paths); - - const std::vector specs = PackageSpec::to_package_specs(ports, triplet); + std::vector specs = PackageSpec::to_package_specs(ports, triplet); + auto featurespecs = Util::fmap(specs, [](auto& spec) { return FeatureSpec(spec, ""); }); StatusParagraphs status_db = database_load_check(paths); const auto& paths_port_file = Dependencies::PathsPortFileProvider(paths); - std::vector install_plan = - Dependencies::create_install_plan(paths_port_file, specs, status_db); - - for (InstallPlanAction& plan : install_plan) - { - if (Util::Sets::contains(exclusions_set, plan.spec.name())) - { - plan.plan_type = InstallPlanType::EXCLUDED; - } - } - - Checks::check_exit(VCPKG_LINE_INFO, !install_plan.empty(), "Install plan cannot be empty"); + auto action_plan = Dependencies::create_feature_install_plan(paths_port_file, featurespecs, status_db); const Build::BuildPackageOptions install_plan_options = { Build::UseHeadVersion::NO, @@ -48,11 +36,13 @@ namespace vcpkg::Commands::CI Build::CleanBuildtrees::YES, }; - const std::vector action_plan = - Util::fmap(install_plan, [&install_plan_options](InstallPlanAction& install_action) { - install_action.build_options = install_plan_options; - return Dependencies::AnyAction(std::move(install_action)); - }); + for (auto&& action : action_plan) + { + if (auto p = action.install_action.get()) + { + p->build_options = install_plan_options; + } + } return Install::perform(action_plan, Install::KeepGoing::YES, paths, status_db); } @@ -102,11 +92,13 @@ namespace vcpkg::Commands::CI triplets.push_back(default_triplet); } - const std::vector ports = Install::get_all_port_names(paths); + std::vector ports = Install::get_all_port_names(paths); + Util::erase_remove_if(ports, [&](auto&& port) { return Util::Sets::contains(exclusions_set, port); }); + std::vector results; for (const Triplet& triplet : triplets) { - Install::InstallSummary summary = run_ci_on_triplet(triplet, paths, ports, exclusions_set); + Install::InstallSummary summary = run_ci_on_triplet(triplet, paths, ports); results.push_back({triplet, std::move(summary)}); } diff --git a/toolsrc/src/vcpkg/dependencies.cpp b/toolsrc/src/vcpkg/dependencies.cpp index fedda56ab..793951ab5 100644 --- a/toolsrc/src/vcpkg/dependencies.cpp +++ b/toolsrc/src/vcpkg/dependencies.cpp @@ -280,33 +280,6 @@ namespace vcpkg::Dependencies return nullopt; } - std::vector create_install_plan(const PortFileProvider& port_file_provider, - const std::vector& specs, - const StatusParagraphs& status_db) - { - auto fspecs = Util::fmap(specs, [](const PackageSpec& spec) { return FeatureSpec(spec, ""); }); - auto plan = create_feature_install_plan(port_file_provider, fspecs, status_db); - - std::vector ret; - ret.reserve(plan.size()); - - for (auto&& action : plan) - { - if (auto p_install = action.install_action.get()) - { - ret.push_back(std::move(*p_install)); - } - else - { - Checks::exit_with_message(VCPKG_LINE_INFO, - "The installation plan requires feature packages support. Please re-run the " - "command with --featurepackages."); - } - } - - return ret; - } - std::vector create_remove_plan(const std::vector& specs, const StatusParagraphs& status_db) { -- cgit v1.2.3 From 99092990398ab80484cced0927e55bedfda05077 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 20 Feb 2018 16:56:51 -0800 Subject: Expected::check_exit() now always shows line_info if it fails --- toolsrc/include/vcpkg/base/expected.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/base/expected.h b/toolsrc/include/vcpkg/base/expected.h index b3b81ae81..1f3d94638 100644 --- a/toolsrc/include/vcpkg/base/expected.h +++ b/toolsrc/include/vcpkg/base/expected.h @@ -103,7 +103,12 @@ namespace vcpkg private: void exit_if_error(const LineInfo& line_info) const { - Checks::check_exit(line_info, !m_s.has_error(), m_s.to_string()); + // This is used for quick value_or_exit() calls, so always put line_info in the error message. + Checks::check_exit(line_info, + !m_s.has_error(), + "Failed at [%s] with message:\n%s", + line_info.to_string(), + m_s.to_string()); } ErrorHolder m_s; -- cgit v1.2.3 From adb0930bc54dbff26acf131971199c3f57bdd0fb Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Tue, 20 Feb 2018 18:02:00 -0800 Subject: [vcpkg-metrics] Adjust reporting of build times --- toolsrc/include/vcpkg/metrics.h | 1 + toolsrc/src/vcpkg/build.cpp | 3 ++- toolsrc/src/vcpkg/metrics.cpp | 25 ++++++++++++++++++++++++- 3 files changed, 27 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/metrics.h b/toolsrc/include/vcpkg/metrics.h index ee6f8eb51..cb27ba58d 100644 --- a/toolsrc/include/vcpkg/metrics.h +++ b/toolsrc/include/vcpkg/metrics.h @@ -14,6 +14,7 @@ namespace vcpkg::Metrics static void init_user_information(std::string& user_id, std::string& first_use_time); void track_metric(const std::string& name, double value); + void track_buildtime(const std::string& name, double value); void track_property(const std::string& name, const std::string& value); void upload(const std::string& payload); diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index cc376c773..7d249bd0c 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -339,7 +339,8 @@ namespace vcpkg::Build { auto locked_metrics = Metrics::g_metrics.lock(); - locked_metrics->track_metric("buildtimeus-" + spec_string, buildtimeus); + locked_metrics->track_buildtime(spec.to_string() + ":[" + Strings::join(",", config.feature_list) + "]", + buildtimeus); if (return_code != 0) { locked_metrics->track_property("error", "build failed"); diff --git a/toolsrc/src/vcpkg/metrics.cpp b/toolsrc/src/vcpkg/metrics.cpp index cdb21d260..1f9ddde38 100644 --- a/toolsrc/src/vcpkg/metrics.cpp +++ b/toolsrc/src/vcpkg/metrics.cpp @@ -150,6 +150,9 @@ namespace vcpkg::Metrics std::string properties; std::string measurements; + std::vector buildtime_names; + std::vector buildtime_times; + void track_property(const std::string& name, const std::string& value) { if (properties.size() != 0) properties.push_back(','); @@ -166,8 +169,23 @@ namespace vcpkg::Metrics measurements.append(std::to_string(value)); } + void track_buildtime(const std::string& name, double value) + { + buildtime_names.push_back(name); + buildtime_times.push_back(std::to_string(value)); + } + std::string format_event_data_template() const { + auto props_plus_buildtimes = properties; + if (buildtime_names.size() > 0) + { + if (props_plus_buildtimes.size() > 0) props_plus_buildtimes.push_back(','); + props_plus_buildtimes.append(Strings::format(R"("buildnames": [%s], "buildtimes": [%s])", + Strings::join(",", buildtime_names, to_json_string), + Strings::join(",", buildtime_times))); + } + const std::string& session_id = get_session_id(); return Strings::format(R"([{ "ver": 1, @@ -199,7 +217,7 @@ namespace vcpkg::Metrics session_id, user_id, user_timestamp, - properties, + props_plus_buildtimes, measurements); } }; @@ -274,6 +292,11 @@ namespace vcpkg::Metrics void Metrics::track_metric(const std::string& name, double value) { g_metricmessage.track_metric(name, value); } + void Metrics::track_buildtime(const std::string& name, double value) + { + g_metricmessage.track_buildtime(name, value); + } + void Metrics::track_property(const std::string& name, const std::string& value) { g_metricmessage.track_property(name, value); -- cgit v1.2.3 From 8a4afe16193f274eb4d60357d81b8827ed055fb8 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 20 Feb 2018 17:58:21 -0800 Subject: Update git to 2.16.2 --- toolsrc/src/vcpkg/vcpkgpaths.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index 06e0c01ab..d574b7c4d 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -167,7 +167,7 @@ namespace vcpkg fs::path get_git_path(const fs::path& downloads_folder, const fs::path& scripts_folder) { #if defined(_WIN32) - static constexpr std::array EXPECTED_VERSION = {2, 15, 0}; + static constexpr std::array EXPECTED_VERSION = {2, 16, 2}; #else static constexpr std::array EXPECTED_VERSION = {2, 7, 4}; #endif @@ -175,7 +175,7 @@ namespace vcpkg const std::vector from_path = Files::find_from_PATH("git"); - const fs::path downloaded_copy = downloads_folder / "MinGit-2.15.0-32-bit" / "cmd" / "git.exe"; + const fs::path downloaded_copy = downloads_folder / "MinGit-2.16.2-32-bit" / "cmd" / "git.exe"; std::vector candidate_paths; #if defined(_WIN32) candidate_paths.push_back(downloaded_copy); -- cgit v1.2.3 From 210e6b0114ffe620ef3e41cc41158a26e0df692d Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 20 Feb 2018 18:21:21 -0800 Subject: Update CHANGELOG and bump version to v0.0.105 --- toolsrc/VERSION.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/VERSION.txt b/toolsrc/VERSION.txt index f4950aa0b..157d21b7b 100644 --- a/toolsrc/VERSION.txt +++ b/toolsrc/VERSION.txt @@ -1 +1 @@ -"0.0.104" \ No newline at end of file +"0.0.105" \ No newline at end of file -- cgit v1.2.3 From 494f3002bfdf80c363ae51ca426cabc231c73339 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 21 Feb 2018 15:32:20 -0800 Subject: Add internal option to clean packages\ after the build --- toolsrc/include/vcpkg/build.h | 7 +++++++ toolsrc/src/vcpkg/build.cpp | 18 +++++++++++++++--- toolsrc/src/vcpkg/commands.ci.cpp | 11 +++++------ toolsrc/src/vcpkg/commands.upgrade.cpp | 9 ++++----- toolsrc/src/vcpkg/install.cpp | 2 +- 5 files changed, 32 insertions(+), 15 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/build.h b/toolsrc/include/vcpkg/build.h index d7c5c8344..7ef7d6516 100644 --- a/toolsrc/include/vcpkg/build.h +++ b/toolsrc/include/vcpkg/build.h @@ -44,6 +44,12 @@ namespace vcpkg::Build YES }; + enum class CleanPackages + { + NO = 0, + YES + }; + enum class ConfigurationType { DEBUG, @@ -55,6 +61,7 @@ namespace vcpkg::Build UseHeadVersion use_head_version; AllowDownloads allow_downloads; CleanBuildtrees clean_buildtrees; + CleanPackages clean_packages; }; enum class BuildResult diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index 7d249bd0c..f6c995f2a 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -61,8 +61,10 @@ namespace vcpkg::Build::Command spec.name()); const StatusParagraphs status_db = database_load_check(paths); - const Build::BuildPackageOptions build_package_options{ - Build::UseHeadVersion::NO, Build::AllowDownloads::YES, Build::CleanBuildtrees::NO}; + const Build::BuildPackageOptions build_package_options{Build::UseHeadVersion::NO, + Build::AllowDownloads::YES, + Build::CleanBuildtrees::NO, + Build::CleanPackages::NO}; const std::unordered_set features_as_set(full_spec.features.begin(), full_spec.features.end()); @@ -385,7 +387,7 @@ namespace vcpkg::Build if (config.build_package_options.clean_buildtrees == CleanBuildtrees::YES) { auto& fs = paths.get_filesystem(); - auto buildtrees_dir = paths.buildtrees / config.scf.core_paragraph->name; + const fs::path buildtrees_dir = paths.buildtrees / config.scf.core_paragraph->name; auto buildtree_files = fs.get_files_non_recursive(buildtrees_dir); for (auto&& file : buildtree_files) { @@ -397,6 +399,16 @@ namespace vcpkg::Build } } + if (config.build_package_options.clean_packages == CleanPackages::YES) + { + auto& fs = paths.get_filesystem(); + const PackageSpec spec = PackageSpec::from_name_and_triplet(config.scf.core_paragraph->name, config.triplet) + .value_or_exit(VCPKG_LINE_INFO); + const fs::path package_dir = paths.package_dir(spec); + std::error_code ec; + fs.remove_all(package_dir, ec); + } + return result; } diff --git a/toolsrc/src/vcpkg/commands.ci.cpp b/toolsrc/src/vcpkg/commands.ci.cpp index 7672755ba..313582b7b 100644 --- a/toolsrc/src/vcpkg/commands.ci.cpp +++ b/toolsrc/src/vcpkg/commands.ci.cpp @@ -24,17 +24,16 @@ namespace vcpkg::Commands::CI { Input::check_triplet(triplet, paths); std::vector specs = PackageSpec::to_package_specs(ports, triplet); - auto featurespecs = Util::fmap(specs, [](auto& spec) { return FeatureSpec(spec, ""); }); + const auto featurespecs = Util::fmap(specs, [](auto& spec) { return FeatureSpec(spec, ""); }); StatusParagraphs status_db = database_load_check(paths); const auto& paths_port_file = Dependencies::PathsPortFileProvider(paths); auto action_plan = Dependencies::create_feature_install_plan(paths_port_file, featurespecs, status_db); - const Build::BuildPackageOptions install_plan_options = { - Build::UseHeadVersion::NO, - Build::AllowDownloads::YES, - Build::CleanBuildtrees::YES, - }; + const Build::BuildPackageOptions install_plan_options = {Build::UseHeadVersion::NO, + Build::AllowDownloads::YES, + Build::CleanBuildtrees::YES, + Build::CleanPackages::YES}; for (auto&& action : action_plan) { diff --git a/toolsrc/src/vcpkg/commands.upgrade.cpp b/toolsrc/src/vcpkg/commands.upgrade.cpp index bb26dc735..c5b48f2a2 100644 --- a/toolsrc/src/vcpkg/commands.upgrade.cpp +++ b/toolsrc/src/vcpkg/commands.upgrade.cpp @@ -141,11 +141,10 @@ namespace vcpkg::Commands::Upgrade Checks::check_exit(VCPKG_LINE_INFO, !plan.empty()); - const Build::BuildPackageOptions install_plan_options = { - Build::UseHeadVersion::NO, - Build::AllowDownloads::YES, - Build::CleanBuildtrees::NO, - }; + const Build::BuildPackageOptions install_plan_options = {Build::UseHeadVersion::NO, + Build::AllowDownloads::YES, + Build::CleanBuildtrees::NO, + Build::CleanPackages::NO}; // Set build settings for all install actions for (auto&& action : plan) diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp index 631b16c59..d032f77d8 100644 --- a/toolsrc/src/vcpkg/install.cpp +++ b/toolsrc/src/vcpkg/install.cpp @@ -547,7 +547,7 @@ namespace vcpkg::Install Util::Enum::to_enum(use_head_version), Util::Enum::to_enum(!no_downloads), Build::CleanBuildtrees::NO, - }; + Build::CleanPackages::NO}; // Note: action_plan will hold raw pointers to SourceControlFiles from this map std::vector action_plan; -- cgit v1.2.3 From 35e19d5926f593b135878ee64abf06cf27dd91d9 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 21 Feb 2018 16:58:05 -0800 Subject: Improve error message when we have an error code --- toolsrc/include/vcpkg/base/expected.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/base/expected.h b/toolsrc/include/vcpkg/base/expected.h index 1f3d94638..e20f723db 100644 --- a/toolsrc/include/vcpkg/base/expected.h +++ b/toolsrc/include/vcpkg/base/expected.h @@ -38,7 +38,7 @@ namespace vcpkg const std::error_code& error() const { return m_err; } std::error_code& error() { return m_err; } - CStringView to_string() const { return "value was error"; } + CStringView to_string() const { return m_err.message(); } private: std::error_code m_err; -- cgit v1.2.3 From e02c9e535493842a26b4426ce602c60f90ace671 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 21 Feb 2018 19:57:14 -0800 Subject: [CI] Fix too early deletion of files --- toolsrc/src/vcpkg/build.cpp | 10 ---------- toolsrc/src/vcpkg/install.cpp | 9 +++++++++ 2 files changed, 9 insertions(+), 10 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index f6c995f2a..c169a778e 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -399,16 +399,6 @@ namespace vcpkg::Build } } - if (config.build_package_options.clean_packages == CleanPackages::YES) - { - auto& fs = paths.get_filesystem(); - const PackageSpec spec = PackageSpec::from_name_and_triplet(config.scf.core_paragraph->name, config.triplet) - .value_or_exit(VCPKG_LINE_INFO); - const fs::path package_dir = paths.package_dir(spec); - std::error_code ec; - fs.remove_all(package_dir, ec); - } - return result; } diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp index d032f77d8..46c7c53b8 100644 --- a/toolsrc/src/vcpkg/install.cpp +++ b/toolsrc/src/vcpkg/install.cpp @@ -308,6 +308,15 @@ namespace vcpkg::Install auto bcf = std::make_unique( Paragraphs::try_load_cached_control_package(paths, action.spec).value_or_exit(VCPKG_LINE_INFO)); auto code = aux_install(display_name_with_features, *bcf); + + if (action.build_options.clean_packages == Build::CleanPackages::YES) + { + auto& fs = paths.get_filesystem(); + const fs::path package_dir = paths.package_dir(action.spec); + std::error_code ec; + fs.remove_all(package_dir, ec); + } + return {code, std::move(bcf)}; } -- cgit v1.2.3 From 65e241cf8b47a07b85efae85bac14e723864dccb Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Wed, 21 Feb 2018 22:18:15 -0800 Subject: [vcpkg] Add non-throwing implementation of write_contents() --- toolsrc/include/vcpkg/base/files.h | 10 +++++++++- toolsrc/src/vcpkg/base/checks.cpp | 4 ++++ toolsrc/src/vcpkg/base/files.cpp | 21 +++++++++++++++------ toolsrc/src/vcpkg/metrics.cpp | 5 +++-- toolsrc/src/vcpkg/userconfig.cpp | 3 ++- 5 files changed, 33 insertions(+), 10 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/base/files.h b/toolsrc/include/vcpkg/base/files.h index 9bdc0aa4b..a2bf9c33c 100644 --- a/toolsrc/include/vcpkg/base/files.h +++ b/toolsrc/include/vcpkg/base/files.h @@ -34,7 +34,7 @@ namespace vcpkg::Files virtual std::vector get_files_non_recursive(const fs::path& dir) const = 0; virtual void write_lines(const fs::path& file_path, const std::vector& lines) = 0; - virtual void write_contents(const fs::path& file_path, const std::string& data) = 0; + virtual void write_contents(const fs::path& file_path, const std::string& data, std::error_code& ec) = 0; virtual void rename(const fs::path& oldpath, const fs::path& newpath) = 0; virtual bool remove(const fs::path& path) = 0; virtual bool remove(const fs::path& path, std::error_code& ec) = 0; @@ -51,6 +51,14 @@ namespace vcpkg::Files fs::copy_options opts, std::error_code& ec) = 0; virtual fs::file_status status(const fs::path& path, std::error_code& ec) const = 0; + + inline void write_contents(const fs::path& file_path, const std::string& data) + { + std::error_code ec; + write_contents(file_path, data, ec); + Checks::check_exit( + VCPKG_LINE_INFO, ec, "error while writing file: %s: %s", file_path.u8string(), ec.message()); + } }; Filesystem& get_real_filesystem(); diff --git a/toolsrc/src/vcpkg/base/checks.cpp b/toolsrc/src/vcpkg/base/checks.cpp index 23f2cc630..2977a1d8b 100644 --- a/toolsrc/src/vcpkg/base/checks.cpp +++ b/toolsrc/src/vcpkg/base/checks.cpp @@ -10,6 +10,10 @@ namespace vcpkg::Checks { [[noreturn]] static void cleanup_and_exit(const int exit_code) { + static std::atomic have_entered = false; + if (have_entered) std::terminate(); + have_entered = true; + const auto elapsed_us = GlobalState::timer.lock()->microseconds(); auto metrics = Metrics::g_metrics.lock(); diff --git a/toolsrc/src/vcpkg/base/files.cpp b/toolsrc/src/vcpkg/base/files.cpp index 060a14da3..95ae0fd33 100644 --- a/toolsrc/src/vcpkg/base/files.cpp +++ b/toolsrc/src/vcpkg/base/files.cpp @@ -164,21 +164,30 @@ namespace vcpkg::Files { return fs::stdfs::status(path, ec); } - virtual void write_contents(const fs::path& file_path, const std::string& data) override + virtual void write_contents(const fs::path& file_path, const std::string& data, std::error_code& ec) override { + ec = std::error_code(); + FILE* f = nullptr; #if defined(_WIN32) - auto ec = _wfopen_s(&f, file_path.native().c_str(), L"wb"); + auto err = _wfopen_s(&f, file_path.native().c_str(), L"wb"); #else f = fopen(file_path.native().c_str(), "wb"); - int ec = f != nullptr ? 0 : 1; + int err = f != nullptr ? 0 : 1; #endif - Checks::check_exit( - VCPKG_LINE_INFO, ec == 0, "Error: Could not open file for writing: %s", file_path.u8string().c_str()); + if (err != 0) + { + ec.assign(err, std::system_category()); + return; + } + auto count = fwrite(data.data(), sizeof(data[0]), data.size(), f); fclose(f); - Checks::check_exit(VCPKG_LINE_INFO, count == data.size()); + if (count != data.size()) + { + ec = std::make_error_code(std::errc::no_space_on_device); + } } }; diff --git a/toolsrc/src/vcpkg/metrics.cpp b/toolsrc/src/vcpkg/metrics.cpp index 1f9ddde38..1a322e99c 100644 --- a/toolsrc/src/vcpkg/metrics.cpp +++ b/toolsrc/src/vcpkg/metrics.cpp @@ -427,8 +427,9 @@ namespace vcpkg::Metrics } const fs::path vcpkg_metrics_txt_path = temp_folder_path / ("vcpkg" + generate_random_UUID() + ".txt"); - fs.write_contents(vcpkg_metrics_txt_path, payload); - + std::error_code ec; + fs.write_contents(vcpkg_metrics_txt_path, payload, ec); + if (ec) return; const std::string cmd_line = Strings::format("start \"vcpkgmetricsuploader.exe\" \"%s\" \"%s\"", temp_folder_path_exe.u8string(), vcpkg_metrics_txt_path.u8string()); diff --git a/toolsrc/src/vcpkg/userconfig.cpp b/toolsrc/src/vcpkg/userconfig.cpp index 906594691..c7c57ce26 100644 --- a/toolsrc/src/vcpkg/userconfig.cpp +++ b/toolsrc/src/vcpkg/userconfig.cpp @@ -78,7 +78,8 @@ namespace vcpkg user_id, user_time, user_mac, - last_completed_survey)); + last_completed_survey), + ec); } catch (...) { -- cgit v1.2.3 From 222fa360120b9b66fcd305a247e57e1ddf669229 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Wed, 21 Feb 2018 22:21:19 -0800 Subject: [vcpkg] Fixup previous commit --- toolsrc/include/vcpkg/base/files.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/base/files.h b/toolsrc/include/vcpkg/base/files.h index a2bf9c33c..09393b9ee 100644 --- a/toolsrc/include/vcpkg/base/files.h +++ b/toolsrc/include/vcpkg/base/files.h @@ -57,7 +57,7 @@ namespace vcpkg::Files std::error_code ec; write_contents(file_path, data, ec); Checks::check_exit( - VCPKG_LINE_INFO, ec, "error while writing file: %s: %s", file_path.u8string(), ec.message()); + VCPKG_LINE_INFO, !ec, "error while writing file: %s: %s", file_path.u8string(), ec.message()); } }; -- cgit v1.2.3 From 0ef0300b8eefcdfe119e0bbaa3ce7b0f8c30ee4c Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Mon, 19 Feb 2018 12:20:16 -0800 Subject: [vcpkg] Enable metrics on linux --- toolsrc/CMakeLists.txt | 13 +++--- toolsrc/include/vcpkg/base/strings.h | 2 + toolsrc/src/vcpkg.cpp | 6 ++- toolsrc/src/vcpkg/base/checks.cpp | 2 +- toolsrc/src/vcpkg/base/files.cpp | 2 +- toolsrc/src/vcpkg/base/strings.cpp | 10 +++++ toolsrc/src/vcpkg/commands.contact.cpp | 9 ++-- toolsrc/src/vcpkg/commands.version.cpp | 4 ++ toolsrc/src/vcpkg/metrics.cpp | 75 ++++++++++++++++++++++------------ toolsrc/src/vcpkg/userconfig.cpp | 22 ++++++---- 10 files changed, 97 insertions(+), 48 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/CMakeLists.txt b/toolsrc/CMakeLists.txt index 0168e2de2..aa2146111 100644 --- a/toolsrc/CMakeLists.txt +++ b/toolsrc/CMakeLists.txt @@ -13,15 +13,12 @@ endif() file(GLOB_RECURSE VCPKGLIB_SOURCES src/vcpkg/*.cpp) -add_library(vcpkglib STATIC ${VCPKGLIB_SOURCES}) -target_compile_definitions(vcpkglib PRIVATE -DDISABLE_METRICS=0) -target_include_directories(vcpkglib PUBLIC include) +add_executable(vcpkg src/vcpkg.cpp ${VCPKGLIB_SOURCES}) +target_compile_definitions(vcpkg PRIVATE -DDISABLE_METRICS=0) +target_include_directories(vcpkg PUBLIC include) if(GCC) - target_link_libraries(vcpkglib PUBLIC stdc++fs) + target_link_libraries(vcpkg PUBLIC stdc++fs) elseif(CLANG) - target_link_libraries(vcpkglib PUBLIC c++experimental) + target_link_libraries(vcpkg PUBLIC c++experimental) endif() - -add_executable(vcpkg src/vcpkg.cpp) -target_link_libraries(vcpkg PRIVATE vcpkglib) diff --git a/toolsrc/include/vcpkg/base/strings.h b/toolsrc/include/vcpkg/base/strings.h index ee1b2fc28..6ef840fb3 100644 --- a/toolsrc/include/vcpkg/base/strings.h +++ b/toolsrc/include/vcpkg/base/strings.h @@ -38,6 +38,8 @@ namespace vcpkg::Strings std::string to_utf8(const CWStringView& w); + std::string escape_string(const CStringView& s, char char_to_escape, char escape_char); + std::string::const_iterator case_insensitive_ascii_find(const std::string& s, const std::string& pattern); bool case_insensitive_ascii_contains(const std::string& s, const std::string& pattern); diff --git a/toolsrc/src/vcpkg.cpp b/toolsrc/src/vcpkg.cpp index 9f29dcdd2..adb32c723 100644 --- a/toolsrc/src/vcpkg.cpp +++ b/toolsrc/src/vcpkg.cpp @@ -171,7 +171,6 @@ static void inner(const VcpkgCmdArguments& args) static void load_config() { -#if defined(_WIN32) auto& fs = Files::get_real_filesystem(); auto config = UserConfig::try_read_data(fs); @@ -185,16 +184,20 @@ static void load_config() write_config = true; } +#if defined(_WIN32) if (config.user_mac.empty()) { config.user_mac = Metrics::get_MAC_user(); write_config = true; } +#endif { auto locked_metrics = Metrics::g_metrics.lock(); locked_metrics->set_user_information(config.user_id, config.user_time); +#if defined(_WIN32) locked_metrics->track_property("user_mac", config.user_mac); +#endif } if (config.last_completed_survey.empty()) @@ -208,7 +211,6 @@ static void load_config() { config.try_write_data(fs); } -#endif } static std::string trim_path_from_command_line(const std::string& full_command_line) diff --git a/toolsrc/src/vcpkg/base/checks.cpp b/toolsrc/src/vcpkg/base/checks.cpp index 2977a1d8b..1b3ed5ec9 100644 --- a/toolsrc/src/vcpkg/base/checks.cpp +++ b/toolsrc/src/vcpkg/base/checks.cpp @@ -31,7 +31,7 @@ namespace vcpkg::Checks #if defined(_WIN32) ::TerminateProcess(::GetCurrentProcess(), exit_code); #else - ::exit(exit_code); + std::exit(exit_code); #endif } diff --git a/toolsrc/src/vcpkg/base/files.cpp b/toolsrc/src/vcpkg/base/files.cpp index 95ae0fd33..b59104a59 100644 --- a/toolsrc/src/vcpkg/base/files.cpp +++ b/toolsrc/src/vcpkg/base/files.cpp @@ -166,7 +166,7 @@ namespace vcpkg::Files } virtual void write_contents(const fs::path& file_path, const std::string& data, std::error_code& ec) override { - ec = std::error_code(); + ec.clear(); FILE* f = nullptr; #if defined(_WIN32) diff --git a/toolsrc/src/vcpkg/base/strings.cpp b/toolsrc/src/vcpkg/base/strings.cpp index 27cfcbe71..d912734e3 100644 --- a/toolsrc/src/vcpkg/base/strings.cpp +++ b/toolsrc/src/vcpkg/base/strings.cpp @@ -74,6 +74,16 @@ namespace vcpkg::Strings #endif } + std::string escape_string(const CStringView& s, char char_to_escape, char escape_char) + { + std::string ret = s.c_str(); + // Replace '\' with '\\' or '`' with '``' + ret = Strings::replace_all(std::move(ret), {escape_char}, {escape_char, escape_char}); + // Replace '"' with '\"' or '`"' + ret = Strings::replace_all(std::move(ret), {char_to_escape}, {escape_char, char_to_escape}); + return ret; + } + std::string::const_iterator case_insensitive_ascii_find(const std::string& s, const std::string& pattern) { const std::string pattern_as_lower_case(ascii_to_lowercase(pattern)); diff --git a/toolsrc/src/vcpkg/commands.contact.cpp b/toolsrc/src/vcpkg/commands.contact.cpp index 8063fe317..ffed07557 100644 --- a/toolsrc/src/vcpkg/commands.contact.cpp +++ b/toolsrc/src/vcpkg/commands.contact.cpp @@ -30,7 +30,6 @@ namespace vcpkg::Commands::Contact if (Util::Sets::contains(parsed_args.switches, switches[0].name)) { -#if defined(_WIN32) auto maybe_now = Chrono::CTime::get_current_date_time(); if (auto p_now = maybe_now.get()) { @@ -39,10 +38,14 @@ namespace vcpkg::Commands::Contact config.last_completed_survey = p_now->to_string(); config.try_write_data(fs); } -#endif +#if defined(_WIN32) System::cmd_execute("start https://aka.ms/NPS_vcpkg"); - System::println("Default browser launched to https://aka.ms/NPS_vcpkg, thank you for your feedback!"); + System::println("Default browser launched to https://aka.ms/NPS_vcpkg; thank you for your feedback!"); +#else + System::println( + "Please navigate to https://aka.ms/NPS_vcpkg in your preferred browser. Thank you for your feedback!"); +#endif } else { diff --git a/toolsrc/src/vcpkg/commands.version.cpp b/toolsrc/src/vcpkg/commands.version.cpp index c21e8cafd..ffc5d2c8f 100644 --- a/toolsrc/src/vcpkg/commands.version.cpp +++ b/toolsrc/src/vcpkg/commands.version.cpp @@ -8,7 +8,11 @@ #define STRINGIFY(...) #__VA_ARGS__ #define MACRO_TO_STRING(X) STRINGIFY(X) +#if defined(VCPKG_VERSION) #define VCPKG_VERSION_AS_STRING MACRO_TO_STRING(VCPKG_VERSION) +#else +#define VCPKG_VERSION_AS_STRING "-unknownhash" +#endif namespace vcpkg::Commands::Version { diff --git a/toolsrc/src/vcpkg/metrics.cpp b/toolsrc/src/vcpkg/metrics.cpp index 1a322e99c..f81c53583 100644 --- a/toolsrc/src/vcpkg/metrics.cpp +++ b/toolsrc/src/vcpkg/metrics.cpp @@ -196,8 +196,8 @@ namespace vcpkg::Metrics "iKey": "b4e88960-4393-4dd9-ab8e-97e8fe6d7603", "flags": 0.000000, "tags": { - "ai.device.os": "Windows", - "ai.device.osVersion": "%s", + "ai.device.os": "Other", + "ai.device.osVersion": "%s-%s", "ai.session.id": "%s", "ai.user.id": "%s", "ai.user.accountAcquisitionDate": "%s" @@ -213,6 +213,17 @@ namespace vcpkg::Metrics } }])", timestamp, +#if defined(_WIN32) + "Windows", +#elif defined(__APPLE__) + "OSX", +#elif defined(__linux__) + "Linux", +#elif defined(__unix__) + "Unix", +#elif defined(__unix__) + "Other", +#endif get_os_version_string(), session_id, user_id, @@ -390,50 +401,62 @@ namespace vcpkg::Metrics void Metrics::flush() { -#if defined(_WIN32) const std::string payload = g_metricmessage.format_event_data_template(); if (g_should_print_metrics) std::cerr << payload << "\n"; if (!g_should_send_metrics) return; - // upload(payload); - +#if defined(_WIN32) wchar_t temp_folder[MAX_PATH]; GetTempPathW(MAX_PATH, temp_folder); const fs::path temp_folder_path = fs::path(temp_folder) / "vcpkg"; const fs::path temp_folder_path_exe = temp_folder_path / Strings::format("vcpkgmetricsuploader-%s.exe", Commands::Version::base_version()); +#endif auto& fs = Files::get_real_filesystem(); - if (true) - { - const fs::path exe_path = [&fs]() -> fs::path { - auto vcpkgdir = System::get_exe_path_of_current_process().parent_path(); - auto path = vcpkgdir / "vcpkgmetricsuploader.exe"; - if (fs.exists(path)) return path; - - path = vcpkgdir / "scripts" / "vcpkgmetricsuploader.exe"; - if (fs.exists(path)) return path; - - return ""; - }(); - - std::error_code ec; - fs.create_directories(temp_folder_path, ec); - if (ec) return; - fs.copy_file(exe_path, temp_folder_path_exe, fs::copy_options::skip_existing, ec); - if (ec) return; - } +#if defined(_WIN32) - const fs::path vcpkg_metrics_txt_path = temp_folder_path / ("vcpkg" + generate_random_UUID() + ".txt"); + const fs::path exe_path = [&fs]() -> fs::path { + auto vcpkgdir = System::get_exe_path_of_current_process().parent_path(); + auto path = vcpkgdir / "vcpkgmetricsuploader.exe"; + if (fs.exists(path)) return path; + + path = vcpkgdir / "scripts" / "vcpkgmetricsuploader.exe"; + if (fs.exists(path)) return path; + + return ""; + }(); + + std::error_code ec; + fs.create_directories(temp_folder_path, ec); + if (ec) return; + fs.copy_file(exe_path, temp_folder_path_exe, fs::copy_options::skip_existing, ec); + if (ec) return; +#else + if (!fs.exists("/tmp")) return; + const fs::path temp_folder_path = "/tmp/vcpkg"; std::error_code ec; + fs.create_directory(temp_folder_path, ec); + // ignore error + ec.clear(); +#endif + const fs::path vcpkg_metrics_txt_path = temp_folder_path / ("vcpkg" + generate_random_UUID() + ".txt"); fs.write_contents(vcpkg_metrics_txt_path, payload, ec); if (ec) return; + +#if defined(_WIN32) const std::string cmd_line = Strings::format("start \"vcpkgmetricsuploader.exe\" \"%s\" \"%s\"", temp_folder_path_exe.u8string(), vcpkg_metrics_txt_path.u8string()); - System::cmd_execute_clean(cmd_line); +#else + auto escaped_path = Strings::escape_string(vcpkg_metrics_txt_path.u8string(), '\'', '\\'); + const std::string cmd_line = Strings::format( + R"((curl "https://dc.services.visualstudio.com/v2/track" -H "Content-Type: application/json" -X POST --data '@%s' >/dev/null 2>&1; rm '%s') &)", + escaped_path, + escaped_path); #endif + System::cmd_execute_clean(cmd_line); } } diff --git a/toolsrc/src/vcpkg/userconfig.cpp b/toolsrc/src/vcpkg/userconfig.cpp index c7c57ce26..9db2e5d47 100644 --- a/toolsrc/src/vcpkg/userconfig.cpp +++ b/toolsrc/src/vcpkg/userconfig.cpp @@ -29,13 +29,22 @@ namespace namespace vcpkg { + static fs::path get_config_path() + { +#if defined(_WIN32) + return get_localappdata() / "vcpkg" / "config"; +#else + auto maybe_home = System::get_environment_variable("HOME"); + return fs::path(maybe_home.value_or("/var")) / "vcpkg" / "config"; +#endif + } + UserConfig UserConfig::try_read_data(const Files::Filesystem& fs) { UserConfig ret; -#if defined(_WIN32) try { - auto maybe_pghs = Paragraphs::get_paragraphs(fs, get_localappdata() / "vcpkg" / "config"); + auto maybe_pghs = Paragraphs::get_paragraphs(fs, get_config_path()); if (const auto p_pghs = maybe_pghs.get()) { const auto& pghs = *p_pghs; @@ -58,19 +67,19 @@ namespace vcpkg catch (...) { } -#endif return ret; } void UserConfig::try_write_data(Files::Filesystem& fs) const { -#if defined(_WIN32) try { + auto config_path = get_config_path(); + auto config_dir = config_path.parent_path(); std::error_code ec; - fs.create_directory(get_localappdata() / "vcpkg", ec); - fs.write_contents(get_localappdata() / "vcpkg" / "config", + fs.create_directory(config_dir, ec); + fs.write_contents(config_path, Strings::format("User-Id: %s\n" "User-Since: %s\n" "Mac-Hash: %s\n" @@ -84,6 +93,5 @@ namespace vcpkg catch (...) { } -#endif } } -- cgit v1.2.3 From fe41bfecd6bee02d16347802436a72e12b244d6d Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Thu, 22 Feb 2018 00:10:25 -0800 Subject: [vcpkg] Fix previous commit's typo --- toolsrc/src/vcpkg/metrics.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/metrics.cpp b/toolsrc/src/vcpkg/metrics.cpp index f81c53583..d49cadbe2 100644 --- a/toolsrc/src/vcpkg/metrics.cpp +++ b/toolsrc/src/vcpkg/metrics.cpp @@ -221,7 +221,7 @@ namespace vcpkg::Metrics "Linux", #elif defined(__unix__) "Unix", -#elif defined(__unix__) +#else "Other", #endif get_os_version_string(), -- cgit v1.2.3 From 4a25962307ae3317c94ce1e923ed8aea713931a3 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Thu, 22 Feb 2018 17:07:50 -0800 Subject: [vcpkg] Avoid use of atomic copy constructor on older compilers --- toolsrc/src/vcpkg/base/checks.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/base/checks.cpp b/toolsrc/src/vcpkg/base/checks.cpp index 1b3ed5ec9..d96cb98ff 100644 --- a/toolsrc/src/vcpkg/base/checks.cpp +++ b/toolsrc/src/vcpkg/base/checks.cpp @@ -10,7 +10,7 @@ namespace vcpkg::Checks { [[noreturn]] static void cleanup_and_exit(const int exit_code) { - static std::atomic have_entered = false; + static std::atomic have_entered{false}; if (have_entered) std::terminate(); have_entered = true; -- cgit v1.2.3 From 407767858336479eebe759404db689a9b1e16671 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 23 Feb 2018 16:34:31 -0800 Subject: Rename "depenencies" to tools. Rework xml file to reduce fields. --- toolsrc/src/vcpkg/vcpkgpaths.cpp | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index d574b7c4d..8ec7ba4cc 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -80,10 +80,10 @@ namespace vcpkg return data_lines; } - static fs::path fetch_dependency(const fs::path& scripts_folder, - const std::string& tool_name, - const fs::path& expected_downloaded_path, - const std::array& version) + static fs::path fetch_tool(const fs::path& scripts_folder, + const std::string& tool_name, + const fs::path& expected_downloaded_path, + const std::array& version) { const std::string version_as_string = Strings::format("%d.%d.%d", version[0], version[1], version[2]); System::println("A suitable version of %s was not found (required v%s). Downloading portable %s v%s...", @@ -91,22 +91,21 @@ namespace vcpkg version_as_string, tool_name, version_as_string); - const fs::path script = scripts_folder / "fetchDependency.ps1"; + const fs::path script = scripts_folder / "fetchtool.ps1"; const std::string title = Strings::format( "Fetching %s version %s (No sufficient installed version was found)", tool_name, version_as_string); - const System::PowershellParameter dependency_param("Dependency", tool_name); - const std::string output = System::powershell_execute_and_capture_output(title, script, {dependency_param}); + const System::PowershellParameter tool_param("tool", tool_name); + const std::string output = System::powershell_execute_and_capture_output(title, script, {tool_param}); - const std::vector dependency_path = keep_data_lines(output); - Checks::check_exit( - VCPKG_LINE_INFO, dependency_path.size() == 1, "Expected dependency path, but got %s", output); + const std::vector tool_path = keep_data_lines(output); + Checks::check_exit(VCPKG_LINE_INFO, tool_path.size() == 1, "Expected tool path, but got %s", output); - const fs::path actual_downloaded_path = Strings::trim(std::string{dependency_path.at(0)}); + const fs::path actual_downloaded_path = Strings::trim(std::string{tool_path.at(0)}); std::error_code ec; const auto eq = fs::stdfs::equivalent(expected_downloaded_path, actual_downloaded_path, ec); Checks::check_exit(VCPKG_LINE_INFO, eq && !ec, - "Expected dependency downloaded path to be %s, but was %s", + "Expected tool downloaded path to be %s, but was %s", expected_downloaded_path.u8string(), actual_downloaded_path.u8string()); return actual_downloaded_path; @@ -141,7 +140,7 @@ namespace vcpkg return *p; } - return fetch_dependency(scripts_folder, "cmake", downloaded_copy, EXPECTED_VERSION); + return fetch_tool(scripts_folder, "cmake", downloaded_copy, EXPECTED_VERSION); } fs::path get_nuget_path(const fs::path& downloads_folder, const fs::path& scripts_folder) @@ -161,7 +160,7 @@ namespace vcpkg return *p; } - return fetch_dependency(scripts_folder, "nuget", downloaded_copy, EXPECTED_VERSION); + return fetch_tool(scripts_folder, "nuget", downloaded_copy, EXPECTED_VERSION); } fs::path get_git_path(const fs::path& downloads_folder, const fs::path& scripts_folder) @@ -193,7 +192,7 @@ namespace vcpkg return *p; } - return fetch_dependency(scripts_folder, "git", downloaded_copy, EXPECTED_VERSION); + return fetch_tool(scripts_folder, "git", downloaded_copy, EXPECTED_VERSION); } static fs::path get_ifw_installerbase_path(const fs::path& downloads_folder, const fs::path& scripts_folder) @@ -221,7 +220,7 @@ namespace vcpkg return *p; } - return fetch_dependency(scripts_folder, "installerbase", downloaded_copy, EXPECTED_VERSION); + return fetch_tool(scripts_folder, "installerbase", downloaded_copy, EXPECTED_VERSION); } Expected VcpkgPaths::create(const fs::path& vcpkg_root_dir) -- cgit v1.2.3 From 7f5efbe14419412d8c24df836a0b3b5192661aa3 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 23 Feb 2018 18:15:26 -0800 Subject: [vcpkgTools.xml] Reuse in vcpkg.exe --- toolsrc/src/vcpkg/vcpkgpaths.cpp | 171 ++++++++++++++++++++++++++------------- 1 file changed, 113 insertions(+), 58 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index 8ec7ba4cc..bf231cecd 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -15,35 +15,99 @@ namespace vcpkg static constexpr CStringView V_140 = "v140"; static constexpr CStringView V_141 = "v141"; - static bool exists_and_has_equal_or_greater_version(const std::string& version_cmd, - const std::array& expected_version) + struct ToolData { - static const std::regex RE(R"###((\d+)\.(\d+)\.(\d+))###"); + std::array required_version; + fs::path downloaded_exe_path; + }; - const auto rc = System::cmd_execute_and_capture_output(Strings::format(R"(%s)", version_cmd)); - if (rc.exit_code != 0) - { - return false; - } + static Optional> parse_version_string(const std::string& version_as_string) + { + static const std::regex RE(R"###((\d+)\.(\d+)\.(\d+))###"); std::match_results match; - const auto found = std::regex_search(rc.output, match, RE); + const auto found = std::regex_search(version_as_string, match, RE); if (!found) { - return false; + return {}; } const int d1 = atoi(match[1].str().c_str()); const int d2 = atoi(match[2].str().c_str()); const int d3 = atoi(match[3].str().c_str()); - if (d1 > expected_version[0] || (d1 == expected_version[0] && d2 > expected_version[1]) || - (d1 == expected_version[0] && d2 == expected_version[1] && d3 >= expected_version[2])) + const std::array result = {d1, d2, d3}; + return result; + } + + static ToolData parse_tool_data_from_xml(const VcpkgPaths& paths, const std::string& tool) + { + static const fs::path XML_PATH = paths.scripts / "vcpkgTools.xml"; + + const auto get_string_inside_tags = + [](const std::string& input, const std::regex& regex, const std::string& tag_name) -> std::string { + std::smatch match; + const bool has_match = std::regex_search(input.cbegin(), input.cend(), match, regex); + Checks::check_exit( + VCPKG_LINE_INFO, has_match, "Could not find tag <%s> in %s", tag_name, XML_PATH.generic_string()); + + return match[1]; + }; + + static const std::string XML = paths.get_filesystem().read_contents(XML_PATH).value_or_exit(VCPKG_LINE_INFO); + static const std::regex VERSION_REGEX{ + Strings::format(R"###(([\s\S]*?))###", tool)}; + static const std::regex EXE_RELATIVE_PATH_REGEX{ + Strings::format(R"###(([\s\S]*?))###", tool)}; + + const std::regex tool_regex{Strings::format(R"###(([\s\S]*?))###", tool)}; + + std::smatch match_tool; + const bool has_match_tool = std::regex_search(XML.cbegin(), XML.cend(), match_tool, tool_regex); + Checks::check_exit(VCPKG_LINE_INFO, + has_match_tool, + "Could not find entry for tool [%s] in %s", + tool, + XML_PATH.generic_string()); + + const std::string tool_data_as_string = get_string_inside_tags(XML, tool_regex, tool); + + const std::string required_version_as_string = + get_string_inside_tags(tool_data_as_string, VERSION_REGEX, "requiredVersion"); + + const std::string exe_relative_path = + get_string_inside_tags(tool_data_as_string, EXE_RELATIVE_PATH_REGEX, "exeRelativePath"); + + const Optional> required_version = parse_version_string(required_version_as_string); + Checks::check_exit(VCPKG_LINE_INFO, + required_version.has_value(), + "Could not parse version for tool %s. Version string was: %s", + tool, + required_version_as_string); + + const fs::path exe_path = paths.downloads / exe_relative_path; + return ToolData{*required_version.get(), exe_path}; + } + + static bool exists_and_has_equal_or_greater_version(const std::string& version_cmd, + const std::array& expected_version) + { + const auto rc = System::cmd_execute_and_capture_output(Strings::format(R"(%s)", version_cmd)); + if (rc.exit_code != 0) + { + return false; + } + + const Optional> v = parse_version_string(rc.output); + if (!v.has_value()) { - // satisfactory version found - return true; + return false; } - return false; + const std::array actual_version = *v.get(); + return (actual_version[0] > expected_version[0] || + (actual_version[0] == expected_version[0] && actual_version[1] > expected_version[1]) || + (actual_version[0] == expected_version[0] && actual_version[1] == expected_version[1] && + actual_version[2] >= expected_version[2])); } static Optional find_if_has_equal_or_greater_version(const std::vector& candidate_paths, @@ -80,11 +144,10 @@ namespace vcpkg return data_lines; } - static fs::path fetch_tool(const fs::path& scripts_folder, - const std::string& tool_name, - const fs::path& expected_downloaded_path, - const std::array& version) + static fs::path fetch_tool(const fs::path& scripts_folder, const std::string& tool_name, const ToolData& tool_data) { + const std::array& version = tool_data.required_version; + const std::string version_as_string = Strings::format("%d.%d.%d", version[0], version[1], version[2]); System::println("A suitable version of %s was not found (required v%s). Downloading portable %s v%s...", tool_name, @@ -101,6 +164,7 @@ namespace vcpkg Checks::check_exit(VCPKG_LINE_INFO, tool_path.size() == 1, "Expected tool path, but got %s", output); const fs::path actual_downloaded_path = Strings::trim(std::string{tool_path.at(0)}); + const fs::path& expected_downloaded_path = tool_data.downloaded_exe_path; std::error_code ec; const auto eq = fs::stdfs::equivalent(expected_downloaded_path, actual_downloaded_path, ec); Checks::check_exit(VCPKG_LINE_INFO, @@ -111,22 +175,20 @@ namespace vcpkg return actual_downloaded_path; } - static fs::path get_cmake_path(const fs::path& downloads_folder, const fs::path& scripts_folder) + static fs::path get_cmake_path(const VcpkgPaths& paths) { #if defined(_WIN32) - static constexpr std::array EXPECTED_VERSION = {3, 10, 2}; + static const ToolData TOOL_DATA = parse_tool_data_from_xml(paths, "cmake"); #else - static constexpr std::array EXPECTED_VERSION = {3, 5, 1}; + static const ToolData TOOL_DATA = ToolData{{3, 5, 1}, ""}; #endif static const std::string VERSION_CHECK_ARGUMENTS = "--version"; - const std::vector from_path = Files::find_from_PATH("cmake"); - std::vector candidate_paths; - const fs::path downloaded_copy = downloads_folder / "cmake-3.10.2-win32-x86" / "bin" / "cmake.exe"; #if defined(_WIN32) - candidate_paths.push_back(downloaded_copy); + candidate_paths.push_back(TOOL_DATA.downloaded_exe_path); #endif + const std::vector from_path = Files::find_from_PATH("cmake"); candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); #if defined(_WIN32) candidate_paths.push_back(System::get_program_files_platform_bitness() / "CMake" / "bin" / "cmake.exe"); @@ -134,51 +196,47 @@ namespace vcpkg #endif const Optional path = - find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, EXPECTED_VERSION); + find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, TOOL_DATA.required_version); if (const auto p = path.get()) { return *p; } - return fetch_tool(scripts_folder, "cmake", downloaded_copy, EXPECTED_VERSION); + return fetch_tool(paths.scripts, "cmake", TOOL_DATA); } - fs::path get_nuget_path(const fs::path& downloads_folder, const fs::path& scripts_folder) + static fs::path get_nuget_path(const VcpkgPaths& paths) { - static constexpr std::array EXPECTED_VERSION = {4, 4, 0}; - - const fs::path downloaded_copy = downloads_folder / "nuget-4.4.0" / "nuget.exe"; - const std::vector from_path = Files::find_from_PATH("nuget"); + static const ToolData TOOL_DATA = parse_tool_data_from_xml(paths, "nuget"); std::vector candidate_paths; - candidate_paths.push_back(downloaded_copy); + candidate_paths.push_back(TOOL_DATA.downloaded_exe_path); + const std::vector from_path = Files::find_from_PATH("nuget"); candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); - auto path = find_if_has_equal_or_greater_version(candidate_paths, "", EXPECTED_VERSION); + auto path = find_if_has_equal_or_greater_version(candidate_paths, "", TOOL_DATA.required_version); if (const auto p = path.get()) { return *p; } - return fetch_tool(scripts_folder, "nuget", downloaded_copy, EXPECTED_VERSION); + return fetch_tool(paths.scripts, "nuget", TOOL_DATA); } - fs::path get_git_path(const fs::path& downloads_folder, const fs::path& scripts_folder) + static fs::path get_git_path(const VcpkgPaths& paths) { #if defined(_WIN32) - static constexpr std::array EXPECTED_VERSION = {2, 16, 2}; + static const ToolData TOOL_DATA = parse_tool_data_from_xml(paths, "git"); #else - static constexpr std::array EXPECTED_VERSION = {2, 7, 4}; + static const ToolData TOOL_DATA = ToolData{{2, 7, 4}, ""}; #endif static const std::string VERSION_CHECK_ARGUMENTS = "--version"; - const std::vector from_path = Files::find_from_PATH("git"); - - const fs::path downloaded_copy = downloads_folder / "MinGit-2.16.2-32-bit" / "cmd" / "git.exe"; std::vector candidate_paths; #if defined(_WIN32) - candidate_paths.push_back(downloaded_copy); + candidate_paths.push_back(TOOL_DATA.downloaded_exe_path); #endif + const std::vector from_path = Files::find_from_PATH("git"); candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); #if defined(_WIN32) candidate_paths.push_back(System::get_program_files_platform_bitness() / "git" / "cmd" / "git.exe"); @@ -186,25 +244,23 @@ namespace vcpkg #endif const Optional path = - find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, EXPECTED_VERSION); + find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, TOOL_DATA.required_version); if (const auto p = path.get()) { return *p; } - return fetch_tool(scripts_folder, "git", downloaded_copy, EXPECTED_VERSION); + return fetch_tool(paths.scripts, "git", TOOL_DATA); } - static fs::path get_ifw_installerbase_path(const fs::path& downloads_folder, const fs::path& scripts_folder) + static fs::path get_ifw_installerbase_path(const VcpkgPaths& paths) { - static constexpr std::array EXPECTED_VERSION = {3, 1, 81}; - static const std::string VERSION_CHECK_ARGUMENTS = "--framework-version"; + static const ToolData TOOL_DATA = parse_tool_data_from_xml(paths, "installerbase"); - const fs::path downloaded_copy = - downloads_folder / "QtInstallerFramework-win-x86" / "bin" / "installerbase.exe"; + static const std::string VERSION_CHECK_ARGUMENTS = "--framework-version"; std::vector candidate_paths; - candidate_paths.push_back(downloaded_copy); + candidate_paths.push_back(TOOL_DATA.downloaded_exe_path); // TODO: Uncomment later // const std::vector from_path = Files::find_from_PATH("installerbase"); // candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); @@ -214,13 +270,13 @@ namespace vcpkg // "QtIFW-3.1.0" / "bin" / "installerbase.exe"); const Optional path = - find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, EXPECTED_VERSION); + find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, TOOL_DATA.required_version); if (const auto p = path.get()) { return *p; } - return fetch_tool(scripts_folder, "installerbase", downloaded_copy, EXPECTED_VERSION); + return fetch_tool(paths.scripts, "installerbase", TOOL_DATA); } Expected VcpkgPaths::create(const fs::path& vcpkg_root_dir) @@ -299,23 +355,22 @@ namespace vcpkg const fs::path& VcpkgPaths::get_cmake_exe() const { - return this->cmake_exe.get_lazy([this]() { return get_cmake_path(this->downloads, this->scripts); }); + return this->cmake_exe.get_lazy([this]() { return get_cmake_path(*this); }); } const fs::path& VcpkgPaths::get_git_exe() const { - return this->git_exe.get_lazy([this]() { return get_git_path(this->downloads, this->scripts); }); + return this->git_exe.get_lazy([this]() { return get_git_path(*this); }); } const fs::path& VcpkgPaths::get_nuget_exe() const { - return this->nuget_exe.get_lazy([this]() { return get_nuget_path(this->downloads, this->scripts); }); + return this->nuget_exe.get_lazy([this]() { return get_nuget_path(*this); }); } const fs::path& VcpkgPaths::get_ifw_installerbase_exe() const { - return this->ifw_installerbase_exe.get_lazy( - [this]() { return get_ifw_installerbase_path(this->downloads, this->scripts); }); + return this->ifw_installerbase_exe.get_lazy([this]() { return get_ifw_installerbase_path(*this); }); } const fs::path& VcpkgPaths::get_ifw_binarycreator_exe() const -- cgit v1.2.3 From 8c8fc1a28afd8fa8ea149528d68c264cc1182dd7 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Sun, 25 Feb 2018 03:30:31 -0800 Subject: [vcpkg] Fix exclusions in ci --- toolsrc/src/vcpkg/commands.ci.cpp | 59 +++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 31 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/commands.ci.cpp b/toolsrc/src/vcpkg/commands.ci.cpp index 313582b7b..c43f25b40 100644 --- a/toolsrc/src/vcpkg/commands.ci.cpp +++ b/toolsrc/src/vcpkg/commands.ci.cpp @@ -18,34 +18,6 @@ namespace vcpkg::Commands::CI using Dependencies::InstallPlanAction; using Dependencies::InstallPlanType; - static Install::InstallSummary run_ci_on_triplet(const Triplet& triplet, - const VcpkgPaths& paths, - const std::vector& ports) - { - Input::check_triplet(triplet, paths); - std::vector specs = PackageSpec::to_package_specs(ports, triplet); - const auto featurespecs = Util::fmap(specs, [](auto& spec) { return FeatureSpec(spec, ""); }); - - StatusParagraphs status_db = database_load_check(paths); - const auto& paths_port_file = Dependencies::PathsPortFileProvider(paths); - auto action_plan = Dependencies::create_feature_install_plan(paths_port_file, featurespecs, status_db); - - const Build::BuildPackageOptions install_plan_options = {Build::UseHeadVersion::NO, - Build::AllowDownloads::YES, - Build::CleanBuildtrees::YES, - Build::CleanPackages::YES}; - - for (auto&& action : action_plan) - { - if (auto p = action.install_action.get()) - { - p->build_options = install_plan_options; - } - } - - return Install::perform(action_plan, Install::KeepGoing::YES, paths, status_db); - } - struct TripletAndSummary { Triplet triplet; @@ -91,13 +63,38 @@ namespace vcpkg::Commands::CI triplets.push_back(default_triplet); } - std::vector ports = Install::get_all_port_names(paths); - Util::erase_remove_if(ports, [&](auto&& port) { return Util::Sets::contains(exclusions_set, port); }); + StatusParagraphs status_db = database_load_check(paths); + const auto& paths_port_file = Dependencies::PathsPortFileProvider(paths); + const Build::BuildPackageOptions install_plan_options = {Build::UseHeadVersion::NO, + Build::AllowDownloads::YES, + Build::CleanBuildtrees::YES, + Build::CleanPackages::YES}; + + std::vector ports = Install::get_all_port_names(paths); std::vector results; for (const Triplet& triplet : triplets) { - Install::InstallSummary summary = run_ci_on_triplet(triplet, paths, ports); + Input::check_triplet(triplet, paths); + std::vector specs = PackageSpec::to_package_specs(ports, triplet); + // Install the default features for every package + const auto featurespecs = Util::fmap(specs, [](auto& spec) { return FeatureSpec(spec, ""); }); + + auto action_plan = Dependencies::create_feature_install_plan(paths_port_file, featurespecs, status_db); + + for (auto&& action : action_plan) + { + if (auto p = action.install_action.get()) + { + p->build_options = install_plan_options; + if (Util::Sets::contains(exclusions_set, p->spec.name())) + { + p->plan_type = InstallPlanType::EXCLUDED; + } + } + } + + auto summary = Install::perform(action_plan, Install::KeepGoing::YES, paths, status_db); results.push_back({triplet, std::move(summary)}); } -- cgit v1.2.3 From 8b97ae2dc14672ca83a5a7dc8f1d62af99234476 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Sun, 25 Feb 2018 10:13:57 -0800 Subject: [vcpkg] Fix "just-in-time" requirements calculation --- toolsrc/include/vcpkg/base/util.h | 9 +++ toolsrc/include/vcpkg/build.h | 5 +- toolsrc/include/vcpkg/commands.h | 1 + toolsrc/include/vcpkg/dependencies.h | 6 +- toolsrc/src/vcpkg/build.cpp | 117 +++++++++++++++++++++------------ toolsrc/src/vcpkg/commands.hash.cpp | 10 +-- toolsrc/src/vcpkg/dependencies.cpp | 8 +-- toolsrc/src/vcpkg/statusparagraphs.cpp | 10 +++ 8 files changed, 112 insertions(+), 54 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/base/util.h b/toolsrc/include/vcpkg/base/util.h index 6c05a3a9e..5e07b240a 100644 --- a/toolsrc/include/vcpkg/base/util.h +++ b/toolsrc/include/vcpkg/base/util.h @@ -127,6 +127,15 @@ namespace vcpkg::Util std::sort(begin(cont), end(cont)); } + template + void sort_unique_erase(Range& cont) + { + using std::begin; + using std::end; + std::sort(begin(cont), end(cont)); + cont.erase(std::unique(begin(cont), end(cont)), end(cont)); + } + template bool all_equal(const Range1& r1, const Range2& r2) { diff --git a/toolsrc/include/vcpkg/build.h b/toolsrc/include/vcpkg/build.h index 7ef7d6516..f560dbf57 100644 --- a/toolsrc/include/vcpkg/build.h +++ b/toolsrc/include/vcpkg/build.h @@ -12,6 +12,7 @@ #include #include +#include #include namespace vcpkg::Build @@ -125,7 +126,7 @@ namespace vcpkg::Build const Triplet& triplet, fs::path&& port_dir, const BuildPackageOptions& build_package_options, - const std::unordered_set& feature_list) + const std::set& feature_list) : scf(src) , triplet(triplet) , port_dir(std::move(port_dir)) @@ -138,7 +139,7 @@ namespace vcpkg::Build const Triplet& triplet; fs::path port_dir; const BuildPackageOptions& build_package_options; - const std::unordered_set& feature_list; + const std::set& feature_list; }; ExtendedBuildResult build_package(const VcpkgPaths& paths, diff --git a/toolsrc/include/vcpkg/commands.h b/toolsrc/include/vcpkg/commands.h index 31c750b38..4027e12f4 100644 --- a/toolsrc/include/vcpkg/commands.h +++ b/toolsrc/include/vcpkg/commands.h @@ -120,6 +120,7 @@ namespace vcpkg::Commands namespace Hash { void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); + std::string get_file_hash(fs::path const& cmake_exe_path, fs::path const& path, std::string const& hash_type); } template diff --git a/toolsrc/include/vcpkg/dependencies.h b/toolsrc/include/vcpkg/dependencies.h index de68d06e9..6e02e4efd 100644 --- a/toolsrc/include/vcpkg/dependencies.h +++ b/toolsrc/include/vcpkg/dependencies.h @@ -39,12 +39,12 @@ namespace vcpkg::Dependencies InstallPlanAction(const PackageSpec& spec, InstalledPackageView&& spghs, - const std::unordered_set& features, + const std::set& features, const RequestType& request_type); InstallPlanAction(const PackageSpec& spec, const SourceControlFile& scf, - const std::unordered_set& features, + const std::set& features, const RequestType& request_type); std::string displayname() const; @@ -57,7 +57,7 @@ namespace vcpkg::Dependencies InstallPlanType plan_type; RequestType request_type; Build::BuildPackageOptions build_options; - std::unordered_set feature_list; + std::set feature_list; }; enum class RemovePlanType diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index c169a778e..ff7554b78 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -66,7 +66,8 @@ namespace vcpkg::Build::Command Build::CleanBuildtrees::NO, Build::CleanPackages::NO}; - const std::unordered_set features_as_set(full_spec.features.begin(), full_spec.features.end()); + std::set features_as_set(full_spec.features.begin(), full_spec.features.end()); + features_as_set.emplace("core"); const Build::BuildPackageConfig build_config{ *scf, spec.triplet(), fs::path{port_dir}, build_package_options, features_as_set}; @@ -260,56 +261,93 @@ namespace vcpkg::Build paths.get_filesystem().write_contents(binary_control_file, start); } - static ExtendedBuildResult do_build_package(const VcpkgPaths& paths, - const BuildPackageConfig& config, - const StatusParagraphs& status_db) + static std::vector compute_required_feature_specs(const BuildPackageConfig& config, + const StatusParagraphs& status_db) { - const PackageSpec spec = PackageSpec::from_name_and_triplet(config.scf.core_paragraph->name, config.triplet) - .value_or_exit(VCPKG_LINE_INFO); - const Triplet& triplet = config.triplet; + + auto dep_strings = + Util::fmap_flatten(config.feature_list, [&](std::string const& feature) -> std::vector { + if (feature == "core") + { + return filter_dependencies(config.scf.core_paragraph->depends, triplet); + } + + auto it = + Util::find_if(config.scf.feature_paragraphs, + [&](std::unique_ptr const& fpgh) { return fpgh->name == feature; }); + Checks::check_exit(VCPKG_LINE_INFO, it != config.scf.feature_paragraphs.end()); + + return filter_dependencies(it->get()->depends, triplet); + }); + + auto dep_fspecs = FeatureSpec::from_strings_and_triplet(dep_strings, triplet); + Util::sort_unique_erase(dep_fspecs); + + // expand defaults + std::vector ret; + for (auto&& fspec : dep_fspecs) { - std::vector missing_specs; - for (auto&& dep : filter_dependencies(config.scf.core_paragraph->depends, triplet)) + if (fspec.feature().empty()) { - auto dep_specs = FeatureSpec::from_strings_and_triplet({dep}, triplet); - for (auto&& feature : dep_specs) + // reference to default features + auto it = status_db.find_installed(fspec.spec()); + if (it == status_db.end()) + { + // not currently installed, so just leave the default reference so it will fail later + ret.push_back(fspec); + } + else { - if (!status_db.is_installed(feature)) - { - missing_specs.push_back(std::move(feature)); - } + ret.push_back(FeatureSpec{fspec.spec(), "core"}); + for (auto&& default_feature : it->get()->package.default_features) + ret.push_back(FeatureSpec{fspec.spec(), default_feature}); } } - // Fail the build if any dependencies were missing - if (!missing_specs.empty()) + else { - return {BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES, std::move(missing_specs)}; + ret.push_back(fspec); } } + Util::sort_unique_erase(ret); + + return ret; + } + + static ExtendedBuildResult do_build_package(const VcpkgPaths& paths, + const BuildPackageConfig& config, + const StatusParagraphs& status_db) + { + auto& fs = paths.get_filesystem(); + const Triplet& triplet = config.triplet; + + const PackageSpec spec = + PackageSpec::from_name_and_triplet(config.scf.core_paragraph->name, triplet).value_or_exit(VCPKG_LINE_INFO); + + std::vector required_fspecs = compute_required_feature_specs(config, status_db); + + // Find all features that aren't installed. This destroys required_fspecs. + Util::unstable_keep_if(required_fspecs, + [&](FeatureSpec const& fspec) { return !status_db.is_installed(fspec); }); + + if (!required_fspecs.empty()) + { + return {BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES, std::move(required_fspecs)}; + } const fs::path& cmake_exe_path = paths.get_cmake_exe(); const fs::path& git_exe_path = paths.get_git_exe(); const fs::path ports_cmake_script_path = paths.ports_cmake; + const auto pre_build_info = PreBuildInfo::from_triplet_file(paths, triplet); - std::string features; + std::string features = Strings::join(";", config.feature_list); + std::string all_features; - if (GlobalState::feature_packages) + for (auto& feature : config.scf.feature_paragraphs) { - for (auto&& feature : config.feature_list) - { - features.append(feature + ";"); - } - if (!features.empty()) - { - features.pop_back(); - } - for (auto& feature : config.scf.feature_paragraphs) - { - all_features.append(feature->name + ";"); - } + all_features.append(feature->name + ";"); } const Toolset& toolset = paths.get_toolset(pre_build_info); @@ -351,7 +389,7 @@ namespace vcpkg::Build } } - const BuildInfo build_info = read_build_info(paths.get_filesystem(), paths.build_info_file_path(spec)); + const BuildInfo build_info = read_build_info(fs, paths.build_info_file_path(spec)); const size_t error_count = PostBuildLint::perform_all_checks(spec, paths, pre_build_info, build_info); auto bcf = create_binary_control_file(*config.scf.core_paragraph, triplet, build_info); @@ -360,16 +398,13 @@ namespace vcpkg::Build { return BuildResult::POST_BUILD_CHECKS_FAILED; } - if (GlobalState::feature_packages) + for (auto&& feature : config.feature_list) { - for (auto&& feature : config.feature_list) + for (auto&& f_pgh : config.scf.feature_paragraphs) { - for (auto&& f_pgh : config.scf.feature_paragraphs) - { - if (f_pgh->name == feature) - bcf->features.push_back( - create_binary_feature_control_file(*config.scf.core_paragraph, *f_pgh, triplet)); - } + if (f_pgh->name == feature) + bcf->features.push_back( + create_binary_feature_control_file(*config.scf.core_paragraph, *f_pgh, triplet)); } } diff --git a/toolsrc/src/vcpkg/commands.hash.cpp b/toolsrc/src/vcpkg/commands.hash.cpp index fa3d80f27..767a1bf26 100644 --- a/toolsrc/src/vcpkg/commands.hash.cpp +++ b/toolsrc/src/vcpkg/commands.hash.cpp @@ -7,7 +7,7 @@ namespace vcpkg::Commands::Hash { - static void do_file_hash(fs::path const& cmake_exe_path, fs::path const& path, std::string const& hash_type) + std::string get_file_hash(fs::path const& cmake_exe_path, fs::path const& path, std::string const& hash_type) { const std::string cmd_line = Strings::format( R"("%s" -E %ssum %s)", cmake_exe_path.u8string(), Strings::ascii_to_lowercase(hash_type), path.u8string()); @@ -27,7 +27,7 @@ namespace vcpkg::Commands::Hash auto hash = output.substr(0, start); Util::erase_remove_if(hash, isspace); - System::println(hash); + return hash; } const CommandStructure COMMAND_STRUCTURE = { @@ -45,11 +45,13 @@ namespace vcpkg::Commands::Hash if (args.command_arguments.size() == 1) { - do_file_hash(paths.get_cmake_exe(), args.command_arguments[0], "SHA512"); + auto hash = get_file_hash(paths.get_cmake_exe(), args.command_arguments[0], "SHA512"); + System::println(hash); } if (args.command_arguments.size() == 2) { - do_file_hash(paths.get_cmake_exe(), args.command_arguments[0], args.command_arguments[1]); + auto hash = get_file_hash(paths.get_cmake_exe(), args.command_arguments[0], args.command_arguments[1]); + System::println(hash); } Checks::exit_success(VCPKG_LINE_INFO); diff --git a/toolsrc/src/vcpkg/dependencies.cpp b/toolsrc/src/vcpkg/dependencies.cpp index 793951ab5..649e8f1d8 100644 --- a/toolsrc/src/vcpkg/dependencies.cpp +++ b/toolsrc/src/vcpkg/dependencies.cpp @@ -30,8 +30,8 @@ namespace vcpkg::Dependencies Optional source_control_file; PackageSpec spec; std::unordered_map edges; - std::unordered_set to_install_features; - std::unordered_set original_features; + std::set to_install_features; + std::set original_features; bool will_remove = false; bool transient_uninstalled = true; RequestType request_type = RequestType::AUTO_SELECTED; @@ -143,7 +143,7 @@ namespace vcpkg::Dependencies InstallPlanAction::InstallPlanAction(const PackageSpec& spec, const SourceControlFile& scf, - const std::unordered_set& features, + const std::set& features, const RequestType& request_type) : spec(spec) , source_control_file(scf) @@ -155,7 +155,7 @@ namespace vcpkg::Dependencies InstallPlanAction::InstallPlanAction(const PackageSpec& spec, InstalledPackageView&& ipv, - const std::unordered_set& features, + const std::set& features, const RequestType& request_type) : spec(spec) , installed_package(std::move(ipv)) diff --git a/toolsrc/src/vcpkg/statusparagraphs.cpp b/toolsrc/src/vcpkg/statusparagraphs.cpp index b23d8b884..c642af59b 100644 --- a/toolsrc/src/vcpkg/statusparagraphs.cpp +++ b/toolsrc/src/vcpkg/statusparagraphs.cpp @@ -54,6 +54,11 @@ namespace vcpkg const Triplet& triplet, const std::string& feature) { + if (feature == "core") + { + // The core feature maps to .feature == "" + return find(name, triplet, ""); + } return std::find_if(begin(), end(), [&](const std::unique_ptr& pgh) { const PackageSpec& spec = pgh->package.spec; return spec.name() == name && spec.triplet() == triplet && pgh->package.feature == feature; @@ -64,6 +69,11 @@ namespace vcpkg const Triplet& triplet, const std::string& feature) const { + if (feature == "core") + { + // The core feature maps to .feature == "" + return find(name, triplet, ""); + } return std::find_if(begin(), end(), [&](const std::unique_ptr& pgh) { const PackageSpec& spec = pgh->package.spec; return spec.name() == name && spec.triplet() == triplet && pgh->package.feature == feature; -- cgit v1.2.3 From 2e135bf09677163fc20364f9d46ba4248042ae1a Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Mon, 26 Feb 2018 05:19:05 -0800 Subject: [vcpkg] Fix issue when removing packages that have explicit feature dependencies. --- toolsrc/src/tests.plan.cpp | 15 +++++++++++++++ toolsrc/src/vcpkg/dependencies.cpp | 30 +++++++++++++++++++----------- 2 files changed, 34 insertions(+), 11 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/tests.plan.cpp b/toolsrc/src/tests.plan.cpp index 546e20b0d..d33ab290d 100644 --- a/toolsrc/src/tests.plan.cpp +++ b/toolsrc/src/tests.plan.cpp @@ -780,6 +780,21 @@ namespace UnitTest1 Assert::AreEqual("vtk", remove_plan[1].spec.name().c_str()); Assert::AreEqual("expat", remove_plan[2].spec.name().c_str()); } + + TEST_METHOD(features_depend_core_remove_scheme) + { + std::vector> pghs; + pghs.push_back(make_status_pgh("curl", "", "", "x64")); + pghs.push_back(make_status_pgh("cpr", "curl[core]", "", "x64")); + StatusParagraphs status_db(std::move(pghs)); + + auto remove_plan = Dependencies::create_remove_plan( + {unsafe_pspec("curl", Triplet::from_canonical_name("x64"))}, status_db); + + Assert::AreEqual(size_t(2), remove_plan.size()); + Assert::AreEqual("cpr", remove_plan[0].spec.name().c_str()); + Assert::AreEqual("curl", remove_plan[1].spec.name().c_str()); + } }; class UpgradePlanTests : public TestClass diff --git a/toolsrc/src/vcpkg/dependencies.cpp b/toolsrc/src/vcpkg/dependencies.cpp index 649e8f1d8..43e4d2721 100644 --- a/toolsrc/src/vcpkg/dependencies.cpp +++ b/toolsrc/src/vcpkg/dependencies.cpp @@ -29,7 +29,7 @@ namespace vcpkg::Dependencies Optional source_control_file; PackageSpec spec; - std::unordered_map edges; + std::unordered_map edges_by_feature; std::set to_install_features; std::set original_features; bool will_remove = false; @@ -100,13 +100,13 @@ namespace vcpkg::Dependencies FeatureNodeEdges core_dependencies; core_dependencies.build_edges = filter_dependencies_to_specs(scf.core_paragraph->depends, out_cluster.spec.triplet()); - out_cluster.edges.emplace("core", std::move(core_dependencies)); + out_cluster.edges_by_feature.emplace("core", std::move(core_dependencies)); for (const auto& feature : scf.feature_paragraphs) { FeatureNodeEdges added_edges; added_edges.build_edges = filter_dependencies_to_specs(feature->depends, out_cluster.spec.triplet()); - out_cluster.edges.emplace(feature->name, std::move(added_edges)); + out_cluster.edges_by_feature.emplace(feature->name, std::move(added_edges)); } out_cluster.source_control_file = &scf; } @@ -309,7 +309,15 @@ namespace vcpkg::Dependencies { if (an_installed_package->package.spec.triplet() != spec.triplet()) continue; - const std::vector& deps = an_installed_package->package.depends; + std::vector deps = an_installed_package->package.depends; + // + // This is a hack to work around existing installations that put featurespecs into binary packages + // (example: curl[core]) Eventually, this can be returned to a simple string search. + for (auto&& dep : deps) + { + dep.erase(std::find(dep.begin(), dep.end(), '['), dep.end()); + } + // if (std::find(deps.begin(), deps.end(), spec.name()) == deps.end()) continue; dependents.push_back(an_installed_package->package.spec); @@ -446,10 +454,10 @@ namespace vcpkg::Dependencies } } - auto it = cluster.edges.find(feature); - if (it == cluster.edges.end()) return MarkPlusResult::FEATURE_NOT_FOUND; + auto it = cluster.edges_by_feature.find(feature); + if (it == cluster.edges_by_feature.end()) return MarkPlusResult::FEATURE_NOT_FOUND; - if (cluster.edges[feature].plus) return MarkPlusResult::SUCCESS; + if (cluster.edges_by_feature[feature].plus) return MarkPlusResult::SUCCESS; if (cluster.original_features.find(feature) == cluster.original_features.end()) { @@ -460,7 +468,7 @@ namespace vcpkg::Dependencies { return MarkPlusResult::SUCCESS; } - cluster.edges[feature].plus = true; + cluster.edges_by_feature[feature].plus = true; if (!cluster.original_features.empty()) { @@ -485,7 +493,7 @@ namespace vcpkg::Dependencies auto res = mark_plus("", cluster, graph, graph_plan, prevent_default_features); } - for (auto&& depend : cluster.edges[feature].build_edges) + for (auto&& depend : cluster.edges_by_feature[feature].build_edges) { auto& depend_cluster = graph.get(depend.spec()); auto res = mark_plus(depend.feature(), depend_cluster, graph, graph_plan, prevent_default_features); @@ -521,7 +529,7 @@ namespace vcpkg::Dependencies } graph_plan.remove_graph.add_vertex({&cluster}); - for (auto&& pair : cluster.edges) + for (auto&& pair : cluster.edges_by_feature) { auto& remove_edges_edges = pair.second.remove_edges; for (auto&& depend : remove_edges_edges) @@ -746,7 +754,7 @@ namespace vcpkg::Dependencies auto depends_name = dependency.feature(); if (depends_name.empty()) depends_name = "core"; - auto& target_node = dep_cluster.edges[depends_name]; + auto& target_node = dep_cluster.edges_by_feature[depends_name]; target_node.remove_edges.emplace_back(FeatureSpec{spec, status_paragraph_feature}); } } -- cgit v1.2.3 From 71d44cebdb85926bc00241fc08f0dcaaedb868d2 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Mon, 26 Feb 2018 06:08:51 -0800 Subject: [vcpkg] Add test for default-features with a preinstalled dependency --- toolsrc/src/tests.plan.cpp | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/tests.plan.cpp b/toolsrc/src/tests.plan.cpp index d33ab290d..2bdb4a465 100644 --- a/toolsrc/src/tests.plan.cpp +++ b/toolsrc/src/tests.plan.cpp @@ -536,8 +536,34 @@ namespace UnitTest1 // Expect "a" to get installed and defaults of "b" through the dependency, // as no explicit features of "b" are installed by the user. Assert::IsTrue(install_plan.size() == 2); - features_check(&install_plan[1], "a", {"core"}, Triplet::X64_WINDOWS); features_check(&install_plan[0], "b", {"b1", "core"}, Triplet::X64_WINDOWS); + features_check(&install_plan[1], "a", {"core"}, Triplet::X64_WINDOWS); + } + + TEST_METHOD(do_not_install_default_features_of_existing_dependency) + { + // Add a port "a" which depends on the core of "b" + PackageSpecMap spec_map(Triplet::X64_WINDOWS); + spec_map.emplace("a", "b[core]"); + // "b" has two features, of which "b1" is default. + spec_map.emplace("b", "", {{"b0", ""}, {"b1", ""}}, {"b1"}); + + std::vector> status_paragraphs; + // "b[core]" is already installed + status_paragraphs.push_back(make_status_pgh("b")); + status_paragraphs.back()->package.spec = + PackageSpec::from_name_and_triplet("b", Triplet::X64_WINDOWS).value_or_exit(VCPKG_LINE_INFO); + + // Install "a" (without explicit feature specification) + auto install_specs = FullPackageSpec::from_string("a", Triplet::X64_WINDOWS); + auto install_plan = Dependencies::create_feature_install_plan( + spec_map.map, + FullPackageSpec::to_feature_specs({install_specs.value_or_exit(VCPKG_LINE_INFO)}), + StatusParagraphs(std::move(status_paragraphs))); + + // Expect "a" to get installed, but not require rebuilding "b" + Assert::IsTrue(install_plan.size() == 1); + features_check(&install_plan[0], "a", {"core"}, Triplet::X64_WINDOWS); } TEST_METHOD(install_default_features_of_dependency_test_2) -- cgit v1.2.3 From 65e95f6348e3a23a2afd1c1d25c9501dc826b183 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Mon, 26 Feb 2018 14:35:08 -0800 Subject: [vcpkg] Fix inter-feature references --- toolsrc/src/tests.plan.cpp | 15 +++++++++++++++ toolsrc/src/vcpkg/dependencies.cpp | 2 ++ 2 files changed, 17 insertions(+) (limited to 'toolsrc') diff --git a/toolsrc/src/tests.plan.cpp b/toolsrc/src/tests.plan.cpp index 2bdb4a465..aae4d2ee4 100644 --- a/toolsrc/src/tests.plan.cpp +++ b/toolsrc/src/tests.plan.cpp @@ -821,6 +821,21 @@ namespace UnitTest1 Assert::AreEqual("cpr", remove_plan[0].spec.name().c_str()); Assert::AreEqual("curl", remove_plan[1].spec.name().c_str()); } + + TEST_METHOD(features_depend_core_remove_scheme_2) + { + std::vector> pghs; + pghs.push_back(make_status_pgh("curl", "", "", "x64")); + pghs.push_back(make_status_feature_pgh("curl", "a", "", "x64")); + pghs.push_back(make_status_feature_pgh("curl", "b", "curl[a]", "x64")); + StatusParagraphs status_db(std::move(pghs)); + + auto remove_plan = Dependencies::create_remove_plan( + {unsafe_pspec("curl", Triplet::from_canonical_name("x64"))}, status_db); + + Assert::AreEqual(size_t(1), remove_plan.size()); + Assert::AreEqual("curl", remove_plan[0].spec.name().c_str()); + } }; class UpgradePlanTests : public TestClass diff --git a/toolsrc/src/vcpkg/dependencies.cpp b/toolsrc/src/vcpkg/dependencies.cpp index 43e4d2721..f4a371a2e 100644 --- a/toolsrc/src/vcpkg/dependencies.cpp +++ b/toolsrc/src/vcpkg/dependencies.cpp @@ -317,6 +317,8 @@ namespace vcpkg::Dependencies { dep.erase(std::find(dep.begin(), dep.end(), '['), dep.end()); } + Util::unstable_keep_if(deps, + [&](auto&& e) { return e != an_installed_package->package.spec.name(); }); // if (std::find(deps.begin(), deps.end(), spec.name()) == deps.end()) continue; -- cgit v1.2.3 From c267f32bd976ae599fa57d63031352b1c84a9c53 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Mon, 26 Feb 2018 14:43:47 -0800 Subject: [vcpkg] Fix feature interdependency during install --- toolsrc/src/vcpkg/build.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index ff7554b78..0e0928a1b 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -327,8 +327,9 @@ namespace vcpkg::Build std::vector required_fspecs = compute_required_feature_specs(config, status_db); // Find all features that aren't installed. This destroys required_fspecs. - Util::unstable_keep_if(required_fspecs, - [&](FeatureSpec const& fspec) { return !status_db.is_installed(fspec); }); + Util::unstable_keep_if(required_fspecs, [&](FeatureSpec const& fspec) { + return !status_db.is_installed(fspec) && fspec.name() != spec.name(); + }); if (!required_fspecs.empty()) { -- cgit v1.2.3 From ebdb41039450383ec7f41bd5f589cc46b7fd6a59 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Mon, 26 Feb 2018 18:18:05 -0800 Subject: [everything] Use -text to ensure consistent files across machines. If you experience trouble, you can use the following to renormalize your local working directory: git add --renormalize . git reset . git checkout . --- toolsrc/vcpkg.sln | 216 +++---- toolsrc/vcpkg/vcpkg.vcxproj | 292 ++++----- toolsrc/vcpkg/vcpkg.vcxproj.filters | 52 +- toolsrc/vcpkglib/vcpkglib.vcxproj | 508 +++++++-------- toolsrc/vcpkglib/vcpkglib.vcxproj.filters | 694 ++++++++++----------- .../vcpkgmetricsuploader.vcxproj | 286 ++++----- .../vcpkgmetricsuploader.vcxproj.filters | 42 +- toolsrc/vcpkgtest/vcpkgtest.vcxproj | 374 +++++------ toolsrc/vcpkgtest/vcpkgtest.vcxproj.filters | 112 ++-- 9 files changed, 1288 insertions(+), 1288 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/vcpkg.sln b/toolsrc/vcpkg.sln index 6c429cff9..eae73a760 100644 --- a/toolsrc/vcpkg.sln +++ b/toolsrc/vcpkg.sln @@ -1,108 +1,108 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25420.1 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vcpkg", "vcpkg\vcpkg.vcxproj", "{34671B80-54F9-46F5-8310-AC429C11D4FB}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vcpkglib", "vcpkglib\vcpkglib.vcxproj", "{B98C92B7-2874-4537-9D46-D14E5C237F04}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vcpkgmetricsuploader", "vcpkgmetricsuploader\vcpkgmetricsuploader.vcxproj", "{7D6FDEEB-B299-4A23-85EE-F67C4DED47BE}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vcpkgtest", "vcpkgtest\vcpkgtest.vcxproj", "{F27B8DB0-1279-4AF8-A2E3-1D49C4F0220D}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "scripts", "scripts", "{F5893B21-EA71-4432-84D6-5FB0E0461A2A}" - ProjectSection(SolutionItems) = preProject - ..\scripts\bootstrap.ps1 = ..\scripts\bootstrap.ps1 - ..\scripts\fetchDependency.ps1 = ..\scripts\fetchDependency.ps1 - ..\scripts\findAnyMSBuildWithCppPlatformToolset.ps1 = ..\scripts\findAnyMSBuildWithCppPlatformToolset.ps1 - ..\scripts\findVisualStudioInstallationInstances.ps1 = ..\scripts\findVisualStudioInstallationInstances.ps1 - ..\scripts\get_triplet_environment.cmake = ..\scripts\get_triplet_environment.cmake - ..\scripts\getProgramFiles32bit.ps1 = ..\scripts\getProgramFiles32bit.ps1 - ..\scripts\getProgramFilesPlatformBitness.ps1 = ..\scripts\getProgramFilesPlatformBitness.ps1 - ..\scripts\getWindowsSDK.ps1 = ..\scripts\getWindowsSDK.ps1 - ..\scripts\internalCI.ps1 = ..\scripts\internalCI.ps1 - ..\scripts\ports.cmake = ..\scripts\ports.cmake - ..\scripts\SHA256Hash.ps1 = ..\scripts\SHA256Hash.ps1 - ..\scripts\VcpkgPowershellUtils.ps1 = ..\scripts\VcpkgPowershellUtils.ps1 - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "cmake", "cmake", "{A0122231-04D5-420B-81CA-7960946E5E65}" - ProjectSection(SolutionItems) = preProject - ..\scripts\cmake\vcpkg_acquire_msys.cmake = ..\scripts\cmake\vcpkg_acquire_msys.cmake - ..\scripts\cmake\vcpkg_apply_patches.cmake = ..\scripts\cmake\vcpkg_apply_patches.cmake - ..\scripts\cmake\vcpkg_build_cmake.cmake = ..\scripts\cmake\vcpkg_build_cmake.cmake - ..\scripts\cmake\vcpkg_build_msbuild.cmake = ..\scripts\cmake\vcpkg_build_msbuild.cmake - ..\scripts\cmake\vcpkg_build_qmake.cmake = ..\scripts\cmake\vcpkg_build_qmake.cmake - ..\scripts\cmake\vcpkg_common_functions.cmake = ..\scripts\cmake\vcpkg_common_functions.cmake - ..\scripts\cmake\vcpkg_configure_cmake.cmake = ..\scripts\cmake\vcpkg_configure_cmake.cmake - ..\scripts\cmake\vcpkg_configure_meson.cmake = ..\scripts\cmake\vcpkg_configure_meson.cmake - ..\scripts\cmake\vcpkg_configure_qmake.cmake = ..\scripts\cmake\vcpkg_configure_qmake.cmake - ..\scripts\cmake\vcpkg_copy_pdbs.cmake = ..\scripts\cmake\vcpkg_copy_pdbs.cmake - ..\scripts\cmake\vcpkg_copy_tool_dependencies.cmake = ..\scripts\cmake\vcpkg_copy_tool_dependencies.cmake - ..\scripts\cmake\vcpkg_download_distfile.cmake = ..\scripts\cmake\vcpkg_download_distfile.cmake - ..\scripts\cmake\vcpkg_execute_required_process.cmake = ..\scripts\cmake\vcpkg_execute_required_process.cmake - ..\scripts\cmake\vcpkg_execute_required_process_repeat.cmake = ..\scripts\cmake\vcpkg_execute_required_process_repeat.cmake - ..\scripts\cmake\vcpkg_extract_source_archive.cmake = ..\scripts\cmake\vcpkg_extract_source_archive.cmake - ..\scripts\cmake\vcpkg_find_acquire_program.cmake = ..\scripts\cmake\vcpkg_find_acquire_program.cmake - ..\scripts\cmake\vcpkg_fixup_cmake_targets.cmake = ..\scripts\cmake\vcpkg_fixup_cmake_targets.cmake - ..\scripts\cmake\vcpkg_from_bitbucket.cmake = ..\scripts\cmake\vcpkg_from_bitbucket.cmake - ..\scripts\cmake\vcpkg_from_github.cmake = ..\scripts\cmake\vcpkg_from_github.cmake - ..\scripts\cmake\vcpkg_get_program_files_32_bit.cmake = ..\scripts\cmake\vcpkg_get_program_files_32_bit.cmake - ..\scripts\cmake\vcpkg_get_program_files_platform_bitness.cmake = ..\scripts\cmake\vcpkg_get_program_files_platform_bitness.cmake - ..\scripts\cmake\vcpkg_get_windows_sdk.cmake = ..\scripts\cmake\vcpkg_get_windows_sdk.cmake - ..\scripts\cmake\vcpkg_install_cmake.cmake = ..\scripts\cmake\vcpkg_install_cmake.cmake - ..\scripts\cmake\vcpkg_install_meson.cmake = ..\scripts\cmake\vcpkg_install_meson.cmake - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {34671B80-54F9-46F5-8310-AC429C11D4FB}.Debug|x64.ActiveCfg = Debug|x64 - {34671B80-54F9-46F5-8310-AC429C11D4FB}.Debug|x64.Build.0 = Debug|x64 - {34671B80-54F9-46F5-8310-AC429C11D4FB}.Debug|x86.ActiveCfg = Debug|Win32 - {34671B80-54F9-46F5-8310-AC429C11D4FB}.Debug|x86.Build.0 = Debug|Win32 - {34671B80-54F9-46F5-8310-AC429C11D4FB}.Release|x64.ActiveCfg = Release|x64 - {34671B80-54F9-46F5-8310-AC429C11D4FB}.Release|x64.Build.0 = Release|x64 - {34671B80-54F9-46F5-8310-AC429C11D4FB}.Release|x86.ActiveCfg = Release|Win32 - {34671B80-54F9-46F5-8310-AC429C11D4FB}.Release|x86.Build.0 = Release|Win32 - {B98C92B7-2874-4537-9D46-D14E5C237F04}.Debug|x64.ActiveCfg = Debug|x64 - {B98C92B7-2874-4537-9D46-D14E5C237F04}.Debug|x64.Build.0 = Debug|x64 - {B98C92B7-2874-4537-9D46-D14E5C237F04}.Debug|x86.ActiveCfg = Debug|Win32 - {B98C92B7-2874-4537-9D46-D14E5C237F04}.Debug|x86.Build.0 = Debug|Win32 - {B98C92B7-2874-4537-9D46-D14E5C237F04}.Release|x64.ActiveCfg = Release|x64 - {B98C92B7-2874-4537-9D46-D14E5C237F04}.Release|x64.Build.0 = Release|x64 - {B98C92B7-2874-4537-9D46-D14E5C237F04}.Release|x86.ActiveCfg = Release|Win32 - {B98C92B7-2874-4537-9D46-D14E5C237F04}.Release|x86.Build.0 = Release|Win32 - {7D6FDEEB-B299-4A23-85EE-F67C4DED47BE}.Debug|x64.ActiveCfg = Debug|x64 - {7D6FDEEB-B299-4A23-85EE-F67C4DED47BE}.Debug|x64.Build.0 = Debug|x64 - {7D6FDEEB-B299-4A23-85EE-F67C4DED47BE}.Debug|x86.ActiveCfg = Debug|Win32 - {7D6FDEEB-B299-4A23-85EE-F67C4DED47BE}.Debug|x86.Build.0 = Debug|Win32 - {7D6FDEEB-B299-4A23-85EE-F67C4DED47BE}.Release|x64.ActiveCfg = Release|x64 - {7D6FDEEB-B299-4A23-85EE-F67C4DED47BE}.Release|x64.Build.0 = Release|x64 - {7D6FDEEB-B299-4A23-85EE-F67C4DED47BE}.Release|x86.ActiveCfg = Release|Win32 - {7D6FDEEB-B299-4A23-85EE-F67C4DED47BE}.Release|x86.Build.0 = Release|Win32 - {F27B8DB0-1279-4AF8-A2E3-1D49C4F0220D}.Debug|x64.ActiveCfg = Debug|x64 - {F27B8DB0-1279-4AF8-A2E3-1D49C4F0220D}.Debug|x64.Build.0 = Debug|x64 - {F27B8DB0-1279-4AF8-A2E3-1D49C4F0220D}.Debug|x86.ActiveCfg = Debug|Win32 - {F27B8DB0-1279-4AF8-A2E3-1D49C4F0220D}.Debug|x86.Build.0 = Debug|Win32 - {F27B8DB0-1279-4AF8-A2E3-1D49C4F0220D}.Release|x64.ActiveCfg = Release|x64 - {F27B8DB0-1279-4AF8-A2E3-1D49C4F0220D}.Release|x64.Build.0 = Release|x64 - {F27B8DB0-1279-4AF8-A2E3-1D49C4F0220D}.Release|x86.ActiveCfg = Release|Win32 - {F27B8DB0-1279-4AF8-A2E3-1D49C4F0220D}.Release|x86.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {A0122231-04D5-420B-81CA-7960946E5E65} = {F5893B21-EA71-4432-84D6-5FB0E0461A2A} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {DEDCC7AF-0FE6-4387-9FFE-495D6C1AEE1B} - EndGlobalSection -EndGlobal + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25420.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vcpkg", "vcpkg\vcpkg.vcxproj", "{34671B80-54F9-46F5-8310-AC429C11D4FB}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vcpkglib", "vcpkglib\vcpkglib.vcxproj", "{B98C92B7-2874-4537-9D46-D14E5C237F04}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vcpkgmetricsuploader", "vcpkgmetricsuploader\vcpkgmetricsuploader.vcxproj", "{7D6FDEEB-B299-4A23-85EE-F67C4DED47BE}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vcpkgtest", "vcpkgtest\vcpkgtest.vcxproj", "{F27B8DB0-1279-4AF8-A2E3-1D49C4F0220D}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "scripts", "scripts", "{F5893B21-EA71-4432-84D6-5FB0E0461A2A}" + ProjectSection(SolutionItems) = preProject + ..\scripts\bootstrap.ps1 = ..\scripts\bootstrap.ps1 + ..\scripts\fetchDependency.ps1 = ..\scripts\fetchDependency.ps1 + ..\scripts\findAnyMSBuildWithCppPlatformToolset.ps1 = ..\scripts\findAnyMSBuildWithCppPlatformToolset.ps1 + ..\scripts\findVisualStudioInstallationInstances.ps1 = ..\scripts\findVisualStudioInstallationInstances.ps1 + ..\scripts\get_triplet_environment.cmake = ..\scripts\get_triplet_environment.cmake + ..\scripts\getProgramFiles32bit.ps1 = ..\scripts\getProgramFiles32bit.ps1 + ..\scripts\getProgramFilesPlatformBitness.ps1 = ..\scripts\getProgramFilesPlatformBitness.ps1 + ..\scripts\getWindowsSDK.ps1 = ..\scripts\getWindowsSDK.ps1 + ..\scripts\internalCI.ps1 = ..\scripts\internalCI.ps1 + ..\scripts\ports.cmake = ..\scripts\ports.cmake + ..\scripts\SHA256Hash.ps1 = ..\scripts\SHA256Hash.ps1 + ..\scripts\VcpkgPowershellUtils.ps1 = ..\scripts\VcpkgPowershellUtils.ps1 + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "cmake", "cmake", "{A0122231-04D5-420B-81CA-7960946E5E65}" + ProjectSection(SolutionItems) = preProject + ..\scripts\cmake\vcpkg_acquire_msys.cmake = ..\scripts\cmake\vcpkg_acquire_msys.cmake + ..\scripts\cmake\vcpkg_apply_patches.cmake = ..\scripts\cmake\vcpkg_apply_patches.cmake + ..\scripts\cmake\vcpkg_build_cmake.cmake = ..\scripts\cmake\vcpkg_build_cmake.cmake + ..\scripts\cmake\vcpkg_build_msbuild.cmake = ..\scripts\cmake\vcpkg_build_msbuild.cmake + ..\scripts\cmake\vcpkg_build_qmake.cmake = ..\scripts\cmake\vcpkg_build_qmake.cmake + ..\scripts\cmake\vcpkg_common_functions.cmake = ..\scripts\cmake\vcpkg_common_functions.cmake + ..\scripts\cmake\vcpkg_configure_cmake.cmake = ..\scripts\cmake\vcpkg_configure_cmake.cmake + ..\scripts\cmake\vcpkg_configure_meson.cmake = ..\scripts\cmake\vcpkg_configure_meson.cmake + ..\scripts\cmake\vcpkg_configure_qmake.cmake = ..\scripts\cmake\vcpkg_configure_qmake.cmake + ..\scripts\cmake\vcpkg_copy_pdbs.cmake = ..\scripts\cmake\vcpkg_copy_pdbs.cmake + ..\scripts\cmake\vcpkg_copy_tool_dependencies.cmake = ..\scripts\cmake\vcpkg_copy_tool_dependencies.cmake + ..\scripts\cmake\vcpkg_download_distfile.cmake = ..\scripts\cmake\vcpkg_download_distfile.cmake + ..\scripts\cmake\vcpkg_execute_required_process.cmake = ..\scripts\cmake\vcpkg_execute_required_process.cmake + ..\scripts\cmake\vcpkg_execute_required_process_repeat.cmake = ..\scripts\cmake\vcpkg_execute_required_process_repeat.cmake + ..\scripts\cmake\vcpkg_extract_source_archive.cmake = ..\scripts\cmake\vcpkg_extract_source_archive.cmake + ..\scripts\cmake\vcpkg_find_acquire_program.cmake = ..\scripts\cmake\vcpkg_find_acquire_program.cmake + ..\scripts\cmake\vcpkg_fixup_cmake_targets.cmake = ..\scripts\cmake\vcpkg_fixup_cmake_targets.cmake + ..\scripts\cmake\vcpkg_from_bitbucket.cmake = ..\scripts\cmake\vcpkg_from_bitbucket.cmake + ..\scripts\cmake\vcpkg_from_github.cmake = ..\scripts\cmake\vcpkg_from_github.cmake + ..\scripts\cmake\vcpkg_get_program_files_32_bit.cmake = ..\scripts\cmake\vcpkg_get_program_files_32_bit.cmake + ..\scripts\cmake\vcpkg_get_program_files_platform_bitness.cmake = ..\scripts\cmake\vcpkg_get_program_files_platform_bitness.cmake + ..\scripts\cmake\vcpkg_get_windows_sdk.cmake = ..\scripts\cmake\vcpkg_get_windows_sdk.cmake + ..\scripts\cmake\vcpkg_install_cmake.cmake = ..\scripts\cmake\vcpkg_install_cmake.cmake + ..\scripts\cmake\vcpkg_install_meson.cmake = ..\scripts\cmake\vcpkg_install_meson.cmake + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {34671B80-54F9-46F5-8310-AC429C11D4FB}.Debug|x64.ActiveCfg = Debug|x64 + {34671B80-54F9-46F5-8310-AC429C11D4FB}.Debug|x64.Build.0 = Debug|x64 + {34671B80-54F9-46F5-8310-AC429C11D4FB}.Debug|x86.ActiveCfg = Debug|Win32 + {34671B80-54F9-46F5-8310-AC429C11D4FB}.Debug|x86.Build.0 = Debug|Win32 + {34671B80-54F9-46F5-8310-AC429C11D4FB}.Release|x64.ActiveCfg = Release|x64 + {34671B80-54F9-46F5-8310-AC429C11D4FB}.Release|x64.Build.0 = Release|x64 + {34671B80-54F9-46F5-8310-AC429C11D4FB}.Release|x86.ActiveCfg = Release|Win32 + {34671B80-54F9-46F5-8310-AC429C11D4FB}.Release|x86.Build.0 = Release|Win32 + {B98C92B7-2874-4537-9D46-D14E5C237F04}.Debug|x64.ActiveCfg = Debug|x64 + {B98C92B7-2874-4537-9D46-D14E5C237F04}.Debug|x64.Build.0 = Debug|x64 + {B98C92B7-2874-4537-9D46-D14E5C237F04}.Debug|x86.ActiveCfg = Debug|Win32 + {B98C92B7-2874-4537-9D46-D14E5C237F04}.Debug|x86.Build.0 = Debug|Win32 + {B98C92B7-2874-4537-9D46-D14E5C237F04}.Release|x64.ActiveCfg = Release|x64 + {B98C92B7-2874-4537-9D46-D14E5C237F04}.Release|x64.Build.0 = Release|x64 + {B98C92B7-2874-4537-9D46-D14E5C237F04}.Release|x86.ActiveCfg = Release|Win32 + {B98C92B7-2874-4537-9D46-D14E5C237F04}.Release|x86.Build.0 = Release|Win32 + {7D6FDEEB-B299-4A23-85EE-F67C4DED47BE}.Debug|x64.ActiveCfg = Debug|x64 + {7D6FDEEB-B299-4A23-85EE-F67C4DED47BE}.Debug|x64.Build.0 = Debug|x64 + {7D6FDEEB-B299-4A23-85EE-F67C4DED47BE}.Debug|x86.ActiveCfg = Debug|Win32 + {7D6FDEEB-B299-4A23-85EE-F67C4DED47BE}.Debug|x86.Build.0 = Debug|Win32 + {7D6FDEEB-B299-4A23-85EE-F67C4DED47BE}.Release|x64.ActiveCfg = Release|x64 + {7D6FDEEB-B299-4A23-85EE-F67C4DED47BE}.Release|x64.Build.0 = Release|x64 + {7D6FDEEB-B299-4A23-85EE-F67C4DED47BE}.Release|x86.ActiveCfg = Release|Win32 + {7D6FDEEB-B299-4A23-85EE-F67C4DED47BE}.Release|x86.Build.0 = Release|Win32 + {F27B8DB0-1279-4AF8-A2E3-1D49C4F0220D}.Debug|x64.ActiveCfg = Debug|x64 + {F27B8DB0-1279-4AF8-A2E3-1D49C4F0220D}.Debug|x64.Build.0 = Debug|x64 + {F27B8DB0-1279-4AF8-A2E3-1D49C4F0220D}.Debug|x86.ActiveCfg = Debug|Win32 + {F27B8DB0-1279-4AF8-A2E3-1D49C4F0220D}.Debug|x86.Build.0 = Debug|Win32 + {F27B8DB0-1279-4AF8-A2E3-1D49C4F0220D}.Release|x64.ActiveCfg = Release|x64 + {F27B8DB0-1279-4AF8-A2E3-1D49C4F0220D}.Release|x64.Build.0 = Release|x64 + {F27B8DB0-1279-4AF8-A2E3-1D49C4F0220D}.Release|x86.ActiveCfg = Release|Win32 + {F27B8DB0-1279-4AF8-A2E3-1D49C4F0220D}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {A0122231-04D5-420B-81CA-7960946E5E65} = {F5893B21-EA71-4432-84D6-5FB0E0461A2A} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {DEDCC7AF-0FE6-4387-9FFE-495D6C1AEE1B} + EndGlobalSection +EndGlobal diff --git a/toolsrc/vcpkg/vcpkg.vcxproj b/toolsrc/vcpkg/vcpkg.vcxproj index d15e8dd44..4def6a74b 100644 --- a/toolsrc/vcpkg/vcpkg.vcxproj +++ b/toolsrc/vcpkg/vcpkg.vcxproj @@ -1,147 +1,147 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - {34671B80-54F9-46F5-8310-AC429C11D4FB} - vcpkg - 8.1 - v140 - - - - Application - true - MultiByte - - - Application - false - true - MultiByte - - - Application - true - MultiByte - - - Application - false - true - MultiByte - - - - - - - - - - - - - - - - - - - - - - - Level4 - Disabled - true - ..\include - /std:c++latest %(AdditionalOptions) - true - false - - - winhttp.lib;version.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - - - - - Level4 - Disabled - true - ..\include - /std:c++latest %(AdditionalOptions) - true - false - - - winhttp.lib;version.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - - - - - Level3 - MaxSpeed - true - true - true - ..\include - _MBCS;NDEBUG;%(PreprocessorDefinitions) - /std:c++latest %(AdditionalOptions) - true - - - true - true - winhttp.lib;version.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - - - - - Level3 - MaxSpeed - true - true - true - ..\include - _MBCS;NDEBUG;%(PreprocessorDefinitions) - /std:c++latest %(AdditionalOptions) - true - - - true - true - winhttp.lib;version.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - - - - - {b98c92b7-2874-4537-9d46-d14e5c237f04} - - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + {34671B80-54F9-46F5-8310-AC429C11D4FB} + vcpkg + 8.1 + v140 + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + + + + + + + + + + + Level4 + Disabled + true + ..\include + /std:c++latest %(AdditionalOptions) + true + false + + + winhttp.lib;version.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + Level4 + Disabled + true + ..\include + /std:c++latest %(AdditionalOptions) + true + false + + + winhttp.lib;version.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + Level3 + MaxSpeed + true + true + true + ..\include + _MBCS;NDEBUG;%(PreprocessorDefinitions) + /std:c++latest %(AdditionalOptions) + true + + + true + true + winhttp.lib;version.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + Level3 + MaxSpeed + true + true + true + ..\include + _MBCS;NDEBUG;%(PreprocessorDefinitions) + /std:c++latest %(AdditionalOptions) + true + + + true + true + winhttp.lib;version.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + {b98c92b7-2874-4537-9d46-d14e5c237f04} + + + + + + + + + + + \ No newline at end of file diff --git a/toolsrc/vcpkg/vcpkg.vcxproj.filters b/toolsrc/vcpkg/vcpkg.vcxproj.filters index 45a6238f6..3821d89b3 100644 --- a/toolsrc/vcpkg/vcpkg.vcxproj.filters +++ b/toolsrc/vcpkg/vcpkg.vcxproj.filters @@ -1,27 +1,27 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Source Files - - - - - Source Files - - + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + + + Source Files + + \ No newline at end of file diff --git a/toolsrc/vcpkglib/vcpkglib.vcxproj b/toolsrc/vcpkglib/vcpkglib.vcxproj index c2bc6b6fd..ae699a840 100644 --- a/toolsrc/vcpkglib/vcpkglib.vcxproj +++ b/toolsrc/vcpkglib/vcpkglib.vcxproj @@ -1,255 +1,255 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - {B98C92B7-2874-4537-9D46-D14E5C237F04} - vcpkglib - 8.1 - v140 - - - - StaticLibrary - true - MultiByte - - - StaticLibrary - false - true - MultiByte - - - StaticLibrary - true - MultiByte - - - StaticLibrary - false - true - MultiByte - - - 0 - - - - - - - - - - - - - - - - - - - - - - - Level3 - Disabled - true - ..\include - DISABLE_METRICS=$(DISABLE_METRICS);VCPKG_VERSION=$(VCPKG_VERSION);_MBCS;%(PreprocessorDefinitions) - /std:c++latest %(AdditionalOptions) - true - Use - pch.h - false - - - - - Level4 - Disabled - true - ..\include - DISABLE_METRICS=$(DISABLE_METRICS);VCPKG_VERSION=$(VCPKG_VERSION);_MBCS;%(PreprocessorDefinitions) - /std:c++latest %(AdditionalOptions) - true - Use - pch.h - false - - - - - Level3 - MaxSpeed - true - true - true - ..\include - DISABLE_METRICS=$(DISABLE_METRICS);VCPKG_VERSION=$(VCPKG_VERSION);_MBCS;NDEBUG;%(PreprocessorDefinitions) - /std:c++latest %(AdditionalOptions) - true - Use - pch.h - - - true - true - - - - - Level3 - MaxSpeed - true - true - true - ..\include - DISABLE_METRICS=$(DISABLE_METRICS);VCPKG_VERSION=$(VCPKG_VERSION);_MBCS;NDEBUG;%(PreprocessorDefinitions) - /std:c++latest %(AdditionalOptions) - true - Use - pch.h - - - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create - Create - Create - Create - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + {B98C92B7-2874-4537-9D46-D14E5C237F04} + vcpkglib + 8.1 + v140 + + + + StaticLibrary + true + MultiByte + + + StaticLibrary + false + true + MultiByte + + + StaticLibrary + true + MultiByte + + + StaticLibrary + false + true + MultiByte + + + 0 + + + + + + + + + + + + + + + + + + + + + + + Level3 + Disabled + true + ..\include + DISABLE_METRICS=$(DISABLE_METRICS);VCPKG_VERSION=$(VCPKG_VERSION);_MBCS;%(PreprocessorDefinitions) + /std:c++latest %(AdditionalOptions) + true + Use + pch.h + false + + + + + Level4 + Disabled + true + ..\include + DISABLE_METRICS=$(DISABLE_METRICS);VCPKG_VERSION=$(VCPKG_VERSION);_MBCS;%(PreprocessorDefinitions) + /std:c++latest %(AdditionalOptions) + true + Use + pch.h + false + + + + + Level3 + MaxSpeed + true + true + true + ..\include + DISABLE_METRICS=$(DISABLE_METRICS);VCPKG_VERSION=$(VCPKG_VERSION);_MBCS;NDEBUG;%(PreprocessorDefinitions) + /std:c++latest %(AdditionalOptions) + true + Use + pch.h + + + true + true + + + + + Level3 + MaxSpeed + true + true + true + ..\include + DISABLE_METRICS=$(DISABLE_METRICS);VCPKG_VERSION=$(VCPKG_VERSION);_MBCS;NDEBUG;%(PreprocessorDefinitions) + /std:c++latest %(AdditionalOptions) + true + Use + pch.h + + + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Create + Create + Create + Create + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/toolsrc/vcpkglib/vcpkglib.vcxproj.filters b/toolsrc/vcpkglib/vcpkglib.vcxproj.filters index 24f943e4a..74bfebf3b 100644 --- a/toolsrc/vcpkglib/vcpkglib.vcxproj.filters +++ b/toolsrc/vcpkglib/vcpkglib.vcxproj.filters @@ -1,348 +1,348 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - {69f6b6e6-5ac4-4419-a256-b8a6b0392720} - - - {4a229410-0d09-4dab-953b-f434d6483f96} - - - {75592043-ab63-4905-beee-568a6ab8bf93} - - - {fa1f10e7-58d2-4f7c-ac26-a979baa70061} - - - - - Source Files - - - Source Files\vcpkg - - - Source Files\vcpkg - - - Source Files\vcpkg - - - Source Files\vcpkg - - - Source Files\vcpkg - - - Source Files\vcpkg - - - Source Files\vcpkg - - - Source Files\vcpkg - - - Source Files\vcpkg - - - Source Files\vcpkg - - - Source Files\vcpkg - - - Source Files\vcpkg - - - Source Files\vcpkg - - - Source Files\vcpkg - - - Source Files\vcpkg - - - Source Files\vcpkg - - - Source Files\vcpkg - - - Source Files\vcpkg - - - Source Files\vcpkg - - - Source Files\vcpkg - - - Source Files\vcpkg - - - Source Files\vcpkg - - - Source Files\vcpkg - - - Source Files\vcpkg - - - Source Files\vcpkg - - - Source Files\vcpkg - - - Source Files\vcpkg - - - Source Files\vcpkg - - - Source Files\vcpkg - - - Source Files\vcpkg - - - Source Files\vcpkg - - - Source Files\vcpkg - - - Source Files\vcpkg - - - Source Files\vcpkg - - - Source Files\vcpkg - - - Source Files\vcpkg - - - Source Files\vcpkg - - - Source Files\vcpkg - - - Source Files\vcpkg - - - Source Files\vcpkg - - - Source Files\vcpkg - - - Source Files\vcpkg - - - Source Files\vcpkg - - - Source Files\vcpkg - - - Source Files\vcpkg - - - Source Files\vcpkg\base - - - Source Files\vcpkg\base - - - Source Files\vcpkg\base - - - Source Files\vcpkg\base - - - Source Files\vcpkg\base - - - Source Files\vcpkg\base - - - Source Files\vcpkg\base - - - Source Files\vcpkg\base - - - Source Files\vcpkg\base - - - Source Files\vcpkg - - - Source Files\vcpkg - - - - - Header Files - - - Header Files\vcpkg\base - - - Header Files\vcpkg\base - - - Header Files\vcpkg\base - - - Header Files\vcpkg\base - - - Header Files\vcpkg\base - - - Header Files\vcpkg\base - - - Header Files\vcpkg\base - - - Header Files\vcpkg\base - - - Header Files\vcpkg\base - - - Header Files\vcpkg\base - - - Header Files\vcpkg\base - - - Header Files\vcpkg\base - - - Header Files\vcpkg\base - - - Header Files\vcpkg\base - - - Header Files\vcpkg\base - - - Header Files\vcpkg\base - - - Header Files\vcpkg\base - - - Header Files\vcpkg - - - Header Files\vcpkg - - - Header Files\vcpkg - - - Header Files\vcpkg - - - Header Files\vcpkg - - - Header Files\vcpkg - - - Header Files\vcpkg - - - Header Files\vcpkg - - - Header Files\vcpkg - - - Header Files\vcpkg - - - Header Files\vcpkg - - - Header Files\vcpkg - - - Header Files\vcpkg - - - Header Files\vcpkg - - - Header Files\vcpkg - - - Header Files\vcpkg - - - Header Files\vcpkg - - - Header Files\vcpkg - - - Header Files\vcpkg - - - Header Files\vcpkg - - - Header Files\vcpkg - - - Header Files\vcpkg - - - Header Files\vcpkg - - - Header Files\vcpkg - - - Header Files\vcpkg - - - Header Files\vcpkg - - - Header Files\vcpkg - - - Header Files\vcpkg - - - Header Files\vcpkg - - - Header Files\vcpkg\base - - + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + {69f6b6e6-5ac4-4419-a256-b8a6b0392720} + + + {4a229410-0d09-4dab-953b-f434d6483f96} + + + {75592043-ab63-4905-beee-568a6ab8bf93} + + + {fa1f10e7-58d2-4f7c-ac26-a979baa70061} + + + + + Source Files + + + Source Files\vcpkg + + + Source Files\vcpkg + + + Source Files\vcpkg + + + Source Files\vcpkg + + + Source Files\vcpkg + + + Source Files\vcpkg + + + Source Files\vcpkg + + + Source Files\vcpkg + + + Source Files\vcpkg + + + Source Files\vcpkg + + + Source Files\vcpkg + + + Source Files\vcpkg + + + Source Files\vcpkg + + + Source Files\vcpkg + + + Source Files\vcpkg + + + Source Files\vcpkg + + + Source Files\vcpkg + + + Source Files\vcpkg + + + Source Files\vcpkg + + + Source Files\vcpkg + + + Source Files\vcpkg + + + Source Files\vcpkg + + + Source Files\vcpkg + + + Source Files\vcpkg + + + Source Files\vcpkg + + + Source Files\vcpkg + + + Source Files\vcpkg + + + Source Files\vcpkg + + + Source Files\vcpkg + + + Source Files\vcpkg + + + Source Files\vcpkg + + + Source Files\vcpkg + + + Source Files\vcpkg + + + Source Files\vcpkg + + + Source Files\vcpkg + + + Source Files\vcpkg + + + Source Files\vcpkg + + + Source Files\vcpkg + + + Source Files\vcpkg + + + Source Files\vcpkg + + + Source Files\vcpkg + + + Source Files\vcpkg + + + Source Files\vcpkg + + + Source Files\vcpkg + + + Source Files\vcpkg + + + Source Files\vcpkg\base + + + Source Files\vcpkg\base + + + Source Files\vcpkg\base + + + Source Files\vcpkg\base + + + Source Files\vcpkg\base + + + Source Files\vcpkg\base + + + Source Files\vcpkg\base + + + Source Files\vcpkg\base + + + Source Files\vcpkg\base + + + Source Files\vcpkg + + + Source Files\vcpkg + + + + + Header Files + + + Header Files\vcpkg\base + + + Header Files\vcpkg\base + + + Header Files\vcpkg\base + + + Header Files\vcpkg\base + + + Header Files\vcpkg\base + + + Header Files\vcpkg\base + + + Header Files\vcpkg\base + + + Header Files\vcpkg\base + + + Header Files\vcpkg\base + + + Header Files\vcpkg\base + + + Header Files\vcpkg\base + + + Header Files\vcpkg\base + + + Header Files\vcpkg\base + + + Header Files\vcpkg\base + + + Header Files\vcpkg\base + + + Header Files\vcpkg\base + + + Header Files\vcpkg\base + + + Header Files\vcpkg + + + Header Files\vcpkg + + + Header Files\vcpkg + + + Header Files\vcpkg + + + Header Files\vcpkg + + + Header Files\vcpkg + + + Header Files\vcpkg + + + Header Files\vcpkg + + + Header Files\vcpkg + + + Header Files\vcpkg + + + Header Files\vcpkg + + + Header Files\vcpkg + + + Header Files\vcpkg + + + Header Files\vcpkg + + + Header Files\vcpkg + + + Header Files\vcpkg + + + Header Files\vcpkg + + + Header Files\vcpkg + + + Header Files\vcpkg + + + Header Files\vcpkg + + + Header Files\vcpkg + + + Header Files\vcpkg + + + Header Files\vcpkg + + + Header Files\vcpkg + + + Header Files\vcpkg + + + Header Files\vcpkg + + + Header Files\vcpkg + + + Header Files\vcpkg + + + Header Files\vcpkg + + + Header Files\vcpkg\base + + \ No newline at end of file diff --git a/toolsrc/vcpkgmetricsuploader/vcpkgmetricsuploader.vcxproj b/toolsrc/vcpkgmetricsuploader/vcpkgmetricsuploader.vcxproj index 4b59c5ace..d78e48e13 100644 --- a/toolsrc/vcpkgmetricsuploader/vcpkgmetricsuploader.vcxproj +++ b/toolsrc/vcpkgmetricsuploader/vcpkgmetricsuploader.vcxproj @@ -1,144 +1,144 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - {7D6FDEEB-B299-4A23-85EE-F67C4DED47BE} - vcpkgmetricsuploader - 8.1 - v140 - - - - Application - true - MultiByte - - - Application - false - true - MultiByte - - - Application - true - MultiByte - - - Application - false - true - MultiByte - - - - - - - - - - - - - - - - - - - - - - - Level3 - Disabled - true - ..\include - /std:c++latest %(AdditionalOptions) - true - false - - - winhttp.lib;version.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - - - - - Level4 - Disabled - true - ..\include - /std:c++latest %(AdditionalOptions) - true - false - - - winhttp.lib;version.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - - - - - Level3 - MaxSpeed - true - true - true - ..\include - _MBCS;NDEBUG;%(PreprocessorDefinitions) - /std:c++latest %(AdditionalOptions) - true - - - true - true - winhttp.lib;version.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - - - - - Level3 - MaxSpeed - true - true - true - ..\include - _MBCS;NDEBUG;%(PreprocessorDefinitions) - /std:c++latest %(AdditionalOptions) - true - - - true - true - winhttp.lib;version.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - - - - - - - - {b98c92b7-2874-4537-9d46-d14e5c237f04} - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + {7D6FDEEB-B299-4A23-85EE-F67C4DED47BE} + vcpkgmetricsuploader + 8.1 + v140 + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + + + + + + + + + + + Level3 + Disabled + true + ..\include + /std:c++latest %(AdditionalOptions) + true + false + + + winhttp.lib;version.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + Level4 + Disabled + true + ..\include + /std:c++latest %(AdditionalOptions) + true + false + + + winhttp.lib;version.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + Level3 + MaxSpeed + true + true + true + ..\include + _MBCS;NDEBUG;%(PreprocessorDefinitions) + /std:c++latest %(AdditionalOptions) + true + + + true + true + winhttp.lib;version.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + Level3 + MaxSpeed + true + true + true + ..\include + _MBCS;NDEBUG;%(PreprocessorDefinitions) + /std:c++latest %(AdditionalOptions) + true + + + true + true + winhttp.lib;version.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + + {b98c92b7-2874-4537-9d46-d14e5c237f04} + + + + + \ No newline at end of file diff --git a/toolsrc/vcpkgmetricsuploader/vcpkgmetricsuploader.vcxproj.filters b/toolsrc/vcpkgmetricsuploader/vcpkgmetricsuploader.vcxproj.filters index 847921000..ad56c0c72 100644 --- a/toolsrc/vcpkgmetricsuploader/vcpkgmetricsuploader.vcxproj.filters +++ b/toolsrc/vcpkgmetricsuploader/vcpkgmetricsuploader.vcxproj.filters @@ -1,22 +1,22 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Source Files - - + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + \ No newline at end of file diff --git a/toolsrc/vcpkgtest/vcpkgtest.vcxproj b/toolsrc/vcpkgtest/vcpkgtest.vcxproj index 166216c45..d61b15a71 100644 --- a/toolsrc/vcpkgtest/vcpkgtest.vcxproj +++ b/toolsrc/vcpkgtest/vcpkgtest.vcxproj @@ -1,188 +1,188 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - - - - - - - Create - Create - Create - Create - - - - - - - - - {b98c92b7-2874-4537-9d46-d14e5c237f04} - - - - - - - - {F27B8DB0-1279-4AF8-A2E3-1D49C4F0220D} - Win32Proj - vcpkgtest - 8.1 - v140 - - - - DynamicLibrary - true - Unicode - false - - - DynamicLibrary - false - true - Unicode - false - - - DynamicLibrary - true - Unicode - false - - - DynamicLibrary - false - true - Unicode - false - - - - - - - - - - - - - - - - - - - - - true - - - true - - - - - - Use - Level3 - Disabled - ..\include;$(VCInstallDir)UnitTest\include;$(VsInstallRoot)\VC\Auxiliary\VS\UnitTest\include;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;%(PreprocessorDefinitions) - true - tests.pch.h - /std:c++latest %(AdditionalOptions) - true - false - - - Windows - $(VCInstallDir)UnitTest\lib;$(VsInstallRoot)\VC\Auxiliary\VS\UnitTest\lib;%(AdditionalLibraryDirectories) - - - - - Use - Level4 - Disabled - ..\include;$(VCInstallDir)UnitTest\include;$(VsInstallRoot)\VC\Auxiliary\VS\UnitTest\include;%(AdditionalIncludeDirectories) - _DEBUG;%(PreprocessorDefinitions) - true - tests.pch.h - /std:c++latest %(AdditionalOptions) - true - false - - - Windows - $(VCInstallDir)UnitTest\lib;$(VsInstallRoot)\VC\Auxiliary\VS\UnitTest\lib;%(AdditionalLibraryDirectories) - - - - - Level3 - Use - MaxSpeed - true - true - ..\include;$(VCInstallDir)UnitTest\include;$(VsInstallRoot)\VC\Auxiliary\VS\UnitTest\include;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;%(PreprocessorDefinitions) - true - tests.pch.h - /std:c++latest %(AdditionalOptions) - true - - - Windows - true - true - $(VCInstallDir)UnitTest\lib;$(VsInstallRoot)\VC\Auxiliary\VS\UnitTest\lib;%(AdditionalLibraryDirectories) - - - - - Level3 - Use - MaxSpeed - true - true - ..\include;$(VCInstallDir)UnitTest\include;$(VsInstallRoot)\VC\Auxiliary\VS\UnitTest\include;%(AdditionalIncludeDirectories) - NDEBUG;%(PreprocessorDefinitions) - true - tests.pch.h - /std:c++latest %(AdditionalOptions) - true - - - Windows - true - true - $(VCInstallDir)UnitTest\lib;$(VsInstallRoot)\VC\Auxiliary\VS\UnitTest\lib;%(AdditionalLibraryDirectories) - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + + + + + + + Create + Create + Create + Create + + + + + + + + + {b98c92b7-2874-4537-9d46-d14e5c237f04} + + + + + + + + {F27B8DB0-1279-4AF8-A2E3-1D49C4F0220D} + Win32Proj + vcpkgtest + 8.1 + v140 + + + + DynamicLibrary + true + Unicode + false + + + DynamicLibrary + false + true + Unicode + false + + + DynamicLibrary + true + Unicode + false + + + DynamicLibrary + false + true + Unicode + false + + + + + + + + + + + + + + + + + + + + + true + + + true + + + + + + Use + Level3 + Disabled + ..\include;$(VCInstallDir)UnitTest\include;$(VsInstallRoot)\VC\Auxiliary\VS\UnitTest\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;%(PreprocessorDefinitions) + true + tests.pch.h + /std:c++latest %(AdditionalOptions) + true + false + + + Windows + $(VCInstallDir)UnitTest\lib;$(VsInstallRoot)\VC\Auxiliary\VS\UnitTest\lib;%(AdditionalLibraryDirectories) + + + + + Use + Level4 + Disabled + ..\include;$(VCInstallDir)UnitTest\include;$(VsInstallRoot)\VC\Auxiliary\VS\UnitTest\include;%(AdditionalIncludeDirectories) + _DEBUG;%(PreprocessorDefinitions) + true + tests.pch.h + /std:c++latest %(AdditionalOptions) + true + false + + + Windows + $(VCInstallDir)UnitTest\lib;$(VsInstallRoot)\VC\Auxiliary\VS\UnitTest\lib;%(AdditionalLibraryDirectories) + + + + + Level3 + Use + MaxSpeed + true + true + ..\include;$(VCInstallDir)UnitTest\include;$(VsInstallRoot)\VC\Auxiliary\VS\UnitTest\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;%(PreprocessorDefinitions) + true + tests.pch.h + /std:c++latest %(AdditionalOptions) + true + + + Windows + true + true + $(VCInstallDir)UnitTest\lib;$(VsInstallRoot)\VC\Auxiliary\VS\UnitTest\lib;%(AdditionalLibraryDirectories) + + + + + Level3 + Use + MaxSpeed + true + true + ..\include;$(VCInstallDir)UnitTest\include;$(VsInstallRoot)\VC\Auxiliary\VS\UnitTest\include;%(AdditionalIncludeDirectories) + NDEBUG;%(PreprocessorDefinitions) + true + tests.pch.h + /std:c++latest %(AdditionalOptions) + true + + + Windows + true + true + $(VCInstallDir)UnitTest\lib;$(VsInstallRoot)\VC\Auxiliary\VS\UnitTest\lib;%(AdditionalLibraryDirectories) + + + + + \ No newline at end of file diff --git a/toolsrc/vcpkgtest/vcpkgtest.vcxproj.filters b/toolsrc/vcpkgtest/vcpkgtest.vcxproj.filters index 422f9298e..0f799426e 100644 --- a/toolsrc/vcpkgtest/vcpkgtest.vcxproj.filters +++ b/toolsrc/vcpkgtest/vcpkgtest.vcxproj.filters @@ -1,57 +1,57 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + \ No newline at end of file -- cgit v1.2.3 From e2980c8f91327614f24abec6704a5831d8074a8a Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Mon, 26 Feb 2018 18:18:43 -0800 Subject: [vcpkg] Add 7zip internal tool --- toolsrc/include/vcpkg/vcpkgpaths.h | 2 ++ toolsrc/src/vcpkg/vcpkgpaths.cpp | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/vcpkgpaths.h b/toolsrc/include/vcpkg/vcpkgpaths.h index 33a9b0067..84e8110ec 100644 --- a/toolsrc/include/vcpkg/vcpkgpaths.h +++ b/toolsrc/include/vcpkg/vcpkgpaths.h @@ -63,6 +63,7 @@ namespace vcpkg fs::path ports_cmake; + const fs::path& get_7za_exe() const; const fs::path& get_cmake_exe() const; const fs::path& get_git_exe() const; const fs::path& get_nuget_exe() const; @@ -80,6 +81,7 @@ namespace vcpkg private: Lazy> available_triplets; + Lazy _7za_exe; Lazy cmake_exe; Lazy git_exe; Lazy nuget_exe; diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index bf231cecd..f2b39c110 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -205,6 +205,20 @@ namespace vcpkg return fetch_tool(paths.scripts, "cmake", TOOL_DATA); } + static fs::path get_7za_path(const VcpkgPaths& paths) + { +#if defined(_WIN32) + static const ToolData TOOL_DATA = parse_tool_data_from_xml(paths, "7zip"); + if (!paths.get_filesystem().exists(TOOL_DATA.downloaded_exe_path)) + { + return fetch_tool(paths.scripts, "7zip", TOOL_DATA); + } + return TOOL_DATA.downloaded_exe_path; +#else + Checks::exit_with_message(VCPKG_LINE_INFO, "Cannot download 7zip for non-Windows platforms."); +#endif + } + static fs::path get_nuget_path(const VcpkgPaths& paths) { static const ToolData TOOL_DATA = parse_tool_data_from_xml(paths, "nuget"); @@ -353,6 +367,11 @@ namespace vcpkg return it != this->get_available_triplets().cend(); } + const fs::path& VcpkgPaths::get_7za_exe() const + { + return this->_7za_exe.get_lazy([this]() { return get_7za_path(*this); }); + } + const fs::path& VcpkgPaths::get_cmake_exe() const { return this->cmake_exe.get_lazy([this]() { return get_cmake_path(*this); }); -- cgit v1.2.3 From a2e6ffd86d435f08116e5e80b04796fe6898ebd0 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Mon, 26 Feb 2018 18:22:17 -0800 Subject: [vcpkg] Refactor VcpkgCmdArguments to not utilize global state --- toolsrc/include/vcpkg/vcpkgcmdarguments.h | 2 ++ toolsrc/src/vcpkg.cpp | 1 + toolsrc/src/vcpkg/vcpkgcmdarguments.cpp | 5 +++-- 3 files changed, 6 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/vcpkgcmdarguments.h b/toolsrc/include/vcpkg/vcpkgcmdarguments.h index d84be9c22..bce22b6f9 100644 --- a/toolsrc/include/vcpkg/vcpkgcmdarguments.h +++ b/toolsrc/include/vcpkg/vcpkgcmdarguments.h @@ -79,6 +79,8 @@ namespace vcpkg Optional sendmetrics = nullopt; Optional printmetrics = nullopt; + // feature flags + Optional featurepackages = nullopt; std::string command; std::vector command_arguments; diff --git a/toolsrc/src/vcpkg.cpp b/toolsrc/src/vcpkg.cpp index adb32c723..ffda7ede9 100644 --- a/toolsrc/src/vcpkg.cpp +++ b/toolsrc/src/vcpkg.cpp @@ -265,6 +265,7 @@ int main(const int argc, const char* const* const argv) const VcpkgCmdArguments args = VcpkgCmdArguments::create_from_command_line(argc, argv); + if (const auto p = args.featurepackages.get()) GlobalState::feature_packages = *p; if (const auto p = args.printmetrics.get()) Metrics::g_metrics.lock()->set_print_metrics(*p); if (const auto p = args.sendmetrics.get()) Metrics::g_metrics.lock()->set_send_metrics(*p); if (const auto p = args.debug.get()) GlobalState::debugging = *p; diff --git a/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp b/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp index 84ad17fe3..18acf8e12 100644 --- a/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp +++ b/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp @@ -126,12 +126,13 @@ namespace vcpkg } if (arg == "--featurepackages") { - GlobalState::feature_packages = true; + parse_switch(true, "featurepackages", args.featurepackages); continue; } if (arg == "--no-featurepackages") { - GlobalState::feature_packages = false; + parse_switch(false, "featurepackages", args.featurepackages); + continue; continue; } -- cgit v1.2.3 From 9eb9eca48766289b6377eb479cd5eb5f3da7441d Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Mon, 26 Feb 2018 18:25:01 -0800 Subject: [vcpkg-hash] Fix target paths containing spaces --- toolsrc/src/vcpkg/commands.hash.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/commands.hash.cpp b/toolsrc/src/vcpkg/commands.hash.cpp index 767a1bf26..bbbbed036 100644 --- a/toolsrc/src/vcpkg/commands.hash.cpp +++ b/toolsrc/src/vcpkg/commands.hash.cpp @@ -10,7 +10,10 @@ namespace vcpkg::Commands::Hash std::string get_file_hash(fs::path const& cmake_exe_path, fs::path const& path, std::string const& hash_type) { const std::string cmd_line = Strings::format( - R"("%s" -E %ssum %s)", cmake_exe_path.u8string(), Strings::ascii_to_lowercase(hash_type), path.u8string()); + R"("%s" -E %ssum "%s")", + cmake_exe_path.u8string(), + Strings::ascii_to_lowercase(hash_type), + path.u8string()); const auto ec_data = System::cmd_execute_and_capture_output(cmd_line); Checks::check_exit(VCPKG_LINE_INFO, ec_data.exit_code == 0, "Running command:\n %s\n failed", cmd_line); -- cgit v1.2.3 From 25b8f25dadcb2af28ae5be2e6d31884ca67f1b26 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Mon, 26 Feb 2018 18:38:25 -0800 Subject: [vcpkg] Initial commit of experimental compressed binary archiving behind a flag --- toolsrc/include/vcpkg/binaryparagraph.h | 4 +- toolsrc/include/vcpkg/build.h | 1 + toolsrc/include/vcpkg/globalstate.h | 1 + toolsrc/include/vcpkg/vcpkgcmdarguments.h | 2 + toolsrc/src/vcpkg.cpp | 9 + toolsrc/src/vcpkg/binaryparagraph.cpp | 11 +- toolsrc/src/vcpkg/build.cpp | 263 ++++++++++++++++++++++++------ toolsrc/src/vcpkg/globalstate.cpp | 1 + toolsrc/src/vcpkg/vcpkgcmdarguments.cpp | 9 + 9 files changed, 241 insertions(+), 60 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/binaryparagraph.h b/toolsrc/include/vcpkg/binaryparagraph.h index f59bf693a..3315151c6 100644 --- a/toolsrc/include/vcpkg/binaryparagraph.h +++ b/toolsrc/include/vcpkg/binaryparagraph.h @@ -14,7 +14,7 @@ namespace vcpkg { BinaryParagraph(); explicit BinaryParagraph(std::unordered_map fields); - BinaryParagraph(const SourceParagraph& spgh, const Triplet& triplet); + BinaryParagraph(const SourceParagraph& spgh, const Triplet& triplet, const std::string& abi_tag); BinaryParagraph(const SourceParagraph& spgh, const FeatureParagraph& fpgh, const Triplet& triplet); std::string displayname() const; @@ -40,4 +40,4 @@ namespace vcpkg }; void serialize(const BinaryParagraph& pgh, std::string& out_str); -} \ No newline at end of file +} diff --git a/toolsrc/include/vcpkg/build.h b/toolsrc/include/vcpkg/build.h index f560dbf57..ea81c4dbe 100644 --- a/toolsrc/include/vcpkg/build.h +++ b/toolsrc/include/vcpkg/build.h @@ -98,6 +98,7 @@ namespace vcpkg::Build /// static PreBuildInfo from_triplet_file(const VcpkgPaths& paths, const Triplet& triplet); + std::string triplet_abi_tag; std::string target_architecture; std::string cmake_system_name; std::string cmake_system_version; diff --git a/toolsrc/include/vcpkg/globalstate.h b/toolsrc/include/vcpkg/globalstate.h index 360d3f43e..bc28e3ff8 100644 --- a/toolsrc/include/vcpkg/globalstate.h +++ b/toolsrc/include/vcpkg/globalstate.h @@ -14,6 +14,7 @@ namespace vcpkg static std::atomic debugging; static std::atomic feature_packages; + static std::atomic g_binary_caching; static std::atomic g_init_console_cp; static std::atomic g_init_console_output_cp; diff --git a/toolsrc/include/vcpkg/vcpkgcmdarguments.h b/toolsrc/include/vcpkg/vcpkgcmdarguments.h index bce22b6f9..f449887f1 100644 --- a/toolsrc/include/vcpkg/vcpkgcmdarguments.h +++ b/toolsrc/include/vcpkg/vcpkgcmdarguments.h @@ -81,6 +81,8 @@ namespace vcpkg // feature flags Optional featurepackages = nullopt; + Optional binarycaching = nullopt; + std::string command; std::vector command_arguments; diff --git a/toolsrc/src/vcpkg.cpp b/toolsrc/src/vcpkg.cpp index ffda7ede9..ef68e6f72 100644 --- a/toolsrc/src/vcpkg.cpp +++ b/toolsrc/src/vcpkg.cpp @@ -263,9 +263,18 @@ int main(const int argc, const char* const* const argv) } load_config(); + const auto vcpkg_feature_flags_env = System::get_environment_variable("VCPKG_FEATURE_FLAGS"); + if (const auto v = vcpkg_feature_flags_env.get()) + { + auto flags = Strings::split(*v, ","); + if (std::find(flags.begin(), flags.end(), "binarycaching") != flags.end()) GlobalState::g_binary_caching = true; + } + const VcpkgCmdArguments args = VcpkgCmdArguments::create_from_command_line(argc, argv); if (const auto p = args.featurepackages.get()) GlobalState::feature_packages = *p; + if (const auto p = args.binarycaching.get()) GlobalState::g_binary_caching = *p; + if (const auto p = args.printmetrics.get()) Metrics::g_metrics.lock()->set_print_metrics(*p); if (const auto p = args.sendmetrics.get()) Metrics::g_metrics.lock()->set_send_metrics(*p); if (const auto p = args.debug.get()) GlobalState::debugging = *p; diff --git a/toolsrc/src/vcpkg/binaryparagraph.cpp b/toolsrc/src/vcpkg/binaryparagraph.cpp index 7c9e905e8..7a8b0d577 100644 --- a/toolsrc/src/vcpkg/binaryparagraph.cpp +++ b/toolsrc/src/vcpkg/binaryparagraph.cpp @@ -71,22 +71,17 @@ namespace vcpkg Checks::check_exit(VCPKG_LINE_INFO, multi_arch == "same", "Multi-Arch must be 'same' but was %s", multi_arch); } - BinaryParagraph::BinaryParagraph(const SourceParagraph& spgh, const Triplet& triplet) + BinaryParagraph::BinaryParagraph(const SourceParagraph& spgh, const Triplet& triplet, const std::string& abi_tag) + : version(spgh.version), description(spgh.description), maintainer(spgh.maintainer), abi(abi_tag) { this->spec = PackageSpec::from_name_and_triplet(spgh.name, triplet).value_or_exit(VCPKG_LINE_INFO); - this->version = spgh.version; - this->description = spgh.description; - this->maintainer = spgh.maintainer; this->depends = filter_dependencies(spgh.depends, triplet); } BinaryParagraph::BinaryParagraph(const SourceParagraph& spgh, const FeatureParagraph& fpgh, const Triplet& triplet) + : version(), feature(fpgh.name), description(fpgh.description), maintainer() { this->spec = PackageSpec::from_name_and_triplet(spgh.name, triplet).value_or_exit(VCPKG_LINE_INFO); - this->version = ""; - this->feature = fpgh.name; - this->description = fpgh.description; - this->maintainer = ""; this->depends = filter_dependencies(fpgh.depends, triplet); } diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index 0e0928a1b..0486039b7 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -238,10 +238,11 @@ namespace vcpkg::Build static std::unique_ptr create_binary_control_file(const SourceParagraph& source_paragraph, const Triplet& triplet, - const BuildInfo& build_info) + const BuildInfo& build_info, + const std::string& abi_tag) { auto bcf = std::make_unique(); - BinaryParagraph bpgh(source_paragraph, triplet); + BinaryParagraph bpgh(source_paragraph, triplet, abi_tag); if (const auto p_ver = build_info.version.get()) { bpgh.version = *p_ver; @@ -321,11 +322,23 @@ namespace vcpkg::Build auto& fs = paths.get_filesystem(); const Triplet& triplet = config.triplet; + struct AbiEntry + { + std::string key; + std::string value; + }; + + std::vector abi_tag_entries; + const PackageSpec spec = PackageSpec::from_name_and_triplet(config.scf.core_paragraph->name, triplet).value_or_exit(VCPKG_LINE_INFO); std::vector required_fspecs = compute_required_feature_specs(config, status_db); + // extract out the actual package ids + auto dep_pspecs = Util::fmap(required_fspecs, [](FeatureSpec const& fspec) { return fspec.spec(); }); + Util::sort_unique_erase(dep_pspecs); + // Find all features that aren't installed. This destroys required_fspecs. Util::unstable_keep_if(required_fspecs, [&](FeatureSpec const& fspec) { return !status_db.is_installed(fspec) && fspec.name() != spec.name(); @@ -336,81 +349,210 @@ namespace vcpkg::Build return {BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES, std::move(required_fspecs)}; } + // dep_pspecs was not destroyed + for (auto&& pspec : dep_pspecs) + { + if (pspec == spec) continue; + auto status_it = status_db.find_installed(pspec); + Checks::check_exit(VCPKG_LINE_INFO, status_it != status_db.end()); + abi_tag_entries.emplace_back( + AbiEntry{status_it->get()->package.spec.name(), status_it->get()->package.abi}); + } + const fs::path& cmake_exe_path = paths.get_cmake_exe(); const fs::path& git_exe_path = paths.get_git_exe(); const fs::path ports_cmake_script_path = paths.ports_cmake; + if (GlobalState::g_binary_caching) + { + abi_tag_entries.emplace_back(AbiEntry{ + "portfile", Commands::Hash::get_file_hash(cmake_exe_path, config.port_dir / "portfile.cmake", "SHA1")}); + abi_tag_entries.emplace_back(AbiEntry{ + "control", Commands::Hash::get_file_hash(cmake_exe_path, config.port_dir / "CONTROL", "SHA1")}); + } + const auto pre_build_info = PreBuildInfo::from_triplet_file(paths, triplet); + abi_tag_entries.emplace_back(AbiEntry{"triplet", pre_build_info.triplet_abi_tag}); std::string features = Strings::join(";", config.feature_list); + abi_tag_entries.emplace_back(AbiEntry{"features", features}); - std::string all_features; - for (auto& feature : config.scf.feature_paragraphs) - { - all_features.append(feature->name + ";"); - } + if (config.build_package_options.use_head_version == UseHeadVersion::YES) + abi_tag_entries.emplace_back(AbiEntry{"head", ""}); - const Toolset& toolset = paths.get_toolset(pre_build_info); - const std::string cmd_launch_cmake = System::make_cmake_cmd( - cmake_exe_path, - ports_cmake_script_path, - { - {"CMD", "BUILD"}, - {"PORT", config.scf.core_paragraph->name}, - {"CURRENT_PORT_DIR", config.port_dir / "/."}, - {"TARGET_TRIPLET", triplet.canonical_name()}, - {"VCPKG_PLATFORM_TOOLSET", toolset.version.c_str()}, - {"VCPKG_USE_HEAD_VERSION", - Util::Enum::to_bool(config.build_package_options.use_head_version) ? "1" : "0"}, - {"_VCPKG_NO_DOWNLOADS", !Util::Enum::to_bool(config.build_package_options.allow_downloads) ? "1" : "0"}, - {"GIT", git_exe_path}, - {"FEATURES", features}, - {"ALL_FEATURES", all_features}, - }); + std::string full_abi_info = + Strings::join("", abi_tag_entries, [](const AbiEntry& p) { return p.key + " " + p.value + "\n"; }); - const auto cmd_set_environment = make_build_env_cmd(pre_build_info, toolset); - const std::string command = Strings::format(R"(%s && %s)", cmd_set_environment, cmd_launch_cmake); + std::string abi_tag; + + if (GlobalState::g_binary_caching) + { + if (GlobalState::debugging) + { + System::println("[DEBUG] "); + for (auto&& entry : abi_tag_entries) + { + System::println("[DEBUG] %s|%s", entry.key, entry.value); + } + System::println("[DEBUG] "); + } - const auto timer = Chrono::ElapsedTimer::create_started(); + auto abi_tag_entries_missing = abi_tag_entries; + Util::stable_keep_if(abi_tag_entries_missing, [](const AbiEntry& p) { return p.value.empty(); }); - const int return_code = System::cmd_execute_clean(command); - const auto buildtimeus = timer.microseconds(); - const auto spec_string = spec.to_string(); + if (abi_tag_entries_missing.empty()) + { + std::error_code ec; + fs.create_directories(paths.buildtrees / spec.name(), ec); + auto abi_file_path = paths.buildtrees / spec.name() / "vcpkg_abi_info"; + fs.write_contents(abi_file_path, full_abi_info); - { - auto locked_metrics = Metrics::g_metrics.lock(); - locked_metrics->track_buildtime(spec.to_string() + ":[" + Strings::join(",", config.feature_list) + "]", - buildtimeus); - if (return_code != 0) + abi_tag = Commands::Hash::get_file_hash(paths.get_cmake_exe(), abi_file_path, "SHA1"); + } + else { - locked_metrics->track_property("error", "build failed"); - locked_metrics->track_property("build_error", spec_string); - return BuildResult::BUILD_FAILED; + System::println("Warning: binary caching disabled because abi keys are missing values:\n%s", + Strings::join("", abi_tag_entries_missing, [](const AbiEntry& e) { + return " " + e.key + "\n"; + })); } } - const BuildInfo build_info = read_build_info(fs, paths.build_info_file_path(spec)); - const size_t error_count = PostBuildLint::perform_all_checks(spec, paths, pre_build_info, build_info); + std::unique_ptr bcf; - auto bcf = create_binary_control_file(*config.scf.core_paragraph, triplet, build_info); + auto archives_dir = paths.root / "archives"; + if (!abi_tag.empty()) + { + archives_dir /= abi_tag.substr(0, 2); + } + auto archive_path = archives_dir / (abi_tag + ".zip"); - if (error_count != 0) + if (GlobalState::g_binary_caching && !abi_tag.empty() && fs.exists(archive_path)) { - return BuildResult::POST_BUILD_CHECKS_FAILED; + System::println("Using cached binary package: %s", archive_path.u8string()); + + auto pkg_path = paths.package_dir(spec); + std::error_code ec; + fs.remove_all(pkg_path, ec); + fs.create_directories(pkg_path, ec); + auto files = fs.get_files_non_recursive(pkg_path); + Checks::check_exit(VCPKG_LINE_INFO, files.empty(), "unable to clear path: %s", pkg_path.u8string()); + + auto&& _7za = paths.get_7za_exe(); + + System::cmd_execute_clean(Strings::format( + R"("%s" x "%s" -o"%s" -y >nul)", _7za.u8string(), archive_path.u8string(), pkg_path.u8string())); + + auto maybe_bcf = Paragraphs::try_load_cached_control_package(paths, spec); + bcf = std::make_unique(std::move(maybe_bcf).value_or_exit(VCPKG_LINE_INFO)); } - for (auto&& feature : config.feature_list) + else { - for (auto&& f_pgh : config.scf.feature_paragraphs) + if (GlobalState::g_binary_caching && !abi_tag.empty()) { - if (f_pgh->name == feature) - bcf->features.push_back( - create_binary_feature_control_file(*config.scf.core_paragraph, *f_pgh, triplet)); + System::println("Could not locate cached archive: %s", archive_path.u8string()); } - } - write_binary_control_file(paths, *bcf); + std::string all_features; + for (auto& feature : config.scf.feature_paragraphs) + { + all_features.append(feature->name + ";"); + } + + const Toolset& toolset = paths.get_toolset(pre_build_info); + const std::string cmd_launch_cmake = System::make_cmake_cmd( + cmake_exe_path, + ports_cmake_script_path, + { + {"CMD", "BUILD"}, + {"PORT", config.scf.core_paragraph->name}, + {"CURRENT_PORT_DIR", config.port_dir / "/."}, + {"TARGET_TRIPLET", triplet.canonical_name()}, + {"VCPKG_PLATFORM_TOOLSET", toolset.version.c_str()}, + {"VCPKG_USE_HEAD_VERSION", + Util::Enum::to_bool(config.build_package_options.use_head_version) ? "1" : "0"}, + {"_VCPKG_NO_DOWNLOADS", + !Util::Enum::to_bool(config.build_package_options.allow_downloads) ? "1" : "0"}, + {"GIT", git_exe_path}, + {"FEATURES", features}, + {"ALL_FEATURES", all_features}, + }); + + const auto cmd_set_environment = make_build_env_cmd(pre_build_info, toolset); + const std::string command = Strings::format(R"(%s && %s)", cmd_set_environment, cmd_launch_cmake); + + const auto timer = Chrono::ElapsedTimer::create_started(); + + const int return_code = System::cmd_execute_clean(command); + const auto buildtimeus = timer.microseconds(); + const auto spec_string = spec.to_string(); + { + auto locked_metrics = Metrics::g_metrics.lock(); + locked_metrics->track_buildtime(spec.to_string() + ":[" + Strings::join(",", config.feature_list) + "]", + buildtimeus); + if (return_code != 0) + { + locked_metrics->track_property("error", "build failed"); + locked_metrics->track_property("build_error", spec_string); + return BuildResult::BUILD_FAILED; + } + } + + const BuildInfo build_info = read_build_info(fs, paths.build_info_file_path(spec)); + const size_t error_count = PostBuildLint::perform_all_checks(spec, paths, pre_build_info, build_info); + + bcf = create_binary_control_file(*config.scf.core_paragraph, triplet, build_info, abi_tag); + + if (error_count != 0) + { + return BuildResult::POST_BUILD_CHECKS_FAILED; + } + for (auto&& feature : config.feature_list) + { + for (auto&& f_pgh : config.scf.feature_paragraphs) + { + if (f_pgh->name == feature) + bcf->features.push_back( + create_binary_feature_control_file(*config.scf.core_paragraph, *f_pgh, triplet)); + } + } + + if (GlobalState::g_binary_caching && !abi_tag.empty()) + { + std::error_code ec; + fs.write_contents( + paths.package_dir(spec) / "share" / spec.name() / "vcpkg_abi_info.txt", full_abi_info, ec); + } + + write_binary_control_file(paths, *bcf); + + if (GlobalState::g_binary_caching && !abi_tag.empty()) + { + auto tmp_archive_path = paths.buildtrees / spec.name() / (spec.triplet().to_string() + ".zip"); + + std::error_code ec; + fs.remove(tmp_archive_path, ec); + Checks::check_exit(VCPKG_LINE_INFO, + !fs.exists(tmp_archive_path), + "Could not remove file: %s", + tmp_archive_path.u8string()); + auto&& _7za = paths.get_7za_exe(); + + System::cmd_execute_clean(Strings::format( + R"("%s" a "%s" "%s\*" >nul)", + _7za.u8string(), + tmp_archive_path.u8string(), + paths.package_dir(spec).u8string())); + + fs.create_directories(archives_dir, ec); + + fs.rename(tmp_archive_path, archive_path); + + System::println("Stored binary cache: %s", archive_path.u8string()); + } + } return {BuildResult::SUCCEEDED, std::move(bcf)}; } @@ -549,6 +691,26 @@ namespace vcpkg::Build const fs::path ports_cmake_script_path = paths.scripts / "get_triplet_environment.cmake"; const fs::path triplet_file_path = paths.triplets / (triplet.canonical_name() + ".cmake"); + auto triplet_abi_tag = [&]() { + static std::map s_hash_cache; + + if (GlobalState::g_binary_caching) + { + auto it_hash = s_hash_cache.find(triplet_file_path); + if (it_hash != s_hash_cache.end()) + { + return it_hash->second; + } + auto hash = Commands::Hash::get_file_hash(paths.get_cmake_exe(), triplet_file_path, "SHA1"); + s_hash_cache.emplace(triplet_file_path, hash); + return hash; + } + else + { + return std::string(); + } + }(); + const auto cmd_launch_cmake = System::make_cmake_cmd(cmake_exe_path, ports_cmake_script_path, { @@ -560,6 +722,7 @@ namespace vcpkg::Build const std::vector lines = Strings::split(ec_data.output, "\n"); PreBuildInfo pre_build_info; + pre_build_info.triplet_abi_tag = triplet_abi_tag; const auto e = lines.cend(); auto cur = std::find(lines.cbegin(), e, FLAG_GUID); diff --git a/toolsrc/src/vcpkg/globalstate.cpp b/toolsrc/src/vcpkg/globalstate.cpp index eac69d9f5..a4100acf7 100644 --- a/toolsrc/src/vcpkg/globalstate.cpp +++ b/toolsrc/src/vcpkg/globalstate.cpp @@ -9,6 +9,7 @@ namespace vcpkg std::atomic GlobalState::debugging(false); std::atomic GlobalState::feature_packages(true); + std::atomic GlobalState::g_binary_caching(false); std::atomic GlobalState::g_init_console_cp(0); std::atomic GlobalState::g_init_console_output_cp(0); diff --git a/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp b/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp index 18acf8e12..8909e1552 100644 --- a/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp +++ b/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp @@ -133,6 +133,15 @@ namespace vcpkg { parse_switch(false, "featurepackages", args.featurepackages); continue; + } + if (arg == "--binarycaching") + { + parse_switch(true, "binarycaching", args.binarycaching); + continue; + } + if (arg == "--no-binarycaching") + { + parse_switch(false, "binarycaching", args.binarycaching); continue; } -- cgit v1.2.3 From ef4febc7ef08d1aaa3fb97efadf09e2ad2b9464d Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Wed, 28 Feb 2018 11:54:40 -0800 Subject: [vcpkg] Fix exporting packages with features-depending-on-features --- toolsrc/include/vcpkg/packagespec.h | 4 ---- toolsrc/src/vcpkg/packagespec.cpp | 21 --------------------- toolsrc/src/vcpkg/statusparagraph.cpp | 31 ++++++++++++++++++++++++++++++- 3 files changed, 30 insertions(+), 26 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/packagespec.h b/toolsrc/include/vcpkg/packagespec.h index 0a4347639..299a9c401 100644 --- a/toolsrc/include/vcpkg/packagespec.h +++ b/toolsrc/include/vcpkg/packagespec.h @@ -28,10 +28,6 @@ namespace vcpkg static std::vector to_package_specs(const std::vector& ports, const Triplet& triplet); - static std::vector from_dependencies_of_port(const std::string& port, - const std::vector& dependencies, - const Triplet& triplet); - const std::string& name() const; const Triplet& triplet() const; diff --git a/toolsrc/src/vcpkg/packagespec.cpp b/toolsrc/src/vcpkg/packagespec.cpp index a9e072094..789aaca80 100644 --- a/toolsrc/src/vcpkg/packagespec.cpp +++ b/toolsrc/src/vcpkg/packagespec.cpp @@ -112,27 +112,6 @@ namespace vcpkg }); } - std::vector PackageSpec::from_dependencies_of_port(const std::string& port, - const std::vector& dependencies, - const Triplet& triplet) - { - return Util::fmap(dependencies, [&](const std::string& spec_as_string) -> PackageSpec { - auto maybe_spec = PackageSpec::from_name_and_triplet(spec_as_string, triplet); - if (auto spec = maybe_spec.get()) - { - return std::move(*spec); - } - - const PackageSpecParseResult error_type = maybe_spec.error(); - Checks::exit_with_message(VCPKG_LINE_INFO, - "Invalid dependency [%s] in package [%s]\n" - "%s", - spec_as_string, - port, - vcpkg::to_string(error_type)); - }); - } - const std::string& PackageSpec::name() const { return this->m_name; } const Triplet& PackageSpec::triplet() const { return this->m_triplet; } diff --git a/toolsrc/src/vcpkg/statusparagraph.cpp b/toolsrc/src/vcpkg/statusparagraph.cpp index 05238ba8b..62d1d4b42 100644 --- a/toolsrc/src/vcpkg/statusparagraph.cpp +++ b/toolsrc/src/vcpkg/statusparagraph.cpp @@ -86,13 +86,42 @@ namespace vcpkg } std::vector InstalledPackageView::dependencies() const { + // accumulate all features in installed dependencies + // Todo: make this unneeded by collapsing all package dependencies into the core package auto deps = Util::fmap_flatten(features, [](const StatusParagraph* pgh) -> std::vector const& { return pgh->package.depends; }); + // Add the core paragraph dependencies to the list deps.insert(deps.end(), core->package.depends.begin(), core->package.depends.end()); auto&& spec = core->package.spec; - return PackageSpec::from_dependencies_of_port(spec.name(), deps, spec.triplet()); + + // + // This is a hack to work around existing installations that put featurespecs into binary packages + // (example: curl[core]) + for (auto&& dep : deps) + { + dep.erase(std::find(dep.begin(), dep.end(), '['), dep.end()); + } + Util::unstable_keep_if(deps, [&](auto&& e) { return e != spec.name(); }); + // + Util::sort_unique_erase(deps); + + return Util::fmap(deps, [&](const std::string& dep) -> PackageSpec { + auto maybe_dependency_spec = PackageSpec::from_name_and_triplet(dep, spec.triplet()); + if (auto dependency_spec = maybe_dependency_spec.get()) + { + return std::move(*dependency_spec); + } + + const PackageSpecParseResult error_type = maybe_dependency_spec.error(); + Checks::exit_with_message(VCPKG_LINE_INFO, + "Invalid dependency [%s] in package [%s]\n" + "%s", + dep, + spec.name(), + vcpkg::to_string(error_type)); + }); } } -- cgit v1.2.3 From bbbbfb9e79a201a7c479fbc9e8ca14cd8569703d Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Wed, 28 Feb 2018 12:15:16 -0800 Subject: [vcpkg] Add tests for create_export_plan and remove unused arguments --- toolsrc/include/vcpkg/dependencies.h | 6 +-- toolsrc/src/tests.plan.cpp | 94 ++++++++++++++++++++++++++++++++++++ toolsrc/src/vcpkg/dependencies.cpp | 19 +++----- toolsrc/src/vcpkg/export.cpp | 9 ++-- 4 files changed, 106 insertions(+), 22 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/dependencies.h b/toolsrc/include/vcpkg/dependencies.h index 6e02e4efd..fadb8cc7e 100644 --- a/toolsrc/include/vcpkg/dependencies.h +++ b/toolsrc/include/vcpkg/dependencies.h @@ -93,7 +93,7 @@ namespace vcpkg::Dependencies enum class ExportPlanType { UNKNOWN, - PORT_AVAILABLE_BUT_NOT_BUILT, + NOT_BUILT, ALREADY_BUILT }; @@ -165,9 +165,7 @@ namespace vcpkg::Dependencies std::vector create_remove_plan(const std::vector& specs, const StatusParagraphs& status_db); - std::vector create_export_plan(const PortFileProvider& port_file_provider, - const VcpkgPaths& paths, - const std::vector& specs, + std::vector create_export_plan(const std::vector& specs, const StatusParagraphs& status_db); std::vector create_feature_install_plan(const std::unordered_map& map, diff --git a/toolsrc/src/tests.plan.cpp b/toolsrc/src/tests.plan.cpp index aae4d2ee4..08d3c1dab 100644 --- a/toolsrc/src/tests.plan.cpp +++ b/toolsrc/src/tests.plan.cpp @@ -997,4 +997,98 @@ namespace UnitTest1 features_check(&plan[1], "a", {"core", "a1"}); } }; + + class ExportPlanTests : public TestClass + { + TEST_METHOD(basic_export_scheme) + { + std::vector> pghs; + pghs.push_back(make_status_pgh("a")); + StatusParagraphs status_db(std::move(pghs)); + + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + auto spec_a = spec_map.emplace("a"); + + auto plan = Dependencies::create_export_plan({spec_a}, status_db); + + Assert::AreEqual(size_t(1), plan.size()); + Assert::AreEqual("a", plan[0].spec.name().c_str()); + Assert::IsTrue(plan[0].plan_type == Dependencies::ExportPlanType::ALREADY_BUILT); + } + + TEST_METHOD(basic_export_scheme_with_recurse) + { + std::vector> pghs; + pghs.push_back(make_status_pgh("a")); + pghs.push_back(make_status_pgh("b", "a")); + StatusParagraphs status_db(std::move(pghs)); + + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + auto spec_a = spec_map.emplace("a"); + auto spec_b = spec_map.emplace("b", "a"); + + auto plan = Dependencies::create_export_plan({spec_b}, status_db); + + Assert::AreEqual(size_t(2), plan.size()); + Assert::AreEqual("a", plan[0].spec.name().c_str()); + Assert::IsTrue(plan[0].plan_type == Dependencies::ExportPlanType::ALREADY_BUILT); + + Assert::AreEqual("b", plan[1].spec.name().c_str()); + Assert::IsTrue(plan[1].plan_type == Dependencies::ExportPlanType::ALREADY_BUILT); + } + + TEST_METHOD(basic_export_scheme_with_bystander) + { + std::vector> pghs; + pghs.push_back(make_status_pgh("a")); + pghs.push_back(make_status_pgh("b")); + StatusParagraphs status_db(std::move(pghs)); + + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + auto spec_a = spec_map.emplace("a"); + auto spec_b = spec_map.emplace("b", "a"); + + auto plan = Dependencies::create_export_plan({spec_a}, status_db); + + Assert::AreEqual(size_t(1), plan.size()); + Assert::AreEqual("a", plan[0].spec.name().c_str()); + Assert::IsTrue(plan[0].plan_type == Dependencies::ExportPlanType::ALREADY_BUILT); + } + + TEST_METHOD(basic_export_scheme_with_missing) + { + StatusParagraphs status_db; + + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + auto spec_a = spec_map.emplace("a"); + + auto plan = Dependencies::create_export_plan({spec_a}, status_db); + + Assert::AreEqual(size_t(1), plan.size()); + Assert::AreEqual("a", plan[0].spec.name().c_str()); + Assert::IsTrue(plan[0].plan_type == Dependencies::ExportPlanType::NOT_BUILT); + } + + TEST_METHOD(basic_upgrade_scheme_with_features) + { + std::vector> pghs; + pghs.push_back(make_status_pgh("b")); + pghs.push_back(make_status_pgh("a")); + pghs.push_back(make_status_feature_pgh("a", "a1", "b[core]")); + StatusParagraphs status_db(std::move(pghs)); + + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + auto spec_a = spec_map.emplace("a", "", {{"a1", ""}}); + + auto plan = Dependencies::create_export_plan({spec_a}, status_db); + + Assert::AreEqual(size_t(2), plan.size()); + + Assert::AreEqual("b", plan[0].spec.name().c_str()); + Assert::IsTrue(plan[0].plan_type == Dependencies::ExportPlanType::ALREADY_BUILT); + + Assert::AreEqual("a", plan[1].spec.name().c_str()); + Assert::IsTrue(plan[1].plan_type == Dependencies::ExportPlanType::ALREADY_BUILT); + } + }; } diff --git a/toolsrc/src/vcpkg/dependencies.cpp b/toolsrc/src/vcpkg/dependencies.cpp index f4a371a2e..1f853014b 100644 --- a/toolsrc/src/vcpkg/dependencies.cpp +++ b/toolsrc/src/vcpkg/dependencies.cpp @@ -223,7 +223,7 @@ namespace vcpkg::Dependencies } ExportPlanAction::ExportPlanAction(const PackageSpec& spec, const RequestType& request_type) - : spec(spec), plan_type(ExportPlanType::PORT_AVAILABLE_BUT_NOT_BUILT), request_type(request_type) + : spec(spec), plan_type(ExportPlanType::NOT_BUILT), request_type(request_type) { } @@ -349,23 +349,16 @@ namespace vcpkg::Dependencies return Graphs::topological_sort(specs, RemoveAdjacencyProvider{status_db, installed_ports, specs_as_set}); } - std::vector create_export_plan(const PortFileProvider& port_file_provider, - const VcpkgPaths& paths, - const std::vector& specs, + std::vector create_export_plan(const std::vector& specs, const StatusParagraphs& status_db) { struct ExportAdjacencyProvider final : Graphs::AdjacencyProvider { - const VcpkgPaths& paths; const StatusParagraphs& status_db; - const PortFileProvider& provider; const std::unordered_set& specs_as_set; - ExportAdjacencyProvider(const VcpkgPaths& p, - const StatusParagraphs& s, - const PortFileProvider& prov, - const std::unordered_set& specs_as_set) - : paths(p), status_db(s), provider(prov), specs_as_set(specs_as_set) + ExportAdjacencyProvider(const StatusParagraphs& s, const std::unordered_set& specs_as_set) + : status_db(s), specs_as_set(specs_as_set) { } @@ -394,8 +387,8 @@ namespace vcpkg::Dependencies }; const std::unordered_set specs_as_set(specs.cbegin(), specs.cend()); - std::vector toposort = Graphs::topological_sort( - specs, ExportAdjacencyProvider{paths, status_db, port_file_provider, specs_as_set}); + std::vector toposort = + Graphs::topological_sort(specs, ExportAdjacencyProvider{status_db, specs_as_set}); return toposort; } diff --git a/toolsrc/src/vcpkg/export.cpp b/toolsrc/src/vcpkg/export.cpp index a9c407dd8..831058007 100644 --- a/toolsrc/src/vcpkg/export.cpp +++ b/toolsrc/src/vcpkg/export.cpp @@ -69,7 +69,7 @@ namespace vcpkg::Export static void print_plan(const std::map>& group_by_plan_type) { static constexpr std::array ORDER = {ExportPlanType::ALREADY_BUILT, - ExportPlanType::PORT_AVAILABLE_BUT_NOT_BUILT}; + ExportPlanType::NOT_BUILT}; static constexpr Build::BuildPackageOptions build_options = {Build::UseHeadVersion::NO, Build::AllowDownloads::YES}; @@ -92,7 +92,7 @@ namespace vcpkg::Export case ExportPlanType::ALREADY_BUILT: System::println("The following packages are already built and will be exported:\n%s", as_string); continue; - case ExportPlanType::PORT_AVAILABLE_BUT_NOT_BUILT: + case ExportPlanType::NOT_BUILT: System::println("The following packages need to be built:\n%s", as_string); continue; default: Checks::unreachable(VCPKG_LINE_INFO); @@ -486,8 +486,7 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console // create the plan const StatusParagraphs status_db = database_load_check(paths); Dependencies::PathsPortFileProvider provider(paths); - std::vector export_plan = - Dependencies::create_export_plan(provider, paths, opts.specs, status_db); + std::vector export_plan = Dependencies::create_export_plan(opts.specs, status_db); Checks::check_exit(VCPKG_LINE_INFO, !export_plan.empty(), "Export plan cannot be empty"); std::map> group_by_plan_type; @@ -505,7 +504,7 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console "Additional packages (*) need to be exported to complete this operation."); } - const auto it = group_by_plan_type.find(ExportPlanType::PORT_AVAILABLE_BUT_NOT_BUILT); + const auto it = group_by_plan_type.find(ExportPlanType::NOT_BUILT); if (it != group_by_plan_type.cend() && !it->second.empty()) { System::println(System::Color::error, "There are packages that have not been built."); -- cgit v1.2.3 From bad51b04626f25d323433ec159af1d60f93cadb1 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Fri, 2 Mar 2018 08:59:17 -0800 Subject: [vcpkg] Improve handling of external toolchain files --- toolsrc/include/vcpkg/base/cofffilereader.h | 2 ++ toolsrc/src/vcpkg/base/cofffilereader.cpp | 3 --- toolsrc/src/vcpkg/build.cpp | 9 ++++---- toolsrc/src/vcpkg/commands.env.cpp | 6 +++++- toolsrc/src/vcpkg/postbuildlint.cpp | 33 +++++++++++++++++++---------- toolsrc/src/vcpkg/vcpkgpaths.cpp | 7 +----- 6 files changed, 34 insertions(+), 26 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/base/cofffilereader.h b/toolsrc/include/vcpkg/base/cofffilereader.h index ad2cc7b12..e0ad69b33 100644 --- a/toolsrc/include/vcpkg/base/cofffilereader.h +++ b/toolsrc/include/vcpkg/base/cofffilereader.h @@ -17,7 +17,9 @@ namespace vcpkg::CoffFileReader std::vector machine_types; }; +#if defined(_WIN32) DllInfo read_dll(const fs::path& path); LibInfo read_lib(const fs::path& path); +#endif } diff --git a/toolsrc/src/vcpkg/base/cofffilereader.cpp b/toolsrc/src/vcpkg/base/cofffilereader.cpp index 1927e0b5e..96d280108 100644 --- a/toolsrc/src/vcpkg/base/cofffilereader.cpp +++ b/toolsrc/src/vcpkg/base/cofffilereader.cpp @@ -306,8 +306,5 @@ namespace vcpkg::CoffFileReader return {std::vector(machine_types.cbegin(), machine_types.cend())}; } -#else - DllInfo read_dll(const fs::path& path) { exit(-1); } - LibInfo read_lib(const fs::path& path) { exit(-1); } #endif } diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index 0486039b7..5870bd187 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -208,9 +208,7 @@ namespace vcpkg::Build std::string make_build_env_cmd(const PreBuildInfo& pre_build_info, const Toolset& toolset) { - if (pre_build_info.external_toolchain_file) - return Strings::format( - R"("%s" %s 2>&1)", toolset.vcvarsall.u8string(), Strings::join(" ", toolset.vcvarsall_options)); + if (pre_build_info.external_toolchain_file.has_value()) return ""; const char* tonull = " >nul"; if (GlobalState::debugging) @@ -479,8 +477,9 @@ namespace vcpkg::Build {"ALL_FEATURES", all_features}, }); - const auto cmd_set_environment = make_build_env_cmd(pre_build_info, toolset); - const std::string command = Strings::format(R"(%s && %s)", cmd_set_environment, cmd_launch_cmake); + auto command = make_build_env_cmd(pre_build_info, toolset); + if (!command.empty()) command.append(" && "); + command.append(cmd_launch_cmake); const auto timer = Chrono::ElapsedTimer::create_started(); diff --git a/toolsrc/src/vcpkg/commands.env.cpp b/toolsrc/src/vcpkg/commands.env.cpp index 6e52383d8..f3beef6cd 100644 --- a/toolsrc/src/vcpkg/commands.env.cpp +++ b/toolsrc/src/vcpkg/commands.env.cpp @@ -21,7 +21,11 @@ namespace vcpkg::Commands::Env const auto pre_build_info = Build::PreBuildInfo::from_triplet_file(paths, default_triplet); const Toolset& toolset = paths.get_toolset(pre_build_info); - System::cmd_execute_clean(Build::make_build_env_cmd(pre_build_info, toolset) + " && cmd"); + auto env_cmd = Build::make_build_env_cmd(pre_build_info, toolset); + if (env_cmd.empty()) + System::cmd_execute_clean("cmd"); + else + System::cmd_execute_clean(env_cmd + " && cmd"); Checks::exit_success(VCPKG_LINE_INFO); } diff --git a/toolsrc/src/vcpkg/postbuildlint.cpp b/toolsrc/src/vcpkg/postbuildlint.cpp index 2b427737a..a31518ad7 100644 --- a/toolsrc/src/vcpkg/postbuildlint.cpp +++ b/toolsrc/src/vcpkg/postbuildlint.cpp @@ -391,6 +391,7 @@ namespace vcpkg::PostBuildLint static LintStatus check_dll_architecture(const std::string& expected_architecture, const std::vector& files) { +#if defined(_WIN32) std::vector binaries_with_invalid_architecture; for (const fs::path& file : files) @@ -413,6 +414,7 @@ namespace vcpkg::PostBuildLint print_invalid_architecture_files(expected_architecture, binaries_with_invalid_architecture); return LintStatus::ERROR_DETECTED; } +#endif return LintStatus::SUCCESS; } @@ -420,6 +422,7 @@ namespace vcpkg::PostBuildLint static LintStatus check_lib_architecture(const std::string& expected_architecture, const std::vector& files) { +#if defined(_WIN32) std::vector binaries_with_invalid_architecture; for (const fs::path& file : files) @@ -451,6 +454,7 @@ namespace vcpkg::PostBuildLint print_invalid_architecture_files(expected_architecture, binaries_with_invalid_architecture); return LintStatus::ERROR_DETECTED; } +#endif return LintStatus::SUCCESS; } @@ -790,11 +794,15 @@ namespace vcpkg::PostBuildLint dlls.insert(dlls.cend(), debug_dlls.cbegin(), debug_dlls.cend()); dlls.insert(dlls.cend(), release_dlls.cbegin(), release_dlls.cend()); - error_count += check_exports_of_dlls(dlls, toolset.dumpbin); - error_count += check_uwp_bit_of_dlls(pre_build_info.cmake_system_name, dlls, toolset.dumpbin); - error_count += check_dll_architecture(pre_build_info.target_architecture, dlls); + if (!toolset.dumpbin.empty()) + { + error_count += check_exports_of_dlls(dlls, toolset.dumpbin); + error_count += check_uwp_bit_of_dlls(pre_build_info.cmake_system_name, dlls, toolset.dumpbin); + error_count += + check_outdated_crt_linkage_of_dlls(dlls, toolset.dumpbin, build_info, pre_build_info); + } - error_count += check_outdated_crt_linkage_of_dlls(dlls, toolset.dumpbin, build_info, pre_build_info); + error_count += check_dll_architecture(pre_build_info.target_architecture, dlls); break; } case Build::LinkageType::STATIC: @@ -805,17 +813,20 @@ namespace vcpkg::PostBuildLint error_count += check_bin_folders_are_not_present_in_static_build(fs, package_dir); - if (!build_info.policies.is_enabled(BuildPolicy::ONLY_RELEASE_CRT)) + if (!toolset.dumpbin.empty()) { + if (!build_info.policies.is_enabled(BuildPolicy::ONLY_RELEASE_CRT)) + { + error_count += check_crt_linkage_of_libs( + BuildType::value_of(Build::ConfigurationType::DEBUG, build_info.crt_linkage), + debug_libs, + toolset.dumpbin); + } error_count += check_crt_linkage_of_libs( - BuildType::value_of(Build::ConfigurationType::DEBUG, build_info.crt_linkage), - debug_libs, + BuildType::value_of(Build::ConfigurationType::RELEASE, build_info.crt_linkage), + release_libs, toolset.dumpbin); } - error_count += check_crt_linkage_of_libs( - BuildType::value_of(Build::ConfigurationType::RELEASE, build_info.crt_linkage), - release_libs, - toolset.dumpbin); break; } default: Checks::unreachable(VCPKG_LINE_INFO); diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index f2b39c110..e62ef8662 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -628,13 +628,8 @@ namespace vcpkg ret.dumpbin = ""; ret.supported_architectures = { ToolsetArchOption{"", System::get_host_processor(), System::get_host_processor()}}; -#if defined(_WIN32) - ret.vcvarsall = "cmd"; - ret.vcvarsall_options = {"/c", "echo done"}; -#else - ret.vcvarsall = "true"; + ret.vcvarsall = ""; ret.vcvarsall_options = {}; -#endif ret.version = "external"; ret.visual_studio_root_path = ""; return ret; -- cgit v1.2.3 From 1bcf4cef0dabd4b25acfb933f181d7f1ae1cc2a2 Mon Sep 17 00:00:00 2001 From: Konstantin Podsvirov Date: Fri, 2 Mar 2018 22:16:49 +0300 Subject: [vcpkg] Allow compilation via CMake with MSVC (#2935) --- toolsrc/CMakeLists.txt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/CMakeLists.txt b/toolsrc/CMakeLists.txt index aa2146111..2a340bb8f 100644 --- a/toolsrc/CMakeLists.txt +++ b/toolsrc/CMakeLists.txt @@ -1,16 +1,20 @@ cmake_minimum_required(VERSION 3.3) project(vcpkg CXX) -add_compile_options(-std=c++1z) - if(CMAKE_COMPILER_IS_GNUXX OR CMAKE_CXX_COMPILER_ID MATCHES "GNU") set(GCC 1) elseif(CMAKE_CXX_COMPILER_ID MATCHES "[Cc]lang") set(CLANG 1) +elseif(MSVC) + add_compile_options(/std:c++latest) else() message(FATAL_ERROR "Unknown compiler: ${CMAKE_CXX_COMPILER_ID}") endif() +if(GCC OR CLANG) + add_compile_options(-std=c++1z) +endif() + file(GLOB_RECURSE VCPKGLIB_SOURCES src/vcpkg/*.cpp) add_executable(vcpkg src/vcpkg.cpp ${VCPKGLIB_SOURCES}) -- cgit v1.2.3 From 709ced580d1af1a0704660e355f5a3f0f06c8899 Mon Sep 17 00:00:00 2001 From: Jacob Zhong Date: Wed, 7 Mar 2018 10:19:24 +0800 Subject: Fix export information --- toolsrc/src/vcpkg/export.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/export.cpp b/toolsrc/src/vcpkg/export.cpp index 831058007..16c84f99d 100644 --- a/toolsrc/src/vcpkg/export.cpp +++ b/toolsrc/src/vcpkg/export.cpp @@ -228,6 +228,7 @@ namespace vcpkg::Export {fs::path{"scripts"} / "getWindowsSDK.ps1"}, {fs::path{"scripts"} / "getProgramFilesPlatformBitness.ps1"}, {fs::path{"scripts"} / "getProgramFiles32bit.ps1"}, + {fs::path{"scripts"} / "VcpkgPowershellUtils.ps1"}, }; for (const fs::path& file : integration_files_relative_to_root) @@ -428,7 +429,7 @@ namespace vcpkg::Export { System::println( System::Color::success, R"(Files exported at: "%s")", raw_exported_dir_path.generic_string()); - print_next_step_info(export_to_path); + print_next_step_info(raw_exported_dir_path); } if (opts.nuget) -- cgit v1.2.3 From 1b4bc5e27eeb037c299d3f57e9bed7e3c20c6d76 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Wed, 7 Mar 2018 15:01:49 -0800 Subject: [vcpkg] Add case for exe path discovery for macos --- toolsrc/src/vcpkg/base/system.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/base/system.cpp b/toolsrc/src/vcpkg/base/system.cpp index f71fd8445..e55db9461 100644 --- a/toolsrc/src/vcpkg/base/system.cpp +++ b/toolsrc/src/vcpkg/base/system.cpp @@ -7,6 +7,10 @@ #include +#if defined(__APPLE__) +# include +#endif + #pragma comment(lib, "Advapi32") namespace vcpkg::System @@ -31,7 +35,15 @@ namespace vcpkg::System const int bytes = GetModuleFileNameW(nullptr, buf, _MAX_PATH); if (bytes == 0) std::abort(); return fs::path(buf, buf + bytes); -#else +#elif __APPLE__ + uint32_t size = 1024 * 32; + char buf[size] = {}; + bool result = _NSGetExecutablePath(buf, &size); + Checks::check_exit(VCPKG_LINE_INFO, result != -1, "Could not determine current executable path."); + std::unique_ptr canonicalPath (realpath(buf, NULL)); + Checks::check_exit(VCPKG_LINE_INFO, result != -1, "Could not determine current executable path."); + return fs::path(std::string(canonicalPath.get())); +#else /* LINUX */ std::array buf; auto written = readlink("/proc/self/exe", buf.data(), buf.size()); Checks::check_exit(VCPKG_LINE_INFO, written != -1, "Could not determine current executable path."); -- cgit v1.2.3 From 965e99cf268b32cc32e0599d99e6c9a1991e95f4 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Thu, 8 Mar 2018 23:51:55 -0800 Subject: [rttr] Fix executables. Fix read-only permissions. --- toolsrc/src/vcpkg/remove.cpp | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/remove.cpp b/toolsrc/src/vcpkg/remove.cpp index 3eaf991ce..32433b234 100644 --- a/toolsrc/src/vcpkg/remove.cpp +++ b/toolsrc/src/vcpkg/remove.cpp @@ -58,7 +58,7 @@ namespace vcpkg::Remove const auto status = fs.status(target, ec); if (ec) { - System::println(System::Color::error, "failed: %s", ec.message()); + System::println(System::Color::error, "failed: status(%s): %s", target.u8string(), ec.message()); continue; } @@ -71,12 +71,23 @@ namespace vcpkg::Remove fs.remove(target, ec); if (ec) { - System::println(System::Color::error, "failed: %s: %s", target.u8string(), ec.message()); +#if defined(_WIN32) + fs::stdfs::permissions(target, fs::stdfs::perms::owner_all | fs::stdfs::perms::group_all, ec); + fs.remove(target, ec); + if (ec) + { + System::println( + System::Color::error, "failed: remove(%s): %s", target.u8string(), ec.message()); + } +#else + System::println( + System::Color::error, "failed: remove(%s): %s", target.u8string(), ec.message()); +#endif } } - else if (!fs::status_known(status)) + else if (!fs::stdfs::exists(status)) { - System::println(System::Color::warning, "Warning: unknown status: %s", target.u8string()); + System::println(System::Color::warning, "Warning: %s: file not found", target.u8string()); } else { -- cgit v1.2.3 From ac8b9a13e40082d24afa1fc06757d25136a35b20 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Tue, 6 Mar 2018 09:55:22 -0800 Subject: [vcpkg] Enable qualifiers to use ! for inversion --- toolsrc/src/vcpkg/sourceparagraph.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/sourceparagraph.cpp b/toolsrc/src/vcpkg/sourceparagraph.cpp index 2a9480538..0b4baf189 100644 --- a/toolsrc/src/vcpkg/sourceparagraph.cpp +++ b/toolsrc/src/vcpkg/sourceparagraph.cpp @@ -202,7 +202,15 @@ namespace vcpkg std::vector ret; for (auto&& dep : deps) { - if (dep.qualifier.empty() || t.canonical_name().find(dep.qualifier) != std::string::npos) + auto qualifiers = Strings::split(dep.qualifier, "&"); + if (std::all_of(qualifiers.begin(), qualifiers.end(), [&](const std::string& qualifier) { + if (qualifier.empty()) return true; + if (qualifier[0] == '!') + { + return t.canonical_name().find(qualifier.substr(1)) == std::string::npos; + } + return t.canonical_name().find(qualifier) != std::string::npos; + })) { ret.emplace_back(dep.name()); } -- cgit v1.2.3 From 63e1e1f7117df20c9fe445ed9db8a808fc611ea4 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Fri, 9 Mar 2018 21:53:29 -0800 Subject: [vcpkg] Fix issue in upgrade dependency resolution where self-referencing features cause cycles --- toolsrc/src/tests.plan.cpp | 30 +++++++++++++++++++++++++++++- toolsrc/src/vcpkg/dependencies.cpp | 2 +- 2 files changed, 30 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/tests.plan.cpp b/toolsrc/src/tests.plan.cpp index 08d3c1dab..95056810c 100644 --- a/toolsrc/src/tests.plan.cpp +++ b/toolsrc/src/tests.plan.cpp @@ -996,6 +996,34 @@ namespace UnitTest1 features_check(&plan[1], "a", {"core", "a1"}); } + + TEST_METHOD(basic_upgrade_scheme_with_self_features) + { + std::vector> pghs; + pghs.push_back(make_status_pgh("a")); + pghs.push_back(make_status_feature_pgh("a", "a1", "")); + pghs.push_back(make_status_feature_pgh("a", "a2", "a[a1]")); + StatusParagraphs status_db(std::move(pghs)); + + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + auto spec_a = spec_map.emplace("a", "", {{"a1", ""}, {"a2", "a[a1]"}}); + + Dependencies::MapPortFileProvider provider(spec_map.map); + Dependencies::PackageGraph graph(provider, status_db); + + graph.upgrade(spec_a); + + auto plan = graph.serialize(); + + Assert::AreEqual(size_t(2), plan.size()); + + Assert::AreEqual("a", plan[0].spec().name().c_str()); + Assert::IsTrue(plan[0].remove_action.has_value()); + + Assert::AreEqual("a", plan[1].spec().name().c_str()); + Assert::IsTrue(plan[1].install_action.has_value()); + Assert::IsTrue(plan[1].install_action.get()->feature_list == std::set{"core", "a1", "a2"}); + } }; class ExportPlanTests : public TestClass @@ -1069,7 +1097,7 @@ namespace UnitTest1 Assert::IsTrue(plan[0].plan_type == Dependencies::ExportPlanType::NOT_BUILT); } - TEST_METHOD(basic_upgrade_scheme_with_features) + TEST_METHOD(basic_export_scheme_with_features) { std::vector> pghs; pghs.push_back(make_status_pgh("b")); diff --git a/toolsrc/src/vcpkg/dependencies.cpp b/toolsrc/src/vcpkg/dependencies.cpp index 1f853014b..1d017a8d3 100644 --- a/toolsrc/src/vcpkg/dependencies.cpp +++ b/toolsrc/src/vcpkg/dependencies.cpp @@ -530,7 +530,7 @@ namespace vcpkg::Dependencies for (auto&& depend : remove_edges_edges) { auto& depend_cluster = graph.get(depend.spec()); - graph_plan.remove_graph.add_edge({&cluster}, {&depend_cluster}); + if (&depend_cluster != &cluster) graph_plan.remove_graph.add_edge({&cluster}, {&depend_cluster}); mark_minus(depend_cluster, graph, graph_plan); } } -- cgit v1.2.3 From 6670b87c18c544bbc9fa167f583b27dc52bce3d9 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Sat, 10 Mar 2018 14:19:07 -0800 Subject: [vcpkg] Add VCPKG_DEFAULT_VS_PATH environment variable --- toolsrc/include/vcpkg/vcpkgpaths.h | 4 +++- toolsrc/src/vcpkg.cpp | 4 +++- toolsrc/src/vcpkg/vcpkgpaths.cpp | 9 +++++++-- 3 files changed, 13 insertions(+), 4 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/vcpkgpaths.h b/toolsrc/include/vcpkg/vcpkgpaths.h index 84e8110ec..71f1bbba9 100644 --- a/toolsrc/include/vcpkg/vcpkgpaths.h +++ b/toolsrc/include/vcpkg/vcpkgpaths.h @@ -33,7 +33,7 @@ namespace vcpkg struct VcpkgPaths { - static Expected create(const fs::path& vcpkg_root_dir); + static Expected create(const fs::path& vcpkg_root_dir, const std::string& default_vs_path); fs::path package_dir(const PackageSpec& spec) const; fs::path port_dir(const PackageSpec& spec) const; @@ -90,5 +90,7 @@ namespace vcpkg Lazy ifw_repogen_exe; Lazy> toolsets; Lazy> toolsets_vs2013; + + fs::path default_vs_path; }; } diff --git a/toolsrc/src/vcpkg.cpp b/toolsrc/src/vcpkg.cpp index ef68e6f72..d9b915367 100644 --- a/toolsrc/src/vcpkg.cpp +++ b/toolsrc/src/vcpkg.cpp @@ -94,7 +94,9 @@ static void inner(const VcpkgCmdArguments& args) Checks::check_exit(VCPKG_LINE_INFO, !vcpkg_root_dir.empty(), "Error: Could not detect vcpkg-root."); - const Expected expected_paths = VcpkgPaths::create(vcpkg_root_dir); + auto default_vs_path = System::get_environment_variable("VCPKG_DEFAULT_VS_PATH").value_or(""); + + const Expected expected_paths = VcpkgPaths::create(vcpkg_root_dir, default_vs_path); Checks::check_exit(VCPKG_LINE_INFO, !expected_paths.error(), "Error: Invalid vcpkg root directory %s: %s", diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index e62ef8662..02bc5f041 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -293,7 +293,7 @@ namespace vcpkg return fetch_tool(paths.scripts, "installerbase", TOOL_DATA); } - Expected VcpkgPaths::create(const fs::path& vcpkg_root_dir) + Expected VcpkgPaths::create(const fs::path& vcpkg_root_dir, const std::string& default_vs_path) { std::error_code ec; const fs::path canonical_vcpkg_root_dir = fs::stdfs::canonical(vcpkg_root_dir, ec); @@ -304,6 +304,7 @@ namespace vcpkg VcpkgPaths paths; paths.root = canonical_vcpkg_root_dir; + paths.default_vs_path = default_vs_path; if (paths.root.empty()) { @@ -643,7 +644,11 @@ namespace vcpkg std::vector candidates = Util::element_pointers(vs_toolsets); const auto tsv = prebuildinfo.platform_toolset.get(); - const auto vsp = prebuildinfo.visual_studio_path.get(); + auto vsp = prebuildinfo.visual_studio_path.get(); + if (!vsp && !default_vs_path.empty()) + { + vsp = &default_vs_path; + } if (tsv && vsp) { -- cgit v1.2.3 From ad7fa55bb004571bc7d2aad337dda978fe4d2bac Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Tue, 6 Mar 2018 09:57:37 -0800 Subject: [vcpkg] Improve handling of external toolchains. Extract MSVC settings to a separate toolchain file. --- toolsrc/src/vcpkg/build.cpp | 1 + toolsrc/src/vcpkg/vcpkgpaths.cpp | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index 5870bd187..aa84b6cf5 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -209,6 +209,7 @@ namespace vcpkg::Build std::string make_build_env_cmd(const PreBuildInfo& pre_build_info, const Toolset& toolset) { if (pre_build_info.external_toolchain_file.has_value()) return ""; + if (!pre_build_info.cmake_system_name.empty() && pre_build_info.cmake_system_name != "WindowsStore") return ""; const char* tonull = " >nul"; if (GlobalState::debugging) diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index 02bc5f041..46e80c4a9 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -622,7 +622,8 @@ namespace vcpkg const Toolset& VcpkgPaths::get_toolset(const Build::PreBuildInfo& prebuildinfo) const { - if (prebuildinfo.external_toolchain_file) + if (prebuildinfo.external_toolchain_file || + (!prebuildinfo.cmake_system_name.empty() && prebuildinfo.cmake_system_name != "WindowsStore")) { static Toolset external_toolset = []() -> Toolset { Toolset ret; -- cgit v1.2.3 From 81b58d1868a0f7edf324b2f366426e2973ac80b7 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Fri, 9 Mar 2018 03:51:19 -0800 Subject: [vcpkg] Use unzip/zip on non-windows --- toolsrc/src/vcpkg/build.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index aa84b6cf5..408dde798 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -438,10 +438,15 @@ namespace vcpkg::Build auto files = fs.get_files_non_recursive(pkg_path); Checks::check_exit(VCPKG_LINE_INFO, files.empty(), "unable to clear path: %s", pkg_path.u8string()); +#if defined(_WIN32) auto&& _7za = paths.get_7za_exe(); System::cmd_execute_clean(Strings::format( R"("%s" x "%s" -o"%s" -y >nul)", _7za.u8string(), archive_path.u8string(), pkg_path.u8string())); +#else + System::cmd_execute_clean(Strings::format( + R"(unzip -qq "%s" "-d%s")", archive_path.u8string(), pkg_path.u8string())); +#endif auto maybe_bcf = Paragraphs::try_load_cached_control_package(paths, spec); bcf = std::make_unique(std::move(maybe_bcf).value_or_exit(VCPKG_LINE_INFO)); @@ -538,6 +543,7 @@ namespace vcpkg::Build !fs.exists(tmp_archive_path), "Could not remove file: %s", tmp_archive_path.u8string()); +#if defined(_WIN32) auto&& _7za = paths.get_7za_exe(); System::cmd_execute_clean(Strings::format( @@ -545,7 +551,12 @@ namespace vcpkg::Build _7za.u8string(), tmp_archive_path.u8string(), paths.package_dir(spec).u8string())); - +#else + System::cmd_execute_clean(Strings::format( + R"(cd '%s' && zip --quiet -r '%s' *)", + paths.package_dir(spec).u8string(), + tmp_archive_path.u8string())); +#endif fs.create_directories(archives_dir, ec); fs.rename(tmp_archive_path, archive_path); -- cgit v1.2.3 From 81b9ab1291bd322b5de8ad0cec2f21ce4d828a28 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Tue, 13 Mar 2018 04:26:00 -0700 Subject: [vcpkg] Refactor do_build_package and add archive tombstoning --- toolsrc/include/vcpkg/paragraphs.h | 2 +- toolsrc/src/vcpkg/build.cpp | 238 ++++++++++++++++++++----------------- toolsrc/src/vcpkg/install.cpp | 2 +- toolsrc/src/vcpkg/paragraphs.cpp | 2 +- 4 files changed, 132 insertions(+), 112 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/paragraphs.h b/toolsrc/include/vcpkg/paragraphs.h index e2c7f2d99..fa0265b75 100644 --- a/toolsrc/include/vcpkg/paragraphs.h +++ b/toolsrc/include/vcpkg/paragraphs.h @@ -20,7 +20,7 @@ namespace vcpkg::Paragraphs Parse::ParseExpected try_load_port(const Files::Filesystem& fs, const fs::path& control_path); - Expected try_load_cached_control_package(const VcpkgPaths& paths, const PackageSpec& spec); + Expected try_load_cached_package(const VcpkgPaths& paths, const PackageSpec& spec); struct LoadResults { diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index 408dde798..7abd5ae0a 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -315,8 +315,90 @@ namespace vcpkg::Build } static ExtendedBuildResult do_build_package(const VcpkgPaths& paths, + const PreBuildInfo& pre_build_info, + const PackageSpec& spec, + const std::string& abi_tag, const BuildPackageConfig& config, const StatusParagraphs& status_db) + { + auto& fs = paths.get_filesystem(); + const Triplet& triplet = spec.triplet(); + + const fs::path& cmake_exe_path = paths.get_cmake_exe(); + const fs::path& git_exe_path = paths.get_git_exe(); + + std::string all_features; + for (auto& feature : config.scf.feature_paragraphs) + { + all_features.append(feature->name + ";"); + } + + const Toolset& toolset = paths.get_toolset(pre_build_info); + const std::string cmd_launch_cmake = System::make_cmake_cmd( + cmake_exe_path, + paths.ports_cmake, + { + {"CMD", "BUILD"}, + {"PORT", config.scf.core_paragraph->name}, + {"CURRENT_PORT_DIR", config.port_dir / "/."}, + {"TARGET_TRIPLET", spec.triplet().canonical_name()}, + {"VCPKG_PLATFORM_TOOLSET", toolset.version.c_str()}, + {"VCPKG_USE_HEAD_VERSION", + Util::Enum::to_bool(config.build_package_options.use_head_version) ? "1" : "0"}, + {"_VCPKG_NO_DOWNLOADS", !Util::Enum::to_bool(config.build_package_options.allow_downloads) ? "1" : "0"}, + {"GIT", git_exe_path}, + {"FEATURES", Strings::join(";", config.feature_list)}, + {"ALL_FEATURES", all_features}, + }); + + auto command = make_build_env_cmd(pre_build_info, toolset); + if (!command.empty()) command.append(" && "); + command.append(cmd_launch_cmake); + + const auto timer = Chrono::ElapsedTimer::create_started(); + + const int return_code = System::cmd_execute_clean(command); + const auto buildtimeus = timer.microseconds(); + const auto spec_string = spec.to_string(); + + { + auto locked_metrics = Metrics::g_metrics.lock(); + locked_metrics->track_buildtime(spec.to_string() + ":[" + Strings::join(",", config.feature_list) + "]", + buildtimeus); + if (return_code != 0) + { + locked_metrics->track_property("error", "build failed"); + locked_metrics->track_property("build_error", spec_string); + return BuildResult::BUILD_FAILED; + } + } + + const BuildInfo build_info = read_build_info(fs, paths.build_info_file_path(spec)); + const size_t error_count = PostBuildLint::perform_all_checks(spec, paths, pre_build_info, build_info); + + auto bcf = create_binary_control_file(*config.scf.core_paragraph, triplet, build_info, abi_tag); + + if (error_count != 0) + { + return BuildResult::POST_BUILD_CHECKS_FAILED; + } + for (auto&& feature : config.feature_list) + { + for (auto&& f_pgh : config.scf.feature_paragraphs) + { + if (f_pgh->name == feature) + bcf->features.push_back( + create_binary_feature_control_file(*config.scf.core_paragraph, *f_pgh, triplet)); + } + } + + write_binary_control_file(paths, *bcf); + return {BuildResult::SUCCEEDED, std::move(bcf)}; + } + + ExtendedBuildResult build_package(const VcpkgPaths& paths, + const BuildPackageConfig& config, + const StatusParagraphs& status_db) { auto& fs = paths.get_filesystem(); const Triplet& triplet = config.triplet; @@ -359,9 +441,6 @@ namespace vcpkg::Build } const fs::path& cmake_exe_path = paths.get_cmake_exe(); - const fs::path& git_exe_path = paths.get_git_exe(); - - const fs::path ports_cmake_script_path = paths.ports_cmake; if (GlobalState::g_binary_caching) { @@ -420,124 +499,66 @@ namespace vcpkg::Build std::unique_ptr bcf; - auto archives_dir = paths.root / "archives"; - if (!abi_tag.empty()) - { - archives_dir /= abi_tag.substr(0, 2); - } - auto archive_path = archives_dir / (abi_tag + ".zip"); + auto archives_root_dir = paths.root / "archives"; + auto archive_name = abi_tag + ".zip"; + auto archive_subpath = abi_tag.empty() ? fs::path() : fs::u8path(abi_tag.substr(0, 2)) / archive_name; + auto archive_path = archives_root_dir / archive_subpath; + auto archive_tombstone_path = archives_root_dir / "fail" / archive_subpath; - if (GlobalState::g_binary_caching && !abi_tag.empty() && fs.exists(archive_path)) + auto found_archive = false; + + if (GlobalState::g_binary_caching && !abi_tag.empty()) { - System::println("Using cached binary package: %s", archive_path.u8string()); + if (fs.exists(archive_path)) + { + System::println("Using cached binary package: %s", archive_path.u8string()); - auto pkg_path = paths.package_dir(spec); - std::error_code ec; - fs.remove_all(pkg_path, ec); - fs.create_directories(pkg_path, ec); - auto files = fs.get_files_non_recursive(pkg_path); - Checks::check_exit(VCPKG_LINE_INFO, files.empty(), "unable to clear path: %s", pkg_path.u8string()); + auto pkg_path = paths.package_dir(spec); + std::error_code ec; + fs.remove_all(pkg_path, ec); + fs.create_directories(pkg_path, ec); + auto files = fs.get_files_non_recursive(pkg_path); + Checks::check_exit(VCPKG_LINE_INFO, files.empty(), "unable to clear path: %s", pkg_path.u8string()); #if defined(_WIN32) - auto&& _7za = paths.get_7za_exe(); + auto&& _7za = paths.get_7za_exe(); - System::cmd_execute_clean(Strings::format( - R"("%s" x "%s" -o"%s" -y >nul)", _7za.u8string(), archive_path.u8string(), pkg_path.u8string())); + System::cmd_execute_clean(Strings::format( + R"("%s" x "%s" -o"%s" -y >nul)", _7za.u8string(), archive_path.u8string(), pkg_path.u8string())); #else - System::cmd_execute_clean(Strings::format( - R"(unzip -qq "%s" "-d%s")", archive_path.u8string(), pkg_path.u8string())); + System::cmd_execute_clean(Strings::format( + R"(unzip -qq "%s" "-d%s")", archive_path.u8string(), pkg_path.u8string())); #endif - auto maybe_bcf = Paragraphs::try_load_cached_control_package(paths, spec); - bcf = std::make_unique(std::move(maybe_bcf).value_or_exit(VCPKG_LINE_INFO)); - } - else - { - if (GlobalState::g_binary_caching && !abi_tag.empty()) - { - System::println("Could not locate cached archive: %s", archive_path.u8string()); + auto maybe_bcf = Paragraphs::try_load_cached_package(paths, spec); + bcf = std::make_unique(std::move(maybe_bcf).value_or_exit(VCPKG_LINE_INFO)); + found_archive = true; + return {BuildResult::SUCCEEDED, std::move(bcf)}; } - - std::string all_features; - for (auto& feature : config.scf.feature_paragraphs) + else if (fs.exists(archive_tombstone_path)) { - all_features.append(feature->name + ";"); - } - - const Toolset& toolset = paths.get_toolset(pre_build_info); - const std::string cmd_launch_cmake = System::make_cmake_cmd( - cmake_exe_path, - ports_cmake_script_path, - { - {"CMD", "BUILD"}, - {"PORT", config.scf.core_paragraph->name}, - {"CURRENT_PORT_DIR", config.port_dir / "/."}, - {"TARGET_TRIPLET", triplet.canonical_name()}, - {"VCPKG_PLATFORM_TOOLSET", toolset.version.c_str()}, - {"VCPKG_USE_HEAD_VERSION", - Util::Enum::to_bool(config.build_package_options.use_head_version) ? "1" : "0"}, - {"_VCPKG_NO_DOWNLOADS", - !Util::Enum::to_bool(config.build_package_options.allow_downloads) ? "1" : "0"}, - {"GIT", git_exe_path}, - {"FEATURES", features}, - {"ALL_FEATURES", all_features}, - }); - - auto command = make_build_env_cmd(pre_build_info, toolset); - if (!command.empty()) command.append(" && "); - command.append(cmd_launch_cmake); - - const auto timer = Chrono::ElapsedTimer::create_started(); - - const int return_code = System::cmd_execute_clean(command); - const auto buildtimeus = timer.microseconds(); - const auto spec_string = spec.to_string(); - - { - auto locked_metrics = Metrics::g_metrics.lock(); - locked_metrics->track_buildtime(spec.to_string() + ":[" + Strings::join(",", config.feature_list) + "]", - buildtimeus); - if (return_code != 0) - { - locked_metrics->track_property("error", "build failed"); - locked_metrics->track_property("build_error", spec_string); - return BuildResult::BUILD_FAILED; - } + System::println("Found failure tombstone: %s", archive_tombstone_path.u8string()); + return BuildResult::BUILD_FAILED; } + } - const BuildInfo build_info = read_build_info(fs, paths.build_info_file_path(spec)); - const size_t error_count = PostBuildLint::perform_all_checks(spec, paths, pre_build_info, build_info); + if (GlobalState::g_binary_caching && !abi_tag.empty()) + { + System::println("Could not locate cached archive: %s", archive_path.u8string()); + } - bcf = create_binary_control_file(*config.scf.core_paragraph, triplet, build_info, abi_tag); + ExtendedBuildResult result = do_build_package(paths, pre_build_info, spec, abi_tag, config, status_db); - if (error_count != 0) - { - return BuildResult::POST_BUILD_CHECKS_FAILED; - } - for (auto&& feature : config.feature_list) + if (GlobalState::g_binary_caching && !abi_tag.empty()) + { + if (result.code == BuildResult::SUCCEEDED) { - for (auto&& f_pgh : config.scf.feature_paragraphs) - { - if (f_pgh->name == feature) - bcf->features.push_back( - create_binary_feature_control_file(*config.scf.core_paragraph, *f_pgh, triplet)); - } - } + auto tmp_archive_path = paths.buildtrees / spec.name() / (triplet.to_string() + ".zip"); - if (GlobalState::g_binary_caching && !abi_tag.empty()) - { std::error_code ec; fs.write_contents( paths.package_dir(spec) / "share" / spec.name() / "vcpkg_abi_info.txt", full_abi_info, ec); - } - - write_binary_control_file(paths, *bcf); - if (GlobalState::g_binary_caching && !abi_tag.empty()) - { - auto tmp_archive_path = paths.buildtrees / spec.name() / (spec.triplet().to_string() + ".zip"); - - std::error_code ec; fs.remove(tmp_archive_path, ec); Checks::check_exit(VCPKG_LINE_INFO, !fs.exists(tmp_archive_path), @@ -557,21 +578,20 @@ namespace vcpkg::Build paths.package_dir(spec).u8string(), tmp_archive_path.u8string())); #endif - fs.create_directories(archives_dir, ec); + fs.create_directories(archive_path.parent_path(), ec); fs.rename(tmp_archive_path, archive_path); System::println("Stored binary cache: %s", archive_path.u8string()); } + else if (result.code == BuildResult::BUILD_FAILED || result.code == BuildResult::POST_BUILD_CHECKS_FAILED) + { + // Build failed, so store failure archive + std::error_code ec; + fs.create_directories(archive_tombstone_path.parent_path(), ec); + fs.write_contents(archive_tombstone_path, "", ec); + } } - return {BuildResult::SUCCEEDED, std::move(bcf)}; - } - - ExtendedBuildResult build_package(const VcpkgPaths& paths, - const BuildPackageConfig& config, - const StatusParagraphs& status_db) - { - ExtendedBuildResult result = do_build_package(paths, config, status_db); if (config.build_package_options.clean_buildtrees == CleanBuildtrees::YES) { diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp index 46c7c53b8..7d36fba82 100644 --- a/toolsrc/src/vcpkg/install.cpp +++ b/toolsrc/src/vcpkg/install.cpp @@ -306,7 +306,7 @@ namespace vcpkg::Install System::println("Building package %s... done", display_name_with_features); auto bcf = std::make_unique( - Paragraphs::try_load_cached_control_package(paths, action.spec).value_or_exit(VCPKG_LINE_INFO)); + Paragraphs::try_load_cached_package(paths, action.spec).value_or_exit(VCPKG_LINE_INFO)); auto code = aux_install(display_name_with_features, *bcf); if (action.build_options.clean_packages == Build::CleanPackages::YES) diff --git a/toolsrc/src/vcpkg/paragraphs.cpp b/toolsrc/src/vcpkg/paragraphs.cpp index b66d53994..d0b0c0abf 100644 --- a/toolsrc/src/vcpkg/paragraphs.cpp +++ b/toolsrc/src/vcpkg/paragraphs.cpp @@ -228,7 +228,7 @@ namespace vcpkg::Paragraphs return error_info; } - Expected try_load_cached_control_package(const VcpkgPaths& paths, const PackageSpec& spec) + Expected try_load_cached_package(const VcpkgPaths& paths, const PackageSpec& spec) { Expected>> pghs = get_paragraphs(paths.get_filesystem(), paths.package_dir(spec) / "CONTROL"); -- cgit v1.2.3 From 9336d5ea84f597fa508cbf6a70e591402d210984 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Tue, 13 Mar 2018 05:21:17 -0700 Subject: [vcpkg] Link pthreads --- toolsrc/CMakeLists.txt | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/CMakeLists.txt b/toolsrc/CMakeLists.txt index 2a340bb8f..da0f41631 100644 --- a/toolsrc/CMakeLists.txt +++ b/toolsrc/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.3) -project(vcpkg CXX) +project(vcpkg C CXX) if(CMAKE_COMPILER_IS_GNUXX OR CMAKE_CXX_COMPILER_ID MATCHES "GNU") set(GCC 1) @@ -19,10 +19,14 @@ file(GLOB_RECURSE VCPKGLIB_SOURCES src/vcpkg/*.cpp) add_executable(vcpkg src/vcpkg.cpp ${VCPKGLIB_SOURCES}) target_compile_definitions(vcpkg PRIVATE -DDISABLE_METRICS=0) -target_include_directories(vcpkg PUBLIC include) +target_include_directories(vcpkg PRIVATE include) if(GCC) - target_link_libraries(vcpkg PUBLIC stdc++fs) + target_link_libraries(vcpkg PRIVATE stdc++fs) elseif(CLANG) - target_link_libraries(vcpkg PUBLIC c++experimental) + target_link_libraries(vcpkg PRIVATE c++experimental) endif() + +set(THREADS_PREFER_PTHREAD_FLAG ON) +find_package(Threads REQUIRED) +target_link_libraries(vcpkg PRIVATE Threads::Threads) -- cgit v1.2.3 From f72b46690a89a7e19563f93f0eaa5f8a21184254 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Tue, 13 Mar 2018 06:25:59 -0700 Subject: [vcpkg] Silence warnings on recent clang --- toolsrc/include/pch.h | 4 ++++ toolsrc/src/vcpkg/metrics.cpp | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/include/pch.h b/toolsrc/include/pch.h index 683bef171..9c9deeb3f 100644 --- a/toolsrc/include/pch.h +++ b/toolsrc/include/pch.h @@ -46,7 +46,11 @@ #include #include #include +#if defined(_WIN32) #include +#else +#include +#endif #include #include #include diff --git a/toolsrc/src/vcpkg/metrics.cpp b/toolsrc/src/vcpkg/metrics.cpp index d49cadbe2..9e17b237d 100644 --- a/toolsrc/src/vcpkg/metrics.cpp +++ b/toolsrc/src/vcpkg/metrics.cpp @@ -92,7 +92,7 @@ namespace vcpkg::Metrics { encoded.append("\\\""); } - else if (ch < 0x20 || ch >= 0x80) + else if (ch < 0x20 || static_cast(ch) >= 0x80) { // Note: this treats incoming Strings as Latin-1 static constexpr const char HEX[16] = { -- cgit v1.2.3 From 50a93f01970e499f35edbb57ce0328baeb465635 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Tue, 13 Mar 2018 07:32:51 -0700 Subject: [vcpkg] Fix get_executable_path on BSD --- toolsrc/src/vcpkg/base/system.cpp | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/base/system.cpp b/toolsrc/src/vcpkg/base/system.cpp index e55db9461..e24098f97 100644 --- a/toolsrc/src/vcpkg/base/system.cpp +++ b/toolsrc/src/vcpkg/base/system.cpp @@ -8,7 +8,11 @@ #include #if defined(__APPLE__) -# include +#include +#endif + +#if defined(__FreeBSD__) +#include #endif #pragma comment(lib, "Advapi32") @@ -35,14 +39,22 @@ namespace vcpkg::System const int bytes = GetModuleFileNameW(nullptr, buf, _MAX_PATH); if (bytes == 0) std::abort(); return fs::path(buf, buf + bytes); -#elif __APPLE__ +#elif defined(__APPLE__) uint32_t size = 1024 * 32; char buf[size] = {}; bool result = _NSGetExecutablePath(buf, &size); Checks::check_exit(VCPKG_LINE_INFO, result != -1, "Could not determine current executable path."); - std::unique_ptr canonicalPath (realpath(buf, NULL)); + std::unique_ptr canonicalPath(realpath(buf, NULL)); Checks::check_exit(VCPKG_LINE_INFO, result != -1, "Could not determine current executable path."); return fs::path(std::string(canonicalPath.get())); +#elif defined(__FreeBSD__) + int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1}; + char exePath[2048]; + size_t len = sizeof(exePath); + auto rcode = sysctl(mib, 4, exePath, &len, NULL, 0); + Checks::check_exit(VCPKG_LINE_INFO, rcode == 0, "Could not determine current executable path."); + Checks::check_exit(VCPKG_LINE_INFO, len > 0, "Could not determine current executable path."); + return fs::path(exePath, exePath + len - 1); #else /* LINUX */ std::array buf; auto written = readlink("/proc/self/exe", buf.data(), buf.size()); -- cgit v1.2.3 From 3c7997215bc2e44125912fb7aae672f1b63944a8 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Tue, 13 Mar 2018 11:06:22 -0700 Subject: [vcpkg] Improve default triplets for non-windows --- toolsrc/include/vcpkg/base/strings.h | 2 +- toolsrc/src/vcpkg.cpp | 8 ++++++++ toolsrc/src/vcpkg/base/strings.cpp | 7 +++---- 3 files changed, 12 insertions(+), 5 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/base/strings.h b/toolsrc/include/vcpkg/base/strings.h index 6ef840fb3..6294853af 100644 --- a/toolsrc/include/vcpkg/base/strings.h +++ b/toolsrc/include/vcpkg/base/strings.h @@ -46,7 +46,7 @@ namespace vcpkg::Strings bool case_insensitive_ascii_equals(const CStringView left, const CStringView right); - std::string ascii_to_lowercase(const std::string& input); + std::string ascii_to_lowercase(std::string input); bool case_insensitive_ascii_starts_with(const std::string& s, const std::string& pattern); diff --git a/toolsrc/src/vcpkg.cpp b/toolsrc/src/vcpkg.cpp index d9b915367..a65045aa8 100644 --- a/toolsrc/src/vcpkg.cpp +++ b/toolsrc/src/vcpkg.cpp @@ -157,7 +157,15 @@ static void inner(const VcpkgCmdArguments& args) } else { +#if defined(_WIN32) default_triplet = Triplet::X86_WINDOWS; +#elif defined(__APPLE__) + default_triplet = Triplet::from_canonical_name("x64-osx"); +#elif defined(__FreeBSD__) + default_triplet = Triplet::from_canonical_name("x64-freebsd"); +#else + default_triplet = Triplet::from_canonical_name("x64-linux"); +#endif } } diff --git a/toolsrc/src/vcpkg/base/strings.cpp b/toolsrc/src/vcpkg/base/strings.cpp index d912734e3..a08512c9f 100644 --- a/toolsrc/src/vcpkg/base/strings.cpp +++ b/toolsrc/src/vcpkg/base/strings.cpp @@ -108,11 +108,10 @@ namespace vcpkg::Strings #endif } - std::string ascii_to_lowercase(const std::string& input) + std::string ascii_to_lowercase(std::string s) { - std::string output(input); - std::transform(output.begin(), output.end(), output.begin(), &details::tolower_char); - return output; + std::transform(s.begin(), s.end(), s.begin(), &details::tolower_char); + return s; } bool case_insensitive_ascii_starts_with(const std::string& s, const std::string& pattern) -- cgit v1.2.3 From 90c4b8dbb7a69584a4a36c67e4982cf086b7c578 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Wed, 14 Mar 2018 04:33:14 -0700 Subject: [vcpkg] Further refactoring inside `build_package()` --- toolsrc/include/vcpkg/commands.h | 2 +- toolsrc/src/vcpkg/build.cpp | 320 ++++++++++++++++++++---------------- toolsrc/src/vcpkg/commands.ci.cpp | 21 ++- toolsrc/src/vcpkg/commands.hash.cpp | 8 +- 4 files changed, 202 insertions(+), 149 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/commands.h b/toolsrc/include/vcpkg/commands.h index 4027e12f4..b6b1c56ab 100644 --- a/toolsrc/include/vcpkg/commands.h +++ b/toolsrc/include/vcpkg/commands.h @@ -120,7 +120,7 @@ namespace vcpkg::Commands namespace Hash { void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); - std::string get_file_hash(fs::path const& cmake_exe_path, fs::path const& path, std::string const& hash_type); + std::string get_file_hash(const VcpkgPaths& paths, fs::path const& path, std::string const& hash_type); } template diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index 7abd5ae0a..99ae5d2a3 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -396,23 +396,160 @@ namespace vcpkg::Build return {BuildResult::SUCCEEDED, std::move(bcf)}; } - ExtendedBuildResult build_package(const VcpkgPaths& paths, - const BuildPackageConfig& config, - const StatusParagraphs& status_db) + static ExtendedBuildResult do_build_package_and_clean_buildtrees(const VcpkgPaths& paths, + const PreBuildInfo& pre_build_info, + const PackageSpec& spec, + const std::string& abi_tag, + const BuildPackageConfig& config, + const StatusParagraphs& status_db) { + auto result = do_build_package(paths, pre_build_info, spec, abi_tag, config, status_db); + + if (config.build_package_options.clean_buildtrees == CleanBuildtrees::YES) + { + auto& fs = paths.get_filesystem(); + const fs::path buildtrees_dir = paths.buildtrees / config.scf.core_paragraph->name; + auto buildtree_files = fs.get_files_non_recursive(buildtrees_dir); + for (auto&& file : buildtree_files) + { + if (fs.is_directory(file) && file.filename() != "src") + { + std::error_code ec; + fs.remove_all(file, ec); + } + } + } + + return result; + } + + struct AbiEntry + { + std::string key; + std::string value; + }; + + struct AbiTagAndFile + { + std::string tag; + fs::path tag_file; + }; + + static Optional compute_abi_tag(const VcpkgPaths& paths, + const BuildPackageConfig& config, + const PreBuildInfo& pre_build_info, + Span dependency_abis) + { + if (!GlobalState::g_binary_caching) return nullopt; + auto& fs = paths.get_filesystem(); const Triplet& triplet = config.triplet; + const std::string& name = config.scf.core_paragraph->name; + + std::vector abi_tag_entries; + + abi_tag_entries.insert(abi_tag_entries.end(), dependency_abis.begin(), dependency_abis.end()); + + abi_tag_entries.emplace_back( + AbiEntry{"portfile", Commands::Hash::get_file_hash(paths, config.port_dir / "portfile.cmake", "SHA1")}); + abi_tag_entries.emplace_back( + AbiEntry{"control", Commands::Hash::get_file_hash(paths, config.port_dir / "CONTROL", "SHA1")}); + + abi_tag_entries.emplace_back(AbiEntry{"triplet", pre_build_info.triplet_abi_tag}); + + std::string features = Strings::join(";", config.feature_list); + abi_tag_entries.emplace_back(AbiEntry{"features", features}); - struct AbiEntry + if (config.build_package_options.use_head_version == UseHeadVersion::YES) + abi_tag_entries.emplace_back(AbiEntry{"head", ""}); + + std::string full_abi_info = + Strings::join("", abi_tag_entries, [](const AbiEntry& p) { return p.key + " " + p.value + "\n"; }); + + if (GlobalState::debugging) { - std::string key; - std::string value; - }; + System::println("[DEBUG] "); + for (auto&& entry : abi_tag_entries) + { + System::println("[DEBUG] %s|%s", entry.key, entry.value); + } + System::println("[DEBUG] "); + } - std::vector abi_tag_entries; + auto abi_tag_entries_missing = abi_tag_entries; + Util::stable_keep_if(abi_tag_entries_missing, [](const AbiEntry& p) { return p.value.empty(); }); - const PackageSpec spec = - PackageSpec::from_name_and_triplet(config.scf.core_paragraph->name, triplet).value_or_exit(VCPKG_LINE_INFO); + if (abi_tag_entries_missing.empty()) + { + std::error_code ec; + fs.create_directories(paths.buildtrees / name, ec); + auto abi_file_path = paths.buildtrees / name / (triplet.canonical_name() + ".vcpkg_abi_info.txt"); + fs.write_contents(abi_file_path, full_abi_info); + + return AbiTagAndFile{Commands::Hash::get_file_hash(paths, abi_file_path, "SHA1"), abi_file_path}; + } + else + { + System::println( + "Warning: binary caching disabled because abi keys are missing values:\n%s", + Strings::join("", abi_tag_entries_missing, [](const AbiEntry& e) { return " " + e.key + "\n"; })); + + return nullopt; + } + } + + static void decompress_archive(const VcpkgPaths& paths, const PackageSpec& spec, const fs::path& archive_path) + { + auto& fs = paths.get_filesystem(); + + auto pkg_path = paths.package_dir(spec); + std::error_code ec; + fs.remove_all(pkg_path, ec); + fs.create_directories(pkg_path, ec); + auto files = fs.get_files_non_recursive(pkg_path); + Checks::check_exit(VCPKG_LINE_INFO, files.empty(), "unable to clear path: %s", pkg_path.u8string()); + +#if defined(_WIN32) + auto&& _7za = paths.get_7za_exe(); + + System::cmd_execute_clean(Strings::format( + R"("%s" x "%s" -o"%s" -y >nul)", _7za.u8string(), archive_path.u8string(), pkg_path.u8string())); +#else + System::cmd_execute_clean(Strings::format( + R"(unzip -qq "%s" "-d%s")", archive_path.u8string(), pkg_path.u8string())); +#endif + } + + static void compress_archive(const VcpkgPaths& paths, const PackageSpec& spec, const fs::path& tmp_archive_path) + { + auto& fs = paths.get_filesystem(); + + std::error_code ec; + + fs.remove(tmp_archive_path, ec); + Checks::check_exit( + VCPKG_LINE_INFO, !fs.exists(tmp_archive_path), "Could not remove file: %s", tmp_archive_path.u8string()); +#if defined(_WIN32) + auto&& _7za = paths.get_7za_exe(); + + System::cmd_execute_clean(Strings::format( + R"("%s" a "%s" "%s\*" >nul)", + _7za.u8string(), + tmp_archive_path.u8string(), + paths.package_dir(spec).u8string())); +#else + System::cmd_execute_clean(Strings::format( + R"(cd '%s' && zip --quiet -r '%s' *)", paths.package_dir(spec).u8string(), tmp_archive_path.u8string())); +#endif + } + + ExtendedBuildResult build_package(const VcpkgPaths& paths, + const BuildPackageConfig& config, + const StatusParagraphs& status_db) + { + auto& fs = paths.get_filesystem(); + const Triplet& triplet = config.triplet; + const std::string& name = config.scf.core_paragraph->name; std::vector required_fspecs = compute_required_feature_specs(config, status_db); @@ -422,7 +559,7 @@ namespace vcpkg::Build // Find all features that aren't installed. This destroys required_fspecs. Util::unstable_keep_if(required_fspecs, [&](FeatureSpec const& fspec) { - return !status_db.is_installed(fspec) && fspec.name() != spec.name(); + return !status_db.is_installed(fspec) && fspec.name() != name; }); if (!required_fspecs.empty()) @@ -430,109 +567,45 @@ namespace vcpkg::Build return {BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES, std::move(required_fspecs)}; } + const PackageSpec spec = + PackageSpec::from_name_and_triplet(config.scf.core_paragraph->name, triplet).value_or_exit(VCPKG_LINE_INFO); + + std::vector dependency_abis; + // dep_pspecs was not destroyed for (auto&& pspec : dep_pspecs) { if (pspec == spec) continue; auto status_it = status_db.find_installed(pspec); Checks::check_exit(VCPKG_LINE_INFO, status_it != status_db.end()); - abi_tag_entries.emplace_back( + dependency_abis.emplace_back( AbiEntry{status_it->get()->package.spec.name(), status_it->get()->package.abi}); } - const fs::path& cmake_exe_path = paths.get_cmake_exe(); - - if (GlobalState::g_binary_caching) - { - abi_tag_entries.emplace_back(AbiEntry{ - "portfile", Commands::Hash::get_file_hash(cmake_exe_path, config.port_dir / "portfile.cmake", "SHA1")}); - abi_tag_entries.emplace_back(AbiEntry{ - "control", Commands::Hash::get_file_hash(cmake_exe_path, config.port_dir / "CONTROL", "SHA1")}); - } - const auto pre_build_info = PreBuildInfo::from_triplet_file(paths, triplet); - abi_tag_entries.emplace_back(AbiEntry{"triplet", pre_build_info.triplet_abi_tag}); - std::string features = Strings::join(";", config.feature_list); - abi_tag_entries.emplace_back(AbiEntry{"features", features}); - - if (config.build_package_options.use_head_version == UseHeadVersion::YES) - abi_tag_entries.emplace_back(AbiEntry{"head", ""}); - - std::string full_abi_info = - Strings::join("", abi_tag_entries, [](const AbiEntry& p) { return p.key + " " + p.value + "\n"; }); - - std::string abi_tag; - - if (GlobalState::g_binary_caching) - { - if (GlobalState::debugging) - { - System::println("[DEBUG] "); - for (auto&& entry : abi_tag_entries) - { - System::println("[DEBUG] %s|%s", entry.key, entry.value); - } - System::println("[DEBUG] "); - } - - auto abi_tag_entries_missing = abi_tag_entries; - Util::stable_keep_if(abi_tag_entries_missing, [](const AbiEntry& p) { return p.value.empty(); }); - - if (abi_tag_entries_missing.empty()) - { - std::error_code ec; - fs.create_directories(paths.buildtrees / spec.name(), ec); - auto abi_file_path = paths.buildtrees / spec.name() / "vcpkg_abi_info"; - fs.write_contents(abi_file_path, full_abi_info); - - abi_tag = Commands::Hash::get_file_hash(paths.get_cmake_exe(), abi_file_path, "SHA1"); - } - else - { - System::println("Warning: binary caching disabled because abi keys are missing values:\n%s", - Strings::join("", abi_tag_entries_missing, [](const AbiEntry& e) { - return " " + e.key + "\n"; - })); - } - } + auto abi_tag_and_file = compute_abi_tag(paths, config, pre_build_info, dependency_abis); std::unique_ptr bcf; - auto archives_root_dir = paths.root / "archives"; - auto archive_name = abi_tag + ".zip"; - auto archive_subpath = abi_tag.empty() ? fs::path() : fs::u8path(abi_tag.substr(0, 2)) / archive_name; - auto archive_path = archives_root_dir / archive_subpath; - auto archive_tombstone_path = archives_root_dir / "fail" / archive_subpath; + auto maybe_abi_tag_and_file = abi_tag_and_file.get(); - auto found_archive = false; - - if (GlobalState::g_binary_caching && !abi_tag.empty()) + if (GlobalState::g_binary_caching && maybe_abi_tag_and_file) { + auto archives_root_dir = paths.root / "archives"; + auto archive_name = maybe_abi_tag_and_file->tag + ".zip"; + auto archive_subpath = fs::u8path(maybe_abi_tag_and_file->tag.substr(0, 2)) / archive_name; + auto archive_path = archives_root_dir / archive_subpath; + auto archive_tombstone_path = archives_root_dir / "fail" / archive_subpath; + if (fs.exists(archive_path)) { System::println("Using cached binary package: %s", archive_path.u8string()); - auto pkg_path = paths.package_dir(spec); - std::error_code ec; - fs.remove_all(pkg_path, ec); - fs.create_directories(pkg_path, ec); - auto files = fs.get_files_non_recursive(pkg_path); - Checks::check_exit(VCPKG_LINE_INFO, files.empty(), "unable to clear path: %s", pkg_path.u8string()); - -#if defined(_WIN32) - auto&& _7za = paths.get_7za_exe(); - - System::cmd_execute_clean(Strings::format( - R"("%s" x "%s" -o"%s" -y >nul)", _7za.u8string(), archive_path.u8string(), pkg_path.u8string())); -#else - System::cmd_execute_clean(Strings::format( - R"(unzip -qq "%s" "-d%s")", archive_path.u8string(), pkg_path.u8string())); -#endif + decompress_archive(paths, spec, archive_path); auto maybe_bcf = Paragraphs::try_load_cached_package(paths, spec); bcf = std::make_unique(std::move(maybe_bcf).value_or_exit(VCPKG_LINE_INFO)); - found_archive = true; return {BuildResult::SUCCEEDED, std::move(bcf)}; } else if (fs.exists(archive_tombstone_path)) @@ -540,75 +613,42 @@ namespace vcpkg::Build System::println("Found failure tombstone: %s", archive_tombstone_path.u8string()); return BuildResult::BUILD_FAILED; } - } - if (GlobalState::g_binary_caching && !abi_tag.empty()) - { System::println("Could not locate cached archive: %s", archive_path.u8string()); - } - ExtendedBuildResult result = do_build_package(paths, pre_build_info, spec, abi_tag, config, status_db); + ExtendedBuildResult result = do_build_package_and_clean_buildtrees( + paths, pre_build_info, spec, abi_tag_and_file.value_or(AbiTagAndFile{}).tag, config, status_db); + + std::error_code ec; + auto abi_file_in_package = paths.package_dir(spec) / "share" / spec.name() / "vcpkg_abi_info.txt"; + fs.copy_file(maybe_abi_tag_and_file->tag_file, abi_file_in_package, fs::stdfs::copy_options::none, ec); + Checks::check_exit(VCPKG_LINE_INFO, !ec, "Could not copy into file: %s", abi_file_in_package.u8string()); - if (GlobalState::g_binary_caching && !abi_tag.empty()) - { if (result.code == BuildResult::SUCCEEDED) { - auto tmp_archive_path = paths.buildtrees / spec.name() / (triplet.to_string() + ".zip"); + auto tmp_archive_path = paths.buildtrees / spec.name() / (spec.triplet().to_string() + ".zip"); - std::error_code ec; - fs.write_contents( - paths.package_dir(spec) / "share" / spec.name() / "vcpkg_abi_info.txt", full_abi_info, ec); - - fs.remove(tmp_archive_path, ec); - Checks::check_exit(VCPKG_LINE_INFO, - !fs.exists(tmp_archive_path), - "Could not remove file: %s", - tmp_archive_path.u8string()); -#if defined(_WIN32) - auto&& _7za = paths.get_7za_exe(); + compress_archive(paths, spec, tmp_archive_path); - System::cmd_execute_clean(Strings::format( - R"("%s" a "%s" "%s\*" >nul)", - _7za.u8string(), - tmp_archive_path.u8string(), - paths.package_dir(spec).u8string())); -#else - System::cmd_execute_clean(Strings::format( - R"(cd '%s' && zip --quiet -r '%s' *)", - paths.package_dir(spec).u8string(), - tmp_archive_path.u8string())); -#endif fs.create_directories(archive_path.parent_path(), ec); - fs.rename(tmp_archive_path, archive_path); System::println("Stored binary cache: %s", archive_path.u8string()); } else if (result.code == BuildResult::BUILD_FAILED || result.code == BuildResult::POST_BUILD_CHECKS_FAILED) { - // Build failed, so store failure archive - std::error_code ec; + // Build failed, so store tombstone archive fs.create_directories(archive_tombstone_path.parent_path(), ec); fs.write_contents(archive_tombstone_path, "", ec); } - } - if (config.build_package_options.clean_buildtrees == CleanBuildtrees::YES) + return result; + } + else { - auto& fs = paths.get_filesystem(); - const fs::path buildtrees_dir = paths.buildtrees / config.scf.core_paragraph->name; - auto buildtree_files = fs.get_files_non_recursive(buildtrees_dir); - for (auto&& file : buildtree_files) - { - if (fs.is_directory(file) && file.filename() != "src") - { - std::error_code ec; - fs.remove_all(file, ec); - } - } + return do_build_package_and_clean_buildtrees( + paths, pre_build_info, spec, abi_tag_and_file.value_or(AbiTagAndFile{}).tag, config, status_db); } - - return result; } const std::string& to_string(const BuildResult build_result) @@ -732,7 +772,7 @@ namespace vcpkg::Build { return it_hash->second; } - auto hash = Commands::Hash::get_file_hash(paths.get_cmake_exe(), triplet_file_path, "SHA1"); + auto hash = Commands::Hash::get_file_hash(paths, triplet_file_path, "SHA1"); s_hash_cache.emplace(triplet_file_path, hash); return hash; } diff --git a/toolsrc/src/vcpkg/commands.ci.cpp b/toolsrc/src/vcpkg/commands.ci.cpp index c43f25b40..e01072a0a 100644 --- a/toolsrc/src/vcpkg/commands.ci.cpp +++ b/toolsrc/src/vcpkg/commands.ci.cpp @@ -24,6 +24,7 @@ namespace vcpkg::Commands::CI Install::InstallSummary summary; }; + static constexpr StringLiteral OPTION_DRY_RUN = "--dry-run"; static constexpr StringLiteral OPTION_EXCLUDE = "--exclude"; static constexpr StringLiteral OPTION_XUNIT = "--x-xunit"; @@ -32,11 +33,14 @@ namespace vcpkg::Commands::CI {OPTION_XUNIT, "File to output results in XUnit format (internal)"}, }}; + static constexpr std::array CI_SWITCHES = { + {{OPTION_DRY_RUN, "Print out plan without execution"}}}; + const CommandStructure COMMAND_STRUCTURE = { Help::create_example_string("ci x64-windows"), - 0, + 1, SIZE_MAX, - {{}, CI_SETTINGS}, + {CI_SWITCHES, CI_SETTINGS}, nullptr, }; @@ -52,6 +56,8 @@ namespace vcpkg::Commands::CI exclusions_set.insert(exclusions.begin(), exclusions.end()); } + auto is_dry_run = Util::Sets::contains(options.switches, OPTION_DRY_RUN); + std::vector triplets; for (const std::string& triplet : args.command_arguments) { @@ -94,8 +100,15 @@ namespace vcpkg::Commands::CI } } - auto summary = Install::perform(action_plan, Install::KeepGoing::YES, paths, status_db); - results.push_back({triplet, std::move(summary)}); + if (is_dry_run) + { + Dependencies::print_plan(action_plan); + } + else + { + auto summary = Install::perform(action_plan, Install::KeepGoing::YES, paths, status_db); + results.push_back({triplet, std::move(summary)}); + } } for (auto&& result : results) diff --git a/toolsrc/src/vcpkg/commands.hash.cpp b/toolsrc/src/vcpkg/commands.hash.cpp index bbbbed036..cb0a8cc51 100644 --- a/toolsrc/src/vcpkg/commands.hash.cpp +++ b/toolsrc/src/vcpkg/commands.hash.cpp @@ -7,11 +7,11 @@ namespace vcpkg::Commands::Hash { - std::string get_file_hash(fs::path const& cmake_exe_path, fs::path const& path, std::string const& hash_type) + std::string get_file_hash(const VcpkgPaths& paths, fs::path const& path, std::string const& hash_type) { const std::string cmd_line = Strings::format( R"("%s" -E %ssum "%s")", - cmake_exe_path.u8string(), + paths.get_cmake_exe().u8string(), Strings::ascii_to_lowercase(hash_type), path.u8string()); @@ -48,12 +48,12 @@ namespace vcpkg::Commands::Hash if (args.command_arguments.size() == 1) { - auto hash = get_file_hash(paths.get_cmake_exe(), args.command_arguments[0], "SHA512"); + auto hash = get_file_hash(paths, args.command_arguments[0], "SHA512"); System::println(hash); } if (args.command_arguments.size() == 2) { - auto hash = get_file_hash(paths.get_cmake_exe(), args.command_arguments[0], args.command_arguments[1]); + auto hash = get_file_hash(paths, args.command_arguments[0], args.command_arguments[1]); System::println(hash); } -- cgit v1.2.3 From 3a056235b85f34573903a7dc325d45e66549b6ff Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Wed, 14 Mar 2018 16:56:33 -0700 Subject: [vcpkg] Create minimal package structure even on failure --- toolsrc/src/vcpkg/build.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index 99ae5d2a3..b71bdbf25 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -620,6 +620,7 @@ namespace vcpkg::Build paths, pre_build_info, spec, abi_tag_and_file.value_or(AbiTagAndFile{}).tag, config, status_db); std::error_code ec; + fs.create_directories(paths.package_dir(spec) / "share" / spec.name(), ec); auto abi_file_in_package = paths.package_dir(spec) / "share" / spec.name() / "vcpkg_abi_info.txt"; fs.copy_file(maybe_abi_tag_and_file->tag_file, abi_file_in_package, fs::stdfs::copy_options::none, ec); Checks::check_exit(VCPKG_LINE_INFO, !ec, "Could not copy into file: %s", abi_file_in_package.u8string()); -- cgit v1.2.3 From d253123055e6bdfb181c6a8a14a63e2d6fc68cad Mon Sep 17 00:00:00 2001 From: Jacob Zhong Date: Sun, 18 Mar 2018 20:24:19 +0800 Subject: Add options and documentation for env command (#3007) * [vcpkg] Add options and documentation for env command * [vcpkg-env] Cleanup. Add tools/*. --- toolsrc/include/vcpkg/base/system.h | 5 +++- toolsrc/src/vcpkg/base/system.cpp | 15 +++++++++-- toolsrc/src/vcpkg/commands.env.cpp | 54 ++++++++++++++++++++++++++++++++----- toolsrc/src/vcpkg/help.cpp | 6 +---- 4 files changed, 66 insertions(+), 14 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/base/system.h b/toolsrc/include/vcpkg/base/system.h index 31034f6b4..b2faf69bb 100644 --- a/toolsrc/include/vcpkg/base/system.h +++ b/toolsrc/include/vcpkg/base/system.h @@ -1,5 +1,7 @@ #pragma once +#include + #include #include #include @@ -38,7 +40,8 @@ namespace vcpkg::System std::string output; }; - int cmd_execute_clean(const CStringView cmd_line); + int cmd_execute_clean(const CStringView cmd_line, + const std::unordered_map& extra_env = {}); int cmd_execute(const CStringView cmd_line); diff --git a/toolsrc/src/vcpkg/base/system.cpp b/toolsrc/src/vcpkg/base/system.cpp index e24098f97..f339afa51 100644 --- a/toolsrc/src/vcpkg/base/system.cpp +++ b/toolsrc/src/vcpkg/base/system.cpp @@ -153,12 +153,12 @@ namespace vcpkg::System R"(powershell -NoProfile -ExecutionPolicy Bypass -Command "& {& '%s' %s}")", script_path.u8string(), args); } - int cmd_execute_clean(const CStringView cmd_line) + int cmd_execute_clean(const CStringView cmd_line, const std::unordered_map& extra_env) { #if defined(_WIN32) static const std::string SYSTEM_ROOT = get_environment_variable("SystemRoot").value_or_exit(VCPKG_LINE_INFO); static const std::string SYSTEM_32 = SYSTEM_ROOT + R"(\system32)"; - static const std::string NEW_PATH = Strings::format( + std::string NEW_PATH = Strings::format( R"(Path=%s;%s;%s\Wbem;%s\WindowsPowerShell\v1.0\)", SYSTEM_32, SYSTEM_ROOT, SYSTEM_32, SYSTEM_32); std::vector env_wstrings = { @@ -224,11 +224,22 @@ namespace vcpkg::System env_cstr.push_back(L'\0'); } + if (extra_env.find("PATH") != extra_env.end()) + NEW_PATH += Strings::format(";%s", extra_env.find("PATH")->second); env_cstr.append(Strings::to_utf16(NEW_PATH)); env_cstr.push_back(L'\0'); env_cstr.append(L"VSLANG=1033"); env_cstr.push_back(L'\0'); + for (auto item : extra_env) + { + if (item.first == "PATH") continue; + env_cstr.append(Strings::to_utf16(item.first)); + env_cstr.push_back(L'='); + env_cstr.append(Strings::to_utf16(item.second)); + env_cstr.push_back(L'\0'); + } + STARTUPINFOW startup_info; memset(&startup_info, 0, sizeof(STARTUPINFOW)); startup_info.cb = sizeof(STARTUPINFOW); diff --git a/toolsrc/src/vcpkg/commands.env.cpp b/toolsrc/src/vcpkg/commands.env.cpp index f3beef6cd..d078baedb 100644 --- a/toolsrc/src/vcpkg/commands.env.cpp +++ b/toolsrc/src/vcpkg/commands.env.cpp @@ -1,5 +1,6 @@ #include "pch.h" +#include #include #include #include @@ -7,25 +8,66 @@ namespace vcpkg::Commands::Env { + static constexpr StringLiteral OPTION_BIN = "--bin"; + static constexpr StringLiteral OPTION_INCLUDE = "--include"; + static constexpr StringLiteral OPTION_DEBUG_BIN = "--debug-bin"; + static constexpr StringLiteral OPTION_TOOLS = "--tools"; + static constexpr StringLiteral OPTION_PYTHON = "--python"; + + static constexpr std::array SWITCHES = {{ + {OPTION_BIN, "Add installed bin/ to PATH"}, + {OPTION_INCLUDE, "Add installed include/ to INCLUDE"}, + {OPTION_DEBUG_BIN, "Add installed debug/bin/ to PATH"}, + {OPTION_TOOLS, "Add installed tools/*/ to PATH"}, + {OPTION_PYTHON, "Add installed python/ to PYTHONPATH"}, + }}; + const CommandStructure COMMAND_STRUCTURE = { Help::create_example_string("env --triplet x64-windows"), 0, 0, - {}, + {SWITCHES, {}}, nullptr, }; - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& triplet) { - args.parse_arguments(COMMAND_STRUCTURE); + const auto& fs = paths.get_filesystem(); + + const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE); - const auto pre_build_info = Build::PreBuildInfo::from_triplet_file(paths, default_triplet); + const auto pre_build_info = Build::PreBuildInfo::from_triplet_file(paths, triplet); const Toolset& toolset = paths.get_toolset(pre_build_info); auto env_cmd = Build::make_build_env_cmd(pre_build_info, toolset); + + std::unordered_map extra_env = {}; + const bool add_bin = Util::Sets::contains(options.switches, OPTION_BIN); + const bool add_include = Util::Sets::contains(options.switches, OPTION_INCLUDE); + const bool add_debug_bin = Util::Sets::contains(options.switches, OPTION_DEBUG_BIN); + const bool add_tools = Util::Sets::contains(options.switches, OPTION_TOOLS); + const bool add_python = Util::Sets::contains(options.switches, OPTION_PYTHON); + + std::vector path_vars; + if (add_bin) path_vars.push_back((paths.installed / triplet.to_string() / "bin").u8string()); + if (add_debug_bin) path_vars.push_back((paths.installed / triplet.to_string() / "debug" / "bin").u8string()); + if (add_include) extra_env.emplace("INCLUDE", (paths.installed / triplet.to_string() / "include").u8string()); + if (add_tools) + { + auto tools_dir = paths.installed / triplet.to_string() / "tools"; + auto tool_files = fs.get_files_non_recursive(tools_dir); + path_vars.push_back(tools_dir.u8string()); + for (auto&& tool_dir : tool_files) + { + if (fs.is_directory(tool_dir)) path_vars.push_back(tool_dir.u8string()); + } + } + if (add_python) extra_env.emplace("PYTHONPATH", (paths.installed / triplet.to_string() / "python").u8string()); + if (path_vars.size() > 0) extra_env.emplace("PATH", Strings::join(";", path_vars)); + if (env_cmd.empty()) - System::cmd_execute_clean("cmd"); + System::cmd_execute_clean("cmd", extra_env); else - System::cmd_execute_clean(env_cmd + " && cmd"); + System::cmd_execute_clean(env_cmd + " && cmd", extra_env); Checks::exit_success(VCPKG_LINE_INFO); } diff --git a/toolsrc/src/vcpkg/help.cpp b/toolsrc/src/vcpkg/help.cpp index b7d355742..743619937 100644 --- a/toolsrc/src/vcpkg/help.cpp +++ b/toolsrc/src/vcpkg/help.cpp @@ -98,14 +98,10 @@ namespace vcpkg::Help " vcpkg create \n" " [archivename] Create a new package\n" " vcpkg owns Search for files in installed packages\n" - " vcpkg cache List cached compiled packages\n" + " vcpkg env Creates a clean shell environment for development or compiling.\n" " vcpkg version Display version information\n" " vcpkg contact Display contact information to send feedback\n" "\n" - //"internal commands:\n" - //" --check-build-deps \n" - //" --create-binary-control \n" - //"\n" "Options:\n" " --triplet Specify the target architecture triplet.\n" " (default: %%VCPKG_DEFAULT_TRIPLET%%, see 'vcpkg help triplet')\n" -- cgit v1.2.3 From 95a8f285d8757f40bbaff0d766e851ba7d82820d Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 19 Mar 2018 18:59:37 -0700 Subject: Update CHANGELOG and bump version to v0.0.106 --- toolsrc/VERSION.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/VERSION.txt b/toolsrc/VERSION.txt index 157d21b7b..1305e8f43 100644 --- a/toolsrc/VERSION.txt +++ b/toolsrc/VERSION.txt @@ -1 +1 @@ -"0.0.105" \ No newline at end of file +"0.0.106" \ No newline at end of file -- cgit v1.2.3 From eab1d5c531695c2a644276832578e5550dd9abf6 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Wed, 14 Mar 2018 10:30:27 -0700 Subject: [vcpkg-ci] Do not rebuild libraries that were previously successful or failed --- toolsrc/include/vcpkg/base/cache.h | 21 +++++ toolsrc/include/vcpkg/base/util.h | 6 +- toolsrc/include/vcpkg/build.h | 17 ++++ toolsrc/include/vcpkg/commands.h | 12 +++ toolsrc/include/vcpkg/dependencies.h | 5 +- toolsrc/include/vcpkg/install.h | 1 + toolsrc/include/vcpkg/sourceparagraph.h | 2 + toolsrc/src/tests.plan.cpp | 84 ++++++++++++++++++- toolsrc/src/vcpkg/base/system.cpp | 10 ++- toolsrc/src/vcpkg/build.cpp | 44 ++++------ toolsrc/src/vcpkg/commands.ci.cpp | 138 +++++++++++++++++++++++++++++++- toolsrc/src/vcpkg/dependencies.cpp | 11 ++- toolsrc/src/vcpkg/install.cpp | 59 +++++++------- toolsrc/src/vcpkg/sourceparagraph.cpp | 10 +++ 14 files changed, 349 insertions(+), 71 deletions(-) create mode 100644 toolsrc/include/vcpkg/base/cache.h (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/base/cache.h b/toolsrc/include/vcpkg/base/cache.h new file mode 100644 index 000000000..dfc7565b8 --- /dev/null +++ b/toolsrc/include/vcpkg/base/cache.h @@ -0,0 +1,21 @@ +#pragma once + +#include + +namespace vcpkg +{ + template + struct Cache + { + template + Value const& get_lazy(const Key& k, const F& f) const + { + auto it = m_cache.find(k); + if (it != m_cache.end()) return it->second; + return m_cache.emplace(k, f()).first->second; + } + + private: + mutable std::map m_cache; + }; +} diff --git a/toolsrc/include/vcpkg/base/util.h b/toolsrc/include/vcpkg/base/util.h index 5e07b240a..b12919951 100644 --- a/toolsrc/include/vcpkg/base/util.h +++ b/toolsrc/include/vcpkg/base/util.h @@ -24,10 +24,10 @@ namespace vcpkg::Util namespace Sets { - template - bool contains(const Container& container, const ElementT& item) + template + bool contains(const Container& container, const Key& item) { - return container.find(item) != container.cend(); + return container.find(item) != container.end(); } } diff --git a/toolsrc/include/vcpkg/build.h b/toolsrc/include/vcpkg/build.h index ea81c4dbe..8c4d7b575 100644 --- a/toolsrc/include/vcpkg/build.h +++ b/toolsrc/include/vcpkg/build.h @@ -204,4 +204,21 @@ namespace vcpkg::Build }; BuildInfo read_build_info(const Files::Filesystem& fs, const fs::path& filepath); + + struct AbiEntry + { + std::string key; + std::string value; + }; + + struct AbiTagAndFile + { + std::string tag; + fs::path tag_file; + }; + + Optional compute_abi_tag(const VcpkgPaths& paths, + const BuildPackageConfig& config, + const PreBuildInfo& pre_build_info, + Span dependency_abis); } diff --git a/toolsrc/include/vcpkg/commands.h b/toolsrc/include/vcpkg/commands.h index b6b1c56ab..7369b8206 100644 --- a/toolsrc/include/vcpkg/commands.h +++ b/toolsrc/include/vcpkg/commands.h @@ -7,6 +7,8 @@ #include #include +#include +#include namespace vcpkg::Commands { @@ -23,7 +25,17 @@ namespace vcpkg::Commands namespace CI { + struct UnknownCIPortsResults + { + std::vector unknown; + std::map known; + }; + extern const CommandStructure COMMAND_STRUCTURE; + UnknownCIPortsResults find_unknown_ports_for_ci(const VcpkgPaths& paths, + const std::set& exclusions, + const Dependencies::PortFileProvider& provider, + const std::vector& fspecs); void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet); } diff --git a/toolsrc/include/vcpkg/dependencies.h b/toolsrc/include/vcpkg/dependencies.h index fadb8cc7e..33af6c4f5 100644 --- a/toolsrc/include/vcpkg/dependencies.h +++ b/toolsrc/include/vcpkg/dependencies.h @@ -45,7 +45,8 @@ namespace vcpkg::Dependencies InstallPlanAction(const PackageSpec& spec, const SourceControlFile& scf, const std::set& features, - const RequestType& request_type); + const RequestType& request_type, + std::vector&& dependencies); std::string displayname() const; @@ -58,6 +59,8 @@ namespace vcpkg::Dependencies RequestType request_type; Build::BuildPackageOptions build_options; std::set feature_list; + + std::vector computed_dependencies; }; enum class RemovePlanType diff --git a/toolsrc/include/vcpkg/install.h b/toolsrc/include/vcpkg/install.h index 2e92764dc..b7acbf15f 100644 --- a/toolsrc/include/vcpkg/install.h +++ b/toolsrc/include/vcpkg/install.h @@ -37,6 +37,7 @@ namespace vcpkg::Install std::string total_elapsed_time; void print() const; + static std::string xunit_result(const PackageSpec& spec, Chrono::ElapsedTime time, Build::BuildResult code); std::string xunit_results() const; }; diff --git a/toolsrc/include/vcpkg/sourceparagraph.h b/toolsrc/include/vcpkg/sourceparagraph.h index ea8e27a94..ae5812ea7 100644 --- a/toolsrc/include/vcpkg/sourceparagraph.h +++ b/toolsrc/include/vcpkg/sourceparagraph.h @@ -63,6 +63,8 @@ namespace vcpkg std::unique_ptr core_paragraph; std::vector> feature_paragraphs; + + Optional find_feature(const std::string& featurename) const; }; void print_error_message(Span> error_info_list); diff --git a/toolsrc/src/tests.plan.cpp b/toolsrc/src/tests.plan.cpp index 95056810c..a99f1abb9 100644 --- a/toolsrc/src/tests.plan.cpp +++ b/toolsrc/src/tests.plan.cpp @@ -593,6 +593,87 @@ namespace UnitTest1 features_check(&install_plan[0], "a", {"core"}, Triplet::X64_WINDOWS); } + TEST_METHOD(install_plan_action_dependencies) + { + std::vector> status_paragraphs; + + // Add a port "a" which depends on the core of "b", which was already + // installed explicitly + PackageSpecMap spec_map(Triplet::X64_WINDOWS); + auto spec_c = spec_map.emplace("c"); + auto spec_b = spec_map.emplace("b", "c"); + spec_map.emplace("a", "b"); + + // Install "a" (without explicit feature specification) + auto install_specs = FullPackageSpec::from_string("a", Triplet::X64_WINDOWS); + auto install_plan = Dependencies::create_feature_install_plan( + spec_map.map, + FullPackageSpec::to_feature_specs({install_specs.value_or_exit(VCPKG_LINE_INFO)}), + StatusParagraphs(std::move(status_paragraphs))); + + Assert::IsTrue(install_plan.size() == 3); + features_check(&install_plan[0], "c", {"core"}, Triplet::X64_WINDOWS); + + features_check(&install_plan[1], "b", {"core"}, Triplet::X64_WINDOWS); + Assert::IsTrue(install_plan[1].install_action.get()->computed_dependencies == + std::vector{spec_c}); + + features_check(&install_plan[2], "a", {"core"}, Triplet::X64_WINDOWS); + Assert::IsTrue(install_plan[2].install_action.get()->computed_dependencies == + std::vector{spec_b}); + } + + TEST_METHOD(install_plan_action_dependencies_2) + { + std::vector> status_paragraphs; + + // Add a port "a" which depends on the core of "b", which was already + // installed explicitly + PackageSpecMap spec_map(Triplet::X64_WINDOWS); + auto spec_c = spec_map.emplace("c"); + auto spec_b = spec_map.emplace("b", "c"); + spec_map.emplace("a", "c, b"); + + // Install "a" (without explicit feature specification) + auto install_specs = FullPackageSpec::from_string("a", Triplet::X64_WINDOWS); + auto install_plan = Dependencies::create_feature_install_plan( + spec_map.map, + FullPackageSpec::to_feature_specs({install_specs.value_or_exit(VCPKG_LINE_INFO)}), + StatusParagraphs(std::move(status_paragraphs))); + + Assert::IsTrue(install_plan.size() == 3); + features_check(&install_plan[0], "c", {"core"}, Triplet::X64_WINDOWS); + + features_check(&install_plan[1], "b", {"core"}, Triplet::X64_WINDOWS); + Assert::IsTrue(install_plan[1].install_action.get()->computed_dependencies == + std::vector{spec_c}); + + features_check(&install_plan[2], "a", {"core"}, Triplet::X64_WINDOWS); + Assert::IsTrue(install_plan[2].install_action.get()->computed_dependencies == + std::vector{spec_b, spec_c}); + } + + TEST_METHOD(install_plan_action_dependencies_3) + { + std::vector> status_paragraphs; + + // Add a port "a" which depends on the core of "b", which was already + // installed explicitly + PackageSpecMap spec_map(Triplet::X64_WINDOWS); + spec_map.emplace("a", "", {{"0", ""}, {"1", "a[0]"}}, {"1"}); + + // Install "a" (without explicit feature specification) + auto install_specs = FullPackageSpec::from_string("a", Triplet::X64_WINDOWS); + auto install_plan = Dependencies::create_feature_install_plan( + spec_map.map, + FullPackageSpec::to_feature_specs({install_specs.value_or_exit(VCPKG_LINE_INFO)}), + StatusParagraphs(std::move(status_paragraphs))); + + Assert::IsTrue(install_plan.size() == 1); + features_check(&install_plan[0], "a", {"1", "0", "core"}, Triplet::X64_WINDOWS); + Assert::IsTrue(install_plan[0].install_action.get()->computed_dependencies == std::vector{}); + } + TEST_METHOD(upgrade_with_default_features_1) { std::vector> pghs; @@ -619,7 +700,6 @@ namespace UnitTest1 Assert::IsTrue(plan[0].remove_action.has_value()); Assert::AreEqual("a", plan[1].spec().name().c_str()); - Assert::IsTrue(plan[1].install_action.has_value()); features_check(&plan[1], "a", {"core", "0"}, Triplet::X86_WINDOWS); } @@ -651,11 +731,9 @@ namespace UnitTest1 Assert::IsTrue(plan[0].remove_action.has_value()); Assert::AreEqual("b", plan[1].spec().name().c_str()); - Assert::IsTrue(plan[1].install_action.has_value()); features_check(&plan[1], "b", {"b0", "core"}, Triplet::X64_WINDOWS); Assert::AreEqual("a", plan[2].spec().name().c_str()); - Assert::IsTrue(plan[2].install_action.has_value()); features_check(&plan[2], "a", {"core"}, Triplet::X64_WINDOWS); } diff --git a/toolsrc/src/vcpkg/base/system.cpp b/toolsrc/src/vcpkg/base/system.cpp index f339afa51..a315c7880 100644 --- a/toolsrc/src/vcpkg/base/system.cpp +++ b/toolsrc/src/vcpkg/base/system.cpp @@ -314,6 +314,8 @@ namespace vcpkg::System // Flush stdout before launching external process fflush(stdout); + auto timer = Chrono::ElapsedTimer::create_started(); + #if defined(_WIN32) const auto actual_cmd_line = Strings::format(R"###("%s 2>&1")###", cmd_line); @@ -335,8 +337,10 @@ namespace vcpkg::System } const auto ec = _pclose(pipe); - Debug::println("_pclose() returned %d", ec); remove_byte_order_marks(&output); + + Debug::println("_pclose() returned %d after %8d us", ec, (int)timer.microseconds()); + return {ec, Strings::to_utf8(output)}; #else const auto actual_cmd_line = Strings::format(R"###(%s 2>&1)###", cmd_line); @@ -359,7 +363,9 @@ namespace vcpkg::System } const auto ec = pclose(pipe); - Debug::println("pclose() returned %d", ec); + + Debug::println("_pclose() returned %d after %8d us", ec, (int)timer.microseconds()); + return {ec, output}; #endif } diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index b71bdbf25..bc9eca3ba 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -273,12 +273,10 @@ namespace vcpkg::Build return filter_dependencies(config.scf.core_paragraph->depends, triplet); } - auto it = - Util::find_if(config.scf.feature_paragraphs, - [&](std::unique_ptr const& fpgh) { return fpgh->name == feature; }); - Checks::check_exit(VCPKG_LINE_INFO, it != config.scf.feature_paragraphs.end()); + auto maybe_feature = config.scf.find_feature(feature); + Checks::check_exit(VCPKG_LINE_INFO, maybe_feature.has_value()); - return filter_dependencies(it->get()->depends, triplet); + return filter_dependencies(maybe_feature.get()->depends, triplet); }); auto dep_fspecs = FeatureSpec::from_strings_and_triplet(dep_strings, triplet); @@ -423,22 +421,10 @@ namespace vcpkg::Build return result; } - struct AbiEntry - { - std::string key; - std::string value; - }; - - struct AbiTagAndFile - { - std::string tag; - fs::path tag_file; - }; - - static Optional compute_abi_tag(const VcpkgPaths& paths, - const BuildPackageConfig& config, - const PreBuildInfo& pre_build_info, - Span dependency_abis) + Optional compute_abi_tag(const VcpkgPaths& paths, + const BuildPackageConfig& config, + const PreBuildInfo& pre_build_info, + Span dependency_abis) { if (!GlobalState::g_binary_caching) return nullopt; @@ -584,17 +570,17 @@ namespace vcpkg::Build const auto pre_build_info = PreBuildInfo::from_triplet_file(paths, triplet); - auto abi_tag_and_file = compute_abi_tag(paths, config, pre_build_info, dependency_abis); + auto maybe_abi_tag_and_file = compute_abi_tag(paths, config, pre_build_info, dependency_abis); std::unique_ptr bcf; - auto maybe_abi_tag_and_file = abi_tag_and_file.get(); + auto abi_tag_and_file = maybe_abi_tag_and_file.get(); - if (GlobalState::g_binary_caching && maybe_abi_tag_and_file) + if (GlobalState::g_binary_caching && abi_tag_and_file) { auto archives_root_dir = paths.root / "archives"; - auto archive_name = maybe_abi_tag_and_file->tag + ".zip"; - auto archive_subpath = fs::u8path(maybe_abi_tag_and_file->tag.substr(0, 2)) / archive_name; + auto archive_name = abi_tag_and_file->tag + ".zip"; + auto archive_subpath = fs::u8path(abi_tag_and_file->tag.substr(0, 2)) / archive_name; auto archive_path = archives_root_dir / archive_subpath; auto archive_tombstone_path = archives_root_dir / "fail" / archive_subpath; @@ -617,12 +603,12 @@ namespace vcpkg::Build System::println("Could not locate cached archive: %s", archive_path.u8string()); ExtendedBuildResult result = do_build_package_and_clean_buildtrees( - paths, pre_build_info, spec, abi_tag_and_file.value_or(AbiTagAndFile{}).tag, config, status_db); + paths, pre_build_info, spec, maybe_abi_tag_and_file.value_or(AbiTagAndFile{}).tag, config, status_db); std::error_code ec; fs.create_directories(paths.package_dir(spec) / "share" / spec.name(), ec); auto abi_file_in_package = paths.package_dir(spec) / "share" / spec.name() / "vcpkg_abi_info.txt"; - fs.copy_file(maybe_abi_tag_and_file->tag_file, abi_file_in_package, fs::stdfs::copy_options::none, ec); + fs.copy_file(abi_tag_and_file->tag_file, abi_file_in_package, fs::stdfs::copy_options::none, ec); Checks::check_exit(VCPKG_LINE_INFO, !ec, "Could not copy into file: %s", abi_file_in_package.u8string()); if (result.code == BuildResult::SUCCEEDED) @@ -648,7 +634,7 @@ namespace vcpkg::Build else { return do_build_package_and_clean_buildtrees( - paths, pre_build_info, spec, abi_tag_and_file.value_or(AbiTagAndFile{}).tag, config, status_db); + paths, pre_build_info, spec, maybe_abi_tag_and_file.value_or(AbiTagAndFile{}).tag, config, status_db); } } diff --git a/toolsrc/src/vcpkg/commands.ci.cpp b/toolsrc/src/vcpkg/commands.ci.cpp index e01072a0a..45eb1c83e 100644 --- a/toolsrc/src/vcpkg/commands.ci.cpp +++ b/toolsrc/src/vcpkg/commands.ci.cpp @@ -1,5 +1,6 @@ #include "pch.h" +#include #include #include #include @@ -7,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -44,8 +46,120 @@ namespace vcpkg::Commands::CI nullptr, }; + UnknownCIPortsResults find_unknown_ports_for_ci(const VcpkgPaths& paths, + const std::set& exclusions, + const Dependencies::PortFileProvider& provider, + const std::vector& fspecs) + { + UnknownCIPortsResults ret; + + auto& fs = paths.get_filesystem(); + + std::map abi_tag_map; + std::set will_fail; + + const Build::BuildPackageOptions install_plan_options = {Build::UseHeadVersion::NO, + Build::AllowDownloads::YES, + Build::CleanBuildtrees::YES, + Build::CleanPackages::YES}; + + vcpkg::Cache pre_build_info_cache; + + auto action_plan = Dependencies::create_feature_install_plan(provider, fspecs, StatusParagraphs{}); + + for (auto&& action : action_plan) + { + if (auto p = action.install_action.get()) + { + // determine abi tag + std::string abi; + if (auto scf = p->source_control_file.get()) + { + auto triplet = p->spec.triplet(); + + const Build::BuildPackageConfig build_config{p->source_control_file.value_or_exit(VCPKG_LINE_INFO), + triplet, + paths.port_dir(p->spec), + install_plan_options, + p->feature_list}; + + auto dependency_abis = + Util::fmap(p->computed_dependencies, [&](const PackageSpec& spec) -> Build::AbiEntry { + auto it = abi_tag_map.find(spec); + + if (it == abi_tag_map.end()) + return {spec.name(), ""}; + else + return {spec.name(), it->second}; + }); + const auto& pre_build_info = pre_build_info_cache.get_lazy( + triplet, [&]() { return Build::PreBuildInfo::from_triplet_file(paths, triplet); }); + + auto maybe_tag_and_file = + Build::compute_abi_tag(paths, build_config, pre_build_info, dependency_abis); + if (auto tag_and_file = maybe_tag_and_file.get()) + { + abi = tag_and_file->tag; + abi_tag_map.emplace(p->spec, abi); + } + } + else if (auto ipv = p->installed_package.get()) + { + abi = ipv->core->package.abi; + if (!abi.empty()) abi_tag_map.emplace(p->spec, abi); + } + + std::string state; + + auto archives_root_dir = paths.root / "archives"; + auto archive_name = abi + ".zip"; + auto archive_subpath = fs::u8path(abi.substr(0, 2)) / archive_name; + auto archive_path = archives_root_dir / archive_subpath; + auto archive_tombstone_path = archives_root_dir / "fail" / archive_subpath; + + bool b_will_build = false; + + if (Util::Sets::contains(exclusions, p->spec.name())) + { + ret.known.emplace(p->spec, BuildResult::EXCLUDED); + will_fail.emplace(p->spec); + } + else if (std::any_of(p->computed_dependencies.begin(), + p->computed_dependencies.end(), + [&](const PackageSpec& spec) { return Util::Sets::contains(will_fail, spec); })) + { + ret.known.emplace(p->spec, BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES); + will_fail.emplace(p->spec); + } + else if (fs.exists(archive_path)) + { + state += "pass"; + ret.known.emplace(p->spec, BuildResult::SUCCEEDED); + } + else if (fs.exists(archive_tombstone_path)) + { + state += "fail"; + ret.known.emplace(p->spec, BuildResult::BUILD_FAILED); + will_fail.emplace(p->spec); + } + else + { + ret.unknown.push_back(p->spec); + b_will_build = true; + } + + System::println("%40s: %1s %8s: %s", p->spec, (b_will_build ? "*" : " "), state, abi); + } + } + + return ret; + } + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) { + Checks::check_exit( + VCPKG_LINE_INFO, GlobalState::g_binary_caching, "The ci command requires binary caching to be enabled."); + const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE); std::set exclusions_set; @@ -77,16 +191,21 @@ namespace vcpkg::Commands::CI Build::CleanBuildtrees::YES, Build::CleanPackages::YES}; - std::vector ports = Install::get_all_port_names(paths); + std::vector> all_known_results; + + std::vector all_ports = Install::get_all_port_names(paths); std::vector results; for (const Triplet& triplet : triplets) { Input::check_triplet(triplet, paths); - std::vector specs = PackageSpec::to_package_specs(ports, triplet); + + std::vector specs = PackageSpec::to_package_specs(all_ports, triplet); // Install the default features for every package - const auto featurespecs = Util::fmap(specs, [](auto& spec) { return FeatureSpec(spec, ""); }); + auto all_fspecs = Util::fmap(specs, [](auto& spec) { return FeatureSpec(spec, ""); }); + auto split_specs = find_unknown_ports_for_ci(paths, exclusions_set, paths_port_file, all_fspecs); + auto fspecs = Util::fmap(split_specs.unknown, [](auto& spec) { return FeatureSpec(spec, ""); }); - auto action_plan = Dependencies::create_feature_install_plan(paths_port_file, featurespecs, status_db); + auto action_plan = Dependencies::create_feature_install_plan(paths_port_file, fspecs, status_db); for (auto&& action : action_plan) { @@ -107,7 +226,10 @@ namespace vcpkg::Commands::CI else { auto summary = Install::perform(action_plan, Install::KeepGoing::YES, paths, status_db); + for (auto&& result : summary.results) + split_specs.known.erase(result.spec); results.push_back({triplet, std::move(summary)}); + all_known_results.emplace_back(std::move(split_specs.known)); } } @@ -125,6 +247,14 @@ namespace vcpkg::Commands::CI for (auto&& result : results) xunit_doc += result.summary.xunit_results(); + for (auto&& known_result : all_known_results) + { + for (auto&& result : known_result) + { + xunit_doc += + Install::InstallSummary::xunit_result(result.first, Chrono::ElapsedTime{}, result.second); + } + } xunit_doc += "\n"; paths.get_filesystem().write_contents(fs::u8path(it_xunit->second), xunit_doc); diff --git a/toolsrc/src/vcpkg/dependencies.cpp b/toolsrc/src/vcpkg/dependencies.cpp index 1d017a8d3..f6d81c973 100644 --- a/toolsrc/src/vcpkg/dependencies.cpp +++ b/toolsrc/src/vcpkg/dependencies.cpp @@ -144,12 +144,14 @@ namespace vcpkg::Dependencies InstallPlanAction::InstallPlanAction(const PackageSpec& spec, const SourceControlFile& scf, const std::set& features, - const RequestType& request_type) + const RequestType& request_type, + std::vector&& dependencies) : spec(spec) , source_control_file(scf) , plan_type(InstallPlanType::BUILD_AND_INSTALL) , request_type(request_type) , feature_list(features) + , computed_dependencies(std::move(dependencies)) { } @@ -162,6 +164,7 @@ namespace vcpkg::Dependencies , plan_type(InstallPlanType::ALREADY_INSTALLED) , request_type(request_type) , feature_list(features) + , computed_dependencies(installed_package.get()->dependencies()) { } @@ -683,11 +686,17 @@ namespace vcpkg::Dependencies // If it will be transiently uninstalled, we need to issue a full installation command auto pscf = p_cluster->source_control_file.value_or_exit(VCPKG_LINE_INFO); Checks::check_exit(VCPKG_LINE_INFO, pscf != nullptr); + + auto dep_specs = Util::fmap(m_graph_plan->install_graph.adjacency_list(p_cluster), + [](ClusterPtr const& p) { return p->spec; }); + Util::sort_unique_erase(dep_specs); + plan.emplace_back(InstallPlanAction{ p_cluster->spec, *pscf, p_cluster->to_install_features, p_cluster->request_type, + std::move(dep_specs), }); } else diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp index 7d36fba82..e30a34c18 100644 --- a/toolsrc/src/vcpkg/install.cpp +++ b/toolsrc/src/vcpkg/install.cpp @@ -668,39 +668,42 @@ namespace vcpkg::Install return nullptr; } + std::string InstallSummary::xunit_result(const PackageSpec& spec, Chrono::ElapsedTime time, BuildResult code) + { + std::string inner_block; + const char* result_string = ""; + switch (code) + { + case BuildResult::POST_BUILD_CHECKS_FAILED: + case BuildResult::FILE_CONFLICTS: + case BuildResult::BUILD_FAILED: + result_string = "Fail"; + inner_block = Strings::format("", to_string(code)); + break; + case BuildResult::EXCLUDED: + case BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES: + result_string = "Skip"; + inner_block = Strings::format("", to_string(code)); + break; + case BuildResult::SUCCEEDED: result_string = "Pass"; break; + default: Checks::exit_fail(VCPKG_LINE_INFO); + } + + return Strings::format(R"(%s)" + "\n", + spec, + spec, + time.as().count(), + result_string, + inner_block); + } + std::string InstallSummary::xunit_results() const { std::string xunit_doc; for (auto&& result : results) { - std::string inner_block; - const char* result_string = ""; - switch (result.build_result.code) - { - case BuildResult::POST_BUILD_CHECKS_FAILED: - case BuildResult::FILE_CONFLICTS: - case BuildResult::BUILD_FAILED: - result_string = "Fail"; - inner_block = Strings::format("", - to_string(result.build_result.code)); - break; - case BuildResult::EXCLUDED: - case BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES: - result_string = "Skip"; - inner_block = - Strings::format("", to_string(result.build_result.code)); - break; - case BuildResult::SUCCEEDED: result_string = "Pass"; break; - default: Checks::exit_fail(VCPKG_LINE_INFO); - } - - xunit_doc += Strings::format(R"(%s)" - "\n", - result.spec, - result.spec, - result.timing.as().count(), - result_string, - inner_block); + xunit_doc += xunit_result(result.spec, result.timing, result.build_result.code); } return xunit_doc; } diff --git a/toolsrc/src/vcpkg/sourceparagraph.cpp b/toolsrc/src/vcpkg/sourceparagraph.cpp index 0b4baf189..ed61cb42a 100644 --- a/toolsrc/src/vcpkg/sourceparagraph.cpp +++ b/toolsrc/src/vcpkg/sourceparagraph.cpp @@ -158,6 +158,16 @@ namespace vcpkg return std::move(control_file); } + Optional SourceControlFile::find_feature(const std::string& featurename) const + { + auto it = Util::find_if(feature_paragraphs, + [&](const std::unique_ptr& p) { return p->name == featurename; }); + if (it != feature_paragraphs.end()) + return **it; + else + return nullopt; + } + Dependency Dependency::parse_dependency(std::string name, std::string qualifier) { Dependency dep; -- cgit v1.2.3 From ab7985a34b8a4de59dc9a6e6c4c40fbb564797b8 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 16 Mar 2018 16:53:48 -0700 Subject: [vcpkg-hash] Use BCrypt on Windows --- toolsrc/include/vcpkg/base/strings.h | 4 +- toolsrc/include/vcpkg/base/util.h | 12 +- toolsrc/src/vcpkg/base/strings.cpp | 13 ++- toolsrc/src/vcpkg/commands.hash.cpp | 124 ++++++++++++++++++--- toolsrc/vcpkg/vcpkg.vcxproj | 8 +- .../vcpkgmetricsuploader.vcxproj | 8 +- toolsrc/vcpkgtest/vcpkgtest.vcxproj | 4 + 7 files changed, 146 insertions(+), 27 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/base/strings.h b/toolsrc/include/vcpkg/base/strings.h index 6294853af..c32e81ac2 100644 --- a/toolsrc/include/vcpkg/base/strings.h +++ b/toolsrc/include/vcpkg/base/strings.h @@ -46,7 +46,9 @@ namespace vcpkg::Strings bool case_insensitive_ascii_equals(const CStringView left, const CStringView right); - std::string ascii_to_lowercase(std::string input); + std::string ascii_to_lowercase(std::string s); + + std::string ascii_to_uppercase(std::string s); bool case_insensitive_ascii_starts_with(const std::string& s, const std::string& pattern); diff --git a/toolsrc/include/vcpkg/base/util.h b/toolsrc/include/vcpkg/base/util.h index b12919951..c73345719 100644 --- a/toolsrc/include/vcpkg/base/util.h +++ b/toolsrc/include/vcpkg/base/util.h @@ -6,8 +6,6 @@ #include #include -#include - namespace vcpkg::Util { template @@ -158,6 +156,8 @@ namespace vcpkg::Util MoveOnlyBase& operator=(const MoveOnlyBase&) = delete; MoveOnlyBase& operator=(MoveOnlyBase&&) = default; + + ~MoveOnlyBase() = default; }; struct ResourceBase @@ -168,6 +168,8 @@ namespace vcpkg::Util ResourceBase& operator=(const ResourceBase&) = delete; ResourceBase& operator=(ResourceBase&&) = delete; + + ~ResourceBase() = default; }; template @@ -214,4 +216,10 @@ namespace vcpkg::Util return e == E::YES; } } + + template + void unused(T&& param) + { + (void)param; + } } diff --git a/toolsrc/src/vcpkg/base/strings.cpp b/toolsrc/src/vcpkg/base/strings.cpp index a08512c9f..5fedf3e1f 100644 --- a/toolsrc/src/vcpkg/base/strings.cpp +++ b/toolsrc/src/vcpkg/base/strings.cpp @@ -7,10 +7,11 @@ namespace vcpkg::Strings::details { // To disambiguate between two overloads - static const auto isspace = [](const char c) { return std::isspace(c); }; + static bool IS_SPACE(const char c) { return std::isspace(c) != 0; }; // Avoids C4244 warnings because of char<->int conversion that occur when using std::tolower() static char tolower_char(const char c) { return static_cast(std::tolower(c)); } + static char toupper_char(const char c) { return static_cast(std::toupper(c)); } #if defined(_WIN32) static _locale_t& c_locale() @@ -114,6 +115,12 @@ namespace vcpkg::Strings return s; } + std::string ascii_to_uppercase(std::string s) + { + std::transform(s.begin(), s.end(), s.begin(), &details::toupper_char); + return s; + } + bool case_insensitive_ascii_starts_with(const std::string& s, const std::string& pattern) { #if defined(_WIN32) @@ -136,8 +143,8 @@ namespace vcpkg::Strings std::string trim(std::string&& s) { - s.erase(std::find_if_not(s.rbegin(), s.rend(), details::isspace).base(), s.end()); - s.erase(s.begin(), std::find_if_not(s.begin(), s.end(), details::isspace)); + s.erase(std::find_if_not(s.rbegin(), s.rend(), details::IS_SPACE).base(), s.end()); + s.erase(s.begin(), std::find_if_not(s.begin(), s.end(), details::IS_SPACE)); return std::move(s); } diff --git a/toolsrc/src/vcpkg/commands.hash.cpp b/toolsrc/src/vcpkg/commands.hash.cpp index cb0a8cc51..9e1b54390 100644 --- a/toolsrc/src/vcpkg/commands.hash.cpp +++ b/toolsrc/src/vcpkg/commands.hash.cpp @@ -1,13 +1,114 @@ #include "pch.h" +#include +#include #include #include #include #include +#if defined(_WIN32) +#include + +#ifndef NT_SUCCESS +#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0) +#endif + namespace vcpkg::Commands::Hash { - std::string get_file_hash(const VcpkgPaths& paths, fs::path const& path, std::string const& hash_type) + namespace + { + static std::string to_hex(const unsigned char* string, const size_t bytes) + { + static constexpr char HEX_MAP[] = "0123456789abcdef"; + + std::string output; + output.resize(2 * bytes); + + size_t current_char = 0; + for (size_t i = 0; i < bytes; i++) + { + // high + output[current_char] = HEX_MAP[(string[i] & 0xF0) >> 4]; + ++current_char; + // low + output[current_char] = HEX_MAP[(string[i] & 0x0F)]; + ++current_char; + } + + return output; + } + + struct BCryptAlgorithmHandle : Util::ResourceBase + { + BCRYPT_ALG_HANDLE handle = nullptr; + + ~BCryptAlgorithmHandle() + { + if (handle) BCryptCloseAlgorithmProvider(handle, 0); + } + }; + + struct BCryptHashHandle : Util::ResourceBase + { + BCRYPT_HASH_HANDLE handle = nullptr; + + ~BCryptHashHandle() + { + if (handle) BCryptDestroyHash(handle); + } + }; + } + + std::string get_file_hash(const VcpkgPaths&, const fs::path& path, const std::string& hash_type) + { + BCryptAlgorithmHandle algorithm_handle; + + NTSTATUS error_code = BCryptOpenAlgorithmProvider( + &algorithm_handle.handle, Strings::to_utf16(Strings::ascii_to_uppercase(hash_type)).c_str(), nullptr, 0); + Checks::check_exit(VCPKG_LINE_INFO, NT_SUCCESS(error_code), "Failed to open the algorithm provider"); + + DWORD hash_buffer_bytes; + DWORD cb_data; + error_code = BCryptGetProperty(algorithm_handle.handle, + BCRYPT_HASH_LENGTH, + reinterpret_cast(&hash_buffer_bytes), + sizeof(DWORD), + &cb_data, + 0); + Checks::check_exit(VCPKG_LINE_INFO, NT_SUCCESS(error_code), "Failed to get hash length"); + const ULONG length_in_bytes = hash_buffer_bytes; + + BCryptHashHandle hash_handle; + + error_code = BCryptCreateHash(algorithm_handle.handle, &hash_handle.handle, nullptr, 0, nullptr, 0, 0); + Checks::check_exit(VCPKG_LINE_INFO, NT_SUCCESS(error_code), "Failed to initialize the hasher"); + + FILE* file = nullptr; + const auto ec = _wfopen_s(&file, path.c_str(), L"rb"); + Checks::check_exit(VCPKG_LINE_INFO, ec == 0, "Failed to open file: %s", path.u8string()); + unsigned char buffer[4096]; + while (const auto actual_size = fread(buffer, 1, sizeof(buffer), file)) + { + error_code = BCryptHashData(hash_handle.handle, buffer, static_cast(actual_size), 0); + Checks::check_exit(VCPKG_LINE_INFO, NT_SUCCESS(error_code), "Failed to hash data"); + } + + fclose(file); + + std::unique_ptr hash_buffer = std::make_unique(length_in_bytes); + + error_code = BCryptFinishHash(hash_handle.handle, hash_buffer.get(), length_in_bytes, 0); + Checks::check_exit(VCPKG_LINE_INFO, NT_SUCCESS(error_code), "Failed to finalize the hash"); + + return to_hex(hash_buffer.get(), length_in_bytes); + } +} + +#else +namespace vcpkg::Commands::Hash +{ + std::string get_file_hash(const VcpkgPaths& paths, const fs::path& path, const std::string& hash_type) { const std::string cmd_line = Strings::format( R"("%s" -E %ssum "%s")", @@ -32,7 +133,11 @@ namespace vcpkg::Commands::Hash Util::erase_remove_if(hash, isspace); return hash; } +} +#endif +namespace vcpkg::Commands::Hash +{ const CommandStructure COMMAND_STRUCTURE = { Strings::format("The argument should be a file path\n%s", Help::create_example_string("hash boost_1_62_0.tar.bz2")), @@ -44,19 +149,12 @@ namespace vcpkg::Commands::Hash void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { - args.parse_arguments(COMMAND_STRUCTURE); - - if (args.command_arguments.size() == 1) - { - auto hash = get_file_hash(paths, args.command_arguments[0], "SHA512"); - System::println(hash); - } - if (args.command_arguments.size() == 2) - { - auto hash = get_file_hash(paths, args.command_arguments[0], args.command_arguments[1]); - System::println(hash); - } + Util::unused(args.parse_arguments(COMMAND_STRUCTURE)); + const fs::path file_to_hash = args.command_arguments[0]; + const std::string algorithm = args.command_arguments.size() == 2 ? args.command_arguments[1] : "SHA512"; + const std::string hash = get_file_hash(paths, file_to_hash, algorithm); + System::println(hash); Checks::exit_success(VCPKG_LINE_INFO); } } diff --git a/toolsrc/vcpkg/vcpkg.vcxproj b/toolsrc/vcpkg/vcpkg.vcxproj index 4def6a74b..2ab94eb0a 100644 --- a/toolsrc/vcpkg/vcpkg.vcxproj +++ b/toolsrc/vcpkg/vcpkg.vcxproj @@ -77,7 +77,7 @@ false - winhttp.lib;version.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + winhttp.lib;version.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;Bcrypt.lib;%(AdditionalDependencies) @@ -91,7 +91,7 @@ false - winhttp.lib;version.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + winhttp.lib;version.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;Bcrypt.lib;%(AdditionalDependencies) @@ -109,7 +109,7 @@ true true - winhttp.lib;version.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + winhttp.lib;version.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;Bcrypt.lib;%(AdditionalDependencies) @@ -127,7 +127,7 @@ true true - winhttp.lib;version.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + winhttp.lib;version.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;Bcrypt.lib;%(AdditionalDependencies) diff --git a/toolsrc/vcpkgmetricsuploader/vcpkgmetricsuploader.vcxproj b/toolsrc/vcpkgmetricsuploader/vcpkgmetricsuploader.vcxproj index d78e48e13..a2ceef9ce 100644 --- a/toolsrc/vcpkgmetricsuploader/vcpkgmetricsuploader.vcxproj +++ b/toolsrc/vcpkgmetricsuploader/vcpkgmetricsuploader.vcxproj @@ -77,7 +77,7 @@ false - winhttp.lib;version.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + winhttp.lib;version.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;Bcrypt.lib;%(AdditionalDependencies) @@ -91,7 +91,7 @@ false - winhttp.lib;version.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + winhttp.lib;version.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;Bcrypt.lib;%(AdditionalDependencies) @@ -109,7 +109,7 @@ true true - winhttp.lib;version.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + winhttp.lib;version.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;Bcrypt.lib;%(AdditionalDependencies) @@ -127,7 +127,7 @@ true true - winhttp.lib;version.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + winhttp.lib;version.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;Bcrypt.lib;%(AdditionalDependencies) diff --git a/toolsrc/vcpkgtest/vcpkgtest.vcxproj b/toolsrc/vcpkgtest/vcpkgtest.vcxproj index d61b15a71..a0d44918d 100644 --- a/toolsrc/vcpkgtest/vcpkgtest.vcxproj +++ b/toolsrc/vcpkgtest/vcpkgtest.vcxproj @@ -120,6 +120,7 @@ Windows $(VCInstallDir)UnitTest\lib;$(VsInstallRoot)\VC\Auxiliary\VS\UnitTest\lib;%(AdditionalLibraryDirectories) + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;Bcrypt.lib;%(AdditionalDependencies) @@ -138,6 +139,7 @@ Windows $(VCInstallDir)UnitTest\lib;$(VsInstallRoot)\VC\Auxiliary\VS\UnitTest\lib;%(AdditionalLibraryDirectories) + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;Bcrypt.lib;%(AdditionalDependencies) @@ -159,6 +161,7 @@ true true $(VCInstallDir)UnitTest\lib;$(VsInstallRoot)\VC\Auxiliary\VS\UnitTest\lib;%(AdditionalLibraryDirectories) + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;Bcrypt.lib;%(AdditionalDependencies) @@ -180,6 +183,7 @@ true true $(VCInstallDir)UnitTest\lib;$(VsInstallRoot)\VC\Auxiliary\VS\UnitTest\lib;%(AdditionalLibraryDirectories) + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;Bcrypt.lib;%(AdditionalDependencies) -- cgit v1.2.3 From d80dd5cbc777ce765c2d6b78d7c485fdf05f284b Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Mon, 19 Mar 2018 15:45:35 -0700 Subject: [vcpkg] Handle failure to store archive --- toolsrc/include/vcpkg/base/files.h | 1 + toolsrc/src/vcpkg/base/files.cpp | 4 ++++ toolsrc/src/vcpkg/build.cpp | 9 ++++++--- 3 files changed, 11 insertions(+), 3 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/base/files.h b/toolsrc/include/vcpkg/base/files.h index 09393b9ee..ac1f192ae 100644 --- a/toolsrc/include/vcpkg/base/files.h +++ b/toolsrc/include/vcpkg/base/files.h @@ -36,6 +36,7 @@ namespace vcpkg::Files virtual void write_lines(const fs::path& file_path, const std::vector& lines) = 0; virtual void write_contents(const fs::path& file_path, const std::string& data, std::error_code& ec) = 0; virtual void rename(const fs::path& oldpath, const fs::path& newpath) = 0; + virtual void rename(const fs::path& oldpath, const fs::path& newpath, std::error_code& ec) = 0; virtual bool remove(const fs::path& path) = 0; virtual bool remove(const fs::path& path, std::error_code& ec) = 0; virtual std::uintmax_t remove_all(const fs::path& path, std::error_code& ec) = 0; diff --git a/toolsrc/src/vcpkg/base/files.cpp b/toolsrc/src/vcpkg/base/files.cpp index b59104a59..4e61666b7 100644 --- a/toolsrc/src/vcpkg/base/files.cpp +++ b/toolsrc/src/vcpkg/base/files.cpp @@ -108,6 +108,10 @@ namespace vcpkg::Files output.close(); } + virtual void rename(const fs::path& oldpath, const fs::path& newpath, std::error_code& ec) override + { + fs::stdfs::rename(oldpath, newpath, ec); + } virtual void rename(const fs::path& oldpath, const fs::path& newpath) override { fs::stdfs::rename(oldpath, newpath); diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index bc9eca3ba..ebded2736 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -618,9 +618,12 @@ namespace vcpkg::Build compress_archive(paths, spec, tmp_archive_path); fs.create_directories(archive_path.parent_path(), ec); - fs.rename(tmp_archive_path, archive_path); - - System::println("Stored binary cache: %s", archive_path.u8string()); + fs.rename(tmp_archive_path, archive_path, ec); + if (ec) + System::println( + System::Color::warning, "Failed to store binary cache: %s", archive_path.u8string()); + else + System::println("Stored binary cache: %s", archive_path.u8string()); } else if (result.code == BuildResult::BUILD_FAILED || result.code == BuildResult::POST_BUILD_CHECKS_FAILED) { -- cgit v1.2.3 From 1baa7f16420a359328761b330cdaf58b82b6656c Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 21 Mar 2018 16:19:06 -0700 Subject: Improve error message when PROGRAMFILES is not found --- toolsrc/src/vcpkg/base/system.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/base/system.cpp b/toolsrc/src/vcpkg/base/system.cpp index a315c7880..60067759a 100644 --- a/toolsrc/src/vcpkg/base/system.cpp +++ b/toolsrc/src/vcpkg/base/system.cpp @@ -533,7 +533,15 @@ namespace vcpkg::System static const fs::path& get_program_files() { - static const fs::path PATH = System::get_environment_variable("PROGRAMFILES").value_or_exit(VCPKG_LINE_INFO); + static const fs::path PATH = []() -> fs::path { + auto value = System::get_environment_variable("PROGRAMFILES"); + if (auto v = value.get()) + { + return *v; + } + Checks::exit_with_message(VCPKG_LINE_INFO, "Could not find PROGRAMFILES environment variable"); + }(); + return PATH; } @@ -543,7 +551,7 @@ namespace vcpkg::System auto value = System::get_environment_variable("ProgramFiles(x86)"); if (auto v = value.get()) { - return std::move(*v); + return *v; } return get_program_files(); }(); @@ -556,7 +564,7 @@ namespace vcpkg::System auto value = System::get_environment_variable("ProgramW6432"); if (auto v = value.get()) { - return std::move(*v); + return *v; } return get_program_files(); }(); -- cgit v1.2.3 From d45954a96b625ba1856ac97b429163a1919a3299 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 21 Mar 2018 18:21:30 -0700 Subject: System::get_program_files() now returns Optional --- toolsrc/include/vcpkg/base/system.h | 4 ++-- toolsrc/src/vcpkg/base/system.cpp | 35 ++++++++++++++++---------------- toolsrc/src/vcpkg/commands.edit.cpp | 20 +++++++++++++----- toolsrc/src/vcpkg/commands.integrate.cpp | 6 +++--- toolsrc/src/vcpkg/vcpkgpaths.cpp | 18 ++++++++-------- 5 files changed, 48 insertions(+), 35 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/base/system.h b/toolsrc/include/vcpkg/base/system.h index b2faf69bb..0d089276f 100644 --- a/toolsrc/include/vcpkg/base/system.h +++ b/toolsrc/include/vcpkg/base/system.h @@ -110,9 +110,9 @@ namespace vcpkg::System std::vector get_supported_host_architectures(); - const fs::path& get_program_files_32_bit(); + const Optional& get_program_files_32_bit(); - const fs::path& get_program_files_platform_bitness(); + const Optional& get_program_files_platform_bitness(); } namespace vcpkg::Debug diff --git a/toolsrc/src/vcpkg/base/system.cpp b/toolsrc/src/vcpkg/base/system.cpp index 60067759a..1094777af 100644 --- a/toolsrc/src/vcpkg/base/system.cpp +++ b/toolsrc/src/vcpkg/base/system.cpp @@ -224,21 +224,21 @@ namespace vcpkg::System env_cstr.push_back(L'\0'); } - if (extra_env.find("PATH") != extra_env.end()) - NEW_PATH += Strings::format(";%s", extra_env.find("PATH")->second); + if (extra_env.find("PATH") != extra_env.end()) + NEW_PATH += Strings::format(";%s", extra_env.find("PATH")->second); env_cstr.append(Strings::to_utf16(NEW_PATH)); env_cstr.push_back(L'\0'); env_cstr.append(L"VSLANG=1033"); env_cstr.push_back(L'\0'); - for (auto item : extra_env) - { - if (item.first == "PATH") continue; - env_cstr.append(Strings::to_utf16(item.first)); - env_cstr.push_back(L'='); - env_cstr.append(Strings::to_utf16(item.second)); - env_cstr.push_back(L'\0'); - } + for (auto item : extra_env) + { + if (item.first == "PATH") continue; + env_cstr.append(Strings::to_utf16(item.first)); + env_cstr.push_back(L'='); + env_cstr.append(Strings::to_utf16(item.second)); + env_cstr.push_back(L'\0'); + } STARTUPINFOW startup_info; memset(&startup_info, 0, sizeof(STARTUPINFOW)); @@ -531,23 +531,24 @@ namespace vcpkg::System } #endif - static const fs::path& get_program_files() + static const Optional& get_program_files() { - static const fs::path PATH = []() -> fs::path { + static const auto PATH = []() -> Optional { auto value = System::get_environment_variable("PROGRAMFILES"); if (auto v = value.get()) { return *v; } - Checks::exit_with_message(VCPKG_LINE_INFO, "Could not find PROGRAMFILES environment variable"); + + return nullopt; }(); return PATH; } - const fs::path& get_program_files_32_bit() + const Optional& get_program_files_32_bit() { - static const fs::path PATH = []() -> fs::path { + static const auto PATH = []() -> Optional { auto value = System::get_environment_variable("ProgramFiles(x86)"); if (auto v = value.get()) { @@ -558,9 +559,9 @@ namespace vcpkg::System return PATH; } - const fs::path& get_program_files_platform_bitness() + const Optional& get_program_files_platform_bitness() { - static const fs::path PATH = []() -> fs::path { + static const auto PATH = []() -> Optional { auto value = System::get_environment_variable("ProgramW6432"); if (auto v = value.get()) { diff --git a/toolsrc/src/vcpkg/commands.edit.cpp b/toolsrc/src/vcpkg/commands.edit.cpp index 41f261a53..ac34a6720 100644 --- a/toolsrc/src/vcpkg/commands.edit.cpp +++ b/toolsrc/src/vcpkg/commands.edit.cpp @@ -69,14 +69,24 @@ namespace vcpkg::Commands::Edit std::vector candidate_paths; auto maybe_editor_path = System::get_environment_variable("EDITOR"); - if (auto editor_path = maybe_editor_path.get()) + if (const std::string* editor_path = maybe_editor_path.get()) { candidate_paths.emplace_back(*editor_path); } - candidate_paths.push_back(System::get_program_files_platform_bitness() / VS_CODE_INSIDERS); - candidate_paths.push_back(System::get_program_files_32_bit() / VS_CODE_INSIDERS); - candidate_paths.push_back(System::get_program_files_platform_bitness() / VS_CODE); - candidate_paths.push_back(System::get_program_files_32_bit() / VS_CODE); + + const auto& program_files = System::get_program_files_platform_bitness(); + if (const fs::path* pf = program_files.get()) + { + candidate_paths.push_back(*pf / VS_CODE_INSIDERS); + candidate_paths.push_back(*pf / VS_CODE); + } + + const auto& program_files_32_bit = System::get_program_files_32_bit(); + if (const fs::path* pf = program_files_32_bit.get()) + { + candidate_paths.push_back(*pf / VS_CODE_INSIDERS); + candidate_paths.push_back(*pf / VS_CODE); + } const std::vector from_registry = find_from_registry(); candidate_paths.insert(candidate_paths.end(), from_registry.cbegin(), from_registry.cend()); diff --git a/toolsrc/src/vcpkg/commands.integrate.cpp b/toolsrc/src/vcpkg/commands.integrate.cpp index 460e99b88..36e4e56e7 100644 --- a/toolsrc/src/vcpkg/commands.integrate.cpp +++ b/toolsrc/src/vcpkg/commands.integrate.cpp @@ -148,12 +148,12 @@ namespace vcpkg::Commands::Integrate static void integrate_install(const VcpkgPaths& paths) { static const std::array OLD_SYSTEM_TARGET_FILES = { - System::get_program_files_32_bit() / + System::get_program_files_32_bit().value_or_exit(VCPKG_LINE_INFO) / "MSBuild/14.0/Microsoft.Common.Targets/ImportBefore/vcpkg.nuget.targets", - System::get_program_files_32_bit() / + System::get_program_files_32_bit().value_or_exit(VCPKG_LINE_INFO) / "MSBuild/14.0/Microsoft.Common.Targets/ImportBefore/vcpkg.system.targets"}; static const fs::path SYSTEM_WIDE_TARGETS_FILE = - System::get_program_files_32_bit() / + System::get_program_files_32_bit().value_or_exit(VCPKG_LINE_INFO) / "MSBuild/Microsoft.Cpp/v4.0/V140/ImportBefore/Default/vcpkg.system.props"; auto& fs = paths.get_filesystem(); diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index 46e80c4a9..63a484a86 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -190,10 +190,11 @@ namespace vcpkg #endif const std::vector from_path = Files::find_from_PATH("cmake"); candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); -#if defined(_WIN32) - candidate_paths.push_back(System::get_program_files_platform_bitness() / "CMake" / "bin" / "cmake.exe"); - candidate_paths.push_back(System::get_program_files_32_bit() / "CMake" / "bin"); -#endif + + const auto& program_files = System::get_program_files_platform_bitness(); + if (const auto pf = program_files.get()) candidate_paths.push_back(*pf / "CMake" / "bin" / "cmake.exe"); + const auto& program_files_32_bit = System::get_program_files_32_bit(); + if (const auto pf = program_files_32_bit.get()) candidate_paths.push_back(*pf / "CMake" / "bin" / "cmake.exe"); const Optional path = find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, TOOL_DATA.required_version); @@ -252,10 +253,11 @@ namespace vcpkg #endif const std::vector from_path = Files::find_from_PATH("git"); candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); -#if defined(_WIN32) - candidate_paths.push_back(System::get_program_files_platform_bitness() / "git" / "cmd" / "git.exe"); - candidate_paths.push_back(System::get_program_files_32_bit() / "git" / "cmd" / "git.exe"); -#endif + + const auto& program_files = System::get_program_files_platform_bitness(); + if (const auto pf = program_files.get()) candidate_paths.push_back(*pf / "git" / "cmd" / "git.exe"); + const auto& program_files_32_bit = System::get_program_files_32_bit(); + if (const auto pf = program_files_32_bit.get()) candidate_paths.push_back(*pf / "git" / "cmd" / "git.exe"); const Optional path = find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, TOOL_DATA.required_version); -- cgit v1.2.3 From c3fb0b169751ec0f25ac3752a7e83e21173073a4 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Thu, 22 Mar 2018 03:08:25 -0700 Subject: [vcpkg] Download cmake on osx and linux --- toolsrc/src/vcpkg/base/system.cpp | 6 ++-- toolsrc/src/vcpkg/vcpkgpaths.cpp | 73 ++++++++++++++++++++++++++++++++------- 2 files changed, 63 insertions(+), 16 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/base/system.cpp b/toolsrc/src/vcpkg/base/system.cpp index 1094777af..171dd2bbf 100644 --- a/toolsrc/src/vcpkg/base/system.cpp +++ b/toolsrc/src/vcpkg/base/system.cpp @@ -285,14 +285,14 @@ namespace vcpkg::System fflush(nullptr); // Basically we are wrapping it in quotes - const std::string& actual_cmd_line = Strings::format(R"###("%s")###", cmd_line); #if defined(_WIN32) + const std::string& actual_cmd_line = Strings::format(R"###("%s")###", cmd_line); Debug::println("_wsystem(%s)", actual_cmd_line); const int exit_code = _wsystem(Strings::to_utf16(actual_cmd_line).c_str()); Debug::println("_wsystem() returned %d", exit_code); #else - Debug::println("_system(%s)", actual_cmd_line); - const int exit_code = system(actual_cmd_line.c_str()); + Debug::println("_system(%s)", cmd_line); + const int exit_code = system(cmd_line.c_str()); Debug::println("_system() returned %d", exit_code); #endif return exit_code; diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index 63a484a86..c36def15d 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -19,6 +19,8 @@ namespace vcpkg { std::array required_version; fs::path downloaded_exe_path; + std::string url; + fs::path downloaded_path; }; static Optional> parse_version_string(const std::string& version_as_string) @@ -41,8 +43,24 @@ namespace vcpkg static ToolData parse_tool_data_from_xml(const VcpkgPaths& paths, const std::string& tool) { +#if defined(_WIN32) + static constexpr StringLiteral OS_STRING = ""; +#elif defined(__APPLE__) + static constexpr StringLiteral OS_STRING = " os=\"osx\""; +#else // assume linux + static constexpr StringLiteral OS_STRING = " os=\"linux\""; +#endif + static const fs::path XML_PATH = paths.scripts / "vcpkgTools.xml"; + const auto maybe_get_string_inside_tags = [](const std::string& input, + const std::regex& regex) -> Optional { + std::smatch match; + const bool has_match = std::regex_search(input.cbegin(), input.cend(), match, regex); + if (!has_match) return nullopt; + return match[1]; + }; + const auto get_string_inside_tags = [](const std::string& input, const std::regex& regex, const std::string& tag_name) -> std::string { std::smatch match; @@ -57,7 +75,10 @@ namespace vcpkg static const std::regex VERSION_REGEX{ Strings::format(R"###(([\s\S]*?))###", tool)}; static const std::regex EXE_RELATIVE_PATH_REGEX{ - Strings::format(R"###(([\s\S]*?))###", tool)}; + Strings::format(R"###(([\s\S]*?))###", OS_STRING)}; + static const std::regex ARCHIVE_RELATIVE_PATH_REGEX{ + Strings::format(R"###(([\s\S]*?))###", OS_STRING)}; + static const std::regex URL_REGEX{Strings::format(R"###(([\s\S]*?))###", OS_STRING)}; const std::regex tool_regex{Strings::format(R"###(([\s\S]*?))###", tool)}; @@ -74,9 +95,13 @@ namespace vcpkg const std::string required_version_as_string = get_string_inside_tags(tool_data_as_string, VERSION_REGEX, "requiredVersion"); + const std::string url = get_string_inside_tags(tool_data_as_string, URL_REGEX, "url"); + const std::string exe_relative_path = get_string_inside_tags(tool_data_as_string, EXE_RELATIVE_PATH_REGEX, "exeRelativePath"); + auto archive_relative_path = maybe_get_string_inside_tags(tool_data_as_string, ARCHIVE_RELATIVE_PATH_REGEX); + const Optional> required_version = parse_version_string(required_version_as_string); Checks::check_exit(VCPKG_LINE_INFO, required_version.has_value(), @@ -85,7 +110,10 @@ namespace vcpkg required_version_as_string); const fs::path exe_path = paths.downloads / exe_relative_path; - return ToolData{*required_version.get(), exe_path}; + return ToolData{*required_version.get(), + exe_path, + url, + paths.downloads / archive_relative_path.value_or(exe_relative_path)}; } static bool exists_and_has_equal_or_greater_version(const std::string& version_cmd, @@ -144,8 +172,10 @@ namespace vcpkg return data_lines; } - static fs::path fetch_tool(const fs::path& scripts_folder, const std::string& tool_name, const ToolData& tool_data) + static fs::path fetch_tool(const VcpkgPaths& paths, const std::string& tool_name, const ToolData& tool_data) { + const auto& fs = paths.get_filesystem(); + const fs::path& scripts_folder = paths.scripts; const std::array& version = tool_data.required_version; const std::string version_as_string = Strings::format("%d.%d.%d", version[0], version[1], version[2]); @@ -154,6 +184,7 @@ namespace vcpkg version_as_string, tool_name, version_as_string); +#if defined(_WIN32) const fs::path script = scripts_folder / "fetchtool.ps1"; const std::string title = Strings::format( "Fetching %s version %s (No sufficient installed version was found)", tool_name, version_as_string); @@ -173,21 +204,37 @@ namespace vcpkg expected_downloaded_path.u8string(), actual_downloaded_path.u8string()); return actual_downloaded_path; +#else + if (!fs.exists(tool_data.downloaded_path)) + { + auto code = System::cmd_execute( + Strings::format(R"(curl '%s' --create-dirs --output '%s')", tool_data.url, tool_data.downloaded_path)); + Checks::check_exit(VCPKG_LINE_INFO, code == 0, "curl failed while downloading %s", tool_data.url); + } + auto code = System::cmd_execute( + Strings::format(R"(cd '%s' && tar xzf '%s')", paths.downloads, tool_data.downloaded_path)); + Checks::check_exit(VCPKG_LINE_INFO, code == 0, "tar failed while extracting %s", tool_data.downloaded_path); + + Checks::check_exit(VCPKG_LINE_INFO, + fs.exists(tool_data.downloaded_exe_path), + "Expected %s to exist after extracting", + tool_data.downloaded_exe_path); + + return tool_data.downloaded_exe_path; +#endif } static fs::path get_cmake_path(const VcpkgPaths& paths) { -#if defined(_WIN32) + std::vector candidate_paths; +#if defined(_WIN32) || defined(__APPLE__) || defined(__linux__) static const ToolData TOOL_DATA = parse_tool_data_from_xml(paths, "cmake"); + candidate_paths.push_back(TOOL_DATA.downloaded_exe_path); #else static const ToolData TOOL_DATA = ToolData{{3, 5, 1}, ""}; #endif static const std::string VERSION_CHECK_ARGUMENTS = "--version"; - std::vector candidate_paths; -#if defined(_WIN32) - candidate_paths.push_back(TOOL_DATA.downloaded_exe_path); -#endif const std::vector from_path = Files::find_from_PATH("cmake"); candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); @@ -203,7 +250,7 @@ namespace vcpkg return *p; } - return fetch_tool(paths.scripts, "cmake", TOOL_DATA); + return fetch_tool(paths, "cmake", TOOL_DATA); } static fs::path get_7za_path(const VcpkgPaths& paths) @@ -212,7 +259,7 @@ namespace vcpkg static const ToolData TOOL_DATA = parse_tool_data_from_xml(paths, "7zip"); if (!paths.get_filesystem().exists(TOOL_DATA.downloaded_exe_path)) { - return fetch_tool(paths.scripts, "7zip", TOOL_DATA); + return fetch_tool(paths, "7zip", TOOL_DATA); } return TOOL_DATA.downloaded_exe_path; #else @@ -235,7 +282,7 @@ namespace vcpkg return *p; } - return fetch_tool(paths.scripts, "nuget", TOOL_DATA); + return fetch_tool(paths, "nuget", TOOL_DATA); } static fs::path get_git_path(const VcpkgPaths& paths) @@ -266,7 +313,7 @@ namespace vcpkg return *p; } - return fetch_tool(paths.scripts, "git", TOOL_DATA); + return fetch_tool(paths, "git", TOOL_DATA); } static fs::path get_ifw_installerbase_path(const VcpkgPaths& paths) @@ -292,7 +339,7 @@ namespace vcpkg return *p; } - return fetch_tool(paths.scripts, "installerbase", TOOL_DATA); + return fetch_tool(paths, "installerbase", TOOL_DATA); } Expected VcpkgPaths::create(const fs::path& vcpkg_root_dir, const std::string& default_vs_path) -- cgit v1.2.3 From 1f62b32641045fe377ee80ff1854a785344687d2 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Thu, 22 Mar 2018 10:01:12 -0700 Subject: [vcpkg] Sort abi tags to ensure stability --- toolsrc/include/vcpkg/build.h | 5 +++++ toolsrc/src/vcpkg/build.cpp | 2 ++ 2 files changed, 7 insertions(+) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/build.h b/toolsrc/include/vcpkg/build.h index 8c4d7b575..1c22d39d8 100644 --- a/toolsrc/include/vcpkg/build.h +++ b/toolsrc/include/vcpkg/build.h @@ -209,6 +209,11 @@ namespace vcpkg::Build { std::string key; std::string value; + + bool operator<(const AbiEntry& other) const + { + return key < other.key || (key == other.key && value < other.value); + } }; struct AbiTagAndFile diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index ebded2736..953e77460 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -449,6 +449,8 @@ namespace vcpkg::Build if (config.build_package_options.use_head_version == UseHeadVersion::YES) abi_tag_entries.emplace_back(AbiEntry{"head", ""}); + Util::sort(abi_tag_entries); + std::string full_abi_info = Strings::join("", abi_tag_entries, [](const AbiEntry& p) { return p.key + " " + p.value + "\n"; }); -- cgit v1.2.3 From 69dfad795f4ffb5bec60602ec1116730027ff088 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 14 Mar 2018 16:48:18 -0700 Subject: Introduce Maps::transform_values() --- toolsrc/include/vcpkg/base/util.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/base/util.h b/toolsrc/include/vcpkg/base/util.h index c73345719..7266fbbc6 100644 --- a/toolsrc/include/vcpkg/base/util.h +++ b/toolsrc/include/vcpkg/base/util.h @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -29,6 +30,17 @@ namespace vcpkg::Util } } + namespace Maps + { + template + void transform_values(const std::unordered_map& container, std::unordered_map& output, Func func) + { + std::for_each(container.cbegin(), container.cend(), [&](const std::pair& p) { + output[p.first] = func(p.second); + }); + } + } + template using FmapOut = decltype(std::declval()(*begin(std::declval()))); -- cgit v1.2.3 From d5580dd330bac4d473f146e6efe3756e83a35066 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Sat, 24 Mar 2018 01:24:07 -0700 Subject: Join declaration and assignment --- toolsrc/src/vcpkg/install.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp index e30a34c18..7a963c82f 100644 --- a/toolsrc/src/vcpkg/install.cpp +++ b/toolsrc/src/vcpkg/install.cpp @@ -558,16 +558,15 @@ namespace vcpkg::Install Build::CleanBuildtrees::NO, Build::CleanPackages::NO}; - // Note: action_plan will hold raw pointers to SourceControlFiles from this map - std::vector action_plan; - auto all_ports = Paragraphs::load_all_ports(paths.get_filesystem(), paths.ports); std::unordered_map scf_map; for (auto&& port : all_ports) scf_map[port->core_paragraph->name] = std::move(*port); MapPortFileProvider provider(scf_map); - action_plan = create_feature_install_plan(provider, FullPackageSpec::to_feature_specs(specs), status_db); + // Note: action_plan will hold raw pointers to SourceControlFiles from this map + std::vector action_plan = + create_feature_install_plan(provider, FullPackageSpec::to_feature_specs(specs), status_db); if (!GlobalState::feature_packages) { -- cgit v1.2.3 From 3a91b0072d7500f2be84fe4d6520e8469ba5b5ad Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Sat, 24 Mar 2018 01:04:48 -0700 Subject: Fix name --- toolsrc/include/vcpkg/dependencies.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/dependencies.h b/toolsrc/include/vcpkg/dependencies.h index 33af6c4f5..fea0d88a9 100644 --- a/toolsrc/include/vcpkg/dependencies.h +++ b/toolsrc/include/vcpkg/dependencies.h @@ -175,7 +175,7 @@ namespace vcpkg::Dependencies const std::vector& specs, const StatusParagraphs& status_db); - std::vector create_feature_install_plan(const PortFileProvider& port_file_provider, + std::vector create_feature_install_plan(const PortFileProvider& provider, const std::vector& specs, const StatusParagraphs& status_db); -- cgit v1.2.3 From 7029daa36df7040e420b3722f345b6923ce93ef0 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Fri, 23 Mar 2018 09:59:42 -0700 Subject: [vcpkg] Handle non-sorted output from std::filesystem --- toolsrc/src/vcpkg/install.cpp | 4 ++-- toolsrc/src/vcpkg/paragraphs.cpp | 4 +++- toolsrc/src/vcpkg/vcpkglib.cpp | 1 + toolsrc/src/vcpkg/vcpkgpaths.cpp | 1 + 4 files changed, 7 insertions(+), 3 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp index 7a963c82f..1fbf6d97e 100644 --- a/toolsrc/src/vcpkg/install.cpp +++ b/toolsrc/src/vcpkg/install.cpp @@ -70,8 +70,8 @@ namespace vcpkg::Install } const std::string filename = file.filename().u8string(); - if (fs::is_regular_file(status) && (Strings::case_insensitive_ascii_equals(filename.c_str(), "CONTROL") || - Strings::case_insensitive_ascii_equals(filename.c_str(), "BUILD_INFO"))) + if (fs::is_regular_file(status) && (Strings::case_insensitive_ascii_equals(filename, "CONTROL") || + Strings::case_insensitive_ascii_equals(filename, "BUILD_INFO"))) { // Do not copy the control file continue; diff --git a/toolsrc/src/vcpkg/paragraphs.cpp b/toolsrc/src/vcpkg/paragraphs.cpp index d0b0c0abf..41ffceec7 100644 --- a/toolsrc/src/vcpkg/paragraphs.cpp +++ b/toolsrc/src/vcpkg/paragraphs.cpp @@ -251,7 +251,9 @@ namespace vcpkg::Paragraphs LoadResults try_load_all_ports(const Files::Filesystem& fs, const fs::path& ports_dir) { LoadResults ret; - for (auto&& path : fs.get_files_non_recursive(ports_dir)) + auto port_dirs = fs.get_files_non_recursive(ports_dir); + Util::sort(port_dirs); + for (auto&& path : port_dirs) { auto maybe_spgh = try_load_port(fs, path); if (const auto spgh = maybe_spgh.get()) diff --git a/toolsrc/src/vcpkg/vcpkglib.cpp b/toolsrc/src/vcpkg/vcpkglib.cpp index 220c29720..7979fd9a5 100644 --- a/toolsrc/src/vcpkg/vcpkglib.cpp +++ b/toolsrc/src/vcpkg/vcpkglib.cpp @@ -54,6 +54,7 @@ namespace vcpkg StatusParagraphs current_status_db = load_current_database(fs, status_file, status_file_old); auto update_files = fs.get_files_non_recursive(updates_dir); + Util::sort(update_files); if (update_files.empty()) { // updates directory is empty, control file is up-to-date. diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index c36def15d..9b331d7fc 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -405,6 +405,7 @@ namespace vcpkg { output.push_back(path.stem().filename().string()); } + Util::sort(output); return output; }); -- cgit v1.2.3 From c814c9b8ac883aa42930e1f48660145fd4234fe6 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 27 Mar 2018 13:23:30 -0700 Subject: [vcpkgTools.xml] Restructre os-specific info --- toolsrc/src/vcpkg/vcpkgpaths.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index 9b331d7fc..feacda026 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -46,9 +46,9 @@ namespace vcpkg #if defined(_WIN32) static constexpr StringLiteral OS_STRING = ""; #elif defined(__APPLE__) - static constexpr StringLiteral OS_STRING = " os=\"osx\""; + static constexpr StringLiteral OS_STRING = R"(os="osx")"; #else // assume linux - static constexpr StringLiteral OS_STRING = " os=\"linux\""; + static constexpr StringLiteral OS_STRING = R"(os="linux")"; #endif static const fs::path XML_PATH = paths.scripts / "vcpkgTools.xml"; @@ -72,15 +72,15 @@ namespace vcpkg }; static const std::string XML = paths.get_filesystem().read_contents(XML_PATH).value_or_exit(VCPKG_LINE_INFO); - static const std::regex VERSION_REGEX{ - Strings::format(R"###(([\s\S]*?))###", tool)}; + static const std::regex VERSION_REGEX{R"###(([\s\S]*?))###"}; static const std::regex EXE_RELATIVE_PATH_REGEX{ - Strings::format(R"###(([\s\S]*?))###", OS_STRING)}; + Strings::format(R"###(([\s\S]*?))###")}; static const std::regex ARCHIVE_RELATIVE_PATH_REGEX{ - Strings::format(R"###(([\s\S]*?))###", OS_STRING)}; - static const std::regex URL_REGEX{Strings::format(R"###(([\s\S]*?))###", OS_STRING)}; + Strings::format(R"###(([\s\S]*?))###")}; + static const std::regex URL_REGEX{Strings::format(R"###(([\s\S]*?))###")}; - const std::regex tool_regex{Strings::format(R"###(([\s\S]*?))###", tool)}; + const std::regex tool_regex{ + Strings::format(R"###(([\s\S]*?))###", tool, OS_STRING)}; std::smatch match_tool; const bool has_match_tool = std::regex_search(XML.cbegin(), XML.cend(), match_tool, tool_regex); -- cgit v1.2.3 From ee1409f432711e59b58bd170f021949e8e12aedd Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 27 Mar 2018 21:39:23 -0700 Subject: Hotfix #3144 --- toolsrc/src/vcpkg/vcpkgpaths.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index feacda026..a17ffeb05 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -80,7 +80,7 @@ namespace vcpkg static const std::regex URL_REGEX{Strings::format(R"###(([\s\S]*?))###")}; const std::regex tool_regex{ - Strings::format(R"###(([\s\S]*?))###", tool, OS_STRING)}; + Strings::format(R"###(([\s\S]*?))###", tool, OS_STRING)}; std::smatch match_tool; const bool has_match_tool = std::regex_search(XML.cbegin(), XML.cend(), match_tool, tool_regex); -- cgit v1.2.3 From 398a972357d059a8d27adb657a33da6cf2a52450 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 27 Mar 2018 21:48:48 -0700 Subject: Update CHANGELOG and bump version to v0.0.107 --- toolsrc/VERSION.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/VERSION.txt b/toolsrc/VERSION.txt index 1305e8f43..daa1cd86e 100644 --- a/toolsrc/VERSION.txt +++ b/toolsrc/VERSION.txt @@ -1 +1 @@ -"0.0.106" \ No newline at end of file +"0.0.107" \ No newline at end of file -- cgit v1.2.3 From ba7b8e6d7336fd4529cfe1de50b224a98d6ff496 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 29 Mar 2018 15:29:16 -0700 Subject: Add message for appleclang versions that don't support std::filesystem --- toolsrc/CMakeLists.txt | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'toolsrc') diff --git a/toolsrc/CMakeLists.txt b/toolsrc/CMakeLists.txt index da0f41631..2a1304526 100644 --- a/toolsrc/CMakeLists.txt +++ b/toolsrc/CMakeLists.txt @@ -3,6 +3,12 @@ project(vcpkg C CXX) if(CMAKE_COMPILER_IS_GNUXX OR CMAKE_CXX_COMPILER_ID MATCHES "GNU") set(GCC 1) +elseif(CMAKE_CXX_COMPILER_ID MATCHES "AppleClang") + if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS_EQUAL 9.0.0) + message(FATAL_ERROR "Apple clang versions 9 and below do not have support for the C++ Filesystem TS. Please install gcc6 or newer from homebrew (brew install gcc6).") + else() + set(CLANG 1) + endif() elseif(CMAKE_CXX_COMPILER_ID MATCHES "[Cc]lang") set(CLANG 1) elseif(MSVC) -- cgit v1.2.3 From 35bbd4015a906c92b394698779e57fc2945505cc Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 30 Mar 2018 14:46:22 -0700 Subject: Improve message for appleclang --- toolsrc/CMakeLists.txt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/CMakeLists.txt b/toolsrc/CMakeLists.txt index 2a1304526..acc12f2b3 100644 --- a/toolsrc/CMakeLists.txt +++ b/toolsrc/CMakeLists.txt @@ -4,8 +4,12 @@ project(vcpkg C CXX) if(CMAKE_COMPILER_IS_GNUXX OR CMAKE_CXX_COMPILER_ID MATCHES "GNU") set(GCC 1) elseif(CMAKE_CXX_COMPILER_ID MATCHES "AppleClang") - if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS_EQUAL 9.0.0) - message(FATAL_ERROR "Apple clang versions 9 and below do not have support for the C++ Filesystem TS. Please install gcc6 or newer from homebrew (brew install gcc6).") + if(NOT VCPKG_ALLOW_APPLE_CLANG) + message(FATAL_ERROR +"Building the vcpkg tool requires support for the C++ Filesystem TS. +Apple clang versions 9 and below do not have support for it. +Please install gcc6 or newer from homebrew (brew install gcc6). +If you would like to try anyway, set VCPKG_ALLOW_APPLE_CLANG.") else() set(CLANG 1) endif() -- cgit v1.2.3 From 4a9feaa2403e59b3267f8bd02ef2fd687ea5661d Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 30 Mar 2018 18:44:13 -0700 Subject: Allow usage of os="windows" in vcpkgTools.xml from vcpkg.exe (use-cases in powershell still need to be modified) --- toolsrc/src/vcpkg/vcpkgpaths.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index a17ffeb05..7ab4c1c98 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -44,11 +44,11 @@ namespace vcpkg static ToolData parse_tool_data_from_xml(const VcpkgPaths& paths, const std::string& tool) { #if defined(_WIN32) - static constexpr StringLiteral OS_STRING = ""; + static constexpr StringLiteral OS_STRING = "windows"; #elif defined(__APPLE__) - static constexpr StringLiteral OS_STRING = R"(os="osx")"; + static constexpr StringLiteral OS_STRING = "osx"; #else // assume linux - static constexpr StringLiteral OS_STRING = R"(os="linux")"; + static constexpr StringLiteral OS_STRING = "linux"; #endif static const fs::path XML_PATH = paths.scripts / "vcpkgTools.xml"; @@ -79,11 +79,16 @@ namespace vcpkg Strings::format(R"###(([\s\S]*?))###")}; static const std::regex URL_REGEX{Strings::format(R"###(([\s\S]*?))###")}; - const std::regex tool_regex{ - Strings::format(R"###(([\s\S]*?))###", tool, OS_STRING)}; + std::regex tool_regex{ + Strings::format(R"###(([\s\S]*?)<\/tool>)###", tool, OS_STRING)}; std::smatch match_tool; - const bool has_match_tool = std::regex_search(XML.cbegin(), XML.cend(), match_tool, tool_regex); + bool has_match_tool = std::regex_search(XML.cbegin(), XML.cend(), match_tool, tool_regex); + if (!has_match_tool && OS_STRING == "windows") // Legacy support. Change introduced in vcpkg v0.0.107. + { + tool_regex = Strings::format(R"###(([\s\S]*?)<\/tool>)###", tool); + has_match_tool = std::regex_search(XML.cbegin(), XML.cend(), match_tool, tool_regex); + } Checks::check_exit(VCPKG_LINE_INFO, has_match_tool, "Could not find entry for tool [%s] in %s", -- cgit v1.2.3 From adccba04db25b3e3bd44c58a9d2cbc1366e53fde Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 2 Apr 2018 17:12:12 -0700 Subject: [vcpkg.exe] Look for vcpkgTools in downloads/tools/$toolname-$toolversion (only non-windows currently) --- toolsrc/include/vcpkg/vcpkgpaths.h | 2 + toolsrc/src/vcpkg/build.cpp | 6 +++ toolsrc/src/vcpkg/vcpkgpaths.cpp | 94 ++++++++++++++++++++++++++++++++------ 3 files changed, 87 insertions(+), 15 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/vcpkgpaths.h b/toolsrc/include/vcpkg/vcpkgpaths.h index 71f1bbba9..b3f24fb89 100644 --- a/toolsrc/include/vcpkg/vcpkgpaths.h +++ b/toolsrc/include/vcpkg/vcpkgpaths.h @@ -66,6 +66,7 @@ namespace vcpkg const fs::path& get_7za_exe() const; const fs::path& get_cmake_exe() const; const fs::path& get_git_exe() const; + const fs::path& get_ninja_exe() const; const fs::path& get_nuget_exe() const; const fs::path& get_ifw_installerbase_exe() const; const fs::path& get_ifw_binarycreator_exe() const; @@ -84,6 +85,7 @@ namespace vcpkg Lazy _7za_exe; Lazy cmake_exe; Lazy git_exe; + Lazy ninja_exe; Lazy nuget_exe; Lazy ifw_installerbase_exe; Lazy ifw_binarycreator_exe; diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index 953e77460..ab2e46aa7 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -322,6 +322,12 @@ namespace vcpkg::Build auto& fs = paths.get_filesystem(); const Triplet& triplet = spec.triplet(); +#if !defined(_WIN32) + // TODO: remove when vcpkg.exe is in charge for acquiring tools. Change introduced in vcpkg v0.0.107. + // bootstrap should have already downloaded ninja, but making sure it is present in case it was deleted. + vcpkg::Util::unused(paths.get_ninja_exe()); +#endif + const fs::path& cmake_exe_path = paths.get_cmake_exe(); const fs::path& git_exe_path = paths.get_git_exe(); diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index 7ab4c1c98..d4bcea5af 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -18,9 +18,10 @@ namespace vcpkg struct ToolData { std::array required_version; - fs::path downloaded_exe_path; + fs::path exe_path; std::string url; fs::path downloaded_path; + fs::path tool_dir_path; }; static Optional> parse_version_string(const std::string& version_as_string) @@ -114,11 +115,20 @@ namespace vcpkg tool, required_version_as_string); +// Legacy support. Change introduced in vcpkg v0.0.107. +#if !defined(_WIN32) + const std::string tool_dir_name = Strings::format("%s-%s", tool, required_version_as_string); + const fs::path tool_dir_path = paths.downloads / "tools" / tool_dir_name; + const fs::path exe_path = tool_dir_path / exe_relative_path; +#else + const fs::path tool_dir_path; const fs::path exe_path = paths.downloads / exe_relative_path; +#endif return ToolData{*required_version.get(), exe_path, url, - paths.downloads / archive_relative_path.value_or(exe_relative_path)}; + paths.downloads / archive_relative_path.value_or(exe_relative_path), + tool_dir_path}; } static bool exists_and_has_equal_or_greater_version(const std::string& version_cmd, @@ -177,6 +187,36 @@ namespace vcpkg return data_lines; } + static void extract_archive(const VcpkgPaths& paths, const fs::path& archive, const fs::path& to_path) + { + Files::Filesystem& fs = paths.get_filesystem(); + const fs::path to_path_partial = to_path.u8string() + ".partial"; + + std::error_code ec; + fs.remove_all(to_path_partial, ec); + fs.create_directories(to_path_partial, ec); + + const auto ext = archive.extension(); + if (ext == ".gz" && ext.extension() != ".tar") + { + const auto code = System::cmd_execute( + Strings::format(R"(cd '%s' && tar xzf '%s')", to_path_partial.u8string(), archive.u8string())); + Checks::check_exit(VCPKG_LINE_INFO, code == 0, "tar failed while extracting %s", archive.u8string()); + } + else if (ext == ".zip") + { + const auto code = System::cmd_execute( + Strings::format(R"(cd '%s' && unzip -qqo '%s')", to_path_partial.u8string(), archive.u8string())); + Checks::check_exit(VCPKG_LINE_INFO, code == 0, "unzip failed while extracting %s", archive.u8string()); + } + else + { + Checks::exit_with_message(VCPKG_LINE_INFO, "Unexpected archive extension: %s", ext.u8string()); + } + + fs.rename(to_path_partial, to_path); + } + static fs::path fetch_tool(const VcpkgPaths& paths, const std::string& tool_name, const ToolData& tool_data) { const auto& fs = paths.get_filesystem(); @@ -200,7 +240,7 @@ namespace vcpkg Checks::check_exit(VCPKG_LINE_INFO, tool_path.size() == 1, "Expected tool path, but got %s", output); const fs::path actual_downloaded_path = Strings::trim(std::string{tool_path.at(0)}); - const fs::path& expected_downloaded_path = tool_data.downloaded_exe_path; + const fs::path& expected_downloaded_path = tool_data.exe_path; std::error_code ec; const auto eq = fs::stdfs::equivalent(expected_downloaded_path, actual_downloaded_path, ec); Checks::check_exit(VCPKG_LINE_INFO, @@ -216,16 +256,17 @@ namespace vcpkg Strings::format(R"(curl '%s' --create-dirs --output '%s')", tool_data.url, tool_data.downloaded_path)); Checks::check_exit(VCPKG_LINE_INFO, code == 0, "curl failed while downloading %s", tool_data.url); } - auto code = System::cmd_execute( - Strings::format(R"(cd '%s' && tar xzf '%s')", paths.downloads, tool_data.downloaded_path)); - Checks::check_exit(VCPKG_LINE_INFO, code == 0, "tar failed while extracting %s", tool_data.downloaded_path); + + System::println("Extracting %s...", tool_name); + extract_archive(paths, tool_data.downloaded_path, tool_data.tool_dir_path); + System::println("Extracting %s... done.", tool_name); Checks::check_exit(VCPKG_LINE_INFO, - fs.exists(tool_data.downloaded_exe_path), + fs.exists(tool_data.exe_path), "Expected %s to exist after extracting", - tool_data.downloaded_exe_path); + tool_data.exe_path); - return tool_data.downloaded_exe_path; + return tool_data.exe_path; #endif } @@ -234,7 +275,7 @@ namespace vcpkg std::vector candidate_paths; #if defined(_WIN32) || defined(__APPLE__) || defined(__linux__) static const ToolData TOOL_DATA = parse_tool_data_from_xml(paths, "cmake"); - candidate_paths.push_back(TOOL_DATA.downloaded_exe_path); + candidate_paths.push_back(TOOL_DATA.exe_path); #else static const ToolData TOOL_DATA = ToolData{{3, 5, 1}, ""}; #endif @@ -262,22 +303,40 @@ namespace vcpkg { #if defined(_WIN32) static const ToolData TOOL_DATA = parse_tool_data_from_xml(paths, "7zip"); - if (!paths.get_filesystem().exists(TOOL_DATA.downloaded_exe_path)) + if (!paths.get_filesystem().exists(TOOL_DATA.exe_path)) { return fetch_tool(paths, "7zip", TOOL_DATA); } - return TOOL_DATA.downloaded_exe_path; + return TOOL_DATA.exe_path; #else Checks::exit_with_message(VCPKG_LINE_INFO, "Cannot download 7zip for non-Windows platforms."); #endif } + static fs::path get_ninja_path(const VcpkgPaths& paths) + { + static const ToolData TOOL_DATA = parse_tool_data_from_xml(paths, "ninja"); + + std::vector candidate_paths; + candidate_paths.push_back(TOOL_DATA.exe_path); + const std::vector from_path = Files::find_from_PATH("ninja"); + candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); + + auto path = find_if_has_equal_or_greater_version(candidate_paths, "--version", TOOL_DATA.required_version); + if (const auto p = path.get()) + { + return *p; + } + + return fetch_tool(paths, "ninja", TOOL_DATA); + } + static fs::path get_nuget_path(const VcpkgPaths& paths) { static const ToolData TOOL_DATA = parse_tool_data_from_xml(paths, "nuget"); std::vector candidate_paths; - candidate_paths.push_back(TOOL_DATA.downloaded_exe_path); + candidate_paths.push_back(TOOL_DATA.exe_path); const std::vector from_path = Files::find_from_PATH("nuget"); candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); @@ -301,7 +360,7 @@ namespace vcpkg std::vector candidate_paths; #if defined(_WIN32) - candidate_paths.push_back(TOOL_DATA.downloaded_exe_path); + candidate_paths.push_back(TOOL_DATA.exe_path); #endif const std::vector from_path = Files::find_from_PATH("git"); candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); @@ -328,7 +387,7 @@ namespace vcpkg static const std::string VERSION_CHECK_ARGUMENTS = "--framework-version"; std::vector candidate_paths; - candidate_paths.push_back(TOOL_DATA.downloaded_exe_path); + candidate_paths.push_back(TOOL_DATA.exe_path); // TODO: Uncomment later // const std::vector from_path = Files::find_from_PATH("installerbase"); // candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); @@ -438,6 +497,11 @@ namespace vcpkg return this->git_exe.get_lazy([this]() { return get_git_path(*this); }); } + const fs::path& VcpkgPaths::get_ninja_exe() const + { + return this->ninja_exe.get_lazy([this]() { return get_ninja_path(*this); }); + } + const fs::path& VcpkgPaths::get_nuget_exe() const { return this->nuget_exe.get_lazy([this]() { return get_nuget_path(*this); }); -- cgit v1.2.3 From 892f7052f943570eb5d8da991ace01725323c695 Mon Sep 17 00:00:00 2001 From: Jacob Zhong Date: Wed, 7 Mar 2018 17:57:16 +0800 Subject: [vcpkg] Add support of external downloader aria2 --- toolsrc/include/vcpkg/build.h | 8 ++++++++ toolsrc/src/vcpkg/build.cpp | 19 +++++++++++++++++-- toolsrc/src/vcpkg/install.cpp | 12 ++++++++++-- 3 files changed, 35 insertions(+), 4 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/build.h b/toolsrc/include/vcpkg/build.h index 1c22d39d8..a86245ccf 100644 --- a/toolsrc/include/vcpkg/build.h +++ b/toolsrc/include/vcpkg/build.h @@ -57,12 +57,20 @@ namespace vcpkg::Build RELEASE, }; + enum class DownloadTool + { + BUILT_IN, + ARIA2, + }; + const std::string& to_string(DownloadTool tool); + struct BuildPackageOptions { UseHeadVersion use_head_version; AllowDownloads allow_downloads; CleanBuildtrees clean_buildtrees; CleanPackages clean_packages; + DownloadTool download_tool; }; enum class BuildResult diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index ab2e46aa7..79a55bd36 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -165,6 +165,19 @@ namespace vcpkg::Build } } + static const std::string NAME_BUILD_IN_DOWNLOAD = "BUILT_IN"; + static const std::string NAME_ARIA2_DOWNLOAD = "ARIA2"; + + const std::string& to_string(DownloadTool tool) + { + switch (tool) + { + case DownloadTool::BUILT_IN: return NAME_BUILD_IN_DOWNLOAD; + case DownloadTool::ARIA2: return NAME_ARIA2_DOWNLOAD; + default: Checks::unreachable(VCPKG_LINE_INFO); + } + } + Optional to_linkage_type(const std::string& str) { if (str == "dynamic") return LinkageType::DYNAMIC; @@ -348,8 +361,10 @@ namespace vcpkg::Build {"TARGET_TRIPLET", spec.triplet().canonical_name()}, {"VCPKG_PLATFORM_TOOLSET", toolset.version.c_str()}, {"VCPKG_USE_HEAD_VERSION", - Util::Enum::to_bool(config.build_package_options.use_head_version) ? "1" : "0"}, - {"_VCPKG_NO_DOWNLOADS", !Util::Enum::to_bool(config.build_package_options.allow_downloads) ? "1" : "0"}, + Util::Enum::to_bool(config.build_package_options.use_head_version) ? "1" : "0"}, + {"_VCPKG_NO_DOWNLOADS", + !Util::Enum::to_bool(config.build_package_options.allow_downloads) ? "1" : "0"}, + {"_VCPKG_DOWNLOAD_TOOL", to_string(config.build_package_options.download_tool)}, {"GIT", git_exe_path}, {"FEATURES", Strings::join(";", config.feature_list)}, {"ALL_FEATURES", all_features}, diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp index 1fbf6d97e..b998d19ab 100644 --- a/toolsrc/src/vcpkg/install.cpp +++ b/toolsrc/src/vcpkg/install.cpp @@ -412,13 +412,15 @@ namespace vcpkg::Install static constexpr StringLiteral OPTION_RECURSE = "--recurse"; static constexpr StringLiteral OPTION_KEEP_GOING = "--keep-going"; static constexpr StringLiteral OPTION_XUNIT = "--x-xunit"; + static constexpr StringLiteral OPTION_USE_ARIA2 = "--use-aria2"; - static constexpr std::array INSTALL_SWITCHES = {{ + static constexpr std::array INSTALL_SWITCHES = {{ {OPTION_DRY_RUN, "Do not actually build or install"}, {OPTION_USE_HEAD_VERSION, "Install the libraries on the command line using the latest upstream sources"}, {OPTION_NO_DOWNLOADS, "Do not download new sources"}, {OPTION_RECURSE, "Allow removal of packages as part of installation"}, {OPTION_KEEP_GOING, "Continue installing packages on failure"}, + {OPTION_USE_ARIA2, "Use aria2 to perform download tasks"}, }}; static constexpr std::array INSTALL_SETTINGS = {{ {OPTION_XUNIT, "File to output results in XUnit format (Internal use)"}, @@ -547,16 +549,22 @@ namespace vcpkg::Install const bool use_head_version = Util::Sets::contains(options.switches, (OPTION_USE_HEAD_VERSION)); const bool no_downloads = Util::Sets::contains(options.switches, (OPTION_NO_DOWNLOADS)); const bool is_recursive = Util::Sets::contains(options.switches, (OPTION_RECURSE)); + const bool use_aria2 = Util::Sets::contains(options.switches, (OPTION_USE_ARIA2)); const KeepGoing keep_going = to_keep_going(Util::Sets::contains(options.switches, OPTION_KEEP_GOING)); // create the plan StatusParagraphs status_db = database_load_check(paths); + Build::DownloadTool download_tool = Build::DownloadTool::BUILT_IN; + if (use_aria2) + download_tool = Build::DownloadTool::ARIA2; + const Build::BuildPackageOptions install_plan_options = { Util::Enum::to_enum(use_head_version), Util::Enum::to_enum(!no_downloads), Build::CleanBuildtrees::NO, - Build::CleanPackages::NO}; + Build::CleanPackages::NO, + download_tool}; auto all_ports = Paragraphs::load_all_ports(paths.get_filesystem(), paths.ports); std::unordered_map scf_map; -- cgit v1.2.3 From 7849f5da1e72977745f9fd69365f70df98eb028e Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 2 Apr 2018 18:37:16 -0700 Subject: [aria2] Use --x-use-aria2 instead of --use-aria2 for now --- toolsrc/src/vcpkg/install.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp index b998d19ab..fc336d6c7 100644 --- a/toolsrc/src/vcpkg/install.cpp +++ b/toolsrc/src/vcpkg/install.cpp @@ -412,7 +412,7 @@ namespace vcpkg::Install static constexpr StringLiteral OPTION_RECURSE = "--recurse"; static constexpr StringLiteral OPTION_KEEP_GOING = "--keep-going"; static constexpr StringLiteral OPTION_XUNIT = "--x-xunit"; - static constexpr StringLiteral OPTION_USE_ARIA2 = "--use-aria2"; + static constexpr StringLiteral OPTION_USE_ARIA2 = "--x-use-aria2"; static constexpr std::array INSTALL_SWITCHES = {{ {OPTION_DRY_RUN, "Do not actually build or install"}, @@ -556,8 +556,7 @@ namespace vcpkg::Install StatusParagraphs status_db = database_load_check(paths); Build::DownloadTool download_tool = Build::DownloadTool::BUILT_IN; - if (use_aria2) - download_tool = Build::DownloadTool::ARIA2; + if (use_aria2) download_tool = Build::DownloadTool::ARIA2; const Build::BuildPackageOptions install_plan_options = { Util::Enum::to_enum(use_head_version), -- cgit v1.2.3 From 410c547fa14ba6197833f19f2180ba2c532c1722 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 3 Apr 2018 15:19:16 -0700 Subject: Use -L on curl --- toolsrc/src/vcpkg/vcpkgpaths.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index d4bcea5af..bda2c4174 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -252,8 +252,8 @@ namespace vcpkg #else if (!fs.exists(tool_data.downloaded_path)) { - auto code = System::cmd_execute( - Strings::format(R"(curl '%s' --create-dirs --output '%s')", tool_data.url, tool_data.downloaded_path)); + auto code = System::cmd_execute(Strings::format( + R"(curl -L '%s' --create-dirs --output '%s')", tool_data.url, tool_data.downloaded_path)); Checks::check_exit(VCPKG_LINE_INFO, code == 0, "curl failed while downloading %s", tool_data.url); } -- cgit v1.2.3 From 385df0b02b204e01fbe49c8e3d24c093b22db4b2 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 3 Apr 2018 15:28:47 -0700 Subject: Add vcpkg edit --all --- toolsrc/src/vcpkg/commands.edit.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/commands.edit.cpp b/toolsrc/src/vcpkg/commands.edit.cpp index ac34a6720..94df9f9af 100644 --- a/toolsrc/src/vcpkg/commands.edit.cpp +++ b/toolsrc/src/vcpkg/commands.edit.cpp @@ -34,6 +34,8 @@ namespace vcpkg::Commands::Edit static constexpr StringLiteral OPTION_BUILDTREES = "--buildtrees"; + static constexpr StringLiteral OPTION_ALL = "--all"; + static std::vector valid_arguments(const VcpkgPaths& paths) { auto sources_and_errors = Paragraphs::try_load_all_ports(paths.get_filesystem(), paths.ports); @@ -42,9 +44,9 @@ namespace vcpkg::Commands::Edit [](auto&& pgh) -> std::string { return pgh->core_paragraph->name; }); } - static constexpr std::array EDIT_SWITCHES = {{ - {OPTION_BUILDTREES, "Open editor into the port-specific buildtree subfolder"}, - }}; + static constexpr std::array EDIT_SWITCHES = { + {{OPTION_BUILDTREES, "Open editor into the port-specific buildtree subfolder"}, + {OPTION_ALL, "Open editor into the port as well as the port-specific buildtree subfolder"}}}; const CommandStructure COMMAND_STRUCTURE = { Help::create_example_string("edit zlib"), @@ -113,6 +115,15 @@ namespace vcpkg::Commands::Edit Checks::exit_with_code(VCPKG_LINE_INFO, System::cmd_execute(cmd_line)); } + if (Util::Sets::contains(options.switches, OPTION_ALL)) + { + const auto buildtrees_current_dir = paths.buildtrees / port_name; + + const auto cmd_line = Strings::format( + R"("%s" "%s" %s -n)", env_editor.u8string(), portpath.u8string(), buildtrees_current_dir.u8string()); + Checks::exit_with_code(VCPKG_LINE_INFO, System::cmd_execute(cmd_line)); + } + const auto cmd_line = Strings::format( R"("%s" "%s" "%s" -n)", env_editor.u8string(), -- cgit v1.2.3 From 599aea98c9a2ef587fd9deacdfcf64dfa2e3c4db Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 3 Apr 2018 15:30:24 -0700 Subject: Add missing quotes --- toolsrc/src/vcpkg/commands.edit.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/commands.edit.cpp b/toolsrc/src/vcpkg/commands.edit.cpp index 94df9f9af..6c696018e 100644 --- a/toolsrc/src/vcpkg/commands.edit.cpp +++ b/toolsrc/src/vcpkg/commands.edit.cpp @@ -120,7 +120,7 @@ namespace vcpkg::Commands::Edit const auto buildtrees_current_dir = paths.buildtrees / port_name; const auto cmd_line = Strings::format( - R"("%s" "%s" %s -n)", env_editor.u8string(), portpath.u8string(), buildtrees_current_dir.u8string()); + R"("%s" "%s" "%s" -n)", env_editor.u8string(), portpath.u8string(), buildtrees_current_dir.u8string()); Checks::exit_with_code(VCPKG_LINE_INFO, System::cmd_execute(cmd_line)); } -- cgit v1.2.3 From 31377dee20dad9b95357934732996e2448f2eaf5 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 3 Apr 2018 21:05:31 -0700 Subject: Use 7z for extracting. Extract tools in downloads/tools --- toolsrc/src/vcpkg/vcpkgpaths.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index bda2c4174..f2086257e 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -115,15 +115,9 @@ namespace vcpkg tool, required_version_as_string); -// Legacy support. Change introduced in vcpkg v0.0.107. -#if !defined(_WIN32) - const std::string tool_dir_name = Strings::format("%s-%s", tool, required_version_as_string); + const std::string tool_dir_name = Strings::format("%s-%s-%s", tool, required_version_as_string, OS_STRING); const fs::path tool_dir_path = paths.downloads / "tools" / tool_dir_name; const fs::path exe_path = tool_dir_path / exe_relative_path; -#else - const fs::path tool_dir_path; - const fs::path exe_path = paths.downloads / exe_relative_path; -#endif return ToolData{*required_version.get(), exe_path, url, -- cgit v1.2.3 From 0c0f68939e0d8367e55793f80f0000f2a43a812a Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 4 Apr 2018 01:45:45 -0700 Subject: Introduce "vcpkg fetch" --- toolsrc/include/vcpkg/commands.h | 7 + toolsrc/include/vcpkg/vcpkgpaths.h | 32 +- toolsrc/src/vcpkg/build.cpp | 15 +- toolsrc/src/vcpkg/commands.cpp | 9 +- toolsrc/src/vcpkg/commands.create.cpp | 2 +- toolsrc/src/vcpkg/commands.exportifw.cpp | 6 +- toolsrc/src/vcpkg/commands.fetch.cpp | 656 ++++++++++++++++++++++++++++++ toolsrc/src/vcpkg/commands.integrate.cpp | 2 +- toolsrc/src/vcpkg/commands.portsdiff.cpp | 4 +- toolsrc/src/vcpkg/export.cpp | 4 +- toolsrc/src/vcpkg/vcpkgpaths.cpp | 654 +---------------------------- toolsrc/vcpkglib/vcpkglib.vcxproj | 1 + toolsrc/vcpkglib/vcpkglib.vcxproj.filters | 3 + 13 files changed, 714 insertions(+), 681 deletions(-) create mode 100644 toolsrc/src/vcpkg/commands.fetch.cpp (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/commands.h b/toolsrc/include/vcpkg/commands.h index 7369b8206..f6f1de626 100644 --- a/toolsrc/include/vcpkg/commands.h +++ b/toolsrc/include/vcpkg/commands.h @@ -135,6 +135,13 @@ namespace vcpkg::Commands std::string get_file_hash(const VcpkgPaths& paths, fs::path const& path, std::string const& hash_type); } + namespace Fetch + { + std::vector find_toolset_instances(const VcpkgPaths& paths); + fs::path get_tool_path(const VcpkgPaths& paths, const std::string& tool); + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); + } + template struct PackageNameAndFunction { diff --git a/toolsrc/include/vcpkg/vcpkgpaths.h b/toolsrc/include/vcpkg/vcpkgpaths.h index b3f24fb89..090414de3 100644 --- a/toolsrc/include/vcpkg/vcpkgpaths.h +++ b/toolsrc/include/vcpkg/vcpkgpaths.h @@ -7,8 +7,22 @@ #include #include +#include + namespace vcpkg { + namespace Tools + { + static const std::string SEVEN_ZIP = "7zip"; + static const std::string CMAKE = "cmake"; + static const std::string GIT = "git"; + static const std::string NINJA = "ninja"; + static const std::string NUGET = "nuget"; + static const std::string IFW_INSTALLER_BASE = "ifw_installerbase"; + static const std::string IFW_BINARYCREATOR = "ifw_binarycreator"; + static const std::string IFW_REPOGEN = "ifw_repogen"; + } + struct ToolsetArchOption { CStringView name; @@ -63,14 +77,7 @@ namespace vcpkg fs::path ports_cmake; - const fs::path& get_7za_exe() const; - const fs::path& get_cmake_exe() const; - const fs::path& get_git_exe() const; - const fs::path& get_ninja_exe() const; - const fs::path& get_nuget_exe() const; - const fs::path& get_ifw_installerbase_exe() const; - const fs::path& get_ifw_binarycreator_exe() const; - const fs::path& get_ifw_repogen_exe() const; + const fs::path& get_tool_exe(const std::string& tool) const; /// Retrieve a toolset matching a VS version /// @@ -82,14 +89,7 @@ namespace vcpkg private: Lazy> available_triplets; - Lazy _7za_exe; - Lazy cmake_exe; - Lazy git_exe; - Lazy ninja_exe; - Lazy nuget_exe; - Lazy ifw_installerbase_exe; - Lazy ifw_binarycreator_exe; - Lazy ifw_repogen_exe; + mutable std::map tool_paths; Lazy> toolsets; Lazy> toolsets_vs2013; diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index 79a55bd36..86d171534 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -341,8 +341,8 @@ namespace vcpkg::Build vcpkg::Util::unused(paths.get_ninja_exe()); #endif - const fs::path& cmake_exe_path = paths.get_cmake_exe(); - const fs::path& git_exe_path = paths.get_git_exe(); + const fs::path& cmake_exe_path = paths.get_tool_exe(Tools::CMAKE); + const fs::path& git_exe_path = paths.get_tool_exe(Tools::GIT); std::string all_features; for (auto& feature : config.scf.feature_paragraphs) @@ -361,9 +361,8 @@ namespace vcpkg::Build {"TARGET_TRIPLET", spec.triplet().canonical_name()}, {"VCPKG_PLATFORM_TOOLSET", toolset.version.c_str()}, {"VCPKG_USE_HEAD_VERSION", - Util::Enum::to_bool(config.build_package_options.use_head_version) ? "1" : "0"}, - {"_VCPKG_NO_DOWNLOADS", - !Util::Enum::to_bool(config.build_package_options.allow_downloads) ? "1" : "0"}, + Util::Enum::to_bool(config.build_package_options.use_head_version) ? "1" : "0"}, + {"_VCPKG_NO_DOWNLOADS", !Util::Enum::to_bool(config.build_package_options.allow_downloads) ? "1" : "0"}, {"_VCPKG_DOWNLOAD_TOOL", to_string(config.build_package_options.download_tool)}, {"GIT", git_exe_path}, {"FEATURES", Strings::join(";", config.feature_list)}, @@ -519,7 +518,7 @@ namespace vcpkg::Build Checks::check_exit(VCPKG_LINE_INFO, files.empty(), "unable to clear path: %s", pkg_path.u8string()); #if defined(_WIN32) - auto&& _7za = paths.get_7za_exe(); + auto&& _7za = paths.get_tool_exe(Tools::SEVEN_ZIP); System::cmd_execute_clean(Strings::format( R"("%s" x "%s" -o"%s" -y >nul)", _7za.u8string(), archive_path.u8string(), pkg_path.u8string())); @@ -539,7 +538,7 @@ namespace vcpkg::Build Checks::check_exit( VCPKG_LINE_INFO, !fs.exists(tmp_archive_path), "Could not remove file: %s", tmp_archive_path.u8string()); #if defined(_WIN32) - auto&& _7za = paths.get_7za_exe(); + auto&& _7za = paths.get_tool_exe(Tools::SEVEN_ZIP); System::cmd_execute_clean(Strings::format( R"("%s" a "%s" "%s\*" >nul)", @@ -771,7 +770,7 @@ namespace vcpkg::Build { static constexpr CStringView FLAG_GUID = "c35112b6-d1ba-415b-aa5d-81de856ef8eb"; - const fs::path& cmake_exe_path = paths.get_cmake_exe(); + const fs::path& cmake_exe_path = paths.get_tool_exe(Tools::CMAKE); const fs::path ports_cmake_script_path = paths.scripts / "get_triplet_environment.cmake"; const fs::path triplet_file_path = paths.triplets / (triplet.canonical_name() + ".cmake"); diff --git a/toolsrc/src/vcpkg/commands.cpp b/toolsrc/src/vcpkg/commands.cpp index d9c0e54cd..e98ff711a 100644 --- a/toolsrc/src/vcpkg/commands.cpp +++ b/toolsrc/src/vcpkg/commands.cpp @@ -43,16 +43,15 @@ namespace vcpkg::Commands {"portsdiff", &PortsDiff::perform_and_exit}, {"autocomplete", &Autocomplete::perform_and_exit}, {"hash", &Hash::perform_and_exit}, - }; + {"fetch", &Fetch::perform_and_exit}, + }; return t; } Span> get_available_commands_type_c() { - static std::vector> t = { - {"version", &Version::perform_and_exit}, - {"contact", &Contact::perform_and_exit} - }; + static std::vector> t = {{"version", &Version::perform_and_exit}, + {"contact", &Contact::perform_and_exit}}; return t; } } diff --git a/toolsrc/src/vcpkg/commands.create.cpp b/toolsrc/src/vcpkg/commands.create.cpp index 25c34cf09..60769c9ef 100644 --- a/toolsrc/src/vcpkg/commands.create.cpp +++ b/toolsrc/src/vcpkg/commands.create.cpp @@ -22,7 +22,7 @@ namespace vcpkg::Commands::Create const std::string port_name = args.command_arguments.at(0); const std::string url = args.command_arguments.at(1); - const fs::path& cmake_exe = paths.get_cmake_exe(); + const fs::path& cmake_exe = paths.get_tool_exe(Tools::CMAKE); std::vector cmake_args{{"CMD", "CREATE"}, {"PORT", port_name}, {"URL", url}}; diff --git a/toolsrc/src/vcpkg/commands.exportifw.cpp b/toolsrc/src/vcpkg/commands.exportifw.cpp index 58d9aa0be..ae106196a 100644 --- a/toolsrc/src/vcpkg/commands.exportifw.cpp +++ b/toolsrc/src/vcpkg/commands.exportifw.cpp @@ -291,7 +291,7 @@ namespace vcpkg::Export::IFW std::error_code ec; Files::Filesystem& fs = paths.get_filesystem(); - const fs::path& installerbase_exe = paths.get_ifw_installerbase_exe(); + const fs::path& installerbase_exe = paths.get_tool_exe(Tools::IFW_INSTALLER_BASE); fs::path tempmaintenancetool = ifw_packages_dir_path / "maintenance" / "data" / "tempmaintenancetool.exe"; fs.create_directories(tempmaintenancetool.parent_path(), ec); Checks::check_exit(VCPKG_LINE_INFO, @@ -335,7 +335,7 @@ namespace vcpkg::Export::IFW void do_repository(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths) { - const fs::path& repogen_exe = paths.get_ifw_repogen_exe(); + const fs::path& repogen_exe = paths.get_tool_exe(Tools::IFW_REPOGEN); const fs::path packages_dir = get_packages_dir_path(export_id, ifw_options, paths); const fs::path repository_dir = get_repository_dir_path(export_id, ifw_options, paths); @@ -361,7 +361,7 @@ namespace vcpkg::Export::IFW void do_installer(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths) { - const fs::path& binarycreator_exe = paths.get_ifw_binarycreator_exe(); + const fs::path& binarycreator_exe = paths.get_tool_exe(Tools::IFW_BINARYCREATOR); const fs::path config_file = get_config_file_path(export_id, ifw_options, paths); const fs::path packages_dir = get_packages_dir_path(export_id, ifw_options, paths); const fs::path repository_dir = get_repository_dir_path(export_id, ifw_options, paths); diff --git a/toolsrc/src/vcpkg/commands.fetch.cpp b/toolsrc/src/vcpkg/commands.fetch.cpp new file mode 100644 index 000000000..95c47e2db --- /dev/null +++ b/toolsrc/src/vcpkg/commands.fetch.cpp @@ -0,0 +1,656 @@ +#include "pch.h" + +#include +#include +#include +#include +#include +#include + +namespace vcpkg::Commands::Fetch +{ + static constexpr CStringView V_120 = "v120"; + static constexpr CStringView V_140 = "v140"; + static constexpr CStringView V_141 = "v141"; + + struct ToolData + { + std::array required_version; + fs::path exe_path; + std::string url; + fs::path downloaded_path; + fs::path tool_dir_path; + }; + + static Optional> parse_version_string(const std::string& version_as_string) + { + static const std::regex RE(R"###((\d+)\.(\d+)\.(\d+))###"); + + std::match_results match; + const auto found = std::regex_search(version_as_string, match, RE); + if (!found) + { + return {}; + } + + const int d1 = atoi(match[1].str().c_str()); + const int d2 = atoi(match[2].str().c_str()); + const int d3 = atoi(match[3].str().c_str()); + const std::array result = {d1, d2, d3}; + return result; + } + + static ToolData parse_tool_data_from_xml(const VcpkgPaths& paths, const std::string& tool) + { +#if defined(_WIN32) + static constexpr StringLiteral OS_STRING = "windows"; +#elif defined(__APPLE__) + static constexpr StringLiteral OS_STRING = "osx"; +#else // assume linux + static constexpr StringLiteral OS_STRING = "linux"; +#endif + + static const fs::path XML_PATH = paths.scripts / "vcpkgTools.xml"; + + const auto maybe_get_string_inside_tags = [](const std::string& input, + const std::regex& regex) -> Optional { + std::smatch match; + const bool has_match = std::regex_search(input.cbegin(), input.cend(), match, regex); + if (!has_match) return nullopt; + return match[1]; + }; + + const auto get_string_inside_tags = + [](const std::string& input, const std::regex& regex, const std::string& tag_name) -> std::string { + std::smatch match; + const bool has_match = std::regex_search(input.cbegin(), input.cend(), match, regex); + Checks::check_exit( + VCPKG_LINE_INFO, has_match, "Could not find tag <%s> in %s", tag_name, XML_PATH.generic_string()); + + return match[1]; + }; + + static const std::string XML = paths.get_filesystem().read_contents(XML_PATH).value_or_exit(VCPKG_LINE_INFO); + static const std::regex VERSION_REGEX{R"###(([\s\S]*?))###"}; + static const std::regex EXE_RELATIVE_PATH_REGEX{ + Strings::format(R"###(([\s\S]*?))###")}; + static const std::regex ARCHIVE_RELATIVE_PATH_REGEX{ + Strings::format(R"###(([\s\S]*?))###")}; + static const std::regex URL_REGEX{Strings::format(R"###(([\s\S]*?))###")}; + + std::regex tool_regex{ + Strings::format(R"###(([\s\S]*?)<\/tool>)###", tool, OS_STRING)}; + + std::smatch match_tool; + bool has_match_tool = std::regex_search(XML.cbegin(), XML.cend(), match_tool, tool_regex); + if (!has_match_tool && OS_STRING == "windows") // Legacy support. Change introduced in vcpkg v0.0.107. + { + tool_regex = Strings::format(R"###(([\s\S]*?)<\/tool>)###", tool); + has_match_tool = std::regex_search(XML.cbegin(), XML.cend(), match_tool, tool_regex); + } + Checks::check_exit(VCPKG_LINE_INFO, + has_match_tool, + "Could not find entry for tool [%s] in %s", + tool, + XML_PATH.generic_string()); + + const std::string tool_data_as_string = get_string_inside_tags(XML, tool_regex, tool); + + const std::string required_version_as_string = + get_string_inside_tags(tool_data_as_string, VERSION_REGEX, "requiredVersion"); + + const std::string url = get_string_inside_tags(tool_data_as_string, URL_REGEX, "url"); + + const std::string exe_relative_path = + get_string_inside_tags(tool_data_as_string, EXE_RELATIVE_PATH_REGEX, "exeRelativePath"); + + auto archive_relative_path = maybe_get_string_inside_tags(tool_data_as_string, ARCHIVE_RELATIVE_PATH_REGEX); + + const Optional> required_version = parse_version_string(required_version_as_string); + Checks::check_exit(VCPKG_LINE_INFO, + required_version.has_value(), + "Could not parse version for tool %s. Version string was: %s", + tool, + required_version_as_string); + + const std::string tool_dir_name = Strings::format("%s-%s-%s", tool, required_version_as_string, OS_STRING); + const fs::path tool_dir_path = paths.downloads / "tools" / tool_dir_name; + const fs::path exe_path = tool_dir_path / exe_relative_path; + return ToolData{*required_version.get(), + exe_path, + url, + paths.downloads / archive_relative_path.value_or(exe_relative_path), + tool_dir_path}; + } + + static bool exists_and_has_equal_or_greater_version(const std::string& version_cmd, + const std::array& expected_version) + { + const auto rc = System::cmd_execute_and_capture_output(Strings::format(R"(%s)", version_cmd)); + if (rc.exit_code != 0) + { + return false; + } + + const Optional> v = parse_version_string(rc.output); + if (!v.has_value()) + { + return false; + } + + const std::array actual_version = *v.get(); + return (actual_version[0] > expected_version[0] || + (actual_version[0] == expected_version[0] && actual_version[1] > expected_version[1]) || + (actual_version[0] == expected_version[0] && actual_version[1] == expected_version[1] && + actual_version[2] >= expected_version[2])); + } + + static Optional find_if_has_equal_or_greater_version(const std::vector& candidate_paths, + const std::string& version_check_arguments, + const std::array& expected_version) + { + auto it = Util::find_if(candidate_paths, [&](const fs::path& p) { + const std::string cmd = Strings::format(R"("%s" %s)", p.u8string(), version_check_arguments); + return exists_and_has_equal_or_greater_version(cmd, expected_version); + }); + + if (it != candidate_paths.cend()) + { + return std::move(*it); + } + + return nullopt; + } + + static std::vector keep_data_lines(const std::string& data_blob) + { + static const std::regex DATA_LINE_REGEX(R"(::(.+?)(?=::))"); + + std::vector data_lines; + + const std::sregex_iterator it(data_blob.cbegin(), data_blob.cend(), DATA_LINE_REGEX); + const std::sregex_iterator end; + for (std::sregex_iterator i = it; i != end; ++i) + { + const std::smatch match = *i; + data_lines.push_back(match[1].str()); + } + + return data_lines; + } + + static void extract_archive(const VcpkgPaths& paths, const fs::path& archive, const fs::path& to_path) + { + Files::Filesystem& fs = paths.get_filesystem(); + const fs::path to_path_partial = to_path.u8string() + ".partial"; + + std::error_code ec; + fs.remove_all(to_path_partial, ec); + fs.create_directories(to_path_partial, ec); + + const auto ext = archive.extension(); + if (ext == ".gz" && ext.extension() != ".tar") + { + const auto code = System::cmd_execute( + Strings::format(R"(cd '%s' && tar xzf '%s')", to_path_partial.u8string(), archive.u8string())); + Checks::check_exit(VCPKG_LINE_INFO, code == 0, "tar failed while extracting %s", archive.u8string()); + } + else if (ext == ".zip") + { + const auto code = System::cmd_execute( + Strings::format(R"(cd '%s' && unzip -qqo '%s')", to_path_partial.u8string(), archive.u8string())); + Checks::check_exit(VCPKG_LINE_INFO, code == 0, "unzip failed while extracting %s", archive.u8string()); + } + else + { + Checks::exit_with_message(VCPKG_LINE_INFO, "Unexpected archive extension: %s", ext.u8string()); + } + + fs.rename(to_path_partial, to_path); + } + + static fs::path fetch_tool(const VcpkgPaths& paths, const std::string& tool_name, const ToolData& tool_data) + { + const auto& fs = paths.get_filesystem(); + const fs::path& scripts_folder = paths.scripts; + const std::array& version = tool_data.required_version; + + const std::string version_as_string = Strings::format("%d.%d.%d", version[0], version[1], version[2]); + System::println("A suitable version of %s was not found (required v%s). Downloading portable %s v%s...", + tool_name, + version_as_string, + tool_name, + version_as_string); +#if defined(_WIN32) + const fs::path script = scripts_folder / "fetchtool.ps1"; + const std::string title = Strings::format( + "Fetching %s version %s (No sufficient installed version was found)", tool_name, version_as_string); + const System::PowershellParameter tool_param("tool", tool_name); + const std::string output = System::powershell_execute_and_capture_output(title, script, {tool_param}); + + const std::vector tool_path = keep_data_lines(output); + Checks::check_exit(VCPKG_LINE_INFO, tool_path.size() == 1, "Expected tool path, but got %s", output); + + const fs::path actual_downloaded_path = Strings::trim(std::string{tool_path.at(0)}); + const fs::path& expected_downloaded_path = tool_data.exe_path; + std::error_code ec; + const auto eq = fs::stdfs::equivalent(expected_downloaded_path, actual_downloaded_path, ec); + Checks::check_exit(VCPKG_LINE_INFO, + eq && !ec, + "Expected tool downloaded path to be %s, but was %s", + expected_downloaded_path.u8string(), + actual_downloaded_path.u8string()); + return actual_downloaded_path; +#else + if (!fs.exists(tool_data.downloaded_path)) + { + auto code = System::cmd_execute(Strings::format( + R"(curl -L '%s' --create-dirs --output '%s')", tool_data.url, tool_data.downloaded_path)); + Checks::check_exit(VCPKG_LINE_INFO, code == 0, "curl failed while downloading %s", tool_data.url); + } + + System::println("Extracting %s...", tool_name); + extract_archive(paths, tool_data.downloaded_path, tool_data.tool_dir_path); + System::println("Extracting %s... done.", tool_name); + + Checks::check_exit(VCPKG_LINE_INFO, + fs.exists(tool_data.exe_path), + "Expected %s to exist after extracting", + tool_data.exe_path); + + return tool_data.exe_path; +#endif + } + + static fs::path get_cmake_path(const VcpkgPaths& paths) + { + std::vector candidate_paths; +#if defined(_WIN32) || defined(__APPLE__) || defined(__linux__) + static const ToolData TOOL_DATA = parse_tool_data_from_xml(paths, "cmake"); + candidate_paths.push_back(TOOL_DATA.exe_path); +#else + static const ToolData TOOL_DATA = ToolData{{3, 5, 1}, ""}; +#endif + static const std::string VERSION_CHECK_ARGUMENTS = "--version"; + + const std::vector from_path = Files::find_from_PATH("cmake"); + candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); + + const auto& program_files = System::get_program_files_platform_bitness(); + if (const auto pf = program_files.get()) candidate_paths.push_back(*pf / "CMake" / "bin" / "cmake.exe"); + const auto& program_files_32_bit = System::get_program_files_32_bit(); + if (const auto pf = program_files_32_bit.get()) candidate_paths.push_back(*pf / "CMake" / "bin" / "cmake.exe"); + + const Optional path = + find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, TOOL_DATA.required_version); + if (const auto p = path.get()) + { + return *p; + } + + return fetch_tool(paths, "cmake", TOOL_DATA); + } + + static fs::path get_7za_path(const VcpkgPaths& paths) + { +#if defined(_WIN32) + static const ToolData TOOL_DATA = parse_tool_data_from_xml(paths, "7zip"); + if (!paths.get_filesystem().exists(TOOL_DATA.exe_path)) + { + return fetch_tool(paths, "7zip", TOOL_DATA); + } + return TOOL_DATA.exe_path; +#else + Checks::exit_with_message(VCPKG_LINE_INFO, "Cannot download 7zip for non-Windows platforms."); +#endif + } + + static fs::path get_ninja_path(const VcpkgPaths& paths) + { + static const ToolData TOOL_DATA = parse_tool_data_from_xml(paths, "ninja"); + + std::vector candidate_paths; + candidate_paths.push_back(TOOL_DATA.exe_path); + const std::vector from_path = Files::find_from_PATH("ninja"); + candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); + + auto path = find_if_has_equal_or_greater_version(candidate_paths, "--version", TOOL_DATA.required_version); + if (const auto p = path.get()) + { + return *p; + } + + return fetch_tool(paths, "ninja", TOOL_DATA); + } + + static fs::path get_nuget_path(const VcpkgPaths& paths) + { + static const ToolData TOOL_DATA = parse_tool_data_from_xml(paths, "nuget"); + + std::vector candidate_paths; + candidate_paths.push_back(TOOL_DATA.exe_path); + const std::vector from_path = Files::find_from_PATH("nuget"); + candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); + + auto path = find_if_has_equal_or_greater_version(candidate_paths, "", TOOL_DATA.required_version); + if (const auto p = path.get()) + { + return *p; + } + + return fetch_tool(paths, "nuget", TOOL_DATA); + } + + static fs::path get_git_path(const VcpkgPaths& paths) + { +#if defined(_WIN32) + static const ToolData TOOL_DATA = parse_tool_data_from_xml(paths, "git"); +#else + static const ToolData TOOL_DATA = ToolData{{2, 7, 4}, ""}; +#endif + static const std::string VERSION_CHECK_ARGUMENTS = "--version"; + + std::vector candidate_paths; +#if defined(_WIN32) + candidate_paths.push_back(TOOL_DATA.exe_path); +#endif + const std::vector from_path = Files::find_from_PATH("git"); + candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); + + const auto& program_files = System::get_program_files_platform_bitness(); + if (const auto pf = program_files.get()) candidate_paths.push_back(*pf / "git" / "cmd" / "git.exe"); + const auto& program_files_32_bit = System::get_program_files_32_bit(); + if (const auto pf = program_files_32_bit.get()) candidate_paths.push_back(*pf / "git" / "cmd" / "git.exe"); + + const Optional path = + find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, TOOL_DATA.required_version); + if (const auto p = path.get()) + { + return *p; + } + + return fetch_tool(paths, "git", TOOL_DATA); + } + + static fs::path get_ifw_installerbase_path(const VcpkgPaths& paths) + { + static const ToolData TOOL_DATA = parse_tool_data_from_xml(paths, "installerbase"); + + static const std::string VERSION_CHECK_ARGUMENTS = "--framework-version"; + + std::vector candidate_paths; + candidate_paths.push_back(TOOL_DATA.exe_path); + // TODO: Uncomment later + // const std::vector from_path = Files::find_from_PATH("installerbase"); + // candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); + // candidate_paths.push_back(fs::path(System::get_environment_variable("HOMEDRIVE").value_or("C:")) / "Qt" / + // "Tools" / "QtInstallerFramework" / "3.1" / "bin" / "installerbase.exe"); + // candidate_paths.push_back(fs::path(System::get_environment_variable("HOMEDRIVE").value_or("C:")) / "Qt" / + // "QtIFW-3.1.0" / "bin" / "installerbase.exe"); + + const Optional path = + find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, TOOL_DATA.required_version); + if (const auto p = path.get()) + { + return *p; + } + + return fetch_tool(paths, "installerbase", TOOL_DATA); + } + + struct VisualStudioInstance + { + fs::path root_path; + std::string version; + std::string release_type; + std::string preference_weight; // Mostly unused, just for verification that order is as intended + + std::string major_version() const { return version.substr(0, 2); } + }; + + static std::vector get_visual_studio_instances(const VcpkgPaths& paths) + { + const fs::path script = paths.scripts / "findVisualStudioInstallationInstances.ps1"; + const std::string output = + System::powershell_execute_and_capture_output("Detecting Visual Studio instances", script); + + const std::vector instances_as_strings = keep_data_lines(output); + Checks::check_exit(VCPKG_LINE_INFO, + !instances_as_strings.empty(), + "Could not detect any Visual Studio instances.\n" + "Powershell script:\n" + " %s\n" + "returned:\n" + "%s", + script.generic_string(), + output); + + std::vector instances; + for (const std::string& instance_as_string : instances_as_strings) + { + const std::vector split = Strings::split(instance_as_string, "::"); + Checks::check_exit(VCPKG_LINE_INFO, + split.size() == 4, + "Invalid Visual Studio instance format.\n" + "Expected: PreferenceWeight::ReleaseType::Version::PathToVisualStudio\n" + "Actual : %s\n", + instance_as_string); + instances.push_back({split.at(3), split.at(2), split.at(1), split.at(0)}); + } + + return instances; + } + + std::vector find_toolset_instances(const VcpkgPaths& paths) + { + using CPU = System::CPUArchitecture; + + const auto& fs = paths.get_filesystem(); + + // Note: this will contain a mix of vcvarsall.bat locations and dumpbin.exe locations. + std::vector paths_examined; + + std::vector found_toolsets; + std::vector excluded_toolsets; + + const std::vector vs_instances = get_visual_studio_instances(paths); + const bool v140_is_available = Util::find_if(vs_instances, [&](const VisualStudioInstance& vs_instance) { + return vs_instance.major_version() == "14"; + }) != vs_instances.cend(); + + for (const VisualStudioInstance& vs_instance : vs_instances) + { + const std::string major_version = vs_instance.major_version(); + if (major_version == "15") + { + const fs::path vc_dir = vs_instance.root_path / "VC"; + + // Skip any instances that do not have vcvarsall. + const fs::path vcvarsall_dir = vc_dir / "Auxiliary" / "Build"; + const fs::path vcvarsall_bat = vcvarsall_dir / "vcvarsall.bat"; + paths_examined.push_back(vcvarsall_bat); + if (!fs.exists(vcvarsall_bat)) continue; + + // Get all supported architectures + std::vector supported_architectures; + if (fs.exists(vcvarsall_dir / "vcvars32.bat")) + supported_architectures.push_back({"x86", CPU::X86, CPU::X86}); + if (fs.exists(vcvarsall_dir / "vcvars64.bat")) + supported_architectures.push_back({"amd64", CPU::X64, CPU::X64}); + if (fs.exists(vcvarsall_dir / "vcvarsx86_amd64.bat")) + supported_architectures.push_back({"x86_amd64", CPU::X86, CPU::X64}); + if (fs.exists(vcvarsall_dir / "vcvarsx86_arm.bat")) + supported_architectures.push_back({"x86_arm", CPU::X86, CPU::ARM}); + if (fs.exists(vcvarsall_dir / "vcvarsx86_arm64.bat")) + supported_architectures.push_back({"x86_arm64", CPU::X86, CPU::ARM64}); + if (fs.exists(vcvarsall_dir / "vcvarsamd64_x86.bat")) + supported_architectures.push_back({"amd64_x86", CPU::X64, CPU::X86}); + if (fs.exists(vcvarsall_dir / "vcvarsamd64_arm.bat")) + supported_architectures.push_back({"amd64_arm", CPU::X64, CPU::ARM}); + if (fs.exists(vcvarsall_dir / "vcvarsamd64_arm64.bat")) + supported_architectures.push_back({"amd64_arm64", CPU::X64, CPU::ARM64}); + + // Locate the "best" MSVC toolchain version + const fs::path msvc_path = vc_dir / "Tools" / "MSVC"; + std::vector 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) { return left.filename() > right.filename(); }); + + for (const fs::path& subdir : msvc_subdirectories) + { + const fs::path dumpbin_path = subdir / "bin" / "HostX86" / "x86" / "dumpbin.exe"; + paths_examined.push_back(dumpbin_path); + if (fs.exists(dumpbin_path)) + { + const Toolset v141toolset = Toolset{ + vs_instance.root_path, dumpbin_path, vcvarsall_bat, {}, V_141, supported_architectures}; + + auto english_language_pack = dumpbin_path.parent_path() / "1033"; + + if (!fs.exists(english_language_pack)) + { + excluded_toolsets.push_back(v141toolset); + break; + } + + found_toolsets.push_back(v141toolset); + + if (v140_is_available) + { + const Toolset v140toolset = Toolset{vs_instance.root_path, + dumpbin_path, + vcvarsall_bat, + {"-vcvars_ver=14.0"}, + V_140, + supported_architectures}; + found_toolsets.push_back(v140toolset); + } + + break; + } + } + + continue; + } + + if (major_version == "14" || major_version == "12") + { + const fs::path vcvarsall_bat = vs_instance.root_path / "VC" / "vcvarsall.bat"; + + paths_examined.push_back(vcvarsall_bat); + if (fs.exists(vcvarsall_bat)) + { + const fs::path vs_dumpbin_exe = vs_instance.root_path / "VC" / "bin" / "dumpbin.exe"; + paths_examined.push_back(vs_dumpbin_exe); + + const fs::path vs_bin_dir = vcvarsall_bat.parent_path() / "bin"; + std::vector supported_architectures; + if (fs.exists(vs_bin_dir / "vcvars32.bat")) + supported_architectures.push_back({"x86", CPU::X86, CPU::X86}); + if (fs.exists(vs_bin_dir / "amd64\\vcvars64.bat")) + supported_architectures.push_back({"x64", CPU::X64, CPU::X64}); + if (fs.exists(vs_bin_dir / "x86_amd64\\vcvarsx86_amd64.bat")) + supported_architectures.push_back({"x86_amd64", CPU::X86, CPU::X64}); + if (fs.exists(vs_bin_dir / "x86_arm\\vcvarsx86_arm.bat")) + supported_architectures.push_back({"x86_arm", CPU::X86, CPU::ARM}); + if (fs.exists(vs_bin_dir / "amd64_x86\\vcvarsamd64_x86.bat")) + supported_architectures.push_back({"amd64_x86", CPU::X64, CPU::X86}); + if (fs.exists(vs_bin_dir / "amd64_arm\\vcvarsamd64_arm.bat")) + supported_architectures.push_back({"amd64_arm", CPU::X64, CPU::ARM}); + + if (fs.exists(vs_dumpbin_exe)) + { + const Toolset toolset = {vs_instance.root_path, + vs_dumpbin_exe, + vcvarsall_bat, + {}, + major_version == "14" ? V_140 : V_120, + supported_architectures}; + + auto english_language_pack = vs_dumpbin_exe.parent_path() / "1033"; + + if (!fs.exists(english_language_pack)) + { + excluded_toolsets.push_back(toolset); + break; + } + + found_toolsets.push_back(toolset); + } + } + } + } + + if (!excluded_toolsets.empty()) + { + System::println( + System::Color::warning, + "Warning: The following VS instances are excluded because the English language pack is unavailable."); + for (const Toolset& toolset : excluded_toolsets) + { + System::println(" %s", toolset.visual_studio_root_path.u8string()); + } + System::println(System::Color::warning, "Please install the English language pack."); + } + + if (found_toolsets.empty()) + { + System::println(System::Color::error, "Could not locate a complete toolset."); + System::println("The following paths were examined:"); + for (const fs::path& path : paths_examined) + { + System::println(" %s", path.u8string()); + } + Checks::exit_fail(VCPKG_LINE_INFO); + } + + return found_toolsets; + } + + fs::path get_tool_path(const VcpkgPaths& paths, const std::string& tool) + { + // First deal with specially handled tools. + // For these we may look in locations like Program Files, the PATH etc as well as the auto-downloaded location. + if (tool == Tools::SEVEN_ZIP) return get_7za_path(paths); + if (tool == Tools::CMAKE) return get_cmake_path(paths); + if (tool == Tools::GIT) return get_git_path(paths); + if (tool == Tools::NINJA) return get_ninja_path(paths); + if (tool == Tools::NUGET) return get_nuget_path(paths); + if (tool == Tools::IFW_INSTALLER_BASE) return get_ifw_installerbase_path(paths); + if (tool == Tools::IFW_BINARYCREATOR) + return get_ifw_installerbase_path(paths).parent_path() / "binarycreator.exe"; + if (tool == Tools::IFW_REPOGEN) return get_ifw_installerbase_path(paths).parent_path() / "repogen.exe"; + + // For other tools, we simply always auto-download them. + const ToolData tool_data = parse_tool_data_from_xml(paths, tool); + if (paths.get_filesystem().exists(tool_data.exe_path)) + { + return tool_data.exe_path; + } + return fetch_tool(paths, tool, tool_data); + } + + const CommandStructure COMMAND_STRUCTURE = { + Strings::format("The argument should be tool name\n%s", Help::create_example_string("fetch cmake")), + 1, + 1, + {}, + nullptr, + }; + + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) + { + Util::unused(args.parse_arguments(COMMAND_STRUCTURE)); + + const std::string tool = args.command_arguments[0]; + const fs::path tool_path = get_tool_path(paths, tool); + System::println(tool_path.u8string()); + Checks::exit_success(VCPKG_LINE_INFO); + } +} diff --git a/toolsrc/src/vcpkg/commands.integrate.cpp b/toolsrc/src/vcpkg/commands.integrate.cpp index 36e4e56e7..d6ae27181 100644 --- a/toolsrc/src/vcpkg/commands.integrate.cpp +++ b/toolsrc/src/vcpkg/commands.integrate.cpp @@ -276,7 +276,7 @@ CMake projects should use: "-DCMAKE_TOOLCHAIN_FILE=%s")", { auto& fs = paths.get_filesystem(); - const fs::path& nuget_exe = paths.get_nuget_exe(); + const fs::path& nuget_exe = paths.get_tool_exe(Tools::NUGET); const fs::path& buildsystems_dir = paths.buildsystems; const fs::path tmp_dir = buildsystems_dir / "tmp"; diff --git a/toolsrc/src/vcpkg/commands.portsdiff.cpp b/toolsrc/src/vcpkg/commands.portsdiff.cpp index dba04ce5b..c6b02582f 100644 --- a/toolsrc/src/vcpkg/commands.portsdiff.cpp +++ b/toolsrc/src/vcpkg/commands.portsdiff.cpp @@ -79,7 +79,7 @@ namespace vcpkg::Commands::PortsDiff { std::error_code ec; auto& fs = paths.get_filesystem(); - const fs::path& git_exe = paths.get_git_exe(); + const fs::path& git_exe = paths.get_tool_exe(Tools::GIT); const fs::path dot_git_dir = paths.root / ".git"; const std::string ports_dir_name_as_string = paths.ports.filename().u8string(); const fs::path temp_checkout_path = @@ -130,7 +130,7 @@ namespace vcpkg::Commands::PortsDiff { args.parse_arguments(COMMAND_STRUCTURE); - const fs::path& git_exe = paths.get_git_exe(); + const fs::path& git_exe = paths.get_tool_exe(Tools::GIT); const std::string git_commit_id_for_previous_snapshot = args.command_arguments.at(0); const std::string git_commit_id_for_current_snapshot = diff --git a/toolsrc/src/vcpkg/export.cpp b/toolsrc/src/vcpkg/export.cpp index 16c84f99d..32151c791 100644 --- a/toolsrc/src/vcpkg/export.cpp +++ b/toolsrc/src/vcpkg/export.cpp @@ -123,7 +123,7 @@ namespace vcpkg::Export const fs::path& output_dir) { Files::Filesystem& fs = paths.get_filesystem(); - const fs::path& nuget_exe = paths.get_nuget_exe(); + const fs::path& nuget_exe = paths.get_tool_exe(Tools::NUGET); // This file will be placed in "build\native" in the nuget package. Therefore, go up two dirs. const std::string targets_redirect_content = @@ -189,7 +189,7 @@ namespace vcpkg::Export const fs::path& output_dir, const ArchiveFormat& format) { - const fs::path& cmake_exe = paths.get_cmake_exe(); + const fs::path& cmake_exe = paths.get_tool_exe(Tools::CMAKE); const std::string exported_dir_filename = raw_exported_dir.filename().u8string(); const std::string exported_archive_filename = diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index f2086257e..4f998d579 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -5,401 +5,13 @@ #include #include #include +#include #include #include #include namespace vcpkg { - static constexpr CStringView V_120 = "v120"; - static constexpr CStringView V_140 = "v140"; - static constexpr CStringView V_141 = "v141"; - - struct ToolData - { - std::array required_version; - fs::path exe_path; - std::string url; - fs::path downloaded_path; - fs::path tool_dir_path; - }; - - static Optional> parse_version_string(const std::string& version_as_string) - { - static const std::regex RE(R"###((\d+)\.(\d+)\.(\d+))###"); - - std::match_results match; - const auto found = std::regex_search(version_as_string, match, RE); - if (!found) - { - return {}; - } - - const int d1 = atoi(match[1].str().c_str()); - const int d2 = atoi(match[2].str().c_str()); - const int d3 = atoi(match[3].str().c_str()); - const std::array result = {d1, d2, d3}; - return result; - } - - static ToolData parse_tool_data_from_xml(const VcpkgPaths& paths, const std::string& tool) - { -#if defined(_WIN32) - static constexpr StringLiteral OS_STRING = "windows"; -#elif defined(__APPLE__) - static constexpr StringLiteral OS_STRING = "osx"; -#else // assume linux - static constexpr StringLiteral OS_STRING = "linux"; -#endif - - static const fs::path XML_PATH = paths.scripts / "vcpkgTools.xml"; - - const auto maybe_get_string_inside_tags = [](const std::string& input, - const std::regex& regex) -> Optional { - std::smatch match; - const bool has_match = std::regex_search(input.cbegin(), input.cend(), match, regex); - if (!has_match) return nullopt; - return match[1]; - }; - - const auto get_string_inside_tags = - [](const std::string& input, const std::regex& regex, const std::string& tag_name) -> std::string { - std::smatch match; - const bool has_match = std::regex_search(input.cbegin(), input.cend(), match, regex); - Checks::check_exit( - VCPKG_LINE_INFO, has_match, "Could not find tag <%s> in %s", tag_name, XML_PATH.generic_string()); - - return match[1]; - }; - - static const std::string XML = paths.get_filesystem().read_contents(XML_PATH).value_or_exit(VCPKG_LINE_INFO); - static const std::regex VERSION_REGEX{R"###(([\s\S]*?))###"}; - static const std::regex EXE_RELATIVE_PATH_REGEX{ - Strings::format(R"###(([\s\S]*?))###")}; - static const std::regex ARCHIVE_RELATIVE_PATH_REGEX{ - Strings::format(R"###(([\s\S]*?))###")}; - static const std::regex URL_REGEX{Strings::format(R"###(([\s\S]*?))###")}; - - std::regex tool_regex{ - Strings::format(R"###(([\s\S]*?)<\/tool>)###", tool, OS_STRING)}; - - std::smatch match_tool; - bool has_match_tool = std::regex_search(XML.cbegin(), XML.cend(), match_tool, tool_regex); - if (!has_match_tool && OS_STRING == "windows") // Legacy support. Change introduced in vcpkg v0.0.107. - { - tool_regex = Strings::format(R"###(([\s\S]*?)<\/tool>)###", tool); - has_match_tool = std::regex_search(XML.cbegin(), XML.cend(), match_tool, tool_regex); - } - Checks::check_exit(VCPKG_LINE_INFO, - has_match_tool, - "Could not find entry for tool [%s] in %s", - tool, - XML_PATH.generic_string()); - - const std::string tool_data_as_string = get_string_inside_tags(XML, tool_regex, tool); - - const std::string required_version_as_string = - get_string_inside_tags(tool_data_as_string, VERSION_REGEX, "requiredVersion"); - - const std::string url = get_string_inside_tags(tool_data_as_string, URL_REGEX, "url"); - - const std::string exe_relative_path = - get_string_inside_tags(tool_data_as_string, EXE_RELATIVE_PATH_REGEX, "exeRelativePath"); - - auto archive_relative_path = maybe_get_string_inside_tags(tool_data_as_string, ARCHIVE_RELATIVE_PATH_REGEX); - - const Optional> required_version = parse_version_string(required_version_as_string); - Checks::check_exit(VCPKG_LINE_INFO, - required_version.has_value(), - "Could not parse version for tool %s. Version string was: %s", - tool, - required_version_as_string); - - const std::string tool_dir_name = Strings::format("%s-%s-%s", tool, required_version_as_string, OS_STRING); - const fs::path tool_dir_path = paths.downloads / "tools" / tool_dir_name; - const fs::path exe_path = tool_dir_path / exe_relative_path; - return ToolData{*required_version.get(), - exe_path, - url, - paths.downloads / archive_relative_path.value_or(exe_relative_path), - tool_dir_path}; - } - - static bool exists_and_has_equal_or_greater_version(const std::string& version_cmd, - const std::array& expected_version) - { - const auto rc = System::cmd_execute_and_capture_output(Strings::format(R"(%s)", version_cmd)); - if (rc.exit_code != 0) - { - return false; - } - - const Optional> v = parse_version_string(rc.output); - if (!v.has_value()) - { - return false; - } - - const std::array actual_version = *v.get(); - return (actual_version[0] > expected_version[0] || - (actual_version[0] == expected_version[0] && actual_version[1] > expected_version[1]) || - (actual_version[0] == expected_version[0] && actual_version[1] == expected_version[1] && - actual_version[2] >= expected_version[2])); - } - - static Optional find_if_has_equal_or_greater_version(const std::vector& candidate_paths, - const std::string& version_check_arguments, - const std::array& expected_version) - { - auto it = Util::find_if(candidate_paths, [&](const fs::path& p) { - const std::string cmd = Strings::format(R"("%s" %s)", p.u8string(), version_check_arguments); - return exists_and_has_equal_or_greater_version(cmd, expected_version); - }); - - if (it != candidate_paths.cend()) - { - return std::move(*it); - } - - return nullopt; - } - - static std::vector keep_data_lines(const std::string& data_blob) - { - static const std::regex DATA_LINE_REGEX(R"(::(.+?)(?=::))"); - - std::vector data_lines; - - const std::sregex_iterator it(data_blob.cbegin(), data_blob.cend(), DATA_LINE_REGEX); - const std::sregex_iterator end; - for (std::sregex_iterator i = it; i != end; ++i) - { - const std::smatch match = *i; - data_lines.push_back(match[1].str()); - } - - return data_lines; - } - - static void extract_archive(const VcpkgPaths& paths, const fs::path& archive, const fs::path& to_path) - { - Files::Filesystem& fs = paths.get_filesystem(); - const fs::path to_path_partial = to_path.u8string() + ".partial"; - - std::error_code ec; - fs.remove_all(to_path_partial, ec); - fs.create_directories(to_path_partial, ec); - - const auto ext = archive.extension(); - if (ext == ".gz" && ext.extension() != ".tar") - { - const auto code = System::cmd_execute( - Strings::format(R"(cd '%s' && tar xzf '%s')", to_path_partial.u8string(), archive.u8string())); - Checks::check_exit(VCPKG_LINE_INFO, code == 0, "tar failed while extracting %s", archive.u8string()); - } - else if (ext == ".zip") - { - const auto code = System::cmd_execute( - Strings::format(R"(cd '%s' && unzip -qqo '%s')", to_path_partial.u8string(), archive.u8string())); - Checks::check_exit(VCPKG_LINE_INFO, code == 0, "unzip failed while extracting %s", archive.u8string()); - } - else - { - Checks::exit_with_message(VCPKG_LINE_INFO, "Unexpected archive extension: %s", ext.u8string()); - } - - fs.rename(to_path_partial, to_path); - } - - static fs::path fetch_tool(const VcpkgPaths& paths, const std::string& tool_name, const ToolData& tool_data) - { - const auto& fs = paths.get_filesystem(); - const fs::path& scripts_folder = paths.scripts; - const std::array& version = tool_data.required_version; - - const std::string version_as_string = Strings::format("%d.%d.%d", version[0], version[1], version[2]); - System::println("A suitable version of %s was not found (required v%s). Downloading portable %s v%s...", - tool_name, - version_as_string, - tool_name, - version_as_string); -#if defined(_WIN32) - const fs::path script = scripts_folder / "fetchtool.ps1"; - const std::string title = Strings::format( - "Fetching %s version %s (No sufficient installed version was found)", tool_name, version_as_string); - const System::PowershellParameter tool_param("tool", tool_name); - const std::string output = System::powershell_execute_and_capture_output(title, script, {tool_param}); - - const std::vector tool_path = keep_data_lines(output); - Checks::check_exit(VCPKG_LINE_INFO, tool_path.size() == 1, "Expected tool path, but got %s", output); - - const fs::path actual_downloaded_path = Strings::trim(std::string{tool_path.at(0)}); - const fs::path& expected_downloaded_path = tool_data.exe_path; - std::error_code ec; - const auto eq = fs::stdfs::equivalent(expected_downloaded_path, actual_downloaded_path, ec); - Checks::check_exit(VCPKG_LINE_INFO, - eq && !ec, - "Expected tool downloaded path to be %s, but was %s", - expected_downloaded_path.u8string(), - actual_downloaded_path.u8string()); - return actual_downloaded_path; -#else - if (!fs.exists(tool_data.downloaded_path)) - { - auto code = System::cmd_execute(Strings::format( - R"(curl -L '%s' --create-dirs --output '%s')", tool_data.url, tool_data.downloaded_path)); - Checks::check_exit(VCPKG_LINE_INFO, code == 0, "curl failed while downloading %s", tool_data.url); - } - - System::println("Extracting %s...", tool_name); - extract_archive(paths, tool_data.downloaded_path, tool_data.tool_dir_path); - System::println("Extracting %s... done.", tool_name); - - Checks::check_exit(VCPKG_LINE_INFO, - fs.exists(tool_data.exe_path), - "Expected %s to exist after extracting", - tool_data.exe_path); - - return tool_data.exe_path; -#endif - } - - static fs::path get_cmake_path(const VcpkgPaths& paths) - { - std::vector candidate_paths; -#if defined(_WIN32) || defined(__APPLE__) || defined(__linux__) - static const ToolData TOOL_DATA = parse_tool_data_from_xml(paths, "cmake"); - candidate_paths.push_back(TOOL_DATA.exe_path); -#else - static const ToolData TOOL_DATA = ToolData{{3, 5, 1}, ""}; -#endif - static const std::string VERSION_CHECK_ARGUMENTS = "--version"; - - const std::vector from_path = Files::find_from_PATH("cmake"); - candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); - - const auto& program_files = System::get_program_files_platform_bitness(); - if (const auto pf = program_files.get()) candidate_paths.push_back(*pf / "CMake" / "bin" / "cmake.exe"); - const auto& program_files_32_bit = System::get_program_files_32_bit(); - if (const auto pf = program_files_32_bit.get()) candidate_paths.push_back(*pf / "CMake" / "bin" / "cmake.exe"); - - const Optional path = - find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, TOOL_DATA.required_version); - if (const auto p = path.get()) - { - return *p; - } - - return fetch_tool(paths, "cmake", TOOL_DATA); - } - - static fs::path get_7za_path(const VcpkgPaths& paths) - { -#if defined(_WIN32) - static const ToolData TOOL_DATA = parse_tool_data_from_xml(paths, "7zip"); - if (!paths.get_filesystem().exists(TOOL_DATA.exe_path)) - { - return fetch_tool(paths, "7zip", TOOL_DATA); - } - return TOOL_DATA.exe_path; -#else - Checks::exit_with_message(VCPKG_LINE_INFO, "Cannot download 7zip for non-Windows platforms."); -#endif - } - - static fs::path get_ninja_path(const VcpkgPaths& paths) - { - static const ToolData TOOL_DATA = parse_tool_data_from_xml(paths, "ninja"); - - std::vector candidate_paths; - candidate_paths.push_back(TOOL_DATA.exe_path); - const std::vector from_path = Files::find_from_PATH("ninja"); - candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); - - auto path = find_if_has_equal_or_greater_version(candidate_paths, "--version", TOOL_DATA.required_version); - if (const auto p = path.get()) - { - return *p; - } - - return fetch_tool(paths, "ninja", TOOL_DATA); - } - - static fs::path get_nuget_path(const VcpkgPaths& paths) - { - static const ToolData TOOL_DATA = parse_tool_data_from_xml(paths, "nuget"); - - std::vector candidate_paths; - candidate_paths.push_back(TOOL_DATA.exe_path); - const std::vector from_path = Files::find_from_PATH("nuget"); - candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); - - auto path = find_if_has_equal_or_greater_version(candidate_paths, "", TOOL_DATA.required_version); - if (const auto p = path.get()) - { - return *p; - } - - return fetch_tool(paths, "nuget", TOOL_DATA); - } - - static fs::path get_git_path(const VcpkgPaths& paths) - { -#if defined(_WIN32) - static const ToolData TOOL_DATA = parse_tool_data_from_xml(paths, "git"); -#else - static const ToolData TOOL_DATA = ToolData{{2, 7, 4}, ""}; -#endif - static const std::string VERSION_CHECK_ARGUMENTS = "--version"; - - std::vector candidate_paths; -#if defined(_WIN32) - candidate_paths.push_back(TOOL_DATA.exe_path); -#endif - const std::vector from_path = Files::find_from_PATH("git"); - candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); - - const auto& program_files = System::get_program_files_platform_bitness(); - if (const auto pf = program_files.get()) candidate_paths.push_back(*pf / "git" / "cmd" / "git.exe"); - const auto& program_files_32_bit = System::get_program_files_32_bit(); - if (const auto pf = program_files_32_bit.get()) candidate_paths.push_back(*pf / "git" / "cmd" / "git.exe"); - - const Optional path = - find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, TOOL_DATA.required_version); - if (const auto p = path.get()) - { - return *p; - } - - return fetch_tool(paths, "git", TOOL_DATA); - } - - static fs::path get_ifw_installerbase_path(const VcpkgPaths& paths) - { - static const ToolData TOOL_DATA = parse_tool_data_from_xml(paths, "installerbase"); - - static const std::string VERSION_CHECK_ARGUMENTS = "--framework-version"; - - std::vector candidate_paths; - candidate_paths.push_back(TOOL_DATA.exe_path); - // TODO: Uncomment later - // const std::vector from_path = Files::find_from_PATH("installerbase"); - // candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); - // candidate_paths.push_back(fs::path(System::get_environment_variable("HOMEDRIVE").value_or("C:")) / "Qt" / - // "Tools" / "QtInstallerFramework" / "3.1" / "bin" / "installerbase.exe"); - // candidate_paths.push_back(fs::path(System::get_environment_variable("HOMEDRIVE").value_or("C:")) / "Qt" / - // "QtIFW-3.1.0" / "bin" / "installerbase.exe"); - - const Optional path = - find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, TOOL_DATA.required_version); - if (const auto p = path.get()) - { - return *p; - } - - return fetch_tool(paths, "installerbase", TOOL_DATA); - } - Expected VcpkgPaths::create(const fs::path& vcpkg_root_dir, const std::string& default_vs_path) { std::error_code ec; @@ -471,266 +83,22 @@ namespace vcpkg bool VcpkgPaths::is_valid_triplet(const Triplet& t) const { - auto it = Util::find_if(this->get_available_triplets(), - [&](auto&& available_triplet) { return t.canonical_name() == available_triplet; }); + const auto it = Util::find_if(this->get_available_triplets(), [&](auto&& available_triplet) { + return t.canonical_name() == available_triplet; + }); return it != this->get_available_triplets().cend(); } - const fs::path& VcpkgPaths::get_7za_exe() const + const fs::path& VcpkgPaths::get_tool_exe(const std::string& tool) const { - return this->_7za_exe.get_lazy([this]() { return get_7za_path(*this); }); - } - - const fs::path& VcpkgPaths::get_cmake_exe() const - { - return this->cmake_exe.get_lazy([this]() { return get_cmake_path(*this); }); - } - - const fs::path& VcpkgPaths::get_git_exe() const - { - return this->git_exe.get_lazy([this]() { return get_git_path(*this); }); - } - - const fs::path& VcpkgPaths::get_ninja_exe() const - { - return this->ninja_exe.get_lazy([this]() { return get_ninja_path(*this); }); - } - - const fs::path& VcpkgPaths::get_nuget_exe() const - { - return this->nuget_exe.get_lazy([this]() { return get_nuget_path(*this); }); - } - - const fs::path& VcpkgPaths::get_ifw_installerbase_exe() const - { - return this->ifw_installerbase_exe.get_lazy([this]() { return get_ifw_installerbase_path(*this); }); - } - - const fs::path& VcpkgPaths::get_ifw_binarycreator_exe() const - { - return this->ifw_binarycreator_exe.get_lazy( - [this]() { return get_ifw_installerbase_exe().parent_path() / "binarycreator.exe"; }); - } - - const fs::path& VcpkgPaths::get_ifw_repogen_exe() const - { - return this->ifw_repogen_exe.get_lazy( - [this]() { return get_ifw_installerbase_exe().parent_path() / "repogen.exe"; }); - } - - struct VisualStudioInstance - { - fs::path root_path; - std::string version; - std::string release_type; - std::string preference_weight; // Mostly unused, just for verification that order is as intended - - std::string major_version() const { return version.substr(0, 2); } - }; - - static std::vector get_visual_studio_instances(const VcpkgPaths& paths) - { - const fs::path script = paths.scripts / "findVisualStudioInstallationInstances.ps1"; - const std::string output = - System::powershell_execute_and_capture_output("Detecting Visual Studio instances", script); - - const std::vector instances_as_strings = keep_data_lines(output); - Checks::check_exit(VCPKG_LINE_INFO, - !instances_as_strings.empty(), - "Could not detect any Visual Studio instances.\n" - "Powershell script:\n" - " %s\n" - "returned:\n" - "%s", - script.generic_string(), - output); - - std::vector instances; - for (const std::string& instance_as_string : instances_as_strings) - { - const std::vector split = Strings::split(instance_as_string, "::"); - Checks::check_exit(VCPKG_LINE_INFO, - split.size() == 4, - "Invalid Visual Studio instance format.\n" - "Expected: PreferenceWeight::ReleaseType::Version::PathToVisualStudio\n" - "Actual : %s\n", - instance_as_string); - instances.push_back({split.at(3), split.at(2), split.at(1), split.at(0)}); - } - - return instances; - } - - static std::vector find_toolset_instances(const VcpkgPaths& paths) - { - using CPU = System::CPUArchitecture; - - const auto& fs = paths.get_filesystem(); - - // Note: this will contain a mix of vcvarsall.bat locations and dumpbin.exe locations. - std::vector paths_examined; - - std::vector found_toolsets; - std::vector excluded_toolsets; - - const std::vector vs_instances = get_visual_studio_instances(paths); - const bool v140_is_available = Util::find_if(vs_instances, [&](const VisualStudioInstance& vs_instance) { - return vs_instance.major_version() == "14"; - }) != vs_instances.cend(); - - for (const VisualStudioInstance& vs_instance : vs_instances) - { - const std::string major_version = vs_instance.major_version(); - if (major_version == "15") - { - const fs::path vc_dir = vs_instance.root_path / "VC"; - - // Skip any instances that do not have vcvarsall. - const fs::path vcvarsall_dir = vc_dir / "Auxiliary" / "Build"; - const fs::path vcvarsall_bat = vcvarsall_dir / "vcvarsall.bat"; - paths_examined.push_back(vcvarsall_bat); - if (!fs.exists(vcvarsall_bat)) continue; - - // Get all supported architectures - std::vector supported_architectures; - if (fs.exists(vcvarsall_dir / "vcvars32.bat")) - supported_architectures.push_back({"x86", CPU::X86, CPU::X86}); - if (fs.exists(vcvarsall_dir / "vcvars64.bat")) - supported_architectures.push_back({"amd64", CPU::X64, CPU::X64}); - if (fs.exists(vcvarsall_dir / "vcvarsx86_amd64.bat")) - supported_architectures.push_back({"x86_amd64", CPU::X86, CPU::X64}); - if (fs.exists(vcvarsall_dir / "vcvarsx86_arm.bat")) - supported_architectures.push_back({"x86_arm", CPU::X86, CPU::ARM}); - if (fs.exists(vcvarsall_dir / "vcvarsx86_arm64.bat")) - supported_architectures.push_back({"x86_arm64", CPU::X86, CPU::ARM64}); - if (fs.exists(vcvarsall_dir / "vcvarsamd64_x86.bat")) - supported_architectures.push_back({"amd64_x86", CPU::X64, CPU::X86}); - if (fs.exists(vcvarsall_dir / "vcvarsamd64_arm.bat")) - supported_architectures.push_back({"amd64_arm", CPU::X64, CPU::ARM}); - if (fs.exists(vcvarsall_dir / "vcvarsamd64_arm64.bat")) - supported_architectures.push_back({"amd64_arm64", CPU::X64, CPU::ARM64}); - - // Locate the "best" MSVC toolchain version - const fs::path msvc_path = vc_dir / "Tools" / "MSVC"; - std::vector 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) { return left.filename() > right.filename(); }); - - for (const fs::path& subdir : msvc_subdirectories) - { - const fs::path dumpbin_path = subdir / "bin" / "HostX86" / "x86" / "dumpbin.exe"; - paths_examined.push_back(dumpbin_path); - if (fs.exists(dumpbin_path)) - { - const Toolset v141toolset = Toolset{ - vs_instance.root_path, dumpbin_path, vcvarsall_bat, {}, V_141, supported_architectures}; - - auto english_language_pack = dumpbin_path.parent_path() / "1033"; - - if (!fs.exists(english_language_pack)) - { - excluded_toolsets.push_back(v141toolset); - break; - } - - found_toolsets.push_back(v141toolset); - - if (v140_is_available) - { - const Toolset v140toolset = Toolset{vs_instance.root_path, - dumpbin_path, - vcvarsall_bat, - {"-vcvars_ver=14.0"}, - V_140, - supported_architectures}; - found_toolsets.push_back(v140toolset); - } - - break; - } - } - - continue; - } - - if (major_version == "14" || major_version == "12") - { - const fs::path vcvarsall_bat = vs_instance.root_path / "VC" / "vcvarsall.bat"; - - paths_examined.push_back(vcvarsall_bat); - if (fs.exists(vcvarsall_bat)) - { - const fs::path vs_dumpbin_exe = vs_instance.root_path / "VC" / "bin" / "dumpbin.exe"; - paths_examined.push_back(vs_dumpbin_exe); - - const fs::path vs_bin_dir = vcvarsall_bat.parent_path() / "bin"; - std::vector supported_architectures; - if (fs.exists(vs_bin_dir / "vcvars32.bat")) - supported_architectures.push_back({"x86", CPU::X86, CPU::X86}); - if (fs.exists(vs_bin_dir / "amd64\\vcvars64.bat")) - supported_architectures.push_back({"x64", CPU::X64, CPU::X64}); - if (fs.exists(vs_bin_dir / "x86_amd64\\vcvarsx86_amd64.bat")) - supported_architectures.push_back({"x86_amd64", CPU::X86, CPU::X64}); - if (fs.exists(vs_bin_dir / "x86_arm\\vcvarsx86_arm.bat")) - supported_architectures.push_back({"x86_arm", CPU::X86, CPU::ARM}); - if (fs.exists(vs_bin_dir / "amd64_x86\\vcvarsamd64_x86.bat")) - supported_architectures.push_back({"amd64_x86", CPU::X64, CPU::X86}); - if (fs.exists(vs_bin_dir / "amd64_arm\\vcvarsamd64_arm.bat")) - supported_architectures.push_back({"amd64_arm", CPU::X64, CPU::ARM}); - - if (fs.exists(vs_dumpbin_exe)) - { - const Toolset toolset = {vs_instance.root_path, - vs_dumpbin_exe, - vcvarsall_bat, - {}, - major_version == "14" ? V_140 : V_120, - supported_architectures}; - - auto english_language_pack = vs_dumpbin_exe.parent_path() / "1033"; - - if (!fs.exists(english_language_pack)) - { - excluded_toolsets.push_back(toolset); - break; - } - - found_toolsets.push_back(toolset); - } - } - } - } - - if (!excluded_toolsets.empty()) - { - System::println( - System::Color::warning, - "Warning: The following VS instances are excluded because the English language pack is unavailable."); - for (const Toolset& toolset : excluded_toolsets) - { - System::println(" %s", toolset.visual_studio_root_path.u8string()); - } - System::println(System::Color::warning, "Please install the English language pack."); - } - - if (found_toolsets.empty()) + const auto it = this->tool_paths.find(tool); + if (it != this->tool_paths.cend()) { - System::println(System::Color::error, "Could not locate a complete toolset."); - System::println("The following paths were examined:"); - for (const fs::path& path : paths_examined) - { - System::println(" %s", path.u8string()); - } - Checks::exit_fail(VCPKG_LINE_INFO); + return it->second; } - return found_toolsets; + this->tool_paths[tool] = Commands::Fetch::get_tool_path(*this, tool); + return this->tool_paths[tool]; } const Toolset& VcpkgPaths::get_toolset(const Build::PreBuildInfo& prebuildinfo) const @@ -754,7 +122,7 @@ namespace vcpkg // Invariant: toolsets are non-empty and sorted with newest at back() const std::vector& vs_toolsets = - this->toolsets.get_lazy([this]() { return find_toolset_instances(*this); }); + this->toolsets.get_lazy([this]() { return Commands::Fetch::find_toolset_instances(*this); }); std::vector candidates = Util::element_pointers(vs_toolsets); const auto tsv = prebuildinfo.platform_toolset.get(); diff --git a/toolsrc/vcpkglib/vcpkglib.vcxproj b/toolsrc/vcpkglib/vcpkglib.vcxproj index ae699a840..871d0c58d 100644 --- a/toolsrc/vcpkglib/vcpkglib.vcxproj +++ b/toolsrc/vcpkglib/vcpkglib.vcxproj @@ -214,6 +214,7 @@ + diff --git a/toolsrc/vcpkglib/vcpkglib.vcxproj.filters b/toolsrc/vcpkglib/vcpkglib.vcxproj.filters index 74bfebf3b..6a23a09b5 100644 --- a/toolsrc/vcpkglib/vcpkglib.vcxproj.filters +++ b/toolsrc/vcpkglib/vcpkglib.vcxproj.filters @@ -198,6 +198,9 @@ Source Files\vcpkg + + Source Files\vcpkg + -- cgit v1.2.3 From 23c2b82535d24a8ef343ce2ca36e5a63d111dcd8 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 4 Apr 2018 19:28:10 -0700 Subject: [vcpkgTools.xml] Add os="windows" to relevant entries --- toolsrc/src/vcpkg/commands.fetch.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/commands.fetch.cpp b/toolsrc/src/vcpkg/commands.fetch.cpp index 95c47e2db..cfb1b6c2a 100644 --- a/toolsrc/src/vcpkg/commands.fetch.cpp +++ b/toolsrc/src/vcpkg/commands.fetch.cpp @@ -78,16 +78,11 @@ namespace vcpkg::Commands::Fetch Strings::format(R"###(([\s\S]*?))###")}; static const std::regex URL_REGEX{Strings::format(R"###(([\s\S]*?))###")}; - std::regex tool_regex{ + const std::regex tool_regex{ Strings::format(R"###(([\s\S]*?)<\/tool>)###", tool, OS_STRING)}; std::smatch match_tool; - bool has_match_tool = std::regex_search(XML.cbegin(), XML.cend(), match_tool, tool_regex); - if (!has_match_tool && OS_STRING == "windows") // Legacy support. Change introduced in vcpkg v0.0.107. - { - tool_regex = Strings::format(R"###(([\s\S]*?)<\/tool>)###", tool); - has_match_tool = std::regex_search(XML.cbegin(), XML.cend(), match_tool, tool_regex); - } + const bool has_match_tool = std::regex_search(XML.cbegin(), XML.cend(), match_tool, tool_regex); Checks::check_exit(VCPKG_LINE_INFO, has_match_tool, "Could not find entry for tool [%s] in %s", -- cgit v1.2.3 From 863a8f3329356d260c02c0d6f855e81fd1e2cea9 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 4 Apr 2018 19:37:31 -0700 Subject: [vcpkgTools.xml] Rename archiveRelativePath to archiveName --- toolsrc/src/vcpkg/commands.fetch.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/commands.fetch.cpp b/toolsrc/src/vcpkg/commands.fetch.cpp index cfb1b6c2a..10153293c 100644 --- a/toolsrc/src/vcpkg/commands.fetch.cpp +++ b/toolsrc/src/vcpkg/commands.fetch.cpp @@ -75,7 +75,7 @@ namespace vcpkg::Commands::Fetch static const std::regex EXE_RELATIVE_PATH_REGEX{ Strings::format(R"###(([\s\S]*?))###")}; static const std::regex ARCHIVE_RELATIVE_PATH_REGEX{ - Strings::format(R"###(([\s\S]*?))###")}; + Strings::format(R"###(([\s\S]*?))###")}; static const std::regex URL_REGEX{Strings::format(R"###(([\s\S]*?))###")}; const std::regex tool_regex{ -- cgit v1.2.3 From 32404eee694266a23a5d8a2c2f004d68c1d79195 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 4 Apr 2018 19:52:14 -0700 Subject: [vcpkgTools.xml] Verify the version field --- toolsrc/src/vcpkg/commands.fetch.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/commands.fetch.cpp b/toolsrc/src/vcpkg/commands.fetch.cpp index 10153293c..d2634a5f0 100644 --- a/toolsrc/src/vcpkg/commands.fetch.cpp +++ b/toolsrc/src/vcpkg/commands.fetch.cpp @@ -50,6 +50,7 @@ namespace vcpkg::Commands::Fetch static constexpr StringLiteral OS_STRING = "linux"; #endif + static const std::string XML_VERSION = "1"; static const fs::path XML_PATH = paths.scripts / "vcpkgTools.xml"; const auto maybe_get_string_inside_tags = [](const std::string& input, @@ -70,6 +71,7 @@ namespace vcpkg::Commands::Fetch return match[1]; }; + static const std::regex XML_VERSION_REGEX{R"###()###"}; static const std::string XML = paths.get_filesystem().read_contents(XML_PATH).value_or_exit(VCPKG_LINE_INFO); static const std::regex VERSION_REGEX{R"###(([\s\S]*?))###"}; static const std::regex EXE_RELATIVE_PATH_REGEX{ @@ -78,6 +80,17 @@ namespace vcpkg::Commands::Fetch Strings::format(R"###(([\s\S]*?))###")}; static const std::regex URL_REGEX{Strings::format(R"###(([\s\S]*?))###")}; + std::smatch match_xml_version; + const bool has_xml_version = std::regex_search(XML.cbegin(), XML.cend(), match_xml_version, XML_VERSION_REGEX); + Checks::check_exit( + VCPKG_LINE_INFO, has_xml_version, "Could not find in %s", XML_PATH.generic_string()); + Checks::check_exit(VCPKG_LINE_INFO, + XML_VERSION == match_xml_version[1], + "Expected %s version: [%s], but was [%s]. Please re-run bootstrap-vcpkg.", + XML_PATH.generic_string(), + XML_VERSION, + match_xml_version[1]); + const std::regex tool_regex{ Strings::format(R"###(([\s\S]*?)<\/tool>)###", tool, OS_STRING)}; -- cgit v1.2.3 From da9d1c46750bf78db65383e3a48d71905b8f91ef Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 4 Apr 2018 19:53:56 -0700 Subject: Misc archiveRelativePath->archiveName renames --- toolsrc/src/vcpkg/commands.fetch.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/commands.fetch.cpp b/toolsrc/src/vcpkg/commands.fetch.cpp index d2634a5f0..90b408cc0 100644 --- a/toolsrc/src/vcpkg/commands.fetch.cpp +++ b/toolsrc/src/vcpkg/commands.fetch.cpp @@ -76,8 +76,7 @@ namespace vcpkg::Commands::Fetch static const std::regex VERSION_REGEX{R"###(([\s\S]*?))###"}; static const std::regex EXE_RELATIVE_PATH_REGEX{ Strings::format(R"###(([\s\S]*?))###")}; - static const std::regex ARCHIVE_RELATIVE_PATH_REGEX{ - Strings::format(R"###(([\s\S]*?))###")}; + static const std::regex ARCHIVE_NAME_REGEX{Strings::format(R"###(([\s\S]*?))###")}; static const std::regex URL_REGEX{Strings::format(R"###(([\s\S]*?))###")}; std::smatch match_xml_version; @@ -112,7 +111,7 @@ namespace vcpkg::Commands::Fetch const std::string exe_relative_path = get_string_inside_tags(tool_data_as_string, EXE_RELATIVE_PATH_REGEX, "exeRelativePath"); - auto archive_relative_path = maybe_get_string_inside_tags(tool_data_as_string, ARCHIVE_RELATIVE_PATH_REGEX); + auto archive_name = maybe_get_string_inside_tags(tool_data_as_string, ARCHIVE_NAME_REGEX); const Optional> required_version = parse_version_string(required_version_as_string); Checks::check_exit(VCPKG_LINE_INFO, @@ -127,7 +126,7 @@ namespace vcpkg::Commands::Fetch return ToolData{*required_version.get(), exe_path, url, - paths.downloads / archive_relative_path.value_or(exe_relative_path), + paths.downloads / archive_name.value_or(exe_relative_path), tool_dir_path}; } -- cgit v1.2.3 From 408cd5ccb8d8260efd9a8f2ff956414587d42e28 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 4 Apr 2018 20:33:45 -0700 Subject: [vcpkgTools.xml] requiredVersion -> version --- toolsrc/src/vcpkg/commands.fetch.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/commands.fetch.cpp b/toolsrc/src/vcpkg/commands.fetch.cpp index 90b408cc0..a82f31724 100644 --- a/toolsrc/src/vcpkg/commands.fetch.cpp +++ b/toolsrc/src/vcpkg/commands.fetch.cpp @@ -15,7 +15,7 @@ namespace vcpkg::Commands::Fetch struct ToolData { - std::array required_version; + std::array version; fs::path exe_path; std::string url; fs::path downloaded_path; @@ -73,7 +73,7 @@ namespace vcpkg::Commands::Fetch static const std::regex XML_VERSION_REGEX{R"###()###"}; static const std::string XML = paths.get_filesystem().read_contents(XML_PATH).value_or_exit(VCPKG_LINE_INFO); - static const std::regex VERSION_REGEX{R"###(([\s\S]*?))###"}; + static const std::regex VERSION_REGEX{R"###(([\s\S]*?))###"}; static const std::regex EXE_RELATIVE_PATH_REGEX{ Strings::format(R"###(([\s\S]*?))###")}; static const std::regex ARCHIVE_NAME_REGEX{Strings::format(R"###(([\s\S]*?))###")}; @@ -104,7 +104,7 @@ namespace vcpkg::Commands::Fetch const std::string tool_data_as_string = get_string_inside_tags(XML, tool_regex, tool); const std::string required_version_as_string = - get_string_inside_tags(tool_data_as_string, VERSION_REGEX, "requiredVersion"); + get_string_inside_tags(tool_data_as_string, VERSION_REGEX, "version"); const std::string url = get_string_inside_tags(tool_data_as_string, URL_REGEX, "url"); @@ -220,7 +220,7 @@ namespace vcpkg::Commands::Fetch { const auto& fs = paths.get_filesystem(); const fs::path& scripts_folder = paths.scripts; - const std::array& version = tool_data.required_version; + const std::array& version = tool_data.version; const std::string version_as_string = Strings::format("%d.%d.%d", version[0], version[1], version[2]); System::println("A suitable version of %s was not found (required v%s). Downloading portable %s v%s...", @@ -289,7 +289,7 @@ namespace vcpkg::Commands::Fetch if (const auto pf = program_files_32_bit.get()) candidate_paths.push_back(*pf / "CMake" / "bin" / "cmake.exe"); const Optional path = - find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, TOOL_DATA.required_version); + find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, TOOL_DATA.version); if (const auto p = path.get()) { return *p; @@ -321,7 +321,7 @@ namespace vcpkg::Commands::Fetch const std::vector from_path = Files::find_from_PATH("ninja"); candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); - auto path = find_if_has_equal_or_greater_version(candidate_paths, "--version", TOOL_DATA.required_version); + auto path = find_if_has_equal_or_greater_version(candidate_paths, "--version", TOOL_DATA.version); if (const auto p = path.get()) { return *p; @@ -339,7 +339,7 @@ namespace vcpkg::Commands::Fetch const std::vector from_path = Files::find_from_PATH("nuget"); candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); - auto path = find_if_has_equal_or_greater_version(candidate_paths, "", TOOL_DATA.required_version); + auto path = find_if_has_equal_or_greater_version(candidate_paths, "", TOOL_DATA.version); if (const auto p = path.get()) { return *p; @@ -370,7 +370,7 @@ namespace vcpkg::Commands::Fetch if (const auto pf = program_files_32_bit.get()) candidate_paths.push_back(*pf / "git" / "cmd" / "git.exe"); const Optional path = - find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, TOOL_DATA.required_version); + find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, TOOL_DATA.version); if (const auto p = path.get()) { return *p; @@ -396,7 +396,7 @@ namespace vcpkg::Commands::Fetch // "QtIFW-3.1.0" / "bin" / "installerbase.exe"); const Optional path = - find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, TOOL_DATA.required_version); + find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, TOOL_DATA.version); if (const auto p = path.get()) { return *p; -- cgit v1.2.3 From 540ab527894f96a57682dc4bca2a08548221b762 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 4 Apr 2018 20:47:58 -0700 Subject: Fix #ifdef'ed references to get_tool_exe() --- toolsrc/src/vcpkg/build.cpp | 2 +- toolsrc/src/vcpkg/commands.hash.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index 86d171534..b7055100b 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -338,7 +338,7 @@ namespace vcpkg::Build #if !defined(_WIN32) // TODO: remove when vcpkg.exe is in charge for acquiring tools. Change introduced in vcpkg v0.0.107. // bootstrap should have already downloaded ninja, but making sure it is present in case it was deleted. - vcpkg::Util::unused(paths.get_ninja_exe()); + vcpkg::Util::unused(paths.get_tool_exe(Tools::NINJA)); #endif const fs::path& cmake_exe_path = paths.get_tool_exe(Tools::CMAKE); diff --git a/toolsrc/src/vcpkg/commands.hash.cpp b/toolsrc/src/vcpkg/commands.hash.cpp index 9e1b54390..517970b2c 100644 --- a/toolsrc/src/vcpkg/commands.hash.cpp +++ b/toolsrc/src/vcpkg/commands.hash.cpp @@ -112,7 +112,7 @@ namespace vcpkg::Commands::Hash { const std::string cmd_line = Strings::format( R"("%s" -E %ssum "%s")", - paths.get_cmake_exe().u8string(), + paths.get_tool_exe(Tools::CMAKE).u8string(), Strings::ascii_to_lowercase(hash_type), path.u8string()); -- cgit v1.2.3 From 0108d6ea2808adea5fe7ce97f6871b59a0fadb1d Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 4 Apr 2018 21:47:50 -0700 Subject: Disable vcpkg fetch for now --- toolsrc/src/vcpkg/commands.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/commands.cpp b/toolsrc/src/vcpkg/commands.cpp index e98ff711a..c6b700aae 100644 --- a/toolsrc/src/vcpkg/commands.cpp +++ b/toolsrc/src/vcpkg/commands.cpp @@ -43,7 +43,7 @@ namespace vcpkg::Commands {"portsdiff", &PortsDiff::perform_and_exit}, {"autocomplete", &Autocomplete::perform_and_exit}, {"hash", &Hash::perform_and_exit}, - {"fetch", &Fetch::perform_and_exit}, + // {"fetch", &Fetch::perform_and_exit}, }; return t; } -- cgit v1.2.3 From b217246f70fd6ac8f8d093b4457ae9035a2dd954 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 4 Apr 2018 22:01:08 -0700 Subject: [vcpkg.exe] Hash check after downloading a tool --- toolsrc/src/vcpkg/commands.fetch.cpp | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/commands.fetch.cpp b/toolsrc/src/vcpkg/commands.fetch.cpp index a82f31724..33fa74c62 100644 --- a/toolsrc/src/vcpkg/commands.fetch.cpp +++ b/toolsrc/src/vcpkg/commands.fetch.cpp @@ -20,6 +20,7 @@ namespace vcpkg::Commands::Fetch std::string url; fs::path downloaded_path; fs::path tool_dir_path; + std::string sha512; }; static Optional> parse_version_string(const std::string& version_as_string) @@ -78,6 +79,7 @@ namespace vcpkg::Commands::Fetch Strings::format(R"###(([\s\S]*?))###")}; static const std::regex ARCHIVE_NAME_REGEX{Strings::format(R"###(([\s\S]*?))###")}; static const std::regex URL_REGEX{Strings::format(R"###(([\s\S]*?))###")}; + static const std::regex SHA512_REGEX{Strings::format(R"###(([\s\S]*?))###")}; std::smatch match_xml_version; const bool has_xml_version = std::regex_search(XML.cbegin(), XML.cend(), match_xml_version, XML_VERSION_REGEX); @@ -123,11 +125,15 @@ namespace vcpkg::Commands::Fetch const std::string tool_dir_name = Strings::format("%s-%s-%s", tool, required_version_as_string, OS_STRING); const fs::path tool_dir_path = paths.downloads / "tools" / tool_dir_name; const fs::path exe_path = tool_dir_path / exe_relative_path; + + const std::string sha512 = get_string_inside_tags(tool_data_as_string, SHA512_REGEX, "sha512"); + return ToolData{*required_version.get(), exe_path, url, paths.downloads / archive_name.value_or(exe_relative_path), - tool_dir_path}; + tool_dir_path, + sha512}; } static bool exists_and_has_equal_or_greater_version(const std::string& version_cmd, @@ -256,6 +262,17 @@ namespace vcpkg::Commands::Fetch Checks::check_exit(VCPKG_LINE_INFO, code == 0, "curl failed while downloading %s", tool_data.url); } + const std::string actual_hash = Hash::get_file_hash(paths, tool_data.downloaded_path, "SHA512"); + Checks::check_exit(VCPKG_LINE_INFO, + tool_data.sha512 == actual_hash, + "File does not have the expected hash:\n" + " File path : [ %s ]\n" + " Expected hash: [ %s ]\n" + " Actual hash: [ %s ] \n", + tool_data.downloaded_path.u8string(), + tool_data.sha512, + actual_hash); + System::println("Extracting %s...", tool_name); extract_archive(paths, tool_data.downloaded_path, tool_data.tool_dir_path); System::println("Extracting %s... done.", tool_name); -- cgit v1.2.3 From 7cfc53a45e53476ff93406644c82c4f15563f67b Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 5 Apr 2018 03:37:04 -0700 Subject: [vcpkg.exe] Move downloaded file in place after hash check --- toolsrc/src/vcpkg/commands.fetch.cpp | 59 +++++++++++++++++++++++++----------- 1 file changed, 41 insertions(+), 18 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/commands.fetch.cpp b/toolsrc/src/vcpkg/commands.fetch.cpp index 33fa74c62..e369f44d2 100644 --- a/toolsrc/src/vcpkg/commands.fetch.cpp +++ b/toolsrc/src/vcpkg/commands.fetch.cpp @@ -18,7 +18,7 @@ namespace vcpkg::Commands::Fetch std::array version; fs::path exe_path; std::string url; - fs::path downloaded_path; + fs::path download_path; fs::path tool_dir_path; std::string sha512; }; @@ -219,7 +219,41 @@ namespace vcpkg::Commands::Fetch Checks::exit_with_message(VCPKG_LINE_INFO, "Unexpected archive extension: %s", ext.u8string()); } - fs.rename(to_path_partial, to_path); + fs.rename(to_path_partial, to_path, ec); + } + + static void download_file(const VcpkgPaths& paths, + const std::string& url, + const fs::path& download_path, + const std::string& sha512) + { + Files::Filesystem& fs = paths.get_filesystem(); + if (fs.exists(download_path)) + { + return; + } + + const std::string download_path_part = download_path.u8string() + ".part"; + std::error_code ec; + fs.remove(download_path_part, ec); + const auto code = System::cmd_execute(Strings::format( + R"(curl -L '%s' --create-dirs --output '%s')", url, download_path_part)); + Checks::check_exit(VCPKG_LINE_INFO, code == 0, "Could not download %s", url); + + const std::string actual_hash = Hash::get_file_hash(paths, download_path_part, "SHA512"); + Checks::check_exit(VCPKG_LINE_INFO, + sha512 == actual_hash, + "File does not have the expected hash:\n" + " url : [ %s ]\n" + " File path : [ %s ]\n" + " Expected hash: [ %s ]\n" + " Actual hash: [ %s ] \n", + url, + download_path.u8string(), + sha512, + actual_hash); + + fs.rename(download_path_part, download_path, ec); } static fs::path fetch_tool(const VcpkgPaths& paths, const std::string& tool_name, const ToolData& tool_data) @@ -255,26 +289,15 @@ namespace vcpkg::Commands::Fetch actual_downloaded_path.u8string()); return actual_downloaded_path; #else - if (!fs.exists(tool_data.downloaded_path)) + if (!fs.exists(tool_data.download_path)) { - auto code = System::cmd_execute(Strings::format( - R"(curl -L '%s' --create-dirs --output '%s')", tool_data.url, tool_data.downloaded_path)); - Checks::check_exit(VCPKG_LINE_INFO, code == 0, "curl failed while downloading %s", tool_data.url); + System::println("Downloading %s...", tool_name); + download_file(paths, tool_data.url, tool_data.download_path, tool_data.sha512); + System::println("Downloading %s... done.", tool_name); } - const std::string actual_hash = Hash::get_file_hash(paths, tool_data.downloaded_path, "SHA512"); - Checks::check_exit(VCPKG_LINE_INFO, - tool_data.sha512 == actual_hash, - "File does not have the expected hash:\n" - " File path : [ %s ]\n" - " Expected hash: [ %s ]\n" - " Actual hash: [ %s ] \n", - tool_data.downloaded_path.u8string(), - tool_data.sha512, - actual_hash); - System::println("Extracting %s...", tool_name); - extract_archive(paths, tool_data.downloaded_path, tool_data.tool_dir_path); + extract_archive(paths, tool_data.download_path, tool_data.tool_dir_path); System::println("Extracting %s... done.", tool_name); Checks::check_exit(VCPKG_LINE_INFO, -- cgit v1.2.3 From 870fa61e0132028f43c292b7fd7a7d7c6525a8d7 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 5 Apr 2018 04:29:43 -0700 Subject: [vcpkg hash] Don't use cmake for non-windows hashes. Use shasum instead --- toolsrc/include/vcpkg/commands.h | 4 ++-- toolsrc/src/vcpkg/build.cpp | 8 +++---- toolsrc/src/vcpkg/commands.cpp | 8 ++++--- toolsrc/src/vcpkg/commands.fetch.cpp | 2 +- toolsrc/src/vcpkg/commands.hash.cpp | 43 ++++++++++++++++-------------------- 5 files changed, 31 insertions(+), 34 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/commands.h b/toolsrc/include/vcpkg/commands.h index f6f1de626..65e7fdd14 100644 --- a/toolsrc/include/vcpkg/commands.h +++ b/toolsrc/include/vcpkg/commands.h @@ -131,8 +131,8 @@ namespace vcpkg::Commands namespace Hash { - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); - std::string get_file_hash(const VcpkgPaths& paths, fs::path const& path, std::string const& hash_type); + void perform_and_exit(const VcpkgCmdArguments& args); + std::string get_file_hash(fs::path const& path, std::string const& hash_type); } namespace Fetch diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index b7055100b..16a85db52 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -457,9 +457,9 @@ namespace vcpkg::Build abi_tag_entries.insert(abi_tag_entries.end(), dependency_abis.begin(), dependency_abis.end()); abi_tag_entries.emplace_back( - AbiEntry{"portfile", Commands::Hash::get_file_hash(paths, config.port_dir / "portfile.cmake", "SHA1")}); + AbiEntry{"portfile", Commands::Hash::get_file_hash(config.port_dir / "portfile.cmake", "SHA1")}); abi_tag_entries.emplace_back( - AbiEntry{"control", Commands::Hash::get_file_hash(paths, config.port_dir / "CONTROL", "SHA1")}); + AbiEntry{"control", Commands::Hash::get_file_hash(config.port_dir / "CONTROL", "SHA1")}); abi_tag_entries.emplace_back(AbiEntry{"triplet", pre_build_info.triplet_abi_tag}); @@ -494,7 +494,7 @@ namespace vcpkg::Build auto abi_file_path = paths.buildtrees / name / (triplet.canonical_name() + ".vcpkg_abi_info.txt"); fs.write_contents(abi_file_path, full_abi_info); - return AbiTagAndFile{Commands::Hash::get_file_hash(paths, abi_file_path, "SHA1"), abi_file_path}; + return AbiTagAndFile{Commands::Hash::get_file_hash(abi_file_path, "SHA1"), abi_file_path}; } else { @@ -784,7 +784,7 @@ namespace vcpkg::Build { return it_hash->second; } - auto hash = Commands::Hash::get_file_hash(paths, triplet_file_path, "SHA1"); + auto hash = Commands::Hash::get_file_hash(triplet_file_path, "SHA1"); s_hash_cache.emplace(triplet_file_path, hash); return hash; } diff --git a/toolsrc/src/vcpkg/commands.cpp b/toolsrc/src/vcpkg/commands.cpp index c6b700aae..9041b37ff 100644 --- a/toolsrc/src/vcpkg/commands.cpp +++ b/toolsrc/src/vcpkg/commands.cpp @@ -42,7 +42,6 @@ namespace vcpkg::Commands {"cache", &Cache::perform_and_exit}, {"portsdiff", &PortsDiff::perform_and_exit}, {"autocomplete", &Autocomplete::perform_and_exit}, - {"hash", &Hash::perform_and_exit}, // {"fetch", &Fetch::perform_and_exit}, }; return t; @@ -50,8 +49,11 @@ namespace vcpkg::Commands Span> get_available_commands_type_c() { - static std::vector> t = {{"version", &Version::perform_and_exit}, - {"contact", &Contact::perform_and_exit}}; + static std::vector> t = { + {"version", &Version::perform_and_exit}, + {"contact", &Contact::perform_and_exit}, + {"hash", &Hash::perform_and_exit}, + }; return t; } } diff --git a/toolsrc/src/vcpkg/commands.fetch.cpp b/toolsrc/src/vcpkg/commands.fetch.cpp index e369f44d2..1ba043728 100644 --- a/toolsrc/src/vcpkg/commands.fetch.cpp +++ b/toolsrc/src/vcpkg/commands.fetch.cpp @@ -240,7 +240,7 @@ namespace vcpkg::Commands::Fetch R"(curl -L '%s' --create-dirs --output '%s')", url, download_path_part)); Checks::check_exit(VCPKG_LINE_INFO, code == 0, "Could not download %s", url); - const std::string actual_hash = Hash::get_file_hash(paths, download_path_part, "SHA512"); + const std::string actual_hash = Hash::get_file_hash(download_path_part, "SHA512"); Checks::check_exit(VCPKG_LINE_INFO, sha512 == actual_hash, "File does not have the expected hash:\n" diff --git a/toolsrc/src/vcpkg/commands.hash.cpp b/toolsrc/src/vcpkg/commands.hash.cpp index 517970b2c..087f3e682 100644 --- a/toolsrc/src/vcpkg/commands.hash.cpp +++ b/toolsrc/src/vcpkg/commands.hash.cpp @@ -60,7 +60,7 @@ namespace vcpkg::Commands::Hash }; } - std::string get_file_hash(const VcpkgPaths&, const fs::path& path, const std::string& hash_type) + std::string get_file_hash(const fs::path& path, const std::string& hash_type) { BCryptAlgorithmHandle algorithm_handle; @@ -108,30 +108,25 @@ namespace vcpkg::Commands::Hash #else namespace vcpkg::Commands::Hash { - std::string get_file_hash(const VcpkgPaths& paths, const fs::path& path, const std::string& hash_type) + std::string get_file_hash(const fs::path& path, const std::string& hash_type) { - const std::string cmd_line = Strings::format( - R"("%s" -E %ssum "%s")", - paths.get_tool_exe(Tools::CMAKE).u8string(), - Strings::ascii_to_lowercase(hash_type), - path.u8string()); - - const auto ec_data = System::cmd_execute_and_capture_output(cmd_line); - Checks::check_exit(VCPKG_LINE_INFO, ec_data.exit_code == 0, "Running command:\n %s\n failed", cmd_line); - - std::string const& output = ec_data.output; - - const auto start = output.find_first_of(' '); - Checks::check_exit( - VCPKG_LINE_INFO, start != std::string::npos, "Unexpected output format from command: %s", cmd_line); + if (!Strings::case_insensitive_ascii_starts_with(hash_type, "SHA")) + { + Checks::exit_with_message( + VCPKG_LINE_INFO, "shasum only supports SHA hashes, but %s was provided", hash_type); + } - const auto end = output.find_first_of("\r\n", start + 1); - Checks::check_exit( - VCPKG_LINE_INFO, end != std::string::npos, "Unexpected output format from command: %s", cmd_line); + const std::string digest_size = hash_type.substr(3, hash_type.length() - 3); - auto hash = output.substr(0, start); - Util::erase_remove_if(hash, isspace); - return hash; + const std::string cmd_line = Strings::format( + R"(shasum -a %s "%s" | awk '{ print $1 }')", digest_size, path.u8string()); + const auto ec_data = System::cmd_execute_and_capture_output(cmd_line); + Checks::check_exit(VCPKG_LINE_INFO, + ec_data.exit_code == 0, + "Failed to run:\n" + " %s", + cmd_line); + return Strings::trim(std::string{ec_data.output}); } } #endif @@ -147,13 +142,13 @@ namespace vcpkg::Commands::Hash nullptr, }; - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) + void perform_and_exit(const VcpkgCmdArguments& args) { Util::unused(args.parse_arguments(COMMAND_STRUCTURE)); const fs::path file_to_hash = args.command_arguments[0]; const std::string algorithm = args.command_arguments.size() == 2 ? args.command_arguments[1] : "SHA512"; - const std::string hash = get_file_hash(paths, file_to_hash, algorithm); + const std::string hash = get_file_hash(file_to_hash, algorithm); System::println(hash); Checks::exit_success(VCPKG_LINE_INFO); } -- cgit v1.2.3 From e71230855443a0b87c38e011531cfc6b9d6ffce5 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 5 Apr 2018 16:41:52 -0700 Subject: [vcpkg hash] Add string hashing (as opposed to file hashing) --- toolsrc/include/vcpkg/commands.h | 4 ++- toolsrc/src/vcpkg/commands.hash.cpp | 57 +++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/commands.h b/toolsrc/include/vcpkg/commands.h index 65e7fdd14..d8d2abfa9 100644 --- a/toolsrc/include/vcpkg/commands.h +++ b/toolsrc/include/vcpkg/commands.h @@ -131,8 +131,10 @@ namespace vcpkg::Commands namespace Hash { + std::string get_string_hash(const std::string& s, const std::string& hash_type); + std::string get_file_hash(const fs::path& path, const std::string& hash_type); + void perform_and_exit(const VcpkgCmdArguments& args); - std::string get_file_hash(fs::path const& path, std::string const& hash_type); } namespace Fetch diff --git a/toolsrc/src/vcpkg/commands.hash.cpp b/toolsrc/src/vcpkg/commands.hash.cpp index 087f3e682..856b0e283 100644 --- a/toolsrc/src/vcpkg/commands.hash.cpp +++ b/toolsrc/src/vcpkg/commands.hash.cpp @@ -103,6 +103,42 @@ namespace vcpkg::Commands::Hash return to_hex(hash_buffer.get(), length_in_bytes); } + + std::string get_string_hash(const std::string& s, const std::string& hash_type) + { + BCryptAlgorithmHandle algorithm_handle; + + NTSTATUS error_code = BCryptOpenAlgorithmProvider( + &algorithm_handle.handle, Strings::to_utf16(Strings::ascii_to_uppercase(hash_type)).c_str(), nullptr, 0); + Checks::check_exit(VCPKG_LINE_INFO, NT_SUCCESS(error_code), "Failed to open the algorithm provider"); + + DWORD hash_buffer_bytes; + DWORD cb_data; + error_code = BCryptGetProperty(algorithm_handle.handle, + BCRYPT_HASH_LENGTH, + reinterpret_cast(&hash_buffer_bytes), + sizeof(DWORD), + &cb_data, + 0); + Checks::check_exit(VCPKG_LINE_INFO, NT_SUCCESS(error_code), "Failed to get hash length"); + const ULONG length_in_bytes = hash_buffer_bytes; + + BCryptHashHandle hash_handle; + + error_code = BCryptCreateHash(algorithm_handle.handle, &hash_handle.handle, nullptr, 0, nullptr, 0, 0); + Checks::check_exit(VCPKG_LINE_INFO, NT_SUCCESS(error_code), "Failed to initialize the hasher"); + + auto* const buffer = reinterpret_cast(const_cast(s.c_str())); + error_code = BCryptHashData(hash_handle.handle, buffer, static_cast(s.size()), 0); + Checks::check_exit(VCPKG_LINE_INFO, NT_SUCCESS(error_code), "Failed to hash data"); + + std::unique_ptr hash_buffer = std::make_unique(length_in_bytes); + + error_code = BCryptFinishHash(hash_handle.handle, hash_buffer.get(), length_in_bytes, 0); + Checks::check_exit(VCPKG_LINE_INFO, NT_SUCCESS(error_code), "Failed to finalize the hash"); + + return to_hex(hash_buffer.get(), length_in_bytes); + } } #else @@ -128,6 +164,27 @@ namespace vcpkg::Commands::Hash cmd_line); return Strings::trim(std::string{ec_data.output}); } + + std::string get_string_hash(const std::string& s, const std::string& hash_type) + { + if (!Strings::case_insensitive_ascii_starts_with(hash_type, "SHA")) + { + Checks::exit_with_message( + VCPKG_LINE_INFO, "shasum only supports SHA hashes, but %s was provided", hash_type); + } + + const std::string digest_size = hash_type.substr(3, hash_type.length() - 3); + + const std::string cmd_line = Strings::format( + R"(echo -n "%s" | shasum -a %s | awk '{ print $1 }')", s, digest_size); + const auto ec_data = System::cmd_execute_and_capture_output(cmd_line); + Checks::check_exit(VCPKG_LINE_INFO, + ec_data.exit_code == 0, + "Failed to run:\n" + " %s", + cmd_line); + return Strings::trim(std::string{ec_data.output}); + } } #endif -- cgit v1.2.3 From c1257f988a49b167cd9d94a0931806c6e465700a Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 5 Apr 2018 17:03:45 -0700 Subject: [vcpkg hash] Refactor to reduce code duplication --- toolsrc/src/vcpkg/commands.hash.cpp | 149 +++++++++++++++++++----------------- 1 file changed, 78 insertions(+), 71 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/commands.hash.cpp b/toolsrc/src/vcpkg/commands.hash.cpp index 856b0e283..c0130f12f 100644 --- a/toolsrc/src/vcpkg/commands.hash.cpp +++ b/toolsrc/src/vcpkg/commands.hash.cpp @@ -18,7 +18,7 @@ namespace vcpkg::Commands::Hash { namespace { - static std::string to_hex(const unsigned char* string, const size_t bytes) + std::string to_hex(const unsigned char* string, const size_t bytes) { static constexpr char HEX_MAP[] = "0123456789abcdef"; @@ -58,86 +58,93 @@ namespace vcpkg::Commands::Hash if (handle) BCryptDestroyHash(handle); } }; - } - std::string get_file_hash(const fs::path& path, const std::string& hash_type) - { - BCryptAlgorithmHandle algorithm_handle; - - NTSTATUS error_code = BCryptOpenAlgorithmProvider( - &algorithm_handle.handle, Strings::to_utf16(Strings::ascii_to_uppercase(hash_type)).c_str(), nullptr, 0); - Checks::check_exit(VCPKG_LINE_INFO, NT_SUCCESS(error_code), "Failed to open the algorithm provider"); - - DWORD hash_buffer_bytes; - DWORD cb_data; - error_code = BCryptGetProperty(algorithm_handle.handle, - BCRYPT_HASH_LENGTH, - reinterpret_cast(&hash_buffer_bytes), - sizeof(DWORD), - &cb_data, - 0); - Checks::check_exit(VCPKG_LINE_INFO, NT_SUCCESS(error_code), "Failed to get hash length"); - const ULONG length_in_bytes = hash_buffer_bytes; - - BCryptHashHandle hash_handle; - - error_code = BCryptCreateHash(algorithm_handle.handle, &hash_handle.handle, nullptr, 0, nullptr, 0, 0); - Checks::check_exit(VCPKG_LINE_INFO, NT_SUCCESS(error_code), "Failed to initialize the hasher"); - - FILE* file = nullptr; - const auto ec = _wfopen_s(&file, path.c_str(), L"rb"); - Checks::check_exit(VCPKG_LINE_INFO, ec == 0, "Failed to open file: %s", path.u8string()); - unsigned char buffer[4096]; - while (const auto actual_size = fread(buffer, 1, sizeof(buffer), file)) + struct BCryptHasher { - error_code = BCryptHashData(hash_handle.handle, buffer, static_cast(actual_size), 0); - Checks::check_exit(VCPKG_LINE_INFO, NT_SUCCESS(error_code), "Failed to hash data"); - } - - fclose(file); - - std::unique_ptr hash_buffer = std::make_unique(length_in_bytes); - - error_code = BCryptFinishHash(hash_handle.handle, hash_buffer.get(), length_in_bytes, 0); - Checks::check_exit(VCPKG_LINE_INFO, NT_SUCCESS(error_code), "Failed to finalize the hash"); - - return to_hex(hash_buffer.get(), length_in_bytes); - } - - std::string get_string_hash(const std::string& s, const std::string& hash_type) - { - BCryptAlgorithmHandle algorithm_handle; + explicit BCryptHasher(const std::string& hash_type) + { + NTSTATUS error_code = + BCryptOpenAlgorithmProvider(&this->algorithm_handle.handle, + Strings::to_utf16(Strings::ascii_to_uppercase(hash_type)).c_str(), + nullptr, + 0); + Checks::check_exit(VCPKG_LINE_INFO, NT_SUCCESS(error_code), "Failed to open the algorithm provider"); + + DWORD hash_buffer_bytes; + DWORD cb_data; + error_code = BCryptGetProperty(this->algorithm_handle.handle, + BCRYPT_HASH_LENGTH, + reinterpret_cast(&hash_buffer_bytes), + sizeof(DWORD), + &cb_data, + 0); + Checks::check_exit(VCPKG_LINE_INFO, NT_SUCCESS(error_code), "Failed to get hash length"); + this->length_in_bytes = hash_buffer_bytes; + } - NTSTATUS error_code = BCryptOpenAlgorithmProvider( - &algorithm_handle.handle, Strings::to_utf16(Strings::ascii_to_uppercase(hash_type)).c_str(), nullptr, 0); - Checks::check_exit(VCPKG_LINE_INFO, NT_SUCCESS(error_code), "Failed to open the algorithm provider"); + std::string hash_file(const fs::path& path) const + { + BCryptHashHandle hash_handle; + this->initialize_hash_handle(hash_handle); + + FILE* file = nullptr; + const auto ec = _wfopen_s(&file, path.c_str(), L"rb"); + Checks::check_exit(VCPKG_LINE_INFO, ec == 0, "Failed to open file: %s", path.u8string()); + unsigned char buffer[4096]; + while (const auto actual_size = fread(buffer, 1, sizeof(buffer), file)) + { + hash_data(hash_handle, buffer, actual_size); + } + fclose(file); + + return this->finalize_hash_handle(hash_handle); + } - DWORD hash_buffer_bytes; - DWORD cb_data; - error_code = BCryptGetProperty(algorithm_handle.handle, - BCRYPT_HASH_LENGTH, - reinterpret_cast(&hash_buffer_bytes), - sizeof(DWORD), - &cb_data, - 0); - Checks::check_exit(VCPKG_LINE_INFO, NT_SUCCESS(error_code), "Failed to get hash length"); - const ULONG length_in_bytes = hash_buffer_bytes; + std::string hash_string(const std::string& s) const + { + BCryptHashHandle hash_handle; + this->initialize_hash_handle(hash_handle); + hash_data(hash_handle, reinterpret_cast(const_cast(s.c_str())), s.size()); + return this->finalize_hash_handle(hash_handle); + } - BCryptHashHandle hash_handle; + private: + void initialize_hash_handle(BCryptHashHandle& hash_handle) const + { + const NTSTATUS error_code = + BCryptCreateHash(this->algorithm_handle.handle, &hash_handle.handle, nullptr, 0, nullptr, 0, 0); + Checks::check_exit(VCPKG_LINE_INFO, NT_SUCCESS(error_code), "Failed to initialize the hasher"); + } - error_code = BCryptCreateHash(algorithm_handle.handle, &hash_handle.handle, nullptr, 0, nullptr, 0, 0); - Checks::check_exit(VCPKG_LINE_INFO, NT_SUCCESS(error_code), "Failed to initialize the hasher"); + void hash_data(BCryptHashHandle& hash_handle, unsigned char* buffer, const size_t& data_size) const + { + const NTSTATUS error_code = + BCryptHashData(hash_handle.handle, buffer, static_cast(data_size), 0); + Checks::check_exit(VCPKG_LINE_INFO, NT_SUCCESS(error_code), "Failed to hash data"); + } - auto* const buffer = reinterpret_cast(const_cast(s.c_str())); - error_code = BCryptHashData(hash_handle.handle, buffer, static_cast(s.size()), 0); - Checks::check_exit(VCPKG_LINE_INFO, NT_SUCCESS(error_code), "Failed to hash data"); + std::string finalize_hash_handle(const BCryptHashHandle& hash_handle) const + { + std::unique_ptr hash_buffer = std::make_unique(this->length_in_bytes); + const NTSTATUS error_code = + BCryptFinishHash(hash_handle.handle, hash_buffer.get(), this->length_in_bytes, 0); + Checks::check_exit(VCPKG_LINE_INFO, NT_SUCCESS(error_code), "Failed to finalize the hash"); + return to_hex(hash_buffer.get(), this->length_in_bytes); + } - std::unique_ptr hash_buffer = std::make_unique(length_in_bytes); + BCryptAlgorithmHandle algorithm_handle; + ULONG length_in_bytes; + }; + } - error_code = BCryptFinishHash(hash_handle.handle, hash_buffer.get(), length_in_bytes, 0); - Checks::check_exit(VCPKG_LINE_INFO, NT_SUCCESS(error_code), "Failed to finalize the hash"); + std::string get_file_hash(const fs::path& path, const std::string& hash_type) + { + return BCryptHasher{hash_type}.hash_file(path); + } - return to_hex(hash_buffer.get(), length_in_bytes); + std::string get_string_hash(const std::string& s, const std::string& hash_type) + { + return BCryptHasher{hash_type}.hash_string(s); } } -- cgit v1.2.3 From 3f6f9f3f4d48ef0115f3095f7d8d2c6d3b0c63e1 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 5 Apr 2018 17:12:59 -0700 Subject: [metrics] Use new string-hash functions instead of ps1 script --- toolsrc/src/vcpkg/metrics.cpp | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/metrics.cpp b/toolsrc/src/vcpkg/metrics.cpp index 9e17b237d..4067efc95 100644 --- a/toolsrc/src/vcpkg/metrics.cpp +++ b/toolsrc/src/vcpkg/metrics.cpp @@ -264,17 +264,10 @@ namespace vcpkg::Metrics while (next != last) { - auto match = *next; + const auto match = *next; if (match[0] != "00-00-00-00-00-00") { - const std::string matchstr = match[0]; - const System::PowershellParameter value("Value", matchstr); - auto hash_result = System::powershell_execute_and_capture_output( - "SHA256Hash", get_vcpkg_root() / "scripts" / "SHA256Hash.ps1", {value}); - Util::erase_remove_if(hash_result, - [](char ch) { return !(ch >= 'A' && ch <= 'F') && !(ch >= '0' && ch <= '9'); }); - hash_result = Strings::ascii_to_lowercase(hash_result); - return hash_result; + return vcpkg::Commands::Hash::get_string_hash(match[0], "SHA256"); } ++next; } -- cgit v1.2.3 From ca9503b9d7f9bca6e2f9881a7f4ec9ce9d600928 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 5 Apr 2018 21:28:02 -0700 Subject: [vcpkg hash] Refactor and tweaks in BCryptHasher. --- toolsrc/src/vcpkg/commands.hash.cpp | 83 +++++++++++++++++++------------------ 1 file changed, 42 insertions(+), 41 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/commands.hash.cpp b/toolsrc/src/vcpkg/commands.hash.cpp index c0130f12f..19f73b463 100644 --- a/toolsrc/src/vcpkg/commands.hash.cpp +++ b/toolsrc/src/vcpkg/commands.hash.cpp @@ -39,28 +39,52 @@ namespace vcpkg::Commands::Hash return output; } - struct BCryptAlgorithmHandle : Util::ResourceBase + class BCryptHasher { - BCRYPT_ALG_HANDLE handle = nullptr; + struct BCryptAlgorithmHandle : Util::ResourceBase + { + BCRYPT_ALG_HANDLE handle = nullptr; + + ~BCryptAlgorithmHandle() + { + if (handle) BCryptCloseAlgorithmProvider(handle, 0); + } + }; + + struct BCryptHashHandle : Util::ResourceBase + { + BCRYPT_HASH_HANDLE handle = nullptr; + + ~BCryptHashHandle() + { + if (handle) BCryptDestroyHash(handle); + } + }; - ~BCryptAlgorithmHandle() + static void initialize_hash_handle(BCryptHashHandle& hash_handle, + const BCryptAlgorithmHandle& algorithm_handle) { - if (handle) BCryptCloseAlgorithmProvider(handle, 0); + const NTSTATUS error_code = + BCryptCreateHash(algorithm_handle.handle, &hash_handle.handle, nullptr, 0, nullptr, 0, 0); + Checks::check_exit(VCPKG_LINE_INFO, NT_SUCCESS(error_code), "Failed to initialize the hasher"); } - }; - struct BCryptHashHandle : Util::ResourceBase - { - BCRYPT_HASH_HANDLE handle = nullptr; + static void hash_data(BCryptHashHandle& hash_handle, const unsigned char* buffer, const size_t& data_size) + { + const NTSTATUS error_code = BCryptHashData( + hash_handle.handle, const_cast(buffer), static_cast(data_size), 0); + Checks::check_exit(VCPKG_LINE_INFO, NT_SUCCESS(error_code), "Failed to hash data"); + } - ~BCryptHashHandle() + static std::string finalize_hash_handle(const BCryptHashHandle& hash_handle, const ULONG length_in_bytes) { - if (handle) BCryptDestroyHash(handle); + std::unique_ptr hash_buffer = std::make_unique(length_in_bytes); + const NTSTATUS error_code = BCryptFinishHash(hash_handle.handle, hash_buffer.get(), length_in_bytes, 0); + Checks::check_exit(VCPKG_LINE_INFO, NT_SUCCESS(error_code), "Failed to finalize the hash"); + return to_hex(hash_buffer.get(), length_in_bytes); } - }; - struct BCryptHasher - { + public: explicit BCryptHasher(const std::string& hash_type) { NTSTATUS error_code = @@ -85,7 +109,7 @@ namespace vcpkg::Commands::Hash std::string hash_file(const fs::path& path) const { BCryptHashHandle hash_handle; - this->initialize_hash_handle(hash_handle); + initialize_hash_handle(hash_handle, this->algorithm_handle); FILE* file = nullptr; const auto ec = _wfopen_s(&file, path.c_str(), L"rb"); @@ -97,41 +121,18 @@ namespace vcpkg::Commands::Hash } fclose(file); - return this->finalize_hash_handle(hash_handle); + return finalize_hash_handle(hash_handle, length_in_bytes); } std::string hash_string(const std::string& s) const { BCryptHashHandle hash_handle; - this->initialize_hash_handle(hash_handle); - hash_data(hash_handle, reinterpret_cast(const_cast(s.c_str())), s.size()); - return this->finalize_hash_handle(hash_handle); + initialize_hash_handle(hash_handle, this->algorithm_handle); + hash_data(hash_handle, reinterpret_cast(s.c_str()), s.size()); + return finalize_hash_handle(hash_handle, length_in_bytes); } private: - void initialize_hash_handle(BCryptHashHandle& hash_handle) const - { - const NTSTATUS error_code = - BCryptCreateHash(this->algorithm_handle.handle, &hash_handle.handle, nullptr, 0, nullptr, 0, 0); - Checks::check_exit(VCPKG_LINE_INFO, NT_SUCCESS(error_code), "Failed to initialize the hasher"); - } - - void hash_data(BCryptHashHandle& hash_handle, unsigned char* buffer, const size_t& data_size) const - { - const NTSTATUS error_code = - BCryptHashData(hash_handle.handle, buffer, static_cast(data_size), 0); - Checks::check_exit(VCPKG_LINE_INFO, NT_SUCCESS(error_code), "Failed to hash data"); - } - - std::string finalize_hash_handle(const BCryptHashHandle& hash_handle) const - { - std::unique_ptr hash_buffer = std::make_unique(this->length_in_bytes); - const NTSTATUS error_code = - BCryptFinishHash(hash_handle.handle, hash_buffer.get(), this->length_in_bytes, 0); - Checks::check_exit(VCPKG_LINE_INFO, NT_SUCCESS(error_code), "Failed to finalize the hash"); - return to_hex(hash_buffer.get(), this->length_in_bytes); - } - BCryptAlgorithmHandle algorithm_handle; ULONG length_in_bytes; }; -- cgit v1.2.3 From ec790eb1716fca367dccc2b5f7e96a8719ca74fa Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 5 Apr 2018 22:01:11 -0700 Subject: [vcpkg hash] Refactor to reduce repetition. Allow simple chars in get_string_hash() for now. --- toolsrc/src/vcpkg/commands.hash.cpp | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/commands.hash.cpp b/toolsrc/src/vcpkg/commands.hash.cpp index 19f73b463..a3ac2cbbb 100644 --- a/toolsrc/src/vcpkg/commands.hash.cpp +++ b/toolsrc/src/vcpkg/commands.hash.cpp @@ -152,7 +152,7 @@ namespace vcpkg::Commands::Hash #else namespace vcpkg::Commands::Hash { - std::string get_file_hash(const fs::path& path, const std::string& hash_type) + static std::string get_digest_size(const std::string& hash_type) { if (!Strings::case_insensitive_ascii_starts_with(hash_type, "SHA")) { @@ -160,10 +160,11 @@ namespace vcpkg::Commands::Hash VCPKG_LINE_INFO, "shasum only supports SHA hashes, but %s was provided", hash_type); } - const std::string digest_size = hash_type.substr(3, hash_type.length() - 3); + return hash_type.substr(3, hash_type.length() - 3); + } - const std::string cmd_line = Strings::format( - R"(shasum -a %s "%s" | awk '{ print $1 }')", digest_size, path.u8string()); + static std::string run_shasum_and_post_process(const std::string& cmd_line) + { const auto ec_data = System::cmd_execute_and_capture_output(cmd_line); Checks::check_exit(VCPKG_LINE_INFO, ec_data.exit_code == 0, @@ -173,25 +174,27 @@ namespace vcpkg::Commands::Hash return Strings::trim(std::string{ec_data.output}); } + std::string get_file_hash(const fs::path& path, const std::string& hash_type) + { + const std::string digest_size = get_digest_size(hash_type); + const std::string cmd_line = Strings::format( + R"(shasum -a %s "%s" | awk '{ print $1 }')", digest_size, path.u8string()); + return run_shasum_and_post_process(cmd_line); + } + std::string get_string_hash(const std::string& s, const std::string& hash_type) { - if (!Strings::case_insensitive_ascii_starts_with(hash_type, "SHA")) - { - Checks::exit_with_message( - VCPKG_LINE_INFO, "shasum only supports SHA hashes, but %s was provided", hash_type); - } + const std::string digest_size = get_digest_size(hash_type); - const std::string digest_size = hash_type.substr(3, hash_type.length() - 3); + static const std::regex ALLOWED_CHARS{"^[a-zA-Z0-9:]*$"}; + + Checks::check_exit(VCPKG_LINE_INFO, + std::regex_match(s, ALLOWED_CHARS), + "Only alphanumeric chars and colons are currently allowed"); const std::string cmd_line = Strings::format( R"(echo -n "%s" | shasum -a %s | awk '{ print $1 }')", s, digest_size); - const auto ec_data = System::cmd_execute_and_capture_output(cmd_line); - Checks::check_exit(VCPKG_LINE_INFO, - ec_data.exit_code == 0, - "Failed to run:\n" - " %s", - cmd_line); - return Strings::trim(std::string{ec_data.output}); + return run_shasum_and_post_process(cmd_line); } } #endif -- cgit v1.2.3 From 1bfb01cfeeffc8c8161f64b1bd2986557b6ba207 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 5 Apr 2018 22:05:55 -0700 Subject: [vcpkg hash] Add sanity checking --- toolsrc/include/vcpkg/commands.h | 4 ++-- toolsrc/src/vcpkg/build.cpp | 8 ++++---- toolsrc/src/vcpkg/commands.cpp | 2 +- toolsrc/src/vcpkg/commands.fetch.cpp | 2 +- toolsrc/src/vcpkg/commands.hash.cpp | 33 +++++++++++++++++++++++---------- 5 files changed, 31 insertions(+), 18 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/commands.h b/toolsrc/include/vcpkg/commands.h index d8d2abfa9..6d29b7960 100644 --- a/toolsrc/include/vcpkg/commands.h +++ b/toolsrc/include/vcpkg/commands.h @@ -132,9 +132,9 @@ namespace vcpkg::Commands namespace Hash { std::string get_string_hash(const std::string& s, const std::string& hash_type); - std::string get_file_hash(const fs::path& path, const std::string& hash_type); + std::string get_file_hash(const VcpkgPaths& paths, const fs::path& path, const std::string& hash_type); - void perform_and_exit(const VcpkgCmdArguments& args); + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); } namespace Fetch diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index 16a85db52..b7055100b 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -457,9 +457,9 @@ namespace vcpkg::Build abi_tag_entries.insert(abi_tag_entries.end(), dependency_abis.begin(), dependency_abis.end()); abi_tag_entries.emplace_back( - AbiEntry{"portfile", Commands::Hash::get_file_hash(config.port_dir / "portfile.cmake", "SHA1")}); + AbiEntry{"portfile", Commands::Hash::get_file_hash(paths, config.port_dir / "portfile.cmake", "SHA1")}); abi_tag_entries.emplace_back( - AbiEntry{"control", Commands::Hash::get_file_hash(config.port_dir / "CONTROL", "SHA1")}); + AbiEntry{"control", Commands::Hash::get_file_hash(paths, config.port_dir / "CONTROL", "SHA1")}); abi_tag_entries.emplace_back(AbiEntry{"triplet", pre_build_info.triplet_abi_tag}); @@ -494,7 +494,7 @@ namespace vcpkg::Build auto abi_file_path = paths.buildtrees / name / (triplet.canonical_name() + ".vcpkg_abi_info.txt"); fs.write_contents(abi_file_path, full_abi_info); - return AbiTagAndFile{Commands::Hash::get_file_hash(abi_file_path, "SHA1"), abi_file_path}; + return AbiTagAndFile{Commands::Hash::get_file_hash(paths, abi_file_path, "SHA1"), abi_file_path}; } else { @@ -784,7 +784,7 @@ namespace vcpkg::Build { return it_hash->second; } - auto hash = Commands::Hash::get_file_hash(triplet_file_path, "SHA1"); + auto hash = Commands::Hash::get_file_hash(paths, triplet_file_path, "SHA1"); s_hash_cache.emplace(triplet_file_path, hash); return hash; } diff --git a/toolsrc/src/vcpkg/commands.cpp b/toolsrc/src/vcpkg/commands.cpp index 9041b37ff..8b6ffb3d7 100644 --- a/toolsrc/src/vcpkg/commands.cpp +++ b/toolsrc/src/vcpkg/commands.cpp @@ -42,6 +42,7 @@ namespace vcpkg::Commands {"cache", &Cache::perform_and_exit}, {"portsdiff", &PortsDiff::perform_and_exit}, {"autocomplete", &Autocomplete::perform_and_exit}, + {"hash", &Hash::perform_and_exit}, // {"fetch", &Fetch::perform_and_exit}, }; return t; @@ -52,7 +53,6 @@ namespace vcpkg::Commands static std::vector> t = { {"version", &Version::perform_and_exit}, {"contact", &Contact::perform_and_exit}, - {"hash", &Hash::perform_and_exit}, }; return t; } diff --git a/toolsrc/src/vcpkg/commands.fetch.cpp b/toolsrc/src/vcpkg/commands.fetch.cpp index 1ba043728..e369f44d2 100644 --- a/toolsrc/src/vcpkg/commands.fetch.cpp +++ b/toolsrc/src/vcpkg/commands.fetch.cpp @@ -240,7 +240,7 @@ namespace vcpkg::Commands::Fetch R"(curl -L '%s' --create-dirs --output '%s')", url, download_path_part)); Checks::check_exit(VCPKG_LINE_INFO, code == 0, "Could not download %s", url); - const std::string actual_hash = Hash::get_file_hash(download_path_part, "SHA512"); + const std::string actual_hash = Hash::get_file_hash(paths, download_path_part, "SHA512"); Checks::check_exit(VCPKG_LINE_INFO, sha512 == actual_hash, "File does not have the expected hash:\n" diff --git a/toolsrc/src/vcpkg/commands.hash.cpp b/toolsrc/src/vcpkg/commands.hash.cpp index a3ac2cbbb..3f90eeaca 100644 --- a/toolsrc/src/vcpkg/commands.hash.cpp +++ b/toolsrc/src/vcpkg/commands.hash.cpp @@ -7,6 +7,19 @@ #include #include +namespace vcpkg::Commands::Hash +{ + static void verify_has_only_allowed_chars(const std::string& s) + { + static const std::regex ALLOWED_CHARS{"^[a-zA-Z0-9-]*$"}; + Checks::check_exit(VCPKG_LINE_INFO, + std::regex_match(s, ALLOWED_CHARS), + "Only alphanumeric chars and dashes are currently allowed. String was:\n" + " % s", + s); + } +} + #if defined(_WIN32) #include @@ -138,13 +151,16 @@ namespace vcpkg::Commands::Hash }; } - std::string get_file_hash(const fs::path& path, const std::string& hash_type) + std::string get_file_hash(const VcpkgPaths& paths, const fs::path& path, const std::string& hash_type) { + Checks::check_exit( + VCPKG_LINE_INFO, paths.get_filesystem().exists(path), "File %s does not exist", path.u8string()); return BCryptHasher{hash_type}.hash_file(path); } std::string get_string_hash(const std::string& s, const std::string& hash_type) { + verify_has_only_allowed_chars(s); return BCryptHasher{hash_type}.hash_string(s); } } @@ -174,9 +190,11 @@ namespace vcpkg::Commands::Hash return Strings::trim(std::string{ec_data.output}); } - std::string get_file_hash(const fs::path& path, const std::string& hash_type) + std::string get_file_hash(const VcpkgPaths& paths, const fs::path& path, const std::string& hash_type) { const std::string digest_size = get_digest_size(hash_type); + Checks::check_exit( + VCPKG_LINE_INFO, paths.get_filesystem().exists(path), "File %s does not exist", path.u8string()); const std::string cmd_line = Strings::format( R"(shasum -a %s "%s" | awk '{ print $1 }')", digest_size, path.u8string()); return run_shasum_and_post_process(cmd_line); @@ -185,12 +203,7 @@ namespace vcpkg::Commands::Hash std::string get_string_hash(const std::string& s, const std::string& hash_type) { const std::string digest_size = get_digest_size(hash_type); - - static const std::regex ALLOWED_CHARS{"^[a-zA-Z0-9:]*$"}; - - Checks::check_exit(VCPKG_LINE_INFO, - std::regex_match(s, ALLOWED_CHARS), - "Only alphanumeric chars and colons are currently allowed"); + verify_has_only_allowed_chars(s); const std::string cmd_line = Strings::format( R"(echo -n "%s" | shasum -a %s | awk '{ print $1 }')", s, digest_size); @@ -210,13 +223,13 @@ namespace vcpkg::Commands::Hash nullptr, }; - void perform_and_exit(const VcpkgCmdArguments& args) + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { Util::unused(args.parse_arguments(COMMAND_STRUCTURE)); const fs::path file_to_hash = args.command_arguments[0]; const std::string algorithm = args.command_arguments.size() == 2 ? args.command_arguments[1] : "SHA512"; - const std::string hash = get_file_hash(file_to_hash, algorithm); + const std::string hash = get_file_hash(paths, file_to_hash, algorithm); System::println(hash); Checks::exit_success(VCPKG_LINE_INFO); } -- cgit v1.2.3 From 7d5c33cf1b9483c94894e5f1831c8411b36f37cf Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 6 Apr 2018 14:36:48 -0700 Subject: [vcpkgTools.xml] Bump version to "2" --- toolsrc/src/vcpkg/commands.fetch.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/commands.fetch.cpp b/toolsrc/src/vcpkg/commands.fetch.cpp index e369f44d2..d085fb0f7 100644 --- a/toolsrc/src/vcpkg/commands.fetch.cpp +++ b/toolsrc/src/vcpkg/commands.fetch.cpp @@ -51,7 +51,7 @@ namespace vcpkg::Commands::Fetch static constexpr StringLiteral OS_STRING = "linux"; #endif - static const std::string XML_VERSION = "1"; + static const std::string XML_VERSION = "2"; static const fs::path XML_PATH = paths.scripts / "vcpkgTools.xml"; const auto maybe_get_string_inside_tags = [](const std::string& input, -- cgit v1.2.3 From ee75dd08d3ea93eb2cc2f309a1f49abe2b470448 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 6 Apr 2018 14:45:50 -0700 Subject: Improve error message --- toolsrc/src/vcpkg/commands.fetch.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/commands.fetch.cpp b/toolsrc/src/vcpkg/commands.fetch.cpp index d085fb0f7..0be097bc9 100644 --- a/toolsrc/src/vcpkg/commands.fetch.cpp +++ b/toolsrc/src/vcpkg/commands.fetch.cpp @@ -83,8 +83,11 @@ namespace vcpkg::Commands::Fetch std::smatch match_xml_version; const bool has_xml_version = std::regex_search(XML.cbegin(), XML.cend(), match_xml_version, XML_VERSION_REGEX); - Checks::check_exit( - VCPKG_LINE_INFO, has_xml_version, "Could not find in %s", XML_PATH.generic_string()); + Checks::check_exit(VCPKG_LINE_INFO, + has_xml_version, + R"(Could not find in %s)", + XML_VERSION, + XML_PATH.generic_string()); Checks::check_exit(VCPKG_LINE_INFO, XML_VERSION == match_xml_version[1], "Expected %s version: [%s], but was [%s]. Please re-run bootstrap-vcpkg.", -- cgit v1.2.3 From d11014e2ae97c8f7b38f72d23d942a4f107afd26 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 6 Apr 2018 14:46:40 -0700 Subject: Don't ignore fs.rename() errors --- toolsrc/src/vcpkg/commands.fetch.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/commands.fetch.cpp b/toolsrc/src/vcpkg/commands.fetch.cpp index 0be097bc9..85ec6b289 100644 --- a/toolsrc/src/vcpkg/commands.fetch.cpp +++ b/toolsrc/src/vcpkg/commands.fetch.cpp @@ -222,7 +222,7 @@ namespace vcpkg::Commands::Fetch Checks::exit_with_message(VCPKG_LINE_INFO, "Unexpected archive extension: %s", ext.u8string()); } - fs.rename(to_path_partial, to_path, ec); + fs.rename(to_path_partial, to_path); } static void download_file(const VcpkgPaths& paths, @@ -256,7 +256,7 @@ namespace vcpkg::Commands::Fetch sha512, actual_hash); - fs.rename(download_path_part, download_path, ec); + fs.rename(download_path_part, download_path); } static fs::path fetch_tool(const VcpkgPaths& paths, const std::string& tool_name, const ToolData& tool_data) -- cgit v1.2.3 From ba432c23bccb3e0eb716765984cc9e9e91845822 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 6 Apr 2018 14:47:15 -0700 Subject: Fix spacing in error message --- toolsrc/src/vcpkg/commands.fetch.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/commands.fetch.cpp b/toolsrc/src/vcpkg/commands.fetch.cpp index 85ec6b289..7cce312dd 100644 --- a/toolsrc/src/vcpkg/commands.fetch.cpp +++ b/toolsrc/src/vcpkg/commands.fetch.cpp @@ -247,10 +247,10 @@ namespace vcpkg::Commands::Fetch Checks::check_exit(VCPKG_LINE_INFO, sha512 == actual_hash, "File does not have the expected hash:\n" - " url : [ %s ]\n" - " File path : [ %s ]\n" - " Expected hash: [ %s ]\n" - " Actual hash: [ %s ] \n", + " url : [ %s ]\n" + " File path : [ %s ]\n" + " Expected hash : [ %s ]\n" + " Actual hash : [ %s ]\n", url, download_path.u8string(), sha512, -- cgit v1.2.3 From 80f16f769e981b4a52ae841dd71f73009866133c Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 6 Apr 2018 14:51:53 -0700 Subject: Use Cache class --- toolsrc/include/vcpkg/vcpkgpaths.h | 3 ++- toolsrc/src/vcpkg/vcpkgpaths.cpp | 9 +-------- 2 files changed, 3 insertions(+), 9 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/vcpkgpaths.h b/toolsrc/include/vcpkg/vcpkgpaths.h index 090414de3..fc6b319d8 100644 --- a/toolsrc/include/vcpkg/vcpkgpaths.h +++ b/toolsrc/include/vcpkg/vcpkgpaths.h @@ -3,6 +3,7 @@ #include #include +#include #include #include #include @@ -89,7 +90,7 @@ namespace vcpkg private: Lazy> available_triplets; - mutable std::map tool_paths; + Cache tool_paths; Lazy> toolsets; Lazy> toolsets_vs2013; diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index 4f998d579..0903c2d76 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -91,14 +91,7 @@ namespace vcpkg const fs::path& VcpkgPaths::get_tool_exe(const std::string& tool) const { - const auto it = this->tool_paths.find(tool); - if (it != this->tool_paths.cend()) - { - return it->second; - } - - this->tool_paths[tool] = Commands::Fetch::get_tool_path(*this, tool); - return this->tool_paths[tool]; + return this->tool_paths.get_lazy(tool, [&]() { return Commands::Fetch::get_tool_path(*this, tool); }); } const Toolset& VcpkgPaths::get_toolset(const Build::PreBuildInfo& prebuildinfo) const -- cgit v1.2.3 From 5d96ff1229d3e93f901215f054225d2859b07f5f Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 6 Apr 2018 15:12:26 -0700 Subject: [fetch] Don't attempt to download on unknown OSes --- toolsrc/src/vcpkg/commands.fetch.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/commands.fetch.cpp b/toolsrc/src/vcpkg/commands.fetch.cpp index 7cce312dd..1d2c67d67 100644 --- a/toolsrc/src/vcpkg/commands.fetch.cpp +++ b/toolsrc/src/vcpkg/commands.fetch.cpp @@ -47,10 +47,13 @@ namespace vcpkg::Commands::Fetch static constexpr StringLiteral OS_STRING = "windows"; #elif defined(__APPLE__) static constexpr StringLiteral OS_STRING = "osx"; -#else // assume linux +#elif defined(__linux__) static constexpr StringLiteral OS_STRING = "linux"; +#else + return ToolData{}; #endif +#if defined(_WIN32) || defined(__APPLE__) || defined(__linux__) static const std::string XML_VERSION = "2"; static const fs::path XML_PATH = paths.scripts / "vcpkgTools.xml"; @@ -137,6 +140,7 @@ namespace vcpkg::Commands::Fetch paths.downloads / archive_name.value_or(exe_relative_path), tool_dir_path, sha512}; +#endif } static bool exists_and_has_equal_or_greater_version(const std::string& version_cmd, -- cgit v1.2.3 From b87aeb77deb7b6cdc7e78d0b006243a15993e78c Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 6 Apr 2018 15:17:16 -0700 Subject: [vcpkg.exe] Verify hash for already present files. Dont check for path twice --- toolsrc/src/vcpkg/commands.fetch.cpp | 42 ++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 18 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/commands.fetch.cpp b/toolsrc/src/vcpkg/commands.fetch.cpp index 1d2c67d67..cf19b4384 100644 --- a/toolsrc/src/vcpkg/commands.fetch.cpp +++ b/toolsrc/src/vcpkg/commands.fetch.cpp @@ -229,17 +229,31 @@ namespace vcpkg::Commands::Fetch fs.rename(to_path_partial, to_path); } + static void verify_hash(const VcpkgPaths& paths, + const std::string& url, + const fs::path& path, + const std::string& sha512) + { + const std::string actual_hash = Hash::get_file_hash(paths, path, "SHA512"); + Checks::check_exit(VCPKG_LINE_INFO, + sha512 == actual_hash, + "File does not have the expected hash:\n" + " url : [ %s ]\n" + " File path : [ %s ]\n" + " Expected hash : [ %s ]\n" + " Actual hash : [ %s ]\n", + url, + path.u8string(), + sha512, + actual_hash); + } + static void download_file(const VcpkgPaths& paths, const std::string& url, const fs::path& download_path, const std::string& sha512) { Files::Filesystem& fs = paths.get_filesystem(); - if (fs.exists(download_path)) - { - return; - } - const std::string download_path_part = download_path.u8string() + ".part"; std::error_code ec; fs.remove(download_path_part, ec); @@ -247,19 +261,7 @@ namespace vcpkg::Commands::Fetch R"(curl -L '%s' --create-dirs --output '%s')", url, download_path_part)); Checks::check_exit(VCPKG_LINE_INFO, code == 0, "Could not download %s", url); - const std::string actual_hash = Hash::get_file_hash(paths, download_path_part, "SHA512"); - Checks::check_exit(VCPKG_LINE_INFO, - sha512 == actual_hash, - "File does not have the expected hash:\n" - " url : [ %s ]\n" - " File path : [ %s ]\n" - " Expected hash : [ %s ]\n" - " Actual hash : [ %s ]\n", - url, - download_path.u8string(), - sha512, - actual_hash); - + verify_hash(paths, url, download_path_part, sha512); fs.rename(download_path_part, download_path); } @@ -302,6 +304,10 @@ namespace vcpkg::Commands::Fetch download_file(paths, tool_data.url, tool_data.download_path, tool_data.sha512); System::println("Downloading %s... done.", tool_name); } + else + { + verify_hash(paths, tool_data.url, tool_data.download_path, tool_data.sha512); + } System::println("Extracting %s...", tool_name); extract_archive(paths, tool_data.download_path, tool_data.tool_dir_path); -- cgit v1.2.3 From be2ea0373fbbb17ec792155ebaec0d2dd3d95242 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 6 Apr 2018 15:47:58 -0700 Subject: #ifdef linux-specific code --- toolsrc/src/vcpkg/commands.fetch.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/commands.fetch.cpp b/toolsrc/src/vcpkg/commands.fetch.cpp index cf19b4384..9652d0b9e 100644 --- a/toolsrc/src/vcpkg/commands.fetch.cpp +++ b/toolsrc/src/vcpkg/commands.fetch.cpp @@ -199,6 +199,7 @@ namespace vcpkg::Commands::Fetch return data_lines; } +#if !defined(_WIN32) static void extract_archive(const VcpkgPaths& paths, const fs::path& archive, const fs::path& to_path) { Files::Filesystem& fs = paths.get_filesystem(); @@ -265,6 +266,7 @@ namespace vcpkg::Commands::Fetch fs.rename(download_path_part, download_path); } +#endif static fs::path fetch_tool(const VcpkgPaths& paths, const std::string& tool_name, const ToolData& tool_data) { const auto& fs = paths.get_filesystem(); -- cgit v1.2.3 From 402bbbc1e2b26f714f88cc6f40283008dabba64f Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 6 Apr 2018 19:19:54 -0700 Subject: [Checks] Take parameter by ref --- toolsrc/include/vcpkg/base/checks.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/base/checks.h b/toolsrc/include/vcpkg/base/checks.h index fb162c897..bceee3428 100644 --- a/toolsrc/include/vcpkg/base/checks.h +++ b/toolsrc/include/vcpkg/base/checks.h @@ -27,7 +27,7 @@ namespace vcpkg::Checks // Display an error message to the user and exit the tool. [[noreturn]] void exit_with_message(const LineInfo& line_info, const char* error_message_template, - const Arg1 error_message_arg1, + const Arg1& error_message_arg1, const Args&... error_message_args) { exit_with_message(line_info, @@ -42,7 +42,7 @@ namespace vcpkg::Checks void check_exit(const LineInfo& line_info, Conditional&& expression, const char* error_message_template, - const Arg1 error_message_arg1, + const Arg1& error_message_arg1, const Args&... error_message_args) { if (!expression) -- cgit v1.2.3 From 15e4f46b45c432a41ee6a962609039bc2497ec19 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 4 Apr 2018 21:32:06 -0700 Subject: Update CHANGELOG and bump version to v0.0.108 --- toolsrc/VERSION.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/VERSION.txt b/toolsrc/VERSION.txt index daa1cd86e..2cd1bf9ac 100644 --- a/toolsrc/VERSION.txt +++ b/toolsrc/VERSION.txt @@ -1 +1 @@ -"0.0.107" \ No newline at end of file +"0.0.108" \ No newline at end of file -- cgit v1.2.3 From bab554a8b3df8bf451e846022b310204b8843640 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 6 Apr 2018 22:52:35 -0700 Subject: [vcpkg hash] Process in C++ instead of calling awk --- toolsrc/src/vcpkg/commands.hash.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/commands.hash.cpp b/toolsrc/src/vcpkg/commands.hash.cpp index 3f90eeaca..801b8d323 100644 --- a/toolsrc/src/vcpkg/commands.hash.cpp +++ b/toolsrc/src/vcpkg/commands.hash.cpp @@ -187,7 +187,16 @@ namespace vcpkg::Commands::Hash "Failed to run:\n" " %s", cmd_line); - return Strings::trim(std::string{ec_data.output}); + + std::vector split = Strings::split(ec_data.output, " "); + Checks::check_exit(VCPKG_LINE_INFO, + split.size() == 3, + "Expected output of the form [hash filename\n] (3 tokens), but got\n" + "[%s] (%s tokens)", + ec_data.output, + std::to_string(split.size())); + + return split[0]; } std::string get_file_hash(const VcpkgPaths& paths, const fs::path& path, const std::string& hash_type) @@ -196,7 +205,7 @@ namespace vcpkg::Commands::Hash Checks::check_exit( VCPKG_LINE_INFO, paths.get_filesystem().exists(path), "File %s does not exist", path.u8string()); const std::string cmd_line = Strings::format( - R"(shasum -a %s "%s" | awk '{ print $1 }')", digest_size, path.u8string()); + R"(shasum -a %s "%s")", digest_size, path.u8string()); return run_shasum_and_post_process(cmd_line); } @@ -206,7 +215,7 @@ namespace vcpkg::Commands::Hash verify_has_only_allowed_chars(s); const std::string cmd_line = Strings::format( - R"(echo -n "%s" | shasum -a %s | awk '{ print $1 }')", s, digest_size); + R"(echo -n "%s" | shasum -a %s)", s, digest_size); return run_shasum_and_post_process(cmd_line); } } -- cgit v1.2.3 From 479ed417d91122f68bf5806622a78be04b391166 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 6 Apr 2018 22:54:27 -0700 Subject: [vcpkg hash] formatting --- toolsrc/src/vcpkg/commands.hash.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/commands.hash.cpp b/toolsrc/src/vcpkg/commands.hash.cpp index 801b8d323..c23a63e1e 100644 --- a/toolsrc/src/vcpkg/commands.hash.cpp +++ b/toolsrc/src/vcpkg/commands.hash.cpp @@ -204,8 +204,7 @@ namespace vcpkg::Commands::Hash const std::string digest_size = get_digest_size(hash_type); Checks::check_exit( VCPKG_LINE_INFO, paths.get_filesystem().exists(path), "File %s does not exist", path.u8string()); - const std::string cmd_line = Strings::format( - R"(shasum -a %s "%s")", digest_size, path.u8string()); + const std::string cmd_line = Strings::format(R"(shasum -a %s "%s")", digest_size, path.u8string()); return run_shasum_and_post_process(cmd_line); } @@ -214,8 +213,7 @@ namespace vcpkg::Commands::Hash const std::string digest_size = get_digest_size(hash_type); verify_has_only_allowed_chars(s); - const std::string cmd_line = Strings::format( - R"(echo -n "%s" | shasum -a %s)", s, digest_size); + const std::string cmd_line = Strings::format(R"(echo -n "%s" | shasum -a %s)", s, digest_size); return run_shasum_and_post_process(cmd_line); } } -- cgit v1.2.3 From 7a19c72ca9e9ae8215be63e957ba11cc156b87b9 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Sat, 7 Apr 2018 02:03:59 -0700 Subject: Rename. Remove stray semicolon --- toolsrc/src/vcpkg/base/strings.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/base/strings.cpp b/toolsrc/src/vcpkg/base/strings.cpp index 5fedf3e1f..541b1f2d9 100644 --- a/toolsrc/src/vcpkg/base/strings.cpp +++ b/toolsrc/src/vcpkg/base/strings.cpp @@ -7,7 +7,7 @@ namespace vcpkg::Strings::details { // To disambiguate between two overloads - static bool IS_SPACE(const char c) { return std::isspace(c) != 0; }; + static bool is_space(const char c) { return std::isspace(c) != 0; } // Avoids C4244 warnings because of char<->int conversion that occur when using std::tolower() static char tolower_char(const char c) { return static_cast(std::tolower(c)); } @@ -143,8 +143,8 @@ namespace vcpkg::Strings std::string trim(std::string&& s) { - s.erase(std::find_if_not(s.rbegin(), s.rend(), details::IS_SPACE).base(), s.end()); - s.erase(s.begin(), std::find_if_not(s.begin(), s.end(), details::IS_SPACE)); + s.erase(std::find_if_not(s.rbegin(), s.rend(), details::is_space).base(), s.end()); + s.erase(s.begin(), std::find_if_not(s.begin(), s.end(), details::is_space)); return std::move(s); } -- cgit v1.2.3 From fcdf4637ed9c645cc3719358a292c4571806e0bd Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Sat, 7 Apr 2018 02:07:40 -0700 Subject: Default construct std::array() --- toolsrc/src/vcpkg/base/chrono.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/base/chrono.cpp b/toolsrc/src/vcpkg/base/chrono.cpp index 00f8ba3f1..eff84ee4e 100644 --- a/toolsrc/src/vcpkg/base/chrono.cpp +++ b/toolsrc/src/vcpkg/base/chrono.cpp @@ -117,9 +117,7 @@ namespace vcpkg::Chrono std::string CTime::to_string() const { - std::array date; - date.fill(0); - + std::array date{}; strftime(&date[0], date.size(), "%Y-%m-%dT%H:%M:%S.0Z", &m_tm); return &date[0]; } -- cgit v1.2.3 From 87f7f23d07ad6af428793a3acb45626d1228c802 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Sat, 7 Apr 2018 02:10:03 -0700 Subject: const/auto --- toolsrc/src/vcpkg/base/chrono.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/base/chrono.cpp b/toolsrc/src/vcpkg/base/chrono.cpp index eff84ee4e..2a76f5df0 100644 --- a/toolsrc/src/vcpkg/base/chrono.cpp +++ b/toolsrc/src/vcpkg/base/chrono.cpp @@ -15,7 +15,7 @@ namespace vcpkg::Chrono using std::chrono::nanoseconds; using std::chrono::seconds; - const double nanos_as_double = static_cast(nanos.count()); + const auto nanos_as_double = static_cast(nanos.count()); if (duration_cast(nanos) > hours()) { @@ -92,7 +92,7 @@ namespace vcpkg::Chrono Optional CTime::parse(CStringView str) { CTime ret; - auto assigned = + const auto assigned = #if defined(_WIN32) sscanf_s #else @@ -123,7 +123,7 @@ namespace vcpkg::Chrono } std::chrono::system_clock::time_point CTime::to_time_point() const { - auto t = mktime(&m_tm); + const time_t t = mktime(&m_tm); return std::chrono::system_clock::from_time_t(t); } } -- cgit v1.2.3 From a64b160c67bfe8de754f41004f5c7cdbfea0a0ee Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Sat, 7 Apr 2018 02:13:41 -0700 Subject: Use auto on left side when casting on right side --- toolsrc/src/vcpkg/base/cofffilereader.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/base/cofffilereader.cpp b/toolsrc/src/vcpkg/base/cofffilereader.cpp index 96d280108..bc418f42a 100644 --- a/toolsrc/src/vcpkg/base/cofffilereader.cpp +++ b/toolsrc/src/vcpkg/base/cofffilereader.cpp @@ -87,7 +87,7 @@ namespace vcpkg::CoffFileReader static const size_t MACHINE_TYPE_SIZE = 2; std::string machine_field_as_string = data.substr(MACHINE_TYPE_OFFSET, MACHINE_TYPE_SIZE); - const uint16_t machine = reinterpret_bytes(machine_field_as_string.c_str()); + const auto machine = reinterpret_bytes(machine_field_as_string.c_str()); return to_machine_type(machine); } @@ -158,7 +158,7 @@ namespace vcpkg::CoffFileReader for (uint32_t i = 0; i < offset_count; ++i) { const std::string value_as_string = raw_offsets.substr(OFFSET_WIDTH * i, OFFSET_WIDTH * (i + 1)); - const uint32_t value = reinterpret_bytes(value_as_string.c_str()); + const auto value = reinterpret_bytes(value_as_string.c_str()); // Ignore offsets that point to offset 0. See vcpkg github #223 #288 #292 if (value != 0) @@ -182,7 +182,7 @@ namespace vcpkg::CoffFileReader static ImportHeader read(fstream& fs) { static const size_t SIG1_OFFSET = 0; - static const uint16_t SIG1 = static_cast(MachineType::UNKNOWN); + static const auto SIG1 = static_cast(MachineType::UNKNOWN); static const size_t SIG1_SIZE = 2; static const size_t SIG2_OFFSET = 2; @@ -194,11 +194,11 @@ namespace vcpkg::CoffFileReader fs.read(&ret.data[0], HEADER_SIZE); const std::string sig1_as_string = ret.data.substr(SIG1_OFFSET, SIG1_SIZE); - const uint16_t sig1 = reinterpret_bytes(sig1_as_string.c_str()); + const auto sig1 = reinterpret_bytes(sig1_as_string.c_str()); Checks::check_exit(VCPKG_LINE_INFO, sig1 == SIG1, "Sig1 was incorrect. Expected %s but got %s", SIG1, sig1); const std::string sig2_as_string = ret.data.substr(SIG2_OFFSET, SIG2_SIZE); - const uint16_t sig2 = reinterpret_bytes(sig2_as_string.c_str()); + const auto sig2 = reinterpret_bytes(sig2_as_string.c_str()); Checks::check_exit(VCPKG_LINE_INFO, sig2 == SIG2, "Sig2 was incorrect. Expected %s but got %s", SIG2, sig2); return ret; @@ -210,7 +210,7 @@ namespace vcpkg::CoffFileReader static const size_t MACHINE_TYPE_SIZE = 2; std::string machine_field_as_string = data.substr(MACHINE_TYPE_OFFSET, MACHINE_TYPE_SIZE); - const uint16_t machine = reinterpret_bytes(machine_field_as_string.c_str()); + const auto machine = reinterpret_bytes(machine_field_as_string.c_str()); return to_machine_type(machine); } @@ -278,7 +278,7 @@ namespace vcpkg::CoffFileReader second_linker_member_header.name().substr(0, 2) == "/ ", "Could not find proper second linker member"); // The first 4 bytes contains the number of archive members - const uint32_t archive_member_count = read_value_from_stream(fs); + const auto archive_member_count = read_value_from_stream(fs); const OffsetsArray offsets = OffsetsArray::read(fs, archive_member_count); marker.advance_by(ArchiveMemberHeader::HEADER_SIZE + second_linker_member_header.member_size()); marker.seek_to_marker(fs); @@ -297,7 +297,7 @@ namespace vcpkg::CoffFileReader { marker.set_to_offset(offset + ArchiveMemberHeader::HEADER_SIZE); // Skip the header, no need to read it. marker.seek_to_marker(fs); - const uint16_t first_two_bytes = peek_value_from_stream(fs); + const auto first_two_bytes = peek_value_from_stream(fs); const bool isImportHeader = to_machine_type(first_two_bytes) == MachineType::UNKNOWN; const MachineType machine = isImportHeader ? ImportHeader::read(fs).machine_type() : CoffFileHeader::read(fs).machine_type(); -- cgit v1.2.3 From 2076dfe376d21d3f89e342903edb0a95e96a51e5 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Sat, 7 Apr 2018 02:14:20 -0700 Subject: Naming convention --- toolsrc/src/vcpkg/base/cofffilereader.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/base/cofffilereader.cpp b/toolsrc/src/vcpkg/base/cofffilereader.cpp index bc418f42a..fdab307eb 100644 --- a/toolsrc/src/vcpkg/base/cofffilereader.cpp +++ b/toolsrc/src/vcpkg/base/cofffilereader.cpp @@ -43,7 +43,7 @@ namespace vcpkg::CoffFileReader actual); } - static void read_and_verify_PE_signature(fstream& fs) + static void read_and_verify_pe_signature(fstream& fs) { static const size_t OFFSET_TO_PE_SIGNATURE_OFFSET = 0x3c; @@ -51,13 +51,13 @@ namespace vcpkg::CoffFileReader static const size_t PE_SIGNATURE_SIZE = 4; fs.seekg(OFFSET_TO_PE_SIGNATURE_OFFSET, ios_base::beg); - const int32_t offset_to_PE_signature = read_value_from_stream(fs); + const auto offset_to_pe_signature = read_value_from_stream(fs); - fs.seekg(offset_to_PE_signature); + fs.seekg(offset_to_pe_signature); char signature[PE_SIGNATURE_SIZE]; fs.read(signature, PE_SIGNATURE_SIZE); verify_equal_strings(VCPKG_LINE_INFO, PE_SIGNATURE, signature, PE_SIGNATURE_SIZE, "PE_SIGNATURE"); - fs.seekg(offset_to_PE_signature + PE_SIGNATURE_SIZE, ios_base::beg); + fs.seekg(offset_to_pe_signature + PE_SIGNATURE_SIZE, ios_base::beg); } static fpos_t align_to_size(const uint64_t unaligned, const uint64_t alignment_size) @@ -235,7 +235,7 @@ namespace vcpkg::CoffFileReader std::fstream fs(path, std::ios::in | std::ios::binary | std::ios::ate); Checks::check_exit(VCPKG_LINE_INFO, fs.is_open(), "Could not open file %s for reading", path.generic_string()); - read_and_verify_PE_signature(fs); + read_and_verify_pe_signature(fs); CoffFileHeader header = CoffFileHeader::read(fs); const MachineType machine = header.machine_type(); return {machine}; @@ -283,8 +283,8 @@ namespace vcpkg::CoffFileReader marker.advance_by(ArchiveMemberHeader::HEADER_SIZE + second_linker_member_header.member_size()); marker.seek_to_marker(fs); - const bool hasLongnameMemberHeader = peek_value_from_stream(fs) == 0x2F2F; - if (hasLongnameMemberHeader) + const bool has_longname_member_header = peek_value_from_stream(fs) == 0x2F2F; + if (has_longname_member_header) { const ArchiveMemberHeader longnames_member_header = ArchiveMemberHeader::read(fs); marker.advance_by(ArchiveMemberHeader::HEADER_SIZE + longnames_member_header.member_size()); @@ -298,9 +298,9 @@ namespace vcpkg::CoffFileReader marker.set_to_offset(offset + ArchiveMemberHeader::HEADER_SIZE); // Skip the header, no need to read it. marker.seek_to_marker(fs); const auto first_two_bytes = peek_value_from_stream(fs); - const bool isImportHeader = to_machine_type(first_two_bytes) == MachineType::UNKNOWN; + const bool is_import_header = to_machine_type(first_two_bytes) == MachineType::UNKNOWN; const MachineType machine = - isImportHeader ? ImportHeader::read(fs).machine_type() : CoffFileHeader::read(fs).machine_type(); + is_import_header ? ImportHeader::read(fs).machine_type() : CoffFileHeader::read(fs).machine_type(); machine_types.insert(machine); } -- cgit v1.2.3 From fc27c9dd5c2559fb604cc2ce73cfb8e79ef0e406 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Sat, 7 Apr 2018 02:18:07 -0700 Subject: [cofffilereader] Use StringLiteral --- toolsrc/src/vcpkg/base/cofffilereader.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/base/cofffilereader.cpp b/toolsrc/src/vcpkg/base/cofffilereader.cpp index fdab307eb..fec26a441 100644 --- a/toolsrc/src/vcpkg/base/cofffilereader.cpp +++ b/toolsrc/src/vcpkg/base/cofffilereader.cpp @@ -2,6 +2,7 @@ #include #include +#include using namespace std; @@ -47,7 +48,7 @@ namespace vcpkg::CoffFileReader { static const size_t OFFSET_TO_PE_SIGNATURE_OFFSET = 0x3c; - static const char* PE_SIGNATURE = "PE\0\0"; + static const StringLiteral PE_SIGNATURE = "PE\0\0"; static const size_t PE_SIGNATURE_SIZE = 4; fs.seekg(OFFSET_TO_PE_SIGNATURE_OFFSET, ios_base::beg); @@ -56,7 +57,7 @@ namespace vcpkg::CoffFileReader fs.seekg(offset_to_pe_signature); char signature[PE_SIGNATURE_SIZE]; fs.read(signature, PE_SIGNATURE_SIZE); - verify_equal_strings(VCPKG_LINE_INFO, PE_SIGNATURE, signature, PE_SIGNATURE_SIZE, "PE_SIGNATURE"); + verify_equal_strings(VCPKG_LINE_INFO, PE_SIGNATURE.c_str(), signature, PE_SIGNATURE_SIZE, "PE_SIGNATURE"); fs.seekg(offset_to_pe_signature + PE_SIGNATURE_SIZE, ios_base::beg); } @@ -102,7 +103,7 @@ namespace vcpkg::CoffFileReader static ArchiveMemberHeader read(fstream& fs) { static const size_t HEADER_END_OFFSET = 58; - static const char* HEADER_END = "`\n"; + static const StringLiteral HEADER_END = "`\n"; static const size_t HEADER_END_SIZE = 2; ArchiveMemberHeader ret; @@ -113,7 +114,7 @@ namespace vcpkg::CoffFileReader { const std::string header_end = ret.data.substr(HEADER_END_OFFSET, HEADER_END_SIZE); verify_equal_strings( - VCPKG_LINE_INFO, HEADER_END, header_end.c_str(), HEADER_END_SIZE, "LIB HEADER_END"); + VCPKG_LINE_INFO, HEADER_END.c_str(), header_end.c_str(), HEADER_END_SIZE, "LIB HEADER_END"); } return ret; @@ -220,14 +221,14 @@ namespace vcpkg::CoffFileReader static void read_and_verify_archive_file_signature(fstream& fs) { - static const char* FILE_START = "!\n"; + static const StringLiteral FILE_START = "!\n"; static const size_t FILE_START_SIZE = 8; fs.seekg(fs.beg); char file_start[FILE_START_SIZE]; fs.read(file_start, FILE_START_SIZE); - verify_equal_strings(VCPKG_LINE_INFO, FILE_START, file_start, FILE_START_SIZE, "LIB FILE_START"); + verify_equal_strings(VCPKG_LINE_INFO, FILE_START.c_str(), file_start, FILE_START_SIZE, "LIB FILE_START"); } DllInfo read_dll(const fs::path& path) -- cgit v1.2.3 From d1420efa9faf9b18ba49f3990d8c0cebf7889641 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Sat, 7 Apr 2018 02:18:46 -0700 Subject: fs.beg -> std::festream::beg --- toolsrc/src/vcpkg/base/cofffilereader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/base/cofffilereader.cpp b/toolsrc/src/vcpkg/base/cofffilereader.cpp index fec26a441..7538808c2 100644 --- a/toolsrc/src/vcpkg/base/cofffilereader.cpp +++ b/toolsrc/src/vcpkg/base/cofffilereader.cpp @@ -224,7 +224,7 @@ namespace vcpkg::CoffFileReader static const StringLiteral FILE_START = "!\n"; static const size_t FILE_START_SIZE = 8; - fs.seekg(fs.beg); + fs.seekg(std::fstream::beg); char file_start[FILE_START_SIZE]; fs.read(file_start, FILE_START_SIZE); -- cgit v1.2.3 From 84a0eaa0f2ead797cc78d74e3f35239430447383 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Sat, 7 Apr 2018 02:20:25 -0700 Subject: [cofffilereader.cpp] static const -> static constexpr --- toolsrc/src/vcpkg/base/cofffilereader.cpp | 54 +++++++++++++++---------------- 1 file changed, 27 insertions(+), 27 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/base/cofffilereader.cpp b/toolsrc/src/vcpkg/base/cofffilereader.cpp index 7538808c2..5b06a885c 100644 --- a/toolsrc/src/vcpkg/base/cofffilereader.cpp +++ b/toolsrc/src/vcpkg/base/cofffilereader.cpp @@ -46,10 +46,10 @@ namespace vcpkg::CoffFileReader static void read_and_verify_pe_signature(fstream& fs) { - static const size_t OFFSET_TO_PE_SIGNATURE_OFFSET = 0x3c; + static constexpr size_t OFFSET_TO_PE_SIGNATURE_OFFSET = 0x3c; - static const StringLiteral PE_SIGNATURE = "PE\0\0"; - static const size_t PE_SIGNATURE_SIZE = 4; + static constexpr StringLiteral PE_SIGNATURE = "PE\0\0"; + static constexpr size_t PE_SIGNATURE_SIZE = 4; fs.seekg(OFFSET_TO_PE_SIGNATURE_OFFSET, ios_base::beg); const auto offset_to_pe_signature = read_value_from_stream(fs); @@ -72,7 +72,7 @@ namespace vcpkg::CoffFileReader struct CoffFileHeader { - static const size_t HEADER_SIZE = 20; + static constexpr size_t HEADER_SIZE = 20; static CoffFileHeader read(fstream& fs) { @@ -84,8 +84,8 @@ namespace vcpkg::CoffFileReader MachineType machine_type() const { - static const size_t MACHINE_TYPE_OFFSET = 0; - static const size_t MACHINE_TYPE_SIZE = 2; + static constexpr size_t MACHINE_TYPE_OFFSET = 0; + static constexpr size_t MACHINE_TYPE_SIZE = 2; std::string machine_field_as_string = data.substr(MACHINE_TYPE_OFFSET, MACHINE_TYPE_SIZE); const auto machine = reinterpret_bytes(machine_field_as_string.c_str()); @@ -98,13 +98,13 @@ namespace vcpkg::CoffFileReader struct ArchiveMemberHeader { - static const size_t HEADER_SIZE = 60; + static constexpr size_t HEADER_SIZE = 60; static ArchiveMemberHeader read(fstream& fs) { - static const size_t HEADER_END_OFFSET = 58; - static const StringLiteral HEADER_END = "`\n"; - static const size_t HEADER_END_SIZE = 2; + static constexpr size_t HEADER_END_OFFSET = 58; + static constexpr StringLiteral HEADER_END = "`\n"; + static constexpr size_t HEADER_END_SIZE = 2; ArchiveMemberHeader ret; ret.data.resize(HEADER_SIZE); @@ -122,17 +122,17 @@ namespace vcpkg::CoffFileReader std::string name() const { - static const size_t HEADER_NAME_OFFSET = 0; - static const size_t HEADER_NAME_SIZE = 16; + static constexpr size_t HEADER_NAME_OFFSET = 0; + static constexpr size_t HEADER_NAME_SIZE = 16; return data.substr(HEADER_NAME_OFFSET, HEADER_NAME_SIZE); } uint64_t member_size() const { - static const size_t ALIGNMENT_SIZE = 2; + static constexpr size_t ALIGNMENT_SIZE = 2; - static const size_t HEADER_SIZE_OFFSET = 48; - static const size_t HEADER_SIZE_FIELD_SIZE = 10; + static constexpr size_t HEADER_SIZE_OFFSET = 48; + static constexpr size_t HEADER_SIZE_FIELD_SIZE = 10; const std::string as_string = data.substr(HEADER_SIZE_OFFSET, HEADER_SIZE_FIELD_SIZE); // This is in ASCII decimal representation const uint64_t value = std::strtoull(as_string.c_str(), nullptr, 10); @@ -148,7 +148,7 @@ namespace vcpkg::CoffFileReader { static OffsetsArray read(fstream& fs, const uint32_t offset_count) { - static const size_t OFFSET_WIDTH = 4; + static constexpr size_t OFFSET_WIDTH = 4; std::string raw_offsets; const size_t raw_offset_size = offset_count * OFFSET_WIDTH; @@ -178,17 +178,17 @@ namespace vcpkg::CoffFileReader struct ImportHeader { - static const size_t HEADER_SIZE = 20; + static constexpr size_t HEADER_SIZE = 20; static ImportHeader read(fstream& fs) { - static const size_t SIG1_OFFSET = 0; - static const auto SIG1 = static_cast(MachineType::UNKNOWN); - static const size_t SIG1_SIZE = 2; + static constexpr size_t SIG1_OFFSET = 0; + static constexpr auto SIG1 = static_cast(MachineType::UNKNOWN); + static constexpr size_t SIG1_SIZE = 2; - static const size_t SIG2_OFFSET = 2; - static const uint16_t SIG2 = 0xFFFF; - static const size_t SIG2_SIZE = 2; + static constexpr size_t SIG2_OFFSET = 2; + static constexpr uint16_t SIG2 = 0xFFFF; + static constexpr size_t SIG2_SIZE = 2; ImportHeader ret; ret.data.resize(HEADER_SIZE); @@ -207,8 +207,8 @@ namespace vcpkg::CoffFileReader MachineType machine_type() const { - static const size_t MACHINE_TYPE_OFFSET = 6; - static const size_t MACHINE_TYPE_SIZE = 2; + static constexpr size_t MACHINE_TYPE_OFFSET = 6; + static constexpr size_t MACHINE_TYPE_SIZE = 2; std::string machine_field_as_string = data.substr(MACHINE_TYPE_OFFSET, MACHINE_TYPE_SIZE); const auto machine = reinterpret_bytes(machine_field_as_string.c_str()); @@ -221,8 +221,8 @@ namespace vcpkg::CoffFileReader static void read_and_verify_archive_file_signature(fstream& fs) { - static const StringLiteral FILE_START = "!\n"; - static const size_t FILE_START_SIZE = 8; + static constexpr StringLiteral FILE_START = "!\n"; + static constexpr size_t FILE_START_SIZE = 8; fs.seekg(std::fstream::beg); -- cgit v1.2.3 From 4f1c5e0b9ad516b1b506154fe4bf88d96e8664c8 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Sat, 7 Apr 2018 02:32:40 -0700 Subject: Use instead of . Default construct. --- toolsrc/src/vcpkg/base/system.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/base/system.cpp b/toolsrc/src/vcpkg/base/system.cpp index 171dd2bbf..ea74f872e 100644 --- a/toolsrc/src/vcpkg/base/system.cpp +++ b/toolsrc/src/vcpkg/base/system.cpp @@ -5,7 +5,7 @@ #include #include -#include +#include #if defined(__APPLE__) #include @@ -23,7 +23,7 @@ namespace vcpkg::System { using std::chrono::system_clock; std::time_t now_time = system_clock::to_time_t(system_clock::now()); - tm parts; + tm parts{}; #if defined(_WIN32) localtime_s(&parts, &now_time); #else -- cgit v1.2.3 From 9725e59b997e1db31db9b9dfcb96725cbe0f474d Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Sat, 7 Apr 2018 02:37:02 -0700 Subject: [system.cpp] Naming convention, const, auto& --- toolsrc/src/vcpkg/base/system.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/base/system.cpp b/toolsrc/src/vcpkg/base/system.cpp index ea74f872e..3f2f47d72 100644 --- a/toolsrc/src/vcpkg/base/system.cpp +++ b/toolsrc/src/vcpkg/base/system.cpp @@ -158,7 +158,7 @@ namespace vcpkg::System #if defined(_WIN32) static const std::string SYSTEM_ROOT = get_environment_variable("SystemRoot").value_or_exit(VCPKG_LINE_INFO); static const std::string SYSTEM_32 = SYSTEM_ROOT + R"(\system32)"; - std::string NEW_PATH = Strings::format( + std::string new_path = Strings::format( R"(Path=%s;%s;%s\Wbem;%s\WindowsPowerShell\v1.0\)", SYSTEM_32, SYSTEM_ROOT, SYSTEM_32, SYSTEM_32); std::vector env_wstrings = { @@ -225,13 +225,13 @@ namespace vcpkg::System } if (extra_env.find("PATH") != extra_env.end()) - NEW_PATH += Strings::format(";%s", extra_env.find("PATH")->second); - env_cstr.append(Strings::to_utf16(NEW_PATH)); + new_path += Strings::format(";%s", extra_env.find("PATH")->second); + env_cstr.append(Strings::to_utf16(new_path)); env_cstr.push_back(L'\0'); env_cstr.append(L"VSLANG=1033"); env_cstr.push_back(L'\0'); - for (auto item : extra_env) + for (const auto& item : extra_env) { if (item.first == "PATH") continue; env_cstr.append(Strings::to_utf16(item.first)); @@ -339,7 +339,7 @@ namespace vcpkg::System const auto ec = _pclose(pipe); remove_byte_order_marks(&output); - Debug::println("_pclose() returned %d after %8d us", ec, (int)timer.microseconds()); + Debug::println("_pclose() returned %d after %8d us", ec, static_cast(timer.microseconds())); return {ec, Strings::to_utf8(output)}; #else -- cgit v1.2.3 From 30e516cd6163fb06d517669497b1aa7ad6db666f Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Sat, 7 Apr 2018 02:39:23 -0700 Subject: constructor order of init --- toolsrc/src/vcpkg/binaryparagraph.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/binaryparagraph.cpp b/toolsrc/src/vcpkg/binaryparagraph.cpp index 7a8b0d577..73ca23df1 100644 --- a/toolsrc/src/vcpkg/binaryparagraph.cpp +++ b/toolsrc/src/vcpkg/binaryparagraph.cpp @@ -79,7 +79,7 @@ namespace vcpkg } BinaryParagraph::BinaryParagraph(const SourceParagraph& spgh, const FeatureParagraph& fpgh, const Triplet& triplet) - : version(), feature(fpgh.name), description(fpgh.description), maintainer() + : version(), description(fpgh.description), maintainer(), feature(fpgh.name) { this->spec = PackageSpec::from_name_and_triplet(spgh.name, triplet).value_or_exit(VCPKG_LINE_INFO); this->depends = filter_dependencies(fpgh.depends, triplet); -- cgit v1.2.3 From 4e4afa29bfc053d852544a24c2ecaeff165521fd Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Sat, 7 Apr 2018 02:47:31 -0700 Subject: [build.cpp] Clang tidy fixes --- toolsrc/src/vcpkg/build.cpp | 73 ++++++++++++++++++++++----------------------- 1 file changed, 35 insertions(+), 38 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index b7055100b..76381f862 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -64,7 +64,8 @@ namespace vcpkg::Build::Command const Build::BuildPackageOptions build_package_options{Build::UseHeadVersion::NO, Build::AllowDownloads::YES, Build::CleanBuildtrees::NO, - Build::CleanPackages::NO}; + Build::CleanPackages::NO, + Build::DownloadTool::BUILT_IN}; std::set features_as_set(full_spec.features.begin(), full_spec.features.end()); features_as_set.emplace("core"); @@ -210,7 +211,7 @@ namespace vcpkg::Build for (auto&& host : host_architectures) { - auto it = Util::find_if(toolset.supported_architectures, [&](const ToolsetArchOption& opt) { + const auto it = Util::find_if(toolset.supported_architectures, [&](const ToolsetArchOption& opt) { return host == opt.host_arch && target_arch == opt.target_arch; }); if (it != toolset.supported_architectures.end()) return it->name; @@ -279,7 +280,7 @@ namespace vcpkg::Build { const Triplet& triplet = config.triplet; - auto dep_strings = + const std::vector dep_strings = Util::fmap_flatten(config.feature_list, [&](std::string const& feature) -> std::vector { if (feature == "core") { @@ -302,7 +303,7 @@ namespace vcpkg::Build if (fspec.feature().empty()) { // reference to default features - auto it = status_db.find_installed(fspec.spec()); + const auto it = status_db.find_installed(fspec.spec()); if (it == status_db.end()) { // not currently installed, so just leave the default reference so it will fail later @@ -310,9 +311,9 @@ namespace vcpkg::Build } else { - ret.push_back(FeatureSpec{fspec.spec(), "core"}); + ret.emplace_back(fspec.spec(), "core"); for (auto&& default_feature : it->get()->package.default_features) - ret.push_back(FeatureSpec{fspec.spec(), default_feature}); + ret.emplace_back(fspec.spec(), default_feature); } } else @@ -463,7 +464,7 @@ namespace vcpkg::Build abi_tag_entries.emplace_back(AbiEntry{"triplet", pre_build_info.triplet_abi_tag}); - std::string features = Strings::join(";", config.feature_list); + const std::string features = Strings::join(";", config.feature_list); abi_tag_entries.emplace_back(AbiEntry{"features", features}); if (config.build_package_options.use_head_version == UseHeadVersion::YES) @@ -471,7 +472,7 @@ namespace vcpkg::Build Util::sort(abi_tag_entries); - std::string full_abi_info = + const std::string full_abi_info = Strings::join("", abi_tag_entries, [](const AbiEntry& p) { return p.key + " " + p.value + "\n"; }); if (GlobalState::debugging) @@ -491,19 +492,17 @@ namespace vcpkg::Build { std::error_code ec; fs.create_directories(paths.buildtrees / name, ec); - auto abi_file_path = paths.buildtrees / name / (triplet.canonical_name() + ".vcpkg_abi_info.txt"); + const auto abi_file_path = paths.buildtrees / name / (triplet.canonical_name() + ".vcpkg_abi_info.txt"); fs.write_contents(abi_file_path, full_abi_info); return AbiTagAndFile{Commands::Hash::get_file_hash(paths, abi_file_path, "SHA1"), abi_file_path}; } - else - { - System::println( - "Warning: binary caching disabled because abi keys are missing values:\n%s", - Strings::join("", abi_tag_entries_missing, [](const AbiEntry& e) { return " " + e.key + "\n"; })); - return nullopt; - } + System::println( + "Warning: binary caching disabled because abi keys are missing values:\n%s", + Strings::join("", abi_tag_entries_missing, [](const AbiEntry& e) { return " " + e.key + "\n"; })); + + return nullopt; } static void decompress_archive(const VcpkgPaths& paths, const PackageSpec& spec, const fs::path& archive_path) @@ -518,10 +517,10 @@ namespace vcpkg::Build Checks::check_exit(VCPKG_LINE_INFO, files.empty(), "unable to clear path: %s", pkg_path.u8string()); #if defined(_WIN32) - auto&& _7za = paths.get_tool_exe(Tools::SEVEN_ZIP); + auto&& seven_zip_exe = paths.get_tool_exe(Tools::SEVEN_ZIP); System::cmd_execute_clean(Strings::format( - R"("%s" x "%s" -o"%s" -y >nul)", _7za.u8string(), archive_path.u8string(), pkg_path.u8string())); + R"("%s" x "%s" -o"%s" -y >nul)", seven_zip_exe.u8string(), archive_path.u8string(), pkg_path.u8string())); #else System::cmd_execute_clean(Strings::format( R"(unzip -qq "%s" "-d%s")", archive_path.u8string(), pkg_path.u8string())); @@ -538,11 +537,11 @@ namespace vcpkg::Build Checks::check_exit( VCPKG_LINE_INFO, !fs.exists(tmp_archive_path), "Could not remove file: %s", tmp_archive_path.u8string()); #if defined(_WIN32) - auto&& _7za = paths.get_tool_exe(Tools::SEVEN_ZIP); + auto&& seven_zip_exe = paths.get_tool_exe(Tools::SEVEN_ZIP); System::cmd_execute_clean(Strings::format( R"("%s" a "%s" "%s\*" >nul)", - _7za.u8string(), + seven_zip_exe.u8string(), tmp_archive_path.u8string(), paths.package_dir(spec).u8string())); #else @@ -584,7 +583,7 @@ namespace vcpkg::Build for (auto&& pspec : dep_pspecs) { if (pspec == spec) continue; - auto status_it = status_db.find_installed(pspec); + const auto status_it = status_db.find_installed(pspec); Checks::check_exit(VCPKG_LINE_INFO, status_it != status_db.end()); dependency_abis.emplace_back( AbiEntry{status_it->get()->package.spec.name(), status_it->get()->package.abi}); @@ -594,17 +593,15 @@ namespace vcpkg::Build auto maybe_abi_tag_and_file = compute_abi_tag(paths, config, pre_build_info, dependency_abis); - std::unique_ptr bcf; - - auto abi_tag_and_file = maybe_abi_tag_and_file.get(); + const auto abi_tag_and_file = maybe_abi_tag_and_file.get(); if (GlobalState::g_binary_caching && abi_tag_and_file) { - auto archives_root_dir = paths.root / "archives"; - auto archive_name = abi_tag_and_file->tag + ".zip"; - auto archive_subpath = fs::u8path(abi_tag_and_file->tag.substr(0, 2)) / archive_name; - auto archive_path = archives_root_dir / archive_subpath; - auto archive_tombstone_path = archives_root_dir / "fail" / archive_subpath; + const fs::path archives_root_dir = paths.root / "archives"; + const std::string archive_name = abi_tag_and_file->tag + ".zip"; + const fs::path archive_subpath = fs::u8path(abi_tag_and_file->tag.substr(0, 2)) / archive_name; + const fs::path archive_path = archives_root_dir / archive_subpath; + const fs::path archive_tombstone_path = archives_root_dir / "fail" / archive_subpath; if (fs.exists(archive_path)) { @@ -613,10 +610,12 @@ namespace vcpkg::Build decompress_archive(paths, spec, archive_path); auto maybe_bcf = Paragraphs::try_load_cached_package(paths, spec); - bcf = std::make_unique(std::move(maybe_bcf).value_or_exit(VCPKG_LINE_INFO)); + std::unique_ptr bcf = + std::make_unique(std::move(maybe_bcf).value_or_exit(VCPKG_LINE_INFO)); return {BuildResult::SUCCEEDED, std::move(bcf)}; } - else if (fs.exists(archive_tombstone_path)) + + if (fs.exists(archive_tombstone_path)) { System::println("Found failure tombstone: %s", archive_tombstone_path.u8string()); return BuildResult::BUILD_FAILED; @@ -635,7 +634,7 @@ namespace vcpkg::Build if (result.code == BuildResult::SUCCEEDED) { - auto tmp_archive_path = paths.buildtrees / spec.name() / (spec.triplet().to_string() + ".zip"); + const auto tmp_archive_path = paths.buildtrees / spec.name() / (spec.triplet().to_string() + ".zip"); compress_archive(paths, spec, tmp_archive_path); @@ -656,11 +655,9 @@ namespace vcpkg::Build return result; } - else - { - return do_build_package_and_clean_buildtrees( - paths, pre_build_info, spec, maybe_abi_tag_and_file.value_or(AbiTagAndFile{}).tag, config, status_db); - } + + return do_build_package_and_clean_buildtrees( + paths, pre_build_info, spec, maybe_abi_tag_and_file.value_or(AbiTagAndFile{}).tag, config, status_db); } const std::string& to_string(const BuildResult build_result) @@ -774,7 +771,7 @@ namespace vcpkg::Build const fs::path ports_cmake_script_path = paths.scripts / "get_triplet_environment.cmake"; const fs::path triplet_file_path = paths.triplets / (triplet.canonical_name() + ".cmake"); - auto triplet_abi_tag = [&]() { + const std::string triplet_abi_tag = [&]() { static std::map s_hash_cache; if (GlobalState::g_binary_caching) -- cgit v1.2.3 From 627e91a08fbd2cc407b87bbf961067761dec78c0 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Sat, 7 Apr 2018 02:51:36 -0700 Subject: Util::unused() for commands that don't have arguments --- toolsrc/src/vcpkg/commands.cache.cpp | 2 +- toolsrc/src/vcpkg/commands.create.cpp | 2 +- toolsrc/src/vcpkg/commands.dependinfo.cpp | 3 +-- toolsrc/src/vcpkg/commands.import.cpp | 2 +- toolsrc/src/vcpkg/commands.integrate.cpp | 2 +- toolsrc/src/vcpkg/commands.owns.cpp | 2 +- toolsrc/src/vcpkg/commands.portsdiff.cpp | 2 +- toolsrc/src/vcpkg/commands.version.cpp | 2 +- 8 files changed, 8 insertions(+), 9 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/commands.cache.cpp b/toolsrc/src/vcpkg/commands.cache.cpp index 85bf5fb4d..a9d8ba03c 100644 --- a/toolsrc/src/vcpkg/commands.cache.cpp +++ b/toolsrc/src/vcpkg/commands.cache.cpp @@ -38,7 +38,7 @@ namespace vcpkg::Commands::Cache void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { - args.parse_arguments(COMMAND_STRUCTURE); + Util::unused(args.parse_arguments(COMMAND_STRUCTURE)); const std::vector binary_paragraphs = read_all_binary_paragraphs(paths); if (binary_paragraphs.empty()) diff --git a/toolsrc/src/vcpkg/commands.create.cpp b/toolsrc/src/vcpkg/commands.create.cpp index 60769c9ef..dfb3ab784 100644 --- a/toolsrc/src/vcpkg/commands.create.cpp +++ b/toolsrc/src/vcpkg/commands.create.cpp @@ -18,7 +18,7 @@ namespace vcpkg::Commands::Create void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { - args.parse_arguments(COMMAND_STRUCTURE); + Util::unused(args.parse_arguments(COMMAND_STRUCTURE)); const std::string port_name = args.command_arguments.at(0); const std::string url = args.command_arguments.at(1); diff --git a/toolsrc/src/vcpkg/commands.dependinfo.cpp b/toolsrc/src/vcpkg/commands.dependinfo.cpp index bb300d96e..1ca658216 100644 --- a/toolsrc/src/vcpkg/commands.dependinfo.cpp +++ b/toolsrc/src/vcpkg/commands.dependinfo.cpp @@ -19,7 +19,7 @@ namespace vcpkg::Commands::DependInfo void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { - args.parse_arguments(COMMAND_STRUCTURE); + Util::unused(args.parse_arguments(COMMAND_STRUCTURE)); std::vector> source_control_files = Paragraphs::load_all_ports(paths.get_filesystem(), paths.ports); @@ -30,7 +30,6 @@ namespace vcpkg::Commands::DependInfo Util::erase_remove_if(source_control_files, [&](const std::unique_ptr& source_control_file) { - const SourceParagraph& source_paragraph = *source_control_file->core_paragraph; if (Strings::case_insensitive_ascii_contains(source_paragraph.name, filter)) diff --git a/toolsrc/src/vcpkg/commands.import.cpp b/toolsrc/src/vcpkg/commands.import.cpp index 24394207b..4b595697a 100644 --- a/toolsrc/src/vcpkg/commands.import.cpp +++ b/toolsrc/src/vcpkg/commands.import.cpp @@ -103,7 +103,7 @@ namespace vcpkg::Commands::Import void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { - args.parse_arguments(COMMAND_STRUCTURE); + Util::unused(args.parse_arguments(COMMAND_STRUCTURE)); const fs::path control_file_path(args.command_arguments[0]); const fs::path include_directory(args.command_arguments[1]); diff --git a/toolsrc/src/vcpkg/commands.integrate.cpp b/toolsrc/src/vcpkg/commands.integrate.cpp index d6ae27181..044a88d80 100644 --- a/toolsrc/src/vcpkg/commands.integrate.cpp +++ b/toolsrc/src/vcpkg/commands.integrate.cpp @@ -352,7 +352,7 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { - args.parse_arguments(COMMAND_STRUCTURE); + Util::unused(args.parse_arguments(COMMAND_STRUCTURE)); #if defined(_WIN32) if (args.command_arguments[0] == Subcommand::INSTALL) diff --git a/toolsrc/src/vcpkg/commands.owns.cpp b/toolsrc/src/vcpkg/commands.owns.cpp index 52249187b..ee9584651 100644 --- a/toolsrc/src/vcpkg/commands.owns.cpp +++ b/toolsrc/src/vcpkg/commands.owns.cpp @@ -34,7 +34,7 @@ namespace vcpkg::Commands::Owns void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { - args.parse_arguments(COMMAND_STRUCTURE); + Util::unused(args.parse_arguments(COMMAND_STRUCTURE)); const StatusParagraphs status_db = database_load_check(paths); search_file(paths, args.command_arguments[0], status_db); diff --git a/toolsrc/src/vcpkg/commands.portsdiff.cpp b/toolsrc/src/vcpkg/commands.portsdiff.cpp index c6b02582f..0a72b3435 100644 --- a/toolsrc/src/vcpkg/commands.portsdiff.cpp +++ b/toolsrc/src/vcpkg/commands.portsdiff.cpp @@ -128,7 +128,7 @@ namespace vcpkg::Commands::PortsDiff void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { - args.parse_arguments(COMMAND_STRUCTURE); + Util::unused(args.parse_arguments(COMMAND_STRUCTURE)); const fs::path& git_exe = paths.get_tool_exe(Tools::GIT); diff --git a/toolsrc/src/vcpkg/commands.version.cpp b/toolsrc/src/vcpkg/commands.version.cpp index ffc5d2c8f..2ad91b57d 100644 --- a/toolsrc/src/vcpkg/commands.version.cpp +++ b/toolsrc/src/vcpkg/commands.version.cpp @@ -83,7 +83,7 @@ namespace vcpkg::Commands::Version void perform_and_exit(const VcpkgCmdArguments& args) { - args.parse_arguments(COMMAND_STRUCTURE); + Util::unused(args.parse_arguments(COMMAND_STRUCTURE)); System::println("Vcpkg package management program version %s\n" "\n" -- cgit v1.2.3 From 8d343ce6dfc850abdfbfd098765df072271ae6ad Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Sat, 7 Apr 2018 02:58:30 -0700 Subject: [commands] Clang-tidy fixes --- toolsrc/src/vcpkg/commands.contact.cpp | 14 +++++++++----- toolsrc/src/vcpkg/commands.edit.cpp | 2 +- toolsrc/src/vcpkg/commands.integrate.cpp | 2 +- toolsrc/src/vcpkg/commands.list.cpp | 2 +- toolsrc/src/vcpkg/commands.upgrade.cpp | 3 ++- 5 files changed, 14 insertions(+), 9 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/commands.contact.cpp b/toolsrc/src/vcpkg/commands.contact.cpp index ffed07557..9f86a67dc 100644 --- a/toolsrc/src/vcpkg/commands.contact.cpp +++ b/toolsrc/src/vcpkg/commands.contact.cpp @@ -14,24 +14,28 @@ namespace vcpkg::Commands::Contact return S_EMAIL; } - static const CommandSwitch switches[] = {{"--survey", "Launch default browser to the current vcpkg survey"}}; + static constexpr StringLiteral OPTION_SURVEY = "--survey"; + + static constexpr std::array SWITCHES = {{ + {OPTION_SURVEY, "Launch default browser to the current vcpkg survey"}, + }}; const CommandStructure COMMAND_STRUCTURE = { Help::create_example_string("contact"), 0, 0, - {switches, {}}, + {SWITCHES, {}}, nullptr, }; void perform_and_exit(const VcpkgCmdArguments& args) { - auto parsed_args = args.parse_arguments(COMMAND_STRUCTURE); + const ParsedArguments parsed_args = args.parse_arguments(COMMAND_STRUCTURE); - if (Util::Sets::contains(parsed_args.switches, switches[0].name)) + if (Util::Sets::contains(parsed_args.switches, SWITCHES[0].name)) { auto maybe_now = Chrono::CTime::get_current_date_time(); - if (auto p_now = maybe_now.get()) + if (const auto p_now = maybe_now.get()) { auto& fs = Files::get_real_filesystem(); auto config = UserConfig::try_read_data(fs); diff --git a/toolsrc/src/vcpkg/commands.edit.cpp b/toolsrc/src/vcpkg/commands.edit.cpp index 6c696018e..f0ddd43c5 100644 --- a/toolsrc/src/vcpkg/commands.edit.cpp +++ b/toolsrc/src/vcpkg/commands.edit.cpp @@ -93,7 +93,7 @@ namespace vcpkg::Commands::Edit const std::vector from_registry = find_from_registry(); candidate_paths.insert(candidate_paths.end(), from_registry.cbegin(), from_registry.cend()); - auto it = Util::find_if(candidate_paths, [&](const fs::path& p) { return fs.exists(p); }); + const auto it = Util::find_if(candidate_paths, [&](const fs::path& p) { return fs.exists(p); }); if (it == candidate_paths.cend()) { System::println( diff --git a/toolsrc/src/vcpkg/commands.integrate.cpp b/toolsrc/src/vcpkg/commands.integrate.cpp index 044a88d80..e70d9b2e3 100644 --- a/toolsrc/src/vcpkg/commands.integrate.cpp +++ b/toolsrc/src/vcpkg/commands.integrate.cpp @@ -108,7 +108,7 @@ namespace vcpkg::Commands::Integrate #if defined(_WIN32) static ElevationPromptChoice elevated_cmd_execute(const std::string& param) { - SHELLEXECUTEINFOW sh_ex_info = {0}; + SHELLEXECUTEINFOW sh_ex_info{}; sh_ex_info.cbSize = sizeof(sh_ex_info); sh_ex_info.fMask = SEE_MASK_NOCLOSEPROCESS; sh_ex_info.hwnd = nullptr; diff --git a/toolsrc/src/vcpkg/commands.list.cpp b/toolsrc/src/vcpkg/commands.list.cpp index a5efd5442..4c4518d25 100644 --- a/toolsrc/src/vcpkg/commands.list.cpp +++ b/toolsrc/src/vcpkg/commands.list.cpp @@ -10,7 +10,7 @@ namespace vcpkg::Commands::List static constexpr StringLiteral OPTION_FULLDESC = "--x-full-desc"; // TODO: This should find a better home, eventually - static void do_print(const StatusParagraph& pgh, bool full_desc) + static void do_print(const StatusParagraph& pgh, const bool full_desc) { if (full_desc) { diff --git a/toolsrc/src/vcpkg/commands.upgrade.cpp b/toolsrc/src/vcpkg/commands.upgrade.cpp index c5b48f2a2..a902ddeaf 100644 --- a/toolsrc/src/vcpkg/commands.upgrade.cpp +++ b/toolsrc/src/vcpkg/commands.upgrade.cpp @@ -144,7 +144,8 @@ namespace vcpkg::Commands::Upgrade const Build::BuildPackageOptions install_plan_options = {Build::UseHeadVersion::NO, Build::AllowDownloads::YES, Build::CleanBuildtrees::NO, - Build::CleanPackages::NO}; + Build::CleanPackages::NO, + Build::DownloadTool::BUILT_IN}; // Set build settings for all install actions for (auto&& action : plan) -- cgit v1.2.3 From f07026539835aad4b87e2a88b3e38e144edaa9dd Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Sat, 7 Apr 2018 03:12:15 -0700 Subject: [export.cpp] Define all valuse in BuildOptions --- toolsrc/src/vcpkg/export.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/export.cpp b/toolsrc/src/vcpkg/export.cpp index 32151c791..eda909635 100644 --- a/toolsrc/src/vcpkg/export.cpp +++ b/toolsrc/src/vcpkg/export.cpp @@ -70,8 +70,11 @@ namespace vcpkg::Export { static constexpr std::array ORDER = {ExportPlanType::ALREADY_BUILT, ExportPlanType::NOT_BUILT}; - static constexpr Build::BuildPackageOptions build_options = {Build::UseHeadVersion::NO, - Build::AllowDownloads::YES}; + static constexpr Build::BuildPackageOptions BUILD_OPTIONS = {Build::UseHeadVersion::NO, + Build::AllowDownloads::YES, + Build::CleanBuildtrees::NO, + Build::CleanPackages::NO, + Build::DownloadTool::BUILT_IN}; for (const ExportPlanType plan_type : ORDER) { @@ -84,7 +87,7 @@ namespace vcpkg::Export std::vector cont = it->second; std::sort(cont.begin(), cont.end(), &ExportPlanAction::compare_by_name); const std::string as_string = Strings::join("\n", cont, [](const ExportPlanAction* p) { - return Dependencies::to_output_string(p->request_type, p->spec.to_string(), build_options); + return Dependencies::to_output_string(p->request_type, p->spec.to_string(), BUILD_OPTIONS); }); switch (plan_type) -- cgit v1.2.3 From 269e78bb610369cbdc193be92c4fdd5bba1f7831 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Sat, 7 Apr 2018 03:12:33 -0700 Subject: Remove unused #include directives --- toolsrc/src/vcpkg/export.cpp | 2 -- toolsrc/src/vcpkg/parse.cpp | 1 - toolsrc/src/vcpkg/triplet.cpp | 3 +-- 3 files changed, 1 insertion(+), 5 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/export.cpp b/toolsrc/src/vcpkg/export.cpp index eda909635..85a4dfad1 100644 --- a/toolsrc/src/vcpkg/export.cpp +++ b/toolsrc/src/vcpkg/export.cpp @@ -13,8 +13,6 @@ #include #include -#include - namespace vcpkg::Export { using Dependencies::ExportPlanAction; diff --git a/toolsrc/src/vcpkg/parse.cpp b/toolsrc/src/vcpkg/parse.cpp index c2670f561..d50296cf8 100644 --- a/toolsrc/src/vcpkg/parse.cpp +++ b/toolsrc/src/vcpkg/parse.cpp @@ -2,7 +2,6 @@ #include -#include #include namespace vcpkg::Parse diff --git a/toolsrc/src/vcpkg/triplet.cpp b/toolsrc/src/vcpkg/triplet.cpp index ef0fab183..c4ad3f690 100644 --- a/toolsrc/src/vcpkg/triplet.cpp +++ b/toolsrc/src/vcpkg/triplet.cpp @@ -1,6 +1,5 @@ #include "pch.h" -#include #include #include @@ -38,7 +37,7 @@ namespace vcpkg const Triplet Triplet::ARM_UWP = from_canonical_name("arm-uwp"); const Triplet Triplet::ARM64_UWP = from_canonical_name("arm64-uwp"); const Triplet Triplet::ARM_WINDOWS = from_canonical_name("arm-windows"); - const Triplet Triplet::ARM64_WINDOWS = from_canonical_name("arm64-windows"); + const Triplet Triplet::ARM64_WINDOWS = from_canonical_name("arm64-windows"); bool Triplet::operator==(const Triplet& other) const { return this->m_instance == other.m_instance; } -- cgit v1.2.3 From 77338ee0df064fe89f9eb991b61bc9bb467f755c Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Sat, 7 Apr 2018 03:24:45 -0700 Subject: Remove more unused #include directives --- toolsrc/include/vcpkg/base/chrono.h | 1 - toolsrc/include/vcpkg/export.ifw.h | 2 -- toolsrc/include/vcpkg/paragraphs.h | 3 --- toolsrc/include/vcpkg/vcpkgcmdarguments.h | 1 - toolsrc/include/vcpkg/vcpkgpaths.h | 2 -- toolsrc/src/vcpkg/commands.portsdiff.cpp | 1 + 6 files changed, 1 insertion(+), 9 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/base/chrono.h b/toolsrc/include/vcpkg/base/chrono.h index 4291115f7..7b393e377 100644 --- a/toolsrc/include/vcpkg/base/chrono.h +++ b/toolsrc/include/vcpkg/base/chrono.h @@ -2,7 +2,6 @@ #include #include -#include #include namespace vcpkg::Chrono diff --git a/toolsrc/include/vcpkg/export.ifw.h b/toolsrc/include/vcpkg/export.ifw.h index d28a4436d..b1573924e 100644 --- a/toolsrc/include/vcpkg/export.ifw.h +++ b/toolsrc/include/vcpkg/export.ifw.h @@ -3,8 +3,6 @@ #include #include -#include - #include #include diff --git a/toolsrc/include/vcpkg/paragraphs.h b/toolsrc/include/vcpkg/paragraphs.h index fa0265b75..56f09387a 100644 --- a/toolsrc/include/vcpkg/paragraphs.h +++ b/toolsrc/include/vcpkg/paragraphs.h @@ -3,12 +3,9 @@ #include #include #include -#include #include -#include - namespace vcpkg::Paragraphs { using RawParagraph = Parse::RawParagraph; diff --git a/toolsrc/include/vcpkg/vcpkgcmdarguments.h b/toolsrc/include/vcpkg/vcpkgcmdarguments.h index f449887f1..de65eec28 100644 --- a/toolsrc/include/vcpkg/vcpkgcmdarguments.h +++ b/toolsrc/include/vcpkg/vcpkgcmdarguments.h @@ -1,6 +1,5 @@ #pragma once -#include #include #include #include diff --git a/toolsrc/include/vcpkg/vcpkgpaths.h b/toolsrc/include/vcpkg/vcpkgpaths.h index fc6b319d8..9c8f2911a 100644 --- a/toolsrc/include/vcpkg/vcpkgpaths.h +++ b/toolsrc/include/vcpkg/vcpkgpaths.h @@ -8,8 +8,6 @@ #include #include -#include - namespace vcpkg { namespace Tools diff --git a/toolsrc/src/vcpkg/commands.portsdiff.cpp b/toolsrc/src/vcpkg/commands.portsdiff.cpp index 0a72b3435..2d2b4bd5f 100644 --- a/toolsrc/src/vcpkg/commands.portsdiff.cpp +++ b/toolsrc/src/vcpkg/commands.portsdiff.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include -- cgit v1.2.3 From 8da8f3e5b3cca98e9151d421a91f5c1590a47086 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Tue, 10 Apr 2018 04:48:02 -0700 Subject: [vcpkg] Rework dependencies.cpp to improve type safety and error detection --- toolsrc/include/vcpkg/base/optional.h | 6 + toolsrc/include/vcpkg/dependencies.h | 3 +- toolsrc/include/vcpkg/statusparagraph.h | 1 + toolsrc/include/vcpkg/vcpkglib.h | 2 +- toolsrc/src/tests.plan.cpp | 146 +++++++---- toolsrc/src/vcpkg/commands.list.cpp | 9 +- toolsrc/src/vcpkg/dependencies.cpp | 435 ++++++++++++++++---------------- toolsrc/src/vcpkg/remove.cpp | 4 +- toolsrc/src/vcpkg/statusparagraph.cpp | 8 +- toolsrc/src/vcpkg/update.cpp | 11 +- toolsrc/src/vcpkg/vcpkglib.cpp | 24 +- 11 files changed, 364 insertions(+), 285 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/base/optional.h b/toolsrc/include/vcpkg/base/optional.h index af2d297a6..b629de9b3 100644 --- a/toolsrc/include/vcpkg/base/optional.h +++ b/toolsrc/include/vcpkg/base/optional.h @@ -64,6 +64,12 @@ namespace vcpkg return std::move(this->m_base.value()); } + T& value_or_exit(const LineInfo& line_info) & + { + this->exit_if_null(line_info); + return this->m_base.value(); + } + const T& value_or_exit(const LineInfo& line_info) const& { this->exit_if_null(line_info); diff --git a/toolsrc/include/vcpkg/dependencies.h b/toolsrc/include/vcpkg/dependencies.h index fea0d88a9..704e76b07 100644 --- a/toolsrc/include/vcpkg/dependencies.h +++ b/toolsrc/include/vcpkg/dependencies.h @@ -37,8 +37,7 @@ namespace vcpkg::Dependencies InstallPlanAction(); - InstallPlanAction(const PackageSpec& spec, - InstalledPackageView&& spghs, + InstallPlanAction(InstalledPackageView&& spghs, const std::set& features, const RequestType& request_type); diff --git a/toolsrc/include/vcpkg/statusparagraph.h b/toolsrc/include/vcpkg/statusparagraph.h index 0802de530..16144e467 100644 --- a/toolsrc/include/vcpkg/statusparagraph.h +++ b/toolsrc/include/vcpkg/statusparagraph.h @@ -54,6 +54,7 @@ namespace vcpkg { } + const PackageSpec& spec() const { return core->package.spec; } std::vector dependencies() const; const StatusParagraph* core; diff --git a/toolsrc/include/vcpkg/vcpkglib.h b/toolsrc/include/vcpkg/vcpkglib.h index 3c8e676bf..5674d30db 100644 --- a/toolsrc/include/vcpkg/vcpkglib.h +++ b/toolsrc/include/vcpkg/vcpkglib.h @@ -16,7 +16,7 @@ namespace vcpkg SortedVector files; }; - std::vector get_installed_ports(const StatusParagraphs& status_db); + std::vector get_installed_ports(const StatusParagraphs& status_db); std::vector get_installed_files(const VcpkgPaths& paths, const StatusParagraphs& status_db); diff --git a/toolsrc/src/tests.plan.cpp b/toolsrc/src/tests.plan.cpp index a99f1abb9..b054702a1 100644 --- a/toolsrc/src/tests.plan.cpp +++ b/toolsrc/src/tests.plan.cpp @@ -81,7 +81,7 @@ namespace UnitTest1 { std::unordered_map map; Triplet triplet; - PackageSpecMap(const Triplet& t) { triplet = t; } + PackageSpecMap(const Triplet& t = Triplet::X86_WINDOWS) { triplet = t; } PackageSpec emplace(const char* name, const char* depends = "", @@ -105,7 +105,7 @@ namespace UnitTest1 { std::vector> status_paragraphs; - PackageSpecMap spec_map(Triplet::X86_WINDOWS); + PackageSpecMap spec_map; auto spec_a = spec_map.emplace("a", "b"); auto spec_b = spec_map.emplace("b", "c"); auto spec_c = spec_map.emplace("c"); @@ -124,7 +124,7 @@ namespace UnitTest1 { std::vector> status_paragraphs; - PackageSpecMap spec_map(Triplet::X86_WINDOWS); + PackageSpecMap spec_map; auto spec_a = spec_map.emplace("a", "d"); auto spec_b = spec_map.emplace("b", "d, e"); auto spec_c = spec_map.emplace("c", "e, h"); @@ -167,7 +167,7 @@ namespace UnitTest1 std::vector> status_paragraphs; status_paragraphs.push_back(make_status_pgh("a")); - PackageSpecMap spec_map(Triplet::X86_WINDOWS); + PackageSpecMap spec_map; auto spec_a = FullPackageSpec{spec_map.emplace("a")}; auto install_plan = @@ -187,7 +187,7 @@ namespace UnitTest1 { std::vector> status_paragraphs; - PackageSpecMap spec_map(Triplet::X86_WINDOWS); + PackageSpecMap spec_map; auto spec_a = FullPackageSpec{spec_map.emplace("a", "b")}; auto spec_b = FullPackageSpec{spec_map.emplace("b")}; @@ -216,7 +216,7 @@ namespace UnitTest1 status_paragraphs.push_back(make_status_pgh("j", "k")); status_paragraphs.push_back(make_status_pgh("k")); - PackageSpecMap spec_map(Triplet::X86_WINDOWS); + PackageSpecMap spec_map; auto spec_a = spec_map.emplace("a", "b, c, d, e, f, g, h, j, k"); auto spec_b = spec_map.emplace("b", "c, d, e, f, g, h, j, k"); @@ -251,7 +251,7 @@ namespace UnitTest1 status_paragraphs.push_back(make_status_pgh("b")); status_paragraphs.push_back(make_status_feature_pgh("b", "b1")); - PackageSpecMap spec_map(Triplet::X86_WINDOWS); + PackageSpecMap spec_map; auto spec_a = FullPackageSpec{spec_map.emplace("a", "b, b[b1]", {{"a1", "b[b2]"}}), {"a1"}}; auto spec_b = FullPackageSpec{spec_map.emplace("b", "", {{"b1", ""}, {"b2", ""}, {"b3", ""}})}; @@ -271,7 +271,7 @@ namespace UnitTest1 { std::vector> status_paragraphs; - PackageSpecMap spec_map(Triplet::X86_WINDOWS); + PackageSpecMap spec_map; auto spec_a = FullPackageSpec{spec_map.emplace("a", "b[b1]", {{"a1", "b[b2]"}}), {"a1"}}; auto spec_b = FullPackageSpec{spec_map.emplace("b", "", {{"b1", ""}, {"b2", ""}, {"b3", ""}})}; @@ -291,7 +291,7 @@ namespace UnitTest1 std::vector> status_paragraphs; status_paragraphs.push_back(make_status_pgh("a")); - PackageSpecMap spec_map(Triplet::X86_WINDOWS); + PackageSpecMap spec_map; auto spec_a = FullPackageSpec{spec_map.emplace("a", "b", {{"a1", ""}}), {"core"}}; auto spec_b = FullPackageSpec{spec_map.emplace("b")}; @@ -315,7 +315,7 @@ namespace UnitTest1 status_paragraphs.push_back(make_status_pgh("a")); status_paragraphs.push_back(make_status_feature_pgh("a", "a1", "")); - PackageSpecMap spec_map(Triplet::X86_WINDOWS); + PackageSpecMap spec_map; auto spec_a = FullPackageSpec{spec_map.emplace("a", "b", {{"a1", ""}})}; auto spec_b = FullPackageSpec{spec_map.emplace("b")}; @@ -334,7 +334,7 @@ namespace UnitTest1 { std::vector> status_paragraphs; - PackageSpecMap spec_map(Triplet::X86_WINDOWS); + PackageSpecMap spec_map; auto spec_a = FullPackageSpec{spec_map.emplace("a", "", {{"a1", "b[b1]"}, {"a2", "b[b2]"}, {"a3", "a[a2]"}}), {"a3"}}; @@ -355,7 +355,7 @@ namespace UnitTest1 std::vector> status_paragraphs; status_paragraphs.push_back(make_status_pgh("b")); - PackageSpecMap spec_map(Triplet::X86_WINDOWS); + PackageSpecMap spec_map; auto spec_a = FullPackageSpec{spec_map.emplace("a", "b[core]"), {"core"}}; auto spec_b = FullPackageSpec{spec_map.emplace("b", "", {{"b1", ""}}), {"b1"}}; @@ -376,7 +376,7 @@ namespace UnitTest1 status_paragraphs.push_back(make_status_pgh("x", "b")); status_paragraphs.push_back(make_status_pgh("b")); - PackageSpecMap spec_map(Triplet::X86_WINDOWS); + PackageSpecMap spec_map; auto spec_a = FullPackageSpec{spec_map.emplace("a")}; auto spec_x = FullPackageSpec{spec_map.emplace("x", "a"), {"core"}}; @@ -674,17 +674,35 @@ namespace UnitTest1 Assert::IsTrue(install_plan[0].install_action.get()->computed_dependencies == std::vector{}); } + TEST_METHOD(install_with_default_features) + { + std::vector> pghs; + pghs.push_back(make_status_pgh("a", "")); + StatusParagraphs status_db(std::move(pghs)); + + PackageSpecMap spec_map; + auto b_spec = spec_map.emplace("b", "", {{"0", ""}}, {"0"}); + auto a_spec = spec_map.emplace("a", "b[core]", {{"0", ""}}); + + // Install "a" and indicate that "b" should not install default features + auto install_plan = Dependencies::create_feature_install_plan( + spec_map.map, {FeatureSpec{a_spec, "0"}, FeatureSpec{b_spec, "core"}}, status_db); + + Assert::IsTrue(install_plan.size() == 3); + remove_plan_check(&install_plan[0], "a"); + features_check(&install_plan[1], "b", {"core"}); + features_check(&install_plan[2], "a", {"0", "core"}); + } + TEST_METHOD(upgrade_with_default_features_1) { std::vector> pghs; pghs.push_back(make_status_pgh("a", "", "1")); pghs.push_back(make_status_feature_pgh("a", "0")); - pghs.back()->package.spec = - PackageSpec::from_name_and_triplet("a", Triplet::X86_WINDOWS).value_or_exit(VCPKG_LINE_INFO); StatusParagraphs status_db(std::move(pghs)); // Add a port "a" of which "core" and "0" are already installed. - PackageSpecMap spec_map(Triplet::X86_WINDOWS); + PackageSpecMap spec_map; auto spec_a = spec_map.emplace("a", "", {{"0", ""}, {"1", ""}}, {"1"}); Dependencies::MapPortFileProvider provider(spec_map.map); @@ -697,23 +715,47 @@ namespace UnitTest1 Assert::AreEqual(size_t(2), plan.size()); Assert::AreEqual("a", plan[0].spec().name().c_str()); - Assert::IsTrue(plan[0].remove_action.has_value()); - - Assert::AreEqual("a", plan[1].spec().name().c_str()); - features_check(&plan[1], "a", {"core", "0"}, Triplet::X86_WINDOWS); + remove_plan_check(&plan[0], "a"); + features_check(&plan[1], "a", {"core", "0"}); } TEST_METHOD(upgrade_with_default_features_2) { std::vector> pghs; - pghs.push_back(make_status_pgh("b")); - pghs.push_back(make_status_pgh("a", "b[core]")); - pghs.back()->package.spec = - PackageSpec::from_name_and_triplet("a", Triplet::X64_WINDOWS).value_or_exit(VCPKG_LINE_INFO); + // B is currently installed _without_ default feature b0 + pghs.push_back(make_status_pgh("b", "", "b0", "x64-windows")); + pghs.push_back(make_status_pgh("a", "b[core]", "", "x64-windows")); + + StatusParagraphs status_db(std::move(pghs)); + + PackageSpecMap spec_map(Triplet::X64_WINDOWS); + auto spec_a = spec_map.emplace("a", "b[core]"); + auto spec_b = spec_map.emplace("b", "", {{"b0", ""}, {"b1", ""}}, {"b0", "b1"}); + + Dependencies::MapPortFileProvider provider(spec_map.map); + Dependencies::PackageGraph graph(provider, status_db); + + graph.upgrade(spec_a); + graph.upgrade(spec_b); + auto plan = graph.serialize(); + + // The upgrade should install the new default feature b1 but not b0 + Assert::AreEqual(size_t(4), plan.size()); + remove_plan_check(&plan[0], "a", Triplet::X64_WINDOWS); + remove_plan_check(&plan[1], "b", Triplet::X64_WINDOWS); + features_check(&plan[2], "b", {"core", "b1"}, Triplet::X64_WINDOWS); + features_check(&plan[3], "a", {"core"}, Triplet::X64_WINDOWS); + } + + TEST_METHOD(upgrade_with_default_features_3) + { + std::vector> pghs; + // note: unrelated package due to x86 triplet + pghs.push_back(make_status_pgh("b", "", "", "x86-windows")); + pghs.push_back(make_status_pgh("a", "", "", "x64-windows")); StatusParagraphs status_db(std::move(pghs)); - // Add a port "a" of which "core" and "0" are already installed. PackageSpecMap spec_map(Triplet::X64_WINDOWS); auto spec_a = spec_map.emplace("a", "b[core]"); spec_map.emplace("b", "", {{"b0", ""}, {"b1", ""}}, {"b0"}); @@ -724,17 +766,33 @@ namespace UnitTest1 graph.upgrade(spec_a); auto plan = graph.serialize(); - // The upgrade should not install the default feature + // The upgrade should install the default feature Assert::AreEqual(size_t(3), plan.size()); + remove_plan_check(&plan[0], "a", Triplet::X64_WINDOWS); + features_check(&plan[1], "b", {"b0", "core"}, Triplet::X64_WINDOWS); + features_check(&plan[2], "a", {"core"}, Triplet::X64_WINDOWS); + } - Assert::AreEqual("a", plan[0].spec().name().c_str()); - Assert::IsTrue(plan[0].remove_action.has_value()); + TEST_METHOD(upgrade_with_new_default_feature) + { + std::vector> pghs; + pghs.push_back(make_status_pgh("a", "", "0", "x86-windows")); - Assert::AreEqual("b", plan[1].spec().name().c_str()); - features_check(&plan[1], "b", {"b0", "core"}, Triplet::X64_WINDOWS); + StatusParagraphs status_db(std::move(pghs)); - Assert::AreEqual("a", plan[2].spec().name().c_str()); - features_check(&plan[2], "a", {"core"}, Triplet::X64_WINDOWS); + PackageSpecMap spec_map; + auto spec_a = spec_map.emplace("a", "", {{"0", ""}, {"1", ""}, {"2", ""}}, {"0", "1"}); + + Dependencies::MapPortFileProvider provider(spec_map.map); + Dependencies::PackageGraph graph(provider, status_db); + + graph.upgrade(spec_a); + auto plan = graph.serialize(); + + // The upgrade should install the new default feature but not the old default feature 0 + Assert::AreEqual(size_t(2), plan.size()); + remove_plan_check(&plan[0], "a", Triplet::X86_WINDOWS); + features_check(&plan[1], "a", {"core", "1"}, Triplet::X86_WINDOWS); } TEST_METHOD(transitive_features_test) @@ -924,7 +982,7 @@ namespace UnitTest1 pghs.push_back(make_status_pgh("a")); StatusParagraphs status_db(std::move(pghs)); - PackageSpecMap spec_map(Triplet::X86_WINDOWS); + PackageSpecMap spec_map; auto spec_a = spec_map.emplace("a"); Dependencies::MapPortFileProvider provider(spec_map.map); @@ -948,7 +1006,7 @@ namespace UnitTest1 pghs.push_back(make_status_pgh("b", "a")); StatusParagraphs status_db(std::move(pghs)); - PackageSpecMap spec_map(Triplet::X86_WINDOWS); + PackageSpecMap spec_map; auto spec_a = spec_map.emplace("a"); spec_map.emplace("b", "a"); @@ -980,7 +1038,7 @@ namespace UnitTest1 pghs.push_back(make_status_pgh("b")); StatusParagraphs status_db(std::move(pghs)); - PackageSpecMap spec_map(Triplet::X86_WINDOWS); + PackageSpecMap spec_map; auto spec_a = spec_map.emplace("a"); spec_map.emplace("b", "a"); @@ -1004,7 +1062,7 @@ namespace UnitTest1 pghs.push_back(make_status_pgh("a")); StatusParagraphs status_db(std::move(pghs)); - PackageSpecMap spec_map(Triplet::X86_WINDOWS); + PackageSpecMap spec_map; auto spec_a = spec_map.emplace("a", "b"); spec_map.emplace("b"); @@ -1031,7 +1089,7 @@ namespace UnitTest1 pghs.push_back(make_status_feature_pgh("a", "a1")); StatusParagraphs status_db(std::move(pghs)); - PackageSpecMap spec_map(Triplet::X86_WINDOWS); + PackageSpecMap spec_map; auto spec_a = spec_map.emplace("a", "", {{"a1", ""}}); Dependencies::MapPortFileProvider provider(spec_map.map); @@ -1057,7 +1115,7 @@ namespace UnitTest1 StatusParagraphs status_db(std::move(pghs)); // a1 was added as a default feature and should be installed in upgrade - PackageSpecMap spec_map(Triplet::X86_WINDOWS); + PackageSpecMap spec_map; auto spec_a = spec_map.emplace("a", "", {{"a1", ""}}, {"a1"}); Dependencies::MapPortFileProvider provider(spec_map.map); @@ -1083,7 +1141,7 @@ namespace UnitTest1 pghs.push_back(make_status_feature_pgh("a", "a2", "a[a1]")); StatusParagraphs status_db(std::move(pghs)); - PackageSpecMap spec_map(Triplet::X86_WINDOWS); + PackageSpecMap spec_map; auto spec_a = spec_map.emplace("a", "", {{"a1", ""}, {"a2", "a[a1]"}}); Dependencies::MapPortFileProvider provider(spec_map.map); @@ -1112,7 +1170,7 @@ namespace UnitTest1 pghs.push_back(make_status_pgh("a")); StatusParagraphs status_db(std::move(pghs)); - PackageSpecMap spec_map(Triplet::X86_WINDOWS); + PackageSpecMap spec_map; auto spec_a = spec_map.emplace("a"); auto plan = Dependencies::create_export_plan({spec_a}, status_db); @@ -1129,7 +1187,7 @@ namespace UnitTest1 pghs.push_back(make_status_pgh("b", "a")); StatusParagraphs status_db(std::move(pghs)); - PackageSpecMap spec_map(Triplet::X86_WINDOWS); + PackageSpecMap spec_map; auto spec_a = spec_map.emplace("a"); auto spec_b = spec_map.emplace("b", "a"); @@ -1150,7 +1208,7 @@ namespace UnitTest1 pghs.push_back(make_status_pgh("b")); StatusParagraphs status_db(std::move(pghs)); - PackageSpecMap spec_map(Triplet::X86_WINDOWS); + PackageSpecMap spec_map; auto spec_a = spec_map.emplace("a"); auto spec_b = spec_map.emplace("b", "a"); @@ -1165,7 +1223,7 @@ namespace UnitTest1 { StatusParagraphs status_db; - PackageSpecMap spec_map(Triplet::X86_WINDOWS); + PackageSpecMap spec_map; auto spec_a = spec_map.emplace("a"); auto plan = Dependencies::create_export_plan({spec_a}, status_db); @@ -1183,7 +1241,7 @@ namespace UnitTest1 pghs.push_back(make_status_feature_pgh("a", "a1", "b[core]")); StatusParagraphs status_db(std::move(pghs)); - PackageSpecMap spec_map(Triplet::X86_WINDOWS); + PackageSpecMap spec_map; auto spec_a = spec_map.emplace("a", "", {{"a1", ""}}); auto plan = Dependencies::create_export_plan({spec_a}, status_db); diff --git a/toolsrc/src/vcpkg/commands.list.cpp b/toolsrc/src/vcpkg/commands.list.cpp index 4c4518d25..1bfbc4247 100644 --- a/toolsrc/src/vcpkg/commands.list.cpp +++ b/toolsrc/src/vcpkg/commands.list.cpp @@ -44,14 +44,19 @@ namespace vcpkg::Commands::List const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE); const StatusParagraphs status_paragraphs = database_load_check(paths); - std::vector installed_packages = get_installed_ports(status_paragraphs); + auto installed_ipv = get_installed_ports(status_paragraphs); - if (installed_packages.empty()) + if (installed_ipv.empty()) { System::println("No packages are installed. Did you mean `search`?"); Checks::exit_success(VCPKG_LINE_INFO); } + auto installed_packages = Util::fmap(installed_ipv, [](const InstalledPackageView& ipv) { return ipv.core; }); + auto installed_features = + Util::fmap_flatten(installed_ipv, [](const InstalledPackageView& ipv) { return ipv.features; }); + installed_packages.insert(installed_packages.end(), installed_features.begin(), installed_features.end()); + std::sort(installed_packages.begin(), installed_packages.end(), [](const StatusParagraph* lhs, const StatusParagraph* rhs) -> bool { diff --git a/toolsrc/src/vcpkg/dependencies.cpp b/toolsrc/src/vcpkg/dependencies.cpp index f6d81c973..a8bc901a0 100644 --- a/toolsrc/src/vcpkg/dependencies.cpp +++ b/toolsrc/src/vcpkg/dependencies.cpp @@ -13,11 +13,17 @@ namespace vcpkg::Dependencies { - struct FeatureNodeEdges + struct ClusterInstalled { - std::vector remove_edges; - std::vector build_edges; - bool plus = false; + InstalledPackageView ipv; + std::set remove_edges; + std::set original_features; + }; + + struct ClusterSource + { + const SourceControlFile* scf; + std::unordered_map> build_edges; }; /// @@ -25,14 +31,15 @@ namespace vcpkg::Dependencies /// struct Cluster : Util::MoveOnlyBase { - InstalledPackageView installed_package; - - Optional source_control_file; PackageSpec spec; - std::unordered_map edges_by_feature; + + Optional installed; + Optional source; + + // Note: this map can contain "special" strings such as "" and "*" + std::unordered_map plus; std::set to_install_features; - std::set original_features; - bool will_remove = false; + bool minus = false; bool transient_uninstalled = true; RequestType request_type = RequestType::AUTO_SELECTED; }; @@ -88,27 +95,26 @@ namespace vcpkg::Dependencies auto maybe_scf = m_provider.get_control_file(spec.name()); auto& clust = m_graph[spec]; clust.spec = spec; - if (auto p_scf = maybe_scf.get()) cluster_from_scf(*p_scf, clust); + if (auto p_scf = maybe_scf.get()) + { + clust.source = cluster_from_scf(*p_scf, clust.spec.triplet()); + } return clust; } return it->second; } private: - void cluster_from_scf(const SourceControlFile& scf, Cluster& out_cluster) const + static ClusterSource cluster_from_scf(const SourceControlFile& scf, Triplet t) { - FeatureNodeEdges core_dependencies; - core_dependencies.build_edges = - filter_dependencies_to_specs(scf.core_paragraph->depends, out_cluster.spec.triplet()); - out_cluster.edges_by_feature.emplace("core", std::move(core_dependencies)); + ClusterSource ret; + ret.build_edges.emplace("core", filter_dependencies_to_specs(scf.core_paragraph->depends, t)); for (const auto& feature : scf.feature_paragraphs) - { - FeatureNodeEdges added_edges; - added_edges.build_edges = filter_dependencies_to_specs(feature->depends, out_cluster.spec.triplet()); - out_cluster.edges_by_feature.emplace(feature->name, std::move(added_edges)); - } - out_cluster.source_control_file = &scf; + ret.build_edges.emplace(feature->name, filter_dependencies_to_specs(feature->depends, t)); + + ret.scf = &scf; + return ret; } std::unordered_map m_graph; @@ -155,11 +161,10 @@ namespace vcpkg::Dependencies { } - InstallPlanAction::InstallPlanAction(const PackageSpec& spec, - InstalledPackageView&& ipv, + InstallPlanAction::InstallPlanAction(InstalledPackageView&& ipv, const std::set& features, const RequestType& request_type) - : spec(spec) + : spec(ipv.spec()) , installed_package(std::move(ipv)) , plan_type(InstallPlanType::ALREADY_INSTALLED) , request_type(request_type) @@ -289,11 +294,11 @@ namespace vcpkg::Dependencies struct RemoveAdjacencyProvider final : Graphs::AdjacencyProvider { const StatusParagraphs& status_db; - const std::vector& installed_ports; + const std::vector& installed_ports; const std::unordered_set& specs_as_set; RemoveAdjacencyProvider(const StatusParagraphs& status_db, - const std::vector& installed_ports, + const std::vector& installed_ports, const std::unordered_set& specs_as_set) : status_db(status_db), installed_ports(installed_ports), specs_as_set(specs_as_set) { @@ -308,24 +313,13 @@ namespace vcpkg::Dependencies const PackageSpec& spec = plan.spec; std::vector dependents; - for (const StatusParagraph* an_installed_package : installed_ports) + for (auto&& ipv : installed_ports) { - if (an_installed_package->package.spec.triplet() != spec.triplet()) continue; + auto deps = ipv.dependencies(); - std::vector deps = an_installed_package->package.depends; - // - // This is a hack to work around existing installations that put featurespecs into binary packages - // (example: curl[core]) Eventually, this can be returned to a simple string search. - for (auto&& dep : deps) - { - dep.erase(std::find(dep.begin(), dep.end(), '['), dep.end()); - } - Util::unstable_keep_if(deps, - [&](auto&& e) { return e != an_installed_package->package.spec.name(); }); - // - if (std::find(deps.begin(), deps.end(), spec.name()) == deps.end()) continue; + if (std::find(deps.begin(), deps.end(), spec) == deps.end()) continue; - dependents.push_back(an_installed_package->package.spec); + dependents.push_back(ipv.spec()); } return dependents; @@ -347,7 +341,7 @@ namespace vcpkg::Dependencies std::string to_string(const PackageSpec& spec) const override { return spec.to_string(); } }; - const std::vector& installed_ports = get_installed_ports(status_db); + auto installed_ports = get_installed_ports(status_db); const std::unordered_set specs_as_set(specs.cbegin(), specs.cend()); return Graphs::topological_sort(specs, RemoveAdjacencyProvider{status_db, installed_ports, specs_as_set}); } @@ -405,161 +399,201 @@ namespace vcpkg::Dependencies Cluster& cluster, ClusterGraph& graph, GraphPlan& graph_plan, - const std::unordered_set& prevent_default_features = {}); + const std::unordered_set& prevent_default_features); - static void mark_minus(Cluster& cluster, ClusterGraph& graph, GraphPlan& graph_plan); + static void mark_minus(Cluster& cluster, + ClusterGraph& graph, + GraphPlan& graph_plan, + const std::unordered_set& prevent_default_features); - MarkPlusResult mark_plus(const std::string& feature, - Cluster& cluster, - ClusterGraph& graph, - GraphPlan& graph_plan, - const std::unordered_set& prevent_default_features) + static MarkPlusResult follow_plus_dependencies(const std::string& feature, + Cluster& cluster, + ClusterGraph& graph, + GraphPlan& graph_plan, + const std::unordered_set& prevent_default_features) { - if (feature.empty()) + if (auto p_source = cluster.source.get()) { - if (prevent_default_features.find(cluster.spec.name()) == prevent_default_features.end()) + auto it_build_edges = p_source->build_edges.find(feature); + if (it_build_edges != p_source->build_edges.end()) { - // Indicates that core was not specified in the reference + // mark this package for rebuilding if needed + mark_minus(cluster, graph, graph_plan, prevent_default_features); + + graph_plan.install_graph.add_vertex({&cluster}); + cluster.to_install_features.insert(feature); - // Add default features for this package, if this is the "core" feature and we - // are not supposed to prevent default features for this package - if (auto scf = cluster.source_control_file.value_or(nullptr)) + if (feature != "core") { - for (auto&& default_feature : scf->core_paragraph.get()->default_features) - { - auto res = mark_plus(default_feature, cluster, graph, graph_plan, prevent_default_features); - if (res != MarkPlusResult::SUCCESS) - { - return res; - } - } + // All features implicitly depend on core + auto res = mark_plus("core", cluster, graph, graph_plan, prevent_default_features); + + // Should be impossible for "core" to not exist + Checks::check_exit(VCPKG_LINE_INFO, res == MarkPlusResult::SUCCESS); } - // "core" is always an implicit default feature. In case we did not add it as - // a dependency above (e.g. no default features), add it here. - auto res = mark_plus("core", cluster, graph, graph_plan, prevent_default_features); - if (res != MarkPlusResult::SUCCESS) + if (!cluster.installed.get() && !Util::Sets::contains(prevent_default_features, cluster.spec.name())) { - return res; + // Add the default features of this package if it was not previously installed and it isn't being + // suppressed. + auto res = mark_plus("", cluster, graph, graph_plan, prevent_default_features); + + Checks::check_exit(VCPKG_LINE_INFO, + res == MarkPlusResult::SUCCESS, + "Error: Unable to satisfy default dependencies of %s", + cluster.spec); + } + + for (auto&& depend : it_build_edges->second) + { + auto& depend_cluster = graph.get(depend.spec()); + auto res = mark_plus(depend.feature(), depend_cluster, graph, graph_plan, prevent_default_features); + + Checks::check_exit(VCPKG_LINE_INFO, + res == MarkPlusResult::SUCCESS, + "Error: Unable to satisfy dependency %s of %s", + depend, + FeatureSpec(cluster.spec, feature)); + + if (&depend_cluster == &cluster) continue; + graph_plan.install_graph.add_edge({&cluster}, {&depend_cluster}); } - return MarkPlusResult::SUCCESS; - } - else - { - // Skip adding the default features, as explicitly told not to. return MarkPlusResult::SUCCESS; } } - auto it = cluster.edges_by_feature.find(feature); - if (it == cluster.edges_by_feature.end()) return MarkPlusResult::FEATURE_NOT_FOUND; + // The feature was not available in the installed package nor the source paragraph. + return MarkPlusResult::FEATURE_NOT_FOUND; + } - if (cluster.edges_by_feature[feature].plus) return MarkPlusResult::SUCCESS; + MarkPlusResult mark_plus(const std::string& feature, + Cluster& cluster, + ClusterGraph& graph, + GraphPlan& graph_plan, + const std::unordered_set& prevent_default_features) + { + auto& plus = cluster.plus[feature]; + if (plus) return MarkPlusResult::SUCCESS; + plus = true; - if (cluster.original_features.find(feature) == cluster.original_features.end()) + if (feature.empty()) { - cluster.transient_uninstalled = true; - } + // Add default features for this package. This is an exact reference, so ignore prevent_default_features. + if (auto p_source = cluster.source.get()) + { + for (auto&& default_feature : p_source->scf->core_paragraph.get()->default_features) + { + auto res = mark_plus(default_feature, cluster, graph, graph_plan, prevent_default_features); + if (res != MarkPlusResult::SUCCESS) + { + return res; + } + } + } + else + { + Checks::exit_with_message(VCPKG_LINE_INFO, + "Error: Unable to install default features because can't find CONTROL for %s", + cluster.spec); + } - if (!cluster.transient_uninstalled) - { - return MarkPlusResult::SUCCESS; + // "core" is always required. + return mark_plus("core", cluster, graph, graph_plan, prevent_default_features); } - cluster.edges_by_feature[feature].plus = true; - if (!cluster.original_features.empty()) + if (feature == "*") { - mark_minus(cluster, graph, graph_plan); - } + if (auto p_source = cluster.source.get()) + { + for (auto&& feature : p_source->scf->feature_paragraphs) + { + auto res = mark_plus(feature->name, cluster, graph, graph_plan, prevent_default_features); - graph_plan.install_graph.add_vertex({&cluster}); - auto& tracked = cluster.to_install_features; - tracked.insert(feature); + Checks::check_exit(VCPKG_LINE_INFO, + res == MarkPlusResult::SUCCESS, + "Error: Unable to locate feature %s in %s", + feature->name, + cluster.spec); + } - if (feature != "core") - { - // All features implicitly depend on core - auto res = mark_plus("core", cluster, graph, graph_plan, prevent_default_features); + auto res = mark_plus("core", cluster, graph, graph_plan, prevent_default_features); - // Should be impossible for "core" to not exist - Checks::check_exit(VCPKG_LINE_INFO, res == MarkPlusResult::SUCCESS); - } - else - { - // Add the default features of this package. - auto res = mark_plus("", cluster, graph, graph_plan, prevent_default_features); + Checks::check_exit(VCPKG_LINE_INFO, res == MarkPlusResult::SUCCESS); + } + else + { + Checks::exit_with_message( + VCPKG_LINE_INFO, "Error: Unable to handle '*' because can't find CONTROL for %s", cluster.spec); + } + return MarkPlusResult::SUCCESS; } - for (auto&& depend : cluster.edges_by_feature[feature].build_edges) + if (auto p_installed = cluster.installed.get()) { - auto& depend_cluster = graph.get(depend.spec()); - auto res = mark_plus(depend.feature(), depend_cluster, graph, graph_plan, prevent_default_features); - - Checks::check_exit(VCPKG_LINE_INFO, - res == MarkPlusResult::SUCCESS, - "Error: Unable to satisfy dependency %s of %s", - depend, - FeatureSpec(cluster.spec, feature)); - - if (&depend_cluster == &cluster) continue; - graph_plan.install_graph.add_edge({&cluster}, {&depend_cluster}); + if (p_installed->original_features.find(feature) != p_installed->original_features.end()) + { + return MarkPlusResult::SUCCESS; + } } - return MarkPlusResult::SUCCESS; + // This feature was or will be uninstalled, therefore we need to rebuild + mark_minus(cluster, graph, graph_plan, prevent_default_features); + + return follow_plus_dependencies(feature, cluster, graph, graph_plan, prevent_default_features); } - void mark_minus(Cluster& cluster, ClusterGraph& graph, GraphPlan& graph_plan) + void mark_minus(Cluster& cluster, + ClusterGraph& graph, + GraphPlan& graph_plan, + const std::unordered_set& prevent_default_features) { - if (cluster.will_remove) return; - cluster.will_remove = true; - - std::unordered_set prevent_default_features; + if (cluster.minus) return; + cluster.minus = true; + cluster.transient_uninstalled = true; - if (cluster.request_type == RequestType::USER_REQUESTED) - { - // Do not install default features for packages which the user - // installed explicitly. New default features for dependent - // clusters should still be upgraded. - prevent_default_features.insert(cluster.spec.name()); + auto p_installed = cluster.installed.get(); + auto p_source = cluster.source.get(); - // For dependent packages this is handles through the recursion - } + Checks::check_exit( + VCPKG_LINE_INFO, + p_source, + "Error: cannot locate new portfile for %s. Please explicitly remove this package with `vcpkg remove %s`.", + cluster.spec, + cluster.spec); - graph_plan.remove_graph.add_vertex({&cluster}); - for (auto&& pair : cluster.edges_by_feature) + if (p_installed) { - auto& remove_edges_edges = pair.second.remove_edges; - for (auto&& depend : remove_edges_edges) + graph_plan.remove_graph.add_vertex({&cluster}); + for (auto&& edge : p_installed->remove_edges) { - auto& depend_cluster = graph.get(depend.spec()); - if (&depend_cluster != &cluster) graph_plan.remove_graph.add_edge({&cluster}, {&depend_cluster}); - mark_minus(depend_cluster, graph, graph_plan); + auto& depend_cluster = graph.get(edge); + Checks::check_exit(VCPKG_LINE_INFO, &cluster != &depend_cluster); + graph_plan.remove_graph.add_edge({&cluster}, {&depend_cluster}); + mark_minus(depend_cluster, graph, graph_plan, prevent_default_features); } - } - cluster.transient_uninstalled = true; - for (auto&& original_feature : cluster.original_features) - { - auto res = mark_plus(original_feature, cluster, graph, graph_plan, prevent_default_features); - if (res != MarkPlusResult::SUCCESS) + // Reinstall all original features. Don't use mark_plus because it will ignore them since they are + // "already installed". + for (auto&& f : p_installed->original_features) { - System::println(System::Color::warning, - "Warning: could not reinstall feature %s", - FeatureSpec{cluster.spec, original_feature}); + auto res = follow_plus_dependencies(f, cluster, graph, graph_plan, prevent_default_features); + if (res != MarkPlusResult::SUCCESS) + { + System::println(System::Color::warning, + "Warning: could not reinstall feature %s", + FeatureSpec{cluster.spec, f}); + } } - } - // Check if any default features have been added - if (auto scf = cluster.source_control_file.value_or(nullptr)) - { - auto& previous_df = cluster.installed_package.core->package.default_features; - for (auto&& default_feature : scf->core_paragraph->default_features) + // Check if any default features have been added + auto& previous_df = p_installed->ipv.core->package.default_features; + for (auto&& default_feature : p_source->scf->core_paragraph->default_features) { if (std::find(previous_df.begin(), previous_df.end(), default_feature) == previous_df.end()) { - // this is a new default feature, mark it for installation - auto res = mark_plus(default_feature, cluster, graph, graph_plan); + // This is a new default feature, mark it for installation + auto res = mark_plus(default_feature, cluster, graph, graph_plan, prevent_default_features); if (res != MarkPlusResult::SUCCESS) { System::println(System::Color::warning, @@ -588,7 +622,11 @@ namespace vcpkg::Dependencies PackageGraph pgraph(provider, status_db); for (auto&& spec : specs) + { + // If preventing default features, ignore the automatically generated "" references + if (spec.feature().empty() && Util::Sets::contains(prevent_default_features, spec.name())) continue; pgraph.install(spec, prevent_default_features); + } return pgraph.serialize(); } @@ -614,37 +652,10 @@ namespace vcpkg::Dependencies { Cluster& spec_cluster = m_graph->get(spec.spec()); spec_cluster.request_type = RequestType::USER_REQUESTED; - if (spec.feature() == "*") - { - if (auto p_scf = spec_cluster.source_control_file.value_or(nullptr)) - { - for (auto&& feature : p_scf->feature_paragraphs) - { - auto res = - mark_plus(feature->name, spec_cluster, *m_graph, *m_graph_plan, prevent_default_features); - - Checks::check_exit( - VCPKG_LINE_INFO, res == MarkPlusResult::SUCCESS, "Error: Unable to locate feature %s", spec); - } - - auto res = mark_plus("core", spec_cluster, *m_graph, *m_graph_plan, prevent_default_features); - Checks::check_exit( - VCPKG_LINE_INFO, res == MarkPlusResult::SUCCESS, "Error: Unable to locate feature %s", spec); - } - else - { - Checks::exit_with_message( - VCPKG_LINE_INFO, "Error: Unable to handle '*' because can't find CONTROL for %s", spec.spec()); - } - } - else - { - auto res = mark_plus(spec.feature(), spec_cluster, *m_graph, *m_graph_plan, prevent_default_features); + auto res = mark_plus(spec.feature(), spec_cluster, *m_graph, *m_graph_plan, prevent_default_features); - Checks::check_exit( - VCPKG_LINE_INFO, res == MarkPlusResult::SUCCESS, "Error: Unable to locate feature %s", spec); - } + Checks::check_exit(VCPKG_LINE_INFO, res == MarkPlusResult::SUCCESS, "Error: Unable to locate feature %s", spec); m_graph_plan->install_graph.add_vertex(ClusterPtr{&spec_cluster}); } @@ -654,7 +665,7 @@ namespace vcpkg::Dependencies Cluster& spec_cluster = m_graph->get(spec); spec_cluster.request_type = RequestType::USER_REQUESTED; - mark_minus(spec_cluster, *m_graph, *m_graph_plan); + mark_minus(spec_cluster, *m_graph, *m_graph_plan, {}); } std::vector PackageGraph::serialize() const @@ -669,11 +680,8 @@ namespace vcpkg::Dependencies for (auto&& p_cluster : remove_toposort) { - auto scf = *p_cluster->source_control_file.get(); - auto spec = PackageSpec::from_name_and_triplet(scf->core_paragraph->name, p_cluster->spec.triplet()) - .value_or_exit(VCPKG_LINE_INFO); plan.emplace_back(RemovePlanAction{ - std::move(spec), + std::move(p_cluster->spec), RemovePlanType::REMOVE, p_cluster->request_type, }); @@ -684,8 +692,7 @@ namespace vcpkg::Dependencies if (p_cluster->transient_uninstalled) { // If it will be transiently uninstalled, we need to issue a full installation command - auto pscf = p_cluster->source_control_file.value_or_exit(VCPKG_LINE_INFO); - Checks::check_exit(VCPKG_LINE_INFO, pscf != nullptr); + auto pscf = p_cluster->source.value_or_exit(VCPKG_LINE_INFO).scf; auto dep_specs = Util::fmap(m_graph_plan->install_graph.adjacency_list(p_cluster), [](ClusterPtr const& p) { return p->spec; }); @@ -703,10 +710,10 @@ namespace vcpkg::Dependencies { // If the package isn't transitively installed, still include it if the user explicitly requested it if (p_cluster->request_type != RequestType::USER_REQUESTED) continue; + auto&& installed = p_cluster->installed.value_or_exit(VCPKG_LINE_INFO); plan.emplace_back(InstallPlanAction{ - p_cluster->spec, - InstalledPackageView{p_cluster->installed_package}, - p_cluster->original_features, + InstalledPackageView{installed.ipv}, + installed.original_features, p_cluster->request_type, }); } @@ -722,44 +729,36 @@ namespace vcpkg::Dependencies auto installed_ports = get_installed_ports(status_db); - for (auto&& status_paragraph : installed_ports) + for (auto&& ipv : installed_ports) { - Cluster& cluster = graph->get(status_paragraph->package.spec); + Cluster& cluster = graph->get(ipv.spec()); cluster.transient_uninstalled = false; - auto& status_paragraph_feature = status_paragraph->package.feature; - - // In this case, empty string indicates the "core" paragraph for a package. - if (status_paragraph_feature.empty()) - { - cluster.original_features.insert("core"); - cluster.installed_package.core = status_paragraph; - } - else - { - cluster.original_features.insert(status_paragraph_feature); - cluster.installed_package.features.emplace_back(status_paragraph); - } + cluster.installed = [](const InstalledPackageView& ipv) -> ClusterInstalled { + ClusterInstalled ret; + ret.ipv = ipv; + ret.original_features.emplace("core"); + for (auto&& feature : ipv.features) + ret.original_features.emplace(feature->package.feature); + return ret; + }(ipv); } // Populate the graph with "remove edges", which are the reverse of the Build-Depends edges. - for (auto&& status_paragraph : installed_ports) + for (auto&& ipv : installed_ports) { - auto& spec = status_paragraph->package.spec; - auto& status_paragraph_feature = status_paragraph->package.feature; - auto reverse_edges = FeatureSpec::from_strings_and_triplet(status_paragraph->package.depends, - status_paragraph->package.spec.triplet()); + auto deps = ipv.dependencies(); - for (auto&& dependency : reverse_edges) + for (auto&& dep : deps) { - auto& dep_cluster = graph->get(dependency.spec()); - - auto depends_name = dependency.feature(); - if (depends_name.empty()) depends_name = "core"; - - auto& target_node = dep_cluster.edges_by_feature[depends_name]; - target_node.remove_edges.emplace_back(FeatureSpec{spec, status_paragraph_feature}); + auto p_installed = graph->get(dep).installed.get(); + Checks::check_exit(VCPKG_LINE_INFO, + p_installed, + "Error: database corrupted. Package %s is installed but dependency %s is not.", + ipv.spec(), + dep); + p_installed->remove_edges.emplace(ipv.spec()); } } return graph; diff --git a/toolsrc/src/vcpkg/remove.cpp b/toolsrc/src/vcpkg/remove.cpp index 32433b234..13cc9325e 100644 --- a/toolsrc/src/vcpkg/remove.cpp +++ b/toolsrc/src/vcpkg/remove.cpp @@ -201,9 +201,9 @@ namespace vcpkg::Remove static std::vector valid_arguments(const VcpkgPaths& paths) { const StatusParagraphs status_db = database_load_check(paths); - const std::vector installed_packages = get_installed_ports(status_db); + auto installed_packages = get_installed_ports(status_db); - return Util::fmap(installed_packages, [](auto&& pgh) -> std::string { return pgh->package.spec.to_string(); }); + return Util::fmap(installed_packages, [](auto&& pgh) -> std::string { return pgh.spec().to_string(); }); } const CommandStructure COMMAND_STRUCTURE = { diff --git a/toolsrc/src/vcpkg/statusparagraph.cpp b/toolsrc/src/vcpkg/statusparagraph.cpp index 62d1d4b42..236689494 100644 --- a/toolsrc/src/vcpkg/statusparagraph.cpp +++ b/toolsrc/src/vcpkg/statusparagraph.cpp @@ -95,7 +95,7 @@ namespace vcpkg // Add the core paragraph dependencies to the list deps.insert(deps.end(), core->package.depends.begin(), core->package.depends.end()); - auto&& spec = core->package.spec; + auto&& l_spec = spec(); // // This is a hack to work around existing installations that put featurespecs into binary packages @@ -104,12 +104,12 @@ namespace vcpkg { dep.erase(std::find(dep.begin(), dep.end(), '['), dep.end()); } - Util::unstable_keep_if(deps, [&](auto&& e) { return e != spec.name(); }); + Util::unstable_keep_if(deps, [&](auto&& e) { return e != l_spec.name(); }); // Util::sort_unique_erase(deps); return Util::fmap(deps, [&](const std::string& dep) -> PackageSpec { - auto maybe_dependency_spec = PackageSpec::from_name_and_triplet(dep, spec.triplet()); + auto maybe_dependency_spec = PackageSpec::from_name_and_triplet(dep, l_spec.triplet()); if (auto dependency_spec = maybe_dependency_spec.get()) { return std::move(*dependency_spec); @@ -120,7 +120,7 @@ namespace vcpkg "Invalid dependency [%s] in package [%s]\n" "%s", dep, - spec.name(), + l_spec.name(), vcpkg::to_string(error_type)); }); } diff --git a/toolsrc/src/vcpkg/update.cpp b/toolsrc/src/vcpkg/update.cpp index d6c5614ed..57259f952 100644 --- a/toolsrc/src/vcpkg/update.cpp +++ b/toolsrc/src/vcpkg/update.cpp @@ -17,17 +17,12 @@ namespace vcpkg::Update std::vector find_outdated_packages(const Dependencies::PortFileProvider& provider, const StatusParagraphs& status_db) { - const std::vector installed_packages = get_installed_ports(status_db); + auto installed_packages = get_installed_ports(status_db); std::vector output; - for (const StatusParagraph* pgh : installed_packages) + for (auto&& ipv : installed_packages) { - if (!pgh->package.feature.empty()) - { - // Skip feature paragraphs; only consider master paragraphs for needing updates. - continue; - } - + const auto& pgh = ipv.core; auto maybe_scf = provider.get_control_file(pgh->package.spec.name()); if (auto p_scf = maybe_scf.get()) { diff --git a/toolsrc/src/vcpkg/vcpkglib.cpp b/toolsrc/src/vcpkg/vcpkglib.cpp index 7979fd9a5..c8e95dab1 100644 --- a/toolsrc/src/vcpkg/vcpkglib.cpp +++ b/toolsrc/src/vcpkg/vcpkglib.cpp @@ -169,16 +169,32 @@ namespace vcpkg fs.rename(updated_listfile_path, listfile_path); } - std::vector get_installed_ports(const StatusParagraphs& status_db) + std::vector get_installed_ports(const StatusParagraphs& status_db) { - std::vector installed_packages; + std::map ipv_map; + + std::vector installed_packages; for (auto&& pgh : status_db) { if (!pgh->is_installed()) continue; - installed_packages.push_back(pgh.get()); + auto& ipv = ipv_map[pgh->package.spec]; + if (pgh->package.feature.empty()) + { + ipv.core = pgh.get(); + } + else + { + ipv.features.emplace_back(pgh.get()); + } } - return installed_packages; + for (auto&& ipv : ipv_map) + Checks::check_exit(VCPKG_LINE_INFO, + ipv.second.core != nullptr, + "Database is corrupted: package %s has features but no core paragraph.", + ipv.first); + + return Util::fmap(ipv_map, [](auto&& p) -> InstalledPackageView { return std::move(p.second); }); } std::vector get_installed_files(const VcpkgPaths& paths, -- cgit v1.2.3 From a2aeb2f1949c42622ccc7f9572a441e2a4475132 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Thu, 12 Apr 2018 00:47:17 -0700 Subject: [vcpkg] Mark many types noexcept. Make certain code patterns more transparent to /analyze. #ifdef-out unused code on non-windows. --- toolsrc/CMakeLists.txt | 3 +++ toolsrc/include/vcpkg/base/chrono.h | 10 ++++---- toolsrc/include/vcpkg/base/cstringview.h | 15 +----------- toolsrc/include/vcpkg/base/files.h | 2 +- toolsrc/include/vcpkg/base/lineinfo.h | 2 +- toolsrc/include/vcpkg/base/optional.h | 6 ++--- toolsrc/include/vcpkg/base/span.h | 7 +++--- toolsrc/include/vcpkg/base/strings.h | 2 +- toolsrc/include/vcpkg/binaryparagraph.h | 2 +- toolsrc/include/vcpkg/build.h | 6 ++--- toolsrc/include/vcpkg/dependencies.h | 6 ++--- toolsrc/include/vcpkg/packagespecparseresult.h | 2 +- toolsrc/include/vcpkg/statusparagraph.h | 4 ++-- toolsrc/include/vcpkg/triplet.h | 4 ++-- toolsrc/include/vcpkg/versiont.h | 4 ++-- toolsrc/src/tests.plan.cpp | 2 +- toolsrc/src/vcpkg.cpp | 2 ++ toolsrc/src/vcpkg/base/cofffilereader.cpp | 7 +++--- toolsrc/src/vcpkg/base/files.cpp | 17 ++++++++------ toolsrc/src/vcpkg/base/strings.cpp | 14 ++++++----- toolsrc/src/vcpkg/base/system.cpp | 32 +++++++++++--------------- toolsrc/src/vcpkg/binaryparagraph.cpp | 2 +- toolsrc/src/vcpkg/build.cpp | 14 +++++------ toolsrc/src/vcpkg/commands.ci.cpp | 7 ++---- toolsrc/src/vcpkg/commands.edit.cpp | 5 ++-- toolsrc/src/vcpkg/commands.fetch.cpp | 5 ++-- toolsrc/src/vcpkg/commands.hash.cpp | 11 +++++---- toolsrc/src/vcpkg/commands.integrate.cpp | 21 ++++++++++++++++- toolsrc/src/vcpkg/dependencies.cpp | 25 ++++++++++++++------ toolsrc/src/vcpkg/export.cpp | 12 +++++----- toolsrc/src/vcpkg/metrics.cpp | 6 ----- toolsrc/src/vcpkg/postbuildlint.cpp | 8 +++++-- toolsrc/src/vcpkg/statusparagraph.cpp | 3 ++- toolsrc/src/vcpkg/versiont.cpp | 4 ++-- 34 files changed, 147 insertions(+), 125 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/CMakeLists.txt b/toolsrc/CMakeLists.txt index acc12f2b3..db756deee 100644 --- a/toolsrc/CMakeLists.txt +++ b/toolsrc/CMakeLists.txt @@ -23,6 +23,9 @@ endif() if(GCC OR CLANG) add_compile_options(-std=c++1z) + if(WERROR) + add_compile_options(-Wall -Wno-unknown-pragmas -Werror) + endif() endif() file(GLOB_RECURSE VCPKGLIB_SOURCES src/vcpkg/*.cpp) diff --git a/toolsrc/include/vcpkg/base/chrono.h b/toolsrc/include/vcpkg/base/chrono.h index 7b393e377..aa764a597 100644 --- a/toolsrc/include/vcpkg/base/chrono.h +++ b/toolsrc/include/vcpkg/base/chrono.h @@ -11,8 +11,8 @@ namespace vcpkg::Chrono using duration = std::chrono::high_resolution_clock::time_point::duration; public: - constexpr ElapsedTime() : m_duration() {} - constexpr ElapsedTime(duration d) : m_duration(d) {} + constexpr ElapsedTime() noexcept : m_duration() {} + constexpr ElapsedTime(duration d) noexcept : m_duration(d) {} template TimeUnit as() const @@ -31,7 +31,7 @@ namespace vcpkg::Chrono public: static ElapsedTimer create_started(); - constexpr ElapsedTimer() : m_start_tick() {} + constexpr ElapsedTimer() noexcept : m_start_tick() {} ElapsedTime elapsed() const { @@ -52,8 +52,8 @@ namespace vcpkg::Chrono static Optional get_current_date_time(); static Optional parse(CStringView str); - constexpr CTime() : m_tm{0} {} - explicit constexpr CTime(tm t) : m_tm{t} {} + constexpr CTime() noexcept : m_tm{0} {} + explicit constexpr CTime(tm t) noexcept : m_tm{t} {} std::string to_string() const; diff --git a/toolsrc/include/vcpkg/base/cstringview.h b/toolsrc/include/vcpkg/base/cstringview.h index 0441bc573..f285aa36c 100644 --- a/toolsrc/include/vcpkg/base/cstringview.h +++ b/toolsrc/include/vcpkg/base/cstringview.h @@ -7,7 +7,7 @@ namespace vcpkg { struct CStringView { - constexpr CStringView() : cstr(nullptr) {} + constexpr CStringView() noexcept : cstr(nullptr) {} constexpr CStringView(const char* cstr) : cstr(cstr) {} constexpr CStringView(const CStringView&) = default; CStringView(const std::string& str) : cstr(str.c_str()) {} @@ -18,19 +18,6 @@ namespace vcpkg const char* cstr; }; - struct CWStringView - { - constexpr CWStringView() : cstr(nullptr) {} - constexpr CWStringView(const wchar_t* cstr) : cstr(cstr) {} - constexpr CWStringView(const CWStringView&) = default; - CWStringView(const std::wstring& str) : cstr(str.c_str()) {} - - constexpr const wchar_t* c_str() const { return cstr; } - - private: - const wchar_t* cstr; - }; - namespace details { inline bool vcpkg_strcmp(const char* l, const char* r) { return strcmp(l, r) == 0; } diff --git a/toolsrc/include/vcpkg/base/files.h b/toolsrc/include/vcpkg/base/files.h index ac1f192ae..f16805d0a 100644 --- a/toolsrc/include/vcpkg/base/files.h +++ b/toolsrc/include/vcpkg/base/files.h @@ -64,7 +64,7 @@ namespace vcpkg::Files Filesystem& get_real_filesystem(); - static const char* FILESYSTEM_INVALID_CHARACTERS = R"(\/:*?"<>|)"; + static constexpr const char* FILESYSTEM_INVALID_CHARACTERS = R"(\/:*?"<>|)"; bool has_invalid_chars_for_filesystem(const std::string& s); diff --git a/toolsrc/include/vcpkg/base/lineinfo.h b/toolsrc/include/vcpkg/base/lineinfo.h index e7e8c3031..e0eb8bec9 100644 --- a/toolsrc/include/vcpkg/base/lineinfo.h +++ b/toolsrc/include/vcpkg/base/lineinfo.h @@ -9,7 +9,7 @@ namespace vcpkg int line_number; const char* file_name; - constexpr LineInfo() : line_number(0), file_name("") {} + constexpr LineInfo() noexcept : line_number(0), file_name("") {} constexpr LineInfo(const int lineno, const char* filename) : line_number(lineno), file_name(filename) {} std::string to_string() const; diff --git a/toolsrc/include/vcpkg/base/optional.h b/toolsrc/include/vcpkg/base/optional.h index b629de9b3..6b84b10aa 100644 --- a/toolsrc/include/vcpkg/base/optional.h +++ b/toolsrc/include/vcpkg/base/optional.h @@ -16,7 +16,7 @@ namespace vcpkg template struct OptionalStorage { - constexpr OptionalStorage() : m_is_present(false), m_t() {} + constexpr OptionalStorage() noexcept : m_is_present(false), m_t() {} constexpr OptionalStorage(const T& t) : m_is_present(true), m_t(t) {} constexpr OptionalStorage(T&& t) : m_is_present(true), m_t(std::move(t)) {} @@ -33,7 +33,7 @@ namespace vcpkg template struct OptionalStorage { - constexpr OptionalStorage() : m_t(nullptr) {} + constexpr OptionalStorage() noexcept : m_t(nullptr) {} constexpr OptionalStorage(T& t) : m_t(&t) {} constexpr bool has_value() const { return m_t != nullptr; } @@ -48,7 +48,7 @@ namespace vcpkg template struct Optional { - constexpr Optional() {} + constexpr Optional() noexcept {} // Constructors are intentionally implicit constexpr Optional(NullOpt) {} diff --git a/toolsrc/include/vcpkg/base/span.h b/toolsrc/include/vcpkg/base/span.h index c9ac18afe..2b067d0ac 100644 --- a/toolsrc/include/vcpkg/base/span.h +++ b/toolsrc/include/vcpkg/base/span.h @@ -19,18 +19,19 @@ namespace vcpkg using iterator = pointer; constexpr Span() noexcept : m_ptr(nullptr), m_count(0) {} - constexpr Span(std::nullptr_t) noexcept : Span() {} + constexpr Span(std::nullptr_t) noexcept : m_ptr(nullptr), m_count(0) {} constexpr Span(pointer ptr, size_t count) noexcept : m_ptr(ptr), m_count(count) {} constexpr Span(pointer ptr_begin, pointer ptr_end) noexcept : m_ptr(ptr_begin), m_count(ptr_end - ptr_begin) {} constexpr Span(std::initializer_list l) noexcept : m_ptr(l.begin()), m_count(l.size()) {} template - constexpr Span(T (&arr)[N]) noexcept : Span(arr, N) + constexpr Span(T (&arr)[N]) noexcept : m_ptr(arr), m_count(N) { } template - constexpr Span(const std::array, N>& arr) noexcept : Span(arr.data(), arr.size()) + constexpr Span(const std::array, N>& arr) noexcept + : m_ptr(arr.data()), m_count(arr.size()) { } diff --git a/toolsrc/include/vcpkg/base/strings.h b/toolsrc/include/vcpkg/base/strings.h index c32e81ac2..4cc17bcf4 100644 --- a/toolsrc/include/vcpkg/base/strings.h +++ b/toolsrc/include/vcpkg/base/strings.h @@ -36,7 +36,7 @@ namespace vcpkg::Strings std::wstring to_utf16(const CStringView& s); - std::string to_utf8(const CWStringView& w); + std::string to_utf8(const wchar_t* w); std::string escape_string(const CStringView& s, char char_to_escape, char escape_char); diff --git a/toolsrc/include/vcpkg/binaryparagraph.h b/toolsrc/include/vcpkg/binaryparagraph.h index 3315151c6..5ba2fbde3 100644 --- a/toolsrc/include/vcpkg/binaryparagraph.h +++ b/toolsrc/include/vcpkg/binaryparagraph.h @@ -12,7 +12,7 @@ namespace vcpkg /// struct BinaryParagraph { - BinaryParagraph(); + BinaryParagraph() noexcept; explicit BinaryParagraph(std::unordered_map fields); BinaryParagraph(const SourceParagraph& spgh, const Triplet& triplet, const std::string& abi_tag); BinaryParagraph(const SourceParagraph& spgh, const FeatureParagraph& fpgh, const Triplet& triplet); diff --git a/toolsrc/include/vcpkg/build.h b/toolsrc/include/vcpkg/build.h index a86245ccf..c5e7e8d88 100644 --- a/toolsrc/include/vcpkg/build.h +++ b/toolsrc/include/vcpkg/build.h @@ -62,7 +62,7 @@ namespace vcpkg::Build BUILT_IN, ARIA2, }; - const std::string& to_string(DownloadTool tool); + const std::string& to_string(DownloadTool tool); struct BuildPackageOptions { @@ -203,8 +203,8 @@ namespace vcpkg::Build struct BuildInfo { - LinkageType crt_linkage; - LinkageType library_linkage; + LinkageType crt_linkage = LinkageType::DYNAMIC; + LinkageType library_linkage = LinkageType::DYNAMIC; Optional version; diff --git a/toolsrc/include/vcpkg/dependencies.h b/toolsrc/include/vcpkg/dependencies.h index 704e76b07..3c3b8f267 100644 --- a/toolsrc/include/vcpkg/dependencies.h +++ b/toolsrc/include/vcpkg/dependencies.h @@ -35,7 +35,7 @@ namespace vcpkg::Dependencies { static bool compare_by_name(const InstallPlanAction* left, const InstallPlanAction* right); - InstallPlanAction(); + InstallPlanAction() noexcept; InstallPlanAction(InstalledPackageView&& spghs, const std::set& features, @@ -73,7 +73,7 @@ namespace vcpkg::Dependencies { static bool compare_by_name(const RemovePlanAction* left, const RemovePlanAction* right); - RemovePlanAction(); + RemovePlanAction() noexcept; RemovePlanAction(const PackageSpec& spec, const RemovePlanType& plan_type, const RequestType& request_type); PackageSpec spec; @@ -103,7 +103,7 @@ namespace vcpkg::Dependencies { static bool compare_by_name(const ExportPlanAction* left, const ExportPlanAction* right); - ExportPlanAction(); + ExportPlanAction() noexcept; ExportPlanAction(const PackageSpec& spec, InstalledPackageView&& installed_package, const RequestType& request_type); diff --git a/toolsrc/include/vcpkg/packagespecparseresult.h b/toolsrc/include/vcpkg/packagespecparseresult.h index dd91c9a67..be3497152 100644 --- a/toolsrc/include/vcpkg/packagespecparseresult.h +++ b/toolsrc/include/vcpkg/packagespecparseresult.h @@ -17,7 +17,7 @@ namespace vcpkg template<> struct ErrorHolder { - ErrorHolder() : m_err(PackageSpecParseResult::SUCCESS) {} + ErrorHolder() noexcept : m_err(PackageSpecParseResult::SUCCESS) {} ErrorHolder(PackageSpecParseResult err) : m_err(err) {} bool has_error() const { return m_err != PackageSpecParseResult::SUCCESS; } diff --git a/toolsrc/include/vcpkg/statusparagraph.h b/toolsrc/include/vcpkg/statusparagraph.h index 16144e467..e79c946cc 100644 --- a/toolsrc/include/vcpkg/statusparagraph.h +++ b/toolsrc/include/vcpkg/statusparagraph.h @@ -29,7 +29,7 @@ namespace vcpkg /// struct StatusParagraph { - StatusParagraph(); + StatusParagraph() noexcept; explicit StatusParagraph(std::unordered_map&& fields); bool is_installed() const { return want == Want::INSTALL && state == InstallState::INSTALLED; } @@ -47,7 +47,7 @@ namespace vcpkg struct InstalledPackageView { - InstalledPackageView() : core(nullptr) {} + InstalledPackageView() noexcept : core(nullptr) {} InstalledPackageView(const StatusParagraph* c, std::vector&& fs) : core(c), features(std::move(fs)) diff --git a/toolsrc/include/vcpkg/triplet.h b/toolsrc/include/vcpkg/triplet.h index 10464dc2c..334960e49 100644 --- a/toolsrc/include/vcpkg/triplet.h +++ b/toolsrc/include/vcpkg/triplet.h @@ -9,7 +9,7 @@ namespace vcpkg struct Triplet { public: - constexpr Triplet() : m_instance(&DEFAULT_INSTANCE) {} + constexpr Triplet() noexcept : m_instance(&DEFAULT_INSTANCE) {} static Triplet from_canonical_name(const std::string& triplet_as_string); @@ -47,4 +47,4 @@ namespace std { size_t operator()(const vcpkg::Triplet& t) const { return t.hash_code(); } }; -} \ No newline at end of file +} diff --git a/toolsrc/include/vcpkg/versiont.h b/toolsrc/include/vcpkg/versiont.h index 8427dfe3b..e893f1abc 100644 --- a/toolsrc/include/vcpkg/versiont.h +++ b/toolsrc/include/vcpkg/versiont.h @@ -5,7 +5,7 @@ namespace vcpkg { struct VersionT { - VersionT(); + VersionT() noexcept; VersionT(std::string&& value); VersionT(const std::string& value); @@ -23,7 +23,7 @@ namespace vcpkg VersionT left; VersionT right; - VersionDiff(); + VersionDiff() noexcept; VersionDiff(const VersionT& left, const VersionT& right); std::string to_string() const; diff --git a/toolsrc/src/tests.plan.cpp b/toolsrc/src/tests.plan.cpp index b054702a1..238aa7032 100644 --- a/toolsrc/src/tests.plan.cpp +++ b/toolsrc/src/tests.plan.cpp @@ -81,7 +81,7 @@ namespace UnitTest1 { std::unordered_map map; Triplet triplet; - PackageSpecMap(const Triplet& t = Triplet::X86_WINDOWS) { triplet = t; } + PackageSpecMap(const Triplet& t = Triplet::X86_WINDOWS) noexcept { triplet = t; } PackageSpec emplace(const char* name, const char* depends = "", diff --git a/toolsrc/src/vcpkg.cpp b/toolsrc/src/vcpkg.cpp index a65045aa8..06c99e9a8 100644 --- a/toolsrc/src/vcpkg.cpp +++ b/toolsrc/src/vcpkg.cpp @@ -223,6 +223,7 @@ static void load_config() } } +#if defined(_WIN32) static std::string trim_path_from_command_line(const std::string& full_command_line) { Checks::check_exit( @@ -243,6 +244,7 @@ static std::string trim_path_from_command_line(const std::string& full_command_l ++it; return std::string(it, full_command_line.cend()); } +#endif #if defined(_WIN32) int wmain(const int argc, const wchar_t* const* const argv) diff --git a/toolsrc/src/vcpkg/base/cofffilereader.cpp b/toolsrc/src/vcpkg/base/cofffilereader.cpp index 5b06a885c..fca0b627e 100644 --- a/toolsrc/src/vcpkg/base/cofffilereader.cpp +++ b/toolsrc/src/vcpkg/base/cofffilereader.cpp @@ -148,17 +148,18 @@ namespace vcpkg::CoffFileReader { static OffsetsArray read(fstream& fs, const uint32_t offset_count) { - static constexpr size_t OFFSET_WIDTH = 4; + static constexpr uint32_t OFFSET_WIDTH = 4; std::string raw_offsets; - const size_t raw_offset_size = offset_count * OFFSET_WIDTH; + const uint32_t raw_offset_size = offset_count * OFFSET_WIDTH; raw_offsets.resize(raw_offset_size); fs.read(&raw_offsets[0], raw_offset_size); OffsetsArray ret; for (uint32_t i = 0; i < offset_count; ++i) { - const std::string value_as_string = raw_offsets.substr(OFFSET_WIDTH * i, OFFSET_WIDTH * (i + 1)); + const std::string value_as_string = raw_offsets.substr(OFFSET_WIDTH * static_cast(i), + OFFSET_WIDTH * (static_cast(i) + 1)); const auto value = reinterpret_bytes(value_as_string.c_str()); // Ignore offsets that point to offset 0. See vcpkg github #223 #288 #292 diff --git a/toolsrc/src/vcpkg/base/files.cpp b/toolsrc/src/vcpkg/base/files.cpp index 4e61666b7..1723b467e 100644 --- a/toolsrc/src/vcpkg/base/files.cpp +++ b/toolsrc/src/vcpkg/base/files.cpp @@ -22,9 +22,9 @@ namespace vcpkg::Files auto length = file_stream.tellg(); file_stream.seekg(0, file_stream.beg); - if (length > SIZE_MAX) + if (length == std::streampos(-1)) { - return std::make_error_code(std::errc::file_too_large); + return std::make_error_code(std::errc::io_error); } std::string output; @@ -185,12 +185,15 @@ namespace vcpkg::Files return; } - auto count = fwrite(data.data(), sizeof(data[0]), data.size(), f); - fclose(f); - - if (count != data.size()) + if (f != nullptr) { - ec = std::make_error_code(std::errc::no_space_on_device); + auto count = fwrite(data.data(), sizeof(data[0]), data.size(), f); + fclose(f); + + if (count != data.size()) + { + ec = std::make_error_code(std::errc::no_space_on_device); + } } } }; diff --git a/toolsrc/src/vcpkg/base/strings.cpp b/toolsrc/src/vcpkg/base/strings.cpp index 541b1f2d9..fbc33ca42 100644 --- a/toolsrc/src/vcpkg/base/strings.cpp +++ b/toolsrc/src/vcpkg/base/strings.cpp @@ -39,7 +39,7 @@ namespace vcpkg::Strings::details _vsnprintf_s_l(&output.at(0), output.size() + 1, output.size(), fmtstr, c_locale(), args); #else va_start(args, fmtstr); - auto res = vsnprintf(&output.at(0), output.size() + 1, fmtstr, args); + vsnprintf(&output.at(0), output.size() + 1, fmtstr, args); #endif va_end(args); @@ -52,23 +52,25 @@ namespace vcpkg::Strings std::wstring to_utf16(const CStringView& s) { #if defined(_WIN32) - const int size = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, nullptr, 0); std::wstring output; + const size_t size = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, nullptr, 0); + if (size == 0) return output; output.resize(size - 1); - MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, output.data(), size - 1); + MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, output.data(), static_cast(size) - 1); return output; #else Checks::unreachable(VCPKG_LINE_INFO); #endif } - std::string to_utf8(const CWStringView& w) + std::string to_utf8(const wchar_t* w) { #if defined(_WIN32) - const int size = WideCharToMultiByte(CP_UTF8, 0, w.c_str(), -1, nullptr, 0, nullptr, nullptr); std::string output; + const size_t size = WideCharToMultiByte(CP_UTF8, 0, w, -1, nullptr, 0, nullptr, nullptr); + if (size == 0) return output; output.resize(size - 1); - WideCharToMultiByte(CP_UTF8, 0, w.c_str(), -1, output.data(), size - 1, nullptr, nullptr); + WideCharToMultiByte(CP_UTF8, 0, w, -1, output.data(), static_cast(size) - 1, nullptr, nullptr); return output; #else Checks::unreachable(VCPKG_LINE_INFO); diff --git a/toolsrc/src/vcpkg/base/system.cpp b/toolsrc/src/vcpkg/base/system.cpp index 3f2f47d72..d4210fe6d 100644 --- a/toolsrc/src/vcpkg/base/system.cpp +++ b/toolsrc/src/vcpkg/base/system.cpp @@ -214,7 +214,7 @@ namespace vcpkg::System for (auto&& env_wstring : env_wstrings) { - const Optional value = System::get_environment_variable(Strings::to_utf8(env_wstring)); + const Optional value = System::get_environment_variable(Strings::to_utf8(env_wstring.c_str())); const auto v = value.get(); if (!v || v->empty()) continue; @@ -298,17 +298,6 @@ namespace vcpkg::System return exit_code; } - // On Win7, output from powershell calls contain a byte order mark, so we strip it out if it is present - static void remove_byte_order_marks(std::wstring* s) - { - const wchar_t* a = s->c_str(); - // This is the UTF-8 byte-order mark - while (s->size() >= 3 && a[0] == 0xEF && a[1] == 0xBB && a[2] == 0xBF) - { - s->erase(0, 3); - } - } - ExitCodeAndOutput cmd_execute_and_capture_output(const CStringView cmd_line) { // Flush stdout before launching external process @@ -325,7 +314,7 @@ namespace vcpkg::System const auto pipe = _wpopen(Strings::to_utf16(actual_cmd_line).c_str(), L"r"); if (pipe == nullptr) { - return {1, Strings::to_utf8(output)}; + return {1, Strings::to_utf8(output.c_str())}; } while (fgetws(buf, 1024, pipe)) { @@ -333,15 +322,22 @@ namespace vcpkg::System } if (!feof(pipe)) { - return {1, Strings::to_utf8(output)}; + return {1, Strings::to_utf8(output.c_str())}; } const auto ec = _pclose(pipe); - remove_byte_order_marks(&output); + + // On Win7, output from powershell calls contain a utf-8 byte order mark in the utf-16 stream, so we strip it + // out if it is present. 0xEF,0xBB,0xBF is the UTF-8 byte-order mark + const wchar_t* a = output.c_str(); + while (output.size() >= 3 && a[0] == 0xEF && a[1] == 0xBB && a[2] == 0xBF) + { + output.erase(0, 3); + } Debug::println("_pclose() returned %d after %8d us", ec, static_cast(timer.microseconds())); - return {ec, Strings::to_utf8(output)}; + return {ec, Strings::to_utf8(output.c_str())}; #else const auto actual_cmd_line = Strings::format(R"###(%s 2>&1)###", cmd_line); @@ -481,7 +477,7 @@ namespace vcpkg::System const auto sz2 = GetEnvironmentVariableW(w_varname.c_str(), ret.data(), static_cast(ret.size())); Checks::check_exit(VCPKG_LINE_INFO, sz2 + 1 == sz); ret.pop_back(); - return Strings::to_utf8(ret); + return Strings::to_utf8(ret.c_str()); #else auto v = getenv(varname.c_str()); if (!v) return nullopt; @@ -522,7 +518,7 @@ namespace vcpkg::System return nullopt; ret.pop_back(); // remove extra trailing null byte - return Strings::to_utf8(ret); + return Strings::to_utf8(ret.c_str()); } #else Optional get_registry_string(void* base_hkey, const CStringView sub_key, const CStringView valuename) diff --git a/toolsrc/src/vcpkg/binaryparagraph.cpp b/toolsrc/src/vcpkg/binaryparagraph.cpp index 73ca23df1..126c7df97 100644 --- a/toolsrc/src/vcpkg/binaryparagraph.cpp +++ b/toolsrc/src/vcpkg/binaryparagraph.cpp @@ -24,7 +24,7 @@ namespace vcpkg static const std::string DEFAULTFEATURES = "Default-Features"; } - BinaryParagraph::BinaryParagraph() = default; + BinaryParagraph::BinaryParagraph() noexcept = default; BinaryParagraph::BinaryParagraph(std::unordered_map fields) { diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index 76381f862..7a9d35667 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -330,8 +330,7 @@ namespace vcpkg::Build const PreBuildInfo& pre_build_info, const PackageSpec& spec, const std::string& abi_tag, - const BuildPackageConfig& config, - const StatusParagraphs& status_db) + const BuildPackageConfig& config) { auto& fs = paths.get_filesystem(); const Triplet& triplet = spec.triplet(); @@ -419,10 +418,9 @@ namespace vcpkg::Build const PreBuildInfo& pre_build_info, const PackageSpec& spec, const std::string& abi_tag, - const BuildPackageConfig& config, - const StatusParagraphs& status_db) + const BuildPackageConfig& config) { - auto result = do_build_package(paths, pre_build_info, spec, abi_tag, config, status_db); + auto result = do_build_package(paths, pre_build_info, spec, abi_tag, config); if (config.build_package_options.clean_buildtrees == CleanBuildtrees::YES) { @@ -564,7 +562,7 @@ namespace vcpkg::Build auto dep_pspecs = Util::fmap(required_fspecs, [](FeatureSpec const& fspec) { return fspec.spec(); }); Util::sort_unique_erase(dep_pspecs); - // Find all features that aren't installed. This destroys required_fspecs. + // Find all features that aren't installed. This mutates required_fspecs. Util::unstable_keep_if(required_fspecs, [&](FeatureSpec const& fspec) { return !status_db.is_installed(fspec) && fspec.name() != name; }); @@ -624,7 +622,7 @@ namespace vcpkg::Build System::println("Could not locate cached archive: %s", archive_path.u8string()); ExtendedBuildResult result = do_build_package_and_clean_buildtrees( - paths, pre_build_info, spec, maybe_abi_tag_and_file.value_or(AbiTagAndFile{}).tag, config, status_db); + paths, pre_build_info, spec, maybe_abi_tag_and_file.value_or(AbiTagAndFile{}).tag, config); std::error_code ec; fs.create_directories(paths.package_dir(spec) / "share" / spec.name(), ec); @@ -657,7 +655,7 @@ namespace vcpkg::Build } return do_build_package_and_clean_buildtrees( - paths, pre_build_info, spec, maybe_abi_tag_and_file.value_or(AbiTagAndFile{}).tag, config, status_db); + paths, pre_build_info, spec, maybe_abi_tag_and_file.value_or(AbiTagAndFile{}).tag, config); } const std::string& to_string(const BuildResult build_result) diff --git a/toolsrc/src/vcpkg/commands.ci.cpp b/toolsrc/src/vcpkg/commands.ci.cpp index 45eb1c83e..04b42ea00 100644 --- a/toolsrc/src/vcpkg/commands.ci.cpp +++ b/toolsrc/src/vcpkg/commands.ci.cpp @@ -77,11 +77,8 @@ namespace vcpkg::Commands::CI { auto triplet = p->spec.triplet(); - const Build::BuildPackageConfig build_config{p->source_control_file.value_or_exit(VCPKG_LINE_INFO), - triplet, - paths.port_dir(p->spec), - install_plan_options, - p->feature_list}; + const Build::BuildPackageConfig build_config{ + *scf, triplet, paths.port_dir(p->spec), install_plan_options, p->feature_list}; auto dependency_abis = Util::fmap(p->computed_dependencies, [&](const PackageSpec& spec) -> Build::AbiEntry { diff --git a/toolsrc/src/vcpkg/commands.edit.cpp b/toolsrc/src/vcpkg/commands.edit.cpp index f0ddd43c5..82569dd07 100644 --- a/toolsrc/src/vcpkg/commands.edit.cpp +++ b/toolsrc/src/vcpkg/commands.edit.cpp @@ -9,14 +9,15 @@ namespace vcpkg::Commands::Edit { static std::vector find_from_registry() { + std::vector output; + +#if defined(_WIN32) static const std::array REGKEYS = { R"(SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{C26E74D1-022E-4238-8B9D-1E7564A36CC9}_is1)", R"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{1287CAD5-7C8D-410D-88B9-0D1EE4A83FF2}_is1)", R"(SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{F8A2A208-72B3-4D61-95FC-8A65D340689B}_is1)", }; - std::vector output; -#if defined(_WIN32) for (auto&& keypath : REGKEYS) { const Optional code_installpath = diff --git a/toolsrc/src/vcpkg/commands.fetch.cpp b/toolsrc/src/vcpkg/commands.fetch.cpp index 9652d0b9e..7a1e6a810 100644 --- a/toolsrc/src/vcpkg/commands.fetch.cpp +++ b/toolsrc/src/vcpkg/commands.fetch.cpp @@ -269,8 +269,6 @@ namespace vcpkg::Commands::Fetch #endif static fs::path fetch_tool(const VcpkgPaths& paths, const std::string& tool_name, const ToolData& tool_data) { - const auto& fs = paths.get_filesystem(); - const fs::path& scripts_folder = paths.scripts; const std::array& version = tool_data.version; const std::string version_as_string = Strings::format("%d.%d.%d", version[0], version[1], version[2]); @@ -280,7 +278,7 @@ namespace vcpkg::Commands::Fetch tool_name, version_as_string); #if defined(_WIN32) - const fs::path script = scripts_folder / "fetchtool.ps1"; + const fs::path script = paths.scripts / "fetchtool.ps1"; const std::string title = Strings::format( "Fetching %s version %s (No sufficient installed version was found)", tool_name, version_as_string); const System::PowershellParameter tool_param("tool", tool_name); @@ -300,6 +298,7 @@ namespace vcpkg::Commands::Fetch actual_downloaded_path.u8string()); return actual_downloaded_path; #else + const auto& fs = paths.get_filesystem(); if (!fs.exists(tool_data.download_path)) { System::println("Downloading %s...", tool_name); diff --git a/toolsrc/src/vcpkg/commands.hash.cpp b/toolsrc/src/vcpkg/commands.hash.cpp index c23a63e1e..1f709f87b 100644 --- a/toolsrc/src/vcpkg/commands.hash.cpp +++ b/toolsrc/src/vcpkg/commands.hash.cpp @@ -127,12 +127,15 @@ namespace vcpkg::Commands::Hash FILE* file = nullptr; const auto ec = _wfopen_s(&file, path.c_str(), L"rb"); Checks::check_exit(VCPKG_LINE_INFO, ec == 0, "Failed to open file: %s", path.u8string()); - unsigned char buffer[4096]; - while (const auto actual_size = fread(buffer, 1, sizeof(buffer), file)) + if (file != nullptr) { - hash_data(hash_handle, buffer, actual_size); + unsigned char buffer[4096]; + while (const auto actual_size = fread(buffer, 1, sizeof(buffer), file)) + { + hash_data(hash_handle, buffer, actual_size); + } + fclose(file); } - fclose(file); return finalize_hash_handle(hash_handle, length_in_bytes); } diff --git a/toolsrc/src/vcpkg/commands.integrate.cpp b/toolsrc/src/vcpkg/commands.integrate.cpp index e70d9b2e3..7061a3984 100644 --- a/toolsrc/src/vcpkg/commands.integrate.cpp +++ b/toolsrc/src/vcpkg/commands.integrate.cpp @@ -8,6 +8,7 @@ namespace vcpkg::Commands::Integrate { +#if defined(_WIN32) static std::string create_appdata_targets_shortcut(const std::string& target_path) noexcept { return Strings::format(R"###( @@ -18,7 +19,9 @@ namespace vcpkg::Commands::Integrate target_path, target_path); } +#endif +#if defined(_WIN32) static std::string create_system_targets_shortcut() noexcept { return R"###( @@ -31,7 +34,9 @@ namespace vcpkg::Commands::Integrate )###"; } +#endif +#if defined(_WIN32) static std::string create_nuget_targets_file_contents(const fs::path& msbuild_vcpkg_targets_file) noexcept { const std::string as_string = msbuild_vcpkg_targets_file.string(); @@ -47,7 +52,9 @@ namespace vcpkg::Commands::Integrate as_string, as_string); } +#endif +#if defined(_WIN32) static std::string create_nuget_props_file_contents() noexcept { return R"###( @@ -58,7 +65,9 @@ namespace vcpkg::Commands::Integrate )###"; } +#endif +#if defined(_WIN32) static std::string get_nuget_id(const fs::path& vcpkg_root_dir) { std::string dir_id = vcpkg_root_dir.generic_string(); @@ -71,7 +80,9 @@ namespace vcpkg::Commands::Integrate const std::string nuget_id = "vcpkg." + dir_id; return nuget_id; } +#endif +#if defined(_WIN32) static std::string create_nuspec_file_contents(const fs::path& vcpkg_root_dir, const std::string& nuget_id, const std::string& nupkg_version) @@ -98,14 +109,15 @@ namespace vcpkg::Commands::Integrate content = Strings::replace_all(std::move(content), "@VERSION@", nupkg_version); return content; } +#endif +#if defined(_WIN32) enum class ElevationPromptChoice { YES, NO }; -#if defined(_WIN32) static ElevationPromptChoice elevated_cmd_execute(const std::string& param) { SHELLEXECUTEINFOW sh_ex_info{}; @@ -272,6 +284,7 @@ CMake projects should use: "-DCMAKE_TOOLCHAIN_FILE=%s")", } #endif +#if defined(WIN32) static void integrate_project(const VcpkgPaths& paths) { auto& fs = paths.get_filesystem(); @@ -319,13 +332,19 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console Checks::exit_success(VCPKG_LINE_INFO); } +#endif +#if defined(_WIN32) const char* const INTEGRATE_COMMAND_HELPSTRING = " vcpkg integrate install Make installed packages available user-wide. Requires admin privileges on " "first use\n" " vcpkg integrate remove Remove user-wide integration\n" " vcpkg integrate project Generate a referencing nuget package for individual VS project use\n" " vcpkg integrate powershell Enable PowerShell Tab-Completion\n"; +#else + const char* const INTEGRATE_COMMAND_HELPSTRING = + "No user-wide integration methods are available on this platform\n"; +#endif namespace Subcommand { diff --git a/toolsrc/src/vcpkg/dependencies.cpp b/toolsrc/src/vcpkg/dependencies.cpp index a8bc901a0..8fb35b0da 100644 --- a/toolsrc/src/vcpkg/dependencies.cpp +++ b/toolsrc/src/vcpkg/dependencies.cpp @@ -22,7 +22,7 @@ namespace vcpkg::Dependencies struct ClusterSource { - const SourceControlFile* scf; + const SourceControlFile* scf = nullptr; std::unordered_map> build_edges; }; @@ -145,7 +145,10 @@ namespace vcpkg::Dependencies } } - InstallPlanAction::InstallPlanAction() : plan_type(InstallPlanType::UNKNOWN), request_type(RequestType::UNKNOWN) {} + InstallPlanAction::InstallPlanAction() noexcept + : plan_type(InstallPlanType::UNKNOWN), request_type(RequestType::UNKNOWN), build_options{} + { + } InstallPlanAction::InstallPlanAction(const PackageSpec& spec, const SourceControlFile& scf, @@ -156,6 +159,7 @@ namespace vcpkg::Dependencies , source_control_file(scf) , plan_type(InstallPlanType::BUILD_AND_INSTALL) , request_type(request_type) + , build_options{} , feature_list(features) , computed_dependencies(std::move(dependencies)) { @@ -168,6 +172,7 @@ namespace vcpkg::Dependencies , installed_package(std::move(ipv)) , plan_type(InstallPlanType::ALREADY_INSTALLED) , request_type(request_type) + , build_options{} , feature_list(features) , computed_dependencies(installed_package.get()->dependencies()) { @@ -189,7 +194,10 @@ namespace vcpkg::Dependencies return left->spec.name() < right->spec.name(); } - RemovePlanAction::RemovePlanAction() : plan_type(RemovePlanType::UNKNOWN), request_type(RequestType::UNKNOWN) {} + RemovePlanAction::RemovePlanAction() noexcept + : plan_type(RemovePlanType::UNKNOWN), request_type(RequestType::UNKNOWN) + { + } RemovePlanAction::RemovePlanAction(const PackageSpec& spec, const RemovePlanType& plan_type, @@ -218,7 +226,10 @@ namespace vcpkg::Dependencies return left->spec.name() < right->spec.name(); } - ExportPlanAction::ExportPlanAction() : plan_type(ExportPlanType::UNKNOWN), request_type(RequestType::UNKNOWN) {} + ExportPlanAction::ExportPlanAction() noexcept + : plan_type(ExportPlanType::UNKNOWN), request_type(RequestType::UNKNOWN) + { + } ExportPlanAction::ExportPlanAction(const PackageSpec& spec, InstalledPackageView&& installed_package, @@ -506,14 +517,14 @@ namespace vcpkg::Dependencies { if (auto p_source = cluster.source.get()) { - for (auto&& feature : p_source->scf->feature_paragraphs) + for (auto&& fpgh : p_source->scf->feature_paragraphs) { - auto res = mark_plus(feature->name, cluster, graph, graph_plan, prevent_default_features); + auto res = mark_plus(fpgh->name, cluster, graph, graph_plan, prevent_default_features); Checks::check_exit(VCPKG_LINE_INFO, res == MarkPlusResult::SUCCESS, "Error: Unable to locate feature %s in %s", - feature->name, + fpgh->name, cluster.spec); } diff --git a/toolsrc/src/vcpkg/export.cpp b/toolsrc/src/vcpkg/export.cpp index 85a4dfad1..152252018 100644 --- a/toolsrc/src/vcpkg/export.cpp +++ b/toolsrc/src/vcpkg/export.cpp @@ -247,12 +247,12 @@ namespace vcpkg::Export struct ExportArguments { - bool dry_run; - bool raw; - bool nuget; - bool ifw; - bool zip; - bool seven_zip; + bool dry_run = false; + bool raw = false; + bool nuget = false; + bool ifw = false; + bool zip = false; + bool seven_zip = false; Optional maybe_output; diff --git a/toolsrc/src/vcpkg/metrics.cpp b/toolsrc/src/vcpkg/metrics.cpp index 4067efc95..8890c067f 100644 --- a/toolsrc/src/vcpkg/metrics.cpp +++ b/toolsrc/src/vcpkg/metrics.cpp @@ -245,12 +245,6 @@ namespace vcpkg::Metrics bool get_compiled_metrics_enabled() { return DISABLE_METRICS == 0; } - static fs::path get_vcpkg_root() - { - return Files::get_real_filesystem().find_file_recursively_up( - fs::stdfs::absolute(System::get_exe_path_of_current_process()), ".vcpkg-root"); - } - std::string get_MAC_user() { #if defined(_WIN32) diff --git a/toolsrc/src/vcpkg/postbuildlint.cpp b/toolsrc/src/vcpkg/postbuildlint.cpp index a31518ad7..6fe11951f 100644 --- a/toolsrc/src/vcpkg/postbuildlint.cpp +++ b/toolsrc/src/vcpkg/postbuildlint.cpp @@ -361,6 +361,7 @@ namespace vcpkg::PostBuildLint std::string actual_arch; }; +#if defined(_WIN32) static std::string get_actual_architecture(const MachineType& machine_type) { switch (machine_type) @@ -374,7 +375,9 @@ namespace vcpkg::PostBuildLint default: return "Machine Type Code = " + std::to_string(static_cast(machine_type)); } } +#endif +#if defined(_WIN32) static void print_invalid_architecture_files(const std::string& expected_architecture, std::vector binaries_with_invalid_architecture) { @@ -391,7 +394,6 @@ namespace vcpkg::PostBuildLint static LintStatus check_dll_architecture(const std::string& expected_architecture, const std::vector& files) { -#if defined(_WIN32) std::vector binaries_with_invalid_architecture; for (const fs::path& file : files) @@ -414,10 +416,10 @@ namespace vcpkg::PostBuildLint print_invalid_architecture_files(expected_architecture, binaries_with_invalid_architecture); return LintStatus::ERROR_DETECTED; } -#endif return LintStatus::SUCCESS; } +#endif static LintStatus check_lib_architecture(const std::string& expected_architecture, const std::vector& files) @@ -802,7 +804,9 @@ namespace vcpkg::PostBuildLint check_outdated_crt_linkage_of_dlls(dlls, toolset.dumpbin, build_info, pre_build_info); } +#if defined(_WIN32) error_count += check_dll_architecture(pre_build_info.target_architecture, dlls); +#endif break; } case Build::LinkageType::STATIC: diff --git a/toolsrc/src/vcpkg/statusparagraph.cpp b/toolsrc/src/vcpkg/statusparagraph.cpp index 236689494..462d8d8ed 100644 --- a/toolsrc/src/vcpkg/statusparagraph.cpp +++ b/toolsrc/src/vcpkg/statusparagraph.cpp @@ -12,7 +12,7 @@ namespace vcpkg static const std::string STATUS = "Status"; } - StatusParagraph::StatusParagraph() : want(Want::ERROR_STATE), state(InstallState::ERROR_STATE) {} + StatusParagraph::StatusParagraph() noexcept : want(Want::ERROR_STATE), state(InstallState::ERROR_STATE) {} void serialize(const StatusParagraph& pgh, std::string& out_str) { @@ -25,6 +25,7 @@ namespace vcpkg } StatusParagraph::StatusParagraph(std::unordered_map&& fields) + : want(Want::ERROR_STATE), state(InstallState::ERROR_STATE) { auto status_it = fields.find(BinaryParagraphRequiredField::STATUS); Checks::check_exit(VCPKG_LINE_INFO, status_it != fields.end(), "Expected 'Status' field in status paragraph"); diff --git a/toolsrc/src/vcpkg/versiont.cpp b/toolsrc/src/vcpkg/versiont.cpp index 0d4a39255..d20e6b577 100644 --- a/toolsrc/src/vcpkg/versiont.cpp +++ b/toolsrc/src/vcpkg/versiont.cpp @@ -5,7 +5,7 @@ namespace vcpkg { - VersionT::VersionT() : value("0.0.0") {} + VersionT::VersionT() noexcept : value("0.0.0") {} VersionT::VersionT(std::string&& value) : value(std::move(value)) {} VersionT::VersionT(const std::string& value) : value(value) {} const std::string& VersionT::to_string() const { return value; } @@ -13,7 +13,7 @@ namespace vcpkg bool operator!=(const VersionT& left, const VersionT& right) { return left.to_string() != right.to_string(); } std::string to_printf_arg(const VersionT& version) { return version.to_string(); } - VersionDiff::VersionDiff() : left(), right() {} + VersionDiff::VersionDiff() noexcept : left(), right() {} VersionDiff::VersionDiff(const VersionT& left, const VersionT& right) : left(left), right(right) {} std::string VersionDiff::to_string() const -- cgit v1.2.3 From 5886a48dc7c5be48be3baf73ce2e8e136252aede Mon Sep 17 00:00:00 2001 From: "Billy O'Neal (VC LIBS)" Date: Thu, 12 Apr 2018 15:31:11 -0700 Subject: Remove call to nonexistent member of std::fpos. See http://eel.is/c++draft/fpos -- to get to an offset you can convert to int; there is no seekpos member. --- toolsrc/src/vcpkg/base/cofffilereader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/base/cofffilereader.cpp b/toolsrc/src/vcpkg/base/cofffilereader.cpp index fca0b627e..2c09e2c19 100644 --- a/toolsrc/src/vcpkg/base/cofffilereader.cpp +++ b/toolsrc/src/vcpkg/base/cofffilereader.cpp @@ -247,7 +247,7 @@ namespace vcpkg::CoffFileReader { void set_to_offset(const fpos_t position) { this->m_absolute_position = position; } - void set_to_current_pos(fstream& fs) { this->m_absolute_position = fs.tellg().seekpos(); } + void set_to_current_pos(fstream& fs) { this->m_absolute_position = fs.tellg(); } void seek_to_marker(fstream& fs) const { fs.seekg(this->m_absolute_position, ios_base::beg); } -- cgit v1.2.3 From a9b1541fd6d308a17848ab4eb5396598ffa1a240 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 16 Apr 2018 16:14:50 -0700 Subject: [vcpkg, xml] Parse with string-search instead of regex Resolves issue with inconsistent regex behavior between platforms. For example [/s/S]*? does not properly match on Clang. String-searching is also generally more performant. --- toolsrc/src/vcpkg/commands.fetch.cpp | 83 +++++++++++++++++------------------- 1 file changed, 40 insertions(+), 43 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/commands.fetch.cpp b/toolsrc/src/vcpkg/commands.fetch.cpp index 7a1e6a810..1e31e6bc4 100644 --- a/toolsrc/src/vcpkg/commands.fetch.cpp +++ b/toolsrc/src/vcpkg/commands.fetch.cpp @@ -41,6 +41,22 @@ namespace vcpkg::Commands::Fetch return result; } + static Optional extract_string_between_delimiters(const std::string& input, + const std::string& left_delim, + const std::string& right_delim, + const size_t& starting_offset = 0) + { + const size_t from = input.find(left_delim, starting_offset); + if (from == std::string::npos) return nullopt; + + const size_t substring_start = from + left_delim.length(); + + const size_t to = input.find(right_delim, substring_start); + if (from == std::string::npos) return nullopt; + + return input.substr(substring_start, to - substring_start); + } + static ToolData parse_tool_data_from_xml(const VcpkgPaths& paths, const std::string& tool) { #if defined(_WIN32) @@ -57,33 +73,21 @@ namespace vcpkg::Commands::Fetch static const std::string XML_VERSION = "2"; static const fs::path XML_PATH = paths.scripts / "vcpkgTools.xml"; - const auto maybe_get_string_inside_tags = [](const std::string& input, - const std::regex& regex) -> Optional { - std::smatch match; - const bool has_match = std::regex_search(input.cbegin(), input.cend(), match, regex); - if (!has_match) return nullopt; - return match[1]; - }; - const auto get_string_inside_tags = - [](const std::string& input, const std::regex& regex, const std::string& tag_name) -> std::string { - std::smatch match; - const bool has_match = std::regex_search(input.cbegin(), input.cend(), match, regex); - Checks::check_exit( - VCPKG_LINE_INFO, has_match, "Could not find tag <%s> in %s", tag_name, XML_PATH.generic_string()); + [](const std::string& input, const std::string& left_delim, const std::string& right_delim) -> std::string { + Optional result = extract_string_between_delimiters(input, left_delim, right_delim); + Checks::check_exit(VCPKG_LINE_INFO, + result.has_value(), + "Could not find tag <%s>.*<%s> in %s", + left_delim, + right_delim, + XML_PATH.generic_string()); - return match[1]; + return *result.get(); }; static const std::regex XML_VERSION_REGEX{R"###()###"}; static const std::string XML = paths.get_filesystem().read_contents(XML_PATH).value_or_exit(VCPKG_LINE_INFO); - static const std::regex VERSION_REGEX{R"###(([\s\S]*?))###"}; - static const std::regex EXE_RELATIVE_PATH_REGEX{ - Strings::format(R"###(([\s\S]*?))###")}; - static const std::regex ARCHIVE_NAME_REGEX{Strings::format(R"###(([\s\S]*?))###")}; - static const std::regex URL_REGEX{Strings::format(R"###(([\s\S]*?))###")}; - static const std::regex SHA512_REGEX{Strings::format(R"###(([\s\S]*?))###")}; - std::smatch match_xml_version; const bool has_xml_version = std::regex_search(XML.cbegin(), XML.cend(), match_xml_version, XML_VERSION_REGEX); Checks::check_exit(VCPKG_LINE_INFO, @@ -98,43 +102,36 @@ namespace vcpkg::Commands::Fetch XML_VERSION, match_xml_version[1]); - const std::regex tool_regex{ - Strings::format(R"###(([\s\S]*?)<\/tool>)###", tool, OS_STRING)}; - - std::smatch match_tool; - const bool has_match_tool = std::regex_search(XML.cbegin(), XML.cend(), match_tool, tool_regex); + const std::regex tool_regex{Strings::format(R"###()###", tool, OS_STRING)}; + std::smatch match_tool_entry; + const bool has_tool_entry = std::regex_search(XML.cbegin(), XML.cend(), match_tool_entry, tool_regex); Checks::check_exit(VCPKG_LINE_INFO, - has_match_tool, + has_tool_entry, "Could not find entry for tool [%s] in %s", tool, XML_PATH.generic_string()); - const std::string tool_data_as_string = get_string_inside_tags(XML, tool_regex, tool); - - const std::string required_version_as_string = - get_string_inside_tags(tool_data_as_string, VERSION_REGEX, "version"); - - const std::string url = get_string_inside_tags(tool_data_as_string, URL_REGEX, "url"); + const std::string tool_data = get_string_inside_tags(XML, match_tool_entry[0], R"()"); + const std::string version_as_string = get_string_inside_tags(tool_data, "", R"()"); const std::string exe_relative_path = - get_string_inside_tags(tool_data_as_string, EXE_RELATIVE_PATH_REGEX, "exeRelativePath"); - - auto archive_name = maybe_get_string_inside_tags(tool_data_as_string, ARCHIVE_NAME_REGEX); + get_string_inside_tags(tool_data, "", R"()"); + const std::string url = get_string_inside_tags(tool_data, "", R"()"); + const std::string sha512 = get_string_inside_tags(tool_data, "", R"()"); + auto archive_name = extract_string_between_delimiters(tool_data, "", R"()"); - const Optional> required_version = parse_version_string(required_version_as_string); + const Optional> version = parse_version_string(version_as_string); Checks::check_exit(VCPKG_LINE_INFO, - required_version.has_value(), + version.has_value(), "Could not parse version for tool %s. Version string was: %s", tool, - required_version_as_string); + version_as_string); - const std::string tool_dir_name = Strings::format("%s-%s-%s", tool, required_version_as_string, OS_STRING); + const std::string tool_dir_name = Strings::format("%s-%s-%s", tool, version_as_string, OS_STRING); const fs::path tool_dir_path = paths.downloads / "tools" / tool_dir_name; const fs::path exe_path = tool_dir_path / exe_relative_path; - const std::string sha512 = get_string_inside_tags(tool_data_as_string, SHA512_REGEX, "sha512"); - - return ToolData{*required_version.get(), + return ToolData{*version.get(), exe_path, url, paths.downloads / archive_name.value_or(exe_relative_path), -- cgit v1.2.3 From c3062a7b8d06ea20c2105e8b277ccc76af99a2d2 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 17 Apr 2018 13:45:01 -0700 Subject: Use ~/.vcpkg/config instead of ~/vcpkg/config --- toolsrc/src/vcpkg/userconfig.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/userconfig.cpp b/toolsrc/src/vcpkg/userconfig.cpp index 9db2e5d47..574a97b64 100644 --- a/toolsrc/src/vcpkg/userconfig.cpp +++ b/toolsrc/src/vcpkg/userconfig.cpp @@ -35,7 +35,7 @@ namespace vcpkg return get_localappdata() / "vcpkg" / "config"; #else auto maybe_home = System::get_environment_variable("HOME"); - return fs::path(maybe_home.value_or("/var")) / "vcpkg" / "config"; + return fs::path(maybe_home.value_or("/var")) / ".vcpkg" / "config"; #endif } -- cgit v1.2.3 From 8fcb1073abe8611fa24b43f7c1cda0d7404e108e Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 18 Apr 2018 18:52:22 -0700 Subject: [vcpkg edit] Now accepts multiple ports as arg --- toolsrc/src/vcpkg/commands.edit.cpp | 70 +++++++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 27 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/commands.edit.cpp b/toolsrc/src/vcpkg/commands.edit.cpp index 82569dd07..b6324565c 100644 --- a/toolsrc/src/vcpkg/commands.edit.cpp +++ b/toolsrc/src/vcpkg/commands.edit.cpp @@ -1,5 +1,6 @@ #include "pch.h" +#include #include #include #include @@ -52,11 +53,42 @@ namespace vcpkg::Commands::Edit const CommandStructure COMMAND_STRUCTURE = { Help::create_example_string("edit zlib"), 1, - 1, + 10, {EDIT_SWITCHES, {}}, &valid_arguments, }; + static std::vector create_editor_arguments(const VcpkgPaths& paths, + const ParsedArguments& options, + const std::vector& ports) + { + if (Util::Sets::contains(options.switches, OPTION_ALL)) + { + return Util::fmap(ports, [&](const std::string& port_name) -> std::string { + const auto portpath = paths.ports / port_name; + const auto portfile = portpath / "portfile.cmake"; + const auto buildtrees_current_dir = paths.buildtrees / port_name; + return Strings::format(R"###("%s" "%s" "%s")###", + portpath.u8string(), + portfile.u8string(), + buildtrees_current_dir.u8string()); + }); + } + + if (Util::Sets::contains(options.switches, OPTION_BUILDTREES)) + { + return Util::fmap(ports, [&](const std::string& port_name) -> std::string { + return (paths.buildtrees / port_name).u8string(); + }); + } + + return Util::fmap(ports, [&](const std::string& port_name) -> std::string { + const auto portpath = paths.ports / port_name; + const auto portfile = portpath / "portfile.cmake"; + return Strings::format(R"###("%s" "%s")###", portpath.u8string(), portfile.u8string()); + }); + } + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { static const fs::path VS_CODE_INSIDERS = fs::path{"Microsoft VS Code Insiders"} / "Code - Insiders.exe"; @@ -65,10 +97,14 @@ namespace vcpkg::Commands::Edit auto& fs = paths.get_filesystem(); const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE); - 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); + const std::vector& ports = args.command_arguments; + for (auto&& port_name : ports) + { + 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); + } std::vector candidate_paths; auto maybe_editor_path = System::get_environment_variable("EDITOR"); @@ -107,29 +143,9 @@ namespace vcpkg::Commands::Edit } const fs::path env_editor = *it; - if (Util::Sets::contains(options.switches, OPTION_BUILDTREES)) - { - const auto buildtrees_current_dir = paths.buildtrees / port_name; - - const auto cmd_line = - Strings::format(R"("%s" "%s" -n)", env_editor.u8string(), buildtrees_current_dir.u8string()); - Checks::exit_with_code(VCPKG_LINE_INFO, System::cmd_execute(cmd_line)); - } - - if (Util::Sets::contains(options.switches, OPTION_ALL)) - { - const auto buildtrees_current_dir = paths.buildtrees / port_name; - - const auto cmd_line = Strings::format( - R"("%s" "%s" "%s" -n)", env_editor.u8string(), portpath.u8string(), buildtrees_current_dir.u8string()); - Checks::exit_with_code(VCPKG_LINE_INFO, System::cmd_execute(cmd_line)); - } - - const auto cmd_line = Strings::format( - R"("%s" "%s" "%s" -n)", - env_editor.u8string(), - portpath.u8string(), - (portpath / "portfile.cmake").u8string()); + const std::vector arguments = create_editor_arguments(paths, options, ports); + const auto args_as_string = Strings::join(" ", arguments); + const auto cmd_line = Strings::format(R"("%s" %s -n)", env_editor.u8string(), args_as_string); Checks::exit_with_code(VCPKG_LINE_INFO, System::cmd_execute(cmd_line)); } } -- cgit v1.2.3 From aff1819c796fab3e04b9dc1a4b850ef9358ed9a4 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 23 Apr 2018 18:55:52 -0700 Subject: Update CHANGELOG and bump version to v0.0.109 --- toolsrc/VERSION.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/VERSION.txt b/toolsrc/VERSION.txt index 2cd1bf9ac..f8e183aed 100644 --- a/toolsrc/VERSION.txt +++ b/toolsrc/VERSION.txt @@ -1 +1 @@ -"0.0.108" \ No newline at end of file +"0.0.109" \ No newline at end of file -- cgit v1.2.3 From ed9bb364468717b5b1f55980556935fac2f8e8a5 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 24 Apr 2018 10:42:38 -0700 Subject: Update CHANGELOG and bump version to v0.0.110 --- toolsrc/VERSION.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/VERSION.txt b/toolsrc/VERSION.txt index f8e183aed..ca3fbdad8 100644 --- a/toolsrc/VERSION.txt +++ b/toolsrc/VERSION.txt @@ -1 +1 @@ -"0.0.109" \ No newline at end of file +"0.0.110" \ No newline at end of file -- cgit v1.2.3 From d126acab7bc5789e8f75197c2ac1fda03584caba Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 24 Apr 2018 11:02:57 -0700 Subject: [vcpkg integrate] Do nothing on linux instead of showing error message --- toolsrc/src/vcpkg/commands.integrate.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/commands.integrate.cpp b/toolsrc/src/vcpkg/commands.integrate.cpp index 7061a3984..2e1750c80 100644 --- a/toolsrc/src/vcpkg/commands.integrate.cpp +++ b/toolsrc/src/vcpkg/commands.integrate.cpp @@ -392,8 +392,10 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console paths.scripts / "addPoshVcpkgToPowershellProfile.ps1"); Checks::exit_success(VCPKG_LINE_INFO); } -#endif Checks::exit_with_message(VCPKG_LINE_INFO, "Unknown parameter %s for integrate", args.command_arguments[0]); +#else + Checks::exit_success(VCPKG_LINE_INFO); +#endif } } -- cgit v1.2.3 From 967765f294f1390a9963e21c2918502e22e64caf Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 24 Apr 2018 22:56:18 -0700 Subject: [osx] Ignore .DS_Store file. Fixes #3306 --- toolsrc/src/vcpkg/paragraphs.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/paragraphs.cpp b/toolsrc/src/vcpkg/paragraphs.cpp index 41ffceec7..77c028937 100644 --- a/toolsrc/src/vcpkg/paragraphs.cpp +++ b/toolsrc/src/vcpkg/paragraphs.cpp @@ -253,6 +253,10 @@ namespace vcpkg::Paragraphs LoadResults ret; auto port_dirs = fs.get_files_non_recursive(ports_dir); Util::sort(port_dirs); + Util::erase_remove_if(port_dirs, [&](auto&& port_dir_entry) { + return fs.is_regular_file(port_dir_entry) && port_dir_entry.filename() == ".DS_Store"; + }); + for (auto&& path : port_dirs) { auto maybe_spgh = try_load_port(fs, path); -- cgit v1.2.3 From f6530368eb31734734c0e1e7ce990c0cb93f0b24 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 25 Apr 2018 00:19:27 -0700 Subject: Remove noexcept from BinaryParagraph() --- toolsrc/include/vcpkg/binaryparagraph.h | 2 +- toolsrc/src/vcpkg/binaryparagraph.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/binaryparagraph.h b/toolsrc/include/vcpkg/binaryparagraph.h index 5ba2fbde3..3315151c6 100644 --- a/toolsrc/include/vcpkg/binaryparagraph.h +++ b/toolsrc/include/vcpkg/binaryparagraph.h @@ -12,7 +12,7 @@ namespace vcpkg /// struct BinaryParagraph { - BinaryParagraph() noexcept; + BinaryParagraph(); explicit BinaryParagraph(std::unordered_map fields); BinaryParagraph(const SourceParagraph& spgh, const Triplet& triplet, const std::string& abi_tag); BinaryParagraph(const SourceParagraph& spgh, const FeatureParagraph& fpgh, const Triplet& triplet); diff --git a/toolsrc/src/vcpkg/binaryparagraph.cpp b/toolsrc/src/vcpkg/binaryparagraph.cpp index 126c7df97..73ca23df1 100644 --- a/toolsrc/src/vcpkg/binaryparagraph.cpp +++ b/toolsrc/src/vcpkg/binaryparagraph.cpp @@ -24,7 +24,7 @@ namespace vcpkg static const std::string DEFAULTFEATURES = "Default-Features"; } - BinaryParagraph::BinaryParagraph() noexcept = default; + BinaryParagraph::BinaryParagraph() = default; BinaryParagraph::BinaryParagraph(std::unordered_map fields) { -- cgit v1.2.3 From 9167511656715c81d01cc87af5db1835f026f5b6 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 25 Apr 2018 18:14:24 -0700 Subject: Fix #3170 issue with /permissive- --- toolsrc/include/tests.utils.h | 40 ++++++++++++++++++++++++++++++++++++---- toolsrc/src/tests.paragraph.cpp | 9 --------- toolsrc/src/tests.utils.cpp | 30 ------------------------------ 3 files changed, 36 insertions(+), 43 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/tests.utils.h b/toolsrc/include/tests.utils.h index 970506663..7f7ec9e88 100644 --- a/toolsrc/include/tests.utils.h +++ b/toolsrc/include/tests.utils.h @@ -12,10 +12,42 @@ namespace Microsoft::VisualStudio::CppUnitTestFramework { - std::wstring ToString(const vcpkg::Dependencies::InstallPlanType& t); - std::wstring ToString(const vcpkg::Dependencies::RequestType& t); - std::wstring ToString(const vcpkg::PackageSpecParseResult& t); - std::wstring ToString(const vcpkg::PackageSpec& t); + template<> + std::wstring ToString(const vcpkg::Dependencies::InstallPlanType& t) + { + switch (t) + { + case vcpkg::Dependencies::InstallPlanType::ALREADY_INSTALLED: return L"ALREADY_INSTALLED"; + case vcpkg::Dependencies::InstallPlanType::BUILD_AND_INSTALL: return L"BUILD_AND_INSTALL"; + case vcpkg::Dependencies::InstallPlanType::EXCLUDED: return L"EXCLUDED"; + case vcpkg::Dependencies::InstallPlanType::UNKNOWN: return L"UNKNOWN"; + default: return ToString(static_cast(t)); + } + } + + template<> + std::wstring ToString(const vcpkg::Dependencies::RequestType& t) + { + switch (t) + { + case vcpkg::Dependencies::RequestType::AUTO_SELECTED: return L"AUTO_SELECTED"; + case vcpkg::Dependencies::RequestType::USER_REQUESTED: return L"USER_REQUESTED"; + case vcpkg::Dependencies::RequestType::UNKNOWN: return L"UNKNOWN"; + default: return ToString(static_cast(t)); + } + } + + template<> + std::wstring ToString(const vcpkg::PackageSpecParseResult& t) + { + return ToString(static_cast(t)); + } + + template<> + std::wstring ToString(const vcpkg::PackageSpec& t) + { + return ToString(t.to_string()); + } } std::unique_ptr make_status_pgh(const char* name, diff --git a/toolsrc/src/tests.paragraph.cpp b/toolsrc/src/tests.paragraph.cpp index dca89bc59..9a56ad9ee 100644 --- a/toolsrc/src/tests.paragraph.cpp +++ b/toolsrc/src/tests.paragraph.cpp @@ -5,15 +5,6 @@ using namespace Microsoft::VisualStudio::CppUnitTestFramework; -namespace Microsoft::VisualStudio::CppUnitTestFramework -{ - template<> - inline std::wstring ToString(const vcpkg::PackageSpecParseResult& t) - { - return ToString(static_cast(t)); - } -} - namespace Strings = vcpkg::Strings; namespace UnitTest1 diff --git a/toolsrc/src/tests.utils.cpp b/toolsrc/src/tests.utils.cpp index a3d8ffc7d..ac391f559 100644 --- a/toolsrc/src/tests.utils.cpp +++ b/toolsrc/src/tests.utils.cpp @@ -5,36 +5,6 @@ using namespace Microsoft::VisualStudio::CppUnitTestFramework; using namespace vcpkg; -namespace Microsoft::VisualStudio::CppUnitTestFramework -{ - std::wstring ToString(const vcpkg::Dependencies::InstallPlanType& t) - { - switch (t) - { - case Dependencies::InstallPlanType::ALREADY_INSTALLED: return L"ALREADY_INSTALLED"; - case Dependencies::InstallPlanType::BUILD_AND_INSTALL: return L"BUILD_AND_INSTALL"; - case Dependencies::InstallPlanType::EXCLUDED: return L"EXCLUDED"; - case Dependencies::InstallPlanType::UNKNOWN: return L"UNKNOWN"; - default: return ToString(static_cast(t)); - } - } - - std::wstring ToString(const vcpkg::Dependencies::RequestType& t) - { - switch (t) - { - case Dependencies::RequestType::AUTO_SELECTED: return L"AUTO_SELECTED"; - case Dependencies::RequestType::USER_REQUESTED: return L"USER_REQUESTED"; - case Dependencies::RequestType::UNKNOWN: return L"UNKNOWN"; - default: return ToString(static_cast(t)); - } - } - - std::wstring ToString(const vcpkg::PackageSpecParseResult& t) { return ToString(static_cast(t)); } - - std::wstring ToString(const vcpkg::PackageSpec& t) { return ToString(t.to_string()); } -} - std::unique_ptr make_status_pgh(const char* name, const char* depends, const char* default_features, -- cgit v1.2.3 From 039abe258b956fe51b5893b3fb2d20661f2a8eb4 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 18 Apr 2018 02:32:37 -0700 Subject: [ci] Don't block binarycaching = false --- toolsrc/src/vcpkg/commands.ci.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/commands.ci.cpp b/toolsrc/src/vcpkg/commands.ci.cpp index 04b42ea00..e2b93dc7e 100644 --- a/toolsrc/src/vcpkg/commands.ci.cpp +++ b/toolsrc/src/vcpkg/commands.ci.cpp @@ -154,8 +154,10 @@ namespace vcpkg::Commands::CI void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) { - Checks::check_exit( - VCPKG_LINE_INFO, GlobalState::g_binary_caching, "The ci command requires binary caching to be enabled."); + if (!GlobalState::g_binary_caching) + { + System::println(System::Color::warning, "Warning: Running ci without binary caching!"); + } const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE); -- cgit v1.2.3 From a9d989ec056246ea320a56ca7d02b161a6fee387 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Sat, 28 Apr 2018 11:26:57 -0700 Subject: [vcpkg-integrate-install] Add vcpkg.path.txt to localappdata for more generic consumption. --- toolsrc/include/vcpkg/userconfig.h | 2 + toolsrc/src/vcpkg/commands.integrate.cpp | 87 ++++++++++++++++++++++---------- toolsrc/src/vcpkg/userconfig.cpp | 11 ++-- 3 files changed, 70 insertions(+), 30 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/userconfig.h b/toolsrc/include/vcpkg/userconfig.h index 63b8e5481..d044f43ef 100644 --- a/toolsrc/include/vcpkg/userconfig.h +++ b/toolsrc/include/vcpkg/userconfig.h @@ -17,4 +17,6 @@ namespace vcpkg void try_write_data(Files::Filesystem& fs) const; }; + + fs::path get_user_dir(); } diff --git a/toolsrc/src/vcpkg/commands.integrate.cpp b/toolsrc/src/vcpkg/commands.integrate.cpp index 2e1750c80..8897ea138 100644 --- a/toolsrc/src/vcpkg/commands.integrate.cpp +++ b/toolsrc/src/vcpkg/commands.integrate.cpp @@ -5,6 +5,7 @@ #include #include #include +#include namespace vcpkg::Commands::Integrate { @@ -156,8 +157,10 @@ namespace vcpkg::Commands::Integrate } #endif + static fs::path get_path_txt_path() { return get_user_dir() / "vcpkg.path.txt"; } + #if defined(_WIN32) - static void integrate_install(const VcpkgPaths& paths) + static void integrate_install_msbuild14(Files::Filesystem& fs, const fs::path& tmp_dir) { static const std::array OLD_SYSTEM_TARGET_FILES = { System::get_program_files_32_bit().value_or_exit(VCPKG_LINE_INFO) / @@ -168,8 +171,6 @@ namespace vcpkg::Commands::Integrate System::get_program_files_32_bit().value_or_exit(VCPKG_LINE_INFO) / "MSBuild/Microsoft.Cpp/v4.0/V140/ImportBefore/Default/vcpkg.system.props"; - 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) { @@ -188,12 +189,6 @@ namespace vcpkg::Commands::Integrate } } } - - std::error_code ec; - const fs::path tmp_dir = paths.buildsystems / "tmp"; - fs.create_directory(paths.buildsystems, ec); - fs.create_directory(tmp_dir, ec); - bool should_install_system = true; const Expected system_wide_file_contents = fs.read_contents(SYSTEM_WIDE_TARGETS_FILE); static const std::regex RE(R"###()###"); @@ -232,24 +227,52 @@ namespace vcpkg::Commands::Integrate "Error: failed to copy targets file to %s", SYSTEM_WIDE_TARGETS_FILE.string()); } + } +#endif - const fs::path appdata_src_path = tmp_dir / "vcpkg.user.targets"; - fs.write_contents(appdata_src_path, - create_appdata_targets_shortcut(paths.buildsystems_msbuild_targets.string())); - auto appdata_dst_path = get_appdata_targets_path(); + static void integrate_install(const VcpkgPaths& paths) + { + auto& fs = paths.get_filesystem(); + +#if defined(_WIN32) + { + std::error_code ec; + const fs::path tmp_dir = paths.buildsystems / "tmp"; + fs.create_directory(paths.buildsystems, ec); + fs.create_directory(tmp_dir, ec); + + integrate_install_msbuild14(fs, tmp_dir); + + const fs::path appdata_src_path = tmp_dir / "vcpkg.user.targets"; + fs.write_contents(appdata_src_path, + create_appdata_targets_shortcut(paths.buildsystems_msbuild_targets.string())); + auto appdata_dst_path = get_appdata_targets_path(); - const auto rc = fs.copy_file(appdata_src_path, appdata_dst_path, fs::copy_options::overwrite_existing, ec); + const 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); + } + } +#endif - if (!rc || ec) + const auto pathtxt = get_path_txt_path(); + std::error_code ec; + fs.write_contents(pathtxt, paths.root.generic_u8string(), ec); + if (ec) { - System::println(System::Color::error, - "Error: Failed to copy file: %s -> %s", - appdata_src_path.string(), - appdata_dst_path.string()); + System::println(System::Color::error, "Error: Failed to write file: %s", pathtxt.string()); Checks::exit_fail(VCPKG_LINE_INFO); } + System::println(System::Color::success, "Applied user-wide integration for this vcpkg root."); const fs::path cmake_toolchain = paths.buildsystems / "vcpkg.cmake"; +#if defined(_WIN32) System::println( R"( All MSBuild C++ projects can now #include any installed libraries. @@ -258,17 +281,29 @@ Installing new libraries will make them instantly available. CMake projects should use: "-DCMAKE_TOOLCHAIN_FILE=%s")", cmake_toolchain.generic_string()); +#else + System::println( + R"( +CMake projects should use: "-DCMAKE_TOOLCHAIN_FILE=%s")", + cmake_toolchain.generic_string()); +#endif Checks::exit_success(VCPKG_LINE_INFO); } static void integrate_remove(Files::Filesystem& fs) { + std::error_code ec; + bool was_deleted = false; + +#if defined(_WIN32) const fs::path path = get_appdata_targets_path(); - std::error_code ec; - const bool was_deleted = fs.remove(path, ec); + was_deleted |= fs.remove(path, ec); + Checks::check_exit(VCPKG_LINE_INFO, !ec, "Error: Unable to remove user-wide integration: %s", ec.message()); +#endif + was_deleted |= fs.remove(get_path_txt_path(), ec); Checks::check_exit(VCPKG_LINE_INFO, !ec, "Error: Unable to remove user-wide integration: %s", ec.message()); if (was_deleted) @@ -282,7 +317,6 @@ CMake projects should use: "-DCMAKE_TOOLCHAIN_FILE=%s")", Checks::exit_success(VCPKG_LINE_INFO); } -#endif #if defined(WIN32) static void integrate_project(const VcpkgPaths& paths) @@ -343,7 +377,8 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console " vcpkg integrate powershell Enable PowerShell Tab-Completion\n"; #else const char* const INTEGRATE_COMMAND_HELPSTRING = - "No user-wide integration methods are available on this platform\n"; + " vcpkg integrate install Make installed packages available user-wide.\n" + " vcpkg integrate remove Remove user-wide integration\n"; #endif namespace Subcommand @@ -373,7 +408,6 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console { Util::unused(args.parse_arguments(COMMAND_STRUCTURE)); -#if defined(_WIN32) if (args.command_arguments[0] == Subcommand::INSTALL) { return integrate_install(paths); @@ -382,6 +416,7 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console { return integrate_remove(paths.get_filesystem()); } +#if defined(_WIN32) if (args.command_arguments[0] == Subcommand::PROJECT) { return integrate_project(paths); @@ -392,10 +427,8 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console paths.scripts / "addPoshVcpkgToPowershellProfile.ps1"); Checks::exit_success(VCPKG_LINE_INFO); } +#endif Checks::exit_with_message(VCPKG_LINE_INFO, "Unknown parameter %s for integrate", args.command_arguments[0]); -#else - Checks::exit_success(VCPKG_LINE_INFO); -#endif } } diff --git a/toolsrc/src/vcpkg/userconfig.cpp b/toolsrc/src/vcpkg/userconfig.cpp index 574a97b64..4945fdaaa 100644 --- a/toolsrc/src/vcpkg/userconfig.cpp +++ b/toolsrc/src/vcpkg/userconfig.cpp @@ -29,16 +29,21 @@ namespace namespace vcpkg { - static fs::path get_config_path() + fs::path get_user_dir() { #if defined(_WIN32) - return get_localappdata() / "vcpkg" / "config"; + return get_localappdata() / "vcpkg"; #else auto maybe_home = System::get_environment_variable("HOME"); - return fs::path(maybe_home.value_or("/var")) / ".vcpkg" / "config"; + return fs::path(maybe_home.value_or("/var")) / ".vcpkg"; #endif } + static fs::path get_config_path() + { + return get_user_dir() / "config"; + } + UserConfig UserConfig::try_read_data(const Files::Filesystem& fs) { UserConfig ret; -- cgit v1.2.3 From 8f0ebdf8d561ef8402db44cd9abb2c912cff276d Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Thu, 3 May 2018 15:03:35 -0700 Subject: [vcpkg] Remove utf16 usage from non-Windows --- toolsrc/include/vcpkg/base/strings.h | 2 ++ toolsrc/src/vcpkg.cpp | 4 +++- toolsrc/src/vcpkg/base/files.cpp | 7 ++++--- toolsrc/src/vcpkg/base/strings.cpp | 12 ++++-------- 4 files changed, 13 insertions(+), 12 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/base/strings.h b/toolsrc/include/vcpkg/base/strings.h index 4cc17bcf4..e165c69da 100644 --- a/toolsrc/include/vcpkg/base/strings.h +++ b/toolsrc/include/vcpkg/base/strings.h @@ -34,9 +34,11 @@ namespace vcpkg::Strings return details::format_internal(fmtstr, to_printf_arg(to_printf_arg(args))...); } +#if defined(_WIN32) std::wstring to_utf16(const CStringView& s); std::string to_utf8(const wchar_t* w); +#endif std::string escape_string(const CStringView& s, char char_to_escape, char escape_char); diff --git a/toolsrc/src/vcpkg.cpp b/toolsrc/src/vcpkg.cpp index 06c99e9a8..ac2eec876 100644 --- a/toolsrc/src/vcpkg.cpp +++ b/toolsrc/src/vcpkg.cpp @@ -70,7 +70,7 @@ static void inner(const VcpkgCmdArguments& args) fs::path vcpkg_root_dir; if (args.vcpkg_root_dir != nullptr) { - vcpkg_root_dir = fs::stdfs::absolute(Strings::to_utf16(*args.vcpkg_root_dir)); + vcpkg_root_dir = fs::stdfs::absolute(fs::u8path(*args.vcpkg_root_dir)); } else { @@ -94,6 +94,8 @@ static void inner(const VcpkgCmdArguments& args) Checks::check_exit(VCPKG_LINE_INFO, !vcpkg_root_dir.empty(), "Error: Could not detect vcpkg-root."); + Debug::println("Using vcpkg-root: %s", vcpkg_root_dir.u8string()); + auto default_vs_path = System::get_environment_variable("VCPKG_DEFAULT_VS_PATH").value_or(""); const Expected expected_paths = VcpkgPaths::create(vcpkg_root_dir, default_vs_path); diff --git a/toolsrc/src/vcpkg/base/files.cpp b/toolsrc/src/vcpkg/base/files.cpp index 1723b467e..0542af1e7 100644 --- a/toolsrc/src/vcpkg/base/files.cpp +++ b/toolsrc/src/vcpkg/base/files.cpp @@ -56,16 +56,17 @@ namespace vcpkg::Files const std::string& filename) const override { fs::path current_dir = starting_dir; - for (; !current_dir.empty(); current_dir = current_dir.parent_path()) + fs::path unix_root = "/"; + for (; !current_dir.empty() && current_dir != unix_root; current_dir = current_dir.parent_path()) { const fs::path candidate = current_dir / filename; if (exists(candidate)) { - break; + return current_dir; } } - return current_dir; + return fs::path(); } virtual std::vector get_files_recursive(const fs::path& dir) const override diff --git a/toolsrc/src/vcpkg/base/strings.cpp b/toolsrc/src/vcpkg/base/strings.cpp index fbc33ca42..48dc5ed09 100644 --- a/toolsrc/src/vcpkg/base/strings.cpp +++ b/toolsrc/src/vcpkg/base/strings.cpp @@ -49,33 +49,29 @@ namespace vcpkg::Strings::details namespace vcpkg::Strings { +#if defined(_WIN32) std::wstring to_utf16(const CStringView& s) { -#if defined(_WIN32) std::wstring output; const size_t size = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, nullptr, 0); if (size == 0) return output; output.resize(size - 1); MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, output.data(), static_cast(size) - 1); return output; -#else - Checks::unreachable(VCPKG_LINE_INFO); -#endif } +#endif +#if defined(_WIN32) std::string to_utf8(const wchar_t* w) { -#if defined(_WIN32) std::string output; const size_t size = WideCharToMultiByte(CP_UTF8, 0, w, -1, nullptr, 0, nullptr, nullptr); if (size == 0) return output; output.resize(size - 1); WideCharToMultiByte(CP_UTF8, 0, w, -1, output.data(), static_cast(size) - 1, nullptr, nullptr); return output; -#else - Checks::unreachable(VCPKG_LINE_INFO); -#endif } +#endif std::string escape_string(const CStringView& s, char char_to_escape, char escape_char) { -- cgit v1.2.3 From 120f444af37f4b6e2cb4205b0ef5f8c6b97e8637 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Thu, 3 May 2018 15:51:02 -0700 Subject: [vcpkg] Add missing debug statement and fix libc++ Filesystem TS issue. --- toolsrc/src/vcpkg/base/system.cpp | 5 ++++- toolsrc/src/vcpkg/build.cpp | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/base/system.cpp b/toolsrc/src/vcpkg/base/system.cpp index d4210fe6d..95c9511f9 100644 --- a/toolsrc/src/vcpkg/base/system.cpp +++ b/toolsrc/src/vcpkg/base/system.cpp @@ -274,8 +274,11 @@ namespace vcpkg::System Debug::println("CreateProcessW() returned %lu", exit_code); return static_cast(exit_code); #else + Debug::println("system(%s)", cmd_line.c_str()); fflush(nullptr); - return system(cmd_line.c_str()); + int rc = system(cmd_line.c_str()); + Debug::println("system() returned %d", rc); + return rc; #endif } diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index 7a9d35667..3616348d6 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -357,7 +357,7 @@ namespace vcpkg::Build { {"CMD", "BUILD"}, {"PORT", config.scf.core_paragraph->name}, - {"CURRENT_PORT_DIR", config.port_dir / "/."}, + {"CURRENT_PORT_DIR", config.port_dir}, {"TARGET_TRIPLET", spec.triplet().canonical_name()}, {"VCPKG_PLATFORM_TOOLSET", toolset.version.c_str()}, {"VCPKG_USE_HEAD_VERSION", -- cgit v1.2.3 From 9265fe76bf3ed53db03eb31cad9be1c7594bfcb3 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 4 May 2018 16:49:07 -0700 Subject: unix_root -> UNIX_ROOT static const --- toolsrc/src/vcpkg/base/files.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/base/files.cpp b/toolsrc/src/vcpkg/base/files.cpp index 0542af1e7..3d96e834b 100644 --- a/toolsrc/src/vcpkg/base/files.cpp +++ b/toolsrc/src/vcpkg/base/files.cpp @@ -55,9 +55,9 @@ namespace vcpkg::Files virtual fs::path find_file_recursively_up(const fs::path& starting_dir, const std::string& filename) const override { + static const fs::path UNIX_ROOT = "/"; fs::path current_dir = starting_dir; - fs::path unix_root = "/"; - for (; !current_dir.empty() && current_dir != unix_root; current_dir = current_dir.parent_path()) + for (; !current_dir.empty() && current_dir != UNIX_ROOT; current_dir = current_dir.parent_path()) { const fs::path candidate = current_dir / filename; if (exists(candidate)) -- cgit v1.2.3 From ab58f531ccf6da9895502cb8ae7bd85b29823d1d Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 4 May 2018 18:14:54 -0700 Subject: git for linux/osx version moved to vcpkgTools.xml --- toolsrc/src/vcpkg/commands.fetch.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/commands.fetch.cpp b/toolsrc/src/vcpkg/commands.fetch.cpp index 1e31e6bc4..a6cfec3f0 100644 --- a/toolsrc/src/vcpkg/commands.fetch.cpp +++ b/toolsrc/src/vcpkg/commands.fetch.cpp @@ -83,7 +83,8 @@ namespace vcpkg::Commands::Fetch right_delim, XML_PATH.generic_string()); - return *result.get(); + auto r = *result.get(); + return Strings::trim(std::move(r)); }; static const std::regex XML_VERSION_REGEX{R"###()###"}; @@ -255,8 +256,8 @@ namespace vcpkg::Commands::Fetch const std::string download_path_part = download_path.u8string() + ".part"; std::error_code ec; fs.remove(download_path_part, ec); - const auto code = System::cmd_execute(Strings::format( - R"(curl -L '%s' --create-dirs --output '%s')", url, download_path_part)); + const auto code = System::cmd_execute( + Strings::format(R"(curl -L '%s' --create-dirs --output '%s')", url, download_path_part)); Checks::check_exit(VCPKG_LINE_INFO, code == 0, "Could not download %s", url); verify_hash(paths, url, download_path_part, sha512); @@ -267,8 +268,13 @@ namespace vcpkg::Commands::Fetch static fs::path fetch_tool(const VcpkgPaths& paths, const std::string& tool_name, const ToolData& tool_data) { const std::array& version = tool_data.version; - const std::string version_as_string = Strings::format("%d.%d.%d", version[0], version[1], version[2]); + Checks::check_exit(VCPKG_LINE_INFO, + !tool_data.url.empty(), + "A suitable version of %s was not found (required v%s) and unable to automatically " + "download a portable one. Please install a newer version of git.", + tool_name, + version_as_string); System::println("A suitable version of %s was not found (required v%s). Downloading portable %s v%s...", tool_name, version_as_string, @@ -401,11 +407,7 @@ namespace vcpkg::Commands::Fetch static fs::path get_git_path(const VcpkgPaths& paths) { -#if defined(_WIN32) static const ToolData TOOL_DATA = parse_tool_data_from_xml(paths, "git"); -#else - static const ToolData TOOL_DATA = ToolData{{2, 7, 4}, ""}; -#endif static const std::string VERSION_CHECK_ARGUMENTS = "--version"; std::vector candidate_paths; -- cgit v1.2.3 From 6c4c7c0d78f4dd71aa75785fbc09004bbfe345ca Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 9 May 2018 19:26:12 -0700 Subject: Improve unsupported toolchain error message --- toolsrc/src/vcpkg/build.cpp | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index 3616348d6..1ed5e744a 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -217,7 +217,12 @@ namespace vcpkg::Build if (it != toolset.supported_architectures.end()) return it->name; } - Checks::exit_with_message(VCPKG_LINE_INFO, "Unsupported toolchain combination %s", target_architecture); + Checks::exit_with_message(VCPKG_LINE_INFO, + "Unsupported toolchain combination. Target was: %s but supported ones were:\n%s", + target_architecture, + Strings::join(",", toolset.supported_architectures, [](const ToolsetArchOption& t) { + return t.name.c_str(); + })); } std::string make_build_env_cmd(const PreBuildInfo& pre_build_info, const Toolset& toolset) @@ -520,8 +525,8 @@ namespace vcpkg::Build System::cmd_execute_clean(Strings::format( R"("%s" x "%s" -o"%s" -y >nul)", seven_zip_exe.u8string(), archive_path.u8string(), pkg_path.u8string())); #else - System::cmd_execute_clean(Strings::format( - R"(unzip -qq "%s" "-d%s")", archive_path.u8string(), pkg_path.u8string())); + System::cmd_execute_clean( + Strings::format(R"(unzip -qq "%s" "-d%s")", archive_path.u8string(), pkg_path.u8string())); #endif } @@ -537,11 +542,10 @@ namespace vcpkg::Build #if defined(_WIN32) auto&& seven_zip_exe = paths.get_tool_exe(Tools::SEVEN_ZIP); - System::cmd_execute_clean(Strings::format( - R"("%s" a "%s" "%s\*" >nul)", - seven_zip_exe.u8string(), - tmp_archive_path.u8string(), - paths.package_dir(spec).u8string())); + System::cmd_execute_clean(Strings::format(R"("%s" a "%s" "%s\*" >nul)", + seven_zip_exe.u8string(), + tmp_archive_path.u8string(), + paths.package_dir(spec).u8string())); #else System::cmd_execute_clean(Strings::format( R"(cd '%s' && zip --quiet -r '%s' *)", paths.package_dir(spec).u8string(), tmp_archive_path.u8string())); -- cgit v1.2.3 From 29d04b8b4005f5e2bfe61ccdc7a93d5c6c8a13d9 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 11 May 2018 21:46:55 -0700 Subject: Update CHANGELOG and bump version to v0.0.111 --- toolsrc/VERSION.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/VERSION.txt b/toolsrc/VERSION.txt index ca3fbdad8..c1c986b7c 100644 --- a/toolsrc/VERSION.txt +++ b/toolsrc/VERSION.txt @@ -1 +1 @@ -"0.0.110" \ No newline at end of file +"0.0.111" \ No newline at end of file -- cgit v1.2.3 From 1b0682a39e1143660c3d5aa371f66591a64e8a5d Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Sat, 5 May 2018 04:23:19 -0700 Subject: [vcpkg] Significantly reduce usage of powershell. Reduce console font switching bug --- toolsrc/include/vcpkg/base/system.h | 2 + toolsrc/include/vcpkg/commands.h | 4 +- toolsrc/include/vcpkg/vcpkgpaths.h | 1 + toolsrc/src/vcpkg/base/checks.cpp | 2 + toolsrc/src/vcpkg/base/system.cpp | 19 +- toolsrc/src/vcpkg/build.cpp | 14 +- toolsrc/src/vcpkg/commands.cpp | 2 +- toolsrc/src/vcpkg/commands.fetch.cpp | 509 ++++++++++++++++++++++++++--------- toolsrc/src/vcpkg/commands.hash.cpp | 7 +- toolsrc/src/vcpkg/export.cpp | 2 - toolsrc/src/vcpkg/vcpkgpaths.cpp | 9 +- toolsrc/vcpkg.sln | 5 +- 12 files changed, 422 insertions(+), 154 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/base/system.h b/toolsrc/include/vcpkg/base/system.h index 0d089276f..cf9c78868 100644 --- a/toolsrc/include/vcpkg/base/system.h +++ b/toolsrc/include/vcpkg/base/system.h @@ -47,6 +47,7 @@ namespace vcpkg::System ExitCodeAndOutput cmd_execute_and_capture_output(const CStringView cmd_line); +#if defined(_WIN32) void powershell_execute(const std::string& title, const fs::path& script_path, const std::vector& parameters = {}); @@ -54,6 +55,7 @@ namespace vcpkg::System std::string powershell_execute_and_capture_output(const std::string& title, const fs::path& script_path, const std::vector& parameters = {}); +#endif enum class Color { diff --git a/toolsrc/include/vcpkg/commands.h b/toolsrc/include/vcpkg/commands.h index 6d29b7960..708151dce 100644 --- a/toolsrc/include/vcpkg/commands.h +++ b/toolsrc/include/vcpkg/commands.h @@ -132,14 +132,14 @@ namespace vcpkg::Commands namespace Hash { std::string get_string_hash(const std::string& s, const std::string& hash_type); - std::string get_file_hash(const VcpkgPaths& paths, const fs::path& path, const std::string& hash_type); + std::string get_file_hash(const Files::Filesystem& fs, const fs::path& path, const std::string& hash_type); void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); } namespace Fetch { - std::vector find_toolset_instances(const VcpkgPaths& paths); + std::vector find_toolset_instances_prefered_first(const VcpkgPaths& paths); fs::path get_tool_path(const VcpkgPaths& paths, const std::string& tool); void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); } diff --git a/toolsrc/include/vcpkg/vcpkgpaths.h b/toolsrc/include/vcpkg/vcpkgpaths.h index 9c8f2911a..a3c90fd33 100644 --- a/toolsrc/include/vcpkg/vcpkgpaths.h +++ b/toolsrc/include/vcpkg/vcpkgpaths.h @@ -66,6 +66,7 @@ namespace vcpkg fs::path triplets; fs::path scripts; + fs::path tools; fs::path buildsystems; fs::path buildsystems_msbuild_targets; diff --git a/toolsrc/src/vcpkg/base/checks.cpp b/toolsrc/src/vcpkg/base/checks.cpp index d96cb98ff..2ac5f9a15 100644 --- a/toolsrc/src/vcpkg/base/checks.cpp +++ b/toolsrc/src/vcpkg/base/checks.cpp @@ -16,6 +16,8 @@ namespace vcpkg::Checks const auto elapsed_us = GlobalState::timer.lock()->microseconds(); + Debug::println("Exiting after %d us", static_cast(elapsed_us)); + auto metrics = Metrics::g_metrics.lock(); metrics->track_metric("elapsed_us", elapsed_us); GlobalState::debugging = false; diff --git a/toolsrc/src/vcpkg/base/system.cpp b/toolsrc/src/vcpkg/base/system.cpp index 95c9511f9..4da4548af 100644 --- a/toolsrc/src/vcpkg/base/system.cpp +++ b/toolsrc/src/vcpkg/base/system.cpp @@ -155,6 +155,7 @@ namespace vcpkg::System int cmd_execute_clean(const CStringView cmd_line, const std::unordered_map& extra_env) { + auto timer = Chrono::ElapsedTimer::create_started(); #if defined(_WIN32) static const std::string SYSTEM_ROOT = get_environment_variable("SystemRoot").value_or_exit(VCPKG_LINE_INFO); static const std::string SYSTEM_32 = SYSTEM_ROOT + R"(\system32)"; @@ -271,7 +272,7 @@ namespace vcpkg::System DWORD exit_code = 0; GetExitCodeProcess(process_info.hProcess, &exit_code); - Debug::println("CreateProcessW() returned %lu", exit_code); + Debug::println("CreateProcessW() returned %lu after %d us", exit_code, static_cast(timer.microseconds())); return static_cast(exit_code); #else Debug::println("system(%s)", cmd_line.c_str()); @@ -369,13 +370,20 @@ namespace vcpkg::System #endif } +#if defined(_WIN32) void powershell_execute(const std::string& title, const fs::path& script_path, const std::vector& parameters) { + SetConsoleCP(437); + SetConsoleOutputCP(437); + const std::string cmd = make_powershell_cmd(script_path, parameters); const int rc = System::cmd_execute(cmd); + SetConsoleCP(CP_UTF8); + SetConsoleOutputCP(CP_UTF8); + if (rc) { System::println(Color::error, @@ -394,14 +402,22 @@ namespace vcpkg::System Checks::exit_with_code(VCPKG_LINE_INFO, rc); } } +#endif +#if defined(_WIN32) std::string powershell_execute_and_capture_output(const std::string& title, const fs::path& script_path, const std::vector& parameters) { + SetConsoleCP(437); + SetConsoleOutputCP(437); + const std::string cmd = make_powershell_cmd(script_path, parameters); auto rc = System::cmd_execute_and_capture_output(cmd); + SetConsoleCP(CP_UTF8); + SetConsoleOutputCP(CP_UTF8); + if (rc.exit_code) { System::println(Color::error, @@ -433,6 +449,7 @@ namespace vcpkg::System return rc.output; } +#endif void println() { putchar('\n'); } diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index 1ed5e744a..b8ccb15bf 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -461,9 +461,9 @@ namespace vcpkg::Build abi_tag_entries.insert(abi_tag_entries.end(), dependency_abis.begin(), dependency_abis.end()); abi_tag_entries.emplace_back( - AbiEntry{"portfile", Commands::Hash::get_file_hash(paths, config.port_dir / "portfile.cmake", "SHA1")}); + AbiEntry{"portfile", Commands::Hash::get_file_hash(fs, config.port_dir / "portfile.cmake", "SHA1")}); abi_tag_entries.emplace_back( - AbiEntry{"control", Commands::Hash::get_file_hash(paths, config.port_dir / "CONTROL", "SHA1")}); + AbiEntry{"control", Commands::Hash::get_file_hash(fs, config.port_dir / "CONTROL", "SHA1")}); abi_tag_entries.emplace_back(AbiEntry{"triplet", pre_build_info.triplet_abi_tag}); @@ -498,7 +498,7 @@ namespace vcpkg::Build const auto abi_file_path = paths.buildtrees / name / (triplet.canonical_name() + ".vcpkg_abi_info.txt"); fs.write_contents(abi_file_path, full_abi_info); - return AbiTagAndFile{Commands::Hash::get_file_hash(paths, abi_file_path, "SHA1"), abi_file_path}; + return AbiTagAndFile{Commands::Hash::get_file_hash(fs, abi_file_path, "SHA1"), abi_file_path}; } System::println( @@ -783,14 +783,12 @@ namespace vcpkg::Build { return it_hash->second; } - auto hash = Commands::Hash::get_file_hash(paths, triplet_file_path, "SHA1"); + auto hash = Commands::Hash::get_file_hash(paths.get_filesystem(), triplet_file_path, "SHA1"); s_hash_cache.emplace(triplet_file_path, hash); return hash; } - else - { - return std::string(); - } + + return std::string(); }(); const auto cmd_launch_cmake = System::make_cmake_cmd(cmake_exe_path, diff --git a/toolsrc/src/vcpkg/commands.cpp b/toolsrc/src/vcpkg/commands.cpp index 8b6ffb3d7..09da57705 100644 --- a/toolsrc/src/vcpkg/commands.cpp +++ b/toolsrc/src/vcpkg/commands.cpp @@ -43,7 +43,7 @@ namespace vcpkg::Commands {"portsdiff", &PortsDiff::perform_and_exit}, {"autocomplete", &Autocomplete::perform_and_exit}, {"hash", &Hash::perform_and_exit}, - // {"fetch", &Fetch::perform_and_exit}, + {"fetch", &Fetch::perform_and_exit}, }; return t; } diff --git a/toolsrc/src/vcpkg/commands.fetch.cpp b/toolsrc/src/vcpkg/commands.fetch.cpp index a6cfec3f0..d50d13c59 100644 --- a/toolsrc/src/vcpkg/commands.fetch.cpp +++ b/toolsrc/src/vcpkg/commands.fetch.cpp @@ -1,6 +1,7 @@ #include "pch.h" #include +#include #include #include #include @@ -19,6 +20,7 @@ namespace vcpkg::Commands::Fetch fs::path exe_path; std::string url; fs::path download_path; + bool is_archive; fs::path tool_dir_path; std::string sha512; }; @@ -41,20 +43,85 @@ namespace vcpkg::Commands::Fetch return result; } - static Optional extract_string_between_delimiters(const std::string& input, - const std::string& left_delim, - const std::string& right_delim, - const size_t& starting_offset = 0) + struct VcpkgStringRange { - const size_t from = input.find(left_delim, starting_offset); - if (from == std::string::npos) return nullopt; + VcpkgStringRange() = default; - const size_t substring_start = from + left_delim.length(); + // Implicit by design + VcpkgStringRange(const std::string& s) : begin(s.cbegin()), end(s.cend()) {} - const size_t to = input.find(right_delim, substring_start); - if (from == std::string::npos) return nullopt; + VcpkgStringRange(const std::string::const_iterator begin, const std::string::const_iterator end) + : begin(begin), end(end) + { + } + + std::string::const_iterator begin; + std::string::const_iterator end; + + std::string to_string() const { return std::string(this->begin, this->end); } + }; + + static std::vector find_all_enclosed(const VcpkgStringRange& input, + const std::string& left_delim, + const std::string& right_delim) + { + std::string::const_iterator it_left = input.begin; + std::string::const_iterator it_right = input.begin; + + std::vector output; - return input.substr(substring_start, to - substring_start); + while (true) + { + it_left = std::search(it_right, input.end, left_delim.cbegin(), left_delim.cend()); + if (it_left == input.end) break; + + it_left += left_delim.length(); + + it_right = std::search(it_left, input.end, right_delim.cbegin(), right_delim.cend()); + if (it_right == input.end) break; + + output.emplace_back(it_left, it_right); + + ++it_right; + } + + return output; + } + + static VcpkgStringRange find_exactly_one_enclosed(const VcpkgStringRange& input, + const std::string& left_tag, + const std::string& right_tag) + { + std::vector result = find_all_enclosed(input, left_tag, right_tag); + Checks::check_exit(VCPKG_LINE_INFO, + result.size() == 1, + "Found %d sets of %s.*%s but expected exactly 1, in block:\n%s", + result.size(), + left_tag, + right_tag, + input); + return std::move(result.front()); + } + + static Optional find_at_most_one_enclosed(const VcpkgStringRange& input, + const std::string& left_tag, + const std::string& right_tag) + { + std::vector result = find_all_enclosed(input, left_tag, right_tag); + Checks::check_exit(VCPKG_LINE_INFO, + result.size() <= 1, + "Found %d sets of %s.*%s but expected at most 1, in block:\n%s", + result.size(), + left_tag, + right_tag, + input); + + if (result.empty()) + { + return nullopt; + } + + return result.front(); } static ToolData parse_tool_data_from_xml(const VcpkgPaths& paths, const std::string& tool) @@ -72,21 +139,6 @@ namespace vcpkg::Commands::Fetch #if defined(_WIN32) || defined(__APPLE__) || defined(__linux__) static const std::string XML_VERSION = "2"; static const fs::path XML_PATH = paths.scripts / "vcpkgTools.xml"; - - const auto get_string_inside_tags = - [](const std::string& input, const std::string& left_delim, const std::string& right_delim) -> std::string { - Optional result = extract_string_between_delimiters(input, left_delim, right_delim); - Checks::check_exit(VCPKG_LINE_INFO, - result.has_value(), - "Could not find tag <%s>.*<%s> in %s", - left_delim, - right_delim, - XML_PATH.generic_string()); - - auto r = *result.get(); - return Strings::trim(std::move(r)); - }; - static const std::regex XML_VERSION_REGEX{R"###()###"}; static const std::string XML = paths.get_filesystem().read_contents(XML_PATH).value_or_exit(VCPKG_LINE_INFO); std::smatch match_xml_version; @@ -112,14 +164,14 @@ namespace vcpkg::Commands::Fetch tool, XML_PATH.generic_string()); - const std::string tool_data = get_string_inside_tags(XML, match_tool_entry[0], R"()"); - - const std::string version_as_string = get_string_inside_tags(tool_data, "", R"()"); + const std::string tool_data = find_exactly_one_enclosed(XML, match_tool_entry[0], "").to_string(); + const std::string version_as_string = + find_exactly_one_enclosed(tool_data, "", "").to_string(); const std::string exe_relative_path = - get_string_inside_tags(tool_data, "", R"()"); - const std::string url = get_string_inside_tags(tool_data, "", R"()"); - const std::string sha512 = get_string_inside_tags(tool_data, "", R"()"); - auto archive_name = extract_string_between_delimiters(tool_data, "", R"()"); + find_exactly_one_enclosed(tool_data, "", "").to_string(); + const std::string url = find_exactly_one_enclosed(tool_data, "", "").to_string(); + const std::string sha512 = find_exactly_one_enclosed(tool_data, "", "").to_string(); + auto archive_name = find_at_most_one_enclosed(tool_data, "", ""); const Optional> version = parse_version_string(version_as_string); Checks::check_exit(VCPKG_LINE_INFO, @@ -129,13 +181,14 @@ namespace vcpkg::Commands::Fetch version_as_string); const std::string tool_dir_name = Strings::format("%s-%s-%s", tool, version_as_string, OS_STRING); - const fs::path tool_dir_path = paths.downloads / "tools" / tool_dir_name; + const fs::path tool_dir_path = paths.tools / tool_dir_name; const fs::path exe_path = tool_dir_path / exe_relative_path; return ToolData{*version.get(), exe_path, url, - paths.downloads / archive_name.value_or(exe_relative_path), + paths.downloads / archive_name.value_or(exe_relative_path).to_string(), + archive_name.has_value(), tool_dir_path, sha512}; #endif @@ -163,51 +216,87 @@ namespace vcpkg::Commands::Fetch actual_version[2] >= expected_version[2])); } - static Optional find_if_has_equal_or_greater_version(const std::vector& candidate_paths, + static Optional find_if_has_equal_or_greater_version(Files::Filesystem& fs, + const std::vector& candidate_paths, const std::string& version_check_arguments, const std::array& expected_version) { - auto it = Util::find_if(candidate_paths, [&](const fs::path& p) { + const auto it = Util::find_if(candidate_paths, [&](const fs::path& p) { + if (!fs.exists(p)) return false; const std::string cmd = Strings::format(R"("%s" %s)", p.u8string(), version_check_arguments); return exists_and_has_equal_or_greater_version(cmd, expected_version); }); if (it != candidate_paths.cend()) { - return std::move(*it); + return *it; } return nullopt; } - static std::vector keep_data_lines(const std::string& data_blob) - { - static const std::regex DATA_LINE_REGEX(R"(::(.+?)(?=::))"); - - std::vector data_lines; - - const std::sregex_iterator it(data_blob.cbegin(), data_blob.cend(), DATA_LINE_REGEX); - const std::sregex_iterator end; - for (std::sregex_iterator i = it; i != end; ++i) - { - const std::smatch match = *i; - data_lines.push_back(match[1].str()); - } - - return data_lines; - } - -#if !defined(_WIN32) static void extract_archive(const VcpkgPaths& paths, const fs::path& archive, const fs::path& to_path) { Files::Filesystem& fs = paths.get_filesystem(); const fs::path to_path_partial = to_path.u8string() + ".partial"; std::error_code ec; + fs.remove_all(to_path, ec); fs.remove_all(to_path_partial, ec); fs.create_directories(to_path_partial, ec); - const auto ext = archive.extension(); +#if defined(_WIN32) + if (ext == ".nupkg") + { + static bool recursion_limiter_sevenzip_old = false; + Checks::check_exit(VCPKG_LINE_INFO, !recursion_limiter_sevenzip_old); + recursion_limiter_sevenzip_old = true; + const auto nuget_exe = get_tool_path(paths, Tools::NUGET); + + const std::string stem = archive.stem().u8string(); + // assuming format of [name].[version in the form d.d.d] + // This assumption may not always hold + std::smatch match; + const bool has_match = std::regex_match(stem, match, std::regex{R"###(^(.+)\.(\d+\.\d+\.\d+)$)###"}); + Checks::check_exit(VCPKG_LINE_INFO, + has_match, + "Could not deduce nuget id and version from filename: %s", + archive.u8string()); + + const std::string nugetid = match[1]; + const std::string version = match[2]; + + const auto code_and_output = System::cmd_execute_and_capture_output(Strings::format( + R"("%s" install %s -Version %s -OutputDirectory "%s" -Source "%s" -nocache -DirectDownload -NonInteractive -ForceEnglishOutput -PackageSaveMode nuspec)", + nuget_exe.u8string(), + nugetid, + version, + to_path_partial.u8string(), + paths.downloads.u8string())); + + Checks::check_exit(VCPKG_LINE_INFO, + code_and_output.exit_code == 0, + "Failed to extract '%s' with message:\n%s", + archive.u8string(), + code_and_output.output); + recursion_limiter_sevenzip_old = false; + } + else + { + static bool recursion_limiter_sevenzip = false; + Checks::check_exit(VCPKG_LINE_INFO, !recursion_limiter_sevenzip); + recursion_limiter_sevenzip = true; + const auto seven_zip = get_tool_path(paths, Tools::SEVEN_ZIP); + const auto code_and_output = System::cmd_execute_and_capture_output(Strings::format( + R"("%s" x "%s" -o"%s" -y)", seven_zip.u8string(), archive.u8string(), to_path_partial.u8string())); + Checks::check_exit(VCPKG_LINE_INFO, + code_and_output.exit_code == 0, + "7zip failed while extracting '%s' with message:\n%s", + archive.u8string(), + code_and_output.output); + recursion_limiter_sevenzip = false; + } +#else if (ext == ".gz" && ext.extension() != ".tar") { const auto code = System::cmd_execute( @@ -224,16 +313,23 @@ namespace vcpkg::Commands::Fetch { Checks::exit_with_message(VCPKG_LINE_INFO, "Unexpected archive extension: %s", ext.u8string()); } +#endif - fs.rename(to_path_partial, to_path); + fs.rename(to_path_partial, to_path, ec); + Checks::check_exit(VCPKG_LINE_INFO, + !ec, + "Failed to do post-extract rename-in-place.\nfs.rename(%s, %s, %s)", + to_path_partial.u8string(), + to_path.u8string(), + ec.message()); } - static void verify_hash(const VcpkgPaths& paths, + static void verify_hash(const Files::Filesystem& fs, const std::string& url, const fs::path& path, const std::string& sha512) { - const std::string actual_hash = Hash::get_file_hash(paths, path, "SHA512"); + const std::string actual_hash = Hash::get_file_hash(fs, path, "SHA512"); Checks::check_exit(VCPKG_LINE_INFO, sha512 == actual_hash, "File does not have the expected hash:\n" @@ -247,24 +343,119 @@ namespace vcpkg::Commands::Fetch actual_hash); } - static void download_file(const VcpkgPaths& paths, +#if defined(_WIN32) + static void winhttp_download_file(Files::Filesystem& fs, + CStringView target_file_path, + CStringView hostname, + CStringView url_path) + { + // Make sure the directories are present, otherwise fopen_s fails + const auto dir = fs::path(target_file_path.c_str()).parent_path(); + std::error_code ec; + fs.create_directories(dir, ec); + Checks::check_exit(VCPKG_LINE_INFO, !ec, "Could not create directories %s", dir.u8string()); + + FILE* f = nullptr; + const errno_t err = fopen_s(&f, target_file_path.c_str(), "wb"); + Checks::check_exit(VCPKG_LINE_INFO, + !err, + "Could not download https://%s%s. Failed to open file %s. Error code was %s", + hostname, + url_path, + target_file_path, + std::to_string(err)); + + auto hSession = WinHttpOpen( + L"vcpkg/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); + Checks::check_exit(VCPKG_LINE_INFO, hSession, "WinHttpOpen() failed: %d", GetLastError()); + + // Use Windows 10 defaults on Windows 7 + DWORD secure_protocols(WINHTTP_FLAG_SECURE_PROTOCOL_SSL3 | WINHTTP_FLAG_SECURE_PROTOCOL_TLS1 | + WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_1 | WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2); + WinHttpSetOption(hSession, WINHTTP_OPTION_SECURE_PROTOCOLS, &secure_protocols, sizeof(secure_protocols)); + + // Specify an HTTP server. + auto hConnect = WinHttpConnect(hSession, Strings::to_utf16(hostname).c_str(), INTERNET_DEFAULT_HTTPS_PORT, 0); + Checks::check_exit(VCPKG_LINE_INFO, hConnect, "WinHttpConnect() failed: %d", GetLastError()); + + // Create an HTTP request handle. + auto hRequest = WinHttpOpenRequest(hConnect, + L"GET", + Strings::to_utf16(url_path).c_str(), + nullptr, + WINHTTP_NO_REFERER, + WINHTTP_DEFAULT_ACCEPT_TYPES, + WINHTTP_FLAG_SECURE); + Checks::check_exit(VCPKG_LINE_INFO, hRequest, "WinHttpOpenRequest() failed: %d", GetLastError()); + + // Send a request. + auto bResults = + WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0); + Checks::check_exit(VCPKG_LINE_INFO, bResults, "WinHttpSendRequest() failed: %d", GetLastError()); + + // End the request. + bResults = WinHttpReceiveResponse(hRequest, NULL); + Checks::check_exit(VCPKG_LINE_INFO, bResults, "WinHttpReceiveResponse() failed: %d", GetLastError()); + + std::vector buf; + + size_t total_downloaded_size = 0; + DWORD dwSize = 0; + do + { + DWORD downloaded_size = 0; + bResults = WinHttpQueryDataAvailable(hRequest, &dwSize); + Checks::check_exit(VCPKG_LINE_INFO, bResults, "WinHttpQueryDataAvailable() failed: %d", GetLastError()); + + if (buf.size() < dwSize) buf.resize(dwSize * 2); + + bResults = WinHttpReadData(hRequest, (LPVOID)buf.data(), dwSize, &downloaded_size); + Checks::check_exit(VCPKG_LINE_INFO, bResults, "WinHttpReadData() failed: %d", GetLastError()); + fwrite(buf.data(), 1, downloaded_size, f); + + total_downloaded_size += downloaded_size; + } while (dwSize > 0); + + WinHttpCloseHandle(hSession); + WinHttpCloseHandle(hConnect); + WinHttpCloseHandle(hRequest); + fflush(f); + fclose(f); + } +#endif + + static void download_file(Files::Filesystem& fs, const std::string& url, const fs::path& download_path, const std::string& sha512) { - Files::Filesystem& fs = paths.get_filesystem(); const std::string download_path_part = download_path.u8string() + ".part"; std::error_code ec; + fs.remove(download_path, ec); fs.remove(download_path_part, ec); +#if defined(_WIN32) + auto url_no_proto = url.substr(8); // drop https:// + auto path_begin = Util::find(url_no_proto, '/'); + std::string hostname(url_no_proto.begin(), path_begin); + std::string path(path_begin, url_no_proto.end()); + + winhttp_download_file(fs, download_path_part.c_str(), hostname, path); +#else const auto code = System::cmd_execute( Strings::format(R"(curl -L '%s' --create-dirs --output '%s')", url, download_path_part)); Checks::check_exit(VCPKG_LINE_INFO, code == 0, "Could not download %s", url); +#endif - verify_hash(paths, url, download_path_part, sha512); - fs.rename(download_path_part, download_path); + verify_hash(fs, url, download_path_part, sha512); + fs.rename(download_path_part, download_path, ec); + Checks::check_exit(VCPKG_LINE_INFO, + !ec, + "Failed to do post-download rename-in-place.\nfs.rename(%s, %s, %s)", + download_path_part, + download_path.u8string(), + ec.message()); } -#endif static fs::path fetch_tool(const VcpkgPaths& paths, const std::string& tool_name, const ToolData& tool_data) { const std::array& version = tool_data.version; @@ -280,50 +471,37 @@ namespace vcpkg::Commands::Fetch version_as_string, tool_name, version_as_string); -#if defined(_WIN32) - const fs::path script = paths.scripts / "fetchtool.ps1"; - const std::string title = Strings::format( - "Fetching %s version %s (No sufficient installed version was found)", tool_name, version_as_string); - const System::PowershellParameter tool_param("tool", tool_name); - const std::string output = System::powershell_execute_and_capture_output(title, script, {tool_param}); - - const std::vector tool_path = keep_data_lines(output); - Checks::check_exit(VCPKG_LINE_INFO, tool_path.size() == 1, "Expected tool path, but got %s", output); - - const fs::path actual_downloaded_path = Strings::trim(std::string{tool_path.at(0)}); - const fs::path& expected_downloaded_path = tool_data.exe_path; - std::error_code ec; - const auto eq = fs::stdfs::equivalent(expected_downloaded_path, actual_downloaded_path, ec); - Checks::check_exit(VCPKG_LINE_INFO, - eq && !ec, - "Expected tool downloaded path to be %s, but was %s", - expected_downloaded_path.u8string(), - actual_downloaded_path.u8string()); - return actual_downloaded_path; -#else - const auto& fs = paths.get_filesystem(); + auto& fs = paths.get_filesystem(); if (!fs.exists(tool_data.download_path)) { System::println("Downloading %s...", tool_name); - download_file(paths, tool_data.url, tool_data.download_path, tool_data.sha512); + download_file(fs, tool_data.url, tool_data.download_path, tool_data.sha512); System::println("Downloading %s... done.", tool_name); } else { - verify_hash(paths, tool_data.url, tool_data.download_path, tool_data.sha512); + verify_hash(fs, tool_data.url, tool_data.download_path, tool_data.sha512); } - System::println("Extracting %s...", tool_name); - extract_archive(paths, tool_data.download_path, tool_data.tool_dir_path); - System::println("Extracting %s... done.", tool_name); + if (tool_data.is_archive) + { + System::println("Extracting %s...", tool_name); + extract_archive(paths, tool_data.download_path, tool_data.tool_dir_path); + System::println("Extracting %s... done.", tool_name); + } + else + { + std::error_code ec; + fs.create_directories(tool_data.exe_path.parent_path(), ec); + fs.rename(tool_data.download_path, tool_data.exe_path, ec); + } Checks::check_exit(VCPKG_LINE_INFO, fs.exists(tool_data.exe_path), - "Expected %s to exist after extracting", - tool_data.exe_path); + "Expected %s to exist after fetching", + tool_data.exe_path.u8string()); return tool_data.exe_path; -#endif } static fs::path get_cmake_path(const VcpkgPaths& paths) @@ -345,8 +523,8 @@ namespace vcpkg::Commands::Fetch const auto& program_files_32_bit = System::get_program_files_32_bit(); if (const auto pf = program_files_32_bit.get()) candidate_paths.push_back(*pf / "CMake" / "bin" / "cmake.exe"); - const Optional path = - find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, TOOL_DATA.version); + const Optional path = find_if_has_equal_or_greater_version( + paths.get_filesystem(), candidate_paths, VERSION_CHECK_ARGUMENTS, TOOL_DATA.version); if (const auto p = path.get()) { return *p; @@ -378,7 +556,8 @@ namespace vcpkg::Commands::Fetch const std::vector from_path = Files::find_from_PATH("ninja"); candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); - auto path = find_if_has_equal_or_greater_version(candidate_paths, "--version", TOOL_DATA.version); + auto path = find_if_has_equal_or_greater_version( + paths.get_filesystem(), candidate_paths, "--version", TOOL_DATA.version); if (const auto p = path.get()) { return *p; @@ -396,7 +575,8 @@ namespace vcpkg::Commands::Fetch const std::vector from_path = Files::find_from_PATH("nuget"); candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); - auto path = find_if_has_equal_or_greater_version(candidate_paths, "", TOOL_DATA.version); + auto path = + find_if_has_equal_or_greater_version(paths.get_filesystem(), candidate_paths, "", TOOL_DATA.version); if (const auto p = path.get()) { return *p; @@ -422,8 +602,8 @@ namespace vcpkg::Commands::Fetch const auto& program_files_32_bit = System::get_program_files_32_bit(); if (const auto pf = program_files_32_bit.get()) candidate_paths.push_back(*pf / "git" / "cmd" / "git.exe"); - const Optional path = - find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, TOOL_DATA.version); + const Optional path = find_if_has_equal_or_greater_version( + paths.get_filesystem(), candidate_paths, VERSION_CHECK_ARGUMENTS, TOOL_DATA.version); if (const auto p = path.get()) { return *p; @@ -448,8 +628,8 @@ namespace vcpkg::Commands::Fetch // candidate_paths.push_back(fs::path(System::get_environment_variable("HOMEDRIVE").value_or("C:")) / "Qt" / // "QtIFW-3.1.0" / "bin" / "installerbase.exe"); - const Optional path = - find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, TOOL_DATA.version); + const Optional path = find_if_has_equal_or_greater_version( + paths.get_filesystem(), candidate_paths, VERSION_CHECK_ARGUMENTS, TOOL_DATA.version); if (const auto p = path.get()) { return *p; @@ -460,48 +640,114 @@ namespace vcpkg::Commands::Fetch struct VisualStudioInstance { + enum class ReleaseType + { + STABLE, + PRERELEASE, + LEGACY + }; + + static bool prefered_first_comparator(const VisualStudioInstance& left, const VisualStudioInstance& right) + { + const auto get_preference_weight = [](const ReleaseType& type) -> int { + switch (type) + { + case ReleaseType::STABLE: return 3; + case ReleaseType::PRERELEASE: return 2; + case ReleaseType::LEGACY: return 1; + default: Checks::unreachable(VCPKG_LINE_INFO); + } + }; + + if (left.release_type != right.release_type) + { + return get_preference_weight(left.release_type) > get_preference_weight(right.release_type); + } + + return left.version > right.version; + } + + VisualStudioInstance(fs::path&& root_path, std::string&& version, const ReleaseType& release_type) + : root_path(std::move(root_path)), version(std::move(version)), release_type(release_type) + { + } + fs::path root_path; std::string version; - std::string release_type; - std::string preference_weight; // Mostly unused, just for verification that order is as intended + ReleaseType release_type; std::string major_version() const { return version.substr(0, 2); } }; static std::vector get_visual_studio_instances(const VcpkgPaths& paths) { - const fs::path script = paths.scripts / "findVisualStudioInstallationInstances.ps1"; - const std::string output = - System::powershell_execute_and_capture_output("Detecting Visual Studio instances", script); + const auto& fs = paths.get_filesystem(); + + const auto& program_files_32_bit = System::get_program_files_32_bit().value_or_exit(VCPKG_LINE_INFO); + const fs::path vswhere_exe = program_files_32_bit / "Microsoft Visual Studio" / "Installer" / "vswhere.exe"; + Checks::check_exit( + VCPKG_LINE_INFO, fs.exists(vswhere_exe), "Could not locate vswhere at %s", vswhere_exe.u8string()); + + const auto code_and_output = System::cmd_execute_and_capture_output( + Strings::format(R"("%s" -prerelease -legacy -products * -format xml)", vswhere_exe.u8string())); - const std::vector instances_as_strings = keep_data_lines(output); Checks::check_exit(VCPKG_LINE_INFO, - !instances_as_strings.empty(), - "Could not detect any Visual Studio instances.\n" - "Powershell script:\n" - " %s\n" - "returned:\n" - "%s", - script.generic_string(), - output); + code_and_output.exit_code == 0, + "Running vswhere.exe failed with message:\n%s", + code_and_output.output); + + const auto& xml_as_string = code_and_output.output; + + const auto instance_entries = find_all_enclosed(xml_as_string, "", ""); std::vector instances; - for (const std::string& instance_as_string : instances_as_strings) + for (const VcpkgStringRange& instance : instance_entries) { - const std::vector split = Strings::split(instance_as_string, "::"); - Checks::check_exit(VCPKG_LINE_INFO, - split.size() == 4, - "Invalid Visual Studio instance format.\n" - "Expected: PreferenceWeight::ReleaseType::Version::PathToVisualStudio\n" - "Actual : %s\n", - instance_as_string); - instances.push_back({split.at(3), split.at(2), split.at(1), split.at(0)}); + auto maybe_is_prerelease = find_at_most_one_enclosed(instance, "", ""); + + VisualStudioInstance::ReleaseType release_type = VisualStudioInstance::ReleaseType::LEGACY; + if (auto p = maybe_is_prerelease.get()) + { + auto s = p->to_string(); + if (s == "0") + release_type = VisualStudioInstance::ReleaseType::STABLE; + else if (s == "1") + release_type = VisualStudioInstance::ReleaseType::PRERELEASE; + else + Checks::unreachable(VCPKG_LINE_INFO); + } + + instances.emplace_back( + find_exactly_one_enclosed(instance, "", "").to_string(), + find_exactly_one_enclosed(instance, "", "").to_string(), + release_type); } + const auto append_if_has_cl = [&](fs::path&& path_root) { + const auto cl_exe = path_root / "VC" / "bin" / "cl.exe"; + const auto vcvarsall_bat = path_root / "VC" / "vcvarsall.bat"; + + if (fs.exists(cl_exe) && fs.exists(vcvarsall_bat)) + instances.emplace_back(std::move(path_root), "14.0", VisualStudioInstance::ReleaseType::LEGACY); + }; + + auto maybe_vs140comntools = System::get_environment_variable("vs140comntools"); + if (const auto path_as_string = maybe_vs140comntools.get()) + { + // We want lexically_normal(), but it is not available + // Correct root path might be 2 or 3 levels up, depending on if the path has trailing backslash. Try both. + auto common7_tools = fs::path{*path_as_string}; + append_if_has_cl(fs::path{*path_as_string}.parent_path().parent_path()); + append_if_has_cl(fs::path{*path_as_string}.parent_path().parent_path().parent_path()); + } + + append_if_has_cl(program_files_32_bit / "Microsoft Visual Studio 14.0"); + return instances; } - std::vector find_toolset_instances(const VcpkgPaths& paths) +#if defined(_WIN32) + std::vector find_toolset_instances_prefered_first(const VcpkgPaths& paths) { using CPU = System::CPUArchitecture; @@ -513,12 +759,14 @@ namespace vcpkg::Commands::Fetch std::vector found_toolsets; std::vector excluded_toolsets; - const std::vector vs_instances = get_visual_studio_instances(paths); - const bool v140_is_available = Util::find_if(vs_instances, [&](const VisualStudioInstance& vs_instance) { + const SortedVector sorted{get_visual_studio_instances(paths), + VisualStudioInstance::prefered_first_comparator}; + + const bool v140_is_available = Util::find_if(sorted, [&](const VisualStudioInstance& vs_instance) { return vs_instance.major_version() == "14"; - }) != vs_instances.cend(); + }) != sorted.end(); - for (const VisualStudioInstance& vs_instance : vs_instances) + for (const VisualStudioInstance& vs_instance : sorted) { const std::string major_version = vs_instance.major_version(); if (major_version == "15") @@ -672,6 +920,7 @@ namespace vcpkg::Commands::Fetch return found_toolsets; } +#endif fs::path get_tool_path(const VcpkgPaths& paths, const std::string& tool) { diff --git a/toolsrc/src/vcpkg/commands.hash.cpp b/toolsrc/src/vcpkg/commands.hash.cpp index 1f709f87b..d7d653ca3 100644 --- a/toolsrc/src/vcpkg/commands.hash.cpp +++ b/toolsrc/src/vcpkg/commands.hash.cpp @@ -154,10 +154,9 @@ namespace vcpkg::Commands::Hash }; } - std::string get_file_hash(const VcpkgPaths& paths, const fs::path& path, const std::string& hash_type) + std::string get_file_hash(const Files::Filesystem& fs, const fs::path& path, const std::string& hash_type) { - Checks::check_exit( - VCPKG_LINE_INFO, paths.get_filesystem().exists(path), "File %s does not exist", path.u8string()); + Checks::check_exit(VCPKG_LINE_INFO, fs.exists(path), "File %s does not exist", path.u8string()); return BCryptHasher{hash_type}.hash_file(path); } @@ -239,7 +238,7 @@ namespace vcpkg::Commands::Hash const fs::path file_to_hash = args.command_arguments[0]; const std::string algorithm = args.command_arguments.size() == 2 ? args.command_arguments[1] : "SHA512"; - const std::string hash = get_file_hash(paths, file_to_hash, algorithm); + const std::string hash = get_file_hash(paths.get_filesystem(), file_to_hash, algorithm); System::println(hash); Checks::exit_success(VCPKG_LINE_INFO); } diff --git a/toolsrc/src/vcpkg/export.cpp b/toolsrc/src/vcpkg/export.cpp index 152252018..b13140de2 100644 --- a/toolsrc/src/vcpkg/export.cpp +++ b/toolsrc/src/vcpkg/export.cpp @@ -227,8 +227,6 @@ namespace vcpkg::Export {fs::path{"scripts"} / "buildsystems" / "vcpkg.cmake"}, {fs::path{"scripts"} / "cmake" / "vcpkg_get_windows_sdk.cmake"}, {fs::path{"scripts"} / "getWindowsSDK.ps1"}, - {fs::path{"scripts"} / "getProgramFilesPlatformBitness.ps1"}, - {fs::path{"scripts"} / "getProgramFiles32bit.ps1"}, {fs::path{"scripts"} / "VcpkgPowershellUtils.ps1"}, }; diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index 0903c2d76..caf09f526 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -39,6 +39,7 @@ namespace vcpkg paths.triplets = paths.root / "triplets"; paths.scripts = paths.root / "scripts"; + paths.tools = paths.downloads / "tools"; paths.buildsystems = paths.scripts / "buildsystems"; paths.buildsystems_msbuild_targets = paths.buildsystems / "msbuild" / "vcpkg.targets"; @@ -113,9 +114,11 @@ namespace vcpkg return external_toolset; } - // Invariant: toolsets are non-empty and sorted with newest at back() +#if !defined(_WIN32) + Checks::exit_with_message(VCPKG_LINE_INFO, "Cannot build windows triplets from non-windows."); +#else const std::vector& vs_toolsets = - this->toolsets.get_lazy([this]() { return Commands::Fetch::find_toolset_instances(*this); }); + this->toolsets.get_lazy([this]() { return Commands::Fetch::find_toolset_instances_prefered_first(*this); }); std::vector candidates = Util::element_pointers(vs_toolsets); const auto tsv = prebuildinfo.platform_toolset.get(); @@ -159,6 +162,8 @@ namespace vcpkg Checks::check_exit(VCPKG_LINE_INFO, !candidates.empty(), "No suitable Visual Studio instances were found"); return *candidates.front(); + +#endif } Files::Filesystem& VcpkgPaths::get_filesystem() const { return Files::get_real_filesystem(); } diff --git a/toolsrc/vcpkg.sln b/toolsrc/vcpkg.sln index eae73a760..792d39906 100644 --- a/toolsrc/vcpkg.sln +++ b/toolsrc/vcpkg.sln @@ -15,11 +15,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "scripts", "scripts", "{F589 ProjectSection(SolutionItems) = preProject ..\scripts\bootstrap.ps1 = ..\scripts\bootstrap.ps1 ..\scripts\fetchDependency.ps1 = ..\scripts\fetchDependency.ps1 - ..\scripts\findAnyMSBuildWithCppPlatformToolset.ps1 = ..\scripts\findAnyMSBuildWithCppPlatformToolset.ps1 - ..\scripts\findVisualStudioInstallationInstances.ps1 = ..\scripts\findVisualStudioInstallationInstances.ps1 + ..\scripts\getVisualStudioInstances.ps1 = ..\scripts\getVisualStudioInstances.ps1 ..\scripts\get_triplet_environment.cmake = ..\scripts\get_triplet_environment.cmake - ..\scripts\getProgramFiles32bit.ps1 = ..\scripts\getProgramFiles32bit.ps1 - ..\scripts\getProgramFilesPlatformBitness.ps1 = ..\scripts\getProgramFilesPlatformBitness.ps1 ..\scripts\getWindowsSDK.ps1 = ..\scripts\getWindowsSDK.ps1 ..\scripts\internalCI.ps1 = ..\scripts\internalCI.ps1 ..\scripts\ports.cmake = ..\scripts\ports.cmake -- cgit v1.2.3 From 8bb28d0de4903075643a1683cad3c4e5ad89920a Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 15 May 2018 23:41:31 -0700 Subject: Fix signature of hashing function --- toolsrc/src/vcpkg/commands.hash.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/commands.hash.cpp b/toolsrc/src/vcpkg/commands.hash.cpp index d7d653ca3..0c7aa72c4 100644 --- a/toolsrc/src/vcpkg/commands.hash.cpp +++ b/toolsrc/src/vcpkg/commands.hash.cpp @@ -201,11 +201,10 @@ namespace vcpkg::Commands::Hash return split[0]; } - std::string get_file_hash(const VcpkgPaths& paths, const fs::path& path, const std::string& hash_type) + std::string get_file_hash(const Files::Filesystem& fs, const fs::path& path, const std::string& hash_type) { const std::string digest_size = get_digest_size(hash_type); - Checks::check_exit( - VCPKG_LINE_INFO, paths.get_filesystem().exists(path), "File %s does not exist", path.u8string()); + Checks::check_exit(VCPKG_LINE_INFO, fs.exists(path), "File %s does not exist", path.u8string()); const std::string cmd_line = Strings::format(R"(shasum -a %s "%s")", digest_size, path.u8string()); return run_shasum_and_post_process(cmd_line); } -- cgit v1.2.3 From f4c6fe61d0ec08d6911f914d0f57ab525a08ec0b Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 16 May 2018 15:11:55 -0700 Subject: [vcpkg.exe] Don't error if vswhere.exe is not found --- toolsrc/src/vcpkg/commands.fetch.cpp | 68 ++++++++++++++++++------------------ 1 file changed, 34 insertions(+), 34 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/commands.fetch.cpp b/toolsrc/src/vcpkg/commands.fetch.cpp index d50d13c59..c46031665 100644 --- a/toolsrc/src/vcpkg/commands.fetch.cpp +++ b/toolsrc/src/vcpkg/commands.fetch.cpp @@ -682,45 +682,43 @@ namespace vcpkg::Commands::Fetch static std::vector get_visual_studio_instances(const VcpkgPaths& paths) { const auto& fs = paths.get_filesystem(); + std::vector instances; const auto& program_files_32_bit = System::get_program_files_32_bit().value_or_exit(VCPKG_LINE_INFO); - const fs::path vswhere_exe = program_files_32_bit / "Microsoft Visual Studio" / "Installer" / "vswhere.exe"; - Checks::check_exit( - VCPKG_LINE_INFO, fs.exists(vswhere_exe), "Could not locate vswhere at %s", vswhere_exe.u8string()); - - const auto code_and_output = System::cmd_execute_and_capture_output( - Strings::format(R"("%s" -prerelease -legacy -products * -format xml)", vswhere_exe.u8string())); - - Checks::check_exit(VCPKG_LINE_INFO, - code_and_output.exit_code == 0, - "Running vswhere.exe failed with message:\n%s", - code_and_output.output); - const auto& xml_as_string = code_and_output.output; - - const auto instance_entries = find_all_enclosed(xml_as_string, "", ""); - - std::vector instances; - for (const VcpkgStringRange& instance : instance_entries) + // Instances from vswhere + const fs::path vswhere_exe = program_files_32_bit / "Microsoft Visual Studio" / "Installer" / "vswhere.exe"; + if (fs.exists(vswhere_exe)) { - auto maybe_is_prerelease = find_at_most_one_enclosed(instance, "", ""); + const auto code_and_output = System::cmd_execute_and_capture_output( + Strings::format(R"("%s" -prerelease -legacy -products * -format xml)", vswhere_exe.u8string())); + Checks::check_exit(VCPKG_LINE_INFO, + code_and_output.exit_code == 0, + "Running vswhere.exe failed with message:\n%s", + code_and_output.output); - VisualStudioInstance::ReleaseType release_type = VisualStudioInstance::ReleaseType::LEGACY; - if (auto p = maybe_is_prerelease.get()) + const auto instance_entries = find_all_enclosed(code_and_output.output, "", ""); + for (const VcpkgStringRange& instance : instance_entries) { - auto s = p->to_string(); - if (s == "0") - release_type = VisualStudioInstance::ReleaseType::STABLE; - else if (s == "1") - release_type = VisualStudioInstance::ReleaseType::PRERELEASE; - else - Checks::unreachable(VCPKG_LINE_INFO); - } + auto maybe_is_prerelease = find_at_most_one_enclosed(instance, "", ""); - instances.emplace_back( - find_exactly_one_enclosed(instance, "", "").to_string(), - find_exactly_one_enclosed(instance, "", "").to_string(), - release_type); + VisualStudioInstance::ReleaseType release_type = VisualStudioInstance::ReleaseType::LEGACY; + if (const auto p = maybe_is_prerelease.get()) + { + const auto s = p->to_string(); + if (s == "0") + release_type = VisualStudioInstance::ReleaseType::STABLE; + else if (s == "1") + release_type = VisualStudioInstance::ReleaseType::PRERELEASE; + else + Checks::unreachable(VCPKG_LINE_INFO); + } + + instances.emplace_back( + find_exactly_one_enclosed(instance, "", "").to_string(), + find_exactly_one_enclosed(instance, "", "").to_string(), + release_type); + } } const auto append_if_has_cl = [&](fs::path&& path_root) { @@ -731,8 +729,9 @@ namespace vcpkg::Commands::Fetch instances.emplace_back(std::move(path_root), "14.0", VisualStudioInstance::ReleaseType::LEGACY); }; - auto maybe_vs140comntools = System::get_environment_variable("vs140comntools"); - if (const auto path_as_string = maybe_vs140comntools.get()) + // VS2015 instance from environment variable + auto maybe_vs140_comntools = System::get_environment_variable("vs140comntools"); + if (const auto path_as_string = maybe_vs140_comntools.get()) { // We want lexically_normal(), but it is not available // Correct root path might be 2 or 3 levels up, depending on if the path has trailing backslash. Try both. @@ -741,6 +740,7 @@ namespace vcpkg::Commands::Fetch append_if_has_cl(fs::path{*path_as_string}.parent_path().parent_path().parent_path()); } + // VS2015 instance from Program Files append_if_has_cl(program_files_32_bit / "Microsoft Visual Studio 14.0"); return instances; -- cgit v1.2.3 From f69cce7051e4404e19fe8c049c23c4678fe8b3d4 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 16 May 2018 15:30:26 -0700 Subject: Fix typo --- toolsrc/include/vcpkg/commands.h | 2 +- toolsrc/src/vcpkg/commands.fetch.cpp | 6 +++--- toolsrc/src/vcpkg/vcpkgpaths.cpp | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/commands.h b/toolsrc/include/vcpkg/commands.h index 708151dce..21e77aa52 100644 --- a/toolsrc/include/vcpkg/commands.h +++ b/toolsrc/include/vcpkg/commands.h @@ -139,7 +139,7 @@ namespace vcpkg::Commands namespace Fetch { - std::vector find_toolset_instances_prefered_first(const VcpkgPaths& paths); + std::vector find_toolset_instances_preferred_first(const VcpkgPaths& paths); fs::path get_tool_path(const VcpkgPaths& paths, const std::string& tool); void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); } diff --git a/toolsrc/src/vcpkg/commands.fetch.cpp b/toolsrc/src/vcpkg/commands.fetch.cpp index c46031665..c88ae9dd0 100644 --- a/toolsrc/src/vcpkg/commands.fetch.cpp +++ b/toolsrc/src/vcpkg/commands.fetch.cpp @@ -647,7 +647,7 @@ namespace vcpkg::Commands::Fetch LEGACY }; - static bool prefered_first_comparator(const VisualStudioInstance& left, const VisualStudioInstance& right) + static bool preferred_first_comparator(const VisualStudioInstance& left, const VisualStudioInstance& right) { const auto get_preference_weight = [](const ReleaseType& type) -> int { switch (type) @@ -747,7 +747,7 @@ namespace vcpkg::Commands::Fetch } #if defined(_WIN32) - std::vector find_toolset_instances_prefered_first(const VcpkgPaths& paths) + std::vector find_toolset_instances_preferred_first(const VcpkgPaths& paths) { using CPU = System::CPUArchitecture; @@ -760,7 +760,7 @@ namespace vcpkg::Commands::Fetch std::vector excluded_toolsets; const SortedVector sorted{get_visual_studio_instances(paths), - VisualStudioInstance::prefered_first_comparator}; + VisualStudioInstance::preferred_first_comparator}; const bool v140_is_available = Util::find_if(sorted, [&](const VisualStudioInstance& vs_instance) { return vs_instance.major_version() == "14"; diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index caf09f526..9b74bea74 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -117,8 +117,8 @@ namespace vcpkg #if !defined(_WIN32) Checks::exit_with_message(VCPKG_LINE_INFO, "Cannot build windows triplets from non-windows."); #else - const std::vector& vs_toolsets = - this->toolsets.get_lazy([this]() { return Commands::Fetch::find_toolset_instances_prefered_first(*this); }); + const std::vector& vs_toolsets = this->toolsets.get_lazy( + [this]() { return Commands::Fetch::find_toolset_instances_preferred_first(*this); }); std::vector candidates = Util::element_pointers(vs_toolsets); const auto tsv = prebuildinfo.platform_toolset.get(); -- cgit v1.2.3 From 950a3d00493a90fed9bfc629bfbf9144da689d3f Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 16 May 2018 18:59:25 -0700 Subject: [vcpkg edit] Fix whitespace-in-path issue --- toolsrc/src/vcpkg/commands.edit.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/commands.edit.cpp b/toolsrc/src/vcpkg/commands.edit.cpp index b6324565c..2569c2cea 100644 --- a/toolsrc/src/vcpkg/commands.edit.cpp +++ b/toolsrc/src/vcpkg/commands.edit.cpp @@ -78,7 +78,8 @@ namespace vcpkg::Commands::Edit if (Util::Sets::contains(options.switches, OPTION_BUILDTREES)) { return Util::fmap(ports, [&](const std::string& port_name) -> std::string { - return (paths.buildtrees / port_name).u8string(); + const auto buildtrees_current_dir = paths.buildtrees / port_name; + return Strings::format(R"###("%s")###", buildtrees_current_dir.u8string()); }); } -- cgit v1.2.3 From df28620ba6d5e11dbb492a89a042ece1810d8519 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 16 May 2018 19:05:13 -0700 Subject: Update CHANGELOG and bump version to v0.0.112 --- toolsrc/VERSION.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/VERSION.txt b/toolsrc/VERSION.txt index c1c986b7c..3bf1a6f6f 100644 --- a/toolsrc/VERSION.txt +++ b/toolsrc/VERSION.txt @@ -1 +1 @@ -"0.0.111" \ No newline at end of file +"0.0.112" \ No newline at end of file -- cgit v1.2.3 From b31cfb8b87d7548c10b2b04b7298c753b0af1521 Mon Sep 17 00:00:00 2001 From: Sztergbaum Roman Date: Fri, 18 May 2018 21:46:34 +0200 Subject: fix compilation error on clang 6.0/APPLE (#3520) * fix compilation error on clang 6.0/APPLE * Update system.cpp --- toolsrc/src/vcpkg/base/system.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/base/system.cpp b/toolsrc/src/vcpkg/base/system.cpp index 4da4548af..73a92f2da 100644 --- a/toolsrc/src/vcpkg/base/system.cpp +++ b/toolsrc/src/vcpkg/base/system.cpp @@ -40,8 +40,9 @@ namespace vcpkg::System if (bytes == 0) std::abort(); return fs::path(buf, buf + bytes); #elif defined(__APPLE__) - uint32_t size = 1024 * 32; - char buf[size] = {}; + static constexpr const uint32_t buff_size = 1024 * 32; + uint32_t size = buff_size; + char buf[buff_size] = {}; bool result = _NSGetExecutablePath(buf, &size); Checks::check_exit(VCPKG_LINE_INFO, result != -1, "Could not determine current executable path."); std::unique_ptr canonicalPath(realpath(buf, NULL)); -- cgit v1.2.3 From 9e4196d49524d41959e84f27b4080a0ec2cb37e6 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Sat, 19 May 2018 17:50:51 -0700 Subject: Merge getWindowsSDK into bootstrap.ps1 --- toolsrc/vcpkg.sln | 1 - 1 file changed, 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/vcpkg.sln b/toolsrc/vcpkg.sln index 792d39906..0ca40c6cd 100644 --- a/toolsrc/vcpkg.sln +++ b/toolsrc/vcpkg.sln @@ -17,7 +17,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "scripts", "scripts", "{F589 ..\scripts\fetchDependency.ps1 = ..\scripts\fetchDependency.ps1 ..\scripts\getVisualStudioInstances.ps1 = ..\scripts\getVisualStudioInstances.ps1 ..\scripts\get_triplet_environment.cmake = ..\scripts\get_triplet_environment.cmake - ..\scripts\getWindowsSDK.ps1 = ..\scripts\getWindowsSDK.ps1 ..\scripts\internalCI.ps1 = ..\scripts\internalCI.ps1 ..\scripts\ports.cmake = ..\scripts\ports.cmake ..\scripts\SHA256Hash.ps1 = ..\scripts\SHA256Hash.ps1 -- cgit v1.2.3 From 555fa8d7cc25f409fea9626383dfc38c5d5db6b4 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Sat, 19 May 2018 17:54:12 -0700 Subject: Merge getVisualStudioInstances into bootstrap.ps1 --- toolsrc/vcpkg.sln | 1 - 1 file changed, 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/vcpkg.sln b/toolsrc/vcpkg.sln index 0ca40c6cd..3d12aafaf 100644 --- a/toolsrc/vcpkg.sln +++ b/toolsrc/vcpkg.sln @@ -15,7 +15,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "scripts", "scripts", "{F589 ProjectSection(SolutionItems) = preProject ..\scripts\bootstrap.ps1 = ..\scripts\bootstrap.ps1 ..\scripts\fetchDependency.ps1 = ..\scripts\fetchDependency.ps1 - ..\scripts\getVisualStudioInstances.ps1 = ..\scripts\getVisualStudioInstances.ps1 ..\scripts\get_triplet_environment.cmake = ..\scripts\get_triplet_environment.cmake ..\scripts\internalCI.ps1 = ..\scripts\internalCI.ps1 ..\scripts\ports.cmake = ..\scripts\ports.cmake -- cgit v1.2.3 From a739df905c129eb13d7060419a78f5a693974b63 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Sat, 19 May 2018 17:54:50 -0700 Subject: Merge VcpkgPowershellUtils into bootstrap.ps1 --- toolsrc/vcpkg.sln | 1 - 1 file changed, 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/vcpkg.sln b/toolsrc/vcpkg.sln index 3d12aafaf..8155e0882 100644 --- a/toolsrc/vcpkg.sln +++ b/toolsrc/vcpkg.sln @@ -19,7 +19,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "scripts", "scripts", "{F589 ..\scripts\internalCI.ps1 = ..\scripts\internalCI.ps1 ..\scripts\ports.cmake = ..\scripts\ports.cmake ..\scripts\SHA256Hash.ps1 = ..\scripts\SHA256Hash.ps1 - ..\scripts\VcpkgPowershellUtils.ps1 = ..\scripts\VcpkgPowershellUtils.ps1 EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "cmake", "cmake", "{A0122231-04D5-420B-81CA-7960946E5E65}" -- cgit v1.2.3 From 8549a095a8707c2aa38e9ee1642bef2cf0a90d81 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Sat, 19 May 2018 17:55:15 -0700 Subject: Remove stray entries --- toolsrc/src/vcpkg/export.cpp | 2 -- toolsrc/vcpkg.sln | 2 -- 2 files changed, 4 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/export.cpp b/toolsrc/src/vcpkg/export.cpp index b13140de2..c444cf3d0 100644 --- a/toolsrc/src/vcpkg/export.cpp +++ b/toolsrc/src/vcpkg/export.cpp @@ -226,8 +226,6 @@ namespace vcpkg::Export {fs::path{"scripts"} / "buildsystems" / "msbuild" / "vcpkg.targets"}, {fs::path{"scripts"} / "buildsystems" / "vcpkg.cmake"}, {fs::path{"scripts"} / "cmake" / "vcpkg_get_windows_sdk.cmake"}, - {fs::path{"scripts"} / "getWindowsSDK.ps1"}, - {fs::path{"scripts"} / "VcpkgPowershellUtils.ps1"}, }; for (const fs::path& file : integration_files_relative_to_root) diff --git a/toolsrc/vcpkg.sln b/toolsrc/vcpkg.sln index 8155e0882..9a998e214 100644 --- a/toolsrc/vcpkg.sln +++ b/toolsrc/vcpkg.sln @@ -14,11 +14,9 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "scripts", "scripts", "{F5893B21-EA71-4432-84D6-5FB0E0461A2A}" ProjectSection(SolutionItems) = preProject ..\scripts\bootstrap.ps1 = ..\scripts\bootstrap.ps1 - ..\scripts\fetchDependency.ps1 = ..\scripts\fetchDependency.ps1 ..\scripts\get_triplet_environment.cmake = ..\scripts\get_triplet_environment.cmake ..\scripts\internalCI.ps1 = ..\scripts\internalCI.ps1 ..\scripts\ports.cmake = ..\scripts\ports.cmake - ..\scripts\SHA256Hash.ps1 = ..\scripts\SHA256Hash.ps1 EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "cmake", "cmake", "{A0122231-04D5-420B-81CA-7960946E5E65}" -- cgit v1.2.3 From 285c69b0faa220311f3ccc60febaa2e7c6d87bb1 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Sat, 19 May 2018 19:01:10 -0700 Subject: [c++] Condense powershell helper code into the remaining single usage `vcpkg integrate powershell` uses it --- toolsrc/include/vcpkg/base/system.h | 19 ------ toolsrc/src/vcpkg/base/system.cpp | 106 ------------------------------- toolsrc/src/vcpkg/commands.integrate.cpp | 42 +++++++++++- 3 files changed, 39 insertions(+), 128 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/base/system.h b/toolsrc/include/vcpkg/base/system.h index cf9c78868..813d600cd 100644 --- a/toolsrc/include/vcpkg/base/system.h +++ b/toolsrc/include/vcpkg/base/system.h @@ -25,15 +25,6 @@ namespace vcpkg::System const fs::path& cmake_script, const std::vector& pass_variables); - struct PowershellParameter - { - PowershellParameter(const CStringView varname, const char* varvalue); - PowershellParameter(const CStringView varname, const std::string& varvalue); - PowershellParameter(const CStringView varname, const fs::path& path); - - std::string s; - }; - struct ExitCodeAndOutput { int exit_code; @@ -47,16 +38,6 @@ namespace vcpkg::System ExitCodeAndOutput cmd_execute_and_capture_output(const CStringView cmd_line); -#if defined(_WIN32) - void powershell_execute(const std::string& title, - const fs::path& script_path, - const std::vector& parameters = {}); - - std::string powershell_execute_and_capture_output(const std::string& title, - const fs::path& script_path, - const std::vector& parameters = {}); -#endif - enum class Color { success = 10, diff --git a/toolsrc/src/vcpkg/base/system.cpp b/toolsrc/src/vcpkg/base/system.cpp index 73a92f2da..1aa12d0a4 100644 --- a/toolsrc/src/vcpkg/base/system.cpp +++ b/toolsrc/src/vcpkg/base/system.cpp @@ -129,31 +129,6 @@ namespace vcpkg::System R"("%s" %s -P "%s")", cmake_exe.u8string(), cmd_cmake_pass_variables, cmake_script.generic_u8string()); } - PowershellParameter::PowershellParameter(const CStringView varname, const char* varvalue) - : s(Strings::format(R"(-%s '%s')", varname, varvalue)) - { - } - - PowershellParameter::PowershellParameter(const CStringView varname, const std::string& varvalue) - : PowershellParameter(varname, varvalue.c_str()) - { - } - - PowershellParameter::PowershellParameter(const CStringView varname, const fs::path& path) - : PowershellParameter(varname, path.generic_u8string()) - { - } - - static std::string make_powershell_cmd(const fs::path& script_path, - const std::vector& parameters) - { - const std::string args = Strings::join(" ", parameters, [](auto&& v) { return v.s; }); - - // TODO: switch out ExecutionPolicy Bypass with "Remove Mark Of The Web" code and restore RemoteSigned - return Strings::format( - R"(powershell -NoProfile -ExecutionPolicy Bypass -Command "& {& '%s' %s}")", script_path.u8string(), args); - } - int cmd_execute_clean(const CStringView cmd_line, const std::unordered_map& extra_env) { auto timer = Chrono::ElapsedTimer::create_started(); @@ -371,87 +346,6 @@ namespace vcpkg::System #endif } -#if defined(_WIN32) - void powershell_execute(const std::string& title, - const fs::path& script_path, - const std::vector& parameters) - { - SetConsoleCP(437); - SetConsoleOutputCP(437); - - const std::string cmd = make_powershell_cmd(script_path, parameters); - const int rc = System::cmd_execute(cmd); - - SetConsoleCP(CP_UTF8); - SetConsoleOutputCP(CP_UTF8); - - if (rc) - { - System::println(Color::error, - "%s\n" - "Could not run:\n" - " '%s'", - title, - script_path.generic_string()); - - { - auto locked_metrics = Metrics::g_metrics.lock(); - locked_metrics->track_property("error", "powershell script failed"); - locked_metrics->track_property("title", title); - } - - Checks::exit_with_code(VCPKG_LINE_INFO, rc); - } - } -#endif - -#if defined(_WIN32) - std::string powershell_execute_and_capture_output(const std::string& title, - const fs::path& script_path, - const std::vector& parameters) - { - SetConsoleCP(437); - SetConsoleOutputCP(437); - - const std::string cmd = make_powershell_cmd(script_path, parameters); - auto rc = System::cmd_execute_and_capture_output(cmd); - - SetConsoleCP(CP_UTF8); - SetConsoleOutputCP(CP_UTF8); - - if (rc.exit_code) - { - System::println(Color::error, - "%s\n" - "Could not run:\n" - " '%s'\n" - "Error message was:\n" - " %s", - title, - script_path.generic_string(), - rc.output); - - { - auto locked_metrics = Metrics::g_metrics.lock(); - locked_metrics->track_property("error", "powershell script failed"); - locked_metrics->track_property("title", title); - } - - Checks::exit_with_code(VCPKG_LINE_INFO, rc.exit_code); - } - - // Remove newline from all output. - // Powershell returns newlines when it hits the column count of the console. - // For example, this is 80 in cmd on Windows 7. If the expected output is longer than 80 lines, we get - // newlines in-between the data. - // To solve this, we design our interaction with powershell to not depend on newlines, - // and then strip all newlines here. - rc.output = Strings::replace_all(std::move(rc.output), "\n", ""); - - return rc.output; - } -#endif - void println() { putchar('\n'); } void print(const CStringView message) { fputs(message.c_str(), stdout); } diff --git a/toolsrc/src/vcpkg/commands.integrate.cpp b/toolsrc/src/vcpkg/commands.integrate.cpp index 8897ea138..82172e363 100644 --- a/toolsrc/src/vcpkg/commands.integrate.cpp +++ b/toolsrc/src/vcpkg/commands.integrate.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include namespace vcpkg::Commands::Integrate @@ -368,6 +369,43 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console } #endif +#if defined(_WIN32) + static void integrate_powershell(const VcpkgPaths& paths) + { + static constexpr StringLiteral TITLE = "PowerShell Tab-Completion"; + const fs::path script_path = paths.scripts / "addPoshVcpkgToPowershellProfile.ps1"; + + // Console font corruption workaround + SetConsoleCP(437); + SetConsoleOutputCP(437); + + const std::string cmd = Strings::format( + R"(powershell -NoProfile -ExecutionPolicy Bypass -Command "& {& '%s' %s}")", script_path.u8string(), ""); + const int rc = System::cmd_execute(cmd); + + SetConsoleCP(CP_UTF8); + SetConsoleOutputCP(CP_UTF8); + + if (rc) + { + System::println(System::Color::error, + "%s\n" + "Could not run:\n" + " '%s'", + TITLE, + script_path.generic_string()); + + { + auto locked_metrics = Metrics::g_metrics.lock(); + locked_metrics->track_property("error", "powershell script failed"); + locked_metrics->track_property("title", TITLE); + } + } + + Checks::exit_with_code(VCPKG_LINE_INFO, rc); + } +#endif + #if defined(_WIN32) const char* const INTEGRATE_COMMAND_HELPSTRING = " vcpkg integrate install Make installed packages available user-wide. Requires admin privileges on " @@ -423,9 +461,7 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console } if (args.command_arguments[0] == Subcommand::POWERSHELL) { - System::powershell_execute("PowerShell Tab-Completion", - paths.scripts / "addPoshVcpkgToPowershellProfile.ps1"); - Checks::exit_success(VCPKG_LINE_INFO); + return integrate_powershell(paths); } #endif -- cgit v1.2.3 From b07568da4100d8be5d54feb1b1ccf65d0a5c0c3f Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Sat, 19 May 2018 19:29:31 -0700 Subject: Update CHANGELOG and bump version to v0.0.113 --- toolsrc/VERSION.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc') diff --git a/toolsrc/VERSION.txt b/toolsrc/VERSION.txt index 3bf1a6f6f..6833d4427 100644 --- a/toolsrc/VERSION.txt +++ b/toolsrc/VERSION.txt @@ -1 +1 @@ -"0.0.112" \ No newline at end of file +"0.0.113" \ No newline at end of file -- cgit v1.2.3 From 78e4d07e84afc0f1ab23179534aa08bf6e194b98 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Tue, 22 May 2018 03:37:40 -0700 Subject: [vcpkg] Improve CMake messages to account for case-sensitive filesystems. Improve CMake messages to display shortest targets first (which are hopefully the "public" ones). Also, fix bug in StringLiteral. --- toolsrc/include/vcpkg/base/stringliteral.h | 3 ++- toolsrc/include/vcpkg/base/strings.h | 2 ++ toolsrc/src/vcpkg/base/strings.cpp | 6 +++++ toolsrc/src/vcpkg/commands.cache.cpp | 2 +- toolsrc/src/vcpkg/commands.list.cpp | 2 +- toolsrc/src/vcpkg/install.cpp | 43 +++++++++++++++++++++++------- 6 files changed, 46 insertions(+), 12 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/include/vcpkg/base/stringliteral.h b/toolsrc/include/vcpkg/base/stringliteral.h index c07f04cec..9970adc2a 100644 --- a/toolsrc/include/vcpkg/base/stringliteral.h +++ b/toolsrc/include/vcpkg/base/stringliteral.h @@ -7,7 +7,8 @@ namespace vcpkg struct StringLiteral { template - constexpr StringLiteral(const char (&str)[N]) : m_size(N), m_cstr(str) + constexpr StringLiteral(const char (&str)[N]) + : m_size(N - 1) /* -1 here accounts for the null byte at the end*/, m_cstr(str) { } diff --git a/toolsrc/include/vcpkg/base/strings.h b/toolsrc/include/vcpkg/base/strings.h index e165c69da..4b39b0a28 100644 --- a/toolsrc/include/vcpkg/base/strings.h +++ b/toolsrc/include/vcpkg/base/strings.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include @@ -53,6 +54,7 @@ namespace vcpkg::Strings std::string ascii_to_uppercase(std::string s); bool case_insensitive_ascii_starts_with(const std::string& s, const std::string& pattern); + bool ends_with(const std::string& s, StringLiteral pattern); template std::string join(const char* delimiter, const Container& v, Transformer transformer) diff --git a/toolsrc/src/vcpkg/base/strings.cpp b/toolsrc/src/vcpkg/base/strings.cpp index 48dc5ed09..8d43e7af7 100644 --- a/toolsrc/src/vcpkg/base/strings.cpp +++ b/toolsrc/src/vcpkg/base/strings.cpp @@ -128,6 +128,12 @@ namespace vcpkg::Strings #endif } + bool ends_with(const std::string& s, StringLiteral pattern) + { + if (s.size() < pattern.size()) return false; + return std::equal(s.end() - pattern.size(), s.end(), pattern.c_str(), pattern.c_str() + pattern.size()); + } + std::string replace_all(std::string&& s, const std::string& search, const std::string& rep) { size_t pos = 0; diff --git a/toolsrc/src/vcpkg/commands.cache.cpp b/toolsrc/src/vcpkg/commands.cache.cpp index a9d8ba03c..464f4f9ee 100644 --- a/toolsrc/src/vcpkg/commands.cache.cpp +++ b/toolsrc/src/vcpkg/commands.cache.cpp @@ -61,7 +61,7 @@ namespace vcpkg::Commands::Cache for (const BinaryParagraph& binary_paragraph : binary_paragraphs) { const std::string displayname = binary_paragraph.displayname(); - if (Strings::case_insensitive_ascii_find(displayname, args.command_arguments[0]) == displayname.end()) + if (!Strings::case_insensitive_ascii_contains(displayname, args.command_arguments[0])) { continue; } diff --git a/toolsrc/src/vcpkg/commands.list.cpp b/toolsrc/src/vcpkg/commands.list.cpp index 1bfbc4247..cadc06ad3 100644 --- a/toolsrc/src/vcpkg/commands.list.cpp +++ b/toolsrc/src/vcpkg/commands.list.cpp @@ -76,7 +76,7 @@ namespace vcpkg::Commands::List for (const StatusParagraph* status_paragraph : installed_packages) { const std::string displayname = status_paragraph->package.displayname(); - if (Strings::case_insensitive_ascii_find(displayname, args.command_arguments[0]) == displayname.end()) + if (!Strings::case_insensitive_ascii_contains(displayname, args.command_arguments[0])) { continue; } diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp index fc336d6c7..40e696fa0 100644 --- a/toolsrc/src/vcpkg/install.cpp +++ b/toolsrc/src/vcpkg/install.cpp @@ -462,14 +462,14 @@ namespace vcpkg::Install auto files = fs.read_lines(paths.listfile_path(bpgh)); if (auto p_lines = files.get()) { + std::map config_files; std::map> library_targets; for (auto&& suffix : *p_lines) { - if (Strings::case_insensitive_ascii_find(suffix, "/share/") != suffix.end() && - suffix.substr(suffix.size() - 6) == ".cmake") + if (Strings::case_insensitive_ascii_contains(suffix, "/share/") && Strings::ends_with(suffix, ".cmake")) { - // File is inside the share folder + // CMake file is inside the share folder auto path = paths.installed / suffix; auto maybe_contents = fs.read_contents(path); auto find_package_name = path.parent_path().filename().u8string(); @@ -485,6 +485,21 @@ namespace vcpkg::Install ++next; } } + + auto filename = fs::u8path(suffix).filename().u8string(); + + if (Strings::ends_with(filename, "Config.cmake")) + { + auto root = filename.substr(0, filename.size() - 12); + if (Strings::case_insensitive_ascii_equals(root, find_package_name)) + config_files[find_package_name] = root; + } + else if (Strings::ends_with(filename, "-config.cmake")) + { + auto root = filename.substr(0, filename.size() - 13); + if (Strings::case_insensitive_ascii_equals(root, find_package_name)) + config_files[find_package_name] = root; + } } } @@ -497,11 +512,23 @@ namespace vcpkg::Install for (auto&& library_target_pair : library_targets) { + auto config_it = config_files.find(library_target_pair.first); + if (config_it != config_files.end()) + System::println(" find_package(%s CONFIG REQUIRED)", config_it->second); + else + System::println(" find_package(%s CONFIG REQUIRED)", library_target_pair.first); + + std::sort(library_target_pair.second.begin(), + library_target_pair.second.end(), + [](const std::string& l, const std::string& r) { + if (l.size() < r.size()) return true; + if (l.size() > r.size()) return false; + return l < r; + }); + if (library_target_pair.second.size() <= 4) { - System::println(" find_package(%s REQUIRED)\n" - " target_link_libraries(main PRIVATE %s)\n", - library_target_pair.first, + System::println(" target_link_libraries(main PRIVATE %s)\n", Strings::join(" ", library_target_pair.second)); } else @@ -509,10 +536,8 @@ namespace vcpkg::Install auto omitted = library_target_pair.second.size() - 4; library_target_pair.second.erase(library_target_pair.second.begin() + 4, library_target_pair.second.end()); - System::println(" find_package(%s REQUIRED)\n" - " # Note: %zd targets were omitted\n" + System::println(" # Note: %zd target(s) were omitted.\n" " target_link_libraries(main PRIVATE %s)\n", - library_target_pair.first, omitted, Strings::join(" ", library_target_pair.second)); } -- cgit v1.2.3 From 2a73e133448c14738271e8b0227c8b2eb4992ea3 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 22 May 2018 17:14:30 -0700 Subject: Direct-init instead of copy-init --- toolsrc/src/vcpkg/commands.fetch.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'toolsrc') diff --git a/toolsrc/src/vcpkg/commands.fetch.cpp b/toolsrc/src/vcpkg/commands.fetch.cpp index c88ae9dd0..33c5c1dcc 100644 --- a/toolsrc/src/vcpkg/commands.fetch.cpp +++ b/toolsrc/src/vcpkg/commands.fetch.cpp @@ -816,7 +816,7 @@ namespace vcpkg::Commands::Fetch paths_examined.push_back(dumpbin_path); if (fs.exists(dumpbin_path)) { - const Toolset v141toolset = Toolset{ + const Toolset v141toolset{ vs_instance.root_path, dumpbin_path, vcvarsall_bat, {}, V_141, supported_architectures}; auto english_language_pack = dumpbin_path.parent_path() / "1033"; @@ -831,12 +831,12 @@ namespace vcpkg::Commands::Fetch if (v140_is_available) { - const Toolset v140toolset = Toolset{vs_instance.root_path, - dumpbin_path, - vcvarsall_bat, - {"-vcvars_ver=14.0"}, - V_140, - supported_architectures}; + const Toolset v140toolset{vs_instance.root_path, + dumpbin_path, + vcvarsall_bat, + {"-vcvars_ver=14.0"}, + V_140, + supported_architectures}; found_toolsets.push_back(v140toolset); } -- cgit v1.2.3