Skip to content

Commit

Permalink
WIP: Auto create issue on install failure
Browse files Browse the repository at this point in the history
  • Loading branch information
autoantwort committed Dec 21, 2021
1 parent 132714c commit 4e897ed
Show file tree
Hide file tree
Showing 7 changed files with 121 additions and 14 deletions.
3 changes: 3 additions & 0 deletions cmake/utilities.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ function(vcpkg_target_add_warning_options TARGET)
target_compile_options(${TARGET} PRIVATE -Werror)
endif()
endif()
if(APPLE)
target_link_libraries(${TARGET} PRIVATE "-framework CoreFoundation" "-framework ApplicationServices")
endif()
endfunction()

function(vcpkg_target_add_sourcelink target)
Expand Down
4 changes: 4 additions & 0 deletions include/vcpkg/base/system.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ namespace vcpkg
const ExpectedS<Path>& get_appdata_local() noexcept;
#endif

void open_in_default_browser(const std::string& url);

Optional<std::string> get_registry_string(void* base_hkey, StringView subkey, StringView valuename);

long get_process_id();
Expand All @@ -39,6 +41,8 @@ namespace vcpkg

CPUArchitecture get_host_processor();

std::string get_host_os_name();

std::vector<CPUArchitecture> get_supported_host_architectures();

const Optional<Path>& get_program_files_32_bit();
Expand Down
8 changes: 8 additions & 0 deletions include/vcpkg/build.h
Original file line number Diff line number Diff line change
Expand Up @@ -247,14 +247,22 @@ namespace vcpkg::Build
struct ExtendedBuildResult
{
ExtendedBuildResult(BuildResult code);
ExtendedBuildResult(BuildResult code, vcpkg::Path stdoutlog, std::vector<std::string>&& error_logs);
ExtendedBuildResult(BuildResult code, std::vector<FeatureSpec>&& unmet_deps);
ExtendedBuildResult(BuildResult code, std::unique_ptr<BinaryControlFile>&& bcf);

BuildResult code;
std::vector<FeatureSpec> unmet_dependencies;
std::unique_ptr<BinaryControlFile> binary_control_file;
vcpkg::Path stdoutlog;
std::vector<std::string> error_logs;
};

std::string create_github_issue(const VcpkgCmdArguments& args,
const ExtendedBuildResult& build_result,
const PackageSpec& spec,
const VcpkgPaths& paths);

ExtendedBuildResult build_package(const VcpkgCmdArguments& args,
const VcpkgPaths& paths,
const Dependencies::InstallPlanAction& config,
Expand Down
31 changes: 31 additions & 0 deletions src/vcpkg/base/system.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#include <ctime>

#if defined(__APPLE__)
#include <ApplicationServices/ApplicationServices.h>
#include <CoreFoundation/CFBundle.h>
#include <sys/sysctl.h>
#endif

Expand Down Expand Up @@ -367,6 +369,35 @@ namespace vcpkg

return nullopt;
}

std::string get_host_os_name()
{
#if defined(_WIN32)
return "windows";
#elif defined(__APPLE__)
return "osx";
#elif defined(__FreeBSD__)
return "freebsd";
#elif defined(__OpenBSD__)
return "openbsd";
#else
return "linux";
#endif
}

void open_in_default_browser(const std::string& url_str)
{
#ifdef __APPLE__
CFURLRef url = CFURLCreateWithBytes(nullptr, // allocator
(UInt8*)url_str.c_str(), // URLBytes
url_str.length(), // length
kCFStringEncodingUTF8, // encoding
nullptr // baseURL
);
LSOpenCFURLRef(url, nullptr);
CFRelease(url);
#endif
}
}

namespace vcpkg::Debug
Expand Down
68 changes: 67 additions & 1 deletion src/vcpkg/build.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -948,7 +948,15 @@ namespace vcpkg::Build
{
metrics->track_property("error", "build failed");
metrics->track_property("build_error", spec_string);
return BuildResult::BUILD_FAILED;
const auto logs = buildpath / "logs.txt";
std::vector<std::string> error_logs;
if (fs.exists(logs, VCPKG_LINE_INFO))
{
error_logs = fs.read_lines(buildpath / "logs.txt", VCPKG_LINE_INFO);
Util::filter(error_logs, [](const auto& line) { return Strings::starts_with(line, "error:"); });
Util::fmap(error_logs, [](const std::string& line) { return line.substr(6); });
}
return {BuildResult::BUILD_FAILED, stdoutlog, std::move(error_logs)};
}
}

Expand Down Expand Up @@ -1327,6 +1335,58 @@ namespace vcpkg::Build
return Strings::format("Error: Building package %s failed with: %s", spec, Build::to_string(build_result));
}

