/* vim:set ts=2 sw=2 sts=2 et: */
/**
* \author Marcus Holland-Moritz (github@mhxnet.de)
* \copyright Copyright (c) Marcus Holland-Moritz
*
* This file is part of dwarfs.
*
* dwarfs is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* dwarfs is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with dwarfs. If not, see .
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
namespace dwarfs {
history::history(history_config const& cfg)
: history_{std::make_unique()}
, cfg_{cfg} {}
history::~history() = default;
void history::parse(std::span data) {
history_->entries()->clear();
parse_append(data);
}
void history::parse_append(std::span data) {
folly::Range range{data.data(), data.size()};
thrift::history::history tmp;
apache::thrift::CompactSerializer::deserialize(range, tmp);
history_->entries()->insert(history_->entries()->end(),
std::make_move_iterator(tmp.entries()->begin()),
std::make_move_iterator(tmp.entries()->end()));
}
void history::append(std::optional> args) {
auto& histent = history_->entries()->emplace_back();
auto& version = histent.version().value();
version.major() = DWARFS_VERSION_MAJOR;
version.minor() = DWARFS_VERSION_MINOR;
version.patch() = DWARFS_VERSION_PATCH;
version.is_release() = std::string_view(DWARFS_GIT_DESC) == DWARFS_GIT_ID;
version.git_rev() = DWARFS_GIT_REV;
version.git_branch() = DWARFS_GIT_BRANCH;
version.git_desc() = DWARFS_GIT_DESC;
histent.system_id() = DWARFS_SYSTEM_ID;
histent.compiler_id() = DWARFS_COMPILER_ID;
if (args) {
histent.arguments() = std::move(*args);
}
if (cfg_.with_timestamps) {
histent.timestamp() = std::time(nullptr);
}
library_dependencies deps;
deps.add_common_libraries();
histent.library_versions() = deps.as_set();
}
size_t history::size() const { return history_->entries()->size(); }
std::vector history::serialize() const {
std::string buf;
::apache::thrift::CompactSerializer::serialize(*history_, &buf);
return std::vector(buf.begin(), buf.end());
}
void history::dump(std::ostream& os) const {
if (!history_->entries()->empty()) {
size_t const iwidth{std::to_string(history_->entries()->size()).size()};
size_t i{1};
os << "History:\n";
for (auto const& histent : *history_->entries()) {
os << " " << fmt::format("{:>{}}:", i++, iwidth);
if (histent.timestamp().has_value()) {
os << " "
<< fmt::format("[{:%Y-%m-%d %H:%M:%S}]",
fmt::localtime(histent.timestamp().value()));
}
auto const& version = histent.version().value();
os << " libdwarfs " << version.git_desc().value();
if (!version.is_release().value()) {
os << " (" << version.git_branch().value() << ")";
}
os << " on " << histent.system_id().value() << ", "
<< histent.compiler_id().value() << "\n";
if (histent.arguments().has_value() && !histent.arguments()->empty()) {
os << fmt::format(" {:>{}} args:", "", iwidth);
for (auto const& arg : histent.arguments().value()) {
os << ' ' << arg;
}
os << "\n";
}
}
}
}
nlohmann::json history::as_json() const {
nlohmann::json dyn;
for (auto const& histent : *history_->entries()) {
auto& entry = dyn.emplace_back();
auto const& version = histent.version().value();
entry["libdwarfs_version"] = {
{"major", version.major().value()},
{"minor", version.minor().value()},
{"patch", version.patch().value()},
{"is_release", version.is_release().value()},
};
auto& version_dyn = entry["libdwarfs_version"];
if (version.git_rev().has_value()) {
version_dyn["git_rev"] = version.git_rev().value();
}
if (version.git_branch().has_value()) {
version_dyn["git_branch"] = version.git_branch().value();
}
if (version.git_desc().has_value()) {
version_dyn["git_desc"] = version.git_desc().value();
}
entry["system_id"] = histent.system_id().value();
entry["compiler_id"] = histent.compiler_id().value();
if (histent.arguments().has_value()) {
auto& args = entry["arguments"];
for (auto const& arg : histent.arguments().value()) {
args.push_back(arg);
}
}
if (histent.timestamp().has_value()) {
entry["timestamp"] = {
{"epoch", histent.timestamp().value()},
{"local", fmt::format("{:%Y-%m-%dT%H:%M:%S}",
fmt::localtime(histent.timestamp().value()))},
};
}
if (histent.library_versions().has_value()) {
auto& libs = entry["library_versions"].emplace_back();
for (auto const& lib : histent.library_versions().value()) {
libs.push_back(lib);
}
}
}
return dyn;
}
} // namespace dwarfs