From 946235318a5970f92d22904ace7ee26dd8c82141 Mon Sep 17 00:00:00 2001 From: Simon Quigley Date: Mon, 10 Feb 2025 15:08:36 -0600 Subject: [PATCH] Move common filesystem utilities from utilities to a new fs_common --- cpp/CMakeLists.txt | 1 + cpp/ci_logic.cpp | 1 + cpp/fetch-indexes.cpp | 1 + cpp/fs_common.cpp | 100 ++++++++++++++++++++++++++++++++++ cpp/fs_common.h | 40 ++++++++++++++ cpp/update-maintainer-lib.cpp | 15 +---- cpp/utilities.cpp | 92 ------------------------------- cpp/utilities.h | 25 ++------- 8 files changed, 148 insertions(+), 127 deletions(-) create mode 100644 cpp/fs_common.cpp create mode 100644 cpp/fs_common.h diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 9cf932a..5a927bf 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -42,6 +42,7 @@ set(UUID_LIB "uuid") add_library(lubuntuci_lib SHARED utilities.cpp db_common.cpp + fs_common.cpp git_common.cpp tar_common.cpp sources_parser.cpp diff --git a/cpp/ci_logic.cpp b/cpp/ci_logic.cpp index 9166a08..ac2204d 100644 --- a/cpp/ci_logic.cpp +++ b/cpp/ci_logic.cpp @@ -16,6 +16,7 @@ #include "ci_logic.h" #include "db_common.h" #include "git_common.h" +#include "fs_common.h" #include "tar_common.h" #include "task_queue.h" #include "utilities.h" diff --git a/cpp/fetch-indexes.cpp b/cpp/fetch-indexes.cpp index 07ed9e8..36db10b 100644 --- a/cpp/fetch-indexes.cpp +++ b/cpp/fetch-indexes.cpp @@ -13,6 +13,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +#include "fs_common.h" #include "utilities.h" #include "launchpad.h" diff --git a/cpp/fs_common.cpp b/cpp/fs_common.cpp new file mode 100644 index 0000000..a82f57c --- /dev/null +++ b/cpp/fs_common.cpp @@ -0,0 +1,100 @@ +// Copyright (C) 2025 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 +#include +#include +#include +#include +#include +#include +#include + +#include "fs_common.h" +#include "utilities.h" + +namespace fs = std::filesystem; + +// Function to read the entire content of a file into a string +std::string read_file(const fs::path& file_path) { + std::ifstream in_file(file_path, std::ios::binary); + if (in_file) return std::string((std::istreambuf_iterator(in_file)), + std::istreambuf_iterator()); + return ""; +} + +// Function to write a string into a file +void write_file(const fs::path& file_path, const std::string& content) { + std::ofstream out_file(file_path, std::ios::binary); + if (out_file) out_file << content; +} + +// Function to perform in-place regex replace on a file +void regex_replace_in_file(const fs::path& file_path, const std::string& pattern, const std::string& replacement) { + std::string content = read_file(file_path); + content = std::regex_replace(content, std::regex(pattern), replacement); + write_file(file_path, content); +} + +std::filesystem::path create_temp_directory() { + auto temp_dir = std::filesystem::temp_directory_path() / generate_random_string(32); + std::filesystem::create_directory(temp_dir); + return temp_dir; +} + +// Function to copy a directory recursively +void copy_directory(const fs::path& source, const fs::path& destination) { + if (!std::filesystem::exists(source) || !std::filesystem::is_directory(source)) throw std::runtime_error("Source directory does not exist or is not a directory: " + source.string()); + + // Create the destination directory + std::filesystem::create_directories(destination); + + // Copy files and directories recursively + for (const auto& entry : std::filesystem::recursive_directory_iterator(source)) { + auto relative_path = std::filesystem::relative(entry.path(), source); + auto target_path = destination / relative_path; + + try { + if (std::filesystem::is_directory(entry)) std::filesystem::create_directory(target_path); + else if (std::filesystem::is_regular_file(entry)) std::filesystem::copy(entry, target_path, std::filesystem::copy_options::overwrite_existing); + } catch (...) { + continue; + } + } +} + +// Function to extract excluded files from a copyright file +std::vector extract_files_excluded(const std::string& filepath) { + std::ifstream file(filepath); + if (!file.is_open()) throw std::runtime_error("Failed to open file: " + filepath); + + std::vector files_excluded; + std::string line; + std::regex files_excluded_pattern(R"(Files-Excluded:\s*(.*))"); + bool in_files_excluded = false; + + while (std::getline(file, line)) { + if (std::regex_match(line, files_excluded_pattern)) { + in_files_excluded = true; + std::smatch match; + if (std::regex_search(line, match, files_excluded_pattern) && match.size() > 1) files_excluded.emplace_back(match[1]); + } else if (in_files_excluded) { + if (!line.empty() && (line[0] == ' ' || line[0] == '\t')) files_excluded.emplace_back(line.substr(1)); + else break; // End of Files-Excluded block + } + } + + return files_excluded; +} diff --git a/cpp/fs_common.h b/cpp/fs_common.h new file mode 100644 index 0000000..302dbc7 --- /dev/null +++ b/cpp/fs_common.h @@ -0,0 +1,40 @@ +// Copyright (C) 2024-2025 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 . + +#pragma once + +#include +#include +#include + +namespace fs = std::filesystem; + +// Function to read the entire content of a file into a string +std::string read_file(const std::filesystem::path& file_path); + +// Function to write a string into a file +void write_file(const std::filesystem::path& file_path, const std::string& content); + +// Function to perform in-place regex replace on a file +void regex_replace_in_file(const std::filesystem::path& file_path, const std::string& pattern, const std::string& replace); + +// Function to create a temporary directory with a random name +std::filesystem::path create_temp_directory(); + +// Function to copy a directory recursively +void copy_directory(const std::filesystem::path& source, const std::filesystem::path& destination); + +// Function to extract excluded files from a copyright file +std::vector extract_files_excluded(const std::string& filepath); diff --git a/cpp/update-maintainer-lib.cpp b/cpp/update-maintainer-lib.cpp index 617d35d..2cc1087 100644 --- a/cpp/update-maintainer-lib.cpp +++ b/cpp/update-maintainer-lib.cpp @@ -13,6 +13,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +#include "fs_common.h" #include "update-maintainer-lib.h" #include #include @@ -56,20 +57,6 @@ static bool xsbc_managed_by_rules(const fs::path &debian_dir) { return false; } -static std::string read_file(const fs::path &p) { - std::ifstream f(p); - if(!f) throw std::runtime_error("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 std::runtime_error("Cannot write file: " + p.string()); - f << content; -} - static void update_maintainer_file(const fs::path &control_file, bool verbose) { std::string c = read_file(control_file); diff --git a/cpp/utilities.cpp b/cpp/utilities.cpp index 28a5245..e44b7a8 100644 --- a/cpp/utilities.cpp +++ b/cpp/utilities.cpp @@ -41,33 +41,6 @@ static std::counting_semaphore<10> sem(10); static std::mutex queue_mutex; static std::atomic daemon_running{false}; -// Function to read the entire content of a file into a string -std::string read_file(const fs::path& file_path) { - std::ifstream in_file(file_path, std::ios::binary); - if (in_file) { - return std::string((std::istreambuf_iterator(in_file)), - std::istreambuf_iterator()); - } - return ""; -} - -// Function to write a string into a file -void write_file(const fs::path& file_path, const std::string& content) { - std::ofstream out_file(file_path, std::ios::binary); - if (out_file) { - out_file << content; - } -} - -// Function to perform in-place regex replace on a file -void regex_replace_in_file(const fs::path& file_path, - const std::string& pattern, - const std::string& replacement) { - std::string content = read_file(file_path); - content = std::regex_replace(content, std::regex(pattern), replacement); - write_file(file_path, content); -} - // Function to decompress gzipped files std::string decompress_gzip(const fs::path& file_path) { gzFile infile = gzopen(file_path.c_str(), "rb"); @@ -151,38 +124,6 @@ void download_file_with_timestamping(const std::string& url, } } -std::filesystem::path create_temp_directory() { - auto temp_dir = std::filesystem::temp_directory_path() / generate_random_string(32); - std::filesystem::create_directory(temp_dir); - return temp_dir; -} - -// Function to copy a directory recursively -void copy_directory(const fs::path& source, const fs::path& destination) { - if (!std::filesystem::exists(source) || !std::filesystem::is_directory(source)) { - throw std::runtime_error("Source directory does not exist or is not a directory: " + source.string()); - } - - // Create the destination directory - std::filesystem::create_directories(destination); - - // Copy files and directories recursively - for (const auto& entry : std::filesystem::recursive_directory_iterator(source)) { - auto relative_path = std::filesystem::relative(entry.path(), source); - auto target_path = destination / relative_path; - - try { - if (std::filesystem::is_directory(entry)) { - std::filesystem::create_directory(target_path); - } else if (std::filesystem::is_regular_file(entry)) { - std::filesystem::copy(entry, target_path, std::filesystem::copy_options::overwrite_existing); - } - } catch (...) { - continue; - } - } -} - // Function to generate a random string of given length std::string generate_random_string(size_t length) { const std::string chars = @@ -301,8 +242,6 @@ void log_verbose(const std::string &msg) { } } -namespace fs = std::filesystem; - bool run_command(const std::vector &cmd, const std::optional &cwd, bool show_output, @@ -368,34 +307,3 @@ bool run_command(const std::vector &cmd, return true; } - -// Function to extract excluded files from a copyright file -std::vector extract_files_excluded(const std::string& filepath) { - std::ifstream file(filepath); - if (!file.is_open()) { - throw std::runtime_error("Failed to open file: " + filepath); - } - - std::vector files_excluded; - std::string line; - std::regex files_excluded_pattern(R"(Files-Excluded:\s*(.*))"); - bool in_files_excluded = false; - - while (std::getline(file, line)) { - if (std::regex_match(line, files_excluded_pattern)) { - in_files_excluded = true; - std::smatch match; - if (std::regex_search(line, match, files_excluded_pattern) && match.size() > 1) { - files_excluded.emplace_back(match[1]); - } - } else if (in_files_excluded) { - if (!line.empty() && (line[0] == ' ' || line[0] == '\t')) { - files_excluded.emplace_back(line.substr(1)); - } else { - break; // End of Files-Excluded block - } - } - } - - return files_excluded; -} diff --git a/cpp/utilities.h b/cpp/utilities.h index 8a5493a..db2703e 100644 --- a/cpp/utilities.h +++ b/cpp/utilities.h @@ -15,14 +15,15 @@ #pragma once -#include #include +#include +#include #include #include -#include #include #include -#include +#include + #include namespace fs = std::filesystem; @@ -68,15 +69,6 @@ public: } }; -// Function to read the entire content of a file into a string -std::string read_file(const std::filesystem::path& filePath); - -// Function to write a string into a file -void write_file(const std::filesystem::path& filePath, const std::string& content); - -// Function to perform in-place regex replace on a file -void regex_replace_in_file(const std::filesystem::path& filePath, const std::string& pattern, const std::string& replace); - // Function to decompress gzipped files std::string decompress_gzip(const std::filesystem::path& filePath); @@ -87,12 +79,6 @@ void download_file_with_timestamping(const std::string& url, const std::filesyst // Helper function for libcurl write callback size_t write_data(void* ptr, size_t size, size_t nmemb, void* stream); -// Function to create a temporary directory with a random name -std::filesystem::path create_temp_directory(); - -// Function to copy a directory recursively -void copy_directory(const std::filesystem::path& source, const std::filesystem::path& destination); - // String utilities std::vector split_string(const std::string& input, const std::string& delimiter); std::string remove_suffix(const std::string& input, const std::string& suffix); @@ -115,6 +101,3 @@ bool run_command(const std::vector &cmd, const std::optional &cwd = std::nullopt, bool show_output = false, std::shared_ptr log = nullptr); - -// Function to extract excluded files from a copyright file -std::vector extract_files_excluded(const std::string& filepath);