Reorganize build-package to separate concerns a bit
This commit is contained in:
parent
48c59962d0
commit
6d81551a5d
@ -63,6 +63,22 @@ static std::mutex& get_repo_mutex(const fs::path& repo_path) {
|
||||
static std::mutex dput_futures_mutex;
|
||||
static std::vector<std::future<void>> dput_futures;
|
||||
|
||||
// Mutex and map to store failed packages and their reasons
|
||||
static std::mutex failures_mutex;
|
||||
static std::map<std::string, std::string> failed_packages;
|
||||
|
||||
// Struct to represent a package
|
||||
struct Package {
|
||||
std::string name;
|
||||
std::string upload_target;
|
||||
std::string upstream_url;
|
||||
std::string packaging_url;
|
||||
std::optional<std::string> packaging_branch;
|
||||
bool large;
|
||||
std::vector<std::string> changes_files;
|
||||
std::vector<std::string> devel_changes_files;
|
||||
};
|
||||
|
||||
static const std::string BASE_DIR = "/srv/lubuntu-ci/repos";
|
||||
static const std::string DEBFULLNAME = "Lugito";
|
||||
static const std::string DEBEMAIL = "info@lubuntu.me";
|
||||
@ -408,27 +424,25 @@ static void run_source_lintian(const std::string &name, const fs::path &source_p
|
||||
log_verbose("Completed Lintian run for package: " + name);
|
||||
}
|
||||
|
||||
static void dput_source(const std::string &name, const std::string &upload_target, const std::vector<std::string> &changes_files, const std::vector<std::string> &devel_changes_files) {
|
||||
log_info("Uploading changes for package: " + name + " to " + upload_target);
|
||||
if(!changes_files.empty()) {
|
||||
static void dput_source(const Package &pkg) {
|
||||
log_info("Uploading changes for package: " + pkg.name + " to " + pkg.upload_target);
|
||||
if(!pkg.changes_files.empty()) {
|
||||
std::string hr_changes;
|
||||
for(auto &c: changes_files) hr_changes += c + " ";
|
||||
for(auto &c: pkg.changes_files) hr_changes += c + " ";
|
||||
log_verbose("Changes files: " + hr_changes);
|
||||
std::vector<std::string> cmd = {"dput", upload_target};
|
||||
for(auto &c: changes_files) cmd.push_back(c);
|
||||
std::vector<std::string> cmd = {"dput", pkg.upload_target};
|
||||
for(auto &c: pkg.changes_files) cmd.push_back(c);
|
||||
try {
|
||||
run_command_silent_on_success(cmd, OUTPUT_DIR);
|
||||
log_info("Successfully uploaded changes for package: " + name);
|
||||
for(auto &file: devel_changes_files) {
|
||||
if(!file.empty()) {
|
||||
run_source_lintian(name, file);
|
||||
}
|
||||
}
|
||||
log_info("Successfully uploaded changes for package: " + pkg.name);
|
||||
} catch (...) {
|
||||
log_error("Failed to upload changes for package: " + name);
|
||||
log_error("Failed to upload changes for package: " + pkg.name);
|
||||
// Record the failure
|
||||
std::lock_guard<std::mutex> lock(failures_mutex);
|
||||
failed_packages[pkg.name] = "Failed to upload changes with dput.";
|
||||
}
|
||||
} else {
|
||||
log_warning("No changes files to upload for package: " + name);
|
||||
log_warning("No changes files to upload for package: " + pkg.name);
|
||||
}
|
||||
}
|
||||
|
||||
@ -440,22 +454,32 @@ static void update_changelog(const fs::path &packaging_dir, const std::string &r
|
||||
log_verbose("Checked out debian/changelog for " + name);
|
||||
} catch (const std::exception &e) {
|
||||
log_error("Failed to checkout debian/changelog for " + name + ": " + e.what());
|
||||
// Record the failure
|
||||
std::lock_guard<std::mutex> lock(failures_mutex);
|
||||
failed_packages[name] = "Failed to checkout debian/changelog: " + std::string(e.what());
|
||||
throw;
|
||||
}
|
||||
std::vector<std::string> cmd = {
|
||||
"dch", "--distribution", release, "--package", name, "--newversion", version_with_epoch + "-0ubuntu1~ppa1",
|
||||
"--urgency", urgency_level_override, "CI upload."
|
||||
};
|
||||
run_command_silent_on_success(cmd, packaging_dir);
|
||||
log_info("Changelog updated for " + name);
|
||||
try {
|
||||
run_command_silent_on_success(cmd, packaging_dir);
|
||||
log_info("Changelog updated for " + name);
|
||||
} catch (const std::exception &e) {
|
||||
log_error("Failed to update changelog for " + name + ": " + e.what());
|
||||
// Record the failure
|
||||
std::lock_guard<std::mutex> lock(failures_mutex);
|
||||
failed_packages[name] = "Failed to update changelog: " + std::string(e.what());
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
static std::string build_package(const fs::path &packaging_dir, const std::map<std::string, std::string> &env_vars, bool large) {
|
||||
static std::string build_package(const fs::path &packaging_dir, const std::map<std::string, std::string> &env_vars, bool large, const std::string &pkg_name) {
|
||||
// Acquire the semaphore here so that each build only happens if there's capacity.
|
||||
// This ensures we never have more than 5 /tmp dirs at once.
|
||||
semaphore.acquire();
|
||||
std::string name = packaging_dir.filename().string();
|
||||
log_info("Building source package for " + name);
|
||||
log_info("Building source package for " + pkg_name);
|
||||
fs::path temp_dir;
|
||||
std::error_code ec;
|
||||
|
||||
@ -475,15 +499,15 @@ static std::string build_package(const fs::path &packaging_dir, const std::map<s
|
||||
|
||||
try {
|
||||
if(large) {
|
||||
temp_dir = fs::path(OUTPUT_DIR) / (".tmp_" + name + "_" + env_vars.at("VERSION"));
|
||||
temp_dir = fs::path(OUTPUT_DIR) / (".tmp_" + pkg_name + "_" + env_vars.at("VERSION"));
|
||||
fs::create_directories(temp_dir);
|
||||
} else {
|
||||
temp_dir = fs::temp_directory_path() / ("tmp_build_" + name + "_" + env_vars.at("VERSION"));
|
||||
temp_dir = fs::temp_directory_path() / ("tmp_build_" + pkg_name + "_" + env_vars.at("VERSION"));
|
||||
fs::create_directories(temp_dir);
|
||||
}
|
||||
log_verbose("Temporary packaging directory created at: " + temp_dir.string());
|
||||
|
||||
fs::path temp_packaging_dir = temp_dir / name;
|
||||
fs::path temp_packaging_dir = temp_dir / pkg_name;
|
||||
fs::create_directories(temp_packaging_dir, ec);
|
||||
if(ec) {
|
||||
log_error("Failed to create temporary packaging directory: " + temp_packaging_dir.string() + " Error: " + ec.message());
|
||||
@ -496,8 +520,8 @@ static std::string build_package(const fs::path &packaging_dir, const std::map<s
|
||||
throw std::runtime_error("Failed to copy debian directory");
|
||||
}
|
||||
|
||||
std::string tarball_name = name + "_" + env_vars.at("VERSION") + ".orig.tar.gz";
|
||||
fs::path tarball_source = fs::path(BASE_DIR) / (name + "_MAIN.orig.tar.gz");
|
||||
std::string tarball_name = pkg_name + "_" + env_vars.at("VERSION") + ".orig.tar.gz";
|
||||
fs::path tarball_source = fs::path(BASE_DIR) / (pkg_name + "_MAIN.orig.tar.gz");
|
||||
fs::path tarball_dest = temp_dir / tarball_name;
|
||||
fs::copy_file(tarball_source, tarball_dest, fs::copy_options::overwrite_existing, ec);
|
||||
if(ec) {
|
||||
@ -514,9 +538,9 @@ static std::string build_package(const fs::path &packaging_dir, const std::map<s
|
||||
run_command_silent_on_success(cmd_build, temp_packaging_dir);
|
||||
|
||||
run_command_silent_on_success({"git", "checkout", "debian/changelog"}, packaging_dir);
|
||||
log_info("Built package for " + name);
|
||||
log_info("Built package for " + pkg_name);
|
||||
|
||||
std::string pattern = name + "_" + env_vars.at("VERSION");
|
||||
std::string pattern = pkg_name + "_" + env_vars.at("VERSION");
|
||||
std::string changes_file;
|
||||
for(auto &entry: fs::directory_iterator(temp_dir)) {
|
||||
std::string fname = entry.path().filename().string();
|
||||
@ -531,14 +555,14 @@ static std::string build_package(const fs::path &packaging_dir, const std::map<s
|
||||
|
||||
for(auto &entry : fs::directory_iterator(OUTPUT_DIR)) {
|
||||
std::string fname = entry.path().filename().string();
|
||||
if(fname.rfind(name + "_" + env_vars.at("VERSION"), 0) == 0 && fname.ends_with("_source.changes")) {
|
||||
if(fname.rfind(pkg_name + "_" + env_vars.at("VERSION"), 0) == 0 && fname.ends_with("_source.changes")) {
|
||||
changes_file = entry.path().string();
|
||||
log_info("Found changes file: " + changes_file);
|
||||
}
|
||||
}
|
||||
|
||||
if(changes_file.empty()) {
|
||||
log_error("No changes file found after build for package: " + name);
|
||||
log_error("No changes file found after build for package: " + pkg_name);
|
||||
throw std::runtime_error("Changes file not found");
|
||||
}
|
||||
|
||||
@ -546,34 +570,19 @@ static std::string build_package(const fs::path &packaging_dir, const std::map<s
|
||||
|
||||
cleanup();
|
||||
return changes_file;
|
||||
} catch(...) {
|
||||
} catch(const std::exception &e) {
|
||||
cleanup();
|
||||
// Record the failure
|
||||
std::lock_guard<std::mutex> lock(failures_mutex);
|
||||
failed_packages[pkg_name] = "Build failed: " + std::string(e.what());
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
static void process_package(const YAML::Node &pkg, const YAML::Node &releases) {
|
||||
std::string name = pkg["name"] ? pkg["name"].as<std::string>() : "";
|
||||
std::string upload_target = pkg["upload_target"] ? pkg["upload_target"].as<std::string>() : "ppa:lubuntu-ci/unstable-ci-proposed";
|
||||
if(name.empty()) {
|
||||
log_warning("Skipping package due to missing name.");
|
||||
return;
|
||||
}
|
||||
log_info("Processing package: " + name);
|
||||
|
||||
fs::path packaging_destination = fs::path(BASE_DIR) / name;
|
||||
fs::path changelog_path = packaging_destination / "debian" / "changelog";
|
||||
std::string version = "";
|
||||
|
||||
std::string upstream_url = pkg["upstream_url"] ? pkg["upstream_url"].as<std::string>() : ("https://github.com/lxqt/" + name + ".git");
|
||||
fs::path upstream_destination = fs::path(BASE_DIR) / ("upstream-" + name);
|
||||
std::optional<std::string> packaging_branch = std::nullopt;
|
||||
if(pkg["packaging_branch"] && pkg["packaging_branch"].IsScalar()) {
|
||||
packaging_branch = pkg["packaging_branch"].as<std::string>();
|
||||
} else if (releases.size() > 0) {
|
||||
packaging_branch = "ubuntu/" + releases[0].as<std::string>();
|
||||
}
|
||||
std::string packaging_url = pkg["packaging_url"] ? pkg["packaging_url"].as<std::string>() : ("https://git.lubuntu.me/Lubuntu/" + name + "-packaging.git");
|
||||
static void pull_package(Package &pkg, const YAML::Node &releases) {
|
||||
log_info("Pulling package: " + pkg.name);
|
||||
fs::path packaging_destination = fs::path(BASE_DIR) / pkg.name;
|
||||
fs::path upstream_destination = fs::path(BASE_DIR) / ("upstream-" + pkg.name);
|
||||
fs::path packaging_repo = packaging_destination;
|
||||
|
||||
std::mutex& upstream_mutex = get_repo_mutex(upstream_destination);
|
||||
@ -581,27 +590,59 @@ static void process_package(const YAML::Node &pkg, const YAML::Node &releases) {
|
||||
|
||||
std::scoped_lock lock(upstream_mutex, packaging_mutex);
|
||||
|
||||
git_fetch_and_checkout(upstream_destination, upstream_url, std::nullopt);
|
||||
git_fetch_and_checkout(packaging_repo, packaging_url, packaging_branch);
|
||||
try {
|
||||
git_fetch_and_checkout(upstream_destination, pkg.upstream_url, std::nullopt);
|
||||
git_fetch_and_checkout(packaging_repo, pkg.packaging_url, pkg.packaging_branch);
|
||||
} catch(const std::exception &e) {
|
||||
log_error("Failed to fetch and checkout repositories for package " + pkg.name + ": " + e.what());
|
||||
// Record the failure
|
||||
std::lock_guard<std::mutex> lock_fail(failures_mutex);
|
||||
failed_packages[pkg.name] = "Failed to fetch/checkout repositories: " + std::string(e.what());
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
log_info("Updating maintainer for package: " + name);
|
||||
log_info("Updating maintainer for package: " + pkg.name);
|
||||
update_maintainer((packaging_destination / "debian").string(), false);
|
||||
log_info("Maintainer updated for package: " + name);
|
||||
log_info("Maintainer updated for package: " + pkg.name);
|
||||
} catch(std::exception &e) {
|
||||
log_warning("update_maintainer error for " + name + ": " + std::string(e.what()));
|
||||
log_warning("update_maintainer error for " + pkg.name + ": " + std::string(e.what()));
|
||||
// Record the failure
|
||||
std::lock_guard<std::mutex> lock_fail(failures_mutex);
|
||||
failed_packages[pkg.name] = "Failed to update maintainer: " + std::string(e.what());
|
||||
}
|
||||
|
||||
auto exclusions = get_exclusions(packaging_destination);
|
||||
log_info("Creating tarball for package: " + name);
|
||||
create_tarball(name, upstream_destination, exclusions);
|
||||
log_info("Tarball created for package: " + name);
|
||||
log_info("Creating tarball for package: " + pkg.name);
|
||||
try {
|
||||
create_tarball(pkg.name, upstream_destination, exclusions);
|
||||
log_info("Tarball created for package: " + pkg.name);
|
||||
} catch(const std::exception &e) {
|
||||
log_error("Failed to create tarball for package " + pkg.name + ": " + e.what());
|
||||
// Record the failure
|
||||
std::lock_guard<std::mutex> lock_fail(failures_mutex);
|
||||
failed_packages[pkg.name] = "Failed to create tarball: " + std::string(e.what());
|
||||
}
|
||||
}
|
||||
|
||||
version = parse_version(changelog_path);
|
||||
static void build_package_stage(Package &pkg, const YAML::Node &releases) {
|
||||
fs::path packaging_destination = fs::path(BASE_DIR) / pkg.name;
|
||||
fs::path changelog_path = packaging_destination / "debian" / "changelog";
|
||||
std::string version = "";
|
||||
|
||||
bool large = pkg["large"] ? pkg["large"].as<bool>() : false;
|
||||
try {
|
||||
version = parse_version(changelog_path);
|
||||
} catch(const std::exception &e) {
|
||||
log_error("Failed to parse version for package " + pkg.name + ": " + e.what());
|
||||
// Record the failure
|
||||
std::lock_guard<std::mutex> lock_fail(failures_mutex);
|
||||
failed_packages[pkg.name] = "Failed to parse version: " + std::string(e.what());
|
||||
return;
|
||||
}
|
||||
|
||||
bool large = pkg.large;
|
||||
if(large) {
|
||||
log_info("Package " + name + " is marked as large.");
|
||||
log_info("Package " + pkg.name + " is marked as large.");
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> env_map;
|
||||
@ -613,62 +654,99 @@ static void process_package(const YAML::Node &pkg, const YAML::Node &releases) {
|
||||
if(auto pos = version.find(':'); pos != std::string::npos) {
|
||||
epoch = version.substr(0, pos);
|
||||
version_no_epoch = version.substr(pos + 1);
|
||||
log_verbose("Package " + name + " has epoch: " + epoch);
|
||||
log_verbose("Package " + pkg.name + " has epoch: " + epoch);
|
||||
}
|
||||
env_map["VERSION"] = version_no_epoch;
|
||||
|
||||
std::vector<std::string> changes_files;
|
||||
std::vector<std::string> devel_changes_files;
|
||||
for(auto rel : releases) {
|
||||
std::string release = rel.as<std::string>();
|
||||
log_info("Building " + name + " for release: " + release);
|
||||
log_info("Building " + pkg.name + " for release: " + release);
|
||||
|
||||
std::string release_version_no_epoch = version_no_epoch + "~" + release;
|
||||
std::string version_for_dch = epoch.empty() ? release_version_no_epoch : (epoch + ":" + release_version_no_epoch);
|
||||
env_map["UPLOAD_TARGET"] = upload_target;
|
||||
env_map["UPLOAD_TARGET"] = pkg.upload_target;
|
||||
|
||||
try {
|
||||
update_changelog(packaging_destination, release, version_for_dch);
|
||||
} catch(const std::exception &e) {
|
||||
log_error("Failed to update changelog for package " + pkg.name + ": " + e.what());
|
||||
continue;
|
||||
}
|
||||
|
||||
update_changelog(packaging_destination, release, version_for_dch);
|
||||
env_map["VERSION"] = release_version_no_epoch;
|
||||
|
||||
try {
|
||||
std::string changes_file = build_package(packaging_destination, env_map, large);
|
||||
std::string changes_file = build_package(packaging_destination, env_map, large, pkg.name);
|
||||
if(!changes_file.empty()) {
|
||||
changes_files.push_back(changes_file);
|
||||
pkg.changes_files.push_back(changes_file);
|
||||
if(rel == releases[0]) {
|
||||
devel_changes_files.push_back(changes_file);
|
||||
pkg.devel_changes_files.push_back(changes_file);
|
||||
} else {
|
||||
devel_changes_files.push_back("");
|
||||
pkg.devel_changes_files.push_back("");
|
||||
}
|
||||
}
|
||||
} catch(std::exception &e) {
|
||||
log_error("Error building package '" + name + "' for release '" + release + "': " + std::string(e.what()));
|
||||
log_error("Error building package '" + pkg.name + "' for release '" + release + "': " + std::string(e.what()));
|
||||
// Failure already recorded in build_package
|
||||
}
|
||||
}
|
||||
|
||||
fs::path main_tarball = fs::path(BASE_DIR) / (name + "_MAIN.orig.tar.gz");
|
||||
fs::path main_tarball = fs::path(BASE_DIR) / (pkg.name + "_MAIN.orig.tar.gz");
|
||||
fs::remove(main_tarball);
|
||||
log_verbose("Removed main orig tarball for package: " + name);
|
||||
log_verbose("Removed main orig tarball for package: " + pkg.name);
|
||||
}
|
||||
|
||||
if(!changes_files.empty() && !upload_target.empty()) {
|
||||
std::vector<std::string> dput_changes = changes_files;
|
||||
std::vector<std::string> dput_devel_changes = devel_changes_files;
|
||||
auto fut = std::async(std::launch::async, [name, upload_target, dput_changes, dput_devel_changes]() {
|
||||
dput_source(name, upload_target, dput_changes, dput_devel_changes);
|
||||
});
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(dput_futures_mutex);
|
||||
dput_futures.emplace_back(std::move(fut));
|
||||
}
|
||||
} else {
|
||||
log_warning("No changes files to upload for package: " + name);
|
||||
static void build_package_stage_wrapper(Package &pkg, const YAML::Node &releases) {
|
||||
try {
|
||||
build_package_stage(pkg, releases);
|
||||
} catch(const std::exception &e) {
|
||||
log_error(std::string("Exception in building package: ") + e.what());
|
||||
// Record the failure
|
||||
std::lock_guard<std::mutex> lock_fail(failures_mutex);
|
||||
failed_packages[pkg.name] = "Exception during build: " + std::string(e.what());
|
||||
}
|
||||
}
|
||||
|
||||
static void prepare_package(const YAML::Node &pkg, const YAML::Node &releases) {
|
||||
try {
|
||||
process_package(pkg, releases);
|
||||
} catch(const std::exception &e) {
|
||||
log_error(std::string("Exception in processing package: ") + e.what());
|
||||
static void upload_package_stage(Package &pkg, bool skip_dput) {
|
||||
if(skip_dput) {
|
||||
log_info("Skipping dput upload for package: " + pkg.name);
|
||||
return;
|
||||
}
|
||||
|
||||
if(!pkg.changes_files.empty() && !pkg.upload_target.empty()) {
|
||||
dput_source(pkg);
|
||||
} else {
|
||||
log_warning("No changes files to upload for package: " + pkg.name);
|
||||
}
|
||||
}
|
||||
|
||||
static void run_lintian_stage(Package &pkg) {
|
||||
for(const auto &changes_file : pkg.changes_files) {
|
||||
fs::path changes_path = changes_file;
|
||||
fs::path source_path = changes_path.parent_path(); // Assuming source package is in the same directory
|
||||
std::string source_package = changes_path.stem().string(); // Remove extension
|
||||
fs::path source_package_path = fs::path(BASE_DIR) / source_package;
|
||||
|
||||
run_source_lintian(pkg.name, source_package_path);
|
||||
}
|
||||
}
|
||||
|
||||
static void clean_old_logs(const fs::path &log_dir) {
|
||||
// Implement log cleaning logic if necessary
|
||||
// Placeholder implementation
|
||||
log_info("Cleaning old logs in: " + log_dir.string());
|
||||
// Example: Remove logs older than 30 days
|
||||
auto now = std::chrono::system_clock::now();
|
||||
for(auto &p : fs::directory_iterator(log_dir)) {
|
||||
if(fs::is_regular_file(p)) {
|
||||
auto ftime = fs::last_write_time(p);
|
||||
auto sctp = std::chrono::time_point_cast<std::chrono::system_clock::duration>(ftime - fs::file_time_type::clock::now()
|
||||
+ std::chrono::system_clock::now());
|
||||
if(now - sctp > std::chrono::hours(24 * 30)) { // Older than 30 days
|
||||
fs::remove(p.path());
|
||||
log_verbose("Removed old log file: " + p.path().string());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -682,6 +760,7 @@ int main(int argc, char** argv) {
|
||||
}
|
||||
if(arg == "--verbose" || arg == "-v") {
|
||||
verbose = true;
|
||||
// Remove the verbose flag from argv
|
||||
for(int j = i; j < argc - 1; j++) {
|
||||
argv[j] = argv[j+1];
|
||||
}
|
||||
@ -762,40 +841,151 @@ int main(int argc, char** argv) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
auto packages = config["packages"];
|
||||
auto packages_node = config["packages"];
|
||||
auto releases = config["releases"];
|
||||
log_info("Loaded " + std::to_string(packages.size()) + " packages and " + std::to_string(releases.size()) + " releases from config.");
|
||||
log_info("Loaded " + std::to_string(packages_node.size()) + " packages and " + std::to_string(releases.size()) + " releases from config.");
|
||||
|
||||
// Populate the packages vector
|
||||
std::vector<Package> packages;
|
||||
for(auto pkg_node : packages_node) {
|
||||
Package pkg;
|
||||
pkg.name = pkg_node["name"] ? pkg_node["name"].as<std::string>() : "";
|
||||
pkg.upload_target = pkg_node["upload_target"] ? pkg_node["upload_target"].as<std::string>() : "ppa:lubuntu-ci/unstable-ci-proposed";
|
||||
pkg.upstream_url = pkg_node["upstream_url"] ? pkg_node["upstream_url"].as<std::string>() : ("https://github.com/lxqt/" + pkg.name + ".git");
|
||||
pkg.packaging_url = pkg_node["packaging_url"] ? pkg_node["packaging_url"].as<std::string>() : ("https://git.lubuntu.me/Lubuntu/" + pkg.name + "-packaging.git");
|
||||
if(pkg_node["packaging_branch"] && pkg_node["packaging_branch"].IsScalar()) {
|
||||
pkg.packaging_branch = pkg_node["packaging_branch"].as<std::string>();
|
||||
}
|
||||
pkg.large = pkg_node["large"] ? pkg_node["large"].as<bool>() : false;
|
||||
|
||||
if(pkg.name.empty()) {
|
||||
log_warning("Skipping package due to missing name.");
|
||||
continue;
|
||||
}
|
||||
packages.emplace_back(std::move(pkg));
|
||||
}
|
||||
log_info("Prepared " + std::to_string(packages.size()) + " packages for processing.");
|
||||
|
||||
fs::current_path(BASE_DIR);
|
||||
log_info("Set current working directory to BASE_DIR: " + BASE_DIR);
|
||||
|
||||
std::vector<std::future<void>> futures;
|
||||
log_info("Starting package preparation for " + std::to_string(packages.size()) + " packages.");
|
||||
for(auto pkg : packages) {
|
||||
futures.emplace_back(std::async(std::launch::async, prepare_package, pkg, releases));
|
||||
// Stage 1: Pull all packages in parallel
|
||||
log_info("Starting Stage 1: Pulling all packages.");
|
||||
std::vector<std::future<void>> pull_futures;
|
||||
for(auto &pkg : packages) {
|
||||
pull_futures.emplace_back(std::async(std::launch::async, pull_package, std::ref(pkg), releases));
|
||||
}
|
||||
|
||||
for(auto &fut : futures) {
|
||||
for(auto &fut : pull_futures) {
|
||||
try {
|
||||
fut.get();
|
||||
log_info("Package processed successfully.");
|
||||
log_info("Package pulled successfully.");
|
||||
} catch(std::exception &e) {
|
||||
log_error(std::string("Task generated an exception: ") + e.what());
|
||||
log_error(std::string("Pull task generated an exception: ") + e.what());
|
||||
// Record the failure if not already recorded
|
||||
// (Handled inside pull_package)
|
||||
}
|
||||
}
|
||||
log_info("Completed Stage 1: All packages pulled.");
|
||||
|
||||
// Check for failures after Stage 1
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(dput_futures_mutex);
|
||||
for(auto &fut : dput_futures) {
|
||||
try {
|
||||
fut.get();
|
||||
log_info("Dput upload completed successfully.");
|
||||
} catch(std::exception &e) {
|
||||
log_error(std::string("Dput upload generated an exception: ") + e.what());
|
||||
}
|
||||
std::lock_guard<std::mutex> lock(failures_mutex);
|
||||
if(!failed_packages.empty()) {
|
||||
log_error("Failures detected after Stage 1: Pulling packages.");
|
||||
// Skip remaining stages
|
||||
goto SUMMARY;
|
||||
}
|
||||
}
|
||||
|
||||
// Stage 2: Build all packages in parallel
|
||||
log_info("Starting Stage 2: Building all packages.");
|
||||
std::vector<std::future<void>> build_futures;
|
||||
for(auto &pkg : packages) {
|
||||
build_futures.emplace_back(std::async(std::launch::async, build_package_stage_wrapper, std::ref(pkg), releases));
|
||||
}
|
||||
|
||||
for(auto &fut : build_futures) {
|
||||
try {
|
||||
fut.get();
|
||||
log_info("Package built successfully.");
|
||||
} catch(std::exception &e) {
|
||||
log_error(std::string("Build task generated an exception: ") + e.what());
|
||||
// Record the failure if not already recorded
|
||||
// (Handled inside build_package_stage_wrapper)
|
||||
}
|
||||
}
|
||||
log_info("Completed Stage 2: All packages built.");
|
||||
|
||||
// Check for failures after Stage 2
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(failures_mutex);
|
||||
if(!failed_packages.empty()) {
|
||||
log_error("Failures detected after Stage 2: Building packages.");
|
||||
// Skip remaining stages
|
||||
goto SUMMARY;
|
||||
}
|
||||
}
|
||||
|
||||
// Stage 3: Dput upload all packages in parallel
|
||||
log_info("Starting Stage 3: Uploading all packages with dput.");
|
||||
std::vector<std::future<void>> upload_futures;
|
||||
for(auto &pkg : packages) {
|
||||
upload_futures.emplace_back(std::async(std::launch::async, upload_package_stage, std::ref(pkg), skip_dput));
|
||||
}
|
||||
|
||||
for(auto &fut : upload_futures) {
|
||||
try {
|
||||
fut.get();
|
||||
log_info("Package uploaded successfully.");
|
||||
} catch(std::exception &e) {
|
||||
log_error(std::string("Upload task generated an exception: ") + e.what());
|
||||
// Record the failure if not already recorded
|
||||
// (Handled inside upload_package_stage)
|
||||
}
|
||||
}
|
||||
log_info("Completed Stage 3: All packages uploaded.");
|
||||
|
||||
// Check for failures after Stage 3
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(failures_mutex);
|
||||
if(!failed_packages.empty()) {
|
||||
log_error("Failures detected after Stage 3: Uploading packages.");
|
||||
// Skip remaining stages
|
||||
goto SUMMARY;
|
||||
}
|
||||
}
|
||||
|
||||
// Stage 4: Run Lintian on all packages in parallel
|
||||
log_info("Starting Stage 4: Running Lintian on all packages.");
|
||||
std::vector<std::future<void>> lintian_futures;
|
||||
for(auto &pkg : packages) {
|
||||
lintian_futures.emplace_back(std::async(std::launch::async, run_lintian_stage, std::ref(pkg)));
|
||||
}
|
||||
|
||||
for(auto &fut : lintian_futures) {
|
||||
try {
|
||||
fut.get();
|
||||
log_info("Lintian run successfully.");
|
||||
} catch(std::exception &e) {
|
||||
log_error(std::string("Lintian task generated an exception: ") + e.what());
|
||||
// Record the failure
|
||||
std::lock_guard<std::mutex> lock_fail(failures_mutex);
|
||||
failed_packages["Lintian"] = "Exception during Lintian run: " + std::string(e.what());
|
||||
}
|
||||
}
|
||||
log_info("Completed Stage 4: All Lintian runs completed.");
|
||||
|
||||
// Check for failures after Stage 4
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(failures_mutex);
|
||||
if(!failed_packages.empty()) {
|
||||
log_error("Failures detected after Stage 4: Running Lintian.");
|
||||
// Proceed to summary
|
||||
}
|
||||
}
|
||||
|
||||
SUMMARY:
|
||||
if(!skip_cleanup) {
|
||||
log_info("Cleaning up output directory: " + OUTPUT_DIR);
|
||||
fs::remove_all(OUTPUT_DIR);
|
||||
@ -803,11 +993,28 @@ int main(int argc, char** argv) {
|
||||
} else {
|
||||
log_info("Skipping cleanup as per flag.");
|
||||
}
|
||||
|
||||
log_info("Publishing Lintian results.");
|
||||
publish_lintian();
|
||||
|
||||
log_info("Cleaning old logs.");
|
||||
clean_old_logs(fs::path(LOG_DIR));
|
||||
|
||||
// Summary of failures
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(failures_mutex);
|
||||
if(!failed_packages.empty()) {
|
||||
log_error("Summary of Failures:");
|
||||
for(const auto &entry : failed_packages) {
|
||||
log_error("Package: " + entry.first + " - Reason: " + entry.second);
|
||||
}
|
||||
std::cerr << "Some packages failed during processing. Check the log file for details.\n";
|
||||
return 1;
|
||||
} else {
|
||||
log_info("All packages processed successfully.");
|
||||
}
|
||||
}
|
||||
|
||||
log_info("Script completed successfully.");
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user