From 917e69ef6819d83e1aef651e2c9b4230dfe31f32 Mon Sep 17 00:00:00 2001 From: data-queue <144965964+data-queue@users.noreply.github.com> Date: Thu, 12 Sep 2024 04:34:02 +0000 Subject: [PATCH 01/30] Move vcpkgTools.xml into the tool --- .../end-to-end-tests-dir/fetch.ps1 | 101 ---- include/vcpkg/tools.h | 1 - include/vcpkg/tools.test.h | 2 - src/vcpkg-test/tools.cpp | 75 --- src/vcpkg.cpp | 2 +- src/vcpkg/tools.cpp | 484 +++++++++++++++--- src/vcpkg/vcpkgpaths.cpp | 1 - 7 files changed, 416 insertions(+), 250 deletions(-) delete mode 100644 azure-pipelines/end-to-end-tests-dir/fetch.ps1 diff --git a/azure-pipelines/end-to-end-tests-dir/fetch.ps1 b/azure-pipelines/end-to-end-tests-dir/fetch.ps1 deleted file mode 100644 index 831b70f1cb..0000000000 --- a/azure-pipelines/end-to-end-tests-dir/fetch.ps1 +++ /dev/null @@ -1,101 +0,0 @@ -. $PSScriptRoot/../end-to-end-tests-prelude.ps1 - -if (-not $IsMacOS -and -not $IsLinux) { - "" | Out-File -enc ascii $(Join-Path $TestingRoot .vcpkg-root) - - $Scripts = Join-Path $TestingRoot "scripts" - mkdir $Scripts | Out-Null - -@" - - - - 19.00 - Files\7-Zip\7z.exe - https://www.7-zip.org/a/7z1900-x64.msi - 7837a8677a01eed9c3309923f7084bc864063ba214ee169882c5b04a7a8b198ed052c15e981860d9d7952c98f459a4fab87a72fd78e7d0303004dcb86f4324c8 - 7z1900-x64.msi - - - 1.10.2 - ninja.exe - https://github.com/ninja-build/ninja/releases/download/v1.10.2/ninja-win.zip - 6004140d92e86afbb17b49c49037ccd0786ce238f340f7d0e62b4b0c29ed0d6ad0bab11feda2094ae849c387d70d63504393714ed0a1f4d3a1f155af7a4f1ba3 - ninja-win-1.10.2.zip - - - 1.10.2 - ninja.exe - https://github.com/ninja-build/ninja/releases/download/v1.10.2/ninja-win.zip - 6004140d92e86afbb17b49c49037ccd0786ce238f340f7d0e62b4b0c29ed0d6ad0bab11feda2094ae849c387d70d63504393714ed0a1f4d3a1f155af7a4f1ba3 - ninja-win-1.10.2.zip - - - 3.22.2 - cmake-3.22.2-windows-i386\bin\cmake.exe - https://github.com/Kitware/CMake/releases/download/v3.22.2/cmake-3.22.2-windows-i386.zip - 969d3d58d56d8fa3cc3acae2b949bf58abab945f70ae292ff20c9060d845dfc094c613c367a924abff47f307cc33af1467cdb9b75bb857868e38b2c7cdc72f79 - cmake-3.22.2-windows-i386.zip - - - 3.22.2 - cmake-3.22.2-macos-universal/CMake.app/Contents/bin/cmake - https://github.com/Kitware/CMake/releases/download/v3.22.2/cmake-3.22.2-macos-universal.tar.gz - 08104f608ecb9a5cfef38e79f0957d21e425616c0677781445492f82cbfec805113e3b5eb4bc737b707bb26a00678e7bd55e17555a5611c08b0b9b44ac5136ac - cmake-3.22.2-macos-universal.tar.gz - - - 3.22.2 - cmake-3.22.2-linux-x86_64/bin/cmake - https://github.com/Kitware/CMake/releases/download/v3.22.2/cmake-3.22.2-linux-x86_64.tar.gz - 579e08b086f6903ef063697fca1dc2692f68a7341dd35998990b772b4221cdb5b1deecfa73bad9d46817ef09e58882b2adff9d64f959c01002c11448a878746b - cmake-3.22.2linux-x86_64.tar.gz - - - 3.20.4 - usr/local/bin/cmake - https://pkg.freebsd.org/FreeBSD:13:amd64/quarterly/All/cmake-3.20.4.txz - 3e5b675d7ff924f92996d912e2365582e687375109ef99c9073fb8196bb329243a406b218cf1358d7cc518988b311ce9e5bf87de4d64f2e6377b7c2bc8894475 - cmake-3.20.4.txz - - -"@ | % { $_ -replace "`r","" } | Out-File -enc ascii $(Join-Path $Scripts "vcpkgTools.xml") - - $env:VCPKG_DOWNLOADS = Join-Path $TestingRoot 'down loads' - Run-Vcpkg -TestArgs ($commonArgs + @("fetch", "7zip", "--vcpkg-root=$TestingRoot")) - Throw-IfFailed - Require-FileExists "$TestingRoot/down loads/tools/7zip-19.00-windows/Files/7-Zip/7z.exe" - - Run-Vcpkg -TestArgs ($commonArgs + @("fetch", "ninja-testing", "--vcpkg-root=$TestingRoot")) - Throw-IfFailed - Require-FileExists "$TestingRoot/down loads/tools/ninja-testing-1.10.2-windows/ninja.exe" - - $path = $env:PATH - - $env:PATH = "$path;$TestingRoot/down loads/tools/ninja-testing-1.10.2-windows" - Run-Vcpkg -TestArgs ($commonArgs + @("fetch", "ninja", "--vcpkg-root=$TestingRoot")) - Throw-IfFailed - Require-FileNotExists "$TestingRoot/down loads/tools/ninja-1.10.2-windows/ninja.exe" - - $env:VCPKG_FORCE_DOWNLOADED_BINARIES = "1" - Run-Vcpkg -TestArgs ($commonArgs + @("fetch", "ninja", "--vcpkg-root=$TestingRoot")) - Throw-IfFailed - Require-FileExists "$TestingRoot/down loads/tools/ninja-1.10.2-windows/ninja.exe" - - Remove-Item -Recurse -Force "$TestingRoot/down loads/tools/ninja-1.10.2-windows" -ErrorAction SilentlyContinue - Remove-Item env:VCPKG_FORCE_DOWNLOADED_BINARIES - - $env:VCPKG_FORCE_SYSTEM_BINARIES = "1" - $env:PATH = "$PSScriptRoot\..\e2e-assets\fetch;$path" - Run-Vcpkg -TestArgs ($commonArgs + @("fetch", "ninja", "--vcpkg-root=$TestingRoot")) - Throw-IfFailed - Require-FileNotExists "$TestingRoot/down loads/tools/ninja-1.10.2-windows/ninja.exe" - - Remove-Item env:VCPKG_FORCE_SYSTEM_BINARIES - $out = Run-VcpkgAndCaptureOutput -TestArgs ($commonArgs + @("fetch", "ninja", "--vcpkg-root=$TestingRoot", "--x-stderr-status")) - Throw-IfFailed - & $out --version - if ($LASTEXITCODE -ne 0) { - throw 'Couldn''t run resulting ninja' - } -} diff --git a/include/vcpkg/tools.h b/include/vcpkg/tools.h index 9e0e6b0b6e..5419bab4ff 100644 --- a/include/vcpkg/tools.h +++ b/include/vcpkg/tools.h @@ -57,7 +57,6 @@ namespace vcpkg std::unique_ptr get_tool_cache(const Filesystem& fs, std::shared_ptr downloader, Path downloads, - Path xml_config, Path tools, RequireExactVersions abiToolVersionHandling); } diff --git a/include/vcpkg/tools.test.h b/include/vcpkg/tools.test.h index 212d41ba65..62a47eeca1 100644 --- a/include/vcpkg/tools.test.h +++ b/include/vcpkg/tools.test.h @@ -29,7 +29,5 @@ namespace vcpkg Path exe_path(const Path& tools_base_path) const { return tools_base_path / tool_dir_subpath / exe_subpath; } }; - Optional parse_tool_data_from_xml(StringView XML, StringView XML_PATH, StringView tool, StringView os); - Optional> parse_tool_version_string(StringView string_version); } diff --git a/src/vcpkg-test/tools.cpp b/src/vcpkg-test/tools.cpp index cc902cc70c..5eb1077a9d 100644 --- a/src/vcpkg-test/tools.cpp +++ b/src/vcpkg-test/tools.cpp @@ -41,81 +41,6 @@ Copyright (C) 2006, 2019 Tatsuhiro Tsujikawa)"); CHECK_FALSE(result.has_value()); } -TEST_CASE ("parse_tool_data_from_xml", "[tools]") -{ - const StringView tool_doc = R"( - - - - 2.7.4 - - - - - - 5.11.0 - nuget.exe - https://dist.nuget.org/win-x86-commandline/v5.11.0/nuget.exe - 06a337c9404dec392709834ef2cdbdce611e104b510ef40201849595d46d242151749aef65bc2d7ce5ade9ebfda83b64c03ce14c8f35ca9957a17a8c02b8c4b7 - - - 16.12.0 - node-v16.12.0-win-x64\node.exe - https://nodejs.org/dist/v16.12.0/node-v16.12.0-win-x64.7z - 0bb793fce8140bd59c17f3ac9661b062eac0f611d704117774f5cb2453d717da94b1e8b17d021d47baff598dc023fb7068ed1f8a7678e446260c3db3537fa888 - node-v16.12.0-win-x64.7z - - -)"; - - { - auto data = parse_tool_data_from_xml(tool_doc, "vcpkgTools.xml", "tool1", "windows"); - REQUIRE(!data.has_value()); - } - { - auto data = parse_tool_data_from_xml(tool_doc, "vcpkgTools.xml", "node", "unknown"); - REQUIRE(!data.has_value()); - } - { - auto data = parse_tool_data_from_xml(tool_doc, "vcpkgTools.xml", "node", "windows"); - REQUIRE(data.has_value()); - auto& p = *data.get(); - CHECK(p.is_archive); - CHECK(p.version == decltype(p.version){16, 12, 0}); - CHECK(p.tool_dir_subpath == "node-16.12.0-windows"); - CHECK(p.exe_subpath == "node-v16.12.0-win-x64\\node.exe"); - CHECK(p.download_subpath == "node-v16.12.0-win-x64.7z"); - CHECK(p.sha512 == "0bb793fce8140bd59c17f3ac9661b062eac0f611d704117774f5cb2453d717da94b1e8b17d021d47baff598dc023" - "fb7068ed1f8a7678e446260c3db3537fa888"); - CHECK(p.url == "https://nodejs.org/dist/v16.12.0/node-v16.12.0-win-x64.7z"); - } - { - auto data = parse_tool_data_from_xml(tool_doc, "vcpkgTools.xml", "nuget", "osx"); - REQUIRE(data.has_value()); - auto& p = *data.get(); - CHECK_FALSE(p.is_archive); - CHECK(p.version == decltype(p.version){5, 11, 0}); - CHECK(p.tool_dir_subpath == "nuget-5.11.0-osx"); - CHECK(p.exe_subpath == "nuget.exe"); - CHECK(p.download_subpath == "06a337c9-nuget.exe"); - CHECK(p.sha512 == "06a337c9404dec392709834ef2cdbdce611e104b510ef40201849595d46d242151749aef65bc2d7ce5ade9ebfda8" - "3b64c03ce14c8f35ca9957a17a8c02b8c4b7"); - CHECK(p.url == "https://dist.nuget.org/win-x86-commandline/v5.11.0/nuget.exe"); - } - { - auto data = parse_tool_data_from_xml(tool_doc, "vcpkgTools.xml", "git", "linux"); - REQUIRE(data.has_value()); - auto& p = *data.get(); - CHECK_FALSE(p.is_archive); - CHECK(p.version == decltype(p.version){2, 7, 4}); - CHECK(p.tool_dir_subpath == "git-2.7.4-linux"); - CHECK(p.exe_subpath == ""); - CHECK(p.download_subpath == ""); - CHECK(p.sha512 == ""); - CHECK(p.url == ""); - } -} - TEST_CASE ("extract_prefixed_nonwhitespace", "[tools]") { CHECK(extract_prefixed_nonwhitespace("fooutil version ", "fooutil", "fooutil version 1.2", "fooutil.exe") diff --git a/src/vcpkg.cpp b/src/vcpkg.cpp index 8b71440aa9..3d2aa53824 100644 --- a/src/vcpkg.cpp +++ b/src/vcpkg.cpp @@ -270,7 +270,7 @@ int main(const int argc, const char* const* const argv) register_console_ctrl_handler(); -#if (defined(__aarch64__) || defined(__arm__) || defined(__s390x__) || defined(__riscv) || \ +#if (defined(__arm__) || defined(__s390x__) || defined(__riscv) || \ ((defined(__ppc64__) || defined(__PPC64__) || defined(__ppc64le__) || defined(__PPC64LE__)) && \ defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) || \ defined(_M_ARM) || defined(_M_ARM64)) && \ diff --git a/src/vcpkg/tools.cpp b/src/vcpkg/tools.cpp index a5eecef261..084e5c2b6e 100644 --- a/src/vcpkg/tools.cpp +++ b/src/vcpkg/tools.cpp @@ -62,82 +62,442 @@ namespace vcpkg return std::array{*d1.get(), *d2.get(), *d3.get()}; } - static Optional parse_tool_data_from_xml(StringView XML, StringView XML_PATH, StringView tool) + struct ArchToolData { + StringView tool; + StringView os; + Optional arch; + StringView version; + StringView exeRelativePath; + StringView url; + StringView sha512; + StringView archiveName; + }; + + static Optional get_raw_tool_data(StringView toolname, CPUArchitecture arch, StringView os) + { + static std::vector tool_data = { + { + "python3", + "windows", + nullopt, + "3.11.8", + "python.exe", + "https://www.python.org/ftp/python/3.11.8/python-3.11.8-embed-win32.zip", + "c88ef02f0860000dbc59361cfe051e3e8dc7d208ed39bb5bc20a3e8b8711b578926e281a11941787ea61b2ef05b945ab313332" + "2dcb85b916f79ac4ada57f6309", + "python-3.11.8-embed-win32.zip", + }, + { + "python3_with_venv", + "windows", + nullopt, + "3.11.8", + "tools/python.exe", + "https://www.nuget.org/api/v2/package/python/3.11.8", + "8c1abd622fb2795fb87ab5208764fe13f7f4d69f2283b4237ea47b7c14b0989b5b4169f1ac1d3b1f417c6c2cc3d85ce151370d" + "ae8efc807c93e57cd67fa3c8cf", + "python-3.11.8.nupkg.zip", + }, + { + "cmake", + "windows", + nullopt, + "3.29.2", + "cmake-3.29.2-windows-i386/bin/cmake.exe", + "https://github.com/Kitware/CMake/releases/download/v3.29.2/cmake-3.29.2-windows-i386.zip", + "562de7b577c99fe347b00437d14ce375a8e5a60504909cb67d2f73c372d39a2f76d2b42b69e4aeb31a4879e1bcf6f7c2d41f2a" + "ce12180ea83ba7af48879d40ab", + "cmake-3.29.2-windows-i386.zip", + }, + { + "cmake", + "osx", + nullopt, + "3.29.2", + "cmake-3.29.2-macos-universal/CMake.app/Contents/bin/cmake", + "https://github.com/Kitware/CMake/releases/download/v3.29.2/cmake-3.29.2-macos-universal.tar.gz", + "26aab0163965f3d560dfd6b1f72c5e77192338237ebe286099fd62f243f1bbd4857b9193118386b801c00dc5cfbc5bc8af8481" + "4692fcfadcf56c7d2faab52533", + "cmake-3.29.2-macos-universal.tar.gz", + }, + { + "cmake", + "linux", + CPUArchitecture::ARM64, + "3.29.2", + "cmake-3.29.2-linux-aarch64/bin/cmake", + "https://github.com/Kitware/CMake/releases/download/v3.29.2/cmake-3.29.2-linux-aarch64.tar.gz", + "206b00604caf72f3dc644c7a5ac6a335814520fbf1512b9f2d4a5e8c26025d286bd106d2925ffbc874c754c518cbdb07f16919" + "16c39fcfd1202a47f592c8e3b0", + "cmake-3.29.2-linux-aarch64.tar.gz", + }, + { + "cmake", + "linux", + nullopt, + "3.29.2", + "cmake-3.29.2-linux-x86_64/bin/cmake", + "https://github.com/Kitware/CMake/releases/download/v3.29.2/cmake-3.29.2-linux-x86_64.tar.gz", + "d88082d582f1774a3d89efbf3f31a03b08a663c359d603d87ee7c4afd862d4164d2b0b9f0b32cece8efee3acfa86b44214cd4f" + "7606b99b8334183a05d5f06edc", + "cmake-3.29.2-linux-x86_64.tar.gz", + }, + { + "git", + "windows", + nullopt, + "2.7.4", + "mingw64/bin/git.exe", + "https://github.com/git-for-windows/git/releases/download/v2.43.0.windows.1/" + "PortableGit-2.43.0-64-bit.7z.exe", + "02ec40f55a6de18f305530e9415b6ce0a597359ebb9a58cf727ac84eceb0003b0f437941b76872b6568157a333c8e6e8d865a3" + "6faf874fd5f04774deb6a9387a", + "PortableGit-2.43.0-32-bit.7z.exe", + }, + { + "git", + "linux", + nullopt, + "2.7.4", + "", + "", + "", + }, + { + "git", + "osx", + nullopt, + "2.7.4", + "", + "", + "", + }, + { + "git", + "freebsd", + nullopt, + "2.7.4", + "", + "", + "", + }, + { + "gsutil", + "windows", + nullopt, + "4.65", + "google-cloud-sdk/bin/gsutil.cmd", + "https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/" + "google-cloud-sdk-347.0.0-windows-x86_64-bundled-python.zip", + "e2792e17b132aad77f7c0b9fd26faf415e9437923d9227a9e6d253554e6843d29a6ddad0a7fb5e9aea4a130fd4c521e6ece884" + "4fd4a4f9e8d580348775425389", + "google-cloud-sdk-347.0.0-windows-x86_64-bundled-python.zip", + }, + { + "gsutil", + "osx", + nullopt, + "4.65", + "gsutil/gsutil", + "https://storage.googleapis.com/pub/gsutil_4.65.tar.gz", + "2c5c9dea48147f97180a491bbb9e24e8cbcd4f3452620e2f80338b781e4dfc90bb754e3bbfa05e1b990e44bff52d990d8c2dd5" + "1bc83d112339d8e6096a2f21c8", + "gsutil_4.65.tar.gz", + }, + { + "gsutil", + "linux", + nullopt, + "4.65", + "gsutil/gsutil", + "https://storage.googleapis.com/pub/gsutil_4.65.tar.gz", + "2c5c9dea48147f97180a491bbb9e24e8cbcd4f3452620e2f80338b781e4dfc90bb754e3bbfa05e1b990e44bff52d990d8c2dd5" + "1bc83d112339d8e6096a2f21c8", + "gsutil_4.65.tar.gz", + }, + { + "vswhere", + "windows", + nullopt, + "3.1.7", + "vswhere.exe", + "https://github.com/microsoft/vswhere/releases/download/3.1.7/vswhere.exe", + "40c534eb27f079c15c9782f53f82c12dabfede4d3d85f0edf8a855c2b0d5e12921a96506b37c210beab3c33220f8ff098447ad" + "054e82d8c2603964975fc12076", + }, + { + "nuget", + "windows", + nullopt, + "6.10.0", + "nuget.exe", + "https://dist.nuget.org/win-x86-commandline/v6.10.0/nuget.exe", + "71d7307bb89de2df3811419c561efa00618a4c68e6ce481b0bdfc94c7c6c6d126a54eb26a0015686fabf99f109744ca41fead9" + "9e97139cdc86dde16a5ec3e7cf", + }, + { + "nuget", + "linux", + nullopt, + "6.10.0", + "nuget.exe", + "https://dist.nuget.org/win-x86-commandline/v6.10.0/nuget.exe", + "71d7307bb89de2df3811419c561efa00618a4c68e6ce481b0bdfc94c7c6c6d126a54eb26a0015686fabf99f109744ca41fead9" + "9e97139cdc86dde16a5ec3e7cf", + }, + { + "nuget", + "osx", + nullopt, + "6.10.0", + "nuget.exe", + "https://dist.nuget.org/win-x86-commandline/v6.10.0/nuget.exe", + "71d7307bb89de2df3811419c561efa00618a4c68e6ce481b0bdfc94c7c6c6d126a54eb26a0015686fabf99f109744ca41fead9" + "9e97139cdc86dde16a5ec3e7cf", + }, + { + "coscli", + "windows", + nullopt, + "0.11.0", + "coscli-windows.exe", + "https://github.com/tencentyun/coscli/releases/download/v0.11.0-beta/coscli-windows.exe", + "38a521ec80cdb6944124f4233d7e71eed8cc9f9be2c0c736269915d21c3718ea8131e4516bb6eeada6df331f5fa8f47a299907" + "e50ee9edbe0114444520974d06", + }, + { + "coscli", + "linux", + nullopt, + "0.11.0", + "coscli-linux", + "https://github.com/tencentyun/coscli/releases/download/v0.11.0-beta/coscli-linux", + "9c930a1d308e9581a0e2fdfe3751ea7fe13d6068df90ca6465740ec3eda034202ef71ec54c99e90015ff81aa68aa1489567db5" + "e411e222eb7258704bdac7e924", + }, + { + "coscli", + "osx", + nullopt, + "0.11.0", + "coscli-mac", + "https://github.com/tencentyun/coscli/releases/download/v0.11.0-beta/coscli-mac", + "9556335bfc8bc14bace6dfced45fa77fb07c80f08aa975e047a54efda1d19852aae0ea68a5bc7f04fbd88e3edce5a73512a612" + "16b1c5ff4cade224de4a9ab8db", + }, + { + "installerbase", + "windows", + nullopt, + "4.4.0", + "QtInstallerFramework-win-x86/bin/installerbase.exe", + "https://download.qt.io/official_releases/qt-installer-framework/4.4.0/" + "installer-framework-opensource-src-4.4.0.zip", + "fc713f54bfe2781cb232cd0ae8eddb96833ec178d53a55ec0b01886aa048b13441eb49a1f33282e8eab7259cfe512c890d50b8" + "e632d3dbf501a0bf1fd83de947", + "installer-framework-opensource-src-4.4.0.zip", + }, + { + "7zip_msi", + "windows", + nullopt, + "24.08", + "Files/7-Zip/7z.exe", + "https://github.com/ip7z/7zip/releases/download/24.08/7z2408-x64.msi", + "3259bf5e251382333c9d18a3fc01d83491fb41bc4ac4ddb25a02918494594c1074482b6608189a8a89e343d78e34d57420cdef" + "f1d7ace5acfdcaacc8776f1be8", + "7z2408-x64.msi", + }, + { + "7zip", + "windows", + nullopt, + "24.08", + "7za.exe", + "https://github.com/ip7z/7zip/releases/download/24.08/7z2408-extra.7z", + "35f55236fccfb576ca014e29d0c35f4a213e53f06683bd2e82f869ed02506e230c8dd623c01d0207244d6a997031f737903456" + "b7ad4a44db1717f0a17a78602e", + "7z2408-extra.7z", + }, + { + "7zr", + "windows", + nullopt, + "24.08", + "7zr.exe", + "https://github.com/ip7z/7zip/releases/download/24.08/7zr.exe", + "424196f2acf5b89807f4038683acc50e7604223fc630245af6bab0e0df923f8b1c49cb09ac709086568c214c3f53dcb7d6c32e" + "8a54af222a3ff78cfab9c51670", + }, + { + "aria2", + "windows", + nullopt, + "1.37.0", + "aria2-1.37.0-win-64bit-build1/aria2c.exe", + "https://github.com/aria2/aria2/releases/download/release-1.37.0/aria2-1.37.0-win-64bit-build1.zip", + "6d78405da9cf5639dbe8174787002161b8124d73880fb57cc8c0a3a63982f84e46df4e626990c58f23452965ad925f0d37cb91" + "47e99b25c3d7ca0ea49602f34d", + "aria2-1.37.0-win-64bit-build1.zip", + }, + { + "aria2", + "osx", + nullopt, + "1.35.0", + "aria2-1.35.0/bin/aria2c", + "https://github.com/aria2/aria2/releases/download/release-1.35.0/aria2-1.35.0-osx-darwin.tar.bz2", + "3bb32b7d55347d1af37c6f4ebf0e20b38ce51c37a1baf92f7ad1762000539a03413dd679a6d902fdb1805fa71917300c9692ac" + "eee012eb06ecdff10491137aec", + "aria2-1.35.0-osx-darwin.tar.bz2", + }, + { + "ninja", + "windows", + nullopt, + "1.11.1", + "ninja.exe", + "https://github.com/ninja-build/ninja/releases/download/v1.11.1/ninja-win.zip", + "a700e794c32eb67b9f87040db7f1ba3a8e891636696fc54d416b01661c2421ff46fa517c97fd904adacdf8e621df3e68ea3801" + "05b909ae8b6651a78ae7eb3199", + "ninja-win-1.11.1.zip", + }, + { + "ninja", + "linux", + nullopt, + "1.11.1", + "ninja", + "https://github.com/ninja-build/ninja/releases/download/v1.11.1/ninja-linux.zip", + "6403dac9196baffcff614fa73ea530752997c8db6bbfbaa0446b4b09d7327e2aa6e8615d1283c961d3bf0df497e85ba8660414" + "9f1505ee75f89d600245a45dde", + "ninja-linux-1.11.1.zip", + }, + { + "ninja", + "osx", + nullopt, + "1.11.1", + "ninja", + "https://github.com/ninja-build/ninja/releases/download/v1.11.1/ninja-mac.zip", + "dad33b0918c60bbf5107951a936175b1610b4894a408f4ba4b47a2f5b328fc982a52a2aed6a0cb75028ee4765af5083bea6661" + "1c37516826eb0c851366bb4427", + "ninja-mac-1.11.1.zip", + }, + { + "powershell-core", + "windows", + nullopt, + "7.2.23", + "pwsh.exe", + "https://github.com/PowerShell/PowerShell/releases/download/v7.2.23/PowerShell-7.2.23-win-x64.zip", + "b374a878df02980d54e17ad7cfc9021e331748c3770f586be61356c257494d1b33899c1167d09a35c210bc084474aefdff972f" + "672d16afb43be0562b3589285a", + "PowerShell-7.2.23-win-x64.zip", + }, + { + "node", + "windows", + nullopt, + "16.15.1", + "node-v16.15.1-win-x64/node.exe", + "https://nodejs.org/dist/v16.15.1/node-v16.15.1-win-x64.7z", + "7ec4bfe2ea6034e1461e306b6372d62c0c5d1060c453ba76a73a5cec38ac26b5952a744caa9071455329caa58eb0a96d26c688" + "54c8915c17610ff27b0cf2c1cf", + "node-v16.15.1-win-x64.7z", + }, + { + "node", + "linux", + nullopt, + "16.15.1", + "node-v16.15.1-linux-x64/bin/node", + "https://nodejs.org/dist/v16.15.1/node-v16.15.1-linux-x64.tar.gz", + "5ad3b4b9caeaa8d31503efa99f5a593118a267dec9d4181d019732126ba248ce9a901207115b3f6b899eb5b3f0373c7f77ea95" + "cc92ac625cddf437ee9b8b8919", + "node-v16.15.1-linux-x64.tar.gz", + }, + { + "node", + "osx", + nullopt, + "16.15.1", + "node-v16.15.1-darwin-x64/bin/node", + "https://nodejs.org/dist/v16.15.1/node-v16.15.1-darwin-x64.tar.gz", + "90d0612bbe5467b6cf385c91a68b8daad0057e3e0ccacea44567f5b95b14f7481cb79784185ab1463b4bd990e092ff0f910957" + "6d1a1934b84e1c816582929611", + "node-v16.15.1-darwin-x64.tar.gz", + }}; + + int default_tool = -1; + for (std::size_t i = 0; i < tool_data.size(); i++) + { + ArchToolData& d = tool_data[i]; + if (d.tool == toolname && d.arch.has_value() && d.arch.value_or_exit(VCPKG_LINE_INFO) == arch && d.os == os) + { + return d; + } + else if (d.tool == toolname && d.os == os && !d.arch.has_value()) + { + default_tool = i; + } + } + if (default_tool >= 0) + { + return tool_data[default_tool]; + } + + return nullopt; + } + + static Optional get_tool_data(StringView tool) + { + auto hp = get_host_processor(); #if defined(_WIN32) - return parse_tool_data_from_xml(XML, XML_PATH, tool, "windows"); + auto data = get_raw_tool_data(tool, hp, "windows"); #elif defined(__APPLE__) - return parse_tool_data_from_xml(XML, XML_PATH, tool, "osx"); + auto data = get_raw_tool_data(tool, hp, "osx"); #elif defined(__linux__) - return parse_tool_data_from_xml(XML, XML_PATH, tool, "linux"); + auto data = get_raw_tool_data(tool, hp, "linux"); #elif defined(__FreeBSD__) - return parse_tool_data_from_xml(XML, XML_PATH, tool, "freebsd"); + auto data = get_raw_tool_data(tool, hp, "freebsd"); #elif defined(__OpenBSD__) - return parse_tool_data_from_xml(XML, XML_PATH, tool, "openbsd"); + auto data = get_raw_tool_data(tool, hp, "openbsd"); #else return nullopt; #endif - } - - Optional parse_tool_data_from_xml(StringView XML, StringView XML_PATH, StringView tool, StringView os) - { - static const char* XML_VERSION = "2"; - static const std::regex XML_VERSION_REGEX{R"###()###"}; - std::cmatch match_xml_version; - const bool has_xml_version = std::regex_search(XML.begin(), XML.end(), match_xml_version, XML_VERSION_REGEX); - Checks::msg_check_exit(VCPKG_LINE_INFO, - has_xml_version, - msgCouldNotFindToolVersion, - msg::version = XML_VERSION, - msg::path = XML_PATH); - Checks::msg_check_exit(VCPKG_LINE_INFO, - XML_VERSION == match_xml_version[1], - msgVersionConflictXML, - msg::path = XML_PATH, - msg::expected_version = XML_VERSION, - msg::actual_version = match_xml_version[1].str()); - - const std::regex tool_regex{fmt::format(R"###()###", tool, os)}; - std::cmatch match_tool_entry; - const bool has_tool_entry = std::regex_search(XML.begin(), XML.end(), match_tool_entry, tool_regex); - if (!has_tool_entry) return nullopt; - - const std::string tool_data = - Strings::find_exactly_one_enclosed(XML, match_tool_entry[0].str(), "").to_string(); - const std::string version_as_string = - Strings::find_exactly_one_enclosed(tool_data, "", "").to_string(); - const std::string exe_relative_path = - Strings::find_exactly_one_enclosed(tool_data, "", "").to_string(); - const std::string url = Strings::find_exactly_one_enclosed(tool_data, "", "").to_string(); - const std::string sha512 = Strings::find_exactly_one_enclosed(tool_data, "", "").to_string(); - auto archive_name = Strings::find_at_most_one_enclosed(tool_data, "", ""); - - const Optional> version = parse_tool_version_string(version_as_string); + if (!data.has_value()) + { + return nullopt; + } + auto& d = data.value_or_exit(VCPKG_LINE_INFO); + const Optional> version = parse_tool_version_string(d.version); Checks::msg_check_exit(VCPKG_LINE_INFO, version.has_value(), msgFailedToParseVersionXML, msg::tool_name = tool, - msg::version = version_as_string); + msg::version = d.version); - Path tool_dir_name = fmt::format("{}-{}-{}", tool, version_as_string, os); + Path tool_dir_name = fmt::format("{}-{}-{}", tool, d.version, d.os); Path download_subpath; - if (auto a = archive_name.get()) + if (!d.archiveName.empty()) { - download_subpath = a->to_string(); + download_subpath = d.archiveName; } - else if (!exe_relative_path.empty()) + else if (!d.exeRelativePath.empty()) { - download_subpath = Strings::concat(sha512.substr(0, 8), '-', exe_relative_path); + download_subpath = Strings::concat(d.sha512.substr(0, 8), '-', d.exeRelativePath); } return ToolData{tool.to_string(), *version.get(), - exe_relative_path, - url, + d.exeRelativePath, + std::string(d.url), download_subpath, - archive_name.has_value(), + !d.archiveName.empty(), tool_dir_name, - sha512}; + std::string(d.sha512)}; } struct PathAndVersion @@ -608,23 +968,19 @@ namespace vcpkg const Filesystem& fs; const std::shared_ptr downloader; const Path downloads; - const Path xml_config; const Path tools; const RequireExactVersions abiToolVersionHandling; - vcpkg::Lazy xml_config_contents; vcpkg::Cache path_version_cache; ToolCacheImpl(const Filesystem& fs, const std::shared_ptr& downloader, Path downloads, - Path xml_config, Path tools, RequireExactVersions abiToolVersionHandling) : fs(fs) , downloader(downloader) , downloads(std::move(downloads)) - , xml_config(std::move(xml_config)) , tools(std::move(tools)) , abiToolVersionHandling(abiToolVersionHandling) { @@ -718,12 +1074,6 @@ namespace vcpkg return exe_path; } - const std::string& get_config_contents() const - { - return xml_config_contents.get_lazy( - [this]() { return this->fs.read_contents(this->xml_config, VCPKG_LINE_INFO); }); - } - virtual const Path& get_tool_path(StringView tool, MessageSink& status_sink) const override { return get_tool_pathversion(tool, status_sink).p; @@ -735,9 +1085,7 @@ namespace vcpkg get_environment_variable(EnvironmentVariableVcpkgForceSystemBinaries).has_value(); const bool env_force_download_binaries = get_environment_variable(EnvironmentVariableVcpkgForceDownloadedBinaries).has_value(); - const auto maybe_tool_data = - parse_tool_data_from_xml(get_config_contents(), xml_config, tool.tool_data_name()); - + const auto maybe_tool_data = get_tool_data(tool.tool_data_name()); const bool download_available = maybe_tool_data.has_value() && !maybe_tool_data.get()->url.empty(); // search for system searchable tools unless forcing downloads and download available const auto system_exe_stems = tool.system_exe_stems(); @@ -755,7 +1103,7 @@ namespace vcpkg if (auto tool_data = maybe_tool_data.get()) { - // If there is an entry for the tool in vcpkgTools.xml, use that version as the minimum + // If there is an entry for the tool in tools.cpp, use that version as the minimum min_version = tool_data->version; if (consider_downloads) @@ -967,11 +1315,9 @@ namespace vcpkg std::unique_ptr get_tool_cache(const Filesystem& fs, std::shared_ptr downloader, Path downloads, - Path xml_config, Path tools, RequireExactVersions abiToolVersionHandling) { - return std::make_unique( - fs, std::move(downloader), downloads, xml_config, tools, abiToolVersionHandling); + return std::make_unique(fs, std::move(downloader), downloads, tools, abiToolVersionHandling); } } diff --git a/src/vcpkg/vcpkgpaths.cpp b/src/vcpkg/vcpkgpaths.cpp index 77e107f5ce..8b7cdf893d 100644 --- a/src/vcpkg/vcpkgpaths.cpp +++ b/src/vcpkg/vcpkgpaths.cpp @@ -561,7 +561,6 @@ namespace vcpkg , m_tool_cache(get_tool_cache(fs, m_download_manager, downloads, - scripts / "vcpkgTools.xml", tools, args.exact_abi_tools_versions.value_or(false) ? RequireExactVersions::YES : RequireExactVersions::NO)) From 23c303e90ab6a9eba0ba2b63c6ed7966ba60974f Mon Sep 17 00:00:00 2001 From: data-queue <144965964+data-queue@users.noreply.github.com> Date: Mon, 16 Sep 2024 19:24:13 +0000 Subject: [PATCH 02/30] fix --- src/vcpkg/tools.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/vcpkg/tools.cpp b/src/vcpkg/tools.cpp index 084e5c2b6e..c8d540b8fe 100644 --- a/src/vcpkg/tools.cpp +++ b/src/vcpkg/tools.cpp @@ -430,7 +430,8 @@ namespace vcpkg "node-v16.15.1-darwin-x64.tar.gz", }}; - int default_tool = -1; + size_t default_tool = 0; + bool existsDefaultTool = false; for (std::size_t i = 0; i < tool_data.size(); i++) { ArchToolData& d = tool_data[i]; @@ -441,9 +442,10 @@ namespace vcpkg else if (d.tool == toolname && d.os == os && !d.arch.has_value()) { default_tool = i; + existsDefaultTool = true; } } - if (default_tool >= 0) + if (existsDefaultTool) { return tool_data[default_tool]; } From e86a63b3009bff94a31822ba807a9c09ac12ec79 Mon Sep 17 00:00:00 2001 From: data-queue <144965964+data-queue@users.noreply.github.com> Date: Mon, 16 Sep 2024 19:48:50 +0000 Subject: [PATCH 03/30] update --- include/vcpkg/base/message-data.inc.h | 9 --------- locales/messages.json | 4 ---- 2 files changed, 13 deletions(-) diff --git a/include/vcpkg/base/message-data.inc.h b/include/vcpkg/base/message-data.inc.h index 94da29347b..67ae4b51b2 100644 --- a/include/vcpkg/base/message-data.inc.h +++ b/include/vcpkg/base/message-data.inc.h @@ -911,10 +911,6 @@ DECLARE_MESSAGE(CouldNotFindGitTreeAtCommit, (msg::package_name, msg::commit_sha), "", "could not find the git tree for `versions` in repo {package_name} at commit {commit_sha}") -DECLARE_MESSAGE(CouldNotFindToolVersion, - (msg::version, msg::path), - "", - "Could not find in {path}") DECLARE_MESSAGE(CouldNotFindVersionDatabaseFile, (msg::path), "", "Couldn't find the versions database file: {path}") DECLARE_MESSAGE(CreatedNuGetPackage, (msg::path), "", "Created nupkg: {path}") DECLARE_MESSAGE(CreateFailureLogsDir, (msg::path), "", "Creating failure logs output directory {path}.") @@ -2952,11 +2948,6 @@ DECLARE_MESSAGE(VersionCommandHeader, (msg::version), "", "vcpkg package management program version {version}\n\nSee LICENSE.txt for license information.") -DECLARE_MESSAGE( - VersionConflictXML, - (msg::path, msg::expected_version, msg::actual_version), - "", - "Expected {path} version: [{expected_version}], but was [{actual_version}]. Please re-run bootstrap-vcpkg.") DECLARE_MESSAGE(VersionConstraintNotInDatabase1, (msg::package_name, msg::version), "", diff --git a/locales/messages.json b/locales/messages.json index 3ce795ad03..a5d5b953e7 100644 --- a/locales/messages.json +++ b/locales/messages.json @@ -527,8 +527,6 @@ "_CouldNotFindBaselineInCommit.comment": "An example of {url} is https://github.com/microsoft/vcpkg. An example of {commit_sha} is 7cfad47ae9f68b183983090afd6337cd60fd4949. An example of {package_name} is zlib.", "CouldNotFindGitTreeAtCommit": "could not find the git tree for `versions` in repo {package_name} at commit {commit_sha}", "_CouldNotFindGitTreeAtCommit.comment": "An example of {package_name} is zlib. An example of {commit_sha} is 7cfad47ae9f68b183983090afd6337cd60fd4949.", - "CouldNotFindToolVersion": "Could not find in {path}", - "_CouldNotFindToolVersion.comment": "An example of {version} is 1.3.8. An example of {path} is /foo/bar.", "CouldNotFindVersionDatabaseFile": "Couldn't find the versions database file: {path}", "_CouldNotFindVersionDatabaseFile.comment": "An example of {path} is /foo/bar.", "CreateFailureLogsDir": "Creating failure logs output directory {path}.", @@ -1574,8 +1572,6 @@ "_VersionBuiltinPortTreeEntryMissing.comment": "{expected} and {actual} are versions like 1.0. An example of {package_name} is zlib.", "VersionCommandHeader": "vcpkg package management program version {version}\n\nSee LICENSE.txt for license information.", "_VersionCommandHeader.comment": "An example of {version} is 1.3.8.", - "VersionConflictXML": "Expected {path} version: [{expected_version}], but was [{actual_version}]. Please re-run bootstrap-vcpkg.", - "_VersionConflictXML.comment": "An example of {path} is /foo/bar. An example of {expected_version} is 1.3.8. An example of {actual_version} is 1.3.8.", "VersionConstraintNotInDatabase1": "the \"version>=\" constraint to {package_name} names version {version} which does not exist in the version database. All versions must exist in the version database to be interpreted by vcpkg.", "_VersionConstraintNotInDatabase1.comment": "An example of {package_name} is zlib. An example of {version} is 1.3.8.", "VersionConstraintNotInDatabase2": "consider removing the version constraint or choosing a value declared here", From 65511afe6238f035eefdc9d7e7b6d15504282373 Mon Sep 17 00:00:00 2001 From: data-queue <144965964+data-queue@users.noreply.github.com> Date: Mon, 16 Sep 2024 19:58:58 +0000 Subject: [PATCH 04/30] format --- src/vcpkg.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vcpkg.cpp b/src/vcpkg.cpp index 3d2aa53824..1b6b7c22ea 100644 --- a/src/vcpkg.cpp +++ b/src/vcpkg.cpp @@ -270,7 +270,7 @@ int main(const int argc, const char* const* const argv) register_console_ctrl_handler(); -#if (defined(__arm__) || defined(__s390x__) || defined(__riscv) || \ +#if (defined(__arm__) || defined(__s390x__) || defined(__riscv) || \ ((defined(__ppc64__) || defined(__PPC64__) || defined(__ppc64le__) || defined(__PPC64LE__)) && \ defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) || \ defined(_M_ARM) || defined(_M_ARM64)) && \ From e6ce6bb17a2e523a0b796fabdcc28a191e6c9db9 Mon Sep 17 00:00:00 2001 From: data-queue <144965964+data-queue@users.noreply.github.com> Date: Tue, 17 Sep 2024 22:28:30 +0000 Subject: [PATCH 05/30] reviews --- src/vcpkg/tools.cpp | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/src/vcpkg/tools.cpp b/src/vcpkg/tools.cpp index c8d540b8fe..cb39740459 100644 --- a/src/vcpkg/tools.cpp +++ b/src/vcpkg/tools.cpp @@ -64,19 +64,20 @@ namespace vcpkg struct ArchToolData { - StringView tool; - StringView os; + StringLiteral tool; + StringLiteral os; Optional arch; - StringView version; - StringView exeRelativePath; - StringView url; - StringView sha512; - StringView archiveName; + StringLiteral version; + StringLiteral exeRelativePath; + StringLiteral url; + StringLiteral sha512; + StringLiteral archiveName; }; - static Optional get_raw_tool_data(StringView toolname, CPUArchitecture arch, StringView os) + static Optional get_raw_tool_data(StringView toolname, CPUArchitecture arch, StringView os) { - static std::vector tool_data = { + const std::size_t NUM_TOOLS = 33; + ArchToolData tool_data[NUM_TOOLS] = { { "python3", "windows", @@ -163,6 +164,7 @@ namespace vcpkg "", "", "", + "", }, { "git", @@ -172,6 +174,7 @@ namespace vcpkg "", "", "", + "", }, { "git", @@ -181,6 +184,7 @@ namespace vcpkg "", "", "", + "", }, { "gsutil", @@ -225,6 +229,7 @@ namespace vcpkg "https://github.com/microsoft/vswhere/releases/download/3.1.7/vswhere.exe", "40c534eb27f079c15c9782f53f82c12dabfede4d3d85f0edf8a855c2b0d5e12921a96506b37c210beab3c33220f8ff098447ad" "054e82d8c2603964975fc12076", + "", }, { "nuget", @@ -235,6 +240,7 @@ namespace vcpkg "https://dist.nuget.org/win-x86-commandline/v6.10.0/nuget.exe", "71d7307bb89de2df3811419c561efa00618a4c68e6ce481b0bdfc94c7c6c6d126a54eb26a0015686fabf99f109744ca41fead9" "9e97139cdc86dde16a5ec3e7cf", + "", }, { "nuget", @@ -245,6 +251,7 @@ namespace vcpkg "https://dist.nuget.org/win-x86-commandline/v6.10.0/nuget.exe", "71d7307bb89de2df3811419c561efa00618a4c68e6ce481b0bdfc94c7c6c6d126a54eb26a0015686fabf99f109744ca41fead9" "9e97139cdc86dde16a5ec3e7cf", + "", }, { "nuget", @@ -255,6 +262,7 @@ namespace vcpkg "https://dist.nuget.org/win-x86-commandline/v6.10.0/nuget.exe", "71d7307bb89de2df3811419c561efa00618a4c68e6ce481b0bdfc94c7c6c6d126a54eb26a0015686fabf99f109744ca41fead9" "9e97139cdc86dde16a5ec3e7cf", + "", }, { "coscli", @@ -265,6 +273,7 @@ namespace vcpkg "https://github.com/tencentyun/coscli/releases/download/v0.11.0-beta/coscli-windows.exe", "38a521ec80cdb6944124f4233d7e71eed8cc9f9be2c0c736269915d21c3718ea8131e4516bb6eeada6df331f5fa8f47a299907" "e50ee9edbe0114444520974d06", + "", }, { "coscli", @@ -275,6 +284,7 @@ namespace vcpkg "https://github.com/tencentyun/coscli/releases/download/v0.11.0-beta/coscli-linux", "9c930a1d308e9581a0e2fdfe3751ea7fe13d6068df90ca6465740ec3eda034202ef71ec54c99e90015ff81aa68aa1489567db5" "e411e222eb7258704bdac7e924", + "", }, { "coscli", @@ -285,6 +295,7 @@ namespace vcpkg "https://github.com/tencentyun/coscli/releases/download/v0.11.0-beta/coscli-mac", "9556335bfc8bc14bace6dfced45fa77fb07c80f08aa975e047a54efda1d19852aae0ea68a5bc7f04fbd88e3edce5a73512a612" "16b1c5ff4cade224de4a9ab8db", + "", }, { "installerbase", @@ -329,6 +340,7 @@ namespace vcpkg "https://github.com/ip7z/7zip/releases/download/24.08/7zr.exe", "424196f2acf5b89807f4038683acc50e7604223fc630245af6bab0e0df923f8b1c49cb09ac709086568c214c3f53dcb7d6c32e" "8a54af222a3ff78cfab9c51670", + "", }, { "aria2", @@ -432,9 +444,9 @@ namespace vcpkg size_t default_tool = 0; bool existsDefaultTool = false; - for (std::size_t i = 0; i < tool_data.size(); i++) + for (std::size_t i = 0; i < NUM_TOOLS; i++) { - ArchToolData& d = tool_data[i]; + const ArchToolData& d = tool_data[i]; if (d.tool == toolname && d.arch.has_value() && d.arch.value_or_exit(VCPKG_LINE_INFO) == arch && d.os == os) { return d; @@ -489,7 +501,7 @@ namespace vcpkg } else if (!d.exeRelativePath.empty()) { - download_subpath = Strings::concat(d.sha512.substr(0, 8), '-', d.exeRelativePath); + download_subpath = Strings::concat(StringView{d.sha512}.substr(0, 8), '-', d.exeRelativePath); } return ToolData{tool.to_string(), From db4bf0322904e8abf52ecf8e164a1f3bb7a35751 Mon Sep 17 00:00:00 2001 From: data-queue <144965964+data-queue@users.noreply.github.com> Date: Tue, 17 Sep 2024 22:34:37 +0000 Subject: [PATCH 06/30] fix --- src/vcpkg/tools.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/vcpkg/tools.cpp b/src/vcpkg/tools.cpp index cb39740459..81cada54e3 100644 --- a/src/vcpkg/tools.cpp +++ b/src/vcpkg/tools.cpp @@ -446,6 +446,9 @@ namespace vcpkg bool existsDefaultTool = false; for (std::size_t i = 0; i < NUM_TOOLS; i++) { + // if possible, find a tool with matching tool name, architecture, and os + // otherwise, choose a tool with only matching name and os and nullopt + // as architecture (this is the default tool) const ArchToolData& d = tool_data[i]; if (d.tool == toolname && d.arch.has_value() && d.arch.value_or_exit(VCPKG_LINE_INFO) == arch && d.os == os) { From 3722ced4ccfee45780224fd4093bc6f1fc9c5fe6 Mon Sep 17 00:00:00 2001 From: Billy Robert O'Neal III Date: Mon, 23 Sep 2024 16:23:09 -0700 Subject: [PATCH 07/30] Allow constexpr Optional when constexpr T is acceptable by propagating trivial destruction. --- include/vcpkg/base/optional.h | 207 ++++++++++++++++++++-------------- 1 file changed, 123 insertions(+), 84 deletions(-) diff --git a/include/vcpkg/base/optional.h b/include/vcpkg/base/optional.h index 12c192957c..e10fe9ac6b 100644 --- a/include/vcpkg/base/optional.h +++ b/include/vcpkg/base/optional.h @@ -23,205 +23,244 @@ namespace vcpkg namespace details { + struct EngageTag + { + }; + + template> + struct OptionalStorageDtor + { + bool m_is_present; + union + { + char m_inactive; + T m_t; + }; + + constexpr OptionalStorageDtor() : m_is_present(false), m_inactive() { } + template + constexpr OptionalStorageDtor(EngageTag, Args&&... args) noexcept(std::is_nothrow_constructible_v) + : m_is_present(false), m_t(std::forward(args)...) + { + } + }; + + template + struct OptionalStorageDtor + { + bool m_is_present; + union + { + char m_inactive; + T m_t; + }; + + constexpr OptionalStorageDtor() : m_is_present(false), m_inactive() { } + template + constexpr OptionalStorageDtor(EngageTag, Args&&... args) noexcept(std::is_nothrow_constructible_v) + : m_is_present(false), m_t(std::forward(args)...) + { + } + + ~OptionalStorageDtor() + { + if (m_is_present) + { + m_t.~T(); + } + } + }; + template> - struct OptionalStorage + struct OptionalStorage : OptionalStorageDtor { - constexpr OptionalStorage() noexcept : m_is_present(false), m_inactive() { } + OptionalStorage() = default; constexpr OptionalStorage(const T& t) noexcept(std::is_nothrow_copy_constructible_v) - : m_is_present(true), m_t(t) + : OptionalStorageDtor(EngageTag{}, t) { } constexpr OptionalStorage(T&& t) noexcept(std::is_nothrow_move_constructible_v) - : m_is_present(true), m_t(std::move(t)) + : OptionalStorageDtor(EngageTag{}, std::move(t)) { } template>> explicit OptionalStorage(Optional&& t) noexcept(std::is_nothrow_constructible_v) - : m_is_present(false), m_inactive() + : OptionalStorageDtor() { if (auto p = t.get()) { - m_is_present = true; - new (&m_t) T(std::move(*p)); + this->m_is_present = true; + new (&this->m_t) T(std::move(*p)); } } template explicit OptionalStorage(const Optional& t) noexcept(std::is_nothrow_constructible_v) - : m_is_present(false), m_inactive() + : OptionalStorageDtor() { if (auto p = t.get()) { - m_is_present = true; - new (&m_t) T(*p); + this->m_is_present = true; + new (&this->m_t) T(*p); } } - ~OptionalStorage() - { - if (m_is_present) m_t.~T(); - } - OptionalStorage(const OptionalStorage& o) noexcept(std::is_nothrow_copy_constructible_v) - : m_is_present(o.m_is_present), m_inactive() + : OptionalStorageDtor() { - if (m_is_present) new (&m_t) T(o.m_t); + if (o.m_is_present) + { + this->m_is_present = true; + new (&this->m_t) T(o.m_t); + } } OptionalStorage(OptionalStorage&& o) noexcept(std::is_nothrow_move_constructible_v) - : m_is_present(o.m_is_present), m_inactive() + : OptionalStorageDtor() { - if (m_is_present) + if (o.m_is_present) { - new (&m_t) T(std::move(o.m_t)); + this->m_is_present = true; + new (&this->m_t) T(std::move(o.m_t)); } } OptionalStorage& operator=(const OptionalStorage& o) noexcept(std::is_nothrow_copy_constructible_v && std::is_nothrow_copy_assignable_v) { - if (m_is_present && o.m_is_present) + if (this->m_is_present && o.m_is_present) { - m_t = o.m_t; + this->m_t = o.m_t; } - else if (!m_is_present && o.m_is_present) + else if (!this->m_is_present && o.m_is_present) { - new (&m_t) T(o.m_t); - m_is_present = true; + new (&this->m_t) T(o.m_t); + this->m_is_present = true; } - else if (m_is_present && !o.m_is_present) + else if (this->m_is_present && !o.m_is_present) { destroy(); } + return *this; } OptionalStorage& operator=(OptionalStorage&& o) noexcept // enforces termination { - if (m_is_present && o.m_is_present) + if (this->m_is_present && o.m_is_present) { - m_t = std::move(o.m_t); + this->m_t = std::move(o.m_t); } - else if (!m_is_present && o.m_is_present) + else if (!this->m_is_present && o.m_is_present) { - new (&m_t) T(std::move(o.m_t)); - m_is_present = true; + new (&this->m_t) T(std::move(o.m_t)); + this->m_is_present = true; } - else if (m_is_present && !o.m_is_present) + else if (this->m_is_present && !o.m_is_present) { destroy(); } return *this; } - constexpr bool has_value() const noexcept { return m_is_present; } + constexpr bool has_value() const noexcept { return this->m_is_present; } const T& value() const noexcept { return this->m_t; } T& value() noexcept { return this->m_t; } - const T* get() const& noexcept { return m_is_present ? &m_t : nullptr; } - T* get() & noexcept { return m_is_present ? &m_t : nullptr; } + const T* get() const& noexcept { return this->m_is_present ? &this->m_t : nullptr; } + T* get() & noexcept { return this->m_is_present ? &this->m_t : nullptr; } const T* get() const&& = delete; T* get() && = delete; void destroy() noexcept // enforces termination { - m_is_present = false; - m_t.~T(); - m_inactive = '\0'; + this->m_is_present = false; + this->m_t.~T(); + this->m_inactive = '\0'; } template T& emplace(Args&&... args) noexcept(std::is_nothrow_constructible_v) { - if (m_is_present) destroy(); - new (&m_t) T(static_cast(args)...); - m_is_present = true; - return m_t; + if (this->m_is_present) destroy(); + new (&this->m_t) T(static_cast(args)...); + this->m_is_present = true; + return this->m_t; } - - private: - bool m_is_present; - union - { - char m_inactive; - T m_t; - }; }; template - struct OptionalStorage + struct OptionalStorage : OptionalStorageDtor { - constexpr OptionalStorage() noexcept : m_is_present(false), m_inactive() { } + OptionalStorage() = default; constexpr OptionalStorage(T&& t) noexcept(std::is_nothrow_move_constructible_v) - : m_is_present(true), m_t(std::move(t)) + : OptionalStorageDtor(EngageTag{}, std::move(t)) { } - - ~OptionalStorage() + template>> + explicit OptionalStorage(Optional&& t) noexcept(std::is_nothrow_constructible_v) + : OptionalStorageDtor() { - if (m_is_present) m_t.~T(); + if (auto p = t.get()) + { + this->m_is_present = true; + new (&this->m_t) T(std::move(*p)); + } } - OptionalStorage(OptionalStorage&& o) noexcept(std::is_nothrow_move_constructible_v) - : m_is_present(o.m_is_present), m_inactive() + : OptionalStorageDtor() { - if (m_is_present) + if (o.m_is_present) { - new (&m_t) T(std::move(o.m_t)); + this->m_is_present = true; + new (&this->m_t) T(std::move(o.m_t)); } } OptionalStorage& operator=(OptionalStorage&& o) noexcept // enforces termination { - if (m_is_present && o.m_is_present) + if (this->m_is_present && o.m_is_present) { - m_t = std::move(o.m_t); + this->m_t = std::move(o.m_t); } - else if (!m_is_present && o.m_is_present) + else if (!this->m_is_present && o.m_is_present) { - m_is_present = true; - new (&m_t) T(std::move(o.m_t)); + this->m_is_present = true; + new (&this->m_t) T(std::move(o.m_t)); } - else if (m_is_present && !o.m_is_present) + else if (this->m_is_present && !o.m_is_present) { destroy(); } + return *this; } - constexpr bool has_value() const noexcept { return m_is_present; } + constexpr bool has_value() const noexcept { return this->m_is_present; } const T& value() const noexcept { return this->m_t; } T& value() noexcept { return this->m_t; } - const T* get() const& noexcept { return m_is_present ? &m_t : nullptr; } - T* get() & noexcept { return m_is_present ? &m_t : nullptr; } + const T* get() const& noexcept { return this->m_is_present ? &this->m_t : nullptr; } + T* get() & noexcept { return this->m_is_present ? &this->m_t : nullptr; } const T* get() const&& = delete; T* get() && = delete; template T& emplace(Args&&... args) noexcept(std::is_nothrow_constructible_v) { - if (m_is_present) destroy(); - new (&m_t) T(static_cast(args)...); - m_is_present = true; - return m_t; + if (this->m_is_present) destroy(); + new (&this->m_t) T(static_cast(args)...); + this->m_is_present = true; + return this->m_t; } void destroy() noexcept { - m_is_present = false; - m_t.~T(); - m_inactive = '\0'; + this->m_is_present = false; + this->m_t.~T(); + this->m_inactive = '\0'; } - - private: - bool m_is_present; - union - { - char m_inactive; - T m_t; - }; }; template From 7126108d65ff28d2d09ae8403c0244ba557992fd Mon Sep 17 00:00:00 2001 From: Billy Robert O'Neal III Date: Mon, 23 Sep 2024 16:29:39 -0700 Subject: [PATCH 08/30] Make the table be static data, deduplicate part of the expression in the search loop, and get rid of magic numbers that is the length of the table. --- src/vcpkg/tools.cpp | 806 ++++++++++++++++++++++---------------------- 1 file changed, 408 insertions(+), 398 deletions(-) diff --git a/src/vcpkg/tools.cpp b/src/vcpkg/tools.cpp index 81cada54e3..dfdfdef11a 100644 --- a/src/vcpkg/tools.cpp +++ b/src/vcpkg/tools.cpp @@ -74,398 +74,409 @@ namespace vcpkg StringLiteral archiveName; }; - static Optional get_raw_tool_data(StringView toolname, CPUArchitecture arch, StringView os) + static constexpr ArchToolData tool_data_table[] = { + { + "python3", + "windows", + nullopt, + "3.11.8", + "python.exe", + "https://www.python.org/ftp/python/3.11.8/python-3.11.8-embed-win32.zip", + "c88ef02f0860000dbc59361cfe051e3e8dc7d208ed39bb5bc20a3e8b8711b578926e281a11941787ea61b2ef05b945ab313332" + "2dcb85b916f79ac4ada57f6309", + "python-3.11.8-embed-win32.zip", + }, + { + "python3_with_venv", + "windows", + nullopt, + "3.11.8", + "tools/python.exe", + "https://www.nuget.org/api/v2/package/python/3.11.8", + "8c1abd622fb2795fb87ab5208764fe13f7f4d69f2283b4237ea47b7c14b0989b5b4169f1ac1d3b1f417c6c2cc3d85ce151370d" + "ae8efc807c93e57cd67fa3c8cf", + "python-3.11.8.nupkg.zip", + }, + { + "cmake", + "windows", + nullopt, + "3.29.2", + "cmake-3.29.2-windows-i386/bin/cmake.exe", + "https://github.com/Kitware/CMake/releases/download/v3.29.2/cmake-3.29.2-windows-i386.zip", + "562de7b577c99fe347b00437d14ce375a8e5a60504909cb67d2f73c372d39a2f76d2b42b69e4aeb31a4879e1bcf6f7c2d41f2a" + "ce12180ea83ba7af48879d40ab", + "cmake-3.29.2-windows-i386.zip", + }, + { + "cmake", + "osx", + nullopt, + "3.29.2", + "cmake-3.29.2-macos-universal/CMake.app/Contents/bin/cmake", + "https://github.com/Kitware/CMake/releases/download/v3.29.2/cmake-3.29.2-macos-universal.tar.gz", + "26aab0163965f3d560dfd6b1f72c5e77192338237ebe286099fd62f243f1bbd4857b9193118386b801c00dc5cfbc5bc8af8481" + "4692fcfadcf56c7d2faab52533", + "cmake-3.29.2-macos-universal.tar.gz", + }, + { + "cmake", + "linux", + CPUArchitecture::ARM64, + "3.29.2", + "cmake-3.29.2-linux-aarch64/bin/cmake", + "https://github.com/Kitware/CMake/releases/download/v3.29.2/cmake-3.29.2-linux-aarch64.tar.gz", + "206b00604caf72f3dc644c7a5ac6a335814520fbf1512b9f2d4a5e8c26025d286bd106d2925ffbc874c754c518cbdb07f16919" + "16c39fcfd1202a47f592c8e3b0", + "cmake-3.29.2-linux-aarch64.tar.gz", + }, + { + "cmake", + "linux", + nullopt, + "3.29.2", + "cmake-3.29.2-linux-x86_64/bin/cmake", + "https://github.com/Kitware/CMake/releases/download/v3.29.2/cmake-3.29.2-linux-x86_64.tar.gz", + "d88082d582f1774a3d89efbf3f31a03b08a663c359d603d87ee7c4afd862d4164d2b0b9f0b32cece8efee3acfa86b44214cd4f" + "7606b99b8334183a05d5f06edc", + "cmake-3.29.2-linux-x86_64.tar.gz", + }, + { + "git", + "windows", + nullopt, + "2.7.4", + "mingw64/bin/git.exe", + "https://github.com/git-for-windows/git/releases/download/v2.43.0.windows.1/" + "PortableGit-2.43.0-64-bit.7z.exe", + "02ec40f55a6de18f305530e9415b6ce0a597359ebb9a58cf727ac84eceb0003b0f437941b76872b6568157a333c8e6e8d865a3" + "6faf874fd5f04774deb6a9387a", + "PortableGit-2.43.0-32-bit.7z.exe", + }, + { + "git", + "linux", + nullopt, + "2.7.4", + "", + "", + "", + "", + }, + { + "git", + "osx", + nullopt, + "2.7.4", + "", + "", + "", + "", + }, + { + "git", + "freebsd", + nullopt, + "2.7.4", + "", + "", + "", + "", + }, + { + "gsutil", + "windows", + nullopt, + "4.65", + "google-cloud-sdk/bin/gsutil.cmd", + "https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/" + "google-cloud-sdk-347.0.0-windows-x86_64-bundled-python.zip", + "e2792e17b132aad77f7c0b9fd26faf415e9437923d9227a9e6d253554e6843d29a6ddad0a7fb5e9aea4a130fd4c521e6ece884" + "4fd4a4f9e8d580348775425389", + "google-cloud-sdk-347.0.0-windows-x86_64-bundled-python.zip", + }, + { + "gsutil", + "osx", + nullopt, + "4.65", + "gsutil/gsutil", + "https://storage.googleapis.com/pub/gsutil_4.65.tar.gz", + "2c5c9dea48147f97180a491bbb9e24e8cbcd4f3452620e2f80338b781e4dfc90bb754e3bbfa05e1b990e44bff52d990d8c2dd5" + "1bc83d112339d8e6096a2f21c8", + "gsutil_4.65.tar.gz", + }, + { + "gsutil", + "linux", + nullopt, + "4.65", + "gsutil/gsutil", + "https://storage.googleapis.com/pub/gsutil_4.65.tar.gz", + "2c5c9dea48147f97180a491bbb9e24e8cbcd4f3452620e2f80338b781e4dfc90bb754e3bbfa05e1b990e44bff52d990d8c2dd5" + "1bc83d112339d8e6096a2f21c8", + "gsutil_4.65.tar.gz", + }, + { + "vswhere", + "windows", + nullopt, + "3.1.7", + "vswhere.exe", + "https://github.com/microsoft/vswhere/releases/download/3.1.7/vswhere.exe", + "40c534eb27f079c15c9782f53f82c12dabfede4d3d85f0edf8a855c2b0d5e12921a96506b37c210beab3c33220f8ff098447ad" + "054e82d8c2603964975fc12076", + "", + }, + { + "nuget", + "windows", + nullopt, + "6.10.0", + "nuget.exe", + "https://dist.nuget.org/win-x86-commandline/v6.10.0/nuget.exe", + "71d7307bb89de2df3811419c561efa00618a4c68e6ce481b0bdfc94c7c6c6d126a54eb26a0015686fabf99f109744ca41fead9" + "9e97139cdc86dde16a5ec3e7cf", + "", + }, + { + "nuget", + "linux", + nullopt, + "6.10.0", + "nuget.exe", + "https://dist.nuget.org/win-x86-commandline/v6.10.0/nuget.exe", + "71d7307bb89de2df3811419c561efa00618a4c68e6ce481b0bdfc94c7c6c6d126a54eb26a0015686fabf99f109744ca41fead9" + "9e97139cdc86dde16a5ec3e7cf", + "", + }, + { + "nuget", + "osx", + nullopt, + "6.10.0", + "nuget.exe", + "https://dist.nuget.org/win-x86-commandline/v6.10.0/nuget.exe", + "71d7307bb89de2df3811419c561efa00618a4c68e6ce481b0bdfc94c7c6c6d126a54eb26a0015686fabf99f109744ca41fead9" + "9e97139cdc86dde16a5ec3e7cf", + "", + }, + { + "coscli", + "windows", + nullopt, + "0.11.0", + "coscli-windows.exe", + "https://github.com/tencentyun/coscli/releases/download/v0.11.0-beta/coscli-windows.exe", + "38a521ec80cdb6944124f4233d7e71eed8cc9f9be2c0c736269915d21c3718ea8131e4516bb6eeada6df331f5fa8f47a299907" + "e50ee9edbe0114444520974d06", + "", + }, + { + "coscli", + "linux", + nullopt, + "0.11.0", + "coscli-linux", + "https://github.com/tencentyun/coscli/releases/download/v0.11.0-beta/coscli-linux", + "9c930a1d308e9581a0e2fdfe3751ea7fe13d6068df90ca6465740ec3eda034202ef71ec54c99e90015ff81aa68aa1489567db5" + "e411e222eb7258704bdac7e924", + "", + }, + { + "coscli", + "osx", + nullopt, + "0.11.0", + "coscli-mac", + "https://github.com/tencentyun/coscli/releases/download/v0.11.0-beta/coscli-mac", + "9556335bfc8bc14bace6dfced45fa77fb07c80f08aa975e047a54efda1d19852aae0ea68a5bc7f04fbd88e3edce5a73512a612" + "16b1c5ff4cade224de4a9ab8db", + "", + }, + { + "installerbase", + "windows", + nullopt, + "4.4.0", + "QtInstallerFramework-win-x86/bin/installerbase.exe", + "https://download.qt.io/official_releases/qt-installer-framework/4.4.0/" + "installer-framework-opensource-src-4.4.0.zip", + "fc713f54bfe2781cb232cd0ae8eddb96833ec178d53a55ec0b01886aa048b13441eb49a1f33282e8eab7259cfe512c890d50b8" + "e632d3dbf501a0bf1fd83de947", + "installer-framework-opensource-src-4.4.0.zip", + }, + { + "7zip_msi", + "windows", + nullopt, + "24.08", + "Files/7-Zip/7z.exe", + "https://github.com/ip7z/7zip/releases/download/24.08/7z2408-x64.msi", + "3259bf5e251382333c9d18a3fc01d83491fb41bc4ac4ddb25a02918494594c1074482b6608189a8a89e343d78e34d57420cdef" + "f1d7ace5acfdcaacc8776f1be8", + "7z2408-x64.msi", + }, + { + "7zip", + "windows", + nullopt, + "24.08", + "7za.exe", + "https://github.com/ip7z/7zip/releases/download/24.08/7z2408-extra.7z", + "35f55236fccfb576ca014e29d0c35f4a213e53f06683bd2e82f869ed02506e230c8dd623c01d0207244d6a997031f737903456" + "b7ad4a44db1717f0a17a78602e", + "7z2408-extra.7z", + }, + { + "7zr", + "windows", + nullopt, + "24.08", + "7zr.exe", + "https://github.com/ip7z/7zip/releases/download/24.08/7zr.exe", + "424196f2acf5b89807f4038683acc50e7604223fc630245af6bab0e0df923f8b1c49cb09ac709086568c214c3f53dcb7d6c32e" + "8a54af222a3ff78cfab9c51670", + "", + }, + { + "aria2", + "windows", + nullopt, + "1.37.0", + "aria2-1.37.0-win-64bit-build1/aria2c.exe", + "https://github.com/aria2/aria2/releases/download/release-1.37.0/aria2-1.37.0-win-64bit-build1.zip", + "6d78405da9cf5639dbe8174787002161b8124d73880fb57cc8c0a3a63982f84e46df4e626990c58f23452965ad925f0d37cb91" + "47e99b25c3d7ca0ea49602f34d", + "aria2-1.37.0-win-64bit-build1.zip", + }, + { + "aria2", + "osx", + nullopt, + "1.35.0", + "aria2-1.35.0/bin/aria2c", + "https://github.com/aria2/aria2/releases/download/release-1.35.0/aria2-1.35.0-osx-darwin.tar.bz2", + "3bb32b7d55347d1af37c6f4ebf0e20b38ce51c37a1baf92f7ad1762000539a03413dd679a6d902fdb1805fa71917300c9692ac" + "eee012eb06ecdff10491137aec", + "aria2-1.35.0-osx-darwin.tar.bz2", + }, + { + "ninja", + "windows", + nullopt, + "1.11.1", + "ninja.exe", + "https://github.com/ninja-build/ninja/releases/download/v1.11.1/ninja-win.zip", + "a700e794c32eb67b9f87040db7f1ba3a8e891636696fc54d416b01661c2421ff46fa517c97fd904adacdf8e621df3e68ea3801" + "05b909ae8b6651a78ae7eb3199", + "ninja-win-1.11.1.zip", + }, + { + "ninja", + "linux", + nullopt, + "1.11.1", + "ninja", + "https://github.com/ninja-build/ninja/releases/download/v1.11.1/ninja-linux.zip", + "6403dac9196baffcff614fa73ea530752997c8db6bbfbaa0446b4b09d7327e2aa6e8615d1283c961d3bf0df497e85ba8660414" + "9f1505ee75f89d600245a45dde", + "ninja-linux-1.11.1.zip", + }, + { + "ninja", + "osx", + nullopt, + "1.11.1", + "ninja", + "https://github.com/ninja-build/ninja/releases/download/v1.11.1/ninja-mac.zip", + "dad33b0918c60bbf5107951a936175b1610b4894a408f4ba4b47a2f5b328fc982a52a2aed6a0cb75028ee4765af5083bea6661" + "1c37516826eb0c851366bb4427", + "ninja-mac-1.11.1.zip", + }, + { + "powershell-core", + "windows", + nullopt, + "7.2.23", + "pwsh.exe", + "https://github.com/PowerShell/PowerShell/releases/download/v7.2.23/PowerShell-7.2.23-win-x64.zip", + "b374a878df02980d54e17ad7cfc9021e331748c3770f586be61356c257494d1b33899c1167d09a35c210bc084474aefdff972f" + "672d16afb43be0562b3589285a", + "PowerShell-7.2.23-win-x64.zip", + }, + { + "node", + "windows", + nullopt, + "16.15.1", + "node-v16.15.1-win-x64/node.exe", + "https://nodejs.org/dist/v16.15.1/node-v16.15.1-win-x64.7z", + "7ec4bfe2ea6034e1461e306b6372d62c0c5d1060c453ba76a73a5cec38ac26b5952a744caa9071455329caa58eb0a96d26c688" + "54c8915c17610ff27b0cf2c1cf", + "node-v16.15.1-win-x64.7z", + }, + { + "node", + "linux", + nullopt, + "16.15.1", + "node-v16.15.1-linux-x64/bin/node", + "https://nodejs.org/dist/v16.15.1/node-v16.15.1-linux-x64.tar.gz", + "5ad3b4b9caeaa8d31503efa99f5a593118a267dec9d4181d019732126ba248ce9a901207115b3f6b899eb5b3f0373c7f77ea95" + "cc92ac625cddf437ee9b8b8919", + "node-v16.15.1-linux-x64.tar.gz", + }, + { + "node", + "osx", + nullopt, + "16.15.1", + "node-v16.15.1-darwin-x64/bin/node", + "https://nodejs.org/dist/v16.15.1/node-v16.15.1-darwin-x64.tar.gz", + "90d0612bbe5467b6cf385c91a68b8daad0057e3e0ccacea44567f5b95b14f7481cb79784185ab1463b4bd990e092ff0f910957" + "6d1a1934b84e1c816582929611", + "node-v16.15.1-darwin-x64.tar.gz", + }, + }; + + static const ArchToolData* get_raw_tool_data(StringView toolname, CPUArchitecture arch, StringView os) { - const std::size_t NUM_TOOLS = 33; - ArchToolData tool_data[NUM_TOOLS] = { - { - "python3", - "windows", - nullopt, - "3.11.8", - "python.exe", - "https://www.python.org/ftp/python/3.11.8/python-3.11.8-embed-win32.zip", - "c88ef02f0860000dbc59361cfe051e3e8dc7d208ed39bb5bc20a3e8b8711b578926e281a11941787ea61b2ef05b945ab313332" - "2dcb85b916f79ac4ada57f6309", - "python-3.11.8-embed-win32.zip", - }, - { - "python3_with_venv", - "windows", - nullopt, - "3.11.8", - "tools/python.exe", - "https://www.nuget.org/api/v2/package/python/3.11.8", - "8c1abd622fb2795fb87ab5208764fe13f7f4d69f2283b4237ea47b7c14b0989b5b4169f1ac1d3b1f417c6c2cc3d85ce151370d" - "ae8efc807c93e57cd67fa3c8cf", - "python-3.11.8.nupkg.zip", - }, - { - "cmake", - "windows", - nullopt, - "3.29.2", - "cmake-3.29.2-windows-i386/bin/cmake.exe", - "https://github.com/Kitware/CMake/releases/download/v3.29.2/cmake-3.29.2-windows-i386.zip", - "562de7b577c99fe347b00437d14ce375a8e5a60504909cb67d2f73c372d39a2f76d2b42b69e4aeb31a4879e1bcf6f7c2d41f2a" - "ce12180ea83ba7af48879d40ab", - "cmake-3.29.2-windows-i386.zip", - }, - { - "cmake", - "osx", - nullopt, - "3.29.2", - "cmake-3.29.2-macos-universal/CMake.app/Contents/bin/cmake", - "https://github.com/Kitware/CMake/releases/download/v3.29.2/cmake-3.29.2-macos-universal.tar.gz", - "26aab0163965f3d560dfd6b1f72c5e77192338237ebe286099fd62f243f1bbd4857b9193118386b801c00dc5cfbc5bc8af8481" - "4692fcfadcf56c7d2faab52533", - "cmake-3.29.2-macos-universal.tar.gz", - }, - { - "cmake", - "linux", - CPUArchitecture::ARM64, - "3.29.2", - "cmake-3.29.2-linux-aarch64/bin/cmake", - "https://github.com/Kitware/CMake/releases/download/v3.29.2/cmake-3.29.2-linux-aarch64.tar.gz", - "206b00604caf72f3dc644c7a5ac6a335814520fbf1512b9f2d4a5e8c26025d286bd106d2925ffbc874c754c518cbdb07f16919" - "16c39fcfd1202a47f592c8e3b0", - "cmake-3.29.2-linux-aarch64.tar.gz", - }, - { - "cmake", - "linux", - nullopt, - "3.29.2", - "cmake-3.29.2-linux-x86_64/bin/cmake", - "https://github.com/Kitware/CMake/releases/download/v3.29.2/cmake-3.29.2-linux-x86_64.tar.gz", - "d88082d582f1774a3d89efbf3f31a03b08a663c359d603d87ee7c4afd862d4164d2b0b9f0b32cece8efee3acfa86b44214cd4f" - "7606b99b8334183a05d5f06edc", - "cmake-3.29.2-linux-x86_64.tar.gz", - }, - { - "git", - "windows", - nullopt, - "2.7.4", - "mingw64/bin/git.exe", - "https://github.com/git-for-windows/git/releases/download/v2.43.0.windows.1/" - "PortableGit-2.43.0-64-bit.7z.exe", - "02ec40f55a6de18f305530e9415b6ce0a597359ebb9a58cf727ac84eceb0003b0f437941b76872b6568157a333c8e6e8d865a3" - "6faf874fd5f04774deb6a9387a", - "PortableGit-2.43.0-32-bit.7z.exe", - }, - { - "git", - "linux", - nullopt, - "2.7.4", - "", - "", - "", - "", - }, - { - "git", - "osx", - nullopt, - "2.7.4", - "", - "", - "", - "", - }, - { - "git", - "freebsd", - nullopt, - "2.7.4", - "", - "", - "", - "", - }, - { - "gsutil", - "windows", - nullopt, - "4.65", - "google-cloud-sdk/bin/gsutil.cmd", - "https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/" - "google-cloud-sdk-347.0.0-windows-x86_64-bundled-python.zip", - "e2792e17b132aad77f7c0b9fd26faf415e9437923d9227a9e6d253554e6843d29a6ddad0a7fb5e9aea4a130fd4c521e6ece884" - "4fd4a4f9e8d580348775425389", - "google-cloud-sdk-347.0.0-windows-x86_64-bundled-python.zip", - }, - { - "gsutil", - "osx", - nullopt, - "4.65", - "gsutil/gsutil", - "https://storage.googleapis.com/pub/gsutil_4.65.tar.gz", - "2c5c9dea48147f97180a491bbb9e24e8cbcd4f3452620e2f80338b781e4dfc90bb754e3bbfa05e1b990e44bff52d990d8c2dd5" - "1bc83d112339d8e6096a2f21c8", - "gsutil_4.65.tar.gz", - }, - { - "gsutil", - "linux", - nullopt, - "4.65", - "gsutil/gsutil", - "https://storage.googleapis.com/pub/gsutil_4.65.tar.gz", - "2c5c9dea48147f97180a491bbb9e24e8cbcd4f3452620e2f80338b781e4dfc90bb754e3bbfa05e1b990e44bff52d990d8c2dd5" - "1bc83d112339d8e6096a2f21c8", - "gsutil_4.65.tar.gz", - }, - { - "vswhere", - "windows", - nullopt, - "3.1.7", - "vswhere.exe", - "https://github.com/microsoft/vswhere/releases/download/3.1.7/vswhere.exe", - "40c534eb27f079c15c9782f53f82c12dabfede4d3d85f0edf8a855c2b0d5e12921a96506b37c210beab3c33220f8ff098447ad" - "054e82d8c2603964975fc12076", - "", - }, - { - "nuget", - "windows", - nullopt, - "6.10.0", - "nuget.exe", - "https://dist.nuget.org/win-x86-commandline/v6.10.0/nuget.exe", - "71d7307bb89de2df3811419c561efa00618a4c68e6ce481b0bdfc94c7c6c6d126a54eb26a0015686fabf99f109744ca41fead9" - "9e97139cdc86dde16a5ec3e7cf", - "", - }, - { - "nuget", - "linux", - nullopt, - "6.10.0", - "nuget.exe", - "https://dist.nuget.org/win-x86-commandline/v6.10.0/nuget.exe", - "71d7307bb89de2df3811419c561efa00618a4c68e6ce481b0bdfc94c7c6c6d126a54eb26a0015686fabf99f109744ca41fead9" - "9e97139cdc86dde16a5ec3e7cf", - "", - }, - { - "nuget", - "osx", - nullopt, - "6.10.0", - "nuget.exe", - "https://dist.nuget.org/win-x86-commandline/v6.10.0/nuget.exe", - "71d7307bb89de2df3811419c561efa00618a4c68e6ce481b0bdfc94c7c6c6d126a54eb26a0015686fabf99f109744ca41fead9" - "9e97139cdc86dde16a5ec3e7cf", - "", - }, - { - "coscli", - "windows", - nullopt, - "0.11.0", - "coscli-windows.exe", - "https://github.com/tencentyun/coscli/releases/download/v0.11.0-beta/coscli-windows.exe", - "38a521ec80cdb6944124f4233d7e71eed8cc9f9be2c0c736269915d21c3718ea8131e4516bb6eeada6df331f5fa8f47a299907" - "e50ee9edbe0114444520974d06", - "", - }, - { - "coscli", - "linux", - nullopt, - "0.11.0", - "coscli-linux", - "https://github.com/tencentyun/coscli/releases/download/v0.11.0-beta/coscli-linux", - "9c930a1d308e9581a0e2fdfe3751ea7fe13d6068df90ca6465740ec3eda034202ef71ec54c99e90015ff81aa68aa1489567db5" - "e411e222eb7258704bdac7e924", - "", - }, - { - "coscli", - "osx", - nullopt, - "0.11.0", - "coscli-mac", - "https://github.com/tencentyun/coscli/releases/download/v0.11.0-beta/coscli-mac", - "9556335bfc8bc14bace6dfced45fa77fb07c80f08aa975e047a54efda1d19852aae0ea68a5bc7f04fbd88e3edce5a73512a612" - "16b1c5ff4cade224de4a9ab8db", - "", - }, - { - "installerbase", - "windows", - nullopt, - "4.4.0", - "QtInstallerFramework-win-x86/bin/installerbase.exe", - "https://download.qt.io/official_releases/qt-installer-framework/4.4.0/" - "installer-framework-opensource-src-4.4.0.zip", - "fc713f54bfe2781cb232cd0ae8eddb96833ec178d53a55ec0b01886aa048b13441eb49a1f33282e8eab7259cfe512c890d50b8" - "e632d3dbf501a0bf1fd83de947", - "installer-framework-opensource-src-4.4.0.zip", - }, - { - "7zip_msi", - "windows", - nullopt, - "24.08", - "Files/7-Zip/7z.exe", - "https://github.com/ip7z/7zip/releases/download/24.08/7z2408-x64.msi", - "3259bf5e251382333c9d18a3fc01d83491fb41bc4ac4ddb25a02918494594c1074482b6608189a8a89e343d78e34d57420cdef" - "f1d7ace5acfdcaacc8776f1be8", - "7z2408-x64.msi", - }, - { - "7zip", - "windows", - nullopt, - "24.08", - "7za.exe", - "https://github.com/ip7z/7zip/releases/download/24.08/7z2408-extra.7z", - "35f55236fccfb576ca014e29d0c35f4a213e53f06683bd2e82f869ed02506e230c8dd623c01d0207244d6a997031f737903456" - "b7ad4a44db1717f0a17a78602e", - "7z2408-extra.7z", - }, - { - "7zr", - "windows", - nullopt, - "24.08", - "7zr.exe", - "https://github.com/ip7z/7zip/releases/download/24.08/7zr.exe", - "424196f2acf5b89807f4038683acc50e7604223fc630245af6bab0e0df923f8b1c49cb09ac709086568c214c3f53dcb7d6c32e" - "8a54af222a3ff78cfab9c51670", - "", - }, - { - "aria2", - "windows", - nullopt, - "1.37.0", - "aria2-1.37.0-win-64bit-build1/aria2c.exe", - "https://github.com/aria2/aria2/releases/download/release-1.37.0/aria2-1.37.0-win-64bit-build1.zip", - "6d78405da9cf5639dbe8174787002161b8124d73880fb57cc8c0a3a63982f84e46df4e626990c58f23452965ad925f0d37cb91" - "47e99b25c3d7ca0ea49602f34d", - "aria2-1.37.0-win-64bit-build1.zip", - }, - { - "aria2", - "osx", - nullopt, - "1.35.0", - "aria2-1.35.0/bin/aria2c", - "https://github.com/aria2/aria2/releases/download/release-1.35.0/aria2-1.35.0-osx-darwin.tar.bz2", - "3bb32b7d55347d1af37c6f4ebf0e20b38ce51c37a1baf92f7ad1762000539a03413dd679a6d902fdb1805fa71917300c9692ac" - "eee012eb06ecdff10491137aec", - "aria2-1.35.0-osx-darwin.tar.bz2", - }, - { - "ninja", - "windows", - nullopt, - "1.11.1", - "ninja.exe", - "https://github.com/ninja-build/ninja/releases/download/v1.11.1/ninja-win.zip", - "a700e794c32eb67b9f87040db7f1ba3a8e891636696fc54d416b01661c2421ff46fa517c97fd904adacdf8e621df3e68ea3801" - "05b909ae8b6651a78ae7eb3199", - "ninja-win-1.11.1.zip", - }, - { - "ninja", - "linux", - nullopt, - "1.11.1", - "ninja", - "https://github.com/ninja-build/ninja/releases/download/v1.11.1/ninja-linux.zip", - "6403dac9196baffcff614fa73ea530752997c8db6bbfbaa0446b4b09d7327e2aa6e8615d1283c961d3bf0df497e85ba8660414" - "9f1505ee75f89d600245a45dde", - "ninja-linux-1.11.1.zip", - }, - { - "ninja", - "osx", - nullopt, - "1.11.1", - "ninja", - "https://github.com/ninja-build/ninja/releases/download/v1.11.1/ninja-mac.zip", - "dad33b0918c60bbf5107951a936175b1610b4894a408f4ba4b47a2f5b328fc982a52a2aed6a0cb75028ee4765af5083bea6661" - "1c37516826eb0c851366bb4427", - "ninja-mac-1.11.1.zip", - }, - { - "powershell-core", - "windows", - nullopt, - "7.2.23", - "pwsh.exe", - "https://github.com/PowerShell/PowerShell/releases/download/v7.2.23/PowerShell-7.2.23-win-x64.zip", - "b374a878df02980d54e17ad7cfc9021e331748c3770f586be61356c257494d1b33899c1167d09a35c210bc084474aefdff972f" - "672d16afb43be0562b3589285a", - "PowerShell-7.2.23-win-x64.zip", - }, - { - "node", - "windows", - nullopt, - "16.15.1", - "node-v16.15.1-win-x64/node.exe", - "https://nodejs.org/dist/v16.15.1/node-v16.15.1-win-x64.7z", - "7ec4bfe2ea6034e1461e306b6372d62c0c5d1060c453ba76a73a5cec38ac26b5952a744caa9071455329caa58eb0a96d26c688" - "54c8915c17610ff27b0cf2c1cf", - "node-v16.15.1-win-x64.7z", - }, - { - "node", - "linux", - nullopt, - "16.15.1", - "node-v16.15.1-linux-x64/bin/node", - "https://nodejs.org/dist/v16.15.1/node-v16.15.1-linux-x64.tar.gz", - "5ad3b4b9caeaa8d31503efa99f5a593118a267dec9d4181d019732126ba248ce9a901207115b3f6b899eb5b3f0373c7f77ea95" - "cc92ac625cddf437ee9b8b8919", - "node-v16.15.1-linux-x64.tar.gz", - }, - { - "node", - "osx", - nullopt, - "16.15.1", - "node-v16.15.1-darwin-x64/bin/node", - "https://nodejs.org/dist/v16.15.1/node-v16.15.1-darwin-x64.tar.gz", - "90d0612bbe5467b6cf385c91a68b8daad0057e3e0ccacea44567f5b95b14f7481cb79784185ab1463b4bd990e092ff0f910957" - "6d1a1934b84e1c816582929611", - "node-v16.15.1-darwin-x64.tar.gz", - }}; - - size_t default_tool = 0; - bool existsDefaultTool = false; - for (std::size_t i = 0; i < NUM_TOOLS; i++) - { - // if possible, find a tool with matching tool name, architecture, and os - // otherwise, choose a tool with only matching name and os and nullopt - // as architecture (this is the default tool) - const ArchToolData& d = tool_data[i]; - if (d.tool == toolname && d.arch.has_value() && d.arch.value_or_exit(VCPKG_LINE_INFO) == arch && d.os == os) - { - return d; - } - else if (d.tool == toolname && d.os == os && !d.arch.has_value()) + const ArchToolData* default_tool = nullptr; + for (auto&& d : tool_data_table) + { + if (d.tool == toolname && d.os == os) { - default_tool = i; - existsDefaultTool = true; + // if the tool data record declares an architecture matching the one we're looking for, that's an exact + // match and we've found the right one + if (auto d_arch = d.arch.get()) + { + if (*d_arch == arch) + { + return &d; + } + } + else + { + // if the tool data record does not declare an architecture, we merely record a 'default tool' in + // case a more specific entry naming an architecture is seen + if (default_tool) + { + Checks::unreachable(VCPKG_LINE_INFO, + "there should be only one tool entry with an undeclared architecture"); + } + + default_tool = &d; + } } } - if (existsDefaultTool) + + if (default_tool) { - return tool_data[default_tool]; + return default_tool; } - return nullopt; + return nullptr; } static Optional get_tool_data(StringView tool) @@ -484,37 +495,36 @@ namespace vcpkg #else return nullopt; #endif - if (!data.has_value()) + if (!data) { return nullopt; } - auto& d = data.value_or_exit(VCPKG_LINE_INFO); - const Optional> version = parse_tool_version_string(d.version); + const Optional> version = parse_tool_version_string(data->version); Checks::msg_check_exit(VCPKG_LINE_INFO, version.has_value(), msgFailedToParseVersionXML, msg::tool_name = tool, - msg::version = d.version); + msg::version = data->version); - Path tool_dir_name = fmt::format("{}-{}-{}", tool, d.version, d.os); + Path tool_dir_name = fmt::format("{}-{}-{}", tool, data->version, data->os); Path download_subpath; - if (!d.archiveName.empty()) + if (!data->archiveName.empty()) { - download_subpath = d.archiveName; + download_subpath = data->archiveName; } - else if (!d.exeRelativePath.empty()) + else if (!data->exeRelativePath.empty()) { - download_subpath = Strings::concat(StringView{d.sha512}.substr(0, 8), '-', d.exeRelativePath); + download_subpath = Strings::concat(StringView{data->sha512}.substr(0, 8), '-', data->exeRelativePath); } return ToolData{tool.to_string(), *version.get(), - d.exeRelativePath, - std::string(d.url), + data->exeRelativePath, + data->url.to_string(), download_subpath, - !d.archiveName.empty(), + !data->archiveName.empty(), tool_dir_name, - std::string(d.sha512)}; + data->sha512.to_string()}; } struct PathAndVersion From c340da3dfc965fb5b4a6ac452962800c464970b3 Mon Sep 17 00:00:00 2001 From: Billy Robert O'Neal III Date: Mon, 23 Sep 2024 16:42:57 -0700 Subject: [PATCH 09/30] =?UTF-8?q?Fixup=20optional=20=F0=9F=98=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/vcpkg/base/optional.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/vcpkg/base/optional.h b/include/vcpkg/base/optional.h index e10fe9ac6b..392da7cdb5 100644 --- a/include/vcpkg/base/optional.h +++ b/include/vcpkg/base/optional.h @@ -40,7 +40,7 @@ namespace vcpkg constexpr OptionalStorageDtor() : m_is_present(false), m_inactive() { } template constexpr OptionalStorageDtor(EngageTag, Args&&... args) noexcept(std::is_nothrow_constructible_v) - : m_is_present(false), m_t(std::forward(args)...) + : m_is_present(true), m_t(std::forward(args)...) { } }; @@ -58,7 +58,7 @@ namespace vcpkg constexpr OptionalStorageDtor() : m_is_present(false), m_inactive() { } template constexpr OptionalStorageDtor(EngageTag, Args&&... args) noexcept(std::is_nothrow_constructible_v) - : m_is_present(false), m_t(std::forward(args)...) + : m_is_present(true), m_t(std::forward(args)...) { } From 6c41ed578d6a80aeb6682e0f1d2945adb701a19e Mon Sep 17 00:00:00 2001 From: Billy Robert O'Neal III Date: Mon, 23 Sep 2024 16:44:04 -0700 Subject: [PATCH 10/30] clang-format --- include/vcpkg/base/optional.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/include/vcpkg/base/optional.h b/include/vcpkg/base/optional.h index 392da7cdb5..c18619deb9 100644 --- a/include/vcpkg/base/optional.h +++ b/include/vcpkg/base/optional.h @@ -39,7 +39,8 @@ namespace vcpkg constexpr OptionalStorageDtor() : m_is_present(false), m_inactive() { } template - constexpr OptionalStorageDtor(EngageTag, Args&&... args) noexcept(std::is_nothrow_constructible_v) + constexpr OptionalStorageDtor(EngageTag, + Args&&... args) noexcept(std::is_nothrow_constructible_v) : m_is_present(true), m_t(std::forward(args)...) { } @@ -57,7 +58,8 @@ namespace vcpkg constexpr OptionalStorageDtor() : m_is_present(false), m_inactive() { } template - constexpr OptionalStorageDtor(EngageTag, Args&&... args) noexcept(std::is_nothrow_constructible_v) + constexpr OptionalStorageDtor(EngageTag, + Args&&... args) noexcept(std::is_nothrow_constructible_v) : m_is_present(true), m_t(std::forward(args)...) { } From 7e6947cb270dde57caaabed01cec47e293b966cc Mon Sep 17 00:00:00 2001 From: Billy Robert O'Neal III Date: Tue, 24 Sep 2024 13:36:46 -0700 Subject: [PATCH 11/30] Suppress -Werror=unused-but-set-variable in optional tests. --- src/vcpkg-test/optional.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/vcpkg-test/optional.cpp b/src/vcpkg-test/optional.cpp index 88c3211001..2bb85b642d 100644 --- a/src/vcpkg-test/optional.cpp +++ b/src/vcpkg-test/optional.cpp @@ -65,6 +65,7 @@ TEST_CASE ("value conversion", "[optional]") Optional j = 1; Optional i = j; + (void)i; Optional cstr = "hello, world!"; Optional cppstr = cstr; @@ -89,9 +90,12 @@ TEST_CASE ("optional.map", "[optional]") const Optional> move_only; Optional m = move_only.map([](auto&& p) { return p.get(); }); + (void)m; Optional> n = move_only.map([](auto&& p) -> Optional { return p ? Optional{p.get()} : nullopt; }); + (void)n; Optional o = move_only.map([](auto&&) { return nullopt; }); + (void)o; Optional five = 5; From 8b5511c52b3e8daef74b13b8d43af832c6a8d9bb Mon Sep 17 00:00:00 2001 From: data-queue <144965964+data-queue@users.noreply.github.com> Date: Thu, 3 Oct 2024 09:09:19 +0000 Subject: [PATCH 12/30] fix --- .../end-to-end-tests-dir/fetch.ps1 | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 azure-pipelines/end-to-end-tests-dir/fetch.ps1 diff --git a/azure-pipelines/end-to-end-tests-dir/fetch.ps1 b/azure-pipelines/end-to-end-tests-dir/fetch.ps1 new file mode 100644 index 0000000000..c4d4ce2244 --- /dev/null +++ b/azure-pipelines/end-to-end-tests-dir/fetch.ps1 @@ -0,0 +1,51 @@ +. $PSScriptRoot/../end-to-end-tests-prelude.ps1 + +if (-not $IsMacOS -and -not $IsLinux) { + "" | Out-File -enc ascii $(Join-Path $TestingRoot .vcpkg-root) + + $Scripts = Join-Path $TestingRoot "scripts" + mkdir $Scripts | Out-Null + + $7zip_version = "24.08" + $ninja_version = "1.11.1" + + $env:VCPKG_DOWNLOADS = Join-Path $TestingRoot 'down loads' + Run-Vcpkg -TestArgs ($commonArgs + @("fetch", "7zip", "--vcpkg-root=$TestingRoot")) + Throw-IfFailed + Require-FileExists "$TestingRoot/down loads/tools/7zip-${7zip_version}-windows/7za.exe" + + Run-Vcpkg -TestArgs ($commonArgs + @("fetch", "ninja", "--vcpkg-root=$TestingRoot")) + Throw-IfFailed + Require-FileExists "$TestingRoot/down loads/tools/ninja-${ninja_version}-windows/ninja.exe" + + mkdir "$TestingRoot/down loads/tools/ninja-testing-${ninja_version}-windows" | Out-Null + Move-Item -Path "$TestingRoot/down loads/tools/ninja-${ninja_version}-windows/ninja.exe" -Destination "$TestingRoot/down loads/tools/ninja-testing-${ninja_version}-windows/ninja.exe" + $path = $env:PATH + + $env:PATH = "$path;$TestingRoot/down loads/tools/ninja-testing-${ninja_version}-windows" + Run-Vcpkg -TestArgs ($commonArgs + @("fetch", "ninja", "--vcpkg-root=$TestingRoot")) + Throw-IfFailed + Require-FileNotExists "$TestingRoot/down loads/tools/ninja-${ninja_version}-windows/ninja.exe" + + $env:VCPKG_FORCE_DOWNLOADED_BINARIES = "1" + Run-Vcpkg -TestArgs ($commonArgs + @("fetch", "ninja", "--vcpkg-root=$TestingRoot")) + Throw-IfFailed + Require-FileExists "$TestingRoot/down loads/tools/ninja-${ninja_version}-windows/ninja.exe" + + Remove-Item -Recurse -Force "$TestingRoot/down loads/tools/ninja-${ninja_version}-windows" -ErrorAction SilentlyContinue + Remove-Item env:VCPKG_FORCE_DOWNLOADED_BINARIES + + $env:VCPKG_FORCE_SYSTEM_BINARIES = "1" + $env:PATH = "$PSScriptRoot\..\e2e-assets\fetch;$path" + Run-Vcpkg -TestArgs ($commonArgs + @("fetch", "ninja", "--vcpkg-root=$TestingRoot")) + Throw-IfFailed + Require-FileNotExists "$TestingRoot/down loads/tools/ninja-${ninja_version}-windows/ninja.exe" + + Remove-Item env:VCPKG_FORCE_SYSTEM_BINARIES + $out = Run-VcpkgAndCaptureOutput -TestArgs ($commonArgs + @("fetch", "ninja", "--vcpkg-root=$TestingRoot", "--x-stderr-status")) + Throw-IfFailed + & $out --version + if ($LASTEXITCODE -ne 0) { + throw 'Couldn''t run resulting ninja' + } +} From b183ea6dc0df00851de0d52de8b0140abc385c38 Mon Sep 17 00:00:00 2001 From: data-queue <144965964+data-queue@users.noreply.github.com> Date: Thu, 3 Oct 2024 09:31:25 +0000 Subject: [PATCH 13/30] fix --- azure-pipelines/end-to-end-tests-dir/fetch.ps1 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/azure-pipelines/end-to-end-tests-dir/fetch.ps1 b/azure-pipelines/end-to-end-tests-dir/fetch.ps1 index c4d4ce2244..1ed49fc174 100644 --- a/azure-pipelines/end-to-end-tests-dir/fetch.ps1 +++ b/azure-pipelines/end-to-end-tests-dir/fetch.ps1 @@ -10,6 +10,7 @@ if (-not $IsMacOS -and -not $IsLinux) { $ninja_version = "1.11.1" $env:VCPKG_DOWNLOADS = Join-Path $TestingRoot 'down loads' + $env:VCPKG_FORCE_DOWNLOADED_BINARIES = "1" Run-Vcpkg -TestArgs ($commonArgs + @("fetch", "7zip", "--vcpkg-root=$TestingRoot")) Throw-IfFailed Require-FileExists "$TestingRoot/down loads/tools/7zip-${7zip_version}-windows/7za.exe" @@ -21,6 +22,7 @@ if (-not $IsMacOS -and -not $IsLinux) { mkdir "$TestingRoot/down loads/tools/ninja-testing-${ninja_version}-windows" | Out-Null Move-Item -Path "$TestingRoot/down loads/tools/ninja-${ninja_version}-windows/ninja.exe" -Destination "$TestingRoot/down loads/tools/ninja-testing-${ninja_version}-windows/ninja.exe" $path = $env:PATH + Remove-Item env:VCPKG_FORCE_DOWNLOADED_BINARIES $env:PATH = "$path;$TestingRoot/down loads/tools/ninja-testing-${ninja_version}-windows" Run-Vcpkg -TestArgs ($commonArgs + @("fetch", "ninja", "--vcpkg-root=$TestingRoot")) From 4d8eb9bc5a41b88535514774c42657032d047924 Mon Sep 17 00:00:00 2001 From: Victor Romero Date: Fri, 13 Dec 2024 00:01:09 -0800 Subject: [PATCH 14/30] wip --- .../end-to-end-tests-dir/fetch.ps1 | 90 ++- include/vcpkg/base/jsonreader.h | 14 + include/vcpkg/tools.h | 1 + include/vcpkg/tools.test.h | 32 ++ src/vcpkg-test/tools.cpp | 144 +++++ src/vcpkg/base/json.cpp | 55 ++ src/vcpkg/tools.cpp | 544 +++++------------- src/vcpkg/vcpkgpaths.cpp | 1 + 8 files changed, 459 insertions(+), 422 deletions(-) diff --git a/azure-pipelines/end-to-end-tests-dir/fetch.ps1 b/azure-pipelines/end-to-end-tests-dir/fetch.ps1 index 1ed49fc174..cd83a52c54 100644 --- a/azure-pipelines/end-to-end-tests-dir/fetch.ps1 +++ b/azure-pipelines/end-to-end-tests-dir/fetch.ps1 @@ -6,42 +6,104 @@ if (-not $IsMacOS -and -not $IsLinux) { $Scripts = Join-Path $TestingRoot "scripts" mkdir $Scripts | Out-Null - $7zip_version = "24.08" - $ninja_version = "1.11.1" + $7zip_version = "19.00" + $ninja_version = "1.10.2" + + @' +[{ + "name": "7zip", + "os": "windows", + "version": "19.00", + "executable": "Files\\7-Zip\\7z.exe", + "url": "https://www.7-zip.org/a/7z1900-x64.msi", + "sha512": "7837a8677a01eed9c3309923f7084bc864063ba214ee169882c5b04a7a8b198ed052c15e981860d9d7952c98f459a4fab87a72fd78e7d0303004dcb86f4324c8", + "archive": "7z1900-x64.msi" +}, +{ + "name": "ninja-testing", + "os": "windows", + "version": "1.10.2", + "executable": "ninja.exe", + "url": "https://github.com/ninja-build/ninja/releases/download/v1.10.2/ninja-win.zip", + "sha512": "6004140d92e86afbb17b49c49037ccd0786ce238f340f7d0e62b4b0c29ed0d6ad0bab11feda2094ae849c387d70d63504393714ed0a1f4d3a1f155af7a4f1ba3", + "archive": "ninja-win-1.10.2.zip" +}, +{ + "name": "ninja", + "os": "windows", + "version": "1.10.2", + "executable": "ninja.exe", + "url": "https://github.com/ninja-build/ninja/releases/download/v1.10.2/ninja-win.zip", + "sha512": "6004140d92e86afbb17b49c49037ccd0786ce238f340f7d0e62b4b0c29ed0d6ad0bab11feda2094ae849c387d70d63504393714ed0a1f4d3a1f155af7a4f1ba3", + "archive": "ninja-win-1.10.2.zip" +}, +{ + "name": "cmake", + "os": "windows", + "version": "3.22.2", + "executable": "cmake-3.22.2-windows-i386\\bin\\cmake.exe", + "url": "https://github.com/Kitware/CMake/releases/download/v3.22.2/cmake-3.22.2-windows-i386.zip", + "sha512": "969d3d58d56d8fa3cc3acae2b949bf58abab945f70ae292ff20c9060d845dfc094c613c367a924abff47f307cc33af1467cdb9b75bb857868e38b2c7cdc72f79", + "archive": "cmake-3.22.2-windows-i386.zip" +}, +{ + "name": "cmake", + "os": "osx", + "version": "3.22.2", + "executable": "cmake-3.22.2-macos-universal/CMake.app/Contents/bin/cmake", + "url": "https://github.com/Kitware/CMake/releases/download/v3.22.2/cmake-3.22.2-macos-universal.tar.gz", + "sha512": "08104f608ecb9a5cfef38e79f0957d21e425616c0677781445492f82cbfec805113e3b5eb4bc737b707bb26a00678e7bd55e17555a5611c08b0b9b44ac5136ac", + "archive": "cmake-3.22.2-macos-universal.tar.gz" +}, +{ + "name": "cmake", + "os": "linux", + "version": "3.22.2", + "executable": "cmake-3.22.2-linux-x86_64/bin/cmake", + "url": "https://github.com/Kitware/CMake/releases/download/v3.22.2/cmake-3.22.2-linux-x86_64.tar.gz", + "sha512": "579e08b086f6903ef063697fca1dc2692f68a7341dd35998990b772b4221cdb5b1deecfa73bad9d46817ef09e58882b2adff9d64f959c01002c11448a878746b", + "archive": "cmake-3.22.2linux-x86_64.tar.gz" +}, +{ + "name": "cmake", + "os": "freebsd", + "version": "3.20.4", + "executable": "/usr/local/bin/cmake", + "url": "https://pkg.freebsd.org/FreeBSD:13:amd64/quarterly/All/cmake-3.20.4.txz", + "sha512": "3e5b675d7ff924f92996d912e2365582e687375109ef99c9073fb8196bb329243a406b218cf1358d7cc518988b311ce9e5bf87de4d64f2e6377b7c2bc8894475", + "archive": "cmake-3.20.4.txz" +}] +'@ | % { $_ -replace "`r","" } | Out-File -enc ascii $(Join-Path $Scripts "vcpkg-tools.json") $env:VCPKG_DOWNLOADS = Join-Path $TestingRoot 'down loads' - $env:VCPKG_FORCE_DOWNLOADED_BINARIES = "1" Run-Vcpkg -TestArgs ($commonArgs + @("fetch", "7zip", "--vcpkg-root=$TestingRoot")) Throw-IfFailed - Require-FileExists "$TestingRoot/down loads/tools/7zip-${7zip_version}-windows/7za.exe" + Require-FileExists "$env:VCPKG_DOWNLOADS/tools/7zip-19.00-windows/Files/7-Zip/7z.exe" - Run-Vcpkg -TestArgs ($commonArgs + @("fetch", "ninja", "--vcpkg-root=$TestingRoot")) + Run-Vcpkg -TestArgs ($commonArgs + @("fetch", "ninja-testing", "--vcpkg-root=$TestingRoot")) Throw-IfFailed - Require-FileExists "$TestingRoot/down loads/tools/ninja-${ninja_version}-windows/ninja.exe" + Require-FileExists "$env:VCPKG_DOWNLOADS/tools/ninja-testing-1.10.2-windows/ninja.exe" - mkdir "$TestingRoot/down loads/tools/ninja-testing-${ninja_version}-windows" | Out-Null - Move-Item -Path "$TestingRoot/down loads/tools/ninja-${ninja_version}-windows/ninja.exe" -Destination "$TestingRoot/down loads/tools/ninja-testing-${ninja_version}-windows/ninja.exe" $path = $env:PATH - Remove-Item env:VCPKG_FORCE_DOWNLOADED_BINARIES - $env:PATH = "$path;$TestingRoot/down loads/tools/ninja-testing-${ninja_version}-windows" + $env:PATH = "$path;$env:VCPKG_DOWNLOADS/tools/ninja-testing-1.10.2-windows" Run-Vcpkg -TestArgs ($commonArgs + @("fetch", "ninja", "--vcpkg-root=$TestingRoot")) Throw-IfFailed - Require-FileNotExists "$TestingRoot/down loads/tools/ninja-${ninja_version}-windows/ninja.exe" + Require-FileNotExists "$env:VCPKG_DOWNLOADS/tools/ninja-1.10.2-windows/ninja.exe" $env:VCPKG_FORCE_DOWNLOADED_BINARIES = "1" Run-Vcpkg -TestArgs ($commonArgs + @("fetch", "ninja", "--vcpkg-root=$TestingRoot")) Throw-IfFailed - Require-FileExists "$TestingRoot/down loads/tools/ninja-${ninja_version}-windows/ninja.exe" + Require-FileExists "$env:VCPKG_DOWNLOADS/tools/ninja-1.10.2-windows/ninja.exe" - Remove-Item -Recurse -Force "$TestingRoot/down loads/tools/ninja-${ninja_version}-windows" -ErrorAction SilentlyContinue + Remove-Item -Recurse -Force "$env:VCPKG_DOWNLOADS/tools/ninja-1.10.2-windows" -ErrorAction SilentlyContinue Remove-Item env:VCPKG_FORCE_DOWNLOADED_BINARIES $env:VCPKG_FORCE_SYSTEM_BINARIES = "1" $env:PATH = "$PSScriptRoot\..\e2e-assets\fetch;$path" Run-Vcpkg -TestArgs ($commonArgs + @("fetch", "ninja", "--vcpkg-root=$TestingRoot")) Throw-IfFailed - Require-FileNotExists "$TestingRoot/down loads/tools/ninja-${ninja_version}-windows/ninja.exe" + Require-FileNotExists "$env:VCPKG_DOWNLOADS/tools/ninja-1.10.2-windows/ninja.exe" Remove-Item env:VCPKG_FORCE_SYSTEM_BINARIES $out = Run-VcpkgAndCaptureOutput -TestArgs ($commonArgs + @("fetch", "ninja", "--vcpkg-root=$TestingRoot", "--x-stderr-status")) diff --git a/include/vcpkg/base/jsonreader.h b/include/vcpkg/base/jsonreader.h index e4c3522ed7..e1bc62172f 100644 --- a/include/vcpkg/base/jsonreader.h +++ b/include/vcpkg/base/jsonreader.h @@ -361,4 +361,18 @@ namespace vcpkg::Json virtual Optional visit_string(Json::Reader&, StringView sv) const override; static const FeatureNameDeserializer instance; }; + + struct ArchitectureDeserializer final : Json::IDeserializer + { + virtual LocalizedString type_name() const override; + virtual Optional visit_string(Json::Reader&, StringView sv) const override; + static const ArchitectureDeserializer instance; + }; + + struct Sha512Deserializer final : Json::IDeserializer + { + virtual LocalizedString type_name() const override; + virtual Optional visit_string(Json::Reader&, StringView sv) const override; + static const Sha512Deserializer instance; + }; } diff --git a/include/vcpkg/tools.h b/include/vcpkg/tools.h index 7f3819a403..6542f324e3 100644 --- a/include/vcpkg/tools.h +++ b/include/vcpkg/tools.h @@ -62,6 +62,7 @@ namespace vcpkg std::unique_ptr get_tool_cache(const Filesystem& fs, std::shared_ptr downloader, Path downloads, + Path config_path, Path tools, RequireExactVersions abiToolVersionHandling); } diff --git a/include/vcpkg/tools.test.h b/include/vcpkg/tools.test.h index 62a47eeca1..2a2003dbc4 100644 --- a/include/vcpkg/tools.test.h +++ b/include/vcpkg/tools.test.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include @@ -30,4 +31,35 @@ namespace vcpkg }; Optional> parse_tool_version_string(StringView string_version); + + struct ArchToolData + { + std::string tool; + std::string os; + Optional arch; + std::string version; + std::string exeRelativePath; + std::string url; + std::string sha512; + std::string archiveName; + }; + + const ArchToolData* get_raw_tool_data(const std::vector& tool_data_table, + StringView toolname, + const CPUArchitecture arch, + StringView os); + + struct ToolDataDeserializer final : Json::IDeserializer + { + virtual LocalizedString type_name() const override; + + virtual Optional visit_object(Json::Reader& r, const Json::Object& obj) const override; + static const ToolDataDeserializer instance; + }; + + struct ToolDataArrayDeserializer final : Json::ArrayDeserializer + { + virtual LocalizedString type_name() const override; + static const ToolDataArrayDeserializer instance; + }; } diff --git a/src/vcpkg-test/tools.cpp b/src/vcpkg-test/tools.cpp index 055f0fcff3..ddb4a712cf 100644 --- a/src/vcpkg-test/tools.cpp +++ b/src/vcpkg-test/tools.cpp @@ -1,10 +1,31 @@ #include +#include + #include #include using namespace vcpkg; +namespace +{ + std::vector parse_tool_data_json(StringView json_contents, StringView origin) + { + auto as_json = Json::parse(json_contents, origin); + REQUIRE(as_json.has_value()); + + auto as_value = std::move(as_json).value(VCPKG_LINE_INFO).value; + REQUIRE(as_value.is_array()); + + Json::Reader r(origin); + ToolDataArrayDeserializer tool_data_deserializer; + auto maybe_tool_data = r.visit(as_value, tool_data_deserializer); + REQUIRE(maybe_tool_data.has_value()); + + return std::move(*maybe_tool_data.get()); + } +} + TEST_CASE ("parse_tool_version_string", "[tools]") { auto result = parse_tool_version_string("1.2.3"); @@ -65,3 +86,126 @@ TEST_CASE ("extract_prefixed_nonquote", "[tools]") CHECK(error_result.error() == "error: fooutil (fooutil.exe) produced unexpected output when attempting to " "determine the version:\nmalformed output"); } + +TEST_CASE ("parse_tool_data_from_json", "[tools]") +{ + const StringView tool_doc = R"([ +{ + "name": "git", + "os": "linux", + "version": "2.7.4", + "executable": "git" +}, +{ + "name": "git", + "os": "linux", + "arch": "arm64", + "version": "2.7.4", + "executable": "git-arm64" +}, +{ + "name": "nuget", + "os": "osx", + "version": "5.11.0", + "executable": "nuget.exe", + "url": "https://dist.nuget.org/win-x86-commandline/v5.11.0/nuget.exe", + "sha512": "06a337c9404dec392709834ef2cdbdce611e104b510ef40201849595d46d242151749aef65bc2d7ce5ade9ebfda83b64c03ce14c8f35ca9957a17a8c02b8c4b7" +}, +{ + "name": "node", + "os": "windows", + "version": "16.12.0", + "executable": "node-v16.12.0-win-x64\\node.exe", + "url": "https://nodejs.org/dist/v16.12.0/node-v16.12.0-win-x64.7z", + "sha512": "0bb793fce8140bd59c17f3ac9661b062eac0f611d704117774f5cb2453d717da94b1e8b17d021d47baff598dc023fb7068ed1f8a7678e446260c3db3537fa888", + "archive": "node-v16.12.0-win-x64.7z" +} +])"; + + auto data = parse_tool_data_json(tool_doc, "vcpkgTools.json"); + REQUIRE(data.size() == 4); + + auto git_linux = data[0]; + CHECK(git_linux.tool == "git"); + CHECK(git_linux.os == "linux"); + CHECK_FALSE(git_linux.arch.has_value()); + CHECK(git_linux.version == "2.7.4"); + CHECK(git_linux.exeRelativePath == "git"); + CHECK(git_linux.url == ""); + CHECK(git_linux.sha512 == ""); + + auto git_arm64 = data[1]; + CHECK(git_arm64.tool == "git"); + CHECK(git_arm64.os == "linux"); + CHECK(git_arm64.arch.has_value()); + CHECK(*git_arm64.arch.get() == CPUArchitecture::ARM64); + CHECK(git_arm64.version == "2.7.4"); + CHECK(git_arm64.exeRelativePath == "git-arm64"); + CHECK(git_arm64.url == ""); + CHECK(git_arm64.sha512 == ""); + + auto nuget_osx = data[2]; + CHECK(nuget_osx.tool == "nuget"); + CHECK(nuget_osx.os == "osx"); + CHECK_FALSE(nuget_osx.arch.has_value()); + CHECK(nuget_osx.version == "5.11.0"); + CHECK(nuget_osx.exeRelativePath == "nuget.exe"); + CHECK(nuget_osx.url == "https://dist.nuget.org/win-x86-commandline/v5.11.0/nuget.exe"); + CHECK(nuget_osx.sha512 == "06a337c9404dec392709834ef2cdbdce611e104b510ef40201849595d46d242151749aef65bc2d7ce5ade9eb" + "fda83b64c03ce14c8f35ca9957a17a8c02b8c4b7"); + + auto node_windows = data[3]; + CHECK(node_windows.tool == "node"); + CHECK(node_windows.os == "windows"); + CHECK_FALSE(node_windows.arch.has_value()); + CHECK(node_windows.version == "16.12.0"); + CHECK(node_windows.exeRelativePath == "node-v16.12.0-win-x64\\node.exe"); + CHECK(node_windows.url == "https://nodejs.org/dist/v16.12.0/node-v16.12.0-win-x64.7z"); + CHECK(node_windows.sha512 == + "0bb793fce8140bd59c17f3ac9661b062eac0f611d704117774f5cb2453d717da94b1e8b17d021d47baff598dc023" + "fb7068ed1f8a7678e446260c3db3537fa888"); + CHECK(node_windows.archiveName == "node-v16.12.0-win-x64.7z"); + + auto* tooL_git_linux = get_raw_tool_data(data, "git", CPUArchitecture::X64, "linux"); + REQUIRE(tooL_git_linux != nullptr); + CHECK(tooL_git_linux->tool == "git"); + CHECK(tooL_git_linux->os == "linux"); + CHECK_FALSE(tooL_git_linux->arch.has_value()); + CHECK(tooL_git_linux->version == "2.7.4"); + CHECK(tooL_git_linux->exeRelativePath == "git"); + CHECK(tooL_git_linux->url == ""); + CHECK(tooL_git_linux->sha512 == ""); + + auto* tooL_git_arm64 = get_raw_tool_data(data, "git", CPUArchitecture::ARM64, "linux"); + REQUIRE(tooL_git_arm64 != nullptr); + CHECK(tooL_git_arm64->tool == "git"); + CHECK(tooL_git_arm64->os == "linux"); + CHECK(tooL_git_arm64->arch.has_value()); + CHECK(*tooL_git_arm64->arch.get() == CPUArchitecture::ARM64); + CHECK(tooL_git_arm64->version == "2.7.4"); + CHECK(tooL_git_arm64->exeRelativePath == "git-arm64"); + CHECK(tooL_git_arm64->url == ""); + CHECK(tooL_git_arm64->sha512 == ""); + + auto* tooL_nuget_osx = get_raw_tool_data(data, "nuget", CPUArchitecture::X64, "osx"); + REQUIRE(tooL_nuget_osx != nullptr); + CHECK(tooL_nuget_osx->tool == "nuget"); + CHECK(tooL_nuget_osx->os == "osx"); + CHECK_FALSE(tooL_nuget_osx->arch.has_value()); + CHECK(tooL_nuget_osx->version == "5.11.0"); + CHECK(tooL_nuget_osx->exeRelativePath == "nuget.exe"); + CHECK(tooL_nuget_osx->url == "https://dist.nuget.org/win-x86-commandline/v5.11.0/nuget.exe"); + + auto* tooL_node_windows = get_raw_tool_data(data, "node", CPUArchitecture::X64, "windows"); + REQUIRE(tooL_node_windows != nullptr); + CHECK(tooL_node_windows->tool == "node"); + CHECK(tooL_node_windows->os == "windows"); + CHECK_FALSE(tooL_node_windows->arch.has_value()); + CHECK(tooL_node_windows->version == "16.12.0"); + CHECK(tooL_node_windows->exeRelativePath == "node-v16.12.0-win-x64\\node.exe"); + CHECK(tooL_node_windows->url == "https://nodejs.org/dist/v16.12.0/node-v16.12.0-win-x64.7z"); + CHECK(tooL_node_windows->sha512 == + "0bb793fce8140bd59c17f3ac9661b062eac0f611d704117774f5cb2453d717da94b1e8b17d021d47baff598dc023" + "fb7068ed1f8a7678e446260c3db3537fa888"); + CHECK(tooL_node_windows->archiveName == "node-v16.12.0-win-x64.7z"); +} diff --git a/src/vcpkg/base/json.cpp b/src/vcpkg/base/json.cpp index e65c51e65a..38b94294ff 100644 --- a/src/vcpkg/base/json.cpp +++ b/src/vcpkg/base/json.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include @@ -1569,4 +1570,58 @@ namespace vcpkg::Json } const FeatureNameDeserializer FeatureNameDeserializer::instance; + + LocalizedString ArchitectureDeserializer::type_name() const + { + // TODO: Add type name + return msg::format(msgAFeatureName); + } + + Optional ArchitectureDeserializer::visit_string(Json::Reader& r, StringView sv) const + { + static const std::vector known_architectures{ + "x86", + "x64", + "arm", + "arm64", + "arm64ec", + "s390x", + "ppc64le", + "riscv32", + "riscv64", + "loongarch32", + "loongarch64", + "mips64", + }; + + if (Util::contains(known_architectures, sv)) + { + return sv.to_string(); + } + + r.add_generic_error(type_name(), msg::format(msgInvalidArchitecture, msg::value = sv)); + return nullopt; + } + + const ArchitectureDeserializer ArchitectureDeserializer::instance; + + LocalizedString Sha512Deserializer::type_name() const + { + // TODO: Add type name + return msg::format(msgAFeatureName); + } + + Optional Sha512Deserializer::visit_string(Json::Reader&, StringView sv) const + { + if (sv.size() == 128 && std::all_of(sv.begin(), sv.end(), ParserBase::is_hex_digit)) + { + return sv.to_string(); + } + + // TODO: Add error + // r.add_generic_error(type_name(), msg::format(msgInvalidSha512Length, msg::value = sv)); + return nullopt; + } + + const Sha512Deserializer Sha512Deserializer::instance; } diff --git a/src/vcpkg/tools.cpp b/src/vcpkg/tools.cpp index 6e4015f8da..35235a6a9e 100644 --- a/src/vcpkg/tools.cpp +++ b/src/vcpkg/tools.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -12,6 +13,7 @@ #include #include #include +#include #include #include @@ -62,441 +64,96 @@ namespace vcpkg return std::array{*d1.get(), *d2.get(), *d3.get()}; } - struct ArchToolData + ExpectedL> parse_tool_data(const Filesystem& fs, Path path) { - StringLiteral tool; - StringLiteral os; - Optional arch; - StringLiteral version; - StringLiteral exeRelativePath; - StringLiteral url; - StringLiteral sha512; - StringLiteral archiveName; - }; - - static constexpr ArchToolData tool_data_table[] = { - { - "python3", - "windows", - nullopt, - "3.11.8", - "python.exe", - "https://www.python.org/ftp/python/3.11.8/python-3.11.8-embed-win32.zip", - "c88ef02f0860000dbc59361cfe051e3e8dc7d208ed39bb5bc20a3e8b8711b578926e281a11941787ea61b2ef05b945ab313332" - "2dcb85b916f79ac4ada57f6309", - "python-3.11.8-embed-win32.zip", - }, - { - "python3_with_venv", - "windows", - nullopt, - "3.11.8", - "tools/python.exe", - "https://www.nuget.org/api/v2/package/python/3.11.8", - "8c1abd622fb2795fb87ab5208764fe13f7f4d69f2283b4237ea47b7c14b0989b5b4169f1ac1d3b1f417c6c2cc3d85ce151370d" - "ae8efc807c93e57cd67fa3c8cf", - "python-3.11.8.nupkg.zip", - }, - { - "cmake", - "windows", - nullopt, - "3.29.2", - "cmake-3.29.2-windows-i386/bin/cmake.exe", - "https://github.com/Kitware/CMake/releases/download/v3.29.2/cmake-3.29.2-windows-i386.zip", - "562de7b577c99fe347b00437d14ce375a8e5a60504909cb67d2f73c372d39a2f76d2b42b69e4aeb31a4879e1bcf6f7c2d41f2a" - "ce12180ea83ba7af48879d40ab", - "cmake-3.29.2-windows-i386.zip", - }, - { - "cmake", - "osx", - nullopt, - "3.29.2", - "cmake-3.29.2-macos-universal/CMake.app/Contents/bin/cmake", - "https://github.com/Kitware/CMake/releases/download/v3.29.2/cmake-3.29.2-macos-universal.tar.gz", - "26aab0163965f3d560dfd6b1f72c5e77192338237ebe286099fd62f243f1bbd4857b9193118386b801c00dc5cfbc5bc8af8481" - "4692fcfadcf56c7d2faab52533", - "cmake-3.29.2-macos-universal.tar.gz", - }, - { - "cmake", - "linux", - CPUArchitecture::ARM64, - "3.29.2", - "cmake-3.29.2-linux-aarch64/bin/cmake", - "https://github.com/Kitware/CMake/releases/download/v3.29.2/cmake-3.29.2-linux-aarch64.tar.gz", - "206b00604caf72f3dc644c7a5ac6a335814520fbf1512b9f2d4a5e8c26025d286bd106d2925ffbc874c754c518cbdb07f16919" - "16c39fcfd1202a47f592c8e3b0", - "cmake-3.29.2-linux-aarch64.tar.gz", - }, - { - "cmake", - "linux", - nullopt, - "3.29.2", - "cmake-3.29.2-linux-x86_64/bin/cmake", - "https://github.com/Kitware/CMake/releases/download/v3.29.2/cmake-3.29.2-linux-x86_64.tar.gz", - "d88082d582f1774a3d89efbf3f31a03b08a663c359d603d87ee7c4afd862d4164d2b0b9f0b32cece8efee3acfa86b44214cd4f" - "7606b99b8334183a05d5f06edc", - "cmake-3.29.2-linux-x86_64.tar.gz", - }, - { - "git", - "windows", - nullopt, - "2.7.4", - "mingw64/bin/git.exe", - "https://github.com/git-for-windows/git/releases/download/v2.43.0.windows.1/" - "PortableGit-2.43.0-64-bit.7z.exe", - "02ec40f55a6de18f305530e9415b6ce0a597359ebb9a58cf727ac84eceb0003b0f437941b76872b6568157a333c8e6e8d865a3" - "6faf874fd5f04774deb6a9387a", - "PortableGit-2.43.0-32-bit.7z.exe", - }, - { - "git", - "linux", - nullopt, - "2.7.4", - "", - "", - "", - "", - }, - { - "git", - "osx", - nullopt, - "2.7.4", - "", - "", - "", - "", - }, - { - "git", - "freebsd", - nullopt, - "2.7.4", - "", - "", - "", - "", - }, - { - "gsutil", - "windows", - nullopt, - "4.65", - "google-cloud-sdk/bin/gsutil.cmd", - "https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/" - "google-cloud-sdk-347.0.0-windows-x86_64-bundled-python.zip", - "e2792e17b132aad77f7c0b9fd26faf415e9437923d9227a9e6d253554e6843d29a6ddad0a7fb5e9aea4a130fd4c521e6ece884" - "4fd4a4f9e8d580348775425389", - "google-cloud-sdk-347.0.0-windows-x86_64-bundled-python.zip", - }, - { - "gsutil", - "osx", - nullopt, - "4.65", - "gsutil/gsutil", - "https://storage.googleapis.com/pub/gsutil_4.65.tar.gz", - "2c5c9dea48147f97180a491bbb9e24e8cbcd4f3452620e2f80338b781e4dfc90bb754e3bbfa05e1b990e44bff52d990d8c2dd5" - "1bc83d112339d8e6096a2f21c8", - "gsutil_4.65.tar.gz", - }, - { - "gsutil", - "linux", - nullopt, - "4.65", - "gsutil/gsutil", - "https://storage.googleapis.com/pub/gsutil_4.65.tar.gz", - "2c5c9dea48147f97180a491bbb9e24e8cbcd4f3452620e2f80338b781e4dfc90bb754e3bbfa05e1b990e44bff52d990d8c2dd5" - "1bc83d112339d8e6096a2f21c8", - "gsutil_4.65.tar.gz", - }, - { - "vswhere", - "windows", - nullopt, - "3.1.7", - "vswhere.exe", - "https://github.com/microsoft/vswhere/releases/download/3.1.7/vswhere.exe", - "40c534eb27f079c15c9782f53f82c12dabfede4d3d85f0edf8a855c2b0d5e12921a96506b37c210beab3c33220f8ff098447ad" - "054e82d8c2603964975fc12076", - "", - }, - { - "nuget", - "windows", - nullopt, - "6.10.0", - "nuget.exe", - "https://dist.nuget.org/win-x86-commandline/v6.10.0/nuget.exe", - "71d7307bb89de2df3811419c561efa00618a4c68e6ce481b0bdfc94c7c6c6d126a54eb26a0015686fabf99f109744ca41fead9" - "9e97139cdc86dde16a5ec3e7cf", - "", - }, - { - "nuget", - "linux", - nullopt, - "6.10.0", - "nuget.exe", - "https://dist.nuget.org/win-x86-commandline/v6.10.0/nuget.exe", - "71d7307bb89de2df3811419c561efa00618a4c68e6ce481b0bdfc94c7c6c6d126a54eb26a0015686fabf99f109744ca41fead9" - "9e97139cdc86dde16a5ec3e7cf", - "", - }, + auto contents = fs.read_contents(path, IgnoreErrors{}); + if (contents.empty()) { - "nuget", - "osx", - nullopt, - "6.10.0", - "nuget.exe", - "https://dist.nuget.org/win-x86-commandline/v6.10.0/nuget.exe", - "71d7307bb89de2df3811419c561efa00618a4c68e6ce481b0bdfc94c7c6c6d126a54eb26a0015686fabf99f109744ca41fead9" - "9e97139cdc86dde16a5ec3e7cf", - "", - }, - { - "coscli", - "windows", - nullopt, - "0.11.0", - "coscli-windows.exe", - "https://github.com/tencentyun/coscli/releases/download/v0.11.0-beta/coscli-windows.exe", - "38a521ec80cdb6944124f4233d7e71eed8cc9f9be2c0c736269915d21c3718ea8131e4516bb6eeada6df331f5fa8f47a299907" - "e50ee9edbe0114444520974d06", - "", - }, - { - "coscli", - "linux", - nullopt, - "0.11.0", - "coscli-linux", - "https://github.com/tencentyun/coscli/releases/download/v0.11.0-beta/coscli-linux", - "9c930a1d308e9581a0e2fdfe3751ea7fe13d6068df90ca6465740ec3eda034202ef71ec54c99e90015ff81aa68aa1489567db5" - "e411e222eb7258704bdac7e924", - "", - }, - { - "coscli", - "osx", - nullopt, - "0.11.0", - "coscli-mac", - "https://github.com/tencentyun/coscli/releases/download/v0.11.0-beta/coscli-mac", - "9556335bfc8bc14bace6dfced45fa77fb07c80f08aa975e047a54efda1d19852aae0ea68a5bc7f04fbd88e3edce5a73512a612" - "16b1c5ff4cade224de4a9ab8db", - "", - }, - { - "installerbase", - "windows", - nullopt, - "4.4.0", - "QtInstallerFramework-win-x86/bin/installerbase.exe", - "https://download.qt.io/official_releases/qt-installer-framework/4.4.0/" - "installer-framework-opensource-src-4.4.0.zip", - "fc713f54bfe2781cb232cd0ae8eddb96833ec178d53a55ec0b01886aa048b13441eb49a1f33282e8eab7259cfe512c890d50b8" - "e632d3dbf501a0bf1fd83de947", - "installer-framework-opensource-src-4.4.0.zip", - }, - { - "7zip_msi", - "windows", - nullopt, - "24.08", - "Files/7-Zip/7z.exe", - "https://github.com/ip7z/7zip/releases/download/24.08/7z2408-x64.msi", - "3259bf5e251382333c9d18a3fc01d83491fb41bc4ac4ddb25a02918494594c1074482b6608189a8a89e343d78e34d57420cdef" - "f1d7ace5acfdcaacc8776f1be8", - "7z2408-x64.msi", - }, - { - "7zip", - "windows", - nullopt, - "24.08", - "7za.exe", - "https://github.com/ip7z/7zip/releases/download/24.08/7z2408-extra.7z", - "35f55236fccfb576ca014e29d0c35f4a213e53f06683bd2e82f869ed02506e230c8dd623c01d0207244d6a997031f737903456" - "b7ad4a44db1717f0a17a78602e", - "7z2408-extra.7z", - }, - { - "7zr", - "windows", - nullopt, - "24.08", - "7zr.exe", - "https://github.com/ip7z/7zip/releases/download/24.08/7zr.exe", - "424196f2acf5b89807f4038683acc50e7604223fc630245af6bab0e0df923f8b1c49cb09ac709086568c214c3f53dcb7d6c32e" - "8a54af222a3ff78cfab9c51670", - "", - }, - { - "aria2", - "windows", - nullopt, - "1.37.0", - "aria2-1.37.0-win-64bit-build1/aria2c.exe", - "https://github.com/aria2/aria2/releases/download/release-1.37.0/aria2-1.37.0-win-64bit-build1.zip", - "6d78405da9cf5639dbe8174787002161b8124d73880fb57cc8c0a3a63982f84e46df4e626990c58f23452965ad925f0d37cb91" - "47e99b25c3d7ca0ea49602f34d", - "aria2-1.37.0-win-64bit-build1.zip", - }, - { - "aria2", - "osx", - nullopt, - "1.35.0", - "aria2-1.35.0/bin/aria2c", - "https://github.com/aria2/aria2/releases/download/release-1.35.0/aria2-1.35.0-osx-darwin.tar.bz2", - "3bb32b7d55347d1af37c6f4ebf0e20b38ce51c37a1baf92f7ad1762000539a03413dd679a6d902fdb1805fa71917300c9692ac" - "eee012eb06ecdff10491137aec", - "aria2-1.35.0-osx-darwin.tar.bz2", - }, - { - "ninja", - "windows", - nullopt, - "1.11.1", - "ninja.exe", - "https://github.com/ninja-build/ninja/releases/download/v1.11.1/ninja-win.zip", - "a700e794c32eb67b9f87040db7f1ba3a8e891636696fc54d416b01661c2421ff46fa517c97fd904adacdf8e621df3e68ea3801" - "05b909ae8b6651a78ae7eb3199", - "ninja-win-1.11.1.zip", - }, - { - "ninja", - "linux", - nullopt, - "1.11.1", - "ninja", - "https://github.com/ninja-build/ninja/releases/download/v1.11.1/ninja-linux.zip", - "6403dac9196baffcff614fa73ea530752997c8db6bbfbaa0446b4b09d7327e2aa6e8615d1283c961d3bf0df497e85ba8660414" - "9f1505ee75f89d600245a45dde", - "ninja-linux-1.11.1.zip", - }, - { - "ninja", - "osx", - nullopt, - "1.11.1", - "ninja", - "https://github.com/ninja-build/ninja/releases/download/v1.11.1/ninja-mac.zip", - "dad33b0918c60bbf5107951a936175b1610b4894a408f4ba4b47a2f5b328fc982a52a2aed6a0cb75028ee4765af5083bea6661" - "1c37516826eb0c851366bb4427", - "ninja-mac-1.11.1.zip", - }, + // TODO: Add an error message + return msg::format_error(LocalizedString::from_raw("")); + } + + auto as_json = Json::parse(contents, path); + if (!as_json) { - "powershell-core", - "windows", - nullopt, - "7.2.23", - "pwsh.exe", - "https://github.com/PowerShell/PowerShell/releases/download/v7.2.23/PowerShell-7.2.23-win-x64.zip", - "b374a878df02980d54e17ad7cfc9021e331748c3770f586be61356c257494d1b33899c1167d09a35c210bc084474aefdff972f" - "672d16afb43be0562b3589285a", - "PowerShell-7.2.23-win-x64.zip", - }, + // TODO: Add an error message + return msg::format_error(LocalizedString::from_raw("")); + } + + auto as_value = std::move(as_json).value(VCPKG_LINE_INFO).value; + if (!as_value.is_array()) { - "node", - "windows", - nullopt, - "16.15.1", - "node-v16.15.1-win-x64/node.exe", - "https://nodejs.org/dist/v16.15.1/node-v16.15.1-win-x64.7z", - "7ec4bfe2ea6034e1461e306b6372d62c0c5d1060c453ba76a73a5cec38ac26b5952a744caa9071455329caa58eb0a96d26c688" - "54c8915c17610ff27b0cf2c1cf", - "node-v16.15.1-win-x64.7z", - }, + // TODO: Add an error message + return msg::format_error(LocalizedString::from_raw("")); + } + + Json::Reader r(path); + auto maybe_tool_data = r.visit(as_value, ToolDataArrayDeserializer::instance); + + if (!r.errors().empty()) { - "node", - "linux", - nullopt, - "16.15.1", - "node-v16.15.1-linux-x64/bin/node", - "https://nodejs.org/dist/v16.15.1/node-v16.15.1-linux-x64.tar.gz", - "5ad3b4b9caeaa8d31503efa99f5a593118a267dec9d4181d019732126ba248ce9a901207115b3f6b899eb5b3f0373c7f77ea95" - "cc92ac625cddf437ee9b8b8919", - "node-v16.15.1-linux-x64.tar.gz", - }, + // TODO: Extract error messages + for (auto&& e : r.errors()) + { + msg::println_error(e); + } + return msg::format_error(LocalizedString::from_raw("error parsing tools json file")); + } + + if (auto tool_data = maybe_tool_data.get()) { - "node", - "osx", - nullopt, - "16.15.1", - "node-v16.15.1-darwin-x64/bin/node", - "https://nodejs.org/dist/v16.15.1/node-v16.15.1-darwin-x64.tar.gz", - "90d0612bbe5467b6cf385c91a68b8daad0057e3e0ccacea44567f5b95b14f7481cb79784185ab1463b4bd990e092ff0f910957" - "6d1a1934b84e1c816582929611", - "node-v16.15.1-darwin-x64.tar.gz", - }, - }; + return *tool_data; + } + + // TODO: Add an error message + return msg::format_error(LocalizedString::from_raw("")); + } - static const ArchToolData* get_raw_tool_data(StringView toolname, CPUArchitecture arch, StringView os) + const ArchToolData* get_raw_tool_data(const std::vector& tool_data_table, + StringView toolname, + const CPUArchitecture arch, + StringView os) { const ArchToolData* default_tool = nullptr; - for (auto&& d : tool_data_table) + for (auto&& tool_candidate : tool_data_table) { - if (d.tool == toolname && d.os == os) + if (tool_candidate.tool == toolname && tool_candidate.os == os) { - // if the tool data record declares an architecture matching the one we're looking for, that's an exact - // match and we've found the right one - if (auto d_arch = d.arch.get()) + if (!tool_candidate.arch) { - if (*d_arch == arch) + if (!default_tool) { - return &d; + default_tool = &tool_candidate; } } - else + else if (arch == *tool_candidate.arch.get()) { - // if the tool data record does not declare an architecture, we merely record a 'default tool' in - // case a more specific entry naming an architecture is seen - if (default_tool) - { - Checks::unreachable(VCPKG_LINE_INFO, - "there should be only one tool entry with an undeclared architecture"); - } - - default_tool = &d; + return &tool_candidate; } } } - - if (default_tool) - { - return default_tool; - } - - return nullptr; + return default_tool; } - static Optional get_tool_data(StringView tool) + static Optional get_tool_data(const std::vector& tool_data_table, StringView tool) { auto hp = get_host_processor(); #if defined(_WIN32) - auto data = get_raw_tool_data(tool, hp, "windows"); + auto data = get_raw_tool_data(tool_data_table, tool, hp, "windows"); #elif defined(__APPLE__) - auto data = get_raw_tool_data(tool, hp, "osx"); + auto data = get_raw_tool_data(tool_data_table, tool, hp, "osx"); #elif defined(__linux__) - auto data = get_raw_tool_data(tool, hp, "linux"); + auto data = get_raw_tool_data(tool_data_table, tool, hp, "linux"); #elif defined(__FreeBSD__) - auto data = get_raw_tool_data(tool, hp, "freebsd"); + auto data = get_raw_tool_data(tool_data_table, tool, hp, "freebsd"); #elif defined(__OpenBSD__) - auto data = get_raw_tool_data(tool, hp, "openbsd"); + auto data = get_raw_tool_data(tool_data_table, tool, hp, "openbsd"); #else return nullopt; #endif if (!data) { + // Make get_raw_tool_data return ExpectedL and handle error here? return nullopt; } const Optional> version = parse_tool_version_string(data->version); @@ -520,11 +177,11 @@ namespace vcpkg return ToolData{tool.to_string(), *version.get(), data->exeRelativePath, - data->url.to_string(), + data->url, download_subpath, !data->archiveName.empty(), tool_dir_name, - data->sha512.to_string()}; + data->sha512}; } struct PathAndVersion @@ -1044,19 +701,23 @@ namespace vcpkg const Filesystem& fs; const std::shared_ptr downloader; const Path downloads; + const Path config_path; const Path tools; const RequireExactVersions abiToolVersionHandling; vcpkg::Cache path_version_cache; + vcpkg::Lazy> m_tool_data_cache; ToolCacheImpl(const Filesystem& fs, const std::shared_ptr& downloader, Path downloads, + Path config_path, Path tools, RequireExactVersions abiToolVersionHandling) : fs(fs) , downloader(downloader) , downloads(std::move(downloads)) + , config_path(std::move(config_path)) , tools(std::move(tools)) , abiToolVersionHandling(abiToolVersionHandling) { @@ -1150,7 +811,7 @@ namespace vcpkg get_environment_variable(EnvironmentVariableVcpkgForceSystemBinaries).has_value(); const bool env_force_download_binaries = get_environment_variable(EnvironmentVariableVcpkgForceDownloadedBinaries).has_value(); - const auto maybe_tool_data = get_tool_data(tool.tool_data_name()); + const auto maybe_tool_data = get_tool_data(load_tool_data(), tool.tool_data_name()); const bool download_available = maybe_tool_data.has_value() && !maybe_tool_data.get()->url.empty(); // search for system searchable tools unless forcing downloads and download available const auto system_exe_stems = tool.system_exe_stems(); @@ -1168,7 +829,7 @@ namespace vcpkg if (auto tool_data = maybe_tool_data.get()) { - // If there is an entry for the tool in tools.cpp, use that version as the minimum + // If there is an entry for the tool in vcpkg-tools.json, use that version as the minimum min_version = tool_data->version; if (consider_downloads) @@ -1309,6 +970,18 @@ namespace vcpkg { return get_tool_pathversion(tool, status_sink).version; } + + std::vector load_tool_data() const + { + return m_tool_data_cache.get_lazy([&]() { + auto maybe_tool_data = parse_tool_data(fs, config_path); + if (auto tool_data = maybe_tool_data.get()) + { + return std::move(*tool_data); + } + Checks::msg_exit_with_error(VCPKG_LINE_INFO, maybe_tool_data.error()); + }); + } }; ExpectedL find_system_tar(const ReadOnlyFilesystem& fs) @@ -1381,9 +1054,64 @@ namespace vcpkg std::unique_ptr get_tool_cache(const Filesystem& fs, std::shared_ptr downloader, Path downloads, + Path config_path, Path tools, RequireExactVersions abiToolVersionHandling) { - return std::make_unique(fs, std::move(downloader), downloads, tools, abiToolVersionHandling); + return std::make_unique( + fs, std::move(downloader), downloads, config_path, tools, abiToolVersionHandling); + } + + LocalizedString ToolDataDeserializer::type_name() const { return msg::format(msgAConfigurationObject); } + + Optional ToolDataDeserializer::visit_object(Json::Reader& r, const Json::Object& obj) const + { + static const std::map arch_map{ + {"x86", CPUArchitecture::X86}, + {"x64", CPUArchitecture::X64}, + {"arm", CPUArchitecture::ARM}, + {"arm64", CPUArchitecture::ARM64}, + {"arm64ec", CPUArchitecture::ARM64EC}, + {"s390x", CPUArchitecture::S390X}, + {"ppc64le", CPUArchitecture::PPC64LE}, + {"riscv32", CPUArchitecture::RISCV32}, + {"riscv64", CPUArchitecture::RISCV64}, + {"loongarch32", CPUArchitecture::LOONGARCH32}, + {"loongarch64", CPUArchitecture::LOONGARCH64}, + {"mips64", CPUArchitecture::MIPS64}, + }; + + ArchToolData value; + + r.required_object_field(type_name(), obj, "name", value.tool, Json::UntypedStringDeserializer::instance); + r.required_object_field(type_name(), obj, "os", value.os, Json::UntypedStringDeserializer::instance); + r.required_object_field(type_name(), obj, "version", value.version, Json::UntypedStringDeserializer::instance); + + std::string arch_str; + if (r.optional_object_field(obj, "arch", arch_str, Json::ArchitectureDeserializer::instance)) + { + auto it = arch_map.find(arch_str); + if (it != arch_map.end()) + { + value.arch = it->second; + } + else + { + // TODO: Add an error message + // r.add_generic_error(type_name(), msg::format(msgInvalidArch, msg::arch = arch_str)); + } + } + r.optional_object_field(obj, "executable", value.exeRelativePath, Json::UntypedStringDeserializer::instance); + r.optional_object_field(obj, "url", value.url, Json::UntypedStringDeserializer::instance); + r.optional_object_field(obj, "sha512", value.sha512, Json::Sha512Deserializer::instance); + r.optional_object_field(obj, "archive", value.archiveName, Json::UntypedStringDeserializer::instance); + + // arch string needs to be converted to CPUArchitecture + return value; } -} + + const ToolDataDeserializer ToolDataDeserializer::instance; + + LocalizedString ToolDataArrayDeserializer::type_name() const { return ToolDataDeserializer::instance.type_name(); } + const ToolDataArrayDeserializer ToolDataArrayDeserializer::instance; +} \ No newline at end of file diff --git a/src/vcpkg/vcpkgpaths.cpp b/src/vcpkg/vcpkgpaths.cpp index 781fd615c9..114f2088e8 100644 --- a/src/vcpkg/vcpkgpaths.cpp +++ b/src/vcpkg/vcpkgpaths.cpp @@ -553,6 +553,7 @@ namespace vcpkg , m_tool_cache(get_tool_cache(fs, m_download_manager, downloads, + scripts / "vcpkg-tools.json", tools, args.exact_abi_tools_versions.value_or(false) ? RequireExactVersions::YES : RequireExactVersions::NO)) From 80cc2ab13754205410838001aaec45462554984c Mon Sep 17 00:00:00 2001 From: Victor Romero Date: Fri, 13 Dec 2024 02:25:20 -0800 Subject: [PATCH 15/30] Add deserializer types and errors --- include/vcpkg/base/message-data.inc.h | 7 +++++++ src/vcpkg/base/json.cpp | 22 ++++++++-------------- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/include/vcpkg/base/message-data.inc.h b/include/vcpkg/base/message-data.inc.h index 04f9935066..2fbbadffa3 100644 --- a/include/vcpkg/base/message-data.inc.h +++ b/include/vcpkg/base/message-data.inc.h @@ -4,6 +4,7 @@ DECLARE_MESSAGE(ADefaultFeature, (), "", "a default feature") DECLARE_MESSAGE(ABoolean, (), "", "a boolean") DECLARE_MESSAGE(ABuiltinRegistry, (), "", "a builtin registry") DECLARE_MESSAGE(AConfigurationObject, (), "", "a configuration object") +DECLARE_MESSAGE(ACpuArchitecture, (), "", "a CPU architecture") DECLARE_MESSAGE(ADependency, (), "", "a dependency") DECLARE_MESSAGE(ADependencyFeature, (), "", "a feature of a dependency") DECLARE_MESSAGE(ADemandObject, @@ -11,6 +12,7 @@ DECLARE_MESSAGE(ADemandObject, "'demands' are a concept in the schema of a JSON file the user can edit", "a demand object") DECLARE_MESSAGE(AString, (), "", "a string") +DECLARE_MESSAGE(ASha512, (), "", "a SHA512 hex string") DECLARE_MESSAGE(ADateVersionString, (), "", "a date version string") DECLARE_MESSAGE(AddArtifactOnlyOne, (msg::command_line), "", "'{command_line}' can only add one artifact at a time.") DECLARE_MESSAGE(AddCommandFirstArg, (), "", "The first parameter to add must be 'artifact' or 'port'.") @@ -1798,6 +1800,10 @@ DECLARE_MESSAGE(InvalidArchitecture, (msg::value), "{value} is what the user entered that we did not understand", "invalid architecture: {value}") +DECLARE_MESSAGE(InvalidArchitectureValue, + (msg::value, msg::expected), + "{value} is what the user entered that we did not understand", + "Invalid architecture: {value}. Expected one of: {expected}.") DECLARE_MESSAGE(InvalidArgument, (), "", "invalid argument") DECLARE_MESSAGE( InvalidArgumentRequiresAbsolutePath, @@ -1920,6 +1926,7 @@ DECLARE_MESSAGE(InvalidOptionForRemove, "'remove' is a command that should not be changed.", "'remove' accepts either libraries or '--outdated'") DECLARE_MESSAGE(InvalidPortVersonName, (msg::path), "", "Found invalid port version file name: `{path}`.") +DECLARE_MESSAGE(InvalidSha512, (msg::sha), "", "Invalid SHA512: {sha}") DECLARE_MESSAGE(InvalidSharpInVersion, (), "", "invalid character '#' in version text") DECLARE_MESSAGE(InvalidSharpInVersionDidYouMean, (msg::value), diff --git a/src/vcpkg/base/json.cpp b/src/vcpkg/base/json.cpp index 38b94294ff..2c1cf21484 100644 --- a/src/vcpkg/base/json.cpp +++ b/src/vcpkg/base/json.cpp @@ -1571,11 +1571,7 @@ namespace vcpkg::Json const FeatureNameDeserializer FeatureNameDeserializer::instance; - LocalizedString ArchitectureDeserializer::type_name() const - { - // TODO: Add type name - return msg::format(msgAFeatureName); - } + LocalizedString ArchitectureDeserializer::type_name() const { return msg::format(msgACpuArchitecture); } Optional ArchitectureDeserializer::visit_string(Json::Reader& r, StringView sv) const { @@ -1599,27 +1595,25 @@ namespace vcpkg::Json return sv.to_string(); } - r.add_generic_error(type_name(), msg::format(msgInvalidArchitecture, msg::value = sv)); + r.add_generic_error(type_name(), + msg::format(msgInvalidArchitectureValue, + msg::value = sv, + msg::expected = Strings::join(",", known_architectures))); return nullopt; } const ArchitectureDeserializer ArchitectureDeserializer::instance; - LocalizedString Sha512Deserializer::type_name() const - { - // TODO: Add type name - return msg::format(msgAFeatureName); - } + LocalizedString Sha512Deserializer::type_name() const { return msg::format(msgASha512); } - Optional Sha512Deserializer::visit_string(Json::Reader&, StringView sv) const + Optional Sha512Deserializer::visit_string(Json::Reader& r, StringView sv) const { if (sv.size() == 128 && std::all_of(sv.begin(), sv.end(), ParserBase::is_hex_digit)) { return sv.to_string(); } - // TODO: Add error - // r.add_generic_error(type_name(), msg::format(msgInvalidSha512Length, msg::value = sv)); + r.add_generic_error(type_name(), msg::format(msgInvalidSha512, msg::sha = sv)); return nullopt; } From 3b33ef6d3f42222b5beca6376937a2cc3794d3c9 Mon Sep 17 00:00:00 2001 From: Victor Romero Date: Fri, 13 Dec 2024 13:26:48 -0800 Subject: [PATCH 16/30] more error messages --- include/vcpkg/base/jsonreader.h | 2 + include/vcpkg/base/message-data.inc.h | 6 +++ include/vcpkg/tools.test.h | 2 + src/vcpkg-test/tools.cpp | 26 +++---------- src/vcpkg/base/json.cpp | 34 ++++++++--------- src/vcpkg/tools.cpp | 54 ++++++++++++--------------- 6 files changed, 56 insertions(+), 68 deletions(-) diff --git a/include/vcpkg/base/jsonreader.h b/include/vcpkg/base/jsonreader.h index e1bc62172f..874de86890 100644 --- a/include/vcpkg/base/jsonreader.h +++ b/include/vcpkg/base/jsonreader.h @@ -364,6 +364,8 @@ namespace vcpkg::Json struct ArchitectureDeserializer final : Json::IDeserializer { + static const std::vector KNOWN_ARCHITECTURES; + virtual LocalizedString type_name() const override; virtual Optional visit_string(Json::Reader&, StringView sv) const override; static const ArchitectureDeserializer instance; diff --git a/include/vcpkg/base/message-data.inc.h b/include/vcpkg/base/message-data.inc.h index 2fbbadffa3..8c59951cc6 100644 --- a/include/vcpkg/base/message-data.inc.h +++ b/include/vcpkg/base/message-data.inc.h @@ -261,6 +261,7 @@ DECLARE_MESSAGE(ASemanticVersionString, (), "", "a semantic version string") DECLARE_MESSAGE(ASetOfFeatures, (), "", "a set of features") DECLARE_MESSAGE(AStringOrArrayOfStrings, (), "", "a string or array of strings") DECLARE_MESSAGE(AStringStringDictionary, (), "", "a \"string\": \"string\" dictionary") +DECLARE_MESSAGE(AToolDataObject, (), "", "an executable tool's metadata") DECLARE_MESSAGE(AttemptingToSetBuiltInBaseline, (), "", @@ -1145,6 +1146,10 @@ DECLARE_MESSAGE(ErrorWhileFetchingBaseline, "{value} is a commit sha.", "while fetching baseline `\"{value}\"` from repo {package_name}:") DECLARE_MESSAGE(ErrorWhileParsing, (msg::path), "", "Errors occurred while parsing {path}.") +DECLARE_MESSAGE(ErrorWhileParsingToolData, + (msg::path), + "", + "An unexpected error ocurred while parsing tool data from {path}.") DECLARE_MESSAGE(ErrorWhileWriting, (msg::path), "", "Error occurred while writing {path}.") DECLARE_MESSAGE(ExamplesHeader, (), "Printed before a list of example command lines", "Examples:") DECLARE_MESSAGE(ExceededRecursionDepth, (), "", "Recursion depth exceeded.") @@ -1262,6 +1267,7 @@ DECLARE_MESSAGE(FailedToParseBaseline, (msg::path), "", "Failed to parse baselin DECLARE_MESSAGE(FailedToParseConfig, (msg::path), "", "Failed to parse configuration: {path}") DECLARE_MESSAGE(FailedToParseVersionFile, (msg::path), "", "Failed to parse version file: {path}") DECLARE_MESSAGE(FailedToParseNoTopLevelObj, (msg::path), "", "Failed to parse {path}, expected a top-level object.") +DECLARE_MESSAGE(FailedToParseTopLevelArray, (msg::path), "", "Failed to parse {path}, expected a top-level array.") DECLARE_MESSAGE(FailedToParseNoVersionsArray, (msg::path), "", "Failed to parse {path}, expected a 'versions' array.") DECLARE_MESSAGE(FailedToParseSerializedBinParagraph, (msg::error_msg), diff --git a/include/vcpkg/tools.test.h b/include/vcpkg/tools.test.h index 2a2003dbc4..c0fa0f077c 100644 --- a/include/vcpkg/tools.test.h +++ b/include/vcpkg/tools.test.h @@ -44,6 +44,8 @@ namespace vcpkg std::string archiveName; }; + ExpectedL> parse_tool_data(StringView contents, StringView origin); + const ArchToolData* get_raw_tool_data(const std::vector& tool_data_table, StringView toolname, const CPUArchitecture arch, diff --git a/src/vcpkg-test/tools.cpp b/src/vcpkg-test/tools.cpp index ddb4a712cf..85fd26cb0c 100644 --- a/src/vcpkg-test/tools.cpp +++ b/src/vcpkg-test/tools.cpp @@ -7,25 +7,6 @@ using namespace vcpkg; -namespace -{ - std::vector parse_tool_data_json(StringView json_contents, StringView origin) - { - auto as_json = Json::parse(json_contents, origin); - REQUIRE(as_json.has_value()); - - auto as_value = std::move(as_json).value(VCPKG_LINE_INFO).value; - REQUIRE(as_value.is_array()); - - Json::Reader r(origin); - ToolDataArrayDeserializer tool_data_deserializer; - auto maybe_tool_data = r.visit(as_value, tool_data_deserializer); - REQUIRE(maybe_tool_data.has_value()); - - return std::move(*maybe_tool_data.get()); - } -} - TEST_CASE ("parse_tool_version_string", "[tools]") { auto result = parse_tool_version_string("1.2.3"); @@ -87,7 +68,7 @@ TEST_CASE ("extract_prefixed_nonquote", "[tools]") "determine the version:\nmalformed output"); } -TEST_CASE ("parse_tool_data_from_json", "[tools]") +TEST_CASE ("parse_tool_data", "[tools]") { const StringView tool_doc = R"([ { @@ -122,7 +103,10 @@ TEST_CASE ("parse_tool_data_from_json", "[tools]") } ])"; - auto data = parse_tool_data_json(tool_doc, "vcpkgTools.json"); + auto maybe_data = parse_tool_data(tool_doc, "vcpkgTools.json"); + REQUIRE(maybe_data.has_value()); + + auto data = maybe_data.value_or_exit(VCPKG_LINE_INFO); REQUIRE(data.size() == 4); auto git_linux = data[0]; diff --git a/src/vcpkg/base/json.cpp b/src/vcpkg/base/json.cpp index 2c1cf21484..8a18b774dd 100644 --- a/src/vcpkg/base/json.cpp +++ b/src/vcpkg/base/json.cpp @@ -1571,26 +1571,26 @@ namespace vcpkg::Json const FeatureNameDeserializer FeatureNameDeserializer::instance; + const std::vector ArchitectureDeserializer::KNOWN_ARCHITECTURES = { + "x86", + "x64", + "arm", + "arm64", + "arm64ec", + "s390x", + "ppc64le", + "riscv32", + "riscv64", + "loongarch32", + "loongarch64", + "mips64", + }; + LocalizedString ArchitectureDeserializer::type_name() const { return msg::format(msgACpuArchitecture); } Optional ArchitectureDeserializer::visit_string(Json::Reader& r, StringView sv) const { - static const std::vector known_architectures{ - "x86", - "x64", - "arm", - "arm64", - "arm64ec", - "s390x", - "ppc64le", - "riscv32", - "riscv64", - "loongarch32", - "loongarch64", - "mips64", - }; - - if (Util::contains(known_architectures, sv)) + if (Util::contains(KNOWN_ARCHITECTURES, sv)) { return sv.to_string(); } @@ -1598,7 +1598,7 @@ namespace vcpkg::Json r.add_generic_error(type_name(), msg::format(msgInvalidArchitectureValue, msg::value = sv, - msg::expected = Strings::join(",", known_architectures))); + msg::expected = Strings::join(",", KNOWN_ARCHITECTURES))); return nullopt; } diff --git a/src/vcpkg/tools.cpp b/src/vcpkg/tools.cpp index 35235a6a9e..86a88dc486 100644 --- a/src/vcpkg/tools.cpp +++ b/src/vcpkg/tools.cpp @@ -64,40 +64,25 @@ namespace vcpkg return std::array{*d1.get(), *d2.get(), *d3.get()}; } - ExpectedL> parse_tool_data(const Filesystem& fs, Path path) + ExpectedL> parse_tool_data(StringView contents, StringView origin) { - auto contents = fs.read_contents(path, IgnoreErrors{}); - if (contents.empty()) - { - // TODO: Add an error message - return msg::format_error(LocalizedString::from_raw("")); - } - - auto as_json = Json::parse(contents, path); + auto as_json = Json::parse(contents, origin); if (!as_json) { - // TODO: Add an error message - return msg::format_error(LocalizedString::from_raw("")); + return as_json.error(); } auto as_value = std::move(as_json).value(VCPKG_LINE_INFO).value; if (!as_value.is_array()) { - // TODO: Add an error message - return msg::format_error(LocalizedString::from_raw("")); + return msg::format_error(msgFailedToParseTopLevelArray, msg::path = origin); } - Json::Reader r(path); + Json::Reader r(origin); auto maybe_tool_data = r.visit(as_value, ToolDataArrayDeserializer::instance); - - if (!r.errors().empty()) + if (!r.errors().empty() || !r.warnings().empty()) { - // TODO: Extract error messages - for (auto&& e : r.errors()) - { - msg::println_error(e); - } - return msg::format_error(LocalizedString::from_raw("error parsing tools json file")); + return r.join(); } if (auto tool_data = maybe_tool_data.get()) @@ -105,8 +90,19 @@ namespace vcpkg return *tool_data; } - // TODO: Add an error message - return msg::format_error(LocalizedString::from_raw("")); + return msg::format_error(msgErrorWhileParsingToolData, msg::path = origin); + } + + static ExpectedL> parse_tool_data_file(const Filesystem& fs, Path path) + { + std::error_code ec; + auto contents = fs.read_contents(path, ec); + if (ec) + { + return format_filesystem_call_error(ec, __func__, {path}); + } + + return parse_tool_data(contents, path); } const ArchToolData* get_raw_tool_data(const std::vector& tool_data_table, @@ -974,7 +970,7 @@ namespace vcpkg std::vector load_tool_data() const { return m_tool_data_cache.get_lazy([&]() { - auto maybe_tool_data = parse_tool_data(fs, config_path); + auto maybe_tool_data = parse_tool_data_file(fs, config_path); if (auto tool_data = maybe_tool_data.get()) { return std::move(*tool_data); @@ -1062,7 +1058,7 @@ namespace vcpkg fs, std::move(downloader), downloads, config_path, tools, abiToolVersionHandling); } - LocalizedString ToolDataDeserializer::type_name() const { return msg::format(msgAConfigurationObject); } + LocalizedString ToolDataDeserializer::type_name() const { return msg::format(msgAToolDataObject); } Optional ToolDataDeserializer::visit_object(Json::Reader& r, const Json::Object& obj) const { @@ -1097,16 +1093,14 @@ namespace vcpkg } else { - // TODO: Add an error message - // r.add_generic_error(type_name(), msg::format(msgInvalidArch, msg::arch = arch_str)); + // ArchitectureDeserializer ensures that one of the valid architectures is set + Checks::unreachable(VCPKG_LINE_INFO); } } r.optional_object_field(obj, "executable", value.exeRelativePath, Json::UntypedStringDeserializer::instance); r.optional_object_field(obj, "url", value.url, Json::UntypedStringDeserializer::instance); r.optional_object_field(obj, "sha512", value.sha512, Json::Sha512Deserializer::instance); r.optional_object_field(obj, "archive", value.archiveName, Json::UntypedStringDeserializer::instance); - - // arch string needs to be converted to CPUArchitecture return value; } From b7075b8a8f10d762eb1faf306fbb4cdd90fedf36 Mon Sep 17 00:00:00 2001 From: Victor Romero Date: Sat, 14 Dec 2024 12:39:04 -0800 Subject: [PATCH 17/30] Add parser unit tests --- include/vcpkg/base/message-data.inc.h | 15 ++++--- include/vcpkg/tools.test.h | 6 +++ src/vcpkg-test/tools.cpp | 57 +++++++++++++++++++++++++++ src/vcpkg/tools.cpp | 38 ++++++++++++------ 4 files changed, 99 insertions(+), 17 deletions(-) diff --git a/include/vcpkg/base/message-data.inc.h b/include/vcpkg/base/message-data.inc.h index 8c59951cc6..9316d5e104 100644 --- a/include/vcpkg/base/message-data.inc.h +++ b/include/vcpkg/base/message-data.inc.h @@ -12,7 +12,7 @@ DECLARE_MESSAGE(ADemandObject, "'demands' are a concept in the schema of a JSON file the user can edit", "a demand object") DECLARE_MESSAGE(AString, (), "", "a string") -DECLARE_MESSAGE(ASha512, (), "", "a SHA512 hex string") +DECLARE_MESSAGE(ASha512, (), "", "a SHA-512 hash") DECLARE_MESSAGE(ADateVersionString, (), "", "a date version string") DECLARE_MESSAGE(AddArtifactOnlyOne, (msg::command_line), "", "'{command_line}' can only add one artifact at a time.") DECLARE_MESSAGE(AddCommandFirstArg, (), "", "The first parameter to add must be 'artifact' or 'port'.") @@ -261,7 +261,8 @@ DECLARE_MESSAGE(ASemanticVersionString, (), "", "a semantic version string") DECLARE_MESSAGE(ASetOfFeatures, (), "", "a set of features") DECLARE_MESSAGE(AStringOrArrayOfStrings, (), "", "a string or array of strings") DECLARE_MESSAGE(AStringStringDictionary, (), "", "a \"string\": \"string\" dictionary") -DECLARE_MESSAGE(AToolDataObject, (), "", "an executable tool's metadata") +DECLARE_MESSAGE(AToolDataObject, (), "", "tool metadata") +DECLARE_MESSAGE(AToolDataArray, (), "", "an array of tool metadata") DECLARE_MESSAGE(AttemptingToSetBuiltInBaseline, (), "", @@ -1267,7 +1268,7 @@ DECLARE_MESSAGE(FailedToParseBaseline, (msg::path), "", "Failed to parse baselin DECLARE_MESSAGE(FailedToParseConfig, (msg::path), "", "Failed to parse configuration: {path}") DECLARE_MESSAGE(FailedToParseVersionFile, (msg::path), "", "Failed to parse version file: {path}") DECLARE_MESSAGE(FailedToParseNoTopLevelObj, (msg::path), "", "Failed to parse {path}, expected a top-level object.") -DECLARE_MESSAGE(FailedToParseTopLevelArray, (msg::path), "", "Failed to parse {path}, expected a top-level array.") +DECLARE_MESSAGE(FailedToParseTopLevelArray, (), "", "Expected a top-level array.") DECLARE_MESSAGE(FailedToParseNoVersionsArray, (msg::path), "", "Failed to parse {path}, expected a 'versions' array.") DECLARE_MESSAGE(FailedToParseSerializedBinParagraph, (msg::error_msg), @@ -1809,7 +1810,7 @@ DECLARE_MESSAGE(InvalidArchitecture, DECLARE_MESSAGE(InvalidArchitectureValue, (msg::value, msg::expected), "{value} is what the user entered that we did not understand", - "Invalid architecture: {value}. Expected one of: {expected}.") + "Invalid architecture: {value}. Expected one of: {expected}") DECLARE_MESSAGE(InvalidArgument, (), "", "invalid argument") DECLARE_MESSAGE( InvalidArgumentRequiresAbsolutePath, @@ -1932,7 +1933,11 @@ DECLARE_MESSAGE(InvalidOptionForRemove, "'remove' is a command that should not be changed.", "'remove' accepts either libraries or '--outdated'") DECLARE_MESSAGE(InvalidPortVersonName, (msg::path), "", "Found invalid port version file name: `{path}`.") -DECLARE_MESSAGE(InvalidSha512, (msg::sha), "", "Invalid SHA512: {sha}") +DECLARE_MESSAGE(InvalidSha512, + (msg::sha), + "", + "invalid SHA-512 hash: {sha}\n" + "SHA-512 hash must be 128 characters long and contain only hexadecimal digits") DECLARE_MESSAGE(InvalidSharpInVersion, (), "", "invalid character '#' in version text") DECLARE_MESSAGE(InvalidSharpInVersionDidYouMean, (msg::value), diff --git a/include/vcpkg/tools.test.h b/include/vcpkg/tools.test.h index c0fa0f077c..6bf54ff9dd 100644 --- a/include/vcpkg/tools.test.h +++ b/include/vcpkg/tools.test.h @@ -55,13 +55,19 @@ namespace vcpkg { virtual LocalizedString type_name() const override; + virtual View valid_fields() const override; + virtual Optional visit_object(Json::Reader& r, const Json::Object& obj) const override; + static const ToolDataDeserializer instance; }; struct ToolDataArrayDeserializer final : Json::ArrayDeserializer { virtual LocalizedString type_name() const override; + + virtual Optional> visit_object(Json::Reader& r, const Json::Object&) const override; + static const ToolDataArrayDeserializer instance; }; } diff --git a/src/vcpkg-test/tools.cpp b/src/vcpkg-test/tools.cpp index 85fd26cb0c..8a10155929 100644 --- a/src/vcpkg-test/tools.cpp +++ b/src/vcpkg-test/tools.cpp @@ -193,3 +193,60 @@ TEST_CASE ("parse_tool_data", "[tools]") "fb7068ed1f8a7678e446260c3db3537fa888"); CHECK(tooL_node_windows->archiveName == "node-v16.12.0-win-x64.7z"); } + +TEST_CASE ("parse_tool_data failuress", "[tools]") +{ + auto empty = parse_tool_data("", "empty.json"); + REQUIRE(!empty.has_value()); + CHECK(Strings::starts_with(empty.error(), "empty.json:1:1: error: Unexpected EOF")); + + auto top_level_object_json = parse_tool_data("{}", "top-level-object.json"); + REQUIRE(!top_level_object_json.has_value()); + CHECK("top-level-object.json: error: $ (an array of tool metadata): Expected a top-level array." == + top_level_object_json.error()); + + auto missing_required = parse_tool_data(R"([{ "executable": "git.exe" }])", "missing_required.json"); + REQUIRE(!missing_required.has_value()); + CHECK("missing_required.json: error: $[0] (tool metadata): missing required field 'name' (a string)\n" + "missing_required.json: error: $[0] (tool metadata): missing required field 'os' (a string)\n" + "missing_required.json: error: $[0] (tool metadata): missing required field 'version' (a string)" == + missing_required.error()); + + auto uexpected_field = parse_tool_data(R"([{ +"name": "git", +"os": "linux", +"version": "2.7.4", +"arc": "x64" +}])", + "uexpected_field.json"); + REQUIRE(!uexpected_field.has_value()); + CHECK("uexpected_field.json: error: $[0] (tool metadata): unexpected field 'arc', did you mean 'arch'?" == + uexpected_field.error()); + + auto invalid_arch = parse_tool_data(R"([{ +"name": "git", +"os": "linux", +"version": "2.7.4", +"arch": "notanarchitecture" +}])", + "invalid_arch.json"); + REQUIRE(!invalid_arch.has_value()); + CHECK("invalid_arch.json: error: $[0].arch (a CPU architecture): Invalid architecture: notanarchitecture. Expected " + "one of: x86,x64,arm,arm64,arm64ec,s390x,ppc64le,riscv32,riscv64,loongarch32,loongarch64,mips64\n" + "invalid_arch.json: error: $[0].arch: mismatched type: expected a CPU architecture" == invalid_arch.error()); + + auto invalid_sha512 = parse_tool_data(R"([{ +"name": "git", +"os": "linux", +"version": "2.7.4", +"executable": "git", +"sha512": "notasha512" +}])", + "invalid_sha512.json"); + + REQUIRE(!invalid_sha512.has_value()); + CHECK("invalid_sha512.json: error: $[0].sha512 (a SHA-512 hash): invalid SHA-512 hash: notasha512\n" + "SHA-512 hash must be 128 characters long and contain only hexadecimal digits\n" + "invalid_sha512.json: error: $[0].sha512: mismatched type: expected a SHA-512 hash" == + invalid_sha512.error()); +} diff --git a/src/vcpkg/tools.cpp b/src/vcpkg/tools.cpp index 86a88dc486..597f4d6406 100644 --- a/src/vcpkg/tools.cpp +++ b/src/vcpkg/tools.cpp @@ -71,12 +71,7 @@ namespace vcpkg { return as_json.error(); } - auto as_value = std::move(as_json).value(VCPKG_LINE_INFO).value; - if (!as_value.is_array()) - { - return msg::format_error(msgFailedToParseTopLevelArray, msg::path = origin); - } Json::Reader r(origin); auto maybe_tool_data = r.visit(as_value, ToolDataArrayDeserializer::instance); @@ -1060,6 +1055,21 @@ namespace vcpkg LocalizedString ToolDataDeserializer::type_name() const { return msg::format(msgAToolDataObject); } + View ToolDataDeserializer::valid_fields() const + { + static const StringView valid_fields[] = { + "name", + "os", + "version", + "arch", + "executable", + "url", + "sha512", + "archive", + }; + return valid_fields; + } + Optional ToolDataDeserializer::visit_object(Json::Reader& r, const Json::Object& obj) const { static const std::map arch_map{ @@ -1091,11 +1101,6 @@ namespace vcpkg { value.arch = it->second; } - else - { - // ArchitectureDeserializer ensures that one of the valid architectures is set - Checks::unreachable(VCPKG_LINE_INFO); - } } r.optional_object_field(obj, "executable", value.exeRelativePath, Json::UntypedStringDeserializer::instance); r.optional_object_field(obj, "url", value.url, Json::UntypedStringDeserializer::instance); @@ -1106,6 +1111,15 @@ namespace vcpkg const ToolDataDeserializer ToolDataDeserializer::instance; - LocalizedString ToolDataArrayDeserializer::type_name() const { return ToolDataDeserializer::instance.type_name(); } + LocalizedString ToolDataArrayDeserializer::type_name() const { return msg::format(msgAToolDataArray); } + + Optional> ToolDataArrayDeserializer::visit_object(Json::Reader& r, + const Json::Object&) const + { + // Maybe the base class should override all non-array visitor methods and add error messages + r.add_generic_error(type_name(), msg::format(msgFailedToParseTopLevelArray)); + return nullopt; + } + const ToolDataArrayDeserializer ToolDataArrayDeserializer::instance; -} \ No newline at end of file +} From d1cf8fb39812bcb95558e0c24c680307fc3e9a25 Mon Sep 17 00:00:00 2001 From: Victor Romero Date: Sun, 15 Dec 2024 01:25:34 -0800 Subject: [PATCH 18/30] Add schema-version --- .../end-to-end-tests-dir/fetch.ps1 | 127 ++++++------- include/vcpkg/base/message-data.inc.h | 5 + include/vcpkg/tools.test.h | 28 +-- src/vcpkg-test/tools.cpp | 148 ++++++++------- src/vcpkg/tools.cpp | 171 +++++++++++------- 5 files changed, 264 insertions(+), 215 deletions(-) diff --git a/azure-pipelines/end-to-end-tests-dir/fetch.ps1 b/azure-pipelines/end-to-end-tests-dir/fetch.ps1 index cd83a52c54..960c8510dc 100644 --- a/azure-pipelines/end-to-end-tests-dir/fetch.ps1 +++ b/azure-pipelines/end-to-end-tests-dir/fetch.ps1 @@ -10,69 +10,72 @@ if (-not $IsMacOS -and -not $IsLinux) { $ninja_version = "1.10.2" @' -[{ - "name": "7zip", - "os": "windows", - "version": "19.00", - "executable": "Files\\7-Zip\\7z.exe", - "url": "https://www.7-zip.org/a/7z1900-x64.msi", - "sha512": "7837a8677a01eed9c3309923f7084bc864063ba214ee169882c5b04a7a8b198ed052c15e981860d9d7952c98f459a4fab87a72fd78e7d0303004dcb86f4324c8", - "archive": "7z1900-x64.msi" -}, { - "name": "ninja-testing", - "os": "windows", - "version": "1.10.2", - "executable": "ninja.exe", - "url": "https://github.com/ninja-build/ninja/releases/download/v1.10.2/ninja-win.zip", - "sha512": "6004140d92e86afbb17b49c49037ccd0786ce238f340f7d0e62b4b0c29ed0d6ad0bab11feda2094ae849c387d70d63504393714ed0a1f4d3a1f155af7a4f1ba3", - "archive": "ninja-win-1.10.2.zip" -}, -{ - "name": "ninja", - "os": "windows", - "version": "1.10.2", - "executable": "ninja.exe", - "url": "https://github.com/ninja-build/ninja/releases/download/v1.10.2/ninja-win.zip", - "sha512": "6004140d92e86afbb17b49c49037ccd0786ce238f340f7d0e62b4b0c29ed0d6ad0bab11feda2094ae849c387d70d63504393714ed0a1f4d3a1f155af7a4f1ba3", - "archive": "ninja-win-1.10.2.zip" -}, -{ - "name": "cmake", - "os": "windows", - "version": "3.22.2", - "executable": "cmake-3.22.2-windows-i386\\bin\\cmake.exe", - "url": "https://github.com/Kitware/CMake/releases/download/v3.22.2/cmake-3.22.2-windows-i386.zip", - "sha512": "969d3d58d56d8fa3cc3acae2b949bf58abab945f70ae292ff20c9060d845dfc094c613c367a924abff47f307cc33af1467cdb9b75bb857868e38b2c7cdc72f79", - "archive": "cmake-3.22.2-windows-i386.zip" -}, -{ - "name": "cmake", - "os": "osx", - "version": "3.22.2", - "executable": "cmake-3.22.2-macos-universal/CMake.app/Contents/bin/cmake", - "url": "https://github.com/Kitware/CMake/releases/download/v3.22.2/cmake-3.22.2-macos-universal.tar.gz", - "sha512": "08104f608ecb9a5cfef38e79f0957d21e425616c0677781445492f82cbfec805113e3b5eb4bc737b707bb26a00678e7bd55e17555a5611c08b0b9b44ac5136ac", - "archive": "cmake-3.22.2-macos-universal.tar.gz" -}, -{ - "name": "cmake", - "os": "linux", - "version": "3.22.2", - "executable": "cmake-3.22.2-linux-x86_64/bin/cmake", - "url": "https://github.com/Kitware/CMake/releases/download/v3.22.2/cmake-3.22.2-linux-x86_64.tar.gz", - "sha512": "579e08b086f6903ef063697fca1dc2692f68a7341dd35998990b772b4221cdb5b1deecfa73bad9d46817ef09e58882b2adff9d64f959c01002c11448a878746b", - "archive": "cmake-3.22.2linux-x86_64.tar.gz" -}, -{ - "name": "cmake", - "os": "freebsd", - "version": "3.20.4", - "executable": "/usr/local/bin/cmake", - "url": "https://pkg.freebsd.org/FreeBSD:13:amd64/quarterly/All/cmake-3.20.4.txz", - "sha512": "3e5b675d7ff924f92996d912e2365582e687375109ef99c9073fb8196bb329243a406b218cf1358d7cc518988b311ce9e5bf87de4d64f2e6377b7c2bc8894475", - "archive": "cmake-3.20.4.txz" -}] + "schema-version": 1, + "tools": [{ + "name": "7zip", + "os": "windows", + "version": "19.00", + "executable": "Files\\7-Zip\\7z.exe", + "url": "https://www.7-zip.org/a/7z1900-x64.msi", + "sha512": "7837a8677a01eed9c3309923f7084bc864063ba214ee169882c5b04a7a8b198ed052c15e981860d9d7952c98f459a4fab87a72fd78e7d0303004dcb86f4324c8", + "archive": "7z1900-x64.msi" + }, + { + "name": "ninja-testing", + "os": "windows", + "version": "1.10.2", + "executable": "ninja.exe", + "url": "https://github.com/ninja-build/ninja/releases/download/v1.10.2/ninja-win.zip", + "sha512": "6004140d92e86afbb17b49c49037ccd0786ce238f340f7d0e62b4b0c29ed0d6ad0bab11feda2094ae849c387d70d63504393714ed0a1f4d3a1f155af7a4f1ba3", + "archive": "ninja-win-1.10.2.zip" + }, + { + "name": "ninja", + "os": "windows", + "version": "1.10.2", + "executable": "ninja.exe", + "url": "https://github.com/ninja-build/ninja/releases/download/v1.10.2/ninja-win.zip", + "sha512": "6004140d92e86afbb17b49c49037ccd0786ce238f340f7d0e62b4b0c29ed0d6ad0bab11feda2094ae849c387d70d63504393714ed0a1f4d3a1f155af7a4f1ba3", + "archive": "ninja-win-1.10.2.zip" + }, + { + "name": "cmake", + "os": "windows", + "version": "3.22.2", + "executable": "cmake-3.22.2-windows-i386\\bin\\cmake.exe", + "url": "https://github.com/Kitware/CMake/releases/download/v3.22.2/cmake-3.22.2-windows-i386.zip", + "sha512": "969d3d58d56d8fa3cc3acae2b949bf58abab945f70ae292ff20c9060d845dfc094c613c367a924abff47f307cc33af1467cdb9b75bb857868e38b2c7cdc72f79", + "archive": "cmake-3.22.2-windows-i386.zip" + }, + { + "name": "cmake", + "os": "osx", + "version": "3.22.2", + "executable": "cmake-3.22.2-macos-universal/CMake.app/Contents/bin/cmake", + "url": "https://github.com/Kitware/CMake/releases/download/v3.22.2/cmake-3.22.2-macos-universal.tar.gz", + "sha512": "08104f608ecb9a5cfef38e79f0957d21e425616c0677781445492f82cbfec805113e3b5eb4bc737b707bb26a00678e7bd55e17555a5611c08b0b9b44ac5136ac", + "archive": "cmake-3.22.2-macos-universal.tar.gz" + }, + { + "name": "cmake", + "os": "linux", + "version": "3.22.2", + "executable": "cmake-3.22.2-linux-x86_64/bin/cmake", + "url": "https://github.com/Kitware/CMake/releases/download/v3.22.2/cmake-3.22.2-linux-x86_64.tar.gz", + "sha512": "579e08b086f6903ef063697fca1dc2692f68a7341dd35998990b772b4221cdb5b1deecfa73bad9d46817ef09e58882b2adff9d64f959c01002c11448a878746b", + "archive": "cmake-3.22.2linux-x86_64.tar.gz" + }, + { + "name": "cmake", + "os": "freebsd", + "version": "3.20.4", + "executable": "/usr/local/bin/cmake", + "url": "https://pkg.freebsd.org/FreeBSD:13:amd64/quarterly/All/cmake-3.20.4.txz", + "sha512": "3e5b675d7ff924f92996d912e2365582e687375109ef99c9073fb8196bb329243a406b218cf1358d7cc518988b311ce9e5bf87de4d64f2e6377b7c2bc8894475", + "archive": "cmake-3.20.4.txz" + }] +} '@ | % { $_ -replace "`r","" } | Out-File -enc ascii $(Join-Path $Scripts "vcpkg-tools.json") $env:VCPKG_DOWNLOADS = Join-Path $TestingRoot 'down loads' diff --git a/include/vcpkg/base/message-data.inc.h b/include/vcpkg/base/message-data.inc.h index 9316d5e104..43d55a14d6 100644 --- a/include/vcpkg/base/message-data.inc.h +++ b/include/vcpkg/base/message-data.inc.h @@ -263,6 +263,11 @@ DECLARE_MESSAGE(AStringOrArrayOfStrings, (), "", "a string or array of strings") DECLARE_MESSAGE(AStringStringDictionary, (), "", "a \"string\": \"string\" dictionary") DECLARE_MESSAGE(AToolDataObject, (), "", "tool metadata") DECLARE_MESSAGE(AToolDataArray, (), "", "an array of tool metadata") +DECLARE_MESSAGE(AToolDataFile, (), "", "a tool data file") +DECLARE_MESSAGE(ToolDataFileSchemaVersionNotSupported, + (msg::version), + "", + "document schema version {version} is not supported by this version of vcpkg") DECLARE_MESSAGE(AttemptingToSetBuiltInBaseline, (), "", diff --git a/include/vcpkg/tools.test.h b/include/vcpkg/tools.test.h index 6bf54ff9dd..2dce77deab 100644 --- a/include/vcpkg/tools.test.h +++ b/include/vcpkg/tools.test.h @@ -32,7 +32,7 @@ namespace vcpkg Optional> parse_tool_version_string(StringView string_version); - struct ArchToolData + struct ToolDataEntry { std::string tool; std::string os; @@ -44,30 +44,22 @@ namespace vcpkg std::string archiveName; }; - ExpectedL> parse_tool_data(StringView contents, StringView origin); + ExpectedL> parse_tool_data(StringView contents, StringView origin); - const ArchToolData* get_raw_tool_data(const std::vector& tool_data_table, - StringView toolname, - const CPUArchitecture arch, - StringView os); + const ToolDataEntry* get_raw_tool_data(const std::vector& tool_data_table, + StringView toolname, + const CPUArchitecture arch, + StringView os); - struct ToolDataDeserializer final : Json::IDeserializer + struct ToolDataFileDeserializer final : Json::IDeserializer> { virtual LocalizedString type_name() const override; virtual View valid_fields() const override; - virtual Optional visit_object(Json::Reader& r, const Json::Object& obj) const override; + virtual Optional> visit_object(Json::Reader& r, + const Json::Object& obj) const override; - static const ToolDataDeserializer instance; - }; - - struct ToolDataArrayDeserializer final : Json::ArrayDeserializer - { - virtual LocalizedString type_name() const override; - - virtual Optional> visit_object(Json::Reader& r, const Json::Object&) const override; - - static const ToolDataArrayDeserializer instance; + static const ToolDataFileDeserializer instance; }; } diff --git a/src/vcpkg-test/tools.cpp b/src/vcpkg-test/tools.cpp index 8a10155929..2956c129f4 100644 --- a/src/vcpkg-test/tools.cpp +++ b/src/vcpkg-test/tools.cpp @@ -70,38 +70,42 @@ TEST_CASE ("extract_prefixed_nonquote", "[tools]") TEST_CASE ("parse_tool_data", "[tools]") { - const StringView tool_doc = R"([ + const StringView tool_doc = R"( { - "name": "git", - "os": "linux", - "version": "2.7.4", - "executable": "git" -}, -{ - "name": "git", - "os": "linux", - "arch": "arm64", - "version": "2.7.4", - "executable": "git-arm64" -}, -{ - "name": "nuget", - "os": "osx", - "version": "5.11.0", - "executable": "nuget.exe", - "url": "https://dist.nuget.org/win-x86-commandline/v5.11.0/nuget.exe", - "sha512": "06a337c9404dec392709834ef2cdbdce611e104b510ef40201849595d46d242151749aef65bc2d7ce5ade9ebfda83b64c03ce14c8f35ca9957a17a8c02b8c4b7" -}, -{ - "name": "node", - "os": "windows", - "version": "16.12.0", - "executable": "node-v16.12.0-win-x64\\node.exe", - "url": "https://nodejs.org/dist/v16.12.0/node-v16.12.0-win-x64.7z", - "sha512": "0bb793fce8140bd59c17f3ac9661b062eac0f611d704117774f5cb2453d717da94b1e8b17d021d47baff598dc023fb7068ed1f8a7678e446260c3db3537fa888", - "archive": "node-v16.12.0-win-x64.7z" -} -])"; + "schema-version": 1, + "tools": [ + { + "name": "git", + "os": "linux", + "version": "2.7.4", + "executable": "git" + }, + { + "name": "git", + "os": "linux", + "arch": "arm64", + "version": "2.7.4", + "executable": "git-arm64" + }, + { + "name": "nuget", + "os": "osx", + "version": "5.11.0", + "executable": "nuget.exe", + "url": "https://dist.nuget.org/win-x86-commandline/v5.11.0/nuget.exe", + "sha512": "06a337c9404dec392709834ef2cdbdce611e104b510ef40201849595d46d242151749aef65bc2d7ce5ade9ebfda83b64c03ce14c8f35ca9957a17a8c02b8c4b7" + }, + { + "name": "node", + "os": "windows", + "version": "16.12.0", + "executable": "node-v16.12.0-win-x64\\node.exe", + "url": "https://nodejs.org/dist/v16.12.0/node-v16.12.0-win-x64.7z", + "sha512": "0bb793fce8140bd59c17f3ac9661b062eac0f611d704117774f5cb2453d717da94b1e8b17d021d47baff598dc023fb7068ed1f8a7678e446260c3db3537fa888", + "archive": "node-v16.12.0-win-x64.7z" + } + ] +})"; auto maybe_data = parse_tool_data(tool_doc, "vcpkgTools.json"); REQUIRE(maybe_data.has_value()); @@ -194,59 +198,73 @@ TEST_CASE ("parse_tool_data", "[tools]") CHECK(tooL_node_windows->archiveName == "node-v16.12.0-win-x64.7z"); } -TEST_CASE ("parse_tool_data failuress", "[tools]") +TEST_CASE ("parse_tool_data errors", "[tools]") { auto empty = parse_tool_data("", "empty.json"); REQUIRE(!empty.has_value()); CHECK(Strings::starts_with(empty.error(), "empty.json:1:1: error: Unexpected EOF")); - auto top_level_object_json = parse_tool_data("{}", "top-level-object.json"); - REQUIRE(!top_level_object_json.has_value()); - CHECK("top-level-object.json: error: $ (an array of tool metadata): Expected a top-level array." == - top_level_object_json.error()); + auto top_level_json = parse_tool_data("[]", "top_level.json"); + REQUIRE(!top_level_json.has_value()); + CHECK("An unexpected error ocurred while parsing tool data from top_level.json." == top_level_json.error()); - auto missing_required = parse_tool_data(R"([{ "executable": "git.exe" }])", "missing_required.json"); + auto missing_required = + parse_tool_data(R"({ "schema-version": 1, "tools": [{ "executable": "git.exe" }]})", "missing_required.json"); REQUIRE(!missing_required.has_value()); - CHECK("missing_required.json: error: $[0] (tool metadata): missing required field 'name' (a string)\n" - "missing_required.json: error: $[0] (tool metadata): missing required field 'os' (a string)\n" - "missing_required.json: error: $[0] (tool metadata): missing required field 'version' (a string)" == + CHECK("missing_required.json: error: $.tools[0] (tool metadata): missing required field 'name' (a string)\n" + "missing_required.json: error: $.tools[0] (tool metadata): missing required field 'os' (a string)\n" + "missing_required.json: error: $.tools[0] (tool metadata): missing required field 'version' (a string)" == missing_required.error()); - auto uexpected_field = parse_tool_data(R"([{ -"name": "git", -"os": "linux", -"version": "2.7.4", -"arc": "x64" -}])", + auto uexpected_field = parse_tool_data(R"( +{ + "schema-version": 1, + "tools": [{ + "name": "git", + "os": "linux", + "version": "2.7.4", + "arc": "x64" + }] +})", "uexpected_field.json"); REQUIRE(!uexpected_field.has_value()); - CHECK("uexpected_field.json: error: $[0] (tool metadata): unexpected field 'arc', did you mean 'arch'?" == + CHECK("uexpected_field.json: error: $.tools[0] (tool metadata): unexpected field 'arc', did you mean 'arch'?" == uexpected_field.error()); - auto invalid_arch = parse_tool_data(R"([{ -"name": "git", -"os": "linux", -"version": "2.7.4", -"arch": "notanarchitecture" -}])", + auto invalid_arch = parse_tool_data(R"( +{ + "schema-version": 1, + "tools": [{ + "name": "git", + "os": "linux", + "version": "2.7.4", + "arch": "notanarchitecture" + }] +})", "invalid_arch.json"); REQUIRE(!invalid_arch.has_value()); - CHECK("invalid_arch.json: error: $[0].arch (a CPU architecture): Invalid architecture: notanarchitecture. Expected " + CHECK("invalid_arch.json: error: $.tools[0].arch (a CPU architecture): Invalid architecture: notanarchitecture. " + "Expected " "one of: x86,x64,arm,arm64,arm64ec,s390x,ppc64le,riscv32,riscv64,loongarch32,loongarch64,mips64\n" - "invalid_arch.json: error: $[0].arch: mismatched type: expected a CPU architecture" == invalid_arch.error()); - - auto invalid_sha512 = parse_tool_data(R"([{ -"name": "git", -"os": "linux", -"version": "2.7.4", -"executable": "git", -"sha512": "notasha512" -}])", + "invalid_arch.json: error: $.tools[0].arch: mismatched type: expected a CPU architecture" == + invalid_arch.error()); + + auto invalid_sha512 = parse_tool_data(R"( +{ + "schema-version": 1, + "tools": [{ + "name": "git", + "os": "linux", + "version": "2.7.4", + "executable": "git", + "sha512": "notasha512" + }] +})", "invalid_sha512.json"); REQUIRE(!invalid_sha512.has_value()); - CHECK("invalid_sha512.json: error: $[0].sha512 (a SHA-512 hash): invalid SHA-512 hash: notasha512\n" + CHECK("invalid_sha512.json: error: $.tools[0].sha512 (a SHA-512 hash): invalid SHA-512 hash: notasha512\n" "SHA-512 hash must be 128 characters long and contain only hexadecimal digits\n" - "invalid_sha512.json: error: $[0].sha512: mismatched type: expected a SHA-512 hash" == + "invalid_sha512.json: error: $.tools[0].sha512: mismatched type: expected a SHA-512 hash" == invalid_sha512.error()); } diff --git a/src/vcpkg/tools.cpp b/src/vcpkg/tools.cpp index 597f4d6406..21f3bded0c 100644 --- a/src/vcpkg/tools.cpp +++ b/src/vcpkg/tools.cpp @@ -64,7 +64,7 @@ namespace vcpkg return std::array{*d1.get(), *d2.get(), *d3.get()}; } - ExpectedL> parse_tool_data(StringView contents, StringView origin) + ExpectedL> parse_tool_data(StringView contents, StringView origin) { auto as_json = Json::parse(contents, origin); if (!as_json) @@ -74,7 +74,7 @@ namespace vcpkg auto as_value = std::move(as_json).value(VCPKG_LINE_INFO).value; Json::Reader r(origin); - auto maybe_tool_data = r.visit(as_value, ToolDataArrayDeserializer::instance); + auto maybe_tool_data = r.visit(as_value, ToolDataFileDeserializer::instance); if (!r.errors().empty() || !r.warnings().empty()) { return r.join(); @@ -85,10 +85,10 @@ namespace vcpkg return *tool_data; } - return msg::format_error(msgErrorWhileParsingToolData, msg::path = origin); + return msg::format(msgErrorWhileParsingToolData, msg::path = origin); } - static ExpectedL> parse_tool_data_file(const Filesystem& fs, Path path) + static ExpectedL> parse_tool_data_file(const Filesystem& fs, Path path) { std::error_code ec; auto contents = fs.read_contents(path, ec); @@ -100,12 +100,12 @@ namespace vcpkg return parse_tool_data(contents, path); } - const ArchToolData* get_raw_tool_data(const std::vector& tool_data_table, - StringView toolname, - const CPUArchitecture arch, - StringView os) + const ToolDataEntry* get_raw_tool_data(const std::vector& tool_data_table, + StringView toolname, + const CPUArchitecture arch, + StringView os) { - const ArchToolData* default_tool = nullptr; + const ToolDataEntry* default_tool = nullptr; for (auto&& tool_candidate : tool_data_table) { if (tool_candidate.tool == toolname && tool_candidate.os == os) @@ -126,7 +126,7 @@ namespace vcpkg return default_tool; } - static Optional get_tool_data(const std::vector& tool_data_table, StringView tool) + static Optional get_tool_data(const std::vector& tool_data_table, StringView tool) { auto hp = get_host_processor(); #if defined(_WIN32) @@ -697,7 +697,7 @@ namespace vcpkg const RequireExactVersions abiToolVersionHandling; vcpkg::Cache path_version_cache; - vcpkg::Lazy> m_tool_data_cache; + vcpkg::Lazy> m_tool_data_cache; ToolCacheImpl(const Filesystem& fs, const std::shared_ptr& downloader, @@ -962,7 +962,7 @@ namespace vcpkg return get_tool_pathversion(tool, status_sink).version; } - std::vector load_tool_data() const + std::vector load_tool_data() const { return m_tool_data_cache.get_lazy([&]() { auto maybe_tool_data = parse_tool_data_file(fs, config_path); @@ -1053,73 +1053,104 @@ namespace vcpkg fs, std::move(downloader), downloads, config_path, tools, abiToolVersionHandling); } - LocalizedString ToolDataDeserializer::type_name() const { return msg::format(msgAToolDataObject); } - - View ToolDataDeserializer::valid_fields() const + struct ToolDataEntryDeserializer final : Json::IDeserializer { - static const StringView valid_fields[] = { - "name", - "os", - "version", - "arch", - "executable", - "url", - "sha512", - "archive", - }; - return valid_fields; - } + virtual LocalizedString type_name() const override { return msg::format(msgAToolDataObject); } - Optional ToolDataDeserializer::visit_object(Json::Reader& r, const Json::Object& obj) const - { - static const std::map arch_map{ - {"x86", CPUArchitecture::X86}, - {"x64", CPUArchitecture::X64}, - {"arm", CPUArchitecture::ARM}, - {"arm64", CPUArchitecture::ARM64}, - {"arm64ec", CPUArchitecture::ARM64EC}, - {"s390x", CPUArchitecture::S390X}, - {"ppc64le", CPUArchitecture::PPC64LE}, - {"riscv32", CPUArchitecture::RISCV32}, - {"riscv64", CPUArchitecture::RISCV64}, - {"loongarch32", CPUArchitecture::LOONGARCH32}, - {"loongarch64", CPUArchitecture::LOONGARCH64}, - {"mips64", CPUArchitecture::MIPS64}, - }; - - ArchToolData value; - - r.required_object_field(type_name(), obj, "name", value.tool, Json::UntypedStringDeserializer::instance); - r.required_object_field(type_name(), obj, "os", value.os, Json::UntypedStringDeserializer::instance); - r.required_object_field(type_name(), obj, "version", value.version, Json::UntypedStringDeserializer::instance); - - std::string arch_str; - if (r.optional_object_field(obj, "arch", arch_str, Json::ArchitectureDeserializer::instance)) + virtual View valid_fields() const override { - auto it = arch_map.find(arch_str); - if (it != arch_map.end()) + static const StringView valid_fields[] = { + "name", + "os", + "version", + "arch", + "executable", + "url", + "sha512", + "archive", + }; + return valid_fields; + } + + virtual Optional visit_object(Json::Reader& r, const Json::Object& obj) const override + { + static const std::map arch_map{ + {"x86", CPUArchitecture::X86}, + {"x64", CPUArchitecture::X64}, + {"arm", CPUArchitecture::ARM}, + {"arm64", CPUArchitecture::ARM64}, + {"arm64ec", CPUArchitecture::ARM64EC}, + {"s390x", CPUArchitecture::S390X}, + {"ppc64le", CPUArchitecture::PPC64LE}, + {"riscv32", CPUArchitecture::RISCV32}, + {"riscv64", CPUArchitecture::RISCV64}, + {"loongarch32", CPUArchitecture::LOONGARCH32}, + {"loongarch64", CPUArchitecture::LOONGARCH64}, + {"mips64", CPUArchitecture::MIPS64}, + }; + + ToolDataEntry value; + + r.required_object_field(type_name(), obj, "name", value.tool, Json::UntypedStringDeserializer::instance); + r.required_object_field(type_name(), obj, "os", value.os, Json::UntypedStringDeserializer::instance); + r.required_object_field( + type_name(), obj, "version", value.version, Json::UntypedStringDeserializer::instance); + + std::string arch_str; + if (r.optional_object_field(obj, "arch", arch_str, Json::ArchitectureDeserializer::instance)) { - value.arch = it->second; + auto it = arch_map.find(arch_str); + if (it != arch_map.end()) + { + value.arch = it->second; + } } + r.optional_object_field( + obj, "executable", value.exeRelativePath, Json::UntypedStringDeserializer::instance); + r.optional_object_field(obj, "url", value.url, Json::UntypedStringDeserializer::instance); + r.optional_object_field(obj, "sha512", value.sha512, Json::Sha512Deserializer::instance); + r.optional_object_field(obj, "archive", value.archiveName, Json::UntypedStringDeserializer::instance); + return value; } - r.optional_object_field(obj, "executable", value.exeRelativePath, Json::UntypedStringDeserializer::instance); - r.optional_object_field(obj, "url", value.url, Json::UntypedStringDeserializer::instance); - r.optional_object_field(obj, "sha512", value.sha512, Json::Sha512Deserializer::instance); - r.optional_object_field(obj, "archive", value.archiveName, Json::UntypedStringDeserializer::instance); - return value; - } - const ToolDataDeserializer ToolDataDeserializer::instance; + static const ToolDataEntryDeserializer instance; + }; + const ToolDataEntryDeserializer ToolDataEntryDeserializer::instance; - LocalizedString ToolDataArrayDeserializer::type_name() const { return msg::format(msgAToolDataArray); } + struct ToolDataArrayDeserializer final : Json::ArrayDeserializer + { + virtual LocalizedString type_name() const override { return msg::format(msgAToolDataArray); } - Optional> ToolDataArrayDeserializer::visit_object(Json::Reader& r, - const Json::Object&) const + static const ToolDataArrayDeserializer instance; + }; + const ToolDataArrayDeserializer ToolDataArrayDeserializer::instance; + + LocalizedString ToolDataFileDeserializer::type_name() const { return msg::format(msgAToolDataArray); } + + View ToolDataFileDeserializer::valid_fields() const { - // Maybe the base class should override all non-array visitor methods and add error messages - r.add_generic_error(type_name(), msg::format(msgFailedToParseTopLevelArray)); - return nullopt; + static const StringView valid_fields[] = {"schema-version", "tools"}; + return valid_fields; } - const ToolDataArrayDeserializer ToolDataArrayDeserializer::instance; -} + Optional> ToolDataFileDeserializer::visit_object(Json::Reader& r, + const Json::Object& obj) const + { + int schema_version = -1; + r.required_object_field( + type_name(), obj, "schema-version", schema_version, Json::NaturalNumberDeserializer::instance); + + if (schema_version != 1) + { + r.add_generic_error(type_name(), + msg::format(msgToolDataFileSchemaVersionNotSupported, msg::version = schema_version)); + return nullopt; + } + + std::vector value; + r.required_object_field(type_name(), obj, "tools", value, ToolDataArrayDeserializer::instance); + return value; + } + + const ToolDataFileDeserializer ToolDataFileDeserializer::instance; +} \ No newline at end of file From 61a8b34ec0064856bc762f4d3afdd3c6e3d5bd92 Mon Sep 17 00:00:00 2001 From: Victor Romero Date: Mon, 16 Dec 2024 16:59:25 -0800 Subject: [PATCH 19/30] Update vcpkg-scripts-sha.txt --- src/vcpkg/tools.cpp | 3 +-- vcpkg-init/vcpkg-scripts-sha.txt | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/vcpkg/tools.cpp b/src/vcpkg/tools.cpp index 21f3bded0c..acdcefd0ee 100644 --- a/src/vcpkg/tools.cpp +++ b/src/vcpkg/tools.cpp @@ -13,7 +13,6 @@ #include #include #include -#include #include #include @@ -1153,4 +1152,4 @@ namespace vcpkg } const ToolDataFileDeserializer ToolDataFileDeserializer::instance; -} \ No newline at end of file +} diff --git a/vcpkg-init/vcpkg-scripts-sha.txt b/vcpkg-init/vcpkg-scripts-sha.txt index 361a817e67..496778ddb6 100644 --- a/vcpkg-init/vcpkg-scripts-sha.txt +++ b/vcpkg-init/vcpkg-scripts-sha.txt @@ -1 +1 @@ -b2a47d316de1f3625ea43a7ca3e42dd28c52ece7 +72254a16c21047ed5617ca98a89283e9c93f9b03 From 47205375027fc9a72a3e233d9ec24f55e6ef1990 Mon Sep 17 00:00:00 2001 From: Victor Romero Date: Tue, 17 Dec 2024 01:27:50 -0800 Subject: [PATCH 20/30] Fix message error --- include/vcpkg/base/message-data.inc.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/include/vcpkg/base/message-data.inc.h b/include/vcpkg/base/message-data.inc.h index 43d55a14d6..b4c63f0c35 100644 --- a/include/vcpkg/base/message-data.inc.h +++ b/include/vcpkg/base/message-data.inc.h @@ -1812,10 +1812,11 @@ DECLARE_MESSAGE(InvalidArchitecture, (msg::value), "{value} is what the user entered that we did not understand", "invalid architecture: {value}") -DECLARE_MESSAGE(InvalidArchitectureValue, - (msg::value, msg::expected), - "{value} is what the user entered that we did not understand", - "Invalid architecture: {value}. Expected one of: {expected}") +DECLARE_MESSAGE( + InvalidArchitectureValue, + (msg::value, msg::expected), + "{value} is an unknown CPU architecture type, {expected} is the list of accepted CPU architecture values", + "Invalid architecture: {value}. Expected one of: {expected}") DECLARE_MESSAGE(InvalidArgument, (), "", "invalid argument") DECLARE_MESSAGE( InvalidArgumentRequiresAbsolutePath, From 20ad083af170d219f250ad304a01b682b4332fff Mon Sep 17 00:00:00 2001 From: Victor Romero Date: Tue, 17 Dec 2024 09:50:55 -0800 Subject: [PATCH 21/30] Fix format errors --- include/vcpkg/base/message-data.inc.h | 1 - src/vcpkg/tools.cpp | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/include/vcpkg/base/message-data.inc.h b/include/vcpkg/base/message-data.inc.h index 39cfcd0509..1b3211a2ce 100644 --- a/include/vcpkg/base/message-data.inc.h +++ b/include/vcpkg/base/message-data.inc.h @@ -1302,7 +1302,6 @@ DECLARE_MESSAGE(FailedToParseBaseline, (msg::path), "", "Failed to parse baselin DECLARE_MESSAGE(FailedToParseConfig, (msg::path), "", "Failed to parse configuration: {path}") DECLARE_MESSAGE(FailedToParseVersionFile, (msg::path), "", "Failed to parse version file: {path}") DECLARE_MESSAGE(FailedToParseNoTopLevelObj, (msg::path), "", "Failed to parse {path}, expected a top-level object.") -DECLARE_MESSAGE(FailedToParseTopLevelArray, (), "", "Expected a top-level array.") DECLARE_MESSAGE(FailedToParseNoVersionsArray, (msg::path), "", "Failed to parse {path}, expected a 'versions' array.") DECLARE_MESSAGE(FailedToParseSerializedBinParagraph, (msg::error_msg), diff --git a/src/vcpkg/tools.cpp b/src/vcpkg/tools.cpp index acdcefd0ee..22c515ef28 100644 --- a/src/vcpkg/tools.cpp +++ b/src/vcpkg/tools.cpp @@ -143,7 +143,6 @@ namespace vcpkg #endif if (!data) { - // Make get_raw_tool_data return ExpectedL and handle error here? return nullopt; } const Optional> version = parse_tool_version_string(data->version); @@ -1124,7 +1123,7 @@ namespace vcpkg }; const ToolDataArrayDeserializer ToolDataArrayDeserializer::instance; - LocalizedString ToolDataFileDeserializer::type_name() const { return msg::format(msgAToolDataArray); } + LocalizedString ToolDataFileDeserializer::type_name() const { return msg::format(msgAToolDataFile); } View ToolDataFileDeserializer::valid_fields() const { From 86b54d02f40522be6415b54748f326e4e52e60d5 Mon Sep 17 00:00:00 2001 From: Victor Romero Date: Tue, 17 Dec 2024 10:07:00 -0800 Subject: [PATCH 22/30] generate message map --- locales/messages.json | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/locales/messages.json b/locales/messages.json index 394d2c404e..9c98aad52a 100644 --- a/locales/messages.json +++ b/locales/messages.json @@ -4,6 +4,7 @@ "ABoolean": "a boolean", "ABuiltinRegistry": "a builtin registry", "AConfigurationObject": "a configuration object", + "ACpuArchitecture": "a CPU architecture", "ADateVersionString": "a date version string", "ADefaultFeature": "a default feature", "ADemandObject": "a demand object", @@ -36,9 +37,13 @@ "ARelaxedVersionString": "a relaxed version string", "ASemanticVersionString": "a semantic version string", "ASetOfFeatures": "a set of features", + "ASha512": "a SHA-512 hash", "AString": "a string", "AStringOrArrayOfStrings": "a string or array of strings", "AStringStringDictionary": "a \"string\": \"string\" dictionary", + "AToolDataArray": "an array of tool metadata", + "AToolDataFile": "a tool data file", + "AToolDataObject": "tool metadata", "AUrl": "a url", "AVcpkgRepositoryCommit": "a vcpkg repository commit", "AVersionConstraint": "a version constraint", @@ -672,6 +677,8 @@ "_ErrorWhileFetchingBaseline.comment": "{value} is a commit sha. An example of {package_name} is zlib.", "ErrorWhileParsing": "Errors occurred while parsing {path}.", "_ErrorWhileParsing.comment": "An example of {path} is /foo/bar.", + "ErrorWhileParsingToolData": "An unexpected error ocurred while parsing tool data from {path}.", + "_ErrorWhileParsingToolData.comment": "An example of {path} is /foo/bar.", "ErrorWhileWriting": "Error occurred while writing {path}.", "_ErrorWhileWriting.comment": "An example of {path} is /foo/bar.", "ExamplesHeader": "Examples:", @@ -1001,6 +1008,8 @@ "InternalErrorMessageContact": "Please open an issue at https://github.com/microsoft/vcpkg/issues/new?template=other-type-of-bug-report.md&labels=category:vcpkg-bug with detailed steps to reproduce the problem.", "InvalidArchitecture": "invalid architecture: {value}", "_InvalidArchitecture.comment": "{value} is what the user entered that we did not understand", + "InvalidArchitectureValue": "Invalid architecture: {value}. Expected one of: {expected}", + "_InvalidArchitectureValue.comment": "{value} is an unknown CPU architecture type, {expected} is the list of accepted CPU architecture values", "InvalidArgument": "invalid argument", "InvalidArgumentRequiresAbsolutePath": "invalid argument: binary config '{binary_source}' path arguments for binary config strings must be absolute", "_InvalidArgumentRequiresAbsolutePath.comment": "An example of {binary_source} is azblob.", @@ -1068,6 +1077,8 @@ "_InvalidOptionForRemove.comment": "'remove' is a command that should not be changed.", "InvalidPortVersonName": "Found invalid port version file name: `{path}`.", "_InvalidPortVersonName.comment": "An example of {path} is /foo/bar.", + "InvalidSha512": "invalid SHA-512 hash: {sha}\nSHA-512 hash must be 128 characters long and contain only hexadecimal digits", + "_InvalidSha512.comment": "An example of {sha} is eb32643dd2164c72b8a660ef52f1e701bb368324ae461e12d70d6a9aefc0c9573387ee2ed3828037ed62bb3e8f566416a2d3b3827a3928f0bff7c29f7662293e.", "InvalidSharpInVersion": "invalid character '#' in version text", "InvalidSharpInVersionDidYouMean": "invalid character '#' in version text. Did you mean \"port-version\": {value}?", "_InvalidSharpInVersionDidYouMean.comment": "{value} is an integer. `\"port-version\":' is JSON syntax and should be unlocalized", @@ -1436,6 +1447,8 @@ "_ToRemovePackages.comment": "An example of {command_name} is install.", "ToUpdatePackages": "To update these packages and all dependencies, run\n{command_name} upgrade'", "_ToUpdatePackages.comment": "An example of {command_name} is install.", + "ToolDataFileSchemaVersionNotSupported": "document schema version {version} is not supported by this version of vcpkg", + "_ToolDataFileSchemaVersionNotSupported.comment": "An example of {version} is 1.3.8.", "ToolFetchFailed": "Could not fetch {tool_name}.", "_ToolFetchFailed.comment": "An example of {tool_name} is aria2.", "ToolInWin10": "This utility is bundled with Windows 10 or later.", From 3b7bb19f9b2076731142028333119d1b078e6350 Mon Sep 17 00:00:00 2001 From: Victor Romero Date: Wed, 18 Dec 2024 00:33:49 -0800 Subject: [PATCH 23/30] Add redirection switch --- include/vcpkg/base/contractual-constants.h | 1 + include/vcpkg/vcpkgcmdarguments.h | 1 + src/vcpkg/vcpkgcmdarguments.cpp | 1 + src/vcpkg/vcpkgpaths.cpp | 14 +++++++------- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/include/vcpkg/base/contractual-constants.h b/include/vcpkg/base/contractual-constants.h index 1194c2af13..a9c811087a 100644 --- a/include/vcpkg/base/contractual-constants.h +++ b/include/vcpkg/base/contractual-constants.h @@ -290,6 +290,7 @@ namespace vcpkg inline constexpr StringLiteral SwitchTargetX86 = "target:x86"; inline constexpr StringLiteral SwitchTLogFile = "tlog-file"; inline constexpr StringLiteral SwitchTools = "tools"; + inline constexpr StringLiteral SwitchToolDataFile = "tool-data-file"; inline constexpr StringLiteral SwitchTriplet = "triplet"; inline constexpr StringLiteral SwitchUrl = "url"; inline constexpr StringLiteral SwitchVcpkgRoot = "vcpkg-root"; diff --git a/include/vcpkg/vcpkgcmdarguments.h b/include/vcpkg/vcpkgcmdarguments.h index 37109d3056..12b2452dd1 100644 --- a/include/vcpkg/vcpkgcmdarguments.h +++ b/include/vcpkg/vcpkgcmdarguments.h @@ -223,6 +223,7 @@ namespace vcpkg Optional builtin_ports_root_dir; Optional builtin_registry_versions_dir; Optional registries_cache_dir; + Optional tools_data_file; Optional default_visual_studio_path; diff --git a/src/vcpkg/vcpkgcmdarguments.cpp b/src/vcpkg/vcpkgcmdarguments.cpp index 446466079d..afd3c148c3 100644 --- a/src/vcpkg/vcpkgcmdarguments.cpp +++ b/src/vcpkg/vcpkgcmdarguments.cpp @@ -358,6 +358,7 @@ namespace vcpkg args.parser.parse_option( SwitchBuiltinRegistryVersionsDir, StabilityTag::Experimental, args.builtin_registry_versions_dir); args.parser.parse_option(SwitchRegistriesCache, StabilityTag::Experimental, args.registries_cache_dir); + args.parser.parse_option(SwitchToolDataFile, StabilityTag::ImplementationDetail, args.tools_data_file); args.parser.parse_option(SwitchAssetSources, StabilityTag::Experimental, args.asset_sources_template_arg, diff --git a/src/vcpkg/vcpkgpaths.cpp b/src/vcpkg/vcpkgpaths.cpp index 9c7983d33f..06f52c5801 100644 --- a/src/vcpkg/vcpkgpaths.cpp +++ b/src/vcpkg/vcpkgpaths.cpp @@ -570,13 +570,13 @@ namespace vcpkg "packages", "pkgs", VCPKG_LINE_INFO)) - , m_tool_cache(get_tool_cache(fs, - m_download_manager, - downloads, - scripts / "vcpkg-tools.json", - tools, - args.exact_abi_tools_versions.value_or(false) ? RequireExactVersions::YES - : RequireExactVersions::NO)) + , m_tool_cache(get_tool_cache( + fs, + m_download_manager, + downloads, + args.tools_data_file.has_value() ? Path{*args.tools_data_file.get()} : scripts / "vcpkg-tools.json", + tools, + args.exact_abi_tools_versions.value_or(false) ? RequireExactVersions::YES : RequireExactVersions::NO)) , m_env_cache(m_ff_settings.compiler_tracking) , triplets_dirs() , m_artifacts_dir(downloads / "artifacts") From f990fee1ec3a41fab0c67d5ebe7af9958247c2c8 Mon Sep 17 00:00:00 2001 From: Billy Robert O'Neal III Date: Wed, 18 Dec 2024 17:13:33 -0800 Subject: [PATCH 24/30] Fix local test runs by importing the Pester module. --- .github/workflows/build.yaml | 1 - azure-pipelines/end-to-end-tests.ps1 | 4 ++++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 6065715868..608ff9310f 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -80,7 +80,6 @@ jobs: shell: pwsh run: | cd out/build/${{ matrix.preset }} - Import-Module Pester -Force -MinimumVersion '5.6.1' -MaximumVersion '5.99' ${{ github.workspace }}/azure-pipelines/end-to-end-tests.ps1 -RunArtifactsTests env: VCPKG_ROOT: ${{ github.workspace }}/vcpkg-root diff --git a/azure-pipelines/end-to-end-tests.ps1 b/azure-pipelines/end-to-end-tests.ps1 index 8bafa8d563..88aefaa76c 100755 --- a/azure-pipelines/end-to-end-tests.ps1 +++ b/azure-pipelines/end-to-end-tests.ps1 @@ -41,6 +41,10 @@ if ($PSVersionTable.PSVersion.Major -lt 7) { Write-Error "vcpkg end to end tests must use pwsh rather than Windows PowerShell" } +# If you get an error on the next line, install Pester from an administrative command prompt with: +# Install-Module -Name Pester -Force -MinimumVersion '5.6.1' -MaximumVersion '5.99' -Scope AllUsers +Import-Module Pester -Force -MinimumVersion '5.6.1' -MaximumVersion '5.99' + if ($IsLinux) { $Triplet = 'x64-linux' } elseif ($IsMacOS) { From b1af8a369578975c48c2a3b5ee298230c3613124 Mon Sep 17 00:00:00 2001 From: Billy Robert O'Neal III Date: Thu, 2 Jan 2025 13:47:30 -0800 Subject: [PATCH 25/30] Deduplicate architecture tables and JSON errors. --- include/vcpkg/base/jsonreader.h | 7 ++- include/vcpkg/base/message-data.inc.h | 4 -- include/vcpkg/base/system.h | 2 + locales/messages.json | 2 - src/vcpkg-test/tools.cpp | 10 ++-- src/vcpkg/base/json.cpp | 29 ++++------- src/vcpkg/base/system.cpp | 69 ++++++++++++++++----------- src/vcpkg/commands.build.cpp | 4 +- src/vcpkg/tools.cpp | 25 +--------- src/vcpkg/triplet.cpp | 52 ++------------------ 10 files changed, 67 insertions(+), 137 deletions(-) diff --git a/include/vcpkg/base/jsonreader.h b/include/vcpkg/base/jsonreader.h index 874de86890..e1c7912c58 100644 --- a/include/vcpkg/base/jsonreader.h +++ b/include/vcpkg/base/jsonreader.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include @@ -362,12 +363,10 @@ namespace vcpkg::Json static const FeatureNameDeserializer instance; }; - struct ArchitectureDeserializer final : Json::IDeserializer + struct ArchitectureDeserializer final : Json::IDeserializer> { - static const std::vector KNOWN_ARCHITECTURES; - virtual LocalizedString type_name() const override; - virtual Optional visit_string(Json::Reader&, StringView sv) const override; + virtual Optional> visit_string(Json::Reader&, StringView sv) const override; static const ArchitectureDeserializer instance; }; diff --git a/include/vcpkg/base/message-data.inc.h b/include/vcpkg/base/message-data.inc.h index 8ee00d052a..fe16f0c5af 100644 --- a/include/vcpkg/base/message-data.inc.h +++ b/include/vcpkg/base/message-data.inc.h @@ -1833,10 +1833,6 @@ DECLARE_MESSAGE( "Please open an issue at " "https://github.com/microsoft/vcpkg/issues/new?template=other-type-of-bug-report.md&labels=category:vcpkg-bug " "with detailed steps to reproduce the problem.") -DECLARE_MESSAGE(InvalidArchitecture, - (msg::value), - "{value} is what the user entered that we did not understand", - "invalid architecture: {value}") DECLARE_MESSAGE( InvalidArchitectureValue, (msg::value, msg::expected), diff --git a/include/vcpkg/base/system.h b/include/vcpkg/base/system.h index 1d1c334845..3a1f92054b 100644 --- a/include/vcpkg/base/system.h +++ b/include/vcpkg/base/system.h @@ -48,6 +48,8 @@ namespace vcpkg ZStringView to_zstring_view(CPUArchitecture arch) noexcept; + LocalizedString all_comma_separated_cpu_architectures(); + CPUArchitecture get_host_processor(); std::string get_host_os_name(); diff --git a/locales/messages.json b/locales/messages.json index 4ddcccc50d..d248ac1b60 100644 --- a/locales/messages.json +++ b/locales/messages.json @@ -1004,8 +1004,6 @@ "IntegrationFailedVS2015": "Integration was not applied for Visual Studio 2015.", "InternalCICommand": "vcpkg ci is an internal command which will change incompatibly or be removed at any time.", "InternalErrorMessageContact": "Please open an issue at https://github.com/microsoft/vcpkg/issues/new?template=other-type-of-bug-report.md&labels=category:vcpkg-bug with detailed steps to reproduce the problem.", - "InvalidArchitecture": "invalid architecture: {value}", - "_InvalidArchitecture.comment": "{value} is what the user entered that we did not understand", "InvalidArchitectureValue": "Invalid architecture: {value}. Expected one of: {expected}", "_InvalidArchitectureValue.comment": "{value} is an unknown CPU architecture type, {expected} is the list of accepted CPU architecture values", "InvalidArgument": "invalid argument", diff --git a/src/vcpkg-test/tools.cpp b/src/vcpkg-test/tools.cpp index 2956c129f4..dd2d9ab8fa 100644 --- a/src/vcpkg-test/tools.cpp +++ b/src/vcpkg-test/tools.cpp @@ -244,10 +244,8 @@ TEST_CASE ("parse_tool_data errors", "[tools]") "invalid_arch.json"); REQUIRE(!invalid_arch.has_value()); CHECK("invalid_arch.json: error: $.tools[0].arch (a CPU architecture): Invalid architecture: notanarchitecture. " - "Expected " - "one of: x86,x64,arm,arm64,arm64ec,s390x,ppc64le,riscv32,riscv64,loongarch32,loongarch64,mips64\n" - "invalid_arch.json: error: $.tools[0].arch: mismatched type: expected a CPU architecture" == - invalid_arch.error()); + "Expected one of: x86, x64, amd64, arm, arm64, arm64ec, s390x, ppc64le, riscv32, riscv64, loongarch32, " + "loongarch64, mips64" == invalid_arch.error()); auto invalid_sha512 = parse_tool_data(R"( { @@ -264,7 +262,5 @@ TEST_CASE ("parse_tool_data errors", "[tools]") REQUIRE(!invalid_sha512.has_value()); CHECK("invalid_sha512.json: error: $.tools[0].sha512 (a SHA-512 hash): invalid SHA-512 hash: notasha512\n" - "SHA-512 hash must be 128 characters long and contain only hexadecimal digits\n" - "invalid_sha512.json: error: $.tools[0].sha512: mismatched type: expected a SHA-512 hash" == - invalid_sha512.error()); + "SHA-512 hash must be 128 characters long and contain only hexadecimal digits" == invalid_sha512.error()); } diff --git a/src/vcpkg/base/json.cpp b/src/vcpkg/base/json.cpp index 24bec04f97..767e0683b7 100644 --- a/src/vcpkg/base/json.cpp +++ b/src/vcpkg/base/json.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -1634,35 +1635,21 @@ namespace vcpkg::Json const FeatureNameDeserializer FeatureNameDeserializer::instance; - const std::vector ArchitectureDeserializer::KNOWN_ARCHITECTURES = { - "x86", - "x64", - "arm", - "arm64", - "arm64ec", - "s390x", - "ppc64le", - "riscv32", - "riscv64", - "loongarch32", - "loongarch64", - "mips64", - }; - LocalizedString ArchitectureDeserializer::type_name() const { return msg::format(msgACpuArchitecture); } - Optional ArchitectureDeserializer::visit_string(Json::Reader& r, StringView sv) const + Optional> ArchitectureDeserializer::visit_string(Json::Reader& r, StringView sv) const { - if (Util::contains(KNOWN_ARCHITECTURES, sv)) + auto maybe_cpu_architecture = to_cpu_architecture(sv); + if (maybe_cpu_architecture.has_value()) { - return sv.to_string(); + return maybe_cpu_architecture; } r.add_generic_error(type_name(), msg::format(msgInvalidArchitectureValue, msg::value = sv, - msg::expected = Strings::join(",", KNOWN_ARCHITECTURES))); - return nullopt; + msg::expected = all_comma_separated_cpu_architectures())); + return Optional{nullopt}; } const ArchitectureDeserializer ArchitectureDeserializer::instance; @@ -1677,7 +1664,7 @@ namespace vcpkg::Json } r.add_generic_error(type_name(), msg::format(msgInvalidSha512, msg::sha = sv)); - return nullopt; + return std::string(); } const Sha512Deserializer Sha512Deserializer::instance; diff --git a/src/vcpkg/base/system.cpp b/src/vcpkg/base/system.cpp index 3df622e156..d0a76f1ec1 100644 --- a/src/vcpkg/base/system.cpp +++ b/src/vcpkg/base/system.cpp @@ -134,6 +134,28 @@ namespace return result; } #endif // ^^^ _WIN32 + + struct CPUArchitectureEntry + { + StringLiteral name; + CPUArchitecture arch; + }; + + static constexpr CPUArchitectureEntry cpu_architecture_table[] = { + {"x86", CPUArchitecture::X86}, + {"x64", CPUArchitecture::X64}, + {"amd64", CPUArchitecture::X64}, + {"arm", CPUArchitecture::ARM}, + {"arm64", CPUArchitecture::ARM64}, + {"arm64ec", CPUArchitecture::ARM64EC}, + {"s390x", CPUArchitecture::S390X}, + {"ppc64le", CPUArchitecture::PPC64LE}, + {"riscv32", CPUArchitecture::RISCV32}, + {"riscv64", CPUArchitecture::RISCV64}, + {"loongarch32", CPUArchitecture::LOONGARCH32}, + {"loongarch64", CPUArchitecture::LOONGARCH64}, + {"mips64", CPUArchitecture::MIPS64}, + }; } namespace vcpkg @@ -149,41 +171,34 @@ namespace vcpkg Optional to_cpu_architecture(StringView arch) { - if (Strings::case_insensitive_ascii_equals(arch, "x86")) return CPUArchitecture::X86; - if (Strings::case_insensitive_ascii_equals(arch, "x64")) return CPUArchitecture::X64; - if (Strings::case_insensitive_ascii_equals(arch, "amd64")) return CPUArchitecture::X64; - if (Strings::case_insensitive_ascii_equals(arch, "arm")) return CPUArchitecture::ARM; - if (Strings::case_insensitive_ascii_equals(arch, "arm64")) return CPUArchitecture::ARM64; - if (Strings::case_insensitive_ascii_equals(arch, "arm64ec")) return CPUArchitecture::ARM64EC; - if (Strings::case_insensitive_ascii_equals(arch, "s390x")) return CPUArchitecture::S390X; - if (Strings::case_insensitive_ascii_equals(arch, "ppc64le")) return CPUArchitecture::PPC64LE; - if (Strings::case_insensitive_ascii_equals(arch, "riscv32")) return CPUArchitecture::RISCV32; - if (Strings::case_insensitive_ascii_equals(arch, "riscv64")) return CPUArchitecture::RISCV64; - if (Strings::case_insensitive_ascii_equals(arch, "loongarch32")) return CPUArchitecture::LOONGARCH32; - if (Strings::case_insensitive_ascii_equals(arch, "loongarch64")) return CPUArchitecture::LOONGARCH64; - if (Strings::case_insensitive_ascii_equals(arch, "mips64")) return CPUArchitecture::MIPS64; + for (auto&& entry : cpu_architecture_table) + { + if (Strings::case_insensitive_ascii_equals(arch, entry.name)) + { + return entry.arch; + } + } return nullopt; } ZStringView to_zstring_view(CPUArchitecture arch) noexcept { - switch (arch) + for (auto&& entry : cpu_architecture_table) { - case CPUArchitecture::X86: return "x86"; - case CPUArchitecture::X64: return "x64"; - case CPUArchitecture::ARM: return "arm"; - case CPUArchitecture::ARM64: return "arm64"; - case CPUArchitecture::ARM64EC: return "arm64ec"; - case CPUArchitecture::S390X: return "s390x"; - case CPUArchitecture::PPC64LE: return "ppc64le"; - case CPUArchitecture::RISCV32: return "riscv32"; - case CPUArchitecture::RISCV64: return "riscv64"; - case CPUArchitecture::LOONGARCH32: return "loongarch32"; - case CPUArchitecture::LOONGARCH64: return "loongarch64"; - case CPUArchitecture::MIPS64: return "mips64"; - default: Checks::exit_with_message(VCPKG_LINE_INFO, "unexpected vcpkg::CPUArchitecture"); + if (entry.arch == arch) + { + return entry.name; + } } + + Checks::unreachable(VCPKG_LINE_INFO, "unexpected vcpkg::CPUArchitecture"); + } + + LocalizedString all_comma_separated_cpu_architectures() + { + return LocalizedString::from_raw( + Strings::join(", ", cpu_architecture_table, [](const CPUArchitectureEntry& entry) { return entry.name; })); } CPUArchitecture get_host_processor() diff --git a/src/vcpkg/commands.build.cpp b/src/vcpkg/commands.build.cpp index 16029b5612..ac1b533fb8 100644 --- a/src/vcpkg/commands.build.cpp +++ b/src/vcpkg/commands.build.cpp @@ -323,7 +323,9 @@ namespace vcpkg auto maybe_target_arch = to_cpu_architecture(target_architecture); if (!maybe_target_arch.has_value()) { - msg::println_error(msgInvalidArchitecture, msg::value = target_architecture); + msg::println_error(msgInvalidArchitectureValue, + msg::value = target_architecture, + msg::expected = all_comma_separated_cpu_architectures()); Checks::exit_maybe_upgrade(VCPKG_LINE_INFO); } diff --git a/src/vcpkg/tools.cpp b/src/vcpkg/tools.cpp index 5f5b282c41..59a66c88fd 100644 --- a/src/vcpkg/tools.cpp +++ b/src/vcpkg/tools.cpp @@ -1079,21 +1079,6 @@ namespace vcpkg virtual Optional visit_object(Json::Reader& r, const Json::Object& obj) const override { - static const std::map arch_map{ - {"x86", CPUArchitecture::X86}, - {"x64", CPUArchitecture::X64}, - {"arm", CPUArchitecture::ARM}, - {"arm64", CPUArchitecture::ARM64}, - {"arm64ec", CPUArchitecture::ARM64EC}, - {"s390x", CPUArchitecture::S390X}, - {"ppc64le", CPUArchitecture::PPC64LE}, - {"riscv32", CPUArchitecture::RISCV32}, - {"riscv64", CPUArchitecture::RISCV64}, - {"loongarch32", CPUArchitecture::LOONGARCH32}, - {"loongarch64", CPUArchitecture::LOONGARCH64}, - {"mips64", CPUArchitecture::MIPS64}, - }; - ToolDataEntry value; r.required_object_field(type_name(), obj, "name", value.tool, Json::UntypedStringDeserializer::instance); @@ -1101,15 +1086,7 @@ namespace vcpkg r.required_object_field( type_name(), obj, "version", value.version, Json::UntypedStringDeserializer::instance); - std::string arch_str; - if (r.optional_object_field(obj, "arch", arch_str, Json::ArchitectureDeserializer::instance)) - { - auto it = arch_map.find(arch_str); - if (it != arch_map.end()) - { - value.arch = it->second; - } - } + r.optional_object_field(obj, "arch", value.arch, Json::ArchitectureDeserializer::instance); r.optional_object_field( obj, "executable", value.exeRelativePath, Json::UntypedStringDeserializer::instance); r.optional_object_field(obj, "url", value.url, Json::UntypedStringDeserializer::instance); diff --git a/src/vcpkg/triplet.cpp b/src/vcpkg/triplet.cpp index ba5060eccd..21e597338c 100644 --- a/src/vcpkg/triplet.cpp +++ b/src/vcpkg/triplet.cpp @@ -47,56 +47,14 @@ namespace vcpkg Optional Triplet::guess_architecture() const noexcept { - if (Strings::starts_with(this->canonical_name(), "x86-")) + StringView canonical = this->canonical_name(); + auto dash = std::find(canonical.begin(), canonical.end(), '-'); + if (dash != canonical.end()) { - return CPUArchitecture::X86; - } - if (Strings::starts_with(this->canonical_name(), "x64-")) - { - return CPUArchitecture::X64; - } - if (Strings::starts_with(this->canonical_name(), "arm-")) - { - return CPUArchitecture::ARM; - } - if (Strings::starts_with(this->canonical_name(), "arm64-")) - { - return CPUArchitecture::ARM64; - } - if (Strings::starts_with(this->canonical_name(), "arm64ec-")) - { - return CPUArchitecture::ARM64EC; - } - if (Strings::starts_with(this->canonical_name(), "s390x-")) - { - return CPUArchitecture::S390X; - } - if (Strings::starts_with(this->canonical_name(), "ppc64le-")) - { - return CPUArchitecture::PPC64LE; - } - if (Strings::starts_with(this->canonical_name(), "riscv32-")) - { - return CPUArchitecture::RISCV32; - } - if (Strings::starts_with(this->canonical_name(), "riscv64-")) - { - return CPUArchitecture::RISCV64; - } - if (Strings::starts_with(this->canonical_name(), "loongarch32-")) - { - return CPUArchitecture::LOONGARCH32; - } - if (Strings::starts_with(this->canonical_name(), "loongarch64-")) - { - return CPUArchitecture::LOONGARCH64; - } - if (Strings::starts_with(this->canonical_name(), "mips64-")) - { - return CPUArchitecture::MIPS64; + canonical = StringView{canonical.begin(), dash}; } - return nullopt; + return to_cpu_architecture(canonical); } static std::string system_triplet_canonical_name() From 870da9442e75ec4fd2a335c63aa92d129f32a5d5 Mon Sep 17 00:00:00 2001 From: Billy Robert O'Neal III Date: Thu, 2 Jan 2025 13:52:44 -0800 Subject: [PATCH 26/30] Update vcpkg-scripts-sha. --- vcpkg-init/vcpkg-scripts-sha.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vcpkg-init/vcpkg-scripts-sha.txt b/vcpkg-init/vcpkg-scripts-sha.txt index 496778ddb6..126f8e6daa 100644 --- a/vcpkg-init/vcpkg-scripts-sha.txt +++ b/vcpkg-init/vcpkg-scripts-sha.txt @@ -1 +1 @@ -72254a16c21047ed5617ca98a89283e9c93f9b03 +be8a239dd4fc329ea3f9377c42b2cb5a5d7d75f3 From b4e7579c3134cf360609c157c7156f2e52152a12 Mon Sep 17 00:00:00 2001 From: Billy Robert O'Neal III Date: Thu, 2 Jan 2025 18:33:37 -0800 Subject: [PATCH 27/30] Use more standard JSON parsing bits. --- include/vcpkg/base/message-data.inc.h | 4 --- locales/messages.json | 2 -- src/vcpkg-test/tools.cpp | 2 +- src/vcpkg/tools.cpp | 40 +++++++++------------------ 4 files changed, 14 insertions(+), 34 deletions(-) diff --git a/include/vcpkg/base/message-data.inc.h b/include/vcpkg/base/message-data.inc.h index fe16f0c5af..d08167b59b 100644 --- a/include/vcpkg/base/message-data.inc.h +++ b/include/vcpkg/base/message-data.inc.h @@ -1169,10 +1169,6 @@ DECLARE_MESSAGE(ErrorWhileFetchingBaseline, "{value} is a commit sha.", "while fetching baseline `\"{value}\"` from repo {package_name}:") DECLARE_MESSAGE(ErrorWhileParsing, (msg::path), "", "Errors occurred while parsing {path}.") -DECLARE_MESSAGE(ErrorWhileParsingToolData, - (msg::path), - "", - "An unexpected error ocurred while parsing tool data from {path}.") DECLARE_MESSAGE(ErrorWhileWriting, (msg::path), "", "Error occurred while writing {path}.") DECLARE_MESSAGE(ExamplesHeader, (), "Printed before a list of example command lines", "Examples:") DECLARE_MESSAGE(ExceededRecursionDepth, (), "", "Recursion depth exceeded.") diff --git a/locales/messages.json b/locales/messages.json index d248ac1b60..6cfb61edb5 100644 --- a/locales/messages.json +++ b/locales/messages.json @@ -675,8 +675,6 @@ "_ErrorWhileFetchingBaseline.comment": "{value} is a commit sha. An example of {package_name} is zlib.", "ErrorWhileParsing": "Errors occurred while parsing {path}.", "_ErrorWhileParsing.comment": "An example of {path} is /foo/bar.", - "ErrorWhileParsingToolData": "An unexpected error ocurred while parsing tool data from {path}.", - "_ErrorWhileParsingToolData.comment": "An example of {path} is /foo/bar.", "ErrorWhileWriting": "Error occurred while writing {path}.", "_ErrorWhileWriting.comment": "An example of {path} is /foo/bar.", "ExamplesHeader": "Examples:", diff --git a/src/vcpkg-test/tools.cpp b/src/vcpkg-test/tools.cpp index dd2d9ab8fa..dea8fb5602 100644 --- a/src/vcpkg-test/tools.cpp +++ b/src/vcpkg-test/tools.cpp @@ -206,7 +206,7 @@ TEST_CASE ("parse_tool_data errors", "[tools]") auto top_level_json = parse_tool_data("[]", "top_level.json"); REQUIRE(!top_level_json.has_value()); - CHECK("An unexpected error ocurred while parsing tool data from top_level.json." == top_level_json.error()); + CHECK("Expected \"top_level.json\" to be an object." == top_level_json.error()); auto missing_required = parse_tool_data(R"({ "schema-version": 1, "tools": [{ "executable": "git.exe" }]})", "missing_required.json"); diff --git a/src/vcpkg/tools.cpp b/src/vcpkg/tools.cpp index 59a66c88fd..e2dbbc5bbd 100644 --- a/src/vcpkg/tools.cpp +++ b/src/vcpkg/tools.cpp @@ -65,38 +65,24 @@ namespace vcpkg ExpectedL> parse_tool_data(StringView contents, StringView origin) { - auto as_json = Json::parse(contents, origin); - if (!as_json) - { - return as_json.error(); - } - auto as_value = std::move(as_json).value(VCPKG_LINE_INFO).value; - - Json::Reader r(origin); - auto maybe_tool_data = r.visit(as_value, ToolDataFileDeserializer::instance); - if (!r.errors().empty() || !r.warnings().empty()) - { - return r.join(); - } - - if (auto tool_data = maybe_tool_data.get()) - { - return *tool_data; - } + return Json::parse_object(contents, origin) + .then([&](Json::Object&& as_object) -> ExpectedL> { + Json::Reader r(origin); + auto maybe_tool_data = r.visit(as_object, ToolDataFileDeserializer::instance); + if (!r.errors().empty() || !r.warnings().empty()) + { + return r.join(); + } - return msg::format(msgErrorWhileParsingToolData, msg::path = origin); + return maybe_tool_data.value_or_exit(VCPKG_LINE_INFO); + }); } static ExpectedL> parse_tool_data_file(const Filesystem& fs, Path path) { - std::error_code ec; - auto contents = fs.read_contents(path, ec); - if (ec) - { - return format_filesystem_call_error(ec, __func__, {path}); - } - - return parse_tool_data(contents, path); + return fs.try_read_contents(path).then([](FileContents&& fc) -> ExpectedL> { + return parse_tool_data(fc.content, Path{fc.origin}); + }); } const ToolDataEntry* get_raw_tool_data(const std::vector& tool_data_table, From cf3ea152d47ce80fc002dfcaa9e21366a0384596 Mon Sep 17 00:00:00 2001 From: Billy Robert O'Neal III Date: Thu, 2 Jan 2025 21:07:06 -0800 Subject: [PATCH 28/30] Add JSON schema, better validation for enum fields, and tests. --- .../end-to-end-tests-dir/fetch.ps1 | 13 +- docs/vcpkg-tools.schema.json | 69 ++++++++ include/vcpkg/base/contractual-constants.h | 6 + include/vcpkg/base/jsonreader.h | 6 +- include/vcpkg/base/message-data.inc.h | 15 +- include/vcpkg/base/strings.h | 2 +- include/vcpkg/base/system.h | 7 +- include/vcpkg/tools.test.h | 50 +++++- include/vcpkg/versiondeserializers.h | 4 +- locales/messages.json | 7 +- src/vcpkg-test/system.cpp | 2 +- src/vcpkg-test/tools.cpp | 152 ++++++++++------ src/vcpkg/base/json.cpp | 4 +- src/vcpkg/base/strings.cpp | 2 +- src/vcpkg/base/system.cpp | 8 +- src/vcpkg/commands.build.cpp | 2 +- src/vcpkg/commands.install.cpp | 4 +- src/vcpkg/configuration.cpp | 20 +-- src/vcpkg/registries.cpp | 19 +- src/vcpkg/sourceparagraph.cpp | 33 ++-- src/vcpkg/tools.cpp | 167 +++++++++++++----- src/vcpkg/triplet.cpp | 3 +- src/vcpkg/versiondeserializers.cpp | 7 - 23 files changed, 425 insertions(+), 177 deletions(-) create mode 100644 docs/vcpkg-tools.schema.json diff --git a/azure-pipelines/end-to-end-tests-dir/fetch.ps1 b/azure-pipelines/end-to-end-tests-dir/fetch.ps1 index 960c8510dc..1a0e332be6 100644 --- a/azure-pipelines/end-to-end-tests-dir/fetch.ps1 +++ b/azure-pipelines/end-to-end-tests-dir/fetch.ps1 @@ -1,10 +1,17 @@ . $PSScriptRoot/../end-to-end-tests-prelude.ps1 +$VcpkgToolsJsonSchemaFile = (Get-Item "$PSScriptRoot/../../docs/vcpkg-tools.schema.json").FullName +if (-not (Test-Json -ea:0 -LiteralPath "$VcpkgRoot/scripts/vcpkg-tools.json" -SchemaFile $VcpkgToolsJsonSchemaFile)) { + throw "real vcpkg-tools.json doesn't conform to schema" +} + if (-not $IsMacOS -and -not $IsLinux) { "" | Out-File -enc ascii $(Join-Path $TestingRoot .vcpkg-root) $Scripts = Join-Path $TestingRoot "scripts" mkdir $Scripts | Out-Null + + $VcpkgToolsJson = Join-Path $Scripts "vcpkg-tools.json" $7zip_version = "19.00" $ninja_version = "1.10.2" @@ -76,7 +83,11 @@ if (-not $IsMacOS -and -not $IsLinux) { "archive": "cmake-3.20.4.txz" }] } -'@ | % { $_ -replace "`r","" } | Out-File -enc ascii $(Join-Path $Scripts "vcpkg-tools.json") +'@ | % { $_ -replace "`r","" } | Out-File -enc ascii $VcpkgToolsJson + + if (-not (Test-Json -ea:0 -LiteralPath $VcpkgToolsJson -SchemaFile $VcpkgToolsJsonSchemaFile)) { + throw "testing vcpkg-tools.json doesn't conform to schema" + } $env:VCPKG_DOWNLOADS = Join-Path $TestingRoot 'down loads' Run-Vcpkg -TestArgs ($commonArgs + @("fetch", "7zip", "--vcpkg-root=$TestingRoot")) diff --git a/docs/vcpkg-tools.schema.json b/docs/vcpkg-tools.schema.json new file mode 100644 index 0000000000..f211e3c424 --- /dev/null +++ b/docs/vcpkg-tools.schema.json @@ -0,0 +1,69 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/main/docs/vcpkg-tools.schema.json", + "type": "object", + "properties": { + "schema-version": { + "description": "Identifies the version of the tools database format; currently always 1.", + "type": "number", + "minimum": 1, + "maximum": 1 + }, + "tools": { + "type": "array", + "description": "The set of known tools.", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "The name of the tool as exposed to `vcpkg fetch`." + }, + "os": { + "type": "string", + "description": "The platform where the record is valid.", + "enum": [ "windows", "osx", "linux", "freebsd", "openbsd" ] + }, + "version": { + "type": "string", + "description": "The version to match against against a system provided copy of this tool.", + "pattern": "\\d+(\\.\\d+(\\.\\d+)?)?" + }, + "arch": { + "type": "string", + "description": "The architecture where the record is valid.", + "enum": [ "x86", "x64", "amd64", "arm", "arm64", "arm64ec", "s390x", "ppc64le", "riscv32", "riscv64", "loongarch32", "loongarch64", "mips64" ] + }, + "executable": { + "type": "string", + "description": "The relative path to the executable for the tool within the downloaded archive, if any." + }, + "url": { + "type": "string", + "description": "The URL to download the tool from.", + "format": "uri" + }, + "sha512": { + "type": "string", + "description": "The SHA-512 hash of the downloaded archive.", + "pattern": "^[0-9a-fA-F]{128}$" + }, + "archive": { + "type": "string", + "description": "The name of the downloaded archive." + } + }, + "patternProperties": { + "^\\$": {} + }, + "required": ["name", "os", "version"], + "additionalProperties": false + } + } + }, + "patternProperties": { + "^\\$": {} + }, + "additionalProperties": false, + "required": [ "schema-version", "tools" ] +} diff --git a/include/vcpkg/base/contractual-constants.h b/include/vcpkg/base/contractual-constants.h index f620cd3ba9..fdb5c6cbba 100644 --- a/include/vcpkg/base/contractual-constants.h +++ b/include/vcpkg/base/contractual-constants.h @@ -12,9 +12,11 @@ namespace vcpkg inline constexpr StringLiteral JsonIdAcquiredArtifacts = "acquired-artifacts"; inline constexpr StringLiteral JsonIdActivatedArtifacts = "activated-artifacts"; inline constexpr StringLiteral JsonIdAlgorithm = "algorithm"; + inline constexpr StringLiteral JsonIdArchive = "archive"; inline constexpr StringLiteral JsonIdAllCapsSHA256 = "SHA256"; inline constexpr StringLiteral JsonIdAllCapsSHA512 = "SHA512"; inline constexpr StringLiteral JsonIdApply = "apply"; + inline constexpr StringLiteral JsonIdArch = "arch"; inline constexpr StringLiteral JsonIdArchiveCapitalLocation = "archiveLocation"; inline constexpr StringLiteral JsonIdArtifact = "artifact"; inline constexpr StringLiteral JsonIdBaseline = "baseline"; @@ -46,6 +48,7 @@ namespace vcpkg inline constexpr StringLiteral JsonIdDollarSchema = "$schema"; inline constexpr StringLiteral JsonIdDownloads = "downloads"; inline constexpr StringLiteral JsonIdError = "error"; + inline constexpr StringLiteral JsonIdExecutable = "executable"; inline constexpr StringLiteral JsonIdFeatures = "features"; inline constexpr StringLiteral JsonIdFiles = "files"; inline constexpr StringLiteral JsonIdFilesystem = "filesystem"; @@ -68,6 +71,7 @@ namespace vcpkg inline constexpr StringLiteral JsonIdMessage = "message"; inline constexpr StringLiteral JsonIdMicrosoft = "microsoft"; inline constexpr StringLiteral JsonIdName = "name"; + inline constexpr StringLiteral JsonIdOS = "os"; inline constexpr StringLiteral JsonIdOverlayPorts = "overlay-ports"; inline constexpr StringLiteral JsonIdOverlayTriplets = "overlay-triplets"; inline constexpr StringLiteral JsonIdOverrides = "overrides"; @@ -87,8 +91,10 @@ namespace vcpkg inline constexpr StringLiteral JsonIdRequires = "requires"; inline constexpr StringLiteral JsonIdResolved = "resolved"; inline constexpr StringLiteral JsonIdScanned = "scanned"; + inline constexpr StringLiteral JsonIdSchemaVersion = "schema-version"; inline constexpr StringLiteral JsonIdSettings = "settings"; inline constexpr StringLiteral JsonIdSha = "sha"; + inline constexpr StringLiteral JsonIdSha512 = "sha512"; inline constexpr StringLiteral JsonIdState = "state"; inline constexpr StringLiteral JsonIdSummary = "summary"; inline constexpr StringLiteral JsonIdSupports = "supports"; diff --git a/include/vcpkg/base/jsonreader.h b/include/vcpkg/base/jsonreader.h index e1c7912c58..542cdb741e 100644 --- a/include/vcpkg/base/jsonreader.h +++ b/include/vcpkg/base/jsonreader.h @@ -31,7 +31,7 @@ namespace vcpkg::Json virtual Optional visit_string(Reader&, StringView) const; virtual Optional visit_array(Reader&, const Array&) const; virtual Optional visit_object(Reader&, const Object&) const; - virtual View valid_fields() const; + virtual View valid_fields() const noexcept; virtual ~IDeserializer() = default; @@ -101,7 +101,7 @@ namespace vcpkg::Json // * are not in `valid_fields` // if known_fields.empty(), then it's treated as if all field names are valid void check_for_unexpected_fields(const Object& obj, - View valid_fields, + View valid_fields, const LocalizedString& type_name); template @@ -239,7 +239,7 @@ namespace vcpkg::Json } template - View IDeserializer::valid_fields() const + View IDeserializer::valid_fields() const noexcept { return {}; } diff --git a/include/vcpkg/base/message-data.inc.h b/include/vcpkg/base/message-data.inc.h index d08167b59b..7357d2a412 100644 --- a/include/vcpkg/base/message-data.inc.h +++ b/include/vcpkg/base/message-data.inc.h @@ -269,6 +269,8 @@ DECLARE_MESSAGE(AStringStringDictionary, (), "", "a \"string\": \"string\" dicti DECLARE_MESSAGE(AToolDataObject, (), "", "tool metadata") DECLARE_MESSAGE(AToolDataArray, (), "", "an array of tool metadata") DECLARE_MESSAGE(AToolDataFile, (), "", "a tool data file") +DECLARE_MESSAGE(AToolDataOS, (), "", "a tool data operating system") +DECLARE_MESSAGE(AToolDataVersion, (), "", "a tool data version") DECLARE_MESSAGE(ToolDataFileSchemaVersionNotSupported, (msg::version), "", @@ -1301,10 +1303,6 @@ DECLARE_MESSAGE(FailedToParseSerializedBinParagraph, "[sanity check] Failed to parse a serialized binary paragraph.\nPlease open an issue at " "https://github.com/microsoft/vcpkg, " "with the following output:\n{error_msg}\nSerialized Binary Paragraph:") -DECLARE_MESSAGE(FailedToParseVersionXML, - (msg::tool_name, msg::version), - "", - "Could not parse version for tool {tool_name}. Version string was: {version}") DECLARE_MESSAGE(FailedToRunToolToDetermineVersion, (msg::tool_name, msg::path), "Additional information, such as the command line output, if any, will be appended on " @@ -1967,6 +1965,15 @@ DECLARE_MESSAGE(InvalidSharpInVersionDidYouMean, "{value} is an integer. `\"port-version\":' is JSON syntax and should be unlocalized", "invalid character '#' in version text. Did you mean \"port-version\": {value}?") DECLARE_MESSAGE(InvalidString, (), "", "Invalid utf8 passed to Value::string(std::string)") +DECLARE_MESSAGE(InvalidToolOSValue, + (msg::value, msg::expected), + "{value} is an unknown operating system, {expected} is the list of accepted operating system values", + "Invalid tool operating system: {value}. Expected one of: {expected}") +DECLARE_MESSAGE( + InvalidToolVersion, + (), + "", + "Invalid tool version; expected a string containing a substring of between 1 and 3 numbers separated by dots.") DECLARE_MESSAGE(InvalidTriplet, (msg::triplet), "", "Invalid triplet: {triplet}") DECLARE_MESSAGE(InvalidValueHashAdditionalFiles, (msg::path), diff --git a/include/vcpkg/base/strings.h b/include/vcpkg/base/strings.h index 2d27d27b29..af7ca77acf 100644 --- a/include/vcpkg/base/strings.h +++ b/include/vcpkg/base/strings.h @@ -122,7 +122,7 @@ namespace vcpkg::Strings const char* case_insensitive_ascii_search(StringView s, StringView pattern); bool case_insensitive_ascii_contains(StringView s, StringView pattern); - bool case_insensitive_ascii_equals(StringView left, StringView right); + bool case_insensitive_ascii_equals(StringView left, StringView right) noexcept; bool case_insensitive_ascii_less(StringView left, StringView right); void inplace_ascii_to_lowercase(char* first, char* last); diff --git a/include/vcpkg/base/system.h b/include/vcpkg/base/system.h index 3a1f92054b..aaa4ec8b04 100644 --- a/include/vcpkg/base/system.h +++ b/include/vcpkg/base/system.h @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -44,9 +45,9 @@ namespace vcpkg long get_process_id(); - Optional to_cpu_architecture(StringView arch); + Optional to_cpu_architecture(StringView arch) noexcept; - ZStringView to_zstring_view(CPUArchitecture arch) noexcept; + StringLiteral to_string_literal(CPUArchitecture arch) noexcept; LocalizedString all_comma_separated_cpu_architectures(); @@ -64,3 +65,5 @@ namespace vcpkg Optional guess_visual_studio_prompt_target_architecture(); } + +VCPKG_FORMAT_WITH_TO_STRING_LITERAL_NONMEMBER(vcpkg::CPUArchitecture); diff --git a/include/vcpkg/tools.test.h b/include/vcpkg/tools.test.h index 2dce77deab..ce4fa47cd5 100644 --- a/include/vcpkg/tools.test.h +++ b/include/vcpkg/tools.test.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include #include @@ -12,6 +13,12 @@ namespace vcpkg { + struct ToolVersion + { + std::array cooked; // e.g. 24.8 or 2.7.4 or 1.0.0 + std::string raw; // e.g. 24.08 or 2.7.4 or 1.0 + }; + struct ToolData { std::string name; @@ -32,12 +39,25 @@ namespace vcpkg Optional> parse_tool_version_string(StringView string_version); + enum class ToolOs + { + Windows, + Osx, + Linux, + FreeBsd, + OpenBsd, + }; + + Optional to_tool_os(StringView os) noexcept; + StringLiteral to_string_literal(ToolOs os) noexcept; + LocalizedString all_comma_separated_tool_oses(); + struct ToolDataEntry { std::string tool; - std::string os; - Optional arch; - std::string version; + ToolOs os; + Optional arch; + ToolVersion version; std::string exeRelativePath; std::string url; std::string sha512; @@ -49,17 +69,37 @@ namespace vcpkg const ToolDataEntry* get_raw_tool_data(const std::vector& tool_data_table, StringView toolname, const CPUArchitecture arch, - StringView os); + const ToolOs os); struct ToolDataFileDeserializer final : Json::IDeserializer> { virtual LocalizedString type_name() const override; - virtual View valid_fields() const override; + virtual View valid_fields() const noexcept override; virtual Optional> visit_object(Json::Reader& r, const Json::Object& obj) const override; static const ToolDataFileDeserializer instance; }; + + struct ToolOsDeserializer final : Json::IDeserializer + { + virtual LocalizedString type_name() const override; + + virtual Optional visit_string(Json::Reader& r, StringView str) const override; + + static const ToolOsDeserializer instance; + }; + + struct ToolVersionDeserializer final : Json::IDeserializer + { + virtual LocalizedString type_name() const override; + + virtual Optional visit_string(Json::Reader& r, StringView str) const override; + + static const ToolVersionDeserializer instance; + }; } + +VCPKG_FORMAT_WITH_TO_STRING_LITERAL_NONMEMBER(vcpkg::ToolOs); diff --git a/include/vcpkg/versiondeserializers.h b/include/vcpkg/versiondeserializers.h index 82a5e8d29d..c68951ed25 100644 --- a/include/vcpkg/versiondeserializers.h +++ b/include/vcpkg/versiondeserializers.h @@ -4,6 +4,7 @@ #include +#include #include #include @@ -23,7 +24,8 @@ namespace vcpkg Json::Reader& r, const Json::Object& obj); - View schemed_deserializer_fields(); +#define VCPKG_SCHEMED_DESERIALIZER_FIELDS \ + JsonIdVersion, JsonIdVersionSemver, JsonIdVersionString, JsonIdVersionDate, JsonIdPortVersion void serialize_schemed_version(Json::Object& out_obj, VersionScheme scheme, const Version& version); diff --git a/locales/messages.json b/locales/messages.json index 6cfb61edb5..779bc18bd9 100644 --- a/locales/messages.json +++ b/locales/messages.json @@ -43,7 +43,9 @@ "AStringStringDictionary": "a \"string\": \"string\" dictionary", "AToolDataArray": "an array of tool metadata", "AToolDataFile": "a tool data file", + "AToolDataOS": "a tool data operating system", "AToolDataObject": "tool metadata", + "AToolDataVersion": "a tool data version", "AUrl": "a url", "AVcpkgRepositoryCommit": "a vcpkg repository commit", "AVersionConstraint": "a version constraint", @@ -767,8 +769,6 @@ "_FailedToParseSerializedBinParagraph.comment": "'{error_msg}' is the error message for failing to parse the Binary Paragraph. An example of {error_msg} is File Not Found.", "FailedToParseVersionFile": "Failed to parse version file: {path}", "_FailedToParseVersionFile.comment": "An example of {path} is /foo/bar.", - "FailedToParseVersionXML": "Could not parse version for tool {tool_name}. Version string was: {version}", - "_FailedToParseVersionXML.comment": "An example of {tool_name} is aria2. An example of {version} is 1.3.8.", "FailedToRunToolToDetermineVersion": "Failed to run \"{path}\" to determine the {tool_name} version.", "_FailedToRunToolToDetermineVersion.comment": "Additional information, such as the command line output, if any, will be appended on the line after this message An example of {tool_name} is aria2. An example of {path} is /foo/bar.", "FailedToStoreBackToMirror": "Failed to store {path} to {url}.", @@ -1077,6 +1077,9 @@ "InvalidSharpInVersionDidYouMean": "invalid character '#' in version text. Did you mean \"port-version\": {value}?", "_InvalidSharpInVersionDidYouMean.comment": "{value} is an integer. `\"port-version\":' is JSON syntax and should be unlocalized", "InvalidString": "Invalid utf8 passed to Value::string(std::string)", + "InvalidToolOSValue": "Invalid tool operating system: {value}. Expected one of: {expected}", + "_InvalidToolOSValue.comment": "{value} is an unknown operating system, {expected} is the list of accepted operating system values", + "InvalidToolVersion": "Invalid tool version; expected a string containing a substring of between 1 and 3 numbers separated by dots.", "InvalidTriplet": "Invalid triplet: {triplet}", "_InvalidTriplet.comment": "An example of {triplet} is x64-windows.", "InvalidUri": "unable to parse uri: {value}", diff --git a/src/vcpkg-test/system.cpp b/src/vcpkg-test/system.cpp index 4d0e771d87..9e50027d0c 100644 --- a/src/vcpkg-test/system.cpp +++ b/src/vcpkg-test/system.cpp @@ -78,7 +78,7 @@ TEST_CASE ("from_cpu_architecture", "[system]") for (auto&& instance : test_cases) { - CHECK(to_zstring_view(instance.input) == instance.expected); + CHECK(to_string_literal(instance.input) == instance.expected); } } diff --git a/src/vcpkg-test/tools.cpp b/src/vcpkg-test/tools.cpp index dea8fb5602..1dfe52b993 100644 --- a/src/vcpkg-test/tools.cpp +++ b/src/vcpkg-test/tools.cpp @@ -72,9 +72,11 @@ TEST_CASE ("parse_tool_data", "[tools]") { const StringView tool_doc = R"( { + "$comment": "This is a comment", "schema-version": 1, "tools": [ { + "$comment": "This is a comment", "name": "git", "os": "linux", "version": "2.7.4", @@ -98,7 +100,7 @@ TEST_CASE ("parse_tool_data", "[tools]") { "name": "node", "os": "windows", - "version": "16.12.0", + "version": "node version 16.12.0.windows.2", "executable": "node-v16.12.0-win-x64\\node.exe", "url": "https://nodejs.org/dist/v16.12.0/node-v16.12.0-win-x64.7z", "sha512": "0bb793fce8140bd59c17f3ac9661b062eac0f611d704117774f5cb2453d717da94b1e8b17d021d47baff598dc023fb7068ed1f8a7678e446260c3db3537fa888", @@ -113,40 +115,44 @@ TEST_CASE ("parse_tool_data", "[tools]") auto data = maybe_data.value_or_exit(VCPKG_LINE_INFO); REQUIRE(data.size() == 4); - auto git_linux = data[0]; + auto& git_linux = data[0]; CHECK(git_linux.tool == "git"); - CHECK(git_linux.os == "linux"); + CHECK(git_linux.os == ToolOs::Linux); CHECK_FALSE(git_linux.arch.has_value()); - CHECK(git_linux.version == "2.7.4"); + CHECK(git_linux.version.cooked == std::array{2, 7, 4}); + CHECK(git_linux.version.raw == "2.7.4"); CHECK(git_linux.exeRelativePath == "git"); CHECK(git_linux.url == ""); CHECK(git_linux.sha512 == ""); - auto git_arm64 = data[1]; + auto& git_arm64 = data[1]; CHECK(git_arm64.tool == "git"); - CHECK(git_arm64.os == "linux"); + CHECK(git_arm64.os == ToolOs::Linux); CHECK(git_arm64.arch.has_value()); CHECK(*git_arm64.arch.get() == CPUArchitecture::ARM64); - CHECK(git_arm64.version == "2.7.4"); + CHECK(git_linux.version.cooked == std::array{2, 7, 4}); + CHECK(git_linux.version.raw == "2.7.4"); CHECK(git_arm64.exeRelativePath == "git-arm64"); CHECK(git_arm64.url == ""); CHECK(git_arm64.sha512 == ""); - auto nuget_osx = data[2]; + auto& nuget_osx = data[2]; CHECK(nuget_osx.tool == "nuget"); - CHECK(nuget_osx.os == "osx"); + CHECK(nuget_osx.os == ToolOs::Osx); CHECK_FALSE(nuget_osx.arch.has_value()); - CHECK(nuget_osx.version == "5.11.0"); + CHECK(nuget_osx.version.cooked == std::array{5, 11, 0}); + CHECK(nuget_osx.version.raw == "5.11.0"); CHECK(nuget_osx.exeRelativePath == "nuget.exe"); CHECK(nuget_osx.url == "https://dist.nuget.org/win-x86-commandline/v5.11.0/nuget.exe"); CHECK(nuget_osx.sha512 == "06a337c9404dec392709834ef2cdbdce611e104b510ef40201849595d46d242151749aef65bc2d7ce5ade9eb" "fda83b64c03ce14c8f35ca9957a17a8c02b8c4b7"); - auto node_windows = data[3]; + auto& node_windows = data[3]; CHECK(node_windows.tool == "node"); - CHECK(node_windows.os == "windows"); + CHECK(node_windows.os == ToolOs::Windows); CHECK_FALSE(node_windows.arch.has_value()); - CHECK(node_windows.version == "16.12.0"); + CHECK(node_windows.version.cooked == std::array{16, 12, 0}); + CHECK(node_windows.version.raw == "node version 16.12.0.windows.2"); CHECK(node_windows.exeRelativePath == "node-v16.12.0-win-x64\\node.exe"); CHECK(node_windows.url == "https://nodejs.org/dist/v16.12.0/node-v16.12.0-win-x64.7z"); CHECK(node_windows.sha512 == @@ -154,48 +160,52 @@ TEST_CASE ("parse_tool_data", "[tools]") "fb7068ed1f8a7678e446260c3db3537fa888"); CHECK(node_windows.archiveName == "node-v16.12.0-win-x64.7z"); - auto* tooL_git_linux = get_raw_tool_data(data, "git", CPUArchitecture::X64, "linux"); - REQUIRE(tooL_git_linux != nullptr); - CHECK(tooL_git_linux->tool == "git"); - CHECK(tooL_git_linux->os == "linux"); - CHECK_FALSE(tooL_git_linux->arch.has_value()); - CHECK(tooL_git_linux->version == "2.7.4"); - CHECK(tooL_git_linux->exeRelativePath == "git"); - CHECK(tooL_git_linux->url == ""); - CHECK(tooL_git_linux->sha512 == ""); - - auto* tooL_git_arm64 = get_raw_tool_data(data, "git", CPUArchitecture::ARM64, "linux"); - REQUIRE(tooL_git_arm64 != nullptr); - CHECK(tooL_git_arm64->tool == "git"); - CHECK(tooL_git_arm64->os == "linux"); - CHECK(tooL_git_arm64->arch.has_value()); - CHECK(*tooL_git_arm64->arch.get() == CPUArchitecture::ARM64); - CHECK(tooL_git_arm64->version == "2.7.4"); - CHECK(tooL_git_arm64->exeRelativePath == "git-arm64"); - CHECK(tooL_git_arm64->url == ""); - CHECK(tooL_git_arm64->sha512 == ""); - - auto* tooL_nuget_osx = get_raw_tool_data(data, "nuget", CPUArchitecture::X64, "osx"); - REQUIRE(tooL_nuget_osx != nullptr); - CHECK(tooL_nuget_osx->tool == "nuget"); - CHECK(tooL_nuget_osx->os == "osx"); - CHECK_FALSE(tooL_nuget_osx->arch.has_value()); - CHECK(tooL_nuget_osx->version == "5.11.0"); - CHECK(tooL_nuget_osx->exeRelativePath == "nuget.exe"); - CHECK(tooL_nuget_osx->url == "https://dist.nuget.org/win-x86-commandline/v5.11.0/nuget.exe"); - - auto* tooL_node_windows = get_raw_tool_data(data, "node", CPUArchitecture::X64, "windows"); - REQUIRE(tooL_node_windows != nullptr); - CHECK(tooL_node_windows->tool == "node"); - CHECK(tooL_node_windows->os == "windows"); - CHECK_FALSE(tooL_node_windows->arch.has_value()); - CHECK(tooL_node_windows->version == "16.12.0"); - CHECK(tooL_node_windows->exeRelativePath == "node-v16.12.0-win-x64\\node.exe"); - CHECK(tooL_node_windows->url == "https://nodejs.org/dist/v16.12.0/node-v16.12.0-win-x64.7z"); - CHECK(tooL_node_windows->sha512 == + auto* tool_git_linux = get_raw_tool_data(data, "git", CPUArchitecture::X64, ToolOs::Linux); + REQUIRE(tool_git_linux != nullptr); + CHECK(tool_git_linux->tool == "git"); + CHECK(tool_git_linux->os == ToolOs::Linux); + CHECK_FALSE(tool_git_linux->arch.has_value()); + CHECK(tool_git_linux->version.cooked == std::array{2, 7, 4}); + CHECK(tool_git_linux->version.raw == "2.7.4"); + CHECK(tool_git_linux->exeRelativePath == "git"); + CHECK(tool_git_linux->url == ""); + CHECK(tool_git_linux->sha512 == ""); + + auto* tool_git_arm64 = get_raw_tool_data(data, "git", CPUArchitecture::ARM64, ToolOs::Linux); + REQUIRE(tool_git_arm64 != nullptr); + CHECK(tool_git_arm64->tool == "git"); + CHECK(tool_git_arm64->os == ToolOs::Linux); + CHECK(tool_git_arm64->arch.has_value()); + CHECK(*tool_git_arm64->arch.get() == CPUArchitecture::ARM64); + CHECK(tool_git_arm64->version.cooked == std::array{2, 7, 4}); + CHECK(tool_git_arm64->version.raw == "2.7.4"); + CHECK(tool_git_arm64->exeRelativePath == "git-arm64"); + CHECK(tool_git_arm64->url == ""); + CHECK(tool_git_arm64->sha512 == ""); + + auto* tool_nuget_osx = get_raw_tool_data(data, "nuget", CPUArchitecture::X64, ToolOs::Osx); + REQUIRE(tool_nuget_osx != nullptr); + CHECK(tool_nuget_osx->tool == "nuget"); + CHECK(tool_nuget_osx->os == ToolOs::Osx); + CHECK_FALSE(tool_nuget_osx->arch.has_value()); + CHECK(tool_nuget_osx->version.cooked == std::array{5, 11, 0}); + CHECK(tool_nuget_osx->version.raw == "5.11.0"); + CHECK(tool_nuget_osx->exeRelativePath == "nuget.exe"); + CHECK(tool_nuget_osx->url == "https://dist.nuget.org/win-x86-commandline/v5.11.0/nuget.exe"); + + auto* tool_node_windows = get_raw_tool_data(data, "node", CPUArchitecture::X64, ToolOs::Windows); + REQUIRE(tool_node_windows != nullptr); + CHECK(tool_node_windows->tool == "node"); + CHECK(tool_node_windows->os == ToolOs::Windows); + CHECK_FALSE(tool_node_windows->arch.has_value()); + CHECK(tool_node_windows->version.cooked == std::array{16, 12, 0}); + CHECK(tool_node_windows->version.raw == "node version 16.12.0.windows.2"); + CHECK(tool_node_windows->exeRelativePath == "node-v16.12.0-win-x64\\node.exe"); + CHECK(tool_node_windows->url == "https://nodejs.org/dist/v16.12.0/node-v16.12.0-win-x64.7z"); + CHECK(tool_node_windows->sha512 == "0bb793fce8140bd59c17f3ac9661b062eac0f611d704117774f5cb2453d717da94b1e8b17d021d47baff598dc023" "fb7068ed1f8a7678e446260c3db3537fa888"); - CHECK(tooL_node_windows->archiveName == "node-v16.12.0-win-x64.7z"); + CHECK(tool_node_windows->archiveName == "node-v16.12.0-win-x64.7z"); } TEST_CASE ("parse_tool_data errors", "[tools]") @@ -212,9 +222,10 @@ TEST_CASE ("parse_tool_data errors", "[tools]") parse_tool_data(R"({ "schema-version": 1, "tools": [{ "executable": "git.exe" }]})", "missing_required.json"); REQUIRE(!missing_required.has_value()); CHECK("missing_required.json: error: $.tools[0] (tool metadata): missing required field 'name' (a string)\n" - "missing_required.json: error: $.tools[0] (tool metadata): missing required field 'os' (a string)\n" - "missing_required.json: error: $.tools[0] (tool metadata): missing required field 'version' (a string)" == - missing_required.error()); + "missing_required.json: error: $.tools[0] (tool metadata): missing required field 'os' (a tool data " + "operating system)\n" + "missing_required.json: error: $.tools[0] (tool metadata): missing required field 'version' (a tool data " + "version)" == missing_required.error()); auto uexpected_field = parse_tool_data(R"( { @@ -231,6 +242,35 @@ TEST_CASE ("parse_tool_data errors", "[tools]") CHECK("uexpected_field.json: error: $.tools[0] (tool metadata): unexpected field 'arc', did you mean 'arch'?" == uexpected_field.error()); + auto invalid_os = parse_tool_data(R"( +{ + "schema-version": 1, + "tools": [{ + "name": "git", + "os": "notanos", + "version": "2.7.4" + }] +})", + "invalid_os.json"); + REQUIRE(!invalid_os.has_value()); + CHECK( + "invalid_os.json: error: $.tools[0].os (a tool data operating system): Invalid tool operating system: notanos. " + "Expected one of: windows, osx, linux, freebsd, openbsd" == invalid_os.error()); + + auto invalid_version = parse_tool_data(R"( +{ + "schema-version": 1, + "tools": [{ + "name": "git", + "os": "windows", + "version": "abc" + }] +})", + "invalid_version.json"); + REQUIRE(!invalid_version.has_value()); + CHECK("invalid_version.json: error: $.tools[0].version (a tool data version): Invalid tool version; expected a " + "string containing a substring of between 1 and 3 numbers separated by dots." == invalid_version.error()); + auto invalid_arch = parse_tool_data(R"( { "schema-version": 1, diff --git a/src/vcpkg/base/json.cpp b/src/vcpkg/base/json.cpp index 767e0683b7..b4066b0688 100644 --- a/src/vcpkg/base/json.cpp +++ b/src/vcpkg/base/json.cpp @@ -1427,7 +1427,7 @@ namespace vcpkg::Json uint64_t get_json_parsing_stats() { return g_json_parsing_stats.load(); } static std::vector invalid_json_fields(const Json::Object& obj, - Span known_fields) noexcept + View known_fields) noexcept { const auto field_is_unknown = [known_fields](StringView sv) { // allow directives @@ -1492,7 +1492,7 @@ namespace vcpkg::Json } void Reader::check_for_unexpected_fields(const Object& obj, - View valid_fields, + View valid_fields, const LocalizedString& type_name) { if (valid_fields.size() == 0) diff --git a/src/vcpkg/base/strings.cpp b/src/vcpkg/base/strings.cpp index 34633102c7..16d6a686b3 100644 --- a/src/vcpkg/base/strings.cpp +++ b/src/vcpkg/base/strings.cpp @@ -173,7 +173,7 @@ bool Strings::case_insensitive_ascii_contains(StringView s, StringView pattern) return case_insensitive_ascii_search(s, pattern) != s.end(); } -bool Strings::case_insensitive_ascii_equals(StringView left, StringView right) +bool Strings::case_insensitive_ascii_equals(StringView left, StringView right) noexcept { return std::equal(left.begin(), left.end(), right.begin(), right.end(), icase_eq); } diff --git a/src/vcpkg/base/system.cpp b/src/vcpkg/base/system.cpp index d0a76f1ec1..7592d18ed0 100644 --- a/src/vcpkg/base/system.cpp +++ b/src/vcpkg/base/system.cpp @@ -141,6 +141,7 @@ namespace CPUArchitecture arch; }; + // keep this in sync with vcpkg-tools.schema.json static constexpr CPUArchitectureEntry cpu_architecture_table[] = { {"x86", CPUArchitecture::X86}, {"x64", CPUArchitecture::X64}, @@ -169,7 +170,7 @@ namespace vcpkg #endif // ^^^ !_WIN32 } - Optional to_cpu_architecture(StringView arch) + Optional to_cpu_architecture(StringView arch) noexcept { for (auto&& entry : cpu_architecture_table) { @@ -182,7 +183,7 @@ namespace vcpkg return nullopt; } - ZStringView to_zstring_view(CPUArchitecture arch) noexcept + StringLiteral to_string_literal(CPUArchitecture arch) noexcept { for (auto&& entry : cpu_architecture_table) { @@ -639,8 +640,7 @@ namespace vcpkg case CPUArchitecture::ARM: value = L"ARM"; break; case CPUArchitecture::ARM64: value = L"ARM64"; break; default: - Checks::msg_exit_with_error( - VCPKG_LINE_INFO, msgUnexpectedWindowsArchitecture, msg::actual = to_zstring_view(proc)); + Checks::msg_exit_with_error(VCPKG_LINE_INFO, msgUnexpectedWindowsArchitecture, msg::actual = proc); break; } diff --git a/src/vcpkg/commands.build.cpp b/src/vcpkg/commands.build.cpp index ac1b533fb8..63b344e610 100644 --- a/src/vcpkg/commands.build.cpp +++ b/src/vcpkg/commands.build.cpp @@ -1638,7 +1638,7 @@ namespace vcpkg fmt::format_to(std::back_inserter(issue_body), "Package: {}\n\n**Host Environment**\n\n- Host: {}-{}\n", action.display_name(), - to_zstring_view(get_host_processor()), + get_host_processor(), get_host_os_name()); if (const auto* abi_info = action.abi_info.get()) diff --git a/src/vcpkg/commands.install.cpp b/src/vcpkg/commands.install.cpp index 5c1abf9c30..037d6742f2 100644 --- a/src/vcpkg/commands.install.cpp +++ b/src/vcpkg/commands.install.cpp @@ -1316,9 +1316,7 @@ namespace vcpkg const auto vs_prompt = maybe_vs_prompt.value_or_exit(VCPKG_LINE_INFO); if (common_arch != vs_prompt) { - const auto vs_prompt_view = to_zstring_view(vs_prompt); - msg::println_warning( - msgVcpkgInVsPrompt, msg::value = vs_prompt_view, msg::triplet = common_triplet); + msg::println_warning(msgVcpkgInVsPrompt, msg::value = vs_prompt, msg::triplet = common_triplet); } } } diff --git a/src/vcpkg/configuration.cpp b/src/vcpkg/configuration.cpp index 9aa32cd370..8f48babe18 100644 --- a/src/vcpkg/configuration.cpp +++ b/src/vcpkg/configuration.cpp @@ -99,7 +99,7 @@ namespace struct RegistryConfigDeserializer final : Json::IDeserializer { virtual LocalizedString type_name() const override { return msg::format(msgARegistry); } - virtual View valid_fields() const override; + virtual View valid_fields() const noexcept override; virtual Optional visit_null(Json::Reader&) const override; virtual Optional visit_object(Json::Reader&, const Json::Object&) const override; @@ -147,7 +147,7 @@ namespace struct RegistryDeserializer final : Json::IDeserializer { virtual LocalizedString type_name() const override { return msg::format(msgARegistry); } - virtual View valid_fields() const override; + virtual View valid_fields() const noexcept override; virtual Optional visit_object(Json::Reader&, const Json::Object&) const override; @@ -164,9 +164,9 @@ namespace const RegistriesArrayDeserializer RegistriesArrayDeserializer::instance; - View RegistryConfigDeserializer::valid_fields() const + View RegistryConfigDeserializer::valid_fields() const noexcept { - static constexpr StringView t[] = { + static constexpr StringLiteral t[] = { JsonIdKind, JsonIdBaseline, JsonIdPath, @@ -177,20 +177,20 @@ namespace }; return t; } - static constexpr StringView valid_builtin_fields[] = { + static constexpr StringLiteral valid_builtin_fields[] = { JsonIdKind, JsonIdBaseline, JsonIdPackages, }; - static constexpr StringView valid_filesystem_fields[] = { + static constexpr StringLiteral valid_filesystem_fields[] = { JsonIdKind, JsonIdBaseline, JsonIdPath, JsonIdPackages, }; - static constexpr StringView valid_git_fields[] = { + static constexpr StringLiteral valid_git_fields[] = { JsonIdKind, JsonIdBaseline, JsonIdRepository, @@ -198,7 +198,7 @@ namespace JsonIdPackages, }; - static constexpr StringView valid_artifact_fields[] = { + static constexpr StringLiteral valid_artifact_fields[] = { JsonIdKind, JsonIdName, JsonIdLocation, @@ -283,9 +283,9 @@ namespace return std::move(res); // gcc-7 bug workaround redundant move } - View RegistryDeserializer::valid_fields() const + View RegistryDeserializer::valid_fields() const noexcept { - static constexpr StringView t[] = { + static constexpr StringLiteral t[] = { JsonIdKind, JsonIdBaseline, JsonIdPath, diff --git a/src/vcpkg/registries.cpp b/src/vcpkg/registries.cpp index c77c0f75dc..2bac907db7 100644 --- a/src/vcpkg/registries.cpp +++ b/src/vcpkg/registries.cpp @@ -46,17 +46,15 @@ namespace struct GitVersionDbEntryDeserializer final : Json::IDeserializer { LocalizedString type_name() const override; - View valid_fields() const override; + View valid_fields() const noexcept override; Optional visit_object(Json::Reader& r, const Json::Object& obj) const override; }; LocalizedString GitVersionDbEntryDeserializer::type_name() const { return msg::format(msgAVersionDatabaseEntry); } - View GitVersionDbEntryDeserializer::valid_fields() const + View GitVersionDbEntryDeserializer::valid_fields() const noexcept { - static constexpr StringView u_git[] = {JsonIdGitTree}; - static const auto t_git = vcpkg::Util::Vectors::concat(schemed_deserializer_fields(), u_git); - - return t_git; + static constexpr StringLiteral fields[] = {VCPKG_SCHEMED_DESERIALIZER_FIELDS, JsonIdGitTree}; + return fields; } Optional GitVersionDbEntryDeserializer::visit_object(Json::Reader& r, @@ -88,7 +86,7 @@ namespace struct FilesystemVersionDbEntryDeserializer final : Json::IDeserializer { LocalizedString type_name() const override; - View valid_fields() const override; + View valid_fields() const noexcept override; Optional visit_object(Json::Reader& r, const Json::Object& obj) const override; FilesystemVersionDbEntryDeserializer(const Path& root) : registry_root(root) { } @@ -100,11 +98,10 @@ namespace { return msg::format(msgAVersionDatabaseEntry); } - View FilesystemVersionDbEntryDeserializer::valid_fields() const + View FilesystemVersionDbEntryDeserializer::valid_fields() const noexcept { - static constexpr StringView u_path[] = {JsonIdPath}; - static const auto t_path = vcpkg::Util::Vectors::concat(schemed_deserializer_fields(), u_path); - return t_path; + static constexpr StringLiteral fields[] = {VCPKG_SCHEMED_DESERIALIZER_FIELDS, JsonIdPath}; + return fields; } Optional FilesystemVersionDbEntryDeserializer::visit_object(Json::Reader& r, diff --git a/src/vcpkg/sourceparagraph.cpp b/src/vcpkg/sourceparagraph.cpp index a250c4c4b6..3f17507780 100644 --- a/src/vcpkg/sourceparagraph.cpp +++ b/src/vcpkg/sourceparagraph.cpp @@ -516,9 +516,9 @@ namespace vcpkg { LocalizedString type_name() const override { return msg::format(msgADefaultFeature); } - Span valid_fields() const override + View valid_fields() const noexcept override { - static const StringView t[] = { + static const StringLiteral t[] = { JsonIdName, JsonIdPlatform, }; @@ -580,9 +580,9 @@ namespace vcpkg { LocalizedString type_name() const override { return msg::format(msgADependencyFeature); } - Span valid_fields() const override + View valid_fields() const noexcept override { - static const StringView t[] = { + static const StringLiteral t[] = { JsonIdName, JsonIdPlatform, }; @@ -620,9 +620,9 @@ namespace vcpkg { virtual LocalizedString type_name() const override { return msg::format(msgADependency); } - virtual Span valid_fields() const override + virtual View valid_fields() const noexcept override { - static constexpr StringView t[] = { + static constexpr StringLiteral t[] = { JsonIdName, JsonIdHost, JsonIdFeatures, @@ -701,11 +701,10 @@ namespace vcpkg struct DependencyOverrideDeserializer final : Json::IDeserializer { virtual LocalizedString type_name() const override { return msg::format(msgAnOverride); } - virtual Span valid_fields() const override + virtual View valid_fields() const noexcept override { - static constexpr StringView u[] = {JsonIdName}; - static const auto t = Util::Vectors::concat(schemed_deserializer_fields(), u); - return t; + static constexpr StringLiteral fields[] = {VCPKG_SCHEMED_DESERIALIZER_FIELDS, JsonIdName}; + return fields; } virtual Optional visit_object(Json::Reader& r, const Json::Object& obj) const override @@ -1004,9 +1003,9 @@ namespace vcpkg { virtual LocalizedString type_name() const override { return msg::format(msgAFeature); } - virtual Span valid_fields() const override + virtual View valid_fields() const noexcept override { - static constexpr StringView t[] = {JsonIdDescription, JsonIdDependencies, JsonIdSupports, JsonIdLicense}; + static constexpr StringLiteral t[] = {JsonIdDescription, JsonIdDependencies, JsonIdSupports, JsonIdLicense}; return t; } @@ -1052,8 +1051,6 @@ namespace vcpkg { virtual LocalizedString type_name() const override { return msg::format(msgASetOfFeatures); } - virtual Span valid_fields() const override { return {}; } - virtual Optional visit_object(Json::Reader& r, const Json::Object& obj) const override { FeaturesObject res; @@ -1122,9 +1119,10 @@ namespace vcpkg { virtual LocalizedString type_name() const override { return msg::format(msgAManifest); } - virtual Span valid_fields() const override + virtual View valid_fields() const noexcept override { - static constexpr StringView u[] = { + static constexpr StringLiteral fields[] = { + VCPKG_SCHEMED_DESERIALIZER_FIELDS, JsonIdName, JsonIdMaintainers, JsonIdContacts, @@ -1141,9 +1139,8 @@ namespace vcpkg JsonIdBuiltinBaseline, JsonIdVcpkgConfiguration, }; - static const auto t = Util::Vectors::concat(schemed_deserializer_fields(), u); - return t; + return fields; } vcpkg::Optional> visit_object_common( diff --git a/src/vcpkg/tools.cpp b/src/vcpkg/tools.cpp index e2dbbc5bbd..3e60ab3d9d 100644 --- a/src/vcpkg/tools.cpp +++ b/src/vcpkg/tools.cpp @@ -21,9 +21,30 @@ #include +#include + +namespace +{ + using namespace vcpkg; + struct ToolOsEntry + { + StringLiteral name; + ToolOs os; + }; + + // keep this in sync with vcpkg-tools.schema.json + static constexpr ToolOsEntry all_tool_oses[] = { + {"windows", ToolOs::Windows}, + {"osx", ToolOs::Osx}, + {"linux", ToolOs::Linux}, + {"freebsd", ToolOs::FreeBsd}, + {"openbsd", ToolOs::OpenBsd}, + }; +} + namespace vcpkg { - // /\d+\.\d+(\.\d+)?/ + // /\d+(\.\d+(\.\d+)?)?/ Optional> parse_tool_version_string(StringView string_version) { // first, find the beginning of the version @@ -63,6 +84,38 @@ namespace vcpkg return std::array{*d1.get(), *d2.get(), *d3.get()}; } + Optional to_tool_os(StringView os) noexcept + { + for (auto&& entry : all_tool_oses) + { + if (os == entry.name) + { + return entry.os; + } + } + + return nullopt; + } + + StringLiteral to_string_literal(ToolOs os) noexcept + { + for (auto&& entry : all_tool_oses) + { + if (os == entry.os) + { + return entry.name; + } + } + + Checks::unreachable(VCPKG_LINE_INFO, "Unexpected ToolOs"); + } + + LocalizedString all_comma_separated_tool_oses() + { + return LocalizedString::from_raw( + Strings::join(", ", all_tool_oses, [](const ToolOsEntry& entry) { return entry.name; })); + } + ExpectedL> parse_tool_data(StringView contents, StringView origin) { return Json::parse_object(contents, origin) @@ -88,7 +141,7 @@ namespace vcpkg const ToolDataEntry* get_raw_tool_data(const std::vector& tool_data_table, StringView toolname, const CPUArchitecture arch, - StringView os) + const ToolOs os) { const ToolDataEntry* default_tool = nullptr; for (auto&& tool_candidate : tool_data_table) @@ -115,15 +168,15 @@ namespace vcpkg { auto hp = get_host_processor(); #if defined(_WIN32) - auto data = get_raw_tool_data(tool_data_table, tool, hp, "windows"); + auto data = get_raw_tool_data(tool_data_table, tool, hp, ToolOs::Windows); #elif defined(__APPLE__) - auto data = get_raw_tool_data(tool_data_table, tool, hp, "osx"); + auto data = get_raw_tool_data(tool_data_table, tool, hp, ToolOs::Osx); #elif defined(__linux__) - auto data = get_raw_tool_data(tool_data_table, tool, hp, "linux"); + auto data = get_raw_tool_data(tool_data_table, tool, hp, ToolOs::Linux); #elif defined(__FreeBSD__) - auto data = get_raw_tool_data(tool_data_table, tool, hp, "freebsd"); + auto data = get_raw_tool_data(tool_data_table, tool, hp, ToolOs::FreeBsd); #elif defined(__OpenBSD__) - auto data = get_raw_tool_data(tool_data_table, tool, hp, "openbsd"); + auto data = get_raw_tool_data(tool_data_table, tool, hp, ToolOs::OpenBsd); #else return nullopt; #endif @@ -131,14 +184,8 @@ namespace vcpkg { return nullopt; } - const Optional> version = parse_tool_version_string(data->version); - Checks::msg_check_exit(VCPKG_LINE_INFO, - version.has_value(), - msgFailedToParseVersionXML, - msg::tool_name = tool, - msg::version = data->version); - - Path tool_dir_name = fmt::format("{}-{}-{}", tool, data->version, data->os); + + Path tool_dir_name = fmt::format("{}-{}-{}", tool, data->version.raw, data->os); Path download_subpath; if (!data->archiveName.empty()) { @@ -150,7 +197,7 @@ namespace vcpkg } return ToolData{tool.to_string(), - *version.get(), + data->version.cooked, data->exeRelativePath, data->url, download_subpath, @@ -1048,36 +1095,36 @@ namespace vcpkg { virtual LocalizedString type_name() const override { return msg::format(msgAToolDataObject); } - virtual View valid_fields() const override + virtual View valid_fields() const noexcept override { - static const StringView valid_fields[] = { - "name", - "os", - "version", - "arch", - "executable", - "url", - "sha512", - "archive", + static const StringLiteral fields[] = { + JsonIdName, + JsonIdOS, + JsonIdVersion, + JsonIdArch, + JsonIdExecutable, + JsonIdUrl, + JsonIdSha512, + JsonIdArchive, }; - return valid_fields; + return fields; } virtual Optional visit_object(Json::Reader& r, const Json::Object& obj) const override { ToolDataEntry value; - r.required_object_field(type_name(), obj, "name", value.tool, Json::UntypedStringDeserializer::instance); - r.required_object_field(type_name(), obj, "os", value.os, Json::UntypedStringDeserializer::instance); r.required_object_field( - type_name(), obj, "version", value.version, Json::UntypedStringDeserializer::instance); + type_name(), obj, JsonIdName, value.tool, Json::UntypedStringDeserializer::instance); + r.required_object_field(type_name(), obj, JsonIdOS, value.os, ToolOsDeserializer::instance); + r.required_object_field(type_name(), obj, JsonIdVersion, value.version, ToolVersionDeserializer::instance); - r.optional_object_field(obj, "arch", value.arch, Json::ArchitectureDeserializer::instance); + r.optional_object_field(obj, JsonIdArch, value.arch, Json::ArchitectureDeserializer::instance); r.optional_object_field( - obj, "executable", value.exeRelativePath, Json::UntypedStringDeserializer::instance); - r.optional_object_field(obj, "url", value.url, Json::UntypedStringDeserializer::instance); - r.optional_object_field(obj, "sha512", value.sha512, Json::Sha512Deserializer::instance); - r.optional_object_field(obj, "archive", value.archiveName, Json::UntypedStringDeserializer::instance); + obj, JsonIdExecutable, value.exeRelativePath, Json::UntypedStringDeserializer::instance); + r.optional_object_field(obj, JsonIdUrl, value.url, Json::UntypedStringDeserializer::instance); + r.optional_object_field(obj, JsonIdSha512, value.sha512, Json::Sha512Deserializer::instance); + r.optional_object_field(obj, JsonIdArchive, value.archiveName, Json::UntypedStringDeserializer::instance); return value; } @@ -1095,9 +1142,9 @@ namespace vcpkg LocalizedString ToolDataFileDeserializer::type_name() const { return msg::format(msgAToolDataFile); } - View ToolDataFileDeserializer::valid_fields() const + View ToolDataFileDeserializer::valid_fields() const noexcept { - static const StringView valid_fields[] = {"schema-version", "tools"}; + static constexpr StringLiteral valid_fields[] = {JsonIdSchemaVersion, JsonIdTools}; return valid_fields; } @@ -1106,19 +1153,55 @@ namespace vcpkg { int schema_version = -1; r.required_object_field( - type_name(), obj, "schema-version", schema_version, Json::NaturalNumberDeserializer::instance); + type_name(), obj, JsonIdSchemaVersion, schema_version, Json::NaturalNumberDeserializer::instance); - if (schema_version != 1) + std::vector value; + if (schema_version == 1) + { + r.required_object_field(type_name(), obj, JsonIdTools, value, ToolDataArrayDeserializer::instance); + } + else { r.add_generic_error(type_name(), msg::format(msgToolDataFileSchemaVersionNotSupported, msg::version = schema_version)); - return nullopt; } - std::vector value; - r.required_object_field(type_name(), obj, "tools", value, ToolDataArrayDeserializer::instance); return value; } const ToolDataFileDeserializer ToolDataFileDeserializer::instance; + + LocalizedString ToolOsDeserializer::type_name() const { return msg::format(msgAToolDataOS); } + + Optional ToolOsDeserializer::visit_string(Json::Reader& r, StringView str) const + { + auto maybe_tool_os = to_tool_os(str); + if (auto tool_os = maybe_tool_os.get()) + { + return *tool_os; + } + + r.add_generic_error( + type_name(), + msg::format(msgInvalidToolOSValue, msg::value = str, msg::expected = all_comma_separated_tool_oses())); + return ToolOs::Windows; + } + + const ToolOsDeserializer ToolOsDeserializer::instance; + + LocalizedString ToolVersionDeserializer::type_name() const { return msg::format(msgAToolDataVersion); } + + Optional ToolVersionDeserializer::visit_string(Json::Reader& r, StringView str) const + { + auto maybe_parsed = parse_tool_version_string(str); + if (auto parsed = maybe_parsed.get()) + { + return ToolVersion{*parsed, str.to_string()}; + } + + r.add_generic_error(type_name(), msg::format(msgInvalidToolVersion)); + return ToolVersion{}; + } + + const ToolVersionDeserializer ToolVersionDeserializer::instance; } diff --git a/src/vcpkg/triplet.cpp b/src/vcpkg/triplet.cpp index 21e597338c..efc3aeebaf 100644 --- a/src/vcpkg/triplet.cpp +++ b/src/vcpkg/triplet.cpp @@ -59,8 +59,7 @@ namespace vcpkg static std::string system_triplet_canonical_name() { - auto host_proc = get_host_processor(); - return fmt::format("{}-{}", to_zstring_view(host_proc), get_host_os_name()); + return fmt::format("{}-{}", get_host_processor(), get_host_os_name()); } Triplet default_triplet(const VcpkgCmdArguments& args, const TripletDatabase& database) diff --git a/src/vcpkg/versiondeserializers.cpp b/src/vcpkg/versiondeserializers.cpp index b14cde2c74..32c3be8720 100644 --- a/src/vcpkg/versiondeserializers.cpp +++ b/src/vcpkg/versiondeserializers.cpp @@ -261,13 +261,6 @@ namespace vcpkg return Version(std::move(proto_version.first), port_version); } - View schemed_deserializer_fields() - { - static constexpr StringView t[] = { - JsonIdVersion, JsonIdVersionSemver, JsonIdVersionString, JsonIdVersionDate, JsonIdPortVersion}; - return t; - } - void serialize_schemed_version(Json::Object& out_obj, VersionScheme scheme, const Version& version) { auto version_field = [](VersionScheme version_scheme) { From 7a83a7d204fc343a59325d5a627ab27c54b842de Mon Sep 17 00:00:00 2001 From: Billy Robert O'Neal III Date: Thu, 2 Jan 2025 21:23:25 -0800 Subject: [PATCH 29/30] Update scripts SHA again with Ninja arch tagging. --- vcpkg-init/vcpkg-scripts-sha.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vcpkg-init/vcpkg-scripts-sha.txt b/vcpkg-init/vcpkg-scripts-sha.txt index 126f8e6daa..f30e9b1027 100644 --- a/vcpkg-init/vcpkg-scripts-sha.txt +++ b/vcpkg-init/vcpkg-scripts-sha.txt @@ -1 +1 @@ -be8a239dd4fc329ea3f9377c42b2cb5a5d7d75f3 +12393e114e2acb75ba14e52ace6e90c4c8ab2d04 From bfc856bdef88d97f2ff4b400e973484c592e3909 Mon Sep 17 00:00:00 2001 From: Billy Robert O'Neal III Date: Thu, 2 Jan 2025 21:27:55 -0800 Subject: [PATCH 30/30] Remove no longer needed . --- src/vcpkg/tools.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/vcpkg/tools.cpp b/src/vcpkg/tools.cpp index 3e60ab3d9d..9836d269d5 100644 --- a/src/vcpkg/tools.cpp +++ b/src/vcpkg/tools.cpp @@ -19,8 +19,6 @@ #include #include -#include - #include namespace