diff options
| author | Alexander Saprykin <xelfium@gmail.com> | 2018-05-26 13:27:14 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-05-26 13:27:14 +0200 |
| commit | 4ce5f064282c3a8d8d710aa82af7aa346b0c6dd5 (patch) | |
| tree | d95c9490352eb73f078d34a33bc4bb44ac9fa48b /toolsrc/include | |
| parent | fb689bd13dd6ba563a885d71fff1dd2b32a615db (diff) | |
| parent | 2ac7527b40b1dbeb7856b9f763362c1e139e2ca9 (diff) | |
| download | vcpkg-4ce5f064282c3a8d8d710aa82af7aa346b0c6dd5.tar.gz vcpkg-4ce5f064282c3a8d8d710aa82af7aa346b0c6dd5.zip | |
Merge pull request #1 from Microsoft/master
Update vcpkg from upstream
Diffstat (limited to 'toolsrc/include')
80 files changed, 2919 insertions, 1590 deletions
diff --git a/toolsrc/include/CStringView.h b/toolsrc/include/CStringView.h deleted file mode 100644 index 282caad3a..000000000 --- a/toolsrc/include/CStringView.h +++ /dev/null @@ -1,54 +0,0 @@ -#pragma once -#include <string> - -namespace vcpkg -{ - template<class CharType> - struct BasicCStringView - { - constexpr BasicCStringView() : cstr(nullptr) {} - constexpr BasicCStringView(const CharType* cstr) : cstr(cstr) {} - constexpr BasicCStringView(const BasicCStringView&) = default; - BasicCStringView(const std::basic_string<CharType>& str) : cstr(str.c_str()) {} - - constexpr operator const CharType*() const { return cstr; } - constexpr const CharType* c_str() const { return cstr; } - - private: - const CharType* cstr; - }; - - template<class CharType> - bool operator==(const std::basic_string<CharType>& l, const BasicCStringView<CharType>& r) - { - return l == r.c_str(); - } - - template<class CharType> - bool operator==(const BasicCStringView<CharType>& r, const std::basic_string<CharType>& l) - { - return l == r.c_str(); - } - - template<class CharType> - bool operator!=(const BasicCStringView<CharType>& r, const std::basic_string<CharType>& l) - { - return l != r.c_str(); - } - - template<class CharType> - bool operator!=(const std::basic_string<CharType>& l, const BasicCStringView<CharType>& r) - { - return l != r.c_str(); - } - - using CStringView = BasicCStringView<char>; - using CWStringView = BasicCStringView<wchar_t>; - - 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/PackageSpec.h b/toolsrc/include/PackageSpec.h deleted file mode 100644 index 050d9d079..000000000 --- a/toolsrc/include/PackageSpec.h +++ /dev/null @@ -1,47 +0,0 @@ -#pragma once -#include "PackageSpecParseResult.h" -#include "Triplet.h" -#include "vcpkg_expected.h" - -namespace vcpkg -{ - struct PackageSpec - { - static Expected<PackageSpec> 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<PackageSpec> 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; - }; - - bool operator==(const PackageSpec& left, const PackageSpec& right); - bool operator!=(const PackageSpec& left, const PackageSpec& right); -} - -template<> -struct std::hash<vcpkg::PackageSpec> -{ - size_t operator()(const vcpkg::PackageSpec& value) const - { - size_t hash = 17; - hash = hash * 31 + std::hash<std::string>()(value.name()); - hash = hash * 31 + std::hash<vcpkg::Triplet>()(value.triplet()); - return hash; - } -}; - -template<> -struct std::equal_to<vcpkg::PackageSpec> -{ - 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 b72c534c2..000000000 --- a/toolsrc/include/PackageSpecParseResult.h +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once -#include <system_error> - -namespace vcpkg -{ - enum class PackageSpecParseResult - { - SUCCESS = 0, - TOO_MANY_COLONS, - INVALID_CHARACTERS - }; - - struct PackageSpecParseResultCategoryImpl final : std::error_category - { - virtual const char* name() const noexcept override; - - virtual std::string message(int ev) const noexcept override; - }; - - const std::error_category& package_spec_parse_result_category(); - - std::error_code make_error_code(PackageSpecParseResult e); - - PackageSpecParseResult to_package_spec_parse_result(int i); - - PackageSpecParseResult to_package_spec_parse_result(std::error_code ec); -} - -// Enable implicit conversion to std::error_code -namespace std -{ - template<> - struct is_error_code_enum<vcpkg::PackageSpecParseResult> : ::std::true_type - { - }; -} diff --git a/toolsrc/include/Paragraphs.h b/toolsrc/include/Paragraphs.h deleted file mode 100644 index 66f6bd2e4..000000000 --- a/toolsrc/include/Paragraphs.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#include "BinaryParagraph.h" -#include "VcpkgPaths.h" -#include "VersionT.h" -#include "filesystem_fs.h" -#include "vcpkg_expected.h" -#include <map> - -namespace vcpkg::Paragraphs -{ - using ParagraphDataMap = std::unordered_map<std::string, std::string>; - - Expected<ParagraphDataMap> get_single_paragraph(const Files::Filesystem& fs, const fs::path& control_path); - Expected<std::vector<ParagraphDataMap>> get_paragraphs(const Files::Filesystem& fs, const fs::path& control_path); - Expected<ParagraphDataMap> parse_single_paragraph(const std::string& str); - Expected<std::vector<ParagraphDataMap>> parse_paragraphs(const std::string& str); - - Expected<SourceParagraph> try_load_port(const Files::Filesystem& fs, const fs::path& control_path); - - Expected<BinaryParagraph> try_load_cached_package(const VcpkgPaths& paths, const PackageSpec& spec); - - std::vector<SourceParagraph> load_all_ports(const Files::Filesystem& fs, const fs::path& ports_dir); - - std::map<std::string, VersionT> extract_port_names_and_versions( - const std::vector<SourceParagraph>& source_paragraphs); -} diff --git a/toolsrc/include/PostBuildLint_BuildPolicies.h b/toolsrc/include/PostBuildLint_BuildPolicies.h deleted file mode 100644 index 697edbb8d..000000000 --- a/toolsrc/include/PostBuildLint_BuildPolicies.h +++ /dev/null @@ -1,45 +0,0 @@ -#pragma once -#include "CStringView.h" -#include <array> -#include <string> - -namespace vcpkg::PostBuildLint -{ - struct BuildPolicies final - { - enum class BackingEnum - { - NULLVALUE = 0, - EMPTY_PACKAGE, - DLLS_WITHOUT_LIBS, - ONLY_RELEASE_CRT, - EMPTY_INCLUDE_FOLDER - }; - - 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 std::array<BuildPolicies, 4> VALUES = { - EMPTY_PACKAGE, DLLS_WITHOUT_LIBS, ONLY_RELEASE_CRT, EMPTY_INCLUDE_FOLDER}; - } -} diff --git a/toolsrc/include/PostBuildLint_BuildType.h b/toolsrc/include/PostBuildLint_BuildType.h deleted file mode 100644 index 58bb20766..000000000 --- a/toolsrc/include/PostBuildLint_BuildType.h +++ /dev/null @@ -1,58 +0,0 @@ -#pragma once -#include "CStringView.h" -#include "PostBuildLint_ConfigurationType.h" -#include "PostBuildLint_LinkageType.h" -#include <array> -#include <regex> - -namespace vcpkg::PostBuildLint -{ - struct BuildType - { - enum class BackingEnum - { - DEBUG_STATIC = 1, - DEBUG_DYNAMIC, - RELEASE_STATIC, - RELEASE_DYNAMIC - }; - - static BuildType value_of(const ConfigurationType& config, const LinkageType& linkage); - - BuildType() = delete; - - constexpr BuildType(const BackingEnum backing_enum, const ConfigurationType config, const LinkageType linkage) - : backing_enum(backing_enum), m_config(config), m_linkage(linkage) - { - } - - constexpr operator BackingEnum() const { return backing_enum; } - - const ConfigurationType& config() const; - const 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; - }; - - namespace BuildTypeC - { - namespace CC = ConfigurationTypeC; - namespace LC = LinkageTypeC; - 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 std::array<BuildType, 4> 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 <string> - -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<ConfigurationType, 2> VALUES = {DEBUG, RELEASE}; - } -} diff --git a/toolsrc/include/PostBuildLint_LinkageType.h b/toolsrc/include/PostBuildLint_LinkageType.h deleted file mode 100644 index 8d19dc5a4..000000000 --- a/toolsrc/include/PostBuildLint_LinkageType.h +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once -#include "CStringView.h" -#include <string> - -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<LinkageType, 2> VALUES = {DYNAMIC, STATIC}; - } -} diff --git a/toolsrc/include/SourceParagraph.h b/toolsrc/include/SourceParagraph.h deleted file mode 100644 index 8d51b45d4..000000000 --- a/toolsrc/include/SourceParagraph.h +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once - -#include <unordered_map> -#include <vector> - -namespace vcpkg -{ - struct Triplet; - - struct Dependency - { - std::string name; - std::string qualifier; - }; - - const std::string& to_string(const Dependency& dep); - - struct SourceParagraph - { - SourceParagraph(); - - explicit SourceParagraph(std::unordered_map<std::string, std::string> fields); - - std::string name; - std::string version; - std::string description; - std::string maintainer; - std::vector<Dependency> depends; - }; - - std::vector<std::string> filter_dependencies(const std::vector<Dependency>& deps, const Triplet& t); - - std::vector<Dependency> expand_qualified_dependencies(const std::vector<std::string>& depends); - std::vector<std::string> parse_depends(const std::string& depends_string); -} diff --git a/toolsrc/include/StatusParagraph.h b/toolsrc/include/StatusParagraph.h deleted file mode 100644 index ad913d11b..000000000 --- a/toolsrc/include/StatusParagraph.h +++ /dev/null @@ -1,41 +0,0 @@ -#pragma once - -#include "BinaryParagraph.h" -#include <unordered_map> - -namespace vcpkg -{ - enum class InstallState - { - ERROR_STATE, - NOT_INSTALLED, - HALF_INSTALLED, - INSTALLED, - }; - - enum class Want - { - ERROR_STATE, - UNKNOWN, - INSTALL, - HOLD, - DEINSTALL, - PURGE - }; - - struct StatusParagraph - { - StatusParagraph(); - explicit StatusParagraph(const std::unordered_map<std::string, std::string>& 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 2af177219..000000000 --- a/toolsrc/include/StatusParagraphs.h +++ /dev/null @@ -1,44 +0,0 @@ -#pragma once -#include "StatusParagraph.h" -#include <iterator> -#include <memory> - -namespace vcpkg -{ - struct StatusParagraphs - { - StatusParagraphs(); - explicit StatusParagraphs(std::vector<std::unique_ptr<StatusParagraph>>&& ps); - - using container = std::vector<std::unique_ptr<StatusParagraph>>; - 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); - - 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<StatusParagraph>); - - 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<std::unique_ptr<StatusParagraph>> 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 316987100..000000000 --- a/toolsrc/include/VcpkgCmdArguments.h +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once - -#include "vcpkg_optional.h" -#include <memory> -#include <unordered_set> -#include <vector> - -namespace vcpkg -{ - 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<std::string> vcpkg_root_dir; - std::unique_ptr<std::string> triplet; - Optional<bool> debug = nullopt; - Optional<bool> sendmetrics = nullopt; - Optional<bool> printmetrics = nullopt; - - std::string command; - std::vector<std::string> command_arguments; - std::unordered_set<std::string> check_and_get_optional_command_arguments( - const std::vector<std::string>& valid_options) 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_set<std::string> optional_command_arguments; - }; -} diff --git a/toolsrc/include/VcpkgPaths.h b/toolsrc/include/VcpkgPaths.h deleted file mode 100644 index 25c1728b9..000000000 --- a/toolsrc/include/VcpkgPaths.h +++ /dev/null @@ -1,61 +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 Toolset - { - fs::path dumpbin; - fs::path vcvarsall; - CWStringView version; - }; - - struct VcpkgPaths - { - static Expected<VcpkgPaths> 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 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 Toolset& get_toolset() const; - - Files::Filesystem& get_filesystem() const; - - private: - Lazy<fs::path> cmake_exe; - Lazy<fs::path> git_exe; - Lazy<fs::path> nuget_exe; - Lazy<Toolset> toolset; - }; -} diff --git a/toolsrc/include/filesystem_fs.h b/toolsrc/include/filesystem_fs.h deleted file mode 100644 index 8e223511d..000000000 --- a/toolsrc/include/filesystem_fs.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include <filesystem> - -namespace fs -{ - namespace stdfs = std::tr2::sys; - - 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/metrics.h b/toolsrc/include/metrics.h deleted file mode 100644 index 1f5ae2f32..000000000 --- a/toolsrc/include/metrics.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include <string> - -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); - - 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 upload(const std::string& payload); - void flush(); -} diff --git a/toolsrc/include/pch.h b/toolsrc/include/pch.h index 2eee658c8..9c9deeb3f 100644 --- a/toolsrc/include/pch.h +++ b/toolsrc/include/pch.h @@ -1,19 +1,38 @@ #pragma once +#if defined(_WIN32) #define NOMINMAX #define WIN32_LEAN_AND_MEAN +#pragma warning(suppress : 4768) #include <windows.h> +#pragma warning(suppress : 4768) +#include <Shlobj.h> + +#include <process.h> +#include <shellapi.h> +#include <winhttp.h> +#else +#include <unistd.h> +#endif + #include <algorithm> #include <array> +#include <atomic> #include <cassert> #include <cctype> #include <chrono> #include <codecvt> #include <cstdarg> +#include <cstddef> #include <cstdint> +#if defined(_WIN32) #include <filesystem> +#else +#include <experimental/filesystem> +#endif +#include <cstring> #include <fstream> #include <functional> #include <iomanip> @@ -21,18 +40,23 @@ #include <iterator> #include <map> #include <memory> -#include <process.h> +#include <mutex> +#include <random> #include <regex> #include <set> -#include <shellapi.h> -#include <shlobj.h> #include <stdexcept> #include <string> +#if defined(_WIN32) #include <sys/timeb.h> +#else +#include <sys/time.h> +#endif +#include <sys/types.h> #include <system_error> +#include <thread> #include <time.h> +#include <type_traits> #include <unordered_map> #include <unordered_set> #include <utility> #include <vector> -#include <winhttp.h> diff --git a/toolsrc/include/tests.pch.h b/toolsrc/include/tests.pch.h new file mode 100644 index 000000000..5c00fca4a --- /dev/null +++ b/toolsrc/include/tests.pch.h @@ -0,0 +1,19 @@ +#pragma once + +#include <CppUnitTest.h> + +#include <vcpkg/base/chrono.h> +#include <vcpkg/base/sortedvector.h> +#include <vcpkg/base/strings.h> +#include <vcpkg/base/util.h> +#include <vcpkg/binaryparagraph.h> +#include <vcpkg/dependencies.h> +#include <vcpkg/packagespec.h> +#include <vcpkg/packagespecparseresult.h> +#include <vcpkg/paragraphs.h> +#include <vcpkg/sourceparagraph.h> +#include <vcpkg/statusparagraph.h> +#include <vcpkg/statusparagraphs.h> +#include <vcpkg/triplet.h> +#include <vcpkg/update.h> +#include <vcpkg/vcpkgcmdarguments.h> diff --git a/toolsrc/include/tests.utils.h b/toolsrc/include/tests.utils.h new file mode 100644 index 000000000..7f7ec9e88 --- /dev/null +++ b/toolsrc/include/tests.utils.h @@ -0,0 +1,76 @@ +#pragma once + +#include <CppUnitTest.h> + +#include <vcpkg/dependencies.h> +#include <vcpkg/packagespec.h> +#include <vcpkg/packagespecparseresult.h> +#include <vcpkg/statusparagraph.h> +#include <vcpkg/triplet.h> + +#include <memory> + +namespace Microsoft::VisualStudio::CppUnitTestFramework +{ + template<> + std::wstring ToString<vcpkg::Dependencies::InstallPlanType>(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<int>(t)); + } + } + + template<> + std::wstring ToString<vcpkg::Dependencies::RequestType>(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<int>(t)); + } + } + + template<> + std::wstring ToString<vcpkg::PackageSpecParseResult>(const vcpkg::PackageSpecParseResult& t) + { + return ToString(static_cast<uint32_t>(t)); + } + + template<> + std::wstring ToString<vcpkg::PackageSpec>(const vcpkg::PackageSpec& t) + { + return ToString(t.to_string()); + } +} + +std::unique_ptr<vcpkg::StatusParagraph> make_status_pgh(const char* name, + const char* depends = "", + const char* default_features = "", + const char* triplet = "x86-windows"); +std::unique_ptr<vcpkg::StatusParagraph> make_status_feature_pgh(const char* name, + const char* feature, + const char* depends = "", + const char* triplet = "x86-windows"); + +template<class T, class S> +T&& unwrap(vcpkg::ExpectedT<T, S>&& p) +{ + Assert::IsTrue(p.has_value()); + return std::move(*p.get()); +} + +template<class T> +T&& unwrap(vcpkg::Optional<T>&& 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/triplet.h b/toolsrc/include/triplet.h deleted file mode 100644 index e634afd3f..000000000 --- a/toolsrc/include/triplet.h +++ /dev/null @@ -1,43 +0,0 @@ -#pragma once - -#include <string> - -namespace vcpkg -{ - struct Triplet - { - 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; - - private: - std::string m_canonical_name; - }; - - bool operator==(const Triplet& left, const Triplet& right); - - bool operator!=(const Triplet& left, const Triplet& right); -} - -namespace std -{ - template<> - struct hash<vcpkg::Triplet> - { - size_t operator()(const vcpkg::Triplet& t) const - { - std::hash<std::string> hasher; - size_t hash = 17; - hash = hash * 31 + hasher(t.canonical_name()); - return hash; - } - }; - -} // namespace std 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 <map>
+
+namespace vcpkg
+{
+ template<class Key, class Value>
+ struct Cache
+ {
+ template<class F>
+ 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<Key, Value> m_cache;
+ };
+}
diff --git a/toolsrc/include/vcpkg/base/checks.h b/toolsrc/include/vcpkg/base/checks.h new file mode 100644 index 000000000..bceee3428 --- /dev/null +++ b/toolsrc/include/vcpkg/base/checks.h @@ -0,0 +1,55 @@ +#pragma once + +#include <vcpkg/base/cstringview.h> +#include <vcpkg/base/lineinfo.h> +#include <vcpkg/base/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<class Arg1, class... Args> + // 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<class Conditional, class Arg1, class... Args> + 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..aa764a597 --- /dev/null +++ b/toolsrc/include/vcpkg/base/chrono.h @@ -0,0 +1,65 @@ +#pragma once + +#include <chrono> +#include <string> +#include <vcpkg/base/optional.h> + +namespace vcpkg::Chrono +{ + class ElapsedTime + { + using duration = std::chrono::high_resolution_clock::time_point::duration; + + public: + constexpr ElapsedTime() noexcept : m_duration() {} + constexpr ElapsedTime(duration d) noexcept : m_duration(d) {} + + template<class TimeUnit> + TimeUnit as() const + { + return std::chrono::duration_cast<TimeUnit>(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() noexcept : m_start_tick() {} + + ElapsedTime elapsed() const + { + return ElapsedTime(std::chrono::high_resolution_clock::now() - this->m_start_tick); + } + + double microseconds() const { return elapsed().as<std::chrono::duration<double, std::micro>>().count(); } + + std::string to_string() const; + + private: + std::chrono::high_resolution_clock::time_point m_start_tick; + }; + + class CTime + { + public: + static Optional<CTime> get_current_date_time(); + static Optional<CTime> parse(CStringView str); + + constexpr CTime() noexcept : m_tm{0} {} + explicit constexpr CTime(tm t) noexcept : 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/coff_file_reader.h b/toolsrc/include/vcpkg/base/cofffilereader.h index 09f6447c2..e0ad69b33 100644 --- a/toolsrc/include/coff_file_reader.h +++ b/toolsrc/include/vcpkg/base/cofffilereader.h @@ -1,9 +1,11 @@ #pragma once -#include "MachineType.h" -#include "filesystem_fs.h" + +#include <vcpkg/base/files.h> +#include <vcpkg/base/machinetype.h> + #include <vector> -namespace vcpkg::COFFFileReader +namespace vcpkg::CoffFileReader { struct DllInfo { @@ -15,7 +17,9 @@ namespace vcpkg::COFFFileReader std::vector<MachineType> machine_types; }; +#if defined(_WIN32) DllInfo read_dll(const fs::path& path); LibInfo read_lib(const fs::path& path); +#endif } diff --git a/toolsrc/include/vcpkg/base/cstringview.h b/toolsrc/include/vcpkg/base/cstringview.h new file mode 100644 index 000000000..f285aa36c --- /dev/null +++ b/toolsrc/include/vcpkg/base/cstringview.h @@ -0,0 +1,58 @@ +#pragma once + +#include <string.h> +#include <string> + +namespace vcpkg +{ + struct CStringView + { + 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()) {} + + constexpr const char* c_str() const { return cstr; } + + private: + const char* cstr; + }; + + namespace details + { + inline bool vcpkg_strcmp(const char* l, const char* r) { return strcmp(l, r) == 0; } + } + + inline bool operator==(const CStringView& l, const CStringView& r) + { + return details::vcpkg_strcmp(l.c_str(), r.c_str()); + } + + inline bool operator==(const char* l, const CStringView& r) { 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()); } + + inline bool operator==(const std::string& l, const CStringView& r) { return l == r.c_str(); } + + inline bool operator==(const CStringView& r, const std::string& l) { return l == r.c_str(); } + + // notequals + inline bool operator!=(const CStringView& l, const CStringView& r) + { + return !details::vcpkg_strcmp(l.c_str(), r.c_str()); + } + + inline bool operator!=(const char* l, const CStringView& r) { 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()); } + + inline bool operator!=(const CStringView& r, const std::string& l) { return l != r.c_str(); } + + 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_Enums.h b/toolsrc/include/vcpkg/base/enums.h index c75feaa1f..6eca2cfe1 100644 --- a/toolsrc/include/vcpkg_Enums.h +++ b/toolsrc/include/vcpkg/base/enums.h @@ -1,5 +1,7 @@ #pragma once -#include "LineInfo.h" + +#include <vcpkg/base/lineinfo.h> + #include <string> namespace vcpkg::Enums diff --git a/toolsrc/include/vcpkg/base/expected.h b/toolsrc/include/vcpkg/base/expected.h new file mode 100644 index 000000000..e20f723db --- /dev/null +++ b/toolsrc/include/vcpkg/base/expected.h @@ -0,0 +1,120 @@ +#pragma once + +#include <vcpkg/base/checks.h> + +#include <system_error> + +namespace vcpkg +{ + template<class Err> + struct ErrorHolder + { + ErrorHolder() : m_is_error(false) {} + template<class U> + ErrorHolder(U&& err) : m_is_error(true), m_err(std::forward<U>(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<std::error_code> + { + ErrorHolder() = default; + ErrorHolder(const std::error_code& err) : m_err(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; } + + CStringView to_string() const { return m_err.message(); } + + private: + std::error_code m_err; + }; + + template<class T, class S> + 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 + { + // 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<S> m_s; + T m_t; + }; + + template<class T> + using Expected = ExpectedT<T, std::error_code>; +} diff --git a/toolsrc/include/vcpkg_Files.h b/toolsrc/include/vcpkg/base/files.h index ad29ffa14..f16805d0a 100644 --- a/toolsrc/include/vcpkg_Files.h +++ b/toolsrc/include/vcpkg/base/files.h @@ -1,11 +1,31 @@ #pragma once -#include "filesystem_fs.h" -#include "vcpkg_expected.h" +#include <vcpkg/base/expected.h> + +#if defined(_WIN32) +#include <filesystem> +#else +#include <experimental/filesystem> +#endif + +namespace fs +{ + namespace stdfs = std::experimental::filesystem; + + using stdfs::copy_options; + using stdfs::file_status; + using stdfs::file_type; + 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); } + inline bool status_known(file_status s) { return stdfs::status_known(s); } +} namespace vcpkg::Files { - __interface Filesystem + struct Filesystem { virtual Expected<std::string> read_contents(const fs::path& file_path) const = 0; virtual Expected<std::vector<std::string>> read_lines(const fs::path& file_path) const = 0; @@ -14,8 +34,9 @@ namespace vcpkg::Files virtual std::vector<fs::path> get_files_non_recursive(const fs::path& dir) const = 0; virtual void write_lines(const fs::path& file_path, const std::vector<std::string>& 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 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; @@ -26,16 +47,28 @@ 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; + + 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(); - 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); void print_paths(const std::vector<fs::path>& paths); + + std::vector<fs::path> find_from_PATH(const std::string& name); } diff --git a/toolsrc/include/vcpkg/base/graphs.h b/toolsrc/include/vcpkg/base/graphs.h new file mode 100644 index 000000000..1b0fa61c7 --- /dev/null +++ b/toolsrc/include/vcpkg/base/graphs.h @@ -0,0 +1,121 @@ +#pragma once + +#include <unordered_map> +#include <unordered_set> + +#include <vcpkg/base/checks.h> +#include <vcpkg/base/span.h> +#include <vcpkg/base/system.h> + +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<class V, class U> + struct AdjacencyProvider + { + virtual std::vector<V> 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; + }; + + namespace details + { + template<class V, class U> + void topological_sort_internal(const V& vertex, + const AdjacencyProvider<V, U>& f, + std::unordered_map<V, ExplorationStatus>& exploration_status, + std::vector<U>& sorted) + { + ExplorationStatus& status = exploration_status[vertex]; + switch (status) + { + 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); + } + } + } + + template<class VertexRange, class V, class U> + std::vector<U> topological_sort(const VertexRange& starting_vertices, const AdjacencyProvider<V, U>& f) + { + std::vector<U> sorted; + std::unordered_map<V, ExplorationStatus> exploration_status; + + for (auto&& vertex : starting_vertices) + { + details::topological_sort_internal(vertex, f, exploration_status, sorted); + } + + return sorted; + } + + template<class V> + struct Graph final : AdjacencyProvider<V, V> + { + public: + void add_vertex(const V& v) { this->m_edges[v]; } + + void add_edge(const V& u, const V& v) + { + this->m_edges[v]; + this->m_edges[u].insert(v); + } + + std::vector<V> vertex_list() const + { + std::vector<V> vertex_list; + for (auto&& vertex : this->m_edges) + vertex_list.emplace_back(vertex.first); + return vertex_list; + } + + std::vector<V> adjacency_list(const V& vertex) const override + { + const std::unordered_set<V>& as_set = this->m_edges.at(vertex); + return std::vector<V>(as_set.cbegin(), as_set.cend()); // TODO: Avoid redundant copy + } + + V load_vertex_data(const V& vertex) const override { return vertex; } + + // 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<V, std::unordered_set<V>> m_edges; + }; +} diff --git a/toolsrc/include/lazy.h b/toolsrc/include/vcpkg/base/lazy.h index 58c11c002..58c11c002 100644 --- a/toolsrc/include/lazy.h +++ b/toolsrc/include/vcpkg/base/lazy.h diff --git a/toolsrc/include/LineInfo.h b/toolsrc/include/vcpkg/base/lineinfo.h index 66d91c520..e0eb8bec9 100644 --- a/toolsrc/include/LineInfo.h +++ b/toolsrc/include/vcpkg/base/lineinfo.h @@ -1,5 +1,7 @@ #pragma once +#include <string> + namespace vcpkg { struct LineInfo @@ -7,7 +9,7 @@ namespace vcpkg int line_number; const char* file_name; - constexpr LineInfo() : line_number(0), file_name(nullptr) {} + 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/MachineType.h b/toolsrc/include/vcpkg/base/machinetype.h index 2318c092b..b85cdbb0b 100644 --- a/toolsrc/include/MachineType.h +++ b/toolsrc/include/vcpkg/base/machinetype.h @@ -1,4 +1,5 @@ #pragma once + #include <cstdint> namespace vcpkg @@ -32,5 +33,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/vcpkg/base/optional.h b/toolsrc/include/vcpkg/base/optional.h new file mode 100644 index 000000000..6b84b10aa --- /dev/null +++ b/toolsrc/include/vcpkg/base/optional.h @@ -0,0 +1,142 @@ +#pragma once + +#include <vcpkg/base/checks.h> + +namespace vcpkg +{ + struct NullOpt + { + explicit constexpr NullOpt(int) {} + }; + + const static constexpr NullOpt nullopt{0}; + + namespace details + { + template<class T> + struct OptionalStorage + { + 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)) {} + + 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<class T> + struct OptionalStorage<T&> + { + constexpr OptionalStorage() noexcept : 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 T> + struct Optional + { + constexpr Optional() noexcept {} + + // Constructors are intentionally implicit + constexpr Optional(NullOpt) {} + + template<class U> + Optional(U&& t) : m_base(std::forward<U>(t)) + { + } + + T&& value_or_exit(const LineInfo& line_info) && + { + this->exit_if_null(line_info); + 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); + return this->m_base.value(); + } + + constexpr explicit operator bool() const { return this->m_base.has_value(); } + + constexpr bool has_value() const { return this->m_base.has_value(); } + + template<class U> + T value_or(U&& default_value) const& + { + return this->m_base.has_value() ? this->m_base.value() : static_cast<T>(std::forward<U>(default_value)); + } + + template<class U> + T value_or(U&& default_value) && + { + return this->m_base.has_value() ? std::move(this->m_base.value()) + : static_cast<T>(std::forward<U>(default_value)); + } + + typename std::add_pointer<const T>::type get() const + { + return this->m_base.has_value() ? &this->m_base.value() : nullptr; + } + + typename std::add_pointer<T>::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_base.has_value(), "Value was null"); + } + + details::OptionalStorage<T> m_base; + }; + + template<class U> + Optional<std::decay_t<U>> make_optional(U&& u) + { + return Optional<std::decay_t<U>>(std::forward<U>(u)); + } + + template<class T> + bool operator==(const Optional<T>& o, const T& t) + { + if (auto p = o.get()) return *p == t; + return false; + } + template<class T> + bool operator==(const T& t, const Optional<T>& o) + { + if (auto p = o.get()) return t == *p; + return false; + } + template<class T> + bool operator!=(const Optional<T>& o, const T& t) + { + if (auto p = o.get()) return *p != t; + return true; + } + template<class T> + bool operator!=(const T& t, const Optional<T>& o) + { + if (auto p = o.get()) return t != *p; + return true; + } +} diff --git a/toolsrc/include/SortedVector.h b/toolsrc/include/vcpkg/base/sortedvector.h index 62808cc2f..fbb7e5a5a 100644 --- a/toolsrc/include/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<T> m_data; }; diff --git a/toolsrc/include/vcpkg/base/span.h b/toolsrc/include/vcpkg/base/span.h new file mode 100644 index 000000000..2b067d0ac --- /dev/null +++ b/toolsrc/include/vcpkg/base/span.h @@ -0,0 +1,75 @@ +#pragma once
+
+#include <array>
+#include <cstddef>
+#include <initializer_list>
+#include <vector>
+
+namespace vcpkg
+{
+ template<class T>
+ struct Span
+ {
+ public:
+ static_assert(!std::is_reference<T>::value, "Span<&> is illegal");
+
+ using element_type = T;
+ using pointer = std::add_pointer_t<T>;
+ using reference = std::add_lvalue_reference_t<T>;
+ using iterator = pointer;
+
+ constexpr Span() noexcept : m_ptr(nullptr), m_count(0) {}
+ 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<T> l) noexcept : m_ptr(l.begin()), m_count(l.size()) {}
+
+ template<size_t N>
+ constexpr Span(T (&arr)[N]) noexcept : m_ptr(arr), m_count(N)
+ {
+ }
+
+ template<size_t N>
+ constexpr Span(const std::array<std::remove_const_t<T>, N>& arr) noexcept
+ : m_ptr(arr.data()), m_count(arr.size())
+ {
+ }
+
+ Span(std::vector<T>& v) noexcept : Span(v.data(), v.size()) {}
+ Span(const std::vector<std::remove_const_t<T>>& 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<class T>
+ Span<T> make_span(std::vector<T>& v)
+ {
+ return {v.data(), v.size()};
+ }
+
+ template<class T>
+ Span<const T> make_span(const std::vector<T>& v)
+ {
+ return {v.data(), v.size()};
+ }
+
+ template<class T>
+ constexpr T* begin(Span<T> sp)
+ {
+ return sp.begin();
+ }
+
+ template<class T>
+ constexpr T* end(Span<T> sp)
+ {
+ return sp.end();
+ }
+}
diff --git a/toolsrc/include/vcpkg/base/stringliteral.h b/toolsrc/include/vcpkg/base/stringliteral.h new file mode 100644 index 000000000..9970adc2a --- /dev/null +++ b/toolsrc/include/vcpkg/base/stringliteral.h @@ -0,0 +1,27 @@ +#pragma once + +#include <vcpkg/base/cstringview.h> + +namespace vcpkg +{ + struct StringLiteral + { + template<int N> + constexpr StringLiteral(const char (&str)[N]) + : m_size(N - 1) /* -1 here accounts for the null byte at the end*/, 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/include/vcpkg/base/strings.h b/toolsrc/include/vcpkg/base/strings.h new file mode 100644 index 000000000..4b39b0a28 --- /dev/null +++ b/toolsrc/include/vcpkg/base/strings.h @@ -0,0 +1,102 @@ +#pragma once + +#include <vcpkg/base/cstringview.h> +#include <vcpkg/base/stringliteral.h> + +#include <vector> + +namespace vcpkg::Strings::details +{ + template<class T> + 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; } + + template<class T, class = std::enable_if_t<std::is_arithmetic<T>::value>> + T to_printf_arg(T s) + { + return s; + } + + std::string format_internal(const char* fmtstr, ...); +} + +namespace vcpkg::Strings +{ + template<class... Args> + 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))...); + } + +#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); + + 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_equals(const CStringView left, const CStringView right); + + 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); + bool ends_with(const std::string& s, StringLiteral pattern); + + template<class Container, class Transformer> + 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::string(); + } + + std::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<class Container> + 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; }); + } + + std::string replace_all(std::string&& s, const std::string& search, const std::string& rep); + + std::string trim(std::string&& s); + + void trim_all_and_remove_whitespace_strings(std::vector<std::string>* strings); + + std::vector<std::string> split(const std::string& s, const std::string& delimiter); + + template<class T> + 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..813d600cd --- /dev/null +++ b/toolsrc/include/vcpkg/base/system.h @@ -0,0 +1,120 @@ +#pragma once + +#include <unordered_map> + +#include <vcpkg/base/files.h> +#include <vcpkg/base/optional.h> +#include <vcpkg/base/strings.h> + +namespace vcpkg::System +{ + tm get_current_date_time(); + + 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<CMakeVariable>& pass_variables); + + struct ExitCodeAndOutput + { + int exit_code; + std::string output; + }; + + int cmd_execute_clean(const CStringView cmd_line, + const std::unordered_map<std::string, std::string>& extra_env = {}); + + int cmd_execute(const CStringView cmd_line); + + ExitCodeAndOutput cmd_execute_and_capture_output(const CStringView cmd_line); + + 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<class Arg1, class... Args> + void print(const char* message_template, const Arg1& message_arg1, const Args&... message_args) + { + return System::print(Strings::format(message_template, message_arg1, message_args...)); + } + + template<class Arg1, class... Args> + void print(const Color c, const char* message_template, const Arg1& message_arg1, const Args&... message_args) + { + return System::print(c, Strings::format(message_template, message_arg1, message_args...)); + } + + template<class Arg1, class... Args> + void println(const char* message_template, const Arg1& message_arg1, const Args&... message_args) + { + return System::println(Strings::format(message_template, message_arg1, message_args...)); + } + + template<class Arg1, class... Args> + void println(const Color c, const char* message_template, const Arg1& message_arg1, const Args&... message_args) + { + return System::println(c, Strings::format(message_template, message_arg1, message_args...)); + } + + Optional<std::string> get_environment_variable(const CStringView varname) noexcept; + + Optional<std::string> get_registry_string(void* base_hkey, const CStringView subkey, const CStringView valuename); + + enum class CPUArchitecture + { + X86, + X64, + ARM, + ARM64, + }; + + Optional<CPUArchitecture> to_cpu_architecture(const CStringView& arch); + + CPUArchitecture get_host_processor(); + + std::vector<CPUArchitecture> get_supported_host_architectures(); + + const Optional<fs::path>& get_program_files_32_bit(); + + const Optional<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<class Arg1, class... Args> + void println(const char* message_template, const Arg1& message_arg1, const Args&... message_args) + { + return Debug::println(Strings::format(message_template, message_arg1, message_args...)); + } + + template<class Arg1, class... Args> + void println(const System::Color c, + const char* message_template, + const Arg1& message_arg1, + const Args&... message_args) + { + return Debug::println(c, Strings::format(message_template, message_arg1, message_args...)); + } +} diff --git a/toolsrc/include/vcpkg/base/util.h b/toolsrc/include/vcpkg/base/util.h new file mode 100644 index 000000000..7266fbbc6 --- /dev/null +++ b/toolsrc/include/vcpkg/base/util.h @@ -0,0 +1,237 @@ +#pragma once + +#include <algorithm> +#include <map> +#include <mutex> +#include <unordered_map> +#include <utility> +#include <vector> + +namespace vcpkg::Util +{ + template<class Container> + using ElementT = std::remove_reference_t<decltype(*begin(std::declval<Container>()))>; + + namespace Vectors + { + template<class Container, class T = ElementT<Container>> + void concatenate(std::vector<T>* augend, const Container& addend) + { + augend->insert(augend->end(), addend.begin(), addend.end()); + } + } + + namespace Sets + { + template<class Container, class Key> + bool contains(const Container& container, const Key& item) + { + return container.find(item) != container.end(); + } + } + + namespace Maps + { + template<class K, class V1, class V2, class Func> + void transform_values(const std::unordered_map<K, V1>& container, std::unordered_map<K, V2>& output, Func func) + { + std::for_each(container.cbegin(), container.cend(), [&](const std::pair<const K, V1>& p) { + output[p.first] = func(p.second); + }); + } + } + + template<class Cont, class Func> + using FmapOut = decltype(std::declval<Func&>()(*begin(std::declval<Cont&>()))); + + template<class Cont, class Func, class Out = FmapOut<Cont, Func>> + std::vector<Out> fmap(Cont&& xs, Func&& f) + { + std::vector<Out> ret; + ret.reserve(xs.size()); + + for (auto&& x : xs) + ret.push_back(f(x)); + + return ret; + } + + template<class Cont, class Func> + using FmapFlattenOut = std::decay_t<decltype(*begin(std::declval<Func>()(*begin(std::declval<Cont>()))))>; + + template<class Cont, class Func, class Out = FmapFlattenOut<Cont, Func>> + std::vector<Out> fmap_flatten(Cont&& xs, Func&& f) + { + std::vector<Out> ret; + + for (auto&& x : xs) + for (auto&& y : f(x)) + ret.push_back(std::move(y)); + + return ret; + } + + template<class Container, class Pred> + void stable_keep_if(Container& cont, Pred pred) + { + cont.erase(std::stable_partition(cont.begin(), cont.end(), pred), cont.end()); + } + + template<class Container, class Pred> + void unstable_keep_if(Container& cont, Pred pred) + { + cont.erase(std::partition(cont.begin(), cont.end(), pred), cont.end()); + } + + template<class Container, class Pred> + void erase_remove_if(Container& cont, Pred pred) + { + cont.erase(std::remove_if(cont.begin(), cont.end(), pred), cont.end()); + } + + template<class Container, class V> + auto find(Container&& cont, V&& v) + { + using std::begin; + using std::end; + return std::find(begin(cont), end(cont), v); + } + + template<class Container, class Pred> + auto find_if(Container&& cont, Pred pred) + { + using std::begin; + using std::end; + return std::find_if(begin(cont), end(cont), pred); + } + + template<class Container, class T = ElementT<Container>> + std::vector<T*> element_pointers(Container&& cont) + { + return fmap(cont, [](auto&& x) { return &x; }); + } + + template<class Container, class Pred> + 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<class K, class V, class Container, class Func> + void group_by(const Container& cont, std::map<K, std::vector<const V*>>* output, Func&& f) + { + for (const V& element : cont) + { + K key = f(element); + (*output)[key].push_back(&element); + } + } + + template<class Range> + void sort(Range& cont) + { + using std::begin; + using std::end; + std::sort(begin(cont), end(cont)); + } + + template<class Range> + 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<class Range1, class Range2> + 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<class AssocContainer, class K = std::decay_t<decltype(begin(std::declval<AssocContainer>())->first)>> + std::vector<K> 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; + + ~MoveOnlyBase() = default; + }; + + struct ResourceBase + { + ResourceBase() = default; + ResourceBase(const ResourceBase&) = delete; + ResourceBase(ResourceBase&&) = delete; + + ResourceBase& operator=(const ResourceBase&) = delete; + ResourceBase& operator=(ResourceBase&&) = delete; + + ~ResourceBase() = default; + }; + + template<class T> + struct LockGuardPtr; + + template<class T> + struct LockGuarded + { + friend struct LockGuardPtr<T>; + + LockGuardPtr<T> lock() { return *this; } + + private: + std::mutex m_mutex; + T m_t; + }; + + template<class T> + struct LockGuardPtr + { + T& operator*() { return m_ptr; } + T* operator->() { return &m_ptr; } + + T* get() { return &m_ptr; } + + LockGuardPtr(LockGuarded<T>& sync) : m_lock(sync.m_mutex), m_ptr(sync.m_t) {} + + private: + std::unique_lock<std::mutex> m_lock; + T& m_ptr; + }; + + namespace Enum + { + template<class E> + E to_enum(bool b) + { + return b ? E::YES : E::NO; + } + + template<class E> + bool to_bool(E e) + { + return e == E::YES; + } + } + + template<class T> + void unused(T&& param) + { + (void)param; + } +} diff --git a/toolsrc/include/BinaryParagraph.h b/toolsrc/include/vcpkg/binaryparagraph.h index 90ca8fe9a..3315151c6 100644 --- a/toolsrc/include/BinaryParagraph.h +++ b/toolsrc/include/vcpkg/binaryparagraph.h @@ -1,16 +1,21 @@ #pragma once -#include "PackageSpec.h" -#include "SourceParagraph.h" +#include <vcpkg/packagespec.h> +#include <vcpkg/sourceparagraph.h> + #include <unordered_map> namespace vcpkg { + /// <summary> + /// Built package metadata + /// </summary> struct BinaryParagraph { BinaryParagraph(); explicit BinaryParagraph(std::unordered_map<std::string, std::string> 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; @@ -22,7 +27,16 @@ namespace vcpkg std::string version; std::string description; std::string maintainer; + std::string feature; + std::vector<std::string> default_features; std::vector<std::string> depends; + std::string abi; + }; + + struct BinaryControlFile + { + BinaryParagraph core_paragraph; + std::vector<BinaryParagraph> features; }; void serialize(const BinaryParagraph& pgh, std::string& out_str); diff --git a/toolsrc/include/vcpkg/build.h b/toolsrc/include/vcpkg/build.h new file mode 100644 index 000000000..c5e7e8d88 --- /dev/null +++ b/toolsrc/include/vcpkg/build.h @@ -0,0 +1,237 @@ +#pragma once + +#include <vcpkg/packagespec.h> +#include <vcpkg/statusparagraphs.h> +#include <vcpkg/triplet.h> +#include <vcpkg/vcpkgcmdarguments.h> +#include <vcpkg/vcpkgpaths.h> + +#include <vcpkg/base/cstringview.h> +#include <vcpkg/base/files.h> +#include <vcpkg/base/optional.h> + +#include <array> +#include <map> +#include <set> +#include <vector> + +namespace vcpkg::Build +{ + namespace Command + { + 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); + } + + enum class UseHeadVersion + { + NO = 0, + YES + }; + + enum class AllowDownloads + { + NO = 0, + YES + }; + + enum class CleanBuildtrees + { + NO = 0, + YES + }; + + enum class CleanPackages + { + NO = 0, + YES + }; + + enum class ConfigurationType + { + DEBUG, + 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 + { + NULLVALUE = 0, + SUCCEEDED, + BUILD_FAILED, + POST_BUILD_CHECKS_FAILED, + FILE_CONFLICTS, + CASCADED_DUE_TO_MISSING_DEPENDENCIES, + EXCLUDED, + }; + + static constexpr std::array<BuildResult, 6> BUILD_RESULT_VALUES = { + BuildResult::SUCCEEDED, + BuildResult::BUILD_FAILED, + BuildResult::POST_BUILD_CHECKS_FAILED, + BuildResult::FILE_CONFLICTS, + 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); + std::string create_user_troubleshooting_message(const PackageSpec& spec); + + /// <summary> + /// Settings from the triplet file which impact the build environment and post-build checks + /// </summary> + struct PreBuildInfo + { + /// <summary> + /// Runs the triplet file in a "capture" mode to create a PreBuildInfo + /// </summary> + 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; + Optional<std::string> platform_toolset; + Optional<fs::path> visual_studio_path; + Optional<std::string> external_toolchain_file; + Optional<ConfigurationType> build_type; + }; + + std::string make_build_env_cmd(const PreBuildInfo& pre_build_info, const Toolset& toolset); + + struct ExtendedBuildResult + { + ExtendedBuildResult(BuildResult code); + ExtendedBuildResult(BuildResult code, std::vector<FeatureSpec>&& unmet_deps); + ExtendedBuildResult(BuildResult code, std::unique_ptr<BinaryControlFile>&& bcf); + + BuildResult code; + std::vector<FeatureSpec> unmet_dependencies; + std::unique_ptr<BinaryControlFile> binary_control_file; + }; + + struct BuildPackageConfig + { + BuildPackageConfig(const SourceControlFile& src, + const Triplet& triplet, + fs::path&& port_dir, + const BuildPackageOptions& build_package_options, + const std::set<std::string>& feature_list) + : scf(src) + , triplet(triplet) + , port_dir(std::move(port_dir)) + , build_package_options(build_package_options) + , feature_list(feature_list) + { + } + + const SourceControlFile& scf; + const Triplet& triplet; + fs::path port_dir; + const BuildPackageOptions& build_package_options; + const std::set<std::string>& 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<BuildPolicy, size_t(BuildPolicy::COUNT)> 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<BuildPolicy, bool>&& 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<BuildPolicy, bool> m_policies; + }; + + enum class LinkageType : char + { + DYNAMIC, + STATIC, + }; + + Optional<LinkageType> to_linkage_type(const std::string& str); + + struct BuildInfo + { + LinkageType crt_linkage = LinkageType::DYNAMIC; + LinkageType library_linkage = LinkageType::DYNAMIC; + + Optional<std::string> version; + + BuildPolicies policies; + }; + + BuildInfo read_build_info(const Files::Filesystem& fs, const fs::path& filepath); + + struct AbiEntry + { + std::string key; + std::string value; + + bool operator<(const AbiEntry& other) const + { + return key < other.key || (key == other.key && value < other.value); + } + }; + + struct AbiTagAndFile + { + std::string tag; + fs::path tag_file; + }; + + Optional<AbiTagAndFile> compute_abi_tag(const VcpkgPaths& paths, + const BuildPackageConfig& config, + const PreBuildInfo& pre_build_info, + Span<const AbiEntry> dependency_abis); +} diff --git a/toolsrc/include/vcpkg_Commands.h b/toolsrc/include/vcpkg/commands.h index 14d468352..21e77aa52 100644 --- a/toolsrc/include/vcpkg_Commands.h +++ b/toolsrc/include/vcpkg/commands.h @@ -1,10 +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 <vcpkg/statusparagraphs.h> +#include <vcpkg/vcpkgcmdarguments.h> +#include <vcpkg/vcpkgpaths.h> + #include <array> +#include <map> +#include <vector> namespace vcpkg::Commands { @@ -14,90 +18,48 @@ namespace vcpkg::Commands using CommandTypeB = void (*)(const VcpkgCmdArguments& args, const VcpkgPaths& paths); using CommandTypeC = void (*)(const VcpkgCmdArguments& args); - namespace BuildCommand - { - void perform_and_exit(const PackageSpec& spec, - const fs::path& port_dir, - const std::unordered_set<std::string>& 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 + namespace CI { - struct InstallDir + struct UnknownCIPortsResults { - 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; + std::vector<PackageSpec> unknown; + std::map<PackageSpec, Build::BuildResult> known; }; - void install_files_and_write_listfile(Files::Filesystem& fs, - const fs::path& source_dir, - const InstallDir& dirs); - void install_package(const VcpkgPaths& paths, - const BinaryParagraph& binary_paragraph, - 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 - { + extern const CommandStructure COMMAND_STRUCTURE; + UnknownCIPortsResults find_unknown_ports_for_ci(const VcpkgPaths& paths, + const std::set<std::string>& exclusions, + const Dependencies::PortFileProvider& provider, + const std::vector<FeatureSpec>& fspecs); void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet); } - namespace Remove + namespace Env { + extern const CommandStructure COMMAND_STRUCTURE; void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet); } - namespace Update + namespace Create { - struct OutdatedPackage - { - static bool compare_by_name(const OutdatedPackage& left, const OutdatedPackage& right); - - PackageSpec spec; - VersionDiff version_diff; - }; - - std::vector<OutdatedPackage> find_outdated_packages(const VcpkgPaths& paths, const StatusParagraphs& status_db); + extern const CommandStructure COMMAND_STRUCTURE; void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); } - namespace Env + namespace Upgrade { + extern const CommandStructure COMMAND_STRUCTURE; 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 { + extern const CommandStructure COMMAND_STRUCTURE; void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); } @@ -108,16 +70,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); } @@ -134,6 +99,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); } @@ -143,34 +109,39 @@ namespace vcpkg::Commands void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); } - namespace Help + namespace Autocomplete { 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 char* base_version(); const std::string& version(); + void warn_if_vcpkg_version_mismatch(const VcpkgPaths& paths); void perform_and_exit(const VcpkgCmdArguments& args); } namespace Contact { + extern const CommandStructure COMMAND_STRUCTURE; const std::string& email(); void perform_and_exit(const VcpkgCmdArguments& args); } namespace Hash { - void perform_and_exit(const VcpkgCmdArguments& args); + std::string get_string_hash(const std::string& s, 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<Toolset> 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); } template<class T> @@ -180,9 +151,9 @@ namespace vcpkg::Commands T function; }; - const std::vector<PackageNameAndFunction<CommandTypeA>>& get_available_commands_type_a(); - const std::vector<PackageNameAndFunction<CommandTypeB>>& get_available_commands_type_b(); - const std::vector<PackageNameAndFunction<CommandTypeC>>& get_available_commands_type_c(); + Span<const PackageNameAndFunction<CommandTypeA>> get_available_commands_type_a(); + Span<const PackageNameAndFunction<CommandTypeB>> get_available_commands_type_b(); + Span<const PackageNameAndFunction<CommandTypeC>> get_available_commands_type_c(); template<typename T> T find(const std::string& command_name, const std::vector<PackageNameAndFunction<T>> available_commands) diff --git a/toolsrc/include/vcpkg/dependencies.h b/toolsrc/include/vcpkg/dependencies.h new file mode 100644 index 000000000..3c3b8f267 --- /dev/null +++ b/toolsrc/include/vcpkg/dependencies.h @@ -0,0 +1,182 @@ +#pragma once + +#include <vcpkg/base/optional.h> +#include <vcpkg/base/util.h> +#include <vcpkg/build.h> +#include <vcpkg/packagespec.h> +#include <vcpkg/statusparagraphs.h> +#include <vcpkg/vcpkgpaths.h> + +#include <vector> + +namespace vcpkg::Dependencies +{ + enum class RequestType + { + UNKNOWN, + USER_REQUESTED, + 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); + + enum class InstallPlanType + { + UNKNOWN, + BUILD_AND_INSTALL, + ALREADY_INSTALLED, + EXCLUDED + }; + + struct InstallPlanAction : Util::MoveOnlyBase + { + static bool compare_by_name(const InstallPlanAction* left, const InstallPlanAction* right); + + InstallPlanAction() noexcept; + + InstallPlanAction(InstalledPackageView&& spghs, + const std::set<std::string>& features, + const RequestType& request_type); + + InstallPlanAction(const PackageSpec& spec, + const SourceControlFile& scf, + const std::set<std::string>& features, + const RequestType& request_type, + std::vector<PackageSpec>&& dependencies); + + std::string displayname() const; + + PackageSpec spec; + + Optional<const SourceControlFile&> source_control_file; + Optional<InstalledPackageView> installed_package; + + InstallPlanType plan_type; + RequestType request_type; + Build::BuildPackageOptions build_options; + std::set<std::string> feature_list; + + std::vector<PackageSpec> computed_dependencies; + }; + + enum class RemovePlanType + { + UNKNOWN, + NOT_INSTALLED, + REMOVE + }; + + struct RemovePlanAction : Util::MoveOnlyBase + { + static bool compare_by_name(const RemovePlanAction* left, const RemovePlanAction* right); + + RemovePlanAction() noexcept; + 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_action(std::move(iplan)) {} + AnyAction(RemovePlanAction&& rplan) : remove_action(std::move(rplan)) {} + + Optional<InstallPlanAction> install_action; + Optional<RemovePlanAction> remove_action; + + const PackageSpec& spec() const; + }; + + enum class ExportPlanType + { + UNKNOWN, + NOT_BUILT, + ALREADY_BUILT + }; + + struct ExportPlanAction : Util::MoveOnlyBase + { + static bool compare_by_name(const ExportPlanAction* left, const ExportPlanAction* right); + + ExportPlanAction() noexcept; + ExportPlanAction(const PackageSpec& spec, + InstalledPackageView&& installed_package, + const RequestType& request_type); + + ExportPlanAction(const PackageSpec& spec, const RequestType& request_type); + + PackageSpec spec; + ExportPlanType plan_type; + RequestType request_type; + + Optional<const BinaryParagraph&> core_paragraph() const; + std::vector<PackageSpec> dependencies(const Triplet& triplet) const; + + private: + Optional<InstalledPackageView> m_installed_package; + }; + + struct PortFileProvider + { + virtual Optional<const SourceControlFile&> get_control_file(const std::string& src_name) const = 0; + }; + + struct MapPortFileProvider : Util::ResourceBase, PortFileProvider + { + explicit MapPortFileProvider(const std::unordered_map<std::string, SourceControlFile>& map); + Optional<const SourceControlFile&> get_control_file(const std::string& src_name) const override; + + private: + const std::unordered_map<std::string, SourceControlFile>& ports; + }; + + struct PathsPortFileProvider : Util::ResourceBase, PortFileProvider + { + explicit PathsPortFileProvider(const VcpkgPaths& paths); + Optional<const SourceControlFile&> get_control_file(const std::string& src_name) const override; + + private: + const VcpkgPaths& ports; + mutable std::unordered_map<std::string, SourceControlFile> cache; + }; + + struct ClusterGraph; + struct GraphPlan; + + struct PackageGraph + { + PackageGraph(const PortFileProvider& provider, const StatusParagraphs& status_db); + ~PackageGraph(); + + void install(const FeatureSpec& spec, + const std::unordered_set<std::string>& prevent_default_features = {}) const; + void upgrade(const PackageSpec& spec) const; + + std::vector<AnyAction> serialize() const; + + private: + std::unique_ptr<GraphPlan> m_graph_plan; + std::unique_ptr<ClusterGraph> m_graph; + }; + + std::vector<RemovePlanAction> create_remove_plan(const std::vector<PackageSpec>& specs, + const StatusParagraphs& status_db); + + std::vector<ExportPlanAction> create_export_plan(const std::vector<PackageSpec>& specs, + const StatusParagraphs& status_db); + + std::vector<AnyAction> create_feature_install_plan(const std::unordered_map<std::string, SourceControlFile>& map, + const std::vector<FeatureSpec>& specs, + const StatusParagraphs& status_db); + + std::vector<AnyAction> create_feature_install_plan(const PortFileProvider& provider, + const std::vector<FeatureSpec>& specs, + const StatusParagraphs& status_db); + + void print_plan(const std::vector<AnyAction>& action_plan, const bool is_recursive = true); +} diff --git a/toolsrc/include/vcpkg/export.h b/toolsrc/include/vcpkg/export.h new file mode 100644 index 000000000..eb99b4fb1 --- /dev/null +++ b/toolsrc/include/vcpkg/export.h @@ -0,0 +1,12 @@ +#pragma once + +#include <vcpkg/vcpkgpaths.h> + +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/export.ifw.h b/toolsrc/include/vcpkg/export.ifw.h new file mode 100644 index 000000000..b1573924e --- /dev/null +++ b/toolsrc/include/vcpkg/export.ifw.h @@ -0,0 +1,24 @@ +#pragma once + +#include <vcpkg/dependencies.h> +#include <vcpkg/vcpkgpaths.h> + +#include <string> +#include <vector> + +namespace vcpkg::Export::IFW +{ + struct Options + { + Optional<std::string> maybe_repository_url; + Optional<std::string> maybe_packages_dir_path; + Optional<std::string> maybe_repository_dir_path; + Optional<std::string> maybe_config_file_path; + Optional<std::string> maybe_installer_file_path; + }; + + void do_export(const std::vector<Dependencies::ExportPlanAction>& 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..bc28e3ff8 --- /dev/null +++ b/toolsrc/include/vcpkg/globalstate.h @@ -0,0 +1,22 @@ +#pragma once + +#include <vcpkg/base/chrono.h> +#include <vcpkg/base/util.h> + +#include <atomic> + +namespace vcpkg +{ + struct GlobalState + { + static Util::LockGuarded<Chrono::ElapsedTimer> timer; + static Util::LockGuarded<std::string> g_surveydate; + + static std::atomic<bool> debugging; + static std::atomic<bool> feature_packages; + static std::atomic<bool> g_binary_caching; + + static std::atomic<int> g_init_console_cp; + static std::atomic<int> g_init_console_output_cp; + }; +} diff --git a/toolsrc/include/vcpkg/help.h b/toolsrc/include/vcpkg/help.h new file mode 100644 index 000000000..73549efd7 --- /dev/null +++ b/toolsrc/include/vcpkg/help.h @@ -0,0 +1,19 @@ +#pragma once + +#include <vcpkg/vcpkgcmdarguments.h> +#include <vcpkg/vcpkgpaths.h> + +#include <string> + +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(); + + 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 index 77f7ecfb5..621139427 100644 --- a/toolsrc/include/vcpkg_Input.h +++ b/toolsrc/include/vcpkg/input.h @@ -1,11 +1,15 @@ #pragma once -#include "PackageSpec.h" + +#include <vcpkg/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/install.h b/toolsrc/include/vcpkg/install.h new file mode 100644 index 000000000..b7acbf15f --- /dev/null +++ b/toolsrc/include/vcpkg/install.h @@ -0,0 +1,86 @@ +#pragma once + +#include <vcpkg/base/chrono.h> +#include <vcpkg/build.h> +#include <vcpkg/dependencies.h> +#include <vcpkg/vcpkgcmdarguments.h> +#include <vcpkg/vcpkgpaths.h> + +#include <vector> + +namespace vcpkg::Install +{ + enum class KeepGoing + { + NO = 0, + YES + }; + + inline KeepGoing to_keep_going(const bool value) { return value ? KeepGoing::YES : KeepGoing::NO; } + + struct SpecSummary + { + SpecSummary(const PackageSpec& spec, const Dependencies::AnyAction* action); + + const BinaryParagraph* get_binary_paragraph() const; + + PackageSpec spec; + Build::ExtendedBuildResult build_result; + vcpkg::Chrono::ElapsedTime timing; + + const Dependencies::AnyAction* action; + }; + + struct InstallSummary + { + std::vector<SpecSummary> results; + 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; + }; + + 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::ExtendedBuildResult perform_install_plan_action(const VcpkgPaths& paths, + const Dependencies::InstallPlanAction& action, + StatusParagraphs& status_db); + + enum class InstallResult + { + FILE_CONFLICTS, + SUCCESS, + }; + + std::vector<std::string> 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, + StatusParagraphs* status_db); + + InstallSummary perform(const std::vector<Dependencies::AnyAction>& action_plan, + const KeepGoing keep_going, + const VcpkgPaths& paths, + StatusParagraphs& status_db); + + 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/metrics.h b/toolsrc/include/vcpkg/metrics.h new file mode 100644 index 000000000..cb27ba58d --- /dev/null +++ b/toolsrc/include/vcpkg/metrics.h @@ -0,0 +1,28 @@ +#pragma once + +#include <vcpkg/base/util.h> + +#include <string> + +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); + 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); + void flush(); + }; + + extern Util::LockGuarded<Metrics> g_metrics; + + std::string get_MAC_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..299a9c401 --- /dev/null +++ b/toolsrc/include/vcpkg/packagespec.h @@ -0,0 +1,146 @@ +#pragma once + +#include <vcpkg/base/expected.h> +#include <vcpkg/packagespecparseresult.h> +#include <vcpkg/triplet.h> + +namespace vcpkg +{ + struct ParsedSpecifier + { + std::string name; + std::vector<std::string> features; + std::string triplet; + + static ExpectedT<ParsedSpecifier, PackageSpecParseResult> from_string(const std::string& input); + }; + + /// + /// <summary> + /// Full specification of a package. Contains all information to reference + /// a specific package. + /// </summary> + /// + struct PackageSpec + { + static ExpectedT<PackageSpec, PackageSpecParseResult> from_name_and_triplet(const std::string& name, + const Triplet& triplet); + + static std::vector<PackageSpec> to_package_specs(const std::vector<std::string>& ports, const Triplet& triplet); + + const std::string& name() const; + + const Triplet& triplet() const; + + std::string dir() const; + + 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; + }; + + /// + /// <summary> + /// Full specification of a feature. Contains all information to reference + /// a single feature in a specific package. + /// </summary> + /// + 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<FeatureSpec> from_strings_and_triplet(const std::vector<std::string>& 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; + }; + + /// + /// <summary> + /// Full specification of a package. Contains all information to reference + /// a collection of features in a single package. + /// </summary> + /// + struct FullPackageSpec + { + PackageSpec package_spec; + std::vector<std::string> features; + + static std::vector<FeatureSpec> to_feature_specs(const std::vector<FullPackageSpec>& specs); + + static ExpectedT<FullPackageSpec, PackageSpecParseResult> from_string(const std::string& spec_as_string, + const Triplet& default_triplet); + }; + + /// + /// <summary> + /// Contains all information to reference a collection of features in a single package by their names. + /// </summary> + /// + struct Features + { + std::string name; + std::vector<std::string> features; + + static ExpectedT<Features, PackageSpecParseResult> from_string(const std::string& input); + }; + + bool operator==(const PackageSpec& left, const PackageSpec& right); + bool operator!=(const PackageSpec& left, const PackageSpec& right); +} + +namespace std +{ + template<> + struct hash<vcpkg::PackageSpec> + { + size_t operator()(const vcpkg::PackageSpec& value) const + { + size_t hash = 17; + hash = hash * 31 + std::hash<std::string>()(value.name()); + hash = hash * 31 + std::hash<vcpkg::Triplet>()(value.triplet()); + return hash; + } + }; + + template<> + struct equal_to<vcpkg::PackageSpec> + { + 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..be3497152 --- /dev/null +++ b/toolsrc/include/vcpkg/packagespecparseresult.h @@ -0,0 +1,33 @@ +#pragma once + +#include <vcpkg/base/cstringview.h> +#include <vcpkg/base/expected.h> + +namespace vcpkg +{ + enum class PackageSpecParseResult + { + SUCCESS = 0, + TOO_MANY_COLONS, + INVALID_CHARACTERS + }; + + CStringView to_string(PackageSpecParseResult ev) noexcept; + + template<> + struct ErrorHolder<PackageSpecParseResult> + { + ErrorHolder() noexcept : m_err(PackageSpecParseResult::SUCCESS) {} + ErrorHolder(PackageSpecParseResult err) : m_err(err) {} + + 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/vcpkg/paragraphparseresult.h index eaa7e6327..558715bbc 100644 --- a/toolsrc/include/ParagraphParseResult.h +++ b/toolsrc/include/vcpkg/paragraphparseresult.h @@ -1,4 +1,5 @@ #pragma once + #include <system_error> namespace vcpkg @@ -25,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<vcpkg::ParagraphParseResult> : ::std::true_type +namespace std { -}; + // Enable implicit conversion to std::error_code + template<> + struct is_error_code_enum<vcpkg::ParagraphParseResult> : ::std::true_type + { + }; +}
\ No newline at end of file diff --git a/toolsrc/include/vcpkg/paragraphs.h b/toolsrc/include/vcpkg/paragraphs.h new file mode 100644 index 000000000..56f09387a --- /dev/null +++ b/toolsrc/include/vcpkg/paragraphs.h @@ -0,0 +1,32 @@ +#pragma once + +#include <vcpkg/binaryparagraph.h> +#include <vcpkg/parse.h> +#include <vcpkg/vcpkgpaths.h> + +#include <vcpkg/base/expected.h> + +namespace vcpkg::Paragraphs +{ + using RawParagraph = Parse::RawParagraph; + + Expected<RawParagraph> get_single_paragraph(const Files::Filesystem& fs, const fs::path& control_path); + Expected<std::vector<RawParagraph>> get_paragraphs(const Files::Filesystem& fs, const fs::path& control_path); + Expected<RawParagraph> parse_single_paragraph(const std::string& str); + Expected<std::vector<RawParagraph>> parse_paragraphs(const std::string& str); + + Parse::ParseExpected<SourceControlFile> try_load_port(const Files::Filesystem& fs, const fs::path& control_path); + + Expected<BinaryControlFile> try_load_cached_package(const VcpkgPaths& paths, const PackageSpec& spec); + + struct LoadResults + { + std::vector<std::unique_ptr<SourceControlFile>> paragraphs; + std::vector<std::unique_ptr<Parse::ParseControlErrorInfo>> errors; + }; + + LoadResults try_load_all_ports(const Files::Filesystem& fs, const fs::path& ports_dir); + + std::vector<std::unique_ptr<SourceControlFile>> load_all_ports(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 <vcpkg/base/expected.h> +#include <vcpkg/base/optional.h> + +#include <memory> +#include <unordered_map> + +namespace vcpkg::Parse +{ + struct ParseControlErrorInfo + { + std::string name; + std::vector<std::string> missing_fields; + std::vector<std::string> extra_fields; + std::error_code error; + }; + + template<class P> + using ParseExpected = ExpectedT<std::unique_ptr<P>, std::unique_ptr<ParseControlErrorInfo>>; + + using RawParagraph = std::unordered_map<std::string, std::string>; + + 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<ParseControlErrorInfo> error_info(const std::string& name) const; + + private: + RawParagraph&& fields; + std::vector<std::string> missing_fields; + }; + + std::vector<std::string> 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..0b469d9a0 --- /dev/null +++ b/toolsrc/include/vcpkg/postbuildlint.buildtype.h @@ -0,0 +1,64 @@ +#pragma once + +#include <vcpkg/base/cstringview.h> +#include <vcpkg/build.h> + +#include <array> +#include <regex> + +namespace vcpkg::PostBuildLint +{ + struct BuildType + { + enum class BackingEnum + { + DEBUG_STATIC = 1, + DEBUG_DYNAMIC, + RELEASE_STATIC, + RELEASE_DYNAMIC + }; + + static BuildType value_of(const Build::ConfigurationType& config, const Build::LinkageType& linkage); + + BuildType() = delete; + + constexpr BuildType(const BackingEnum backing_enum, + const Build::ConfigurationType config, + const Build::LinkageType linkage) + : backing_enum(backing_enum), m_config(config), m_linkage(linkage) + { + } + + constexpr operator BackingEnum() const { return backing_enum; } + + 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; + Build::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, 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, Build::ConfigurationType::RELEASE, LinkageType::STATIC}; + static constexpr BuildType RELEASE_DYNAMIC = { + BE::RELEASE_DYNAMIC, Build::ConfigurationType::RELEASE, LinkageType::DYNAMIC}; + + static constexpr std::array<BuildType, 4> VALUES = { + DEBUG_STATIC, DEBUG_DYNAMIC, RELEASE_STATIC, RELEASE_DYNAMIC}; + } +} diff --git a/toolsrc/include/PostBuildLint.h b/toolsrc/include/vcpkg/postbuildlint.h index 69fafc9f7..5dcfeb8df 100644 --- a/toolsrc/include/PostBuildLint.h +++ b/toolsrc/include/vcpkg/postbuildlint.h @@ -1,7 +1,8 @@ #pragma once -#include "PackageSpec.h" -#include "VcpkgPaths.h" -#include "vcpkg_Build.h" + +#include <vcpkg/build.h> +#include <vcpkg/packagespec.h> +#include <vcpkg/vcpkgpaths.h> namespace vcpkg::PostBuildLint { diff --git a/toolsrc/include/vcpkg/remove.h b/toolsrc/include/vcpkg/remove.h new file mode 100644 index 000000000..36aeda2ad --- /dev/null +++ b/toolsrc/include/vcpkg/remove.h @@ -0,0 +1,26 @@ +#pragma once + +#include <vcpkg/dependencies.h> +#include <vcpkg/vcpkgcmdarguments.h> +#include <vcpkg/vcpkgpaths.h> + +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); + + 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/include/vcpkg/sourceparagraph.h b/toolsrc/include/vcpkg/sourceparagraph.h new file mode 100644 index 000000000..ae5812ea7 --- /dev/null +++ b/toolsrc/include/vcpkg/sourceparagraph.h @@ -0,0 +1,106 @@ +#pragma once + +#include <vcpkg/packagespec.h> +#include <vcpkg/parse.h> + +#include <vcpkg/base/expected.h> +#include <vcpkg/base/span.h> +#include <vcpkg/base/system.h> + +#include <string> +#include <vector> + +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<std::string> filter_dependencies(const std::vector<Dependency>& deps, const Triplet& t); + std::vector<FeatureSpec> filter_dependencies_to_specs(const std::vector<Dependency>& deps, const Triplet& t); + + // zlib[uwp] becomes Dependency{"zlib", "uwp"} + std::vector<Dependency> expand_qualified_dependencies(const std::vector<std::string>& depends); + + std::string to_string(const Dependency& dep); + + /// <summary> + /// Port metadata of additional feature in a package (part of CONTROL file) + /// </summary> + struct FeatureParagraph + { + std::string name; + std::string description; + std::vector<Dependency> depends; + }; + + /// <summary> + /// Port metadata of the core feature of a package (part of CONTROL file) + /// </summary> + struct SourceParagraph + { + std::string name; + std::string version; + std::string description; + std::string maintainer; + std::vector<std::string> supports; + std::vector<Dependency> depends; + std::vector<std::string> default_features; + }; + + /// <summary> + /// Full metadata of a package: core and other features. + /// </summary> + struct SourceControlFile + { + static Parse::ParseExpected<SourceControlFile> parse_control_file( + std::vector<Parse::RawParagraph>&& control_paragraphs); + + std::unique_ptr<SourceParagraph> core_paragraph; + std::vector<std::unique_ptr<FeatureParagraph>> feature_paragraphs; + + Optional<const FeatureParagraph&> find_feature(const std::string& featurename) const; + }; + + void print_error_message(Span<const std::unique_ptr<Parse::ParseControlErrorInfo>> error_info_list); + inline void print_error_message(const std::unique_ptr<Parse::ParseControlErrorInfo>& error_info_list) + { + return print_error_message({&error_info_list, 1}); + } + + struct Supports + { + static ExpectedT<Supports, std::vector<std::string>> parse(const std::vector<std::string>& 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<Architecture> architectures; + std::vector<Platform> platforms; + std::vector<Linkage> crt_linkages; + std::vector<ToolsetVersion> toolsets; + }; +} diff --git a/toolsrc/include/vcpkg/statusparagraph.h b/toolsrc/include/vcpkg/statusparagraph.h new file mode 100644 index 000000000..e79c946cc --- /dev/null +++ b/toolsrc/include/vcpkg/statusparagraph.h @@ -0,0 +1,63 @@ +#pragma once + +#include <vcpkg/binaryparagraph.h> + +#include <unordered_map> + +namespace vcpkg +{ + enum class InstallState + { + ERROR_STATE, + NOT_INSTALLED, + HALF_INSTALLED, + INSTALLED, + }; + + enum class Want + { + ERROR_STATE, + UNKNOWN, + INSTALL, + HOLD, + DEINSTALL, + PURGE + }; + + /// <summary> + /// Installed package metadata + /// </summary> + struct StatusParagraph + { + StatusParagraph() noexcept; + explicit StatusParagraph(std::unordered_map<std::string, std::string>&& fields); + + bool is_installed() const { return want == Want::INSTALL && state == InstallState::INSTALLED; } + + 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); + + struct InstalledPackageView + { + InstalledPackageView() noexcept : core(nullptr) {} + + InstalledPackageView(const StatusParagraph* c, std::vector<const StatusParagraph*>&& fs) + : core(c), features(std::move(fs)) + { + } + + const PackageSpec& spec() const { return core->package.spec; } + std::vector<PackageSpec> dependencies() const; + + const StatusParagraph* core; + std::vector<const StatusParagraph*> features; + }; +} diff --git a/toolsrc/include/vcpkg/statusparagraphs.h b/toolsrc/include/vcpkg/statusparagraphs.h new file mode 100644 index 000000000..fa064de7e --- /dev/null +++ b/toolsrc/include/vcpkg/statusparagraphs.h @@ -0,0 +1,82 @@ +#pragma once +#include <vcpkg/statusparagraph.h> + +#include <iterator> +#include <memory> + +namespace vcpkg +{ + /// <summary>Status paragraphs</summary> + /// + /// Collection of <see cref="vcpkg::StatusParagraph"/>, e.g. contains the information + /// about whether a package is installed or not. + /// + struct StatusParagraphs + { + StatusParagraphs(); + explicit StatusParagraphs(std::vector<std::unique_ptr<StatusParagraph>>&& ps); + + using container = std::vector<std::unique_ptr<StatusParagraph>>; + using iterator = container::reverse_iterator; + using const_iterator = container::const_reverse_iterator; + + /// <summary>Find the StatusParagraph for given spec.</summary> + /// <param name="spec">Package specification to find the status paragraph for</param> + /// <returns>Iterator for found spec</returns> + const_iterator find(const PackageSpec& spec) const { return find(spec.name(), spec.triplet()); } + + /// <summary>Find the StatusParagraph for given feature spec.</summary> + /// <param name="spec">Feature specification to find the status paragraph for</param> + /// <returns>Iterator for found spec</returns> + const_iterator find(const FeatureSpec& spec) const { return find(spec.name(), spec.triplet(), spec.feature()); } + + /// <summary>Find a StatusParagraph by name, triplet and feature.</summary> + /// <param name="name">Package name</param> + /// <param name="triplet">Triplet</param> + /// <param name="feature">Feature name</param> + /// <returns>Iterator for found spec</returns> + 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<std::unique_ptr<StatusParagraph>*> find_all(const std::string& name, const Triplet& triplet); + + Optional<InstalledPackageView> find_all_installed(const PackageSpec& spec) const; + + /// <summary>Find the StatusParagraph for given spec if installed</summary> + /// <param name="spec">Package specification to find the status for</param> + /// <returns>Iterator for found spec</returns> + const_iterator find_installed(const PackageSpec& spec) const; + + /// <summary>Find the StatusParagraph for given feature spec if installed</summary> + /// <param name="spec">Feature specification to find the status for</param> + /// <returns>Iterator for found spec</returns> + const_iterator find_installed(const FeatureSpec& spec) const; + + /// <summary>Find the StatusParagraph for given spec and return its install status</summary> + /// <param name="spec">Package specification to check if installed</param> + /// <returns>`true` if installed, `false` if not or not found.</returns> + bool is_installed(const PackageSpec& spec) const; + + /// <summary>Find the StatusParagraph for given feature spec and return its install status</summary> + /// <param name="spec">Feature specification to check if installed</param> + /// <returns>`true` if installed, `false` if not or not found.</returns> + bool is_installed(const FeatureSpec& spec) const; + + iterator insert(std::unique_ptr<StatusParagraph>); + + 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<std::unique_ptr<StatusParagraph>> 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..334960e49 --- /dev/null +++ b/toolsrc/include/vcpkg/triplet.h @@ -0,0 +1,50 @@ +#pragma once + +#include <string> + +namespace vcpkg +{ + struct TripletInstance; + + struct Triplet + { + public: + constexpr Triplet() noexcept : 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; + 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; + 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; + + constexpr Triplet(const TripletInstance* ptr) : m_instance(ptr) {} + + const TripletInstance* m_instance; + }; + + bool operator!=(const Triplet& left, const Triplet& right); +} + +namespace std +{ + template<> + struct hash<vcpkg::Triplet> + { + 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..b85f7b2b3 --- /dev/null +++ b/toolsrc/include/vcpkg/update.h @@ -0,0 +1,24 @@ +#pragma once + +#include <vcpkg/dependencies.h> +#include <vcpkg/packagespec.h> +#include <vcpkg/statusparagraphs.h> +#include <vcpkg/vcpkgcmdarguments.h> +#include <vcpkg/vcpkgpaths.h> +#include <vcpkg/versiont.h> + +namespace vcpkg::Update +{ + struct OutdatedPackage + { + static bool compare_by_name(const OutdatedPackage& left, const OutdatedPackage& right); + + PackageSpec spec; + VersionDiff version_diff; + }; + + std::vector<OutdatedPackage> find_outdated_packages(const Dependencies::PortFileProvider& provider, + const StatusParagraphs& status_db); + + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); +} diff --git a/toolsrc/include/vcpkg/userconfig.h b/toolsrc/include/vcpkg/userconfig.h new file mode 100644 index 000000000..d044f43ef --- /dev/null +++ b/toolsrc/include/vcpkg/userconfig.h @@ -0,0 +1,22 @@ +#pragma once + +#include <string> +#include <vcpkg/base/files.h> + +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; + }; + + fs::path get_user_dir(); +} diff --git a/toolsrc/include/vcpkg/vcpkgcmdarguments.h b/toolsrc/include/vcpkg/vcpkgcmdarguments.h new file mode 100644 index 000000000..de65eec28 --- /dev/null +++ b/toolsrc/include/vcpkg/vcpkgcmdarguments.h @@ -0,0 +1,93 @@ +#pragma once + +#include <vcpkg/base/optional.h> +#include <vcpkg/base/span.h> +#include <vcpkg/base/stringliteral.h> + +#include <memory> +#include <unordered_map> +#include <unordered_set> +#include <vector> + +namespace vcpkg +{ + struct ParsedArguments + { + std::unordered_set<std::string> switches; + std::unordered_map<std::string, std::string> settings; + }; + + struct VcpkgPaths; + + struct CommandSwitch + { + 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 + { + 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 + { + Span<const CommandSwitch> switches; + Span<const CommandSetting> settings; + }; + + struct CommandStructure + { + std::string example_text; + + size_t minimum_arity; + size_t maximum_arity; + + CommandOptionsStructure options; + + std::vector<std::string> (*valid_arguments)(const VcpkgPaths& paths); + }; + + void display_usage(const CommandStructure& command_structure); + +#if defined(_WIN32) + using CommandLineCharType = wchar_t; +#else + 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<std::string> vcpkg_root_dir; + std::unique_ptr<std::string> triplet; + Optional<bool> debug = nullopt; + Optional<bool> sendmetrics = nullopt; + Optional<bool> printmetrics = nullopt; + + // feature flags + Optional<bool> featurepackages = nullopt; + Optional<bool> binarycaching = nullopt; + + std::string command; + std::vector<std::string> command_arguments; + + ParsedArguments parse_arguments(const CommandStructure& command_structure) const; + + private: + std::unordered_map<std::string, Optional<std::string>> optional_command_arguments; + }; +} diff --git a/toolsrc/include/vcpkg/vcpkglib.h b/toolsrc/include/vcpkg/vcpkglib.h new file mode 100644 index 000000000..5674d30db --- /dev/null +++ b/toolsrc/include/vcpkg/vcpkglib.h @@ -0,0 +1,24 @@ +#pragma once + +#include <vcpkg/base/sortedvector.h> +#include <vcpkg/statusparagraphs.h> +#include <vcpkg/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<std::string> files; + }; + + std::vector<InstalledPackageView> get_installed_ports(const StatusParagraphs& status_db); + std::vector<StatusParagraphAndAssociatedFiles> get_installed_files(const VcpkgPaths& paths, + const StatusParagraphs& status_db); + + std::string shorten_text(const std::string& desc, const 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..a3c90fd33 --- /dev/null +++ b/toolsrc/include/vcpkg/vcpkgpaths.h @@ -0,0 +1,98 @@ +#pragma once + +#include <vcpkg/binaryparagraph.h> +#include <vcpkg/packagespec.h> + +#include <vcpkg/base/cache.h> +#include <vcpkg/base/expected.h> +#include <vcpkg/base/files.h> +#include <vcpkg/base/lazy.h> + +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; + System::CPUArchitecture host_arch; + System::CPUArchitecture target_arch; + }; + + struct Toolset + { + fs::path visual_studio_root_path; + fs::path dumpbin; + fs::path vcvarsall; + std::vector<std::string> vcvarsall_options; + CStringView version; + std::vector<ToolsetArchOption> supported_architectures; + }; + + namespace Build + { + struct PreBuildInfo; + } + + struct VcpkgPaths + { + static Expected<VcpkgPaths> 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; + 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; + + const std::vector<std::string>& get_available_triplets() 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 tools; + 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_tool_exe(const std::string& tool) const; + + /// <summary>Retrieve a toolset matching a VS version</summary> + /// <remarks> + /// Valid version strings are "v120", "v140", "v141", and "". Empty string gets the latest. + /// </remarks> + const Toolset& get_toolset(const Build::PreBuildInfo& prebuildinfo) const; + + Files::Filesystem& get_filesystem() const; + + private: + Lazy<std::vector<std::string>> available_triplets; + Cache<std::string, fs::path> tool_paths; + Lazy<std::vector<Toolset>> toolsets; + Lazy<std::vector<Toolset>> toolsets_vs2013; + + fs::path default_vs_path; + }; +} diff --git a/toolsrc/include/VersionT.h b/toolsrc/include/vcpkg/versiont.h index 67efd8da3..e893f1abc 100644 --- a/toolsrc/include/VersionT.h +++ b/toolsrc/include/vcpkg/versiont.h @@ -5,11 +5,13 @@ namespace vcpkg { struct VersionT { - VersionT(); + VersionT() noexcept; + VersionT(std::string&& value); VersionT(const std::string& value); - std::string to_string() const; + const std::string& to_string() const; + private: std::string value; }; @@ -21,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/include/vcpkg_Build.h b/toolsrc/include/vcpkg_Build.h deleted file mode 100644 index 4deb81900..000000000 --- a/toolsrc/include/vcpkg_Build.h +++ /dev/null @@ -1,85 +0,0 @@ -#pragma once - -#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 <map> -#include <unordered_map> -#include <vector> - -namespace vcpkg::Build -{ - enum class BuildResult - { - NULLVALUE = 0, - SUCCEEDED, - BUILD_FAILED, - POST_BUILD_CHECKS_FAILED, - CASCADED_DUE_TO_MISSING_DEPENDENCIES - }; - - static constexpr std::array<BuildResult, 4> BuildResult_values = { - BuildResult::SUCCEEDED, - BuildResult::BUILD_FAILED, - BuildResult::POST_BUILD_CHECKS_FAILED, - 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); - - struct 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; - std::string platform_toolset; - }; - - std::wstring make_build_env_cmd(const PreBuildInfo& pre_build_info, const Toolset& toolset); - - struct ExtendedBuildResult - { - BuildResult code; - std::vector<PackageSpec> unmet_dependencies; - }; - - 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) - { - } - - const SourceParagraph& src; - const Triplet& triplet; - fs::path port_dir; - - bool use_head_version; - bool no_downloads; - }; - - ExtendedBuildResult build_package(const VcpkgPaths& paths, - const BuildPackageConfig& config, - const StatusParagraphs& status_db); - - struct BuildInfo - { - static BuildInfo create(std::unordered_map<std::string, std::string> pgh); - - PostBuildLint::LinkageType crt_linkage; - PostBuildLint::LinkageType library_linkage; - - Optional<std::string> version; - - std::map<PostBuildLint::BuildPolicies, bool> 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 6d8ff5711..000000000 --- a/toolsrc/include/vcpkg_Checks.h +++ /dev/null @@ -1,45 +0,0 @@ -#pragma once - -#include "LineInfo.h" -#include "vcpkg_Strings.h" - -namespace vcpkg::Checks -{ - [[noreturn]] void unreachable(const LineInfo& line_info); - - [[noreturn]] void exit_with_code(const LineInfo& line_info, const int exit_code); - - [[noreturn]] inline void exit_fail(const LineInfo& line_info) { exit_with_code(line_info, EXIT_FAILURE); } - - [[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. - [[noreturn]] void exit_with_message(const LineInfo& line_info, const CStringView errorMessage); - - template<class Arg1, class... Args> - [[noreturn]] void exit_with_message(const LineInfo& line_info, - const char* errorMessageTemplate, - const Arg1 errorMessageArg1, - const Args&... errorMessageArgs) - { - exit_with_message(line_info, Strings::format(errorMessageTemplate, errorMessageArg1, errorMessageArgs...)); - } - - void check_exit(const LineInfo& line_info, bool expression); - - void check_exit(const LineInfo& line_info, bool expression, const CStringView errorMessage); - - template<class Conditional, class Arg1, class... Args> - void check_exit(const LineInfo& line_info, - Conditional&& expression, - const char* errorMessageTemplate, - const Arg1 errorMessageArg1, - const Args&... errorMessageArgs) - { - if (!expression) - { - // Only create the string if the expression is false - exit_with_message(line_info, Strings::format(errorMessageTemplate, errorMessageArg1, errorMessageArgs...)); - } - } -} 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 <chrono> -#include <string> - -namespace vcpkg -{ - class ElapsedTime - { - public: - static ElapsedTime create_started(); - - constexpr ElapsedTime() : m_start_tick() {} - - template<class TimeUnit> - TimeUnit elapsed() const - { - return std::chrono::duration_cast<TimeUnit>(std::chrono::high_resolution_clock::now() - this->m_start_tick); - } - - double microseconds() const { return elapsed<std::chrono::duration<double, std::micro>>().count(); } - - std::string to_string() const; - - private: - std::chrono::high_resolution_clock::time_point m_start_tick; - }; -} diff --git a/toolsrc/include/vcpkg_Dependencies.h b/toolsrc/include/vcpkg_Dependencies.h deleted file mode 100644 index 018c4f5cf..000000000 --- a/toolsrc/include/vcpkg_Dependencies.h +++ /dev/null @@ -1,110 +0,0 @@ -#pragma once -#include "PackageSpec.h" -#include "StatusParagraphs.h" -#include "VcpkgPaths.h" -#include "vcpkg_optional.h" -#include <vector> - -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<PackageSpec> dependencies(const Triplet& triplet) const; - - Optional<StatusParagraph> status_paragraph; - Optional<BinaryParagraph> binary_paragraph; - Optional<SourceParagraph> source_paragraph; - }; - - enum class InstallPlanType - { - UNKNOWN, - BUILD_AND_INSTALL, - INSTALL, - ALREADY_INSTALLED - }; - - struct InstallPlanAction - { - static bool compare_by_name(const InstallPlanAction* left, const InstallPlanAction* right); - - InstallPlanAction(); - InstallPlanAction(const PackageSpec& spec, const AnyParagraph& any_paragraph, const RequestType& request_type); - InstallPlanAction(const InstallPlanAction&) = delete; - InstallPlanAction(InstallPlanAction&&) = default; - InstallPlanAction& operator=(const InstallPlanAction&) = delete; - InstallPlanAction& operator=(InstallPlanAction&&) = default; - - PackageSpec spec; - AnyParagraph any_paragraph; - InstallPlanType plan_type; - RequestType request_type; - }; - - enum class RemovePlanType - { - UNKNOWN, - NOT_INSTALLED, - REMOVE - }; - - struct RemovePlanAction - { - 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; - RequestType request_type; - }; - - enum class ExportPlanType - { - UNKNOWN, - PORT_AVAILABLE_BUT_NOT_BUILT, - ALREADY_BUILT - }; - - struct ExportPlanAction - { - 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; - ExportPlanType plan_type; - RequestType request_type; - }; - - std::vector<InstallPlanAction> create_install_plan(const VcpkgPaths& paths, - const std::vector<PackageSpec>& specs, - const StatusParagraphs& status_db); - - std::vector<RemovePlanAction> create_remove_plan(const std::vector<PackageSpec>& specs, - const StatusParagraphs& status_db); - - std::vector<ExportPlanAction> create_export_plan(const VcpkgPaths& paths, - const std::vector<PackageSpec>& specs, - const StatusParagraphs& status_db); -} diff --git a/toolsrc/include/vcpkg_Graphs.h b/toolsrc/include/vcpkg_Graphs.h deleted file mode 100644 index 3c8c024c2..000000000 --- a/toolsrc/include/vcpkg_Graphs.h +++ /dev/null @@ -1,66 +0,0 @@ -#pragma once - -#include <unordered_map> - -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<class V, class U> - __interface AdjacencyProvider - { - std::vector<V> adjacency_list(const U& vertex) const; - - U load_vertex_data(const V& vertex) const; - }; - - template<class V, class U> - static void topological_sort_internal(const V& vertex, - const AdjacencyProvider<V, U>& f, - std::unordered_map<V, ExplorationStatus>& exploration_status, - std::vector<U>& 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<class V, class U> - std::vector<U> topological_sort(const std::vector<V>& starting_vertices, const AdjacencyProvider<V, U>& f) - { - std::vector<U> sorted; - std::unordered_map<V, ExplorationStatus> exploration_status; - - for (auto& vertex : starting_vertices) - { - topological_sort_internal(vertex, f, exploration_status, sorted); - } - - return sorted; - } -} 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 <map> -#include <unordered_map> -#include <unordered_set> - -namespace vcpkg::Maps -{ - template<typename K, typename V> - std::vector<K> extract_keys(const std::unordered_map<K, V>& input_map) - { - std::vector<K> key_set; - for (auto const& element : input_map) - { - key_set.push_back(element.first); - } - return key_set; - } - - template<typename K, typename V> - std::vector<K> extract_keys(const std::map<K, V>& input_map) - { - std::vector<K> key_set; - for (auto const& element : input_map) - { - key_set.push_back(element.first); - } - return key_set; - } -} diff --git a/toolsrc/include/vcpkg_Strings.h b/toolsrc/include/vcpkg_Strings.h deleted file mode 100644 index 3f8f4562e..000000000 --- a/toolsrc/include/vcpkg_Strings.h +++ /dev/null @@ -1,103 +0,0 @@ -#pragma once - -#include "CStringView.h" -#include <vector> - -namespace vcpkg::Strings::details -{ - template<class T> - 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 double to_printf_arg(const double s) { return s; } - - inline size_t to_printf_arg(const size_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 -{ - template<class... Args> - 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<class... Args> - 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); - - int case_insensitive_ascii_compare(const CStringView left, const CStringView right); - - std::string ascii_to_lowercase(const std::string& input); - - template<class T, class Transformer, class CharType> - std::basic_string<CharType> join(const CharType* delimiter, const std::vector<T>& v, Transformer transformer) - { - if (v.empty()) - { - return std::basic_string<CharType>(); - } - - std::basic_string<CharType> output; - size_t size = v.size(); - - output.append(transformer(v.at(0))); - - for (size_t i = 1; i < size; ++i) - { - output.append(delimiter); - output.append(transformer(v.at(i))); - } - - return output; - } - template<class T, class CharType> - std::basic_string<CharType> join(const CharType* delimiter, const std::vector<T>& v) - { - return join(delimiter, v, [](const T& x) -> const T& { return x; }); - } - - void trim(std::string* s); - - std::string trimmed(const std::string& s); - - void trim_all_and_remove_whitespace_strings(std::vector<std::string>* strings); - - std::vector<std::string> split(const std::string& s, const std::string& delimiter); - - template<class T> - 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 2ea0241f6..000000000 --- a/toolsrc/include/vcpkg_System.h +++ /dev/null @@ -1,104 +0,0 @@ -#pragma once - -#include "filesystem_fs.h" -#include "vcpkg_Strings.h" -#include "vcpkg_optional.h" -#include <Windows.h> - -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 = L""); - - enum class Color - { - success = 10, - error = 12, - warning = 14, - }; - - 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<class Arg1, class... Args> - void print(const char* messageTemplate, const Arg1& messageArg1, const Args&... messageArgs) - { - return System::print(Strings::format(messageTemplate, messageArg1, messageArgs...)); - } - - template<class Arg1, class... Args> - void print(const Color c, const char* messageTemplate, const Arg1& messageArg1, const Args&... messageArgs) - { - return System::print(c, Strings::format(messageTemplate, messageArg1, messageArgs...)); - } - - template<class Arg1, class... Args> - void println(const char* messageTemplate, const Arg1& messageArg1, const Args&... messageArgs) - { - return System::println(Strings::format(messageTemplate, messageArg1, messageArgs...)); - } - - template<class Arg1, class... Args> - void println(const Color c, const char* messageTemplate, const Arg1& messageArg1, const Args&... messageArgs) - { - return System::println(c, Strings::format(messageTemplate, messageArg1, messageArgs...)); - } - - Optional<std::wstring> get_environment_variable(const CWStringView varname) noexcept; - - Optional<std::wstring> get_registry_string(HKEY base, const CWStringView subkey, const CWStringView valuename); - - enum class CPUArchitecture - { - X86, - X64, - ARM, - ARM64, - }; - - Optional<CPUArchitecture> to_cpu_architecture(CStringView arch); - - CPUArchitecture get_host_processor(); - - const fs::path& get_ProgramFiles_32_bit(); - - const fs::path& get_ProgramFiles_platform_bitness(); -} - -namespace vcpkg::Debug -{ - void println(const CStringView message); - void println(const System::Color c, const CStringView message); - - template<class Arg1, class... Args> - void println(const char* messageTemplate, const Arg1& messageArg1, const Args&... messageArgs) - { - return Debug::println(Strings::format(messageTemplate, messageArg1, messageArgs...)); - } - - template<class Arg1, class... Args> - 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 6648302ac..000000000 --- a/toolsrc/include/vcpkg_Util.h +++ /dev/null @@ -1,58 +0,0 @@ -#pragma once - -#include <utility> -#include <vector> - -namespace vcpkg::Util -{ - template<class Cont, class Func> - using FmapOut = decltype(std::declval<Func>()(std::declval<Cont>()[0])); - - template<class Cont, class Func, class Out = FmapOut<Cont, Func>> - std::vector<Out> fmap(const Cont& xs, Func&& f) - { - using O = decltype(f(xs[0])); - - std::vector<O> ret; - ret.reserve(xs.size()); - - for (auto&& x : xs) - ret.push_back(f(x)); - - return ret; - } - - template<class Container, class Pred> - void unstable_keep_if(Container& cont, Pred pred) - { - cont.erase(std::partition(cont.begin(), cont.end(), pred), cont.end()); - } - - template<class Container, class Pred> - void erase_remove_if(Container& cont, Pred pred) - { - cont.erase(std::remove_if(cont.begin(), cont.end(), pred), cont.end()); - } - - template<class Container, class Pred> - auto find_if(const Container& cont, Pred pred) - { - return std::find_if(cont.cbegin(), cont.cend(), pred); - } - - template<class Container, class Pred> - auto find_if_not(const Container& cont, Pred pred) - { - return std::find_if_not(cont.cbegin(), cont.cend(), pred); - } - - template<class K, class V, class Container, class Func> - void group_by(const Container& cont, std::map<K, std::vector<const V*>>* output, Func f) - { - for (const V& element : cont) - { - K key = f(element); - (*output)[key].push_back(&element); - } - } -}
\ 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 3a920022b..000000000 --- a/toolsrc/include/vcpkg_expected.h +++ /dev/null @@ -1,69 +0,0 @@ -#pragma once - -#include "vcpkg_Checks.h" -#include <system_error> - -namespace vcpkg -{ - template<class T> - class Expected - { - public: - // Constructors are intentionally implicit - Expected(const std::error_code& ec) : m_error_code(ec), m_t() {} - - Expected(std::errc ec) : Expected(std::make_error_code(ec)) {} - - Expected(const T& t) : m_error_code(), m_t(t) {} - - Expected(T&& t) : m_error_code(), m_t(std::move(t)) {} - - Expected() : Expected(std::error_code(), T()) {} - - Expected(const Expected&) = default; - Expected(Expected&&) = default; - Expected& operator=(const Expected&) = default; - Expected& operator=(Expected&&) = default; - - std::error_code error_code() const { return this->m_error_code; } - - 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 T* get() const - { - if (m_error_code) - { - return nullptr; - } - return &this->m_t; - } - - T* get() - { - if (m_error_code) - { - return nullptr; - } - return &this->m_t; - } - - private: - void exit_if_error(const LineInfo& line_info) const - { - Checks::check_exit(line_info, !this->m_error_code, this->m_error_code.message()); - } - - std::error_code m_error_code; - T m_t; - }; -} diff --git a/toolsrc/include/vcpkg_optional.h b/toolsrc/include/vcpkg_optional.h deleted file mode 100644 index 03fa50678..000000000 --- a/toolsrc/include/vcpkg_optional.h +++ /dev/null @@ -1,92 +0,0 @@ -#pragma once -#include "vcpkg_Checks.h" - -namespace vcpkg -{ - struct NullOpt - { - explicit constexpr NullOpt(int) {} - }; - - const static constexpr NullOpt nullopt{0}; - - template<class T> - 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<class U> - T value_or(U&& default_value) const & - { - return bool(*this) ? this->m_t : static_cast<T>(std::forward<U>(default_value)); - } - - template<class U> - T value_or(U&& default_value) && - { - return bool(*this) ? std::move(this->m_t) : static_cast<T>(std::forward<U>(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<class T> - bool operator==(const Optional<T>& o, const T& t) - { - if (auto p = o.get()) return *p == t; - return false; - } - template<class T> - bool operator==(const T& t, const Optional<T>& o) - { - if (auto p = o.get()) return t == *p; - return false; - } - template<class T> - bool operator!=(const Optional<T>& o, const T& t) - { - if (auto p = o.get()) return *p != t; - return true; - } - template<class T> - bool operator!=(const T& t, const Optional<T>& 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 df64e5463..000000000 --- a/toolsrc/include/vcpkglib.h +++ /dev/null @@ -1,39 +0,0 @@ -#pragma once - -#include "SortedVector.h" -#include "StatusParagraphs.h" -#include "VcpkgPaths.h" - -namespace vcpkg -{ - extern bool g_debugging; - - StatusParagraphs database_load_check(const VcpkgPaths& paths); - - void write_update(const VcpkgPaths& paths, const StatusParagraph& p); - - struct StatusParagraphAndAssociatedFiles - { - StatusParagraph pgh; - SortedVector<std::string> files; - }; - - std::vector<StatusParagraph*> get_installed_ports(const StatusParagraphs& status_db); - std::vector<StatusParagraphAndAssociatedFiles> 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<CMakeVariable>& pass_variables); - -} // 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 <unordered_map> - -namespace vcpkg::details -{ - std::string optional_field(const std::unordered_map<std::string, std::string>& fields, - const std::string& fieldname); - std::string remove_optional_field(std::unordered_map<std::string, std::string>* fields, - const std::string& fieldname); - - std::string required_field(const std::unordered_map<std::string, std::string>& fields, - const std::string& fieldname); - std::string remove_required_field(std::unordered_map<std::string, std::string>* fields, - const std::string& fieldname); - - std::string shorten_description(const std::string& desc); -} |
