diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt
index 4bdd210..3cb8e88 100644
--- a/cpp/CMakeLists.txt
+++ b/cpp/CMakeLists.txt
@@ -20,13 +20,16 @@ add_library(lubuntuci SHARED common.cpp utilities.cpp)
target_include_directories(lubuntuci PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(lubuntuci PUBLIC yaml-cpp::yaml-cpp PRIVATE CURL::libcurl /srv/lubuntu-ci/repos/ci-tools/lib/liblaunchpad.so)
+add_library(update_maintainer_lib STATIC update-maintainer-lib.cpp)
+target_include_directories(update_maintainer_lib PRIVATE /srv/lubuntu-ci/repos/ci-tools/include/launchpadlib-cpp)
+target_link_libraries(update_maintainer_lib PRIVATE lubuntuci yaml-cpp::yaml-cpp CURL::libcurl)
+
add_executable(update-maintainer update-maintainer.cpp)
-target_include_directories(update-maintainer PRIVATE /srv/lubuntu-ci/repos/ci-tools/include/launchpadlib-cpp)
-target_link_libraries(update-maintainer PRIVATE lubuntuci yaml-cpp::yaml-cpp CURL::libcurl)
+target_link_libraries(update-maintainer PRIVATE update_maintainer_lib)
add_executable(build-packages build-packages.cpp)
target_include_directories(build-packages PRIVATE /srv/lubuntu-ci/repos/ci-tools/include/launchpadlib-cpp)
-target_link_libraries(build-packages PRIVATE lubuntuci PkgConfig::LIBGIT2 yaml-cpp::yaml-cpp)
+target_link_libraries(build-packages PRIVATE lubuntuci PkgConfig::LIBGIT2 update_maintainer_lib yaml-cpp::yaml-cpp)
add_executable(fetch-indexes fetch-indexes.cpp utilities.cpp)
target_include_directories(fetch-indexes PRIVATE /srv/lubuntu-ci/repos/ci-tools/include/launchpadlib-cpp)
diff --git a/cpp/build-packages.cpp b/cpp/build-packages.cpp
index d3d0de6..75e9dcb 100644
--- a/cpp/build-packages.cpp
+++ b/cpp/build-packages.cpp
@@ -14,7 +14,7 @@
// along with this program. If not, see .
#include "common.h"
-#include "update-maintainer.h"
+#include "update-maintainer-lib.h"
#include
#include
#include
diff --git a/cpp/update-maintainer-lib.cpp b/cpp/update-maintainer-lib.cpp
new file mode 100644
index 0000000..a8e7fe2
--- /dev/null
+++ b/cpp/update-maintainer-lib.cpp
@@ -0,0 +1,215 @@
+// Copyright (C) 2024 Simon Quigley
+//
+// This program 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.
+//
+// This program 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 this program. If not, see .
+
+#include "update-maintainer-lib.h"
+#include "update-maintainer.h"
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace fs = std::filesystem;
+
+// Definitions from update-maintainer.cpp moved here
+static const char* PREVIOUS_UBUNTU_MAINTAINERS[] = {
+ "ubuntu core developers ",
+ "ubuntu core developers ",
+ "ubuntu motu developers "
+};
+static const char* UBUNTU_MAINTAINER = "Ubuntu Developers ";
+
+class MaintainerUpdateException : public std::runtime_error {
+public:
+ using std::runtime_error::runtime_error;
+};
+
+static std::optional find_control_file(const fs::path &debian_dir) {
+ fs::path control_in = debian_dir / "control.in";
+ fs::path control = debian_dir / "control";
+ if (fs::exists(control_in)) return control_in;
+ if (fs::exists(control)) return control;
+ return std::nullopt;
+}
+
+static fs::path find_changelog_file(const fs::path &debian_dir) {
+ fs::path changelog = debian_dir / "changelog";
+ if (!fs::exists(changelog)) {
+ throw MaintainerUpdateException("No changelog file found");
+ }
+ return changelog;
+}
+
+static bool xsbc_managed_by_rules(const fs::path &debian_dir) {
+ fs::path rules = debian_dir / "rules";
+ if (!fs::exists(rules)) return false;
+ std::ifstream rf(rules);
+ std::string line;
+ while (std::getline(rf, line)) {
+ if (line.find("XSBC-Original-") != std::string::npos) {
+ return true;
+ }
+ }
+ return false;
+}
+
+static std::string get_distribution(const fs::path &changelog_file) {
+ // parse first line of changelog: "package (version) dist; urgency=..."
+ // dist is the token after ')'
+ std::ifstream f(changelog_file);
+ if(!f) throw MaintainerUpdateException("Unable to open changelog.");
+ std::string first_line;
+ std::getline(f, first_line);
+ size_t pos = first_line.find(')');
+ if(pos == std::string::npos) throw MaintainerUpdateException("Invalid changelog format");
+ pos++;
+ while(pos < first_line.size() && std::isspace((unsigned char)first_line[pos])) pos++;
+ size_t start = pos;
+ while(pos < first_line.size() && !std::isspace((unsigned char)first_line[pos]) && first_line[pos] != ';') pos++;
+ std::string dist = first_line.substr(start, pos - start);
+ size_t dashpos = dist.find('-');
+ if (dashpos != std::string::npos) {
+ dist = dist.substr(0, dashpos);
+ }
+ return dist;
+}
+
+static std::string read_file(const fs::path &p) {
+ std::ifstream f(p);
+ if(!f) throw MaintainerUpdateException("Cannot read file: " + p.string());
+ std::stringstream ss;
+ ss << f.rdbuf();
+ return ss.str();
+}
+
+static void write_file(const fs::path &p, const std::string &content) {
+ std::ofstream f(p);
+ if(!f) throw MaintainerUpdateException("Cannot write file: " + p.string());
+ f << content;
+}
+
+static std::optional get_field(const std::string &content, const std::string &field_regex) {
+ std::regex r(field_regex, std::regex_constants::multiline);
+ std::smatch m;
+ if(std::regex_search(content, m, r)) {
+ return m[1].str();
+ }
+ return std::nullopt;
+}
+
+static std::string set_field(const std::string &content, const std::string &field_regex, const std::string &new_line) {
+ std::regex r(field_regex, std::regex_constants::multiline);
+ return std::regex_replace(content, r, new_line);
+}
+
+static void update_maintainer_file(const fs::path &control_file, const std::string &distribution, bool verbose) {
+ std::string c = read_file(control_file);
+
+ auto original_maintainer = get_field(c, "^Maintainer:\\s?(.*)$");
+ if(!original_maintainer) {
+ throw MaintainerUpdateException("No Maintainer field found");
+ }
+
+ std::string om = *original_maintainer;
+ std::string om_lower = om;
+ for (auto &ch : om_lower) ch = (char)std::tolower((unsigned char)ch);
+
+ // Check previous ubuntu maintainers
+ for (auto &pm : PREVIOUS_UBUNTU_MAINTAINERS) {
+ std::string pm_lower = pm;
+ for (auto &ch: pm_lower) ch=(char)std::tolower((unsigned char)ch);
+ if(pm_lower == om_lower) {
+ if(verbose) {
+ std::cout<<"The old maintainer was: "<", lower_om.size()-11) != std::string::npos) {
+ if(verbose) {
+ std::cout<<"The Maintainer email is ubuntu.com address. Doing nothing.\n";
+ }
+ return;
+ }
+ }
+
+ // Debian distributions: stable, testing, unstable, experimental
+ if(distribution=="stable"||distribution=="testing"||distribution=="unstable"||distribution=="experimental") {
+ if(verbose) {
+ std::cout<<"The package targets Debian. Doing nothing.\n";
+ }
+ return;
+ }
+
+ // set XSBC-Original-Maintainer if needed
+ auto orig_field = get_field(c, "^(?:[XSBC]*-)?Original-Maintainer:\\s?(.*)$");
+ if(orig_field && verbose) {
+ std::cout<<"Overwriting original maintainer: "<< *orig_field <<"\n";
+ }
+
+ if(verbose) {
+ std::cout<<"The original maintainer is: "<< om <<"\n";
+ std::cout<<"Resetting as: "<
+//
+// This program 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.
+//
+// This program 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 this program. If not, see .
+
+#pragma once
+#include
+
+void update_maintainer(const std::string &debian_directory, bool verbose = false);
diff --git a/cpp/update-maintainer.cpp b/cpp/update-maintainer.cpp
index db8191e..b7aa275 100644
--- a/cpp/update-maintainer.cpp
+++ b/cpp/update-maintainer.cpp
@@ -13,206 +13,10 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
-#include "update-maintainer.h"
-#include
-#include
+#include "update-maintainer-lib.h"
#include
-#include
-#include
-#include
-#include
-namespace fs = std::filesystem;
-
-static const char* PREVIOUS_UBUNTU_MAINTAINERS[] = {
- "ubuntu core developers ",
- "ubuntu core developers ",
- "ubuntu motu developers "
-};
-static const char* UBUNTU_MAINTAINER = "Ubuntu Developers ";
-
-class MaintainerUpdateException : public std::runtime_error {
-public:
- using std::runtime_error::runtime_error;
-};
-
-static std::optional find_control_file(const fs::path &debian_dir) {
- fs::path control_in = debian_dir / "control.in";
- fs::path control = debian_dir / "control";
- if (fs::exists(control_in)) return control_in;
- if (fs::exists(control)) return control;
- return std::nullopt;
-}
-
-static fs::path find_changelog_file(const fs::path &debian_dir) {
- fs::path changelog = debian_dir / "changelog";
- if (!fs::exists(changelog)) {
- throw MaintainerUpdateException("No changelog file found");
- }
- return changelog;
-}
-
-static bool xsbc_managed_by_rules(const fs::path &debian_dir) {
- fs::path rules = debian_dir / "rules";
- if (!fs::exists(rules)) return false;
- std::ifstream rf(rules);
- std::string line;
- while (std::getline(rf, line)) {
- if (line.find("XSBC-Original-") != std::string::npos) {
- return true;
- }
- }
- return false;
-}
-
-static std::string get_distribution(const fs::path &changelog_file) {
- // parse first line of changelog: "package (version) dist; urgency=..."
- // dist is the token after ')'
- std::ifstream f(changelog_file);
- if(!f) throw MaintainerUpdateException("Unable to open changelog.");
- std::string first_line;
- std::getline(f, first_line);
- size_t pos = first_line.find(')');
- if(pos == std::string::npos) throw MaintainerUpdateException("Invalid changelog format");
- pos++;
- while(pos < first_line.size() && std::isspace((unsigned char)first_line[pos])) pos++;
- size_t start = pos;
- while(pos < first_line.size() && !std::isspace((unsigned char)first_line[pos]) && first_line[pos] != ';') pos++;
- std::string dist = first_line.substr(start, pos - start);
- size_t dashpos = dist.find('-');
- if (dashpos != std::string::npos) {
- dist = dist.substr(0, dashpos);
- }
- return dist;
-}
-
-static std::string read_file(const fs::path &p) {
- std::ifstream f(p);
- if(!f) throw MaintainerUpdateException("Cannot read file: " + p.string());
- std::stringstream ss;
- ss << f.rdbuf();
- return ss.str();
-}
-
-static void write_file(const fs::path &p, const std::string &content) {
- std::ofstream f(p);
- if(!f) throw MaintainerUpdateException("Cannot write file: " + p.string());
- f << content;
-}
-
-static std::optional get_field(const std::string &content, const std::string &field_regex) {
- std::regex r(field_regex, std::regex_constants::multiline);
- std::smatch m;
- if(std::regex_search(content, m, r)) {
- return m[1].str();
- }
- return std::nullopt;
-}
-
-static std::string set_field(const std::string &content, const std::string &field_regex, const std::string &new_line) {
- std::regex r(field_regex, std::regex_constants::multiline);
- return std::regex_replace(content, r, new_line);
-}
-
-static void update_maintainer_file(const fs::path &control_file, const std::string &distribution, bool verbose) {
- std::string c = read_file(control_file);
-
- auto original_maintainer = get_field(c, "^Maintainer:\\s?(.*)$");
- if(!original_maintainer) {
- throw MaintainerUpdateException("No Maintainer field found");
- }
-
- std::string om = *original_maintainer;
- std::string om_lower = om;
- for (auto &ch : om_lower) ch = (char)std::tolower((unsigned char)ch);
-
- // Check previous ubuntu maintainers
- for (auto &pm : PREVIOUS_UBUNTU_MAINTAINERS) {
- std::string pm_lower = pm;
- for (auto &ch: pm_lower) ch=(char)std::tolower((unsigned char)ch);
- if(pm_lower == om_lower) {
- if(verbose) {
- std::cout<<"The old maintainer was: "<", lower_om.size()-11) != std::string::npos) {
- if(verbose) {
- std::cout<<"The Maintainer email is ubuntu.com address. Doing nothing.\n";
- }
- return;
- }
- }
-
- // Debian distributions: stable, testing, unstable, experimental
- if(distribution=="stable"||distribution=="testing"||distribution=="unstable"||distribution=="experimental") {
- if(verbose) {
- std::cout<<"The package targets Debian. Doing nothing.\n";
- }
- return;
- }
-
- // set XSBC-Original-Maintainer if needed
- auto orig_field = get_field(c, "^(?:[XSBC]*-)?Original-Maintainer:\\s?(.*)$");
- if(orig_field && verbose) {
- std::cout<<"Overwriting original maintainer: "<< *orig_field <<"\n";
- }
-
- if(verbose) {
- std::cout<<"The original maintainer is: "<< om <<"\n";
- std::cout<<"Resetting as: "< [--verbose]" << std::endl;
return 1;
@@ -232,7 +36,7 @@ int main(int argc, char** argv) {
if(verbose) {
std::cout << "Maintainer updated successfully." << std::endl;
}
- } catch(const MaintainerUpdateException& e) {
+ } catch(const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
return 1;
}