From 1d242ddb59954581219527bbbc9df712a5c33292 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 12 Feb 2021 22:24:33 +0000 Subject: [PATCH] Add a C++ rpmdb-diff API wrapping the C one, bind in Rust I'd like to compute diffs in apply-live to differentiate between "pure layering" versus modifications/removals. --- Makefile-libpriv.am | 1 + rust/src/lib.rs | 9 +++++ src/libpriv/rpmostree-diff.cxx | 61 ++++++++++++++++++++++++++++++++++ src/libpriv/rpmostree-diff.hpp | 57 +++++++++++++++++++++++++++++++ 4 files changed, 128 insertions(+) create mode 100644 src/libpriv/rpmostree-diff.cxx create mode 100644 src/libpriv/rpmostree-diff.hpp diff --git a/Makefile-libpriv.am b/Makefile-libpriv.am index 1016c3c8..52b48fdc 100644 --- a/Makefile-libpriv.am +++ b/Makefile-libpriv.am @@ -42,6 +42,7 @@ librpmostreepriv_sources = \ src/libpriv/rpmostree-refsack.cxx \ src/libpriv/rpmostree-rpm-util.cxx \ src/libpriv/rpmostree-rpm-util.h \ + src/libpriv/rpmostree-diff.cxx \ src/libpriv/rpmostree-importer.cxx \ src/libpriv/rpmostree-importer.h \ src/libpriv/rpmostree-unpacker-core.cxx \ diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 63aed66e..2ddbc3bc 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -265,6 +265,15 @@ pub mod ffi { fn main_print_error(msg: &str); } + unsafe extern "C++" { + include!("rpmostree-diff.hpp"); + type RPMDiff; + fn n_removed(&self) -> i32; + fn n_added(&self) -> i32; + fn n_modified(&self) -> i32; + dest: &CxxString, + } + unsafe extern "C++" { include!("rpmostree-output.h"); type Progress; diff --git a/src/libpriv/rpmostree-diff.cxx b/src/libpriv/rpmostree-diff.cxx new file mode 100644 index 00000000..ccd9bd87 --- /dev/null +++ b/src/libpriv/rpmostree-diff.cxx @@ -0,0 +1,61 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 2 of the licence or (at + * your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include + +#include "rpmostree-diff.hpp" +#include "rpmostree-db.h" +#include "rpmostree-util.h" + +namespace rpmostreecxx { + +RPMDiff::RPMDiff(GPtrArray *removed, GPtrArray *added, GPtrArray *modified_old, GPtrArray *modified_new) { + removed_ = g_ptr_array_ref(removed); + added_ = g_ptr_array_ref(added); + modified_old_ = g_ptr_array_ref(modified_old); + modified_new_ = g_ptr_array_ref(modified_new); +} + +RPMDiff::~RPMDiff() { + g_ptr_array_unref(removed_); + g_ptr_array_unref(added_); + g_ptr_array_unref(modified_old_); + g_ptr_array_unref(modified_new_); +} + +std::unique_ptr +rpmdb_diff(OstreeRepo &repo, const std::string &from, const std::string &to) { + g_autoptr(GPtrArray) removed = NULL; + g_autoptr(GPtrArray) added = NULL; + g_autoptr(GPtrArray) modified_old = NULL; + g_autoptr(GPtrArray) modified_new = NULL; + g_autoptr(GError) local_error = NULL; + if (!rpm_ostree_db_diff(&repo, from.c_str(), to.c_str(), + &removed, &added, &modified_old, &modified_new, + NULL, &local_error)) + util::throw_gerror(local_error); + return std::make_unique(removed, added, modified_old, modified_new); +} + +void +RPMDiff::print() const +{ + rpmostree_diff_print_formatted (RPMOSTREE_DIFF_PRINT_FORMAT_FULL_MULTILINE, NULL, 0, + removed_, added_, modified_old_, modified_new_); +} + +} /* namespace */ \ No newline at end of file diff --git a/src/libpriv/rpmostree-diff.hpp b/src/libpriv/rpmostree-diff.hpp new file mode 100644 index 00000000..b5cbe7b5 --- /dev/null +++ b/src/libpriv/rpmostree-diff.hpp @@ -0,0 +1,57 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 2 of the licence or (at + * your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#pragma once + +#include +#include +#include +#include + +#include + +#include "rust/cxx.h" + +namespace rpmostreecxx { + +class RPMDiff final { +public: + int n_removed() const { + return removed_->len; + } + int n_added() const { + return added_->len; + } + int n_modified() const { + return modified_old_->len + modified_new_->len; + } + ~RPMDiff(); + RPMDiff(GPtrArray *removed, GPtrArray *added, GPtrArray *modified_old, GPtrArray *modified_new); + + // TODO(cgwalters) enhance this with options + void print() const; + +private: + GPtrArray *removed_; + GPtrArray *added_; + GPtrArray *modified_old_; + GPtrArray *modified_new_; +}; + +std::unique_ptr rpmdb_diff(OstreeRepo &repo, const std::string &src, const std::string &dest); + +} /* namespace */ \ No newline at end of file