Skip to content
This repository was archived by the owner on Apr 16, 2026. It is now read-only.

Commit a696419

Browse files
committed
Save RPMRepositoryFile only once for multiple enable calls
1 parent 17de642 commit a696419

2 files changed

Lines changed: 74 additions & 20 deletions

File tree

src/services/files.cpp

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,6 @@ KeyFile::KeyFile(const std::filesystem::path& path)
6565
m_impl->loadFromFile(path);
6666
}
6767

68-
// KeyFile::KeyFile(const std::string& input)
69-
// : m_impl(std::make_unique<KeyFile::Impl>(Glib::KeyFile::create(),
70-
// std::filesystem::path()))
71-
// {
72-
// m_impl->loadFromData(input);
73-
// }
74-
7568
KeyFile::~KeyFile() = default;
7669

7770
namespace {

src/services/repos.cpp

Lines changed: 74 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
#include <algorithm>
77
#include <filesystem>
8-
#include <fstream>
98
#include <memory>
109
#include <ranges>
1110
#include <sstream>
@@ -33,6 +32,7 @@ using cloyster::services::repos::IRepository;
3332

3433
namespace cloyster::services::repos {
3534

35+
// Represents a debian repository file
3636
class DebianRepository : public IRepository {
3737
private:
3838
std::string m_type; // "deb" or "deb-src"
@@ -61,6 +61,7 @@ class DebianRepository : public IRepository {
6161
void source(const std::filesystem::path value) override;
6262
};
6363

64+
// Represents a RPM Repository inside a repository file (/etc/yum.repo.d/*.repo)
6465
class RPMRepository final : public IRepository {
6566
std::string m_id;
6667
bool m_enabled = true;
@@ -126,16 +127,14 @@ class RPMRepository final : public IRepository {
126127
{
127128
return other.id() == id();
128129
}
129-
130-
131130
};
132131

133132
namespace {
134133

135134
// Easy conversions for string
136135
std::ostream& operator<<(std::ostream& ostr, const RPMRepository& repo)
137136
{
138-
ostr << "RPMRepository( ";
137+
ostr << "RPMRepository(";
139138
ostr << repo.id() << " ";
140139
ostr << repo.name() << " ";
141140
ostr << repo.baseurl().value_or("") << " ";
@@ -155,7 +154,7 @@ std::string toString(const T& input)
155154

156155
};
157156

158-
// Parses .repo files
157+
// Parses RPM .repo files
159158
class RPMRepositoryParser final {
160159
public:
161160
static void parse(
@@ -213,8 +212,6 @@ class RPMRepositoryParser final {
213212
}
214213

215214
file.save();
216-
217-
LOG_DEBUG("UNPARSE FILE {}:\n{}", path.string(), file.toData());
218215
}
219216
};
220217
static_assert(IsParser<RPMRepositoryParser, std::filesystem::path,
@@ -232,6 +229,11 @@ class RPMRepositoryFile final {
232229
m_parser.parse(m_path, m_repos);
233230
}
234231

232+
const auto& path()
233+
{
234+
return m_path;
235+
}
236+
235237
auto& repos()
236238
{
237239
return m_repos;
@@ -325,11 +327,28 @@ class RPMRepoManager final {
325327
repofile->save();
326328
}
327329

330+
// Enable a repo but dot not save the repofile, (used internally)
331+
void enable(const auto& repo, auto& repofile, bool value)
332+
{
333+
LOG_DEBUG("Enabling/Disabling[{}] RPM repo {}",
334+
value, repo);
335+
repofile->repo(repo)->enabled(value);
336+
}
337+
328338
// Enable/disable multiple repositories by name
329339
void enable(const std::vector<std::string>& repos, bool value)
330340
{
341+
auto byIdPtr = [](const std::shared_ptr<RPMRepositoryFile>& rptr) {
342+
return std::hash<std::string>{}(rptr->path());
343+
};
344+
std::unordered_set<std::shared_ptr<RPMRepositoryFile>, decltype(byIdPtr)> toSave;
331345
for (const auto& repo : repos) {
332-
enable(repo, value);
346+
auto& rfile = m_filesIdx.at(repo);
347+
toSave.emplace(rfile);
348+
enable(repo, rfile, value);
349+
}
350+
for (const auto& repoFil : toSave) {
351+
repoFil->save();
333352
}
334353
}
335354

@@ -360,8 +379,6 @@ class RPMRepoManager final {
360379

361380
namespace {
362381

363-
using cloyster::services::repos::RPMRepository;
364-
365382
// These files contains the repositories files data as
366383
// format strings with which we inject the values for
367384
constexpr std::string_view CLOYSTER_REPO_EL8 = {
@@ -439,6 +456,7 @@ std::vector<std::string> getDependenciesEL(const OS& osinfo)
439456

440457
namespace cloyster::services::repos {
441458

459+
// Hidden implementation
442460
struct RepoManager::Impl {
443461
RPMRepoManager rpm;
444462
// Add debian repo manager here when the day arrives
@@ -531,7 +549,29 @@ void RepoManager::enable(const std::string& repoid)
531549

532550
void RepoManager::enable(const std::vector<std::string>& repos)
533551
{
534-
std::ranges::for_each(repos, [&](const auto& repoid) { enable(repoid); });
552+
if (cloyster::dryRun) {
553+
LOG_WARN("Dry Run: Would enable these repos: {}",
554+
fmt::join(repos, ","));
555+
return;
556+
}
557+
try {
558+
switch (m_os.getPackageType()) {
559+
case OS::PackageType::RPM:
560+
m_impl->rpm.enable(repos, true);
561+
break;
562+
default:
563+
throw std::logic_error("Not implemented");
564+
565+
}
566+
} catch (const std::out_of_range&) {
567+
LOG_ERROR("Trying to enable unknown repository {}, "
568+
"failed because the repository was not found.",
569+
fmt::join(repos, ","));
570+
571+
for (const auto& [id, _] : m_repos) {
572+
LOG_ERROR("Repository available: {}", id);
573+
}
574+
}
535575
}
536576

537577
void RepoManager::disable(const std::string& repoid)
@@ -563,8 +603,29 @@ void RepoManager::disable(const std::string& repoid)
563603

564604
void RepoManager::disable(const std::vector<std::string>& repos)
565605
{
566-
std::ranges::for_each(
567-
repos, [&](const auto& repoid) { disable(repoid); });
606+
if (cloyster::dryRun) {
607+
LOG_WARN("Dry Run: Would enable repository {}", fmt::join(repos, ","));
608+
return;
609+
}
610+
611+
try {
612+
switch (m_os.getPackageType()) {
613+
case OS::PackageType::RPM:
614+
m_impl->rpm.enable(repos, false);
615+
break;
616+
default:
617+
throw std::logic_error("Not implemented");
618+
619+
}
620+
} catch (const std::out_of_range&) {
621+
LOG_ERROR("Trying to disable unknown repository {}, "
622+
"failed because the repository was not found.",
623+
fmt::join(repos, ","));
624+
625+
for (const auto& [id, _] : m_repos) {
626+
LOG_ERROR("Repository available: {}", id);
627+
}
628+
}
568629
}
569630

570631
void RepoManager::install(const std::filesystem::path& path)

0 commit comments

Comments
 (0)