-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Repository class refactoring #95
base: master
Are you sure you want to change the base?
Conversation
src/services/repo.cpp
Outdated
|
||
void ELRepoFile::read() | ||
{ | ||
printf("reading\n"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No...
src/services/repo.cpp
Outdated
m_repositories.push_back(std::move(repo)); | ||
} | ||
|
||
for (const auto& r : m_repositories) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would avoid using only r
as variable name. Usually we use it for well defined counters, like: i
, j
and k
. Or for iterators, like it
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is only code for toying with glibmm
In real life, this would not be like this
(This comment applies to every printf/fmt::format comment above)
include/cloysterhpc/services/repo.h
Outdated
class ELRepoFile : public RepoFile<ELRepo> { | ||
private: | ||
Glib::RefPtr<Glib::KeyFile> loadFile(); | ||
|
||
public: | ||
ELRepoFile(const std::filesystem::path& path) | ||
: RepoFile(path) | ||
{ | ||
} | ||
|
||
void read() override; | ||
void write() override; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can have an abstract RepoFile
which extends the File
, adds the m_repositories
generic member, and with parse
unparse
methods, read
is super read
followed by parse
and write
is unparse
followed by super write
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
std::filesystem::path
is convertible to std::string
or const char*
. We must use it. It's the right API.
However the file
class that be dependent on std::filesystem::path
and not the derived one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to be clear
parse
loads data from the file into them_repositories
memberunparse
loads them_repositories
member into the file
Also, @arthurmco, add overloads to parse
and unparse
which I/O into istringstream
ostringstream
instead of directly into the file so we can test without touching the disks. I don't know if this is possible because I don't know the interface of glibmm
if it can load/unload keyfiles from strings, can it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is possible; glibmm can load keyhole data from a string.
src/services/repo.cpp
Outdated
std::vector<ELRepo> ELRepoFile::parse(const std::stringstream& ss) | ||
{ | ||
m_file = Glib::KeyFile::create(); | ||
m_file->load_from_data(ss.str().c_str()); | ||
return this->parseData(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool, now
- Add
m_repositories
member as a vector of ELRepo with a getter - The getter should load the data into the member if the member is empty and return at the end
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inside of ELRepo?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inside ELRepoFile
include/cloysterhpc/services/repo.h
Outdated
struct ELRepo { | ||
std::string group; | ||
std::string name; | ||
std::optional<std::string> baseURL; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
base_url
src/services/repo.cpp
Outdated
auto get_optional_string | ||
= [this](auto group, auto key) -> std::optional<Glib::ustring> { | ||
return m_file->has_key(group, key) | ||
? std::make_optional(m_file->get_string(group, key)) | ||
: std::nullopt; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see why this captures this
, anyway, move it to functions.cpp
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The API looks good, there are a few points
- Make sure to remove the prints
- Rename the ELReo to ELCloneRepo
- Remove the PR from draft
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another issue that I've observed. The virtual classes should be on its own files. This needs to be fixed.
src/services/repo.cpp
Outdated
|
||
std::vector<ELRepo> ELRepoFile::parse() | ||
{ | ||
this->read(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need "this"?
include/cloysterhpc/functions.h
Outdated
@@ -164,6 +166,9 @@ std::string findAndReplace(const std::string_view& source, | |||
*/ | |||
void copyFile(std::filesystem::path source, std::filesystem::path destination); | |||
|
|||
std::optional<Glib::ustring> readKeyfileString(Glib::RefPtr<Glib::KeyFile> file, | |||
const std::string_view& group, const std::string_view& key); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
std:string_view
is already a pointer to a string. It should not be passed as const ref.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't know that. I thought it was pointer+length. It will be fixed
src/functions.cpp
Outdated
@@ -351,4 +351,12 @@ void copyFile(std::filesystem::path source, std::filesystem::path destination) | |||
} | |||
} | |||
|
|||
std::optional<Glib::ustring> readKeyfileString(Glib::RefPtr<Glib::KeyFile> file, | |||
const std::string_view& group, const std::string_view& key) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to be const ref.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See this comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I ended up adding a lot of comments.
I think we should think a little bit more on this implementation.
include/cloysterhpc/file.h
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The class name must match de filename. And also the #ifndef
guards.
I would recommend using a namespace
to avoid clashing.
include/cloysterhpc/file.h
Outdated
virtual void read() { } | ||
virtual void write() { } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be = 0? I can't find the implementation in other files, only the specialization. It should be pure virtual.
include/cloysterhpc/file.h
Outdated
{ | ||
} | ||
|
||
virtual void read() { } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think read will not modify the state of the object right? Should it be const
?
include/cloysterhpc/file.h
Outdated
virtual void read() { } | ||
virtual void write() { } | ||
|
||
virtual ~GenericFile() = default; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since you defaulted a destructor, AFAIK, the move operations are by default deleted. I think we should define the move operations:
GenericFile(GenericFile&&) = default;
GenericFile& operator=(GenericFile&&) = default;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch
src/services/repofile.cpp
Outdated
repo.enabled = enabled; | ||
repo.gpgcheck = gpgcheck; | ||
repo.gpgkey = gpgkey; | ||
repositories.push_back(std::move(repo)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
emplace_back
.
src/services/repofile.cpp
Outdated
} | ||
|
||
[[nodiscard]] const std::vector<ELCloneRepo>& | ||
ELRepoFile::getRepositoriesConst() const |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Having the qualifier in the method name is a very bad approach.
c00412d
to
79954f1
Compare
9d0b02b
to
ecb7a02
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a big one. There's some comments that were probably not from this PR originally, we should mark those as a BUG to be fixed later.
For everything else can you evaluate @dhilst? Don't be economic when naming things, you can abuse it. Avoids guessing. The compiler will optimize anyway.
#ifndef CLOYSTER_CONCEPTS_H | ||
#define CLOYSTER_CONCEPTS_H |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#ifndef CLOYSTER_CONCEPTS_H | |
#define CLOYSTER_CONCEPTS_H | |
/* | |
* Copyright 2025 Vinícius Ferrão <vinicius@ferrao.net.br> | |
* SPDX-License-Identifier: Apache-2.0 | |
*/ | |
#ifndef CLOYSTERHPC_CONCEPTS_H_ | |
#define CLOYSTERHPC_CONCEPTS_H_ |
* @brief IsParser<P, T> means: P can parse and unparse Ts from streams. The | ||
* parsers are allowed to throw exceptions | ||
*/ | ||
template <typename Parser_, typename I, typename O> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I is input and O is output? If yes I think we should use more descriptive names.
* The parsers are not allowed to throw exceptions, it must return errors of | ||
* type E | ||
*/ | ||
template <typename Parser_, typename T, typename E> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is T and E?
Also the naming with _ at the end, is that a convention?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I removed this concept, anyway T is the parsed type and E the error type
|
||
} | ||
|
||
#endif // CLOYSTER_CONCEPTS_H |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#endif // CLOYSTER_CONCEPTS_H | |
#endif // CLOYSTERHPC_CONCEPTS_H_ |
{ "AlmaLinux-8.8-x86_64-dvd.iso", "OracleLinux-R8-U8-x86_64-dvd.iso", | ||
"rhel-8.8-x86_64-dvd.iso", "Rocky-8.8-x86_64-dvd1.iso", | ||
"Rocky-9.5-x86_64-dvd.iso" }) }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should be better organized or generated since it's a pattern and not hardcoded like that. I know it's a problem from legacy code. But maybe this should be removed.
case OS::Platform::el8: | ||
case OS::Platform::el9: | ||
case OS::Platform::el10: | ||
return "/etc/yum.repos.d/cloyster.repo"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this will explicit return as const char*
. Should we force it to return an std::string
?
std::vector<std::string> dependencies; | ||
|
||
std::size_t version = osinfo.getMajorVersion(); | ||
std::string powertools = "powertools"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That logic is not good at all.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
void RepoManager::enable(const std::string& repoid) | ||
{ | ||
if (cloyster::dryRun) { | ||
LOG_WARN("Dry Run: Would enable repository {}", repoid); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should all dry run statements be LOG_INFO
instead? It's not a warning.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is because I standardized all the dry-run logging messages to be warning and have Dry Run: as the prefix, for the sake of consistency
return std::vector<std::string>( | ||
{ "-beegfs", "-elrepo", "-epel", "-openhpc", | ||
"-openhpc-updates", "-rpmfusion-free-updates" }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's temporary?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is not. These are the repositories enabled by default in EL distros, it comes from old/refactored code. Is it wrong?
* Add script to build rpms * Fix debug build * Link against host Glibmm using pkg-config * Extract glibmm from diskImage, move it to files.cpp --------- Co-authored-by: Daniel Hilst <daniel@versatushpc.com.br>
|
@viniciusferrao Changing the smart pointers in the postfix (for the client bus) requires refactoring and changing the IService interface. Replacing shared with unique pointers in the presenter requires a major refactoring too because these classes should not have ownership of these objects I will address these problems in another PR |
This is a HUGE refactoring adding some structure to the code base (namespace and folders) and removing old RepoManager code
RepoManager
over the repository type and the runner,cloyster::models
andcloyster::services
to start splitting the code according to the model-view-presenter architectureKeyFile
implementation hiding glibmm KeyFile (files.h/files.cpp)concepts.h
header for general conceptsCATTUS_SKIP_DISK_CHECKSUM
environment to skip checksum of the ISO--test-conf-file
for testing KeyFile implementation against arbitrary files (it loads and prints the file)