ostern ...

This commit is contained in:
Gerhard Hoffmann 2024-03-28 16:45:46 +01:00
parent 5338c30e79
commit 7ba9cb8147
7 changed files with 259 additions and 94 deletions

View File

@ -28,12 +28,14 @@ CONFIG += c++20 console
SOURCES += \ SOURCES += \
calculator_c_interface_lib.cpp \ calculator_c_interface_lib.cpp \
git_library.cpp \
tariff_calculator.cpp \ tariff_calculator.cpp \
local_git_repository.cpp local_git_repository.cpp
HEADERS += \ HEADERS += \
calculator_c_interface_lib.h \ calculator_c_interface_lib.h \
calculator_c_interface_lib_global.h \ calculator_c_interface_lib_global.h \
git_library.h \
tariff_calculator.h \ tariff_calculator.h \
local_git_repository.h local_git_repository.h

View File

@ -1,4 +1,6 @@
#include "calculator_c_interface_lib.h" #include "calculator_c_interface_lib.h"
#include "local_git_repository.h"
#include "git_library.h"
//#include <git2/common.h> //#include <git2/common.h>
@ -275,51 +277,17 @@ void DeleteTariffCalculator(TariffCalculatorHandle handle) {
delete handle; delete handle;
} }
int InitGitLibrary(void) { int InitGitLibraryInternal(void) {
return git_libgit2_init(); return GitLibrary::Init();
} }
int ShutdownGitLibrary(void) { int ShutdownGitLibraryInternal(void) {
LocalGitRepository::DestroyAllRepositories();
for (auto key : customerRepoMap.keys()) { return GitLibrary::Shutdown();
git_repository_free(customerRepoMap.value(key));
}
customerRepoMap.clear();
return git_libgit2_shutdown();
} }
int CloneRepository(char const *url, char const *local_path) { int CloneRepositoryInternal(char const *url, char const *local_path) {
return GitLibrary::CloneRepository(url, local_path);
QString localRepoPath(QDir::cleanPath(QString(local_path) + QDir::separator() + ".git"));
QDir localRepoDir(localRepoPath);
if (localRepoDir.exists()) {
fprintf(stderr, "local repository path %s already exists\n",
localRepoPath.toUtf8().constData());
return -1;
}
git_repository *out;
git_clone_options opts;
int res = 0;
if ((res = git_clone_options_init(&opts, GIT_CLONE_OPTIONS_VERSION)) == 0) {
opts.checkout_branch = "master";
fprintf(stderr, "%s:%d %s %s\n", __func__, __LINE__, url, local_path);
if ((res = git_clone(&out, url, local_path, &opts)) < 0) {
git_error const *error = git_error_last();
fprintf(stderr, "%s:%d error: %s\n", __func__, __LINE__, error->message);
} else {
QString localRepoPath = QDir::cleanPath(QString(local_path) + QDir::separator() + ".git");
customerRepoMap.insert(localRepoPath, out);
}
} else {
git_error const *error = git_error_last();
fprintf(stderr, "%s:%d error: %s\n", __func__, __LINE__, error->message);
}
return res;
} }
int CheckoutLocalBranch(char const *local_path, char const *branch_name) { int CheckoutLocalBranch(char const *local_path, char const *branch_name) {
@ -596,38 +564,25 @@ int PushLocalRepository(char const *local_path, char const *branch_name, char co
#include <local_git_repository.h> #include <local_git_repository.h>
static QMap<QString, LocalGitRepository *> localGitRepos;
void SetReposRootDirectoryInternal(char const *p) { void SetReposRootDirectoryInternal(char const *p) {
LocalGitRepository::SetReposRootDirectory(QString::fromUtf8(p)); LocalGitRepository::SetReposRootDirectory(QString::fromUtf8(p));
} }
char const *GetReposRootDirectoryInternal() { char const *GetReposRootDirectoryInternal() {
return LocalGitRepository::GetReposRootDirectory().toUtf8().constData(); return (char const *)LocalGitRepository::GetReposRootDirectory().constData();
} }
char const *GetLocalRepositoryPathInternal(char const *localGitRepo) { char const *GetLocalRepositoryPathInternal(char const *localGitRepo) {
if (localGitRepos.count(localGitRepo) == 0) { return (char const *)LocalGitRepository::GetInstance(localGitRepo)->localRepositoryPath().constData();
localGitRepos.insert(localGitRepo,
new LocalGitRepository(localGitRepo));
}
return localGitRepos[localGitRepo]->localRepositoryPath().toUtf8().constData();
} }
int32_t GetFileMenuSizeInternal(char const *localGitRepo) { int32_t GetFileMenuSizeInternal(char const *localGitRepo) {
if (localGitRepos.count(localGitRepo) == 0) { return LocalGitRepository::GetInstance(localGitRepo)->GetFileMenuSizeInternal();
localGitRepos.insert(localGitRepo,
new LocalGitRepository(localGitRepo));
}
return localGitRepos[localGitRepo]->GetFileMenuSizeInternal();
} }
char const *GetFileMenuInternal(const char *localGitRepo) { char const *GetFileMenuInternal(const char *localGitRepo) {
if (localGitRepos.count(localGitRepo) == 0) { QByteArray const &a = LocalGitRepository::GetInstance(localGitRepo)->GetFileMenuInternal().constData();
localGitRepos.insert(localGitRepo,
new LocalGitRepository(localGitRepo));
}
QByteArray const &a = localGitRepos[localGitRepo]->GetFileMenuInternal().constData();
if (a.isValidUtf8()) { if (a.isValidUtf8()) {
int const len = GetFileMenuSizeInternal(localGitRepo); int const len = GetFileMenuSizeInternal(localGitRepo);
if (len > 0) { if (len > 0) {
@ -643,11 +598,7 @@ char const *GetFileMenuInternal(const char *localGitRepo) {
char const *GetFileNameInternal(char const *localGitRepo, char const *fileId) { char const *GetFileNameInternal(char const *localGitRepo, char const *fileId) {
if (localGitRepos.count(localGitRepo) == 0) { QByteArray const &a = LocalGitRepository::GetInstance(localGitRepo)->GetFileNameInternal(fileId);
localGitRepos.insert(localGitRepo,
new LocalGitRepository(localGitRepo));
}
QByteArray const &a = localGitRepos[localGitRepo]->GetFileNameInternal(fileId);
if (a.isValidUtf8()) { if (a.isValidUtf8()) {
char *c = new char[a.size() + 1]; char *c = new char[a.size() + 1];
memset(c, 0x00, a.size() + 1); memset(c, 0x00, a.size() + 1);
@ -658,19 +609,11 @@ char const *GetFileNameInternal(char const *localGitRepo, char const *fileId) {
} }
int32_t GetFileSize(char const *localGitRepo, char const *fileId) { int32_t GetFileSize(char const *localGitRepo, char const *fileId) {
if (localGitRepos.count(localGitRepo) == 0) { return LocalGitRepository::GetInstance(localGitRepo)->GetFileSize(fileId);
localGitRepos.insert(localGitRepo,
new LocalGitRepository(localGitRepo));
}
return localGitRepos[localGitRepo]->GetFileSize(fileId);
} }
char const *GetFileInternal(char const *localGitRepo, char const *fileId) { char const *GetFileInternal(char const *localGitRepo, char const *fileId) {
if (localGitRepos.count(localGitRepo) == 0) { QByteArray const &a = LocalGitRepository::GetInstance(localGitRepo)->GetFileInternal(fileId);
localGitRepos.insert(localGitRepo,
new LocalGitRepository(localGitRepo));
}
QByteArray const &a = localGitRepos[localGitRepo]->GetFileInternal(fileId);
if (a.isValidUtf8()) { if (a.isValidUtf8()) {
char *c = new char[a.size() + 1]; char *c = new char[a.size() + 1];
memset(c, 0x00, a.size() + 1); memset(c, 0x00, a.size() + 1);
@ -681,11 +624,7 @@ char const *GetFileInternal(char const *localGitRepo, char const *fileId) {
} }
bool SetFileInternal(char const *localGitRepo, char const *fileId, char const *json, int size) { bool SetFileInternal(char const *localGitRepo, char const *fileId, char const *json, int size) {
if (localGitRepos.count(localGitRepo) == 0) { return LocalGitRepository::GetInstance(localGitRepo)->SetFileInternal(QString(fileId), QByteArray(json, size));
localGitRepos.insert(localGitRepo,
new LocalGitRepository(localGitRepo));
}
return localGitRepos[localGitRepo]->SetFileInternal(QString(fileId), QByteArray(json, size));
} }
void DeleteMem(char *p) { void DeleteMem(char *p) {

View File

@ -27,9 +27,9 @@ TariffCalculatorHandle NewTariffCalculator(void) CALCULATOR_C_INTERFACE_LIB_EXPO
void DeleteTariffCalculator(TariffCalculatorHandle handle) CALCULATOR_C_INTERFACE_LIB_EXPORT; void DeleteTariffCalculator(TariffCalculatorHandle handle) CALCULATOR_C_INTERFACE_LIB_EXPORT;
// libgit2 // libgit2
int InitGitLibrary(void) CALCULATOR_C_INTERFACE_LIB_EXPORT; int InitGitLibraryInternal(void) CALCULATOR_C_INTERFACE_LIB_EXPORT;
int ShutdownGitLibrary(void) CALCULATOR_C_INTERFACE_LIB_EXPORT; int ShutdownGitLibraryInternal(void) CALCULATOR_C_INTERFACE_LIB_EXPORT;
int CloneRepository(char const *url, char const *local_path) CALCULATOR_C_INTERFACE_LIB_EXPORT; int CloneRepositoryInternal(char const *url, char const *local_path) CALCULATOR_C_INTERFACE_LIB_EXPORT;
int CheckoutLocalBranch(char const *local_path, char const *branch) CALCULATOR_C_INTERFACE_LIB_EXPORT; int CheckoutLocalBranch(char const *local_path, char const *branch) CALCULATOR_C_INTERFACE_LIB_EXPORT;
int CommitFile(char const *local_path, char const *branch_name, char const *file_name, char const *commit_message) CALCULATOR_C_INTERFACE_LIB_EXPORT; int CommitFile(char const *local_path, char const *branch_name, char const *file_name, char const *commit_message) CALCULATOR_C_INTERFACE_LIB_EXPORT;
int PushLocalRepository(char const *local_path, char const *branch_name, char const *user, char const *password) CALCULATOR_C_INTERFACE_LIB_EXPORT; int PushLocalRepository(char const *local_path, char const *branch_name, char const *user, char const *password) CALCULATOR_C_INTERFACE_LIB_EXPORT;

View File

@ -0,0 +1,93 @@
#include "git_library.h"
#include "local_git_repository.h"
#include <QDir>
#include <QDebug>
#include <git2.h>
int GitLibrary::Init() {
return git_libgit2_init();
}
int GitLibrary::Shutdown() {
return git_libgit2_shutdown();
}
int GitLibrary::CheckoutRepository(char const *localRepoName, char const *branchName) {
QString localRepo(localRepoName);
QDir localRepoDir;
if (strstr(localRepoName, "customer_") == localRepoName) { // localRepoPath starts with 'customer_'
QString const &p = QDir::cleanPath(LocalGitRepository::GetReposRootDirectory()
+ QDir::separator() + localRepoName);
localRepoDir.setPath(p);
} else {
qCritical() << __func__ << ":" << __LINE__
<< "localRepoPath" << localRepoDir.path() << "either not absolute"
<< "or not starting with customer_*";
return -1;
}
}
int GitLibrary::CloneRepository(char const *url, char const *localRepoPath /* absolute path or repo-name */) {
QString localRepoName;
QDir localRepoDir;
if (strstr(localRepoPath, "customer_") == localRepoPath) { // localRepoPath starts with 'customer_'
QString const &p = QDir::cleanPath(LocalGitRepository::GetReposRootDirectory()
+ QDir::separator() + localRepoPath);
localRepoDir.setPath(p);
localRepoName = localRepoPath;
} else if (QDir::isAbsolutePath(localRepoPath) &&
strstr(localRepoPath, "/customer_") != localRepoPath) {
localRepoDir.setPath(localRepoPath);
localRepoName = localRepoDir.dirName(); // extract e.g. customer_999
} else {
qCritical() << __func__ << ":" << __LINE__
<< "localRepoPath" << localRepoPath << "either not absolute"
<< "or not starting with customer_*";
return -1;
}
if (!QDir(localRepoDir).exists()) {
if (!QDir().mkpath(localRepoDir.absolutePath())) {
qCritical() << __func__ << ":" << __LINE__
<< "can not create git-repositories-root-dir" << localRepoDir;
return -1;
}
}
QDir gitDir(QDir::cleanPath(localRepoDir.absolutePath() + QDir::separator() + ".git"));
if (gitDir.exists()) {
qCritical() << __func__ << ":" << __LINE__
<< "local repository" << gitDir.path() << "already exists,"
<< "no clone necessary";
return -1;
}
int res = 0;
QDir const &current = QDir::current();
git_clone_options opts;
if ((res = git_clone_options_init(&opts, GIT_CLONE_OPTIONS_VERSION)) == 0) {
opts.checkout_branch = "master";
if (QDir::setCurrent(localRepoDir.absolutePath())) {
git_repository *out = LocalGitRepository::GetInstance(localRepoName)->GetGitRepository();
if ((res = git_clone(&out, url, ".", &opts)) < 0) {
git_error const *error = git_error_last();
qCritical() << __func__ << ":" << __LINE__ << error->message << localRepoDir.absolutePath();
}
QDir::setCurrent(current.absolutePath());
} else {
qCritical() << __func__ << ":" << __LINE__
<< "ERROR setCurrent" << localRepoDir.absolutePath();
res = -1;
}
} else {
git_error const *error = git_error_last();
qCritical() << __func__ << ":" << __LINE__ << error->message;
}
return res;
}

View File

@ -0,0 +1,24 @@
#ifndef GIT_LIBRARY_H_INCLUDED
#define GIT_LIBRARY_H_INCLUDED
#include <QByteArray>
#include <QString>
#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonObject>
#include <QDir>
#include <git2.h>
class GitLibrary {
public:
static int Init();
static int Shutdown();
static int CloneRepository(char const *url, char const *localRepoName);
static int CheckoutRepository(char const *localRepoName, char const *branchName);
// explicit GitLibrary();
// ~GitLibrary();
};
#endif // #define GIT_LIBRARY_H_INCLUDED

View File

@ -1,5 +1,7 @@
#include "local_git_repository.h" #include "local_git_repository.h"
#include "git_library.h"
#include <QDebug>
#include <QDir> #include <QDir>
#include <QFile> #include <QFile>
#include <QTextStream> #include <QTextStream>
@ -10,20 +12,107 @@
#include <QFile> #include <QFile>
QString LocalGitRepository::m_repoRootDirectory = "H:\\"; QString LocalGitRepository::repoRootDirectory = "";
QMap<QString, LocalGitRepository *> LocalGitRepository::localGitRepos;
QMap<QString, LocalGitRepository *> &LocalGitRepository::GetLocalGitRepos() {
return localGitRepos;
}
void LocalGitRepository::SetReposRootDirectory(QString s) { void LocalGitRepository::SetReposRootDirectory(QString s) {
m_repoRootDirectory = s; if (repoRootDirectory.isEmpty()) {
repoRootDirectory = s;
return;
}
qCritical() << __func__ << ":" << __LINE__
<< "ERROR git-repository-root-directory already set"
<< repoRootDirectory;
} }
QString LocalGitRepository::GetReposRootDirectory() { QString LocalGitRepository::GetReposRootDirectory() {
return m_repoRootDirectory; return repoRootDirectory;
} }
LocalGitRepository::LocalGitRepository(QString const &localRepository) LocalGitRepository::LocalGitRepository(QString const &localRepository)
: m_localRepository(localRepository) : m_localRepository(localRepository)
, m_fileMenu("{}") , m_fileMenu("{}")
, m_fileMenuSize(-1) { , m_fileMenuSize(-1)
, m_git_repository(nullptr) {
}
LocalGitRepository::~LocalGitRepository() {
}
void LocalGitRepository::SetGitRepository(git_repository *git_repo) {
m_git_repository = git_repo;
}
git_repository const *LocalGitRepository::GetGitRepository() const {
return m_git_repository;
}
git_repository *LocalGitRepository::GetGitRepository() {
return m_git_repository;
}
QString LocalGitRepository::localRepositoryName() const { // e.g. customer_999
return m_localRepository;
}
QString LocalGitRepository::localRepositoryPath() const {
if (!repoRootDirectory.isEmpty()) {
return QDir::cleanPath(repoRootDirectory + QDir::separator() + m_localRepository);
}
qCritical() << __func__ << ":" << __LINE__
<< "ERROR git-repository-root-directory not set";
return "";
}
QString LocalGitRepository::localRepositoryPath(QString const &localRepository) {
if (!repoRootDirectory.isEmpty()) {
return QDir::cleanPath(repoRootDirectory + QDir::separator() + localRepository);
}
qCritical() << __func__ << ":" << __LINE__
<< "ERROR git-repository-root-directory not set";
return "";
}
LocalGitRepository *LocalGitRepository::GetInstance(QString const& localRepository) {
LocalGitRepository *repo = nullptr;
if (GetLocalGitRepos().count(localRepository) > 0) {
repo = GetLocalGitRepos()[localRepository];
} else {
repo = new LocalGitRepository(localRepository);
qCritical() << "created local git-repository" << localRepository;
GetLocalGitRepos().insert(localRepository, repo);
}
if (repo == nullptr) {
qCritical() << __func__ << ":" << __LINE__
<< "ERROR: could not find local git-repository" << localRepository;
}
return repo;
}
bool LocalGitRepository::DestroyInstance(QString const &localRepository) {
if (GetLocalGitRepos().count(localRepository) > 0) {
LocalGitRepository *repo = GetLocalGitRepos().take(localRepository);
delete repo;
qCritical() << "deleted local git-repository" << localRepository;
return true;
}
qCritical() << __func__ << ":" << __LINE__
<< "ERROR: could not find local git-repository" << localRepository;
return false;
}
void LocalGitRepository::DestroyAllRepositories() {
for (auto it = GetLocalGitRepos().keyValueBegin(); it != GetLocalGitRepos().keyValueEnd(); ++it) {
QString const &key = it->first;
LocalGitRepository *repo = GetLocalGitRepos()[key];
delete repo;
qCritical() << "deleted local git-repository" << key;
}
GetLocalGitRepos().clear();
} }
int32_t LocalGitRepository::GetFileMenuSizeInternal() const { int32_t LocalGitRepository::GetFileMenuSizeInternal() const {
@ -32,7 +121,7 @@ int32_t LocalGitRepository::GetFileMenuSizeInternal() const {
QByteArray LocalGitRepository::GetFileMenuInternal() { QByteArray LocalGitRepository::GetFileMenuInternal() {
if (m_fileMenuSize == -1) { if (m_fileMenuSize == -1) {
QFile f(QDir::cleanPath(m_repoRootDirectory + QDir::separator() QFile f(QDir::cleanPath(repoRootDirectory + QDir::separator()
+ m_localRepository + QDir::separator() + m_localRepository + QDir::separator()
+ "etc/psa_webinterface/menu_config.json")); + "etc/psa_webinterface/menu_config.json"));
if (f.exists()) { if (f.exists()) {
@ -63,7 +152,7 @@ QByteArray LocalGitRepository::GetFileNameInternal(QString const &fId) {
if (s != "master") { if (s != "master") {
if (fId.contains("psa_tariff")) { if (fId.contains("psa_tariff")) {
QString fn(QDir::cleanPath( QString fn(QDir::cleanPath(
m_repoRootDirectory + QDir::separator() + repoRootDirectory + QDir::separator() +
QString(m_localRepository) + QDir::separator() QString(m_localRepository) + QDir::separator()
+ path + QDir::separator() + path + QDir::separator()
+ QString("tariff%1.json").arg(s.toUInt(), 2, 10, QChar('0')))); + QString("tariff%1.json").arg(s.toUInt(), 2, 10, QChar('0'))));

View File

@ -7,25 +7,43 @@
#include <QJsonArray> #include <QJsonArray>
#include <QJsonObject> #include <QJsonObject>
#include <QDir> #include <QDir>
#include <QMap>
#include <git2.h>
class GitLibrary;
class LocalGitRepository { class LocalGitRepository {
friend class GitLibrary;
QString m_localRepository; QString m_localRepository;
mutable QByteArray m_fileMenu; mutable QByteArray m_fileMenu;
mutable int32_t m_fileMenuSize; mutable int32_t m_fileMenuSize;
git_repository *m_git_repository;
static QString repoRootDirectory;
static QMap<QString, LocalGitRepository *> localGitRepos;
protected: // force heap-based objects
LocalGitRepository(QString const &localRepository);
~LocalGitRepository();
static QString m_repoRootDirectory;
public: public:
static void SetReposRootDirectory(QString s); static void SetReposRootDirectory(QString s);
static QString GetReposRootDirectory(); static QString GetReposRootDirectory();
LocalGitRepository(QString const &localRepository); static LocalGitRepository *GetInstance(QString const &localRepository);
static bool DestroyInstance(QString const &localRepository);
static void DestroyAllRepositories();
QString localRepository() const { return m_localRepository; } static QMap<QString, LocalGitRepository *> &GetLocalGitRepos();
QString localRepositoryPath() { QString localRepositoryName() const;
return QDir::cleanPath( QString localRepositoryPath() const;
m_repoRootDirectory + QDir::separator() + m_localRepository);
} void SetGitRepository(git_repository *git_repo);
git_repository const *GetGitRepository() const;
git_repository *GetGitRepository();
static QString localRepositoryPath(QString const &localRepository);
QByteArray GetFileMenuInternal(); QByteArray GetFileMenuInternal();
int32_t GetFileMenuSizeInternal() const; int32_t GetFileMenuSizeInternal() const;