diff options
| author | ras0219 <533828+ras0219@users.noreply.github.com> | 2020-12-10 20:54:34 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-12-10 20:54:34 -0800 |
| commit | c2329ab26a6e9e06da101d8541c393c102ba6c8c (patch) | |
| tree | 762cd489a062a85b218e67e4256edef22daec934 /toolsrc | |
| parent | c30903782c88967652178486a5f3e490fb2e8143 (diff) | |
| download | vcpkg-c2329ab26a6e9e06da101d8541c393c102ba6c8c.tar.gz vcpkg-c2329ab26a6e9e06da101d8541c393c102ba6c8c.zip | |
[vcpkg] Improve error messages for incomplete Mono (#14948)
* [vcpkg] Improve error messages for incomplete Mono
* [vcpkg] Add mono upgrade notice for Ubuntu 18.04 users
* [vcpkg] Fix always failing to check CMake version due to preferring 'error' constructor in ExpectedS
* [vcpkg] Eagerly display the 'Ubuntu needs new mono' message to avoid users needing to install it twice
Co-authored-by: Robert Schumacher <roschuma@microsoft.com>
Diffstat (limited to 'toolsrc')
| -rw-r--r-- | toolsrc/include/vcpkg/base/expected.h | 5 | ||||
| -rw-r--r-- | toolsrc/src/vcpkg/tools.cpp | 111 |
2 files changed, 78 insertions, 38 deletions
diff --git a/toolsrc/include/vcpkg/base/expected.h b/toolsrc/include/vcpkg/base/expected.h index 12bb64727..13e7b4bcb 100644 --- a/toolsrc/include/vcpkg/base/expected.h +++ b/toolsrc/include/vcpkg/base/expected.h @@ -110,7 +110,10 @@ namespace vcpkg // Constructors are intentionally implicit ExpectedT(const S& s, ExpectedRightTag = {}) : m_s(s) { } - ExpectedT(S&& s, ExpectedRightTag = {}) : m_s(std::move(s)) { } + template<class = std::enable_if<!std::is_reference<S>::value>> + ExpectedT(S&& s, ExpectedRightTag = {}) : m_s(std::move(s)) + { + } ExpectedT(const T& t, ExpectedLeftTag = {}) : m_t(t) { } template<class = std::enable_if<!std::is_reference<T>::value>> diff --git a/toolsrc/src/vcpkg/tools.cpp b/toolsrc/src/vcpkg/tools.cpp index 69ad05d38..0b82e7780 100644 --- a/toolsrc/src/vcpkg/tools.cpp +++ b/toolsrc/src/vcpkg/tools.cpp @@ -83,12 +83,23 @@ namespace vcpkg const bool has_tool_entry = std::regex_search(XML.cbegin(), XML.cend(), match_tool_entry, tool_regex); if (!has_tool_entry) { + StringLiteral add_info = ""; + if (tool == "mono") + { +#if defined(__APPLE__) + add_info = " (brew install mono)"; +#else + add_info = " (e.g. sudo apt install mono-complete). Ubuntu 18.04 users may " + "need a newer version of mono, available at https://www.mono-project.com/download/stable/"; +#endif + } return Strings::format("Could not automatically acquire %s because there is no entry in %s for os=%s. You " - "may be able to install %s via your system package manager.", + "may be able to install %s via your system package manager%s.", tool, fs::u8string(XML_PATH), OS_STRING, - tool); + tool, + add_info); } const std::string tool_data = @@ -139,7 +150,7 @@ namespace vcpkg virtual std::array<int, 3> default_min_version() const = 0; virtual void add_special_paths(std::vector<fs::path>& out_candidate_paths) const { (void)out_candidate_paths; } - virtual Optional<std::string> get_version(const VcpkgPaths& paths, const fs::path& path_to_exe) const = 0; + virtual ExpectedS<std::string> get_version(const VcpkgPaths& paths, const fs::path& path_to_exe) const = 0; }; static Optional<PathAndVersion> find_first_with_sufficient_version(const VcpkgPaths& paths, @@ -222,10 +233,9 @@ namespace vcpkg const ToolProvider& tool_provider, const ToolData& tool_data) { - const auto downloaded_path = fetch_tool(paths, tool_provider.tool_data_name(), tool_data); - const auto downloaded_version = - tool_provider.get_version(paths, downloaded_path).value_or_exit(VCPKG_LINE_INFO); - return {downloaded_path, downloaded_version}; + auto downloaded_path = fetch_tool(paths, tool_provider.tool_data_name(), tool_data); + auto downloaded_version = tool_provider.get_version(paths, downloaded_path).value_or_exit(VCPKG_LINE_INFO); + return {std::move(downloaded_path), std::move(downloaded_version)}; } static PathAndVersion get_path(const VcpkgPaths& paths, const ToolProvider& tool) @@ -285,13 +295,15 @@ namespace vcpkg (void)out_candidate_paths; #endif } - virtual Optional<std::string> get_version(const VcpkgPaths&, const fs::path& path_to_exe) const override + virtual ExpectedS<std::string> get_version(const VcpkgPaths&, const fs::path& path_to_exe) const override { const std::string cmd = Strings::format(R"("%s" --version)", fs::u8string(path_to_exe)); - const auto rc = System::cmd_execute_and_capture_output(cmd); + auto rc = System::cmd_execute_and_capture_output(cmd); if (rc.exit_code != 0) { - return nullopt; + return {Strings::concat( + std::move(rc.output), "\n\nFailed to get version of ", fs::u8string(path_to_exe), "\n"), + expected_right_tag}; } /* Sample output: @@ -299,7 +311,8 @@ cmake version 3.10.2 CMake suite maintained and supported by Kitware (kitware.com/cmake). */ - return StringView::find_exactly_one_enclosed(rc.output, "cmake version ", "\n").to_string(); + return {StringView::find_exactly_one_enclosed(rc.output, "cmake version ", "\n").to_string(), + expected_left_tag}; } }; @@ -311,19 +324,21 @@ CMake suite maintained and supported by Kitware (kitware.com/cmake). virtual const std::string& exe_stem() const override { return m_exe; } virtual std::array<int, 3> default_min_version() const override { return {3, 5, 1}; } - virtual Optional<std::string> get_version(const VcpkgPaths&, const fs::path& path_to_exe) const override + virtual ExpectedS<std::string> get_version(const VcpkgPaths&, const fs::path& path_to_exe) const override { const std::string cmd = Strings::format(R"("%s" --version)", fs::u8string(path_to_exe)); - const auto rc = System::cmd_execute_and_capture_output(cmd); + auto rc = System::cmd_execute_and_capture_output(cmd); if (rc.exit_code != 0) { - return nullopt; + return {Strings::concat( + std::move(rc.output), "\n\nFailed to get version of ", fs::u8string(path_to_exe), "\n"), + expected_right_tag}; } /* Sample output: 1.8.2 */ - return rc.output; + return {std::move(rc.output), expected_left_tag}; } }; @@ -335,7 +350,7 @@ CMake suite maintained and supported by Kitware (kitware.com/cmake). virtual const std::string& exe_stem() const override { return m_exe; } virtual std::array<int, 3> default_min_version() const override { return {4, 6, 2}; } - virtual Optional<std::string> get_version(const VcpkgPaths& paths, const fs::path& path_to_exe) const override + virtual ExpectedS<std::string> get_version(const VcpkgPaths& paths, const fs::path& path_to_exe) const override { System::CmdLineBuilder cmd; #ifndef _WIN32 @@ -344,10 +359,23 @@ CMake suite maintained and supported by Kitware (kitware.com/cmake). (void)paths; #endif cmd.path_arg(path_to_exe); - const auto rc = System::cmd_execute_and_capture_output(cmd.extract()); + auto rc = System::cmd_execute_and_capture_output(cmd.extract()); if (rc.exit_code != 0) { - return nullopt; +#ifndef _WIN32 + return {Strings::concat( + std::move(rc.output), + "\n\nFailed to get version of ", + fs::u8string(path_to_exe), + "\nThis may be caused by an incomplete mono installation. Full mono is " + "available on some systems via `sudo apt install mono-complete`. Ubuntu 18.04 users may " + "need a newer version of mono, available at https://www.mono-project.com/download/stable/"), + expected_right_tag}; +#else + return {Strings::concat( + std::move(rc.output), "\n\nFailed to get version of ", fs::u8string(path_to_exe), "\n"), + expected_right_tag}; +#endif } /* Sample output: @@ -357,7 +385,8 @@ Type 'NuGet help <command>' for help on a specific command. [[[List of available commands follows]]] */ - return StringView::find_exactly_one_enclosed(rc.output, "NuGet Version: ", "\n").to_string(); + return {StringView::find_exactly_one_enclosed(rc.output, "NuGet Version: ", "\n").to_string(), + expected_left_tag}; } }; @@ -383,13 +412,15 @@ Type 'NuGet help <command>' for help on a specific command. #endif } - virtual Optional<std::string> get_version(const VcpkgPaths&, const fs::path& path_to_exe) const override + virtual ExpectedS<std::string> get_version(const VcpkgPaths&, const fs::path& path_to_exe) const override { const std::string cmd = Strings::format(R"("%s" --version)", fs::u8string(path_to_exe)); - const auto rc = System::cmd_execute_and_capture_output(cmd); + auto rc = System::cmd_execute_and_capture_output(cmd); if (rc.exit_code != 0) { - return nullopt; + return {Strings::concat( + std::move(rc.output), "\n\nFailed to get version of ", fs::u8string(path_to_exe), "\n"), + expected_right_tag}; } /* Sample output: @@ -398,7 +429,7 @@ git version 2.17.1.windows.2 const auto idx = rc.output.find("git version "); Checks::check_exit( VCPKG_LINE_INFO, idx != std::string::npos, "Unexpected format of git version string: %s", rc.output); - return rc.output.substr(idx); + return {rc.output.substr(idx), expected_left_tag}; } }; @@ -410,13 +441,15 @@ git version 2.17.1.windows.2 virtual const std::string& exe_stem() const override { return m_exe; } virtual std::array<int, 3> default_min_version() const override { return {0, 0, 0}; } - virtual Optional<std::string> get_version(const VcpkgPaths&, const fs::path& path_to_exe) const override + virtual ExpectedS<std::string> get_version(const VcpkgPaths&, const fs::path& path_to_exe) const override { - const auto rc = System::cmd_execute_and_capture_output( + auto rc = System::cmd_execute_and_capture_output( System::CmdLineBuilder().path_arg(path_to_exe).string_arg("--version").extract()); if (rc.exit_code != 0) { - return nullopt; + return {Strings::concat( + std::move(rc.output), "\n\nFailed to get version of ", fs::u8string(path_to_exe), "\n"), + expected_right_tag}; } /* Sample output: @@ -425,7 +458,7 @@ Mono JIT compiler version 6.8.0.105 (Debian 6.8.0.105+dfsg-2 Wed Feb 26 23:23:50 const auto idx = rc.output.find("Mono JIT compiler version "); Checks::check_exit( VCPKG_LINE_INFO, idx != std::string::npos, "Unexpected format of mono version string: %s", rc.output); - return rc.output.substr(idx); + return {rc.output.substr(idx), expected_left_tag}; } }; @@ -450,19 +483,21 @@ Mono JIT compiler version 6.8.0.105 (Debian 6.8.0.105+dfsg-2 Wed Feb 26 23:23:50 // "Qt" / "QtIFW-3.1.0" / "bin" / "installerbase.exe"); } - virtual Optional<std::string> get_version(const VcpkgPaths&, const fs::path& path_to_exe) const override + virtual ExpectedS<std::string> get_version(const VcpkgPaths&, const fs::path& path_to_exe) const override { const std::string cmd = Strings::format(R"("%s" --framework-version)", fs::u8string(path_to_exe)); - const auto rc = System::cmd_execute_and_capture_output(cmd); + auto rc = System::cmd_execute_and_capture_output(cmd); if (rc.exit_code != 0) { - return nullopt; + return {Strings::concat( + std::move(rc.output), "\n\nFailed to get version of ", fs::u8string(path_to_exe), "\n"), + expected_right_tag}; } /* Sample output: 3.1.81 */ - return rc.output; + return {std::move(rc.output), expected_left_tag}; } }; @@ -475,17 +510,19 @@ Mono JIT compiler version 6.8.0.105 (Debian 6.8.0.105+dfsg-2 Wed Feb 26 23:23:50 virtual const std::string& exe_stem() const override { return m_exe; } virtual std::array<int, 3> default_min_version() const override { return {7, 0, 3}; } - virtual Optional<std::string> get_version(const VcpkgPaths&, const fs::path& path_to_exe) const override + virtual ExpectedS<std::string> get_version(const VcpkgPaths&, const fs::path& path_to_exe) const override { - const auto pwsh_invocation = System::cmd_execute_and_capture_output( + auto rc = System::cmd_execute_and_capture_output( System::CmdLineBuilder().path_arg(path_to_exe).string_arg("--version").extract()); - if (pwsh_invocation.exit_code != 0) + if (rc.exit_code != 0) { - return nullopt; + return {Strings::concat( + std::move(rc.output), "\n\nFailed to get version of ", fs::u8string(path_to_exe), "\n"), + expected_right_tag}; } // Sample output: PowerShell 7.0.3\r\n - auto output = std::move(pwsh_invocation.output); + auto output = std::move(rc.output); if (!Strings::starts_with(output, "PowerShell ")) { Checks::exit_with_message( @@ -493,7 +530,7 @@ Mono JIT compiler version 6.8.0.105 (Debian 6.8.0.105+dfsg-2 Wed Feb 26 23:23:50 } output.erase(0, 11); - return Strings::trim(std::move(output)); + return {Strings::trim(std::move(output)), expected_left_tag}; } }; |