std::string create_github_issue(const VcpkgCmdArguments& args,
const ExtendedBuildResult& build_result,
const PackageSpec& spec,
const VcpkgPaths& paths)
{
const auto& fs = paths.get_filesystem();
const auto create_log_details = [&fs](vcpkg::Path&& path) {
auto log = fs.read_contents(path, VCPKG_LINE_INFO);
if (log.size() > 20'000)
{
auto first_block_end = log.find_first_of('\n', 3000);
if (first_block_end == std::string::npos || first_block_end > 5000) first_block_end = 3000;

auto last_block_end = log.find_last_of('\n', log.size() - 13000);
if (last_block_end == std::string::npos || last_block_end < log.size() - 15000)
last_block_end = log.size() - 13000;

auto skipped_lines = std::count(log.begin() + first_block_end, log.begin() + last_block_end, '\n');
log = log.substr(0, first_block_end) + "\n...\nSkip " + std::to_string(skipped_lines) +
" lines\n...\n" + log.substr(last_block_end);
}
while (!log.empty() && log.back() == '\n')
log.pop_back();
return Strings::concat(
"<details><summary>", path.native(), "</summary>\n\n```\n", log, "\n```\n</details>");
};
const auto manifest = paths.get_manifest()
.map([](const Json::Object& manifest) {
return Strings::concat("<details><summary>vcpkg.json</summary>\n\n```\n",
Json::stringify(manifest, Json::JsonStyle::with_spaces(2)),
"\n```\n</details>\n");
})
.value_or("");

return Strings::concat(
"**Host Environment**",
"\n- Host: ",
to_zstring_view(get_host_processor()),
'-',
get_host_os_name(),
"\n- Compiler: ",
"compiler",
"\n\n**To Reproduce**\n",
Strings::concat("`", args.command, " ", Strings::join(" ", args.command_arguments), "`\n"),
"\n\n**Failure logs**\n```\n",
paths.get_filesystem().read_contents(build_result.stdoutlog, VCPKG_LINE_INFO),
"\n```\n",
Strings::join("\n", Util::fmap(build_result.error_logs, create_log_details)),
"\n\n**Additional context**\n",
manifest);
}

std::string create_user_troubleshooting_message(const InstallPlanAction& action, const VcpkgPaths& paths)
{
#if defined(_WIN32)
Expand Down Expand Up @@ -1573,6 +1633,12 @@ namespace vcpkg::Build
}

ExtendedBuildResult::ExtendedBuildResult(BuildResult code) : code(code) { }
ExtendedBuildResult::ExtendedBuildResult(BuildResult code,
vcpkg::Path stdoutlog,
std::vector<std::string>&& error_logs)
: code(code), stdoutlog(stdoutlog), error_logs(error_logs)
{
}
ExtendedBuildResult::ExtendedBuildResult(BuildResult code, std::unique_ptr<BinaryControlFile>&& bcf)
: code(code), binary_control_file(std::move(bcf))
{
Expand Down
7 changes: 7 additions & 0 deletions src/vcpkg/install.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,13 @@ namespace vcpkg::Install
perform_install_plan_action(args, paths, action, status_db, binary_cache, build_logs_recorder);
if (result.code != BuildResult::SUCCEEDED && keep_going == KeepGoing::NO)
{
open_in_default_browser(Strings::concat("https://github.com/microsoft/vcpkg/issues/new?title=[",
action.spec.name(),
"] build failure on ",
action.spec.triplet(),
"&body=",
Build::create_github_issue(args, result, action.spec, paths)));

print2(Build::create_user_troubleshooting_message(action, paths), '\n');
Checks::exit_fail(VCPKG_LINE_INFO);
}
Expand Down
14 changes: 1 addition & 13 deletions src/vcpkg/triplet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,20 +74,8 @@ namespace vcpkg

static Triplet system_triplet()
{
#if defined(_WIN32)
StringLiteral operating_system = "windows";
#elif defined(__APPLE__)
StringLiteral operating_system = "osx";
#elif defined(__FreeBSD__)
StringLiteral operating_system = "freebsd";
#elif defined(__OpenBSD__)
StringLiteral operating_system = "openbsd";
#else
StringLiteral operating_system = "linux";
#endif

auto host_proc = get_host_processor();
auto canonical_name = Strings::format("%s-%s", to_zstring_view(host_proc), operating_system);
auto canonical_name = Strings::format("%s-%s", to_zstring_view(host_proc), get_host_os_name());
return Triplet::from_canonical_name(std::move(canonical_name));
}

Expand Down

0 comments on commit 4e897ed

Please sign in to comment.