blob: 2f42c0ac9406b0824fc7ff30031a647b9f19ad61 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#include <filesystem>
#include <fstream>
#include <iostream>
#include "src/developer/bugreport/client/bug_report_handler.h"
#include "src/lib/fxl/command_line.h"
namespace {
std::ifstream* OpenFile(const std::filesystem::path& path) {
std::error_code ec;
if (!std::filesystem::exists(path, ec)) {
FXL_LOG(ERROR) << "Could not open " << path;
return nullptr;
}
static std::ifstream iss;
iss.open(path, std::ifstream::in);
if (!iss.good()) {
FXL_LOG(ERROR) << "Could not read " << path;
return nullptr;
}
return &iss;
}
constexpr char kUsage[] = R"(bugreport
Process an incoming bugreport generated by a target device.
Will output several report files in a given output directory.
Usage:
bugreport [--input-file=<FILEPATH>] <OUTPUT_DIR>
Arguments:
--input_file Optional input file to be read. If not specified, will read
from stdin.
OUTPUT_DIR Where bugreport will store the files. Required.
)";
} // namespace
int main(int argc, char* argv[]) {
auto command_line = fxl::CommandLineFromArgcArgv(argc, argv);
// Check if an input file was given, use stdin otherwise.
std::istream* input;
if (command_line.HasOption("input-file")) {
std::string input_value;
command_line.GetOptionValue("input-file", &input_value);
input = OpenFile(input_value);
if (!input)
exit(1);
} else {
input = &std::cin;
}
FXL_DCHECK(input);
// Bugreport requires the caller to provide a valid directory to where output the report.
auto& pos_args = command_line.positional_args();
if (pos_args.size() != 1u) {
FXL_LOG(ERROR) << "A single output path should be given.";
std::cerr << kUsage;
exit(1);
}
// Output path should be valid.
std::filesystem::path output_path(pos_args[0]);
std::error_code ec;
if (!std::filesystem::is_directory(output_path, ec)) {
FXL_LOG(ERROR) << "Invalid output directory given: " << output_path;
exit(1);
}
auto targets = bugreport::HandleBugReport(output_path, input);
if (!targets) {
std::cerr << "Error processing input bug report. Exiting." << std::endl;
exit(1);
}
// Report the success.
std::cout << "Bug report processing successful." << std::endl;
for (auto& target : *targets) {
auto path = output_path / target.name;
std::cout << "Exported " << path << std::endl;
}
}