From 080906740ca21be6123b383d2a1384c6a622e488 Mon Sep 17 00:00:00 2001 From: Quentin Rouland Date: Mon, 5 Jan 2026 21:03:50 +0100 Subject: [PATCH] Some GIT clone improvements (error messgages ...) --- plugins/Git/CMakeLists.txt | 1 + plugins/Git/error.h | 54 ++++++++++++++++++ plugins/Git/git.cpp | 9 +-- plugins/Git/git.h | 12 ++-- plugins/Git/jobs/clonejob.cpp | 81 +++++++++++++++++---------- plugins/Git/jobs/clonejob.h | 23 ++++---- plugins/Git/jobs/gitjob.cpp | 12 ++-- plugins/Git/jobs/gitjob.h | 10 +++- plugins/Git/utils.h | 2 +- plugins/Pass/error.h | 74 +++++++++++------------- plugins/Pass/pass.cpp | 8 +-- po/utpass.qrouland.pot | 47 +++++++++++----- qml/pages/settings/ImportGitClone.qml | 36 ++++++++++-- qml/pages/settings/ImportKeyFile.qml | 6 +- qml/pages/settings/ImportSSHkey.qml | 6 +- 15 files changed, 257 insertions(+), 124 deletions(-) create mode 100644 plugins/Git/error.h diff --git a/plugins/Git/CMakeLists.txt b/plugins/Git/CMakeLists.txt index 3d6d059..c41653c 100644 --- a/plugins/Git/CMakeLists.txt +++ b/plugins/Git/CMakeLists.txt @@ -6,6 +6,7 @@ set( plugin.cpp git.cpp utils.h + error.h jobs/clonejob.cpp jobs/gitjob.cpp ) diff --git a/plugins/Git/error.h b/plugins/Git/error.h new file mode 100644 index 0000000..86fdbfa --- /dev/null +++ b/plugins/Git/error.h @@ -0,0 +1,54 @@ +// error.h +#ifndef ERROR_H +#define ERROR_H + +#include +extern "C" { +#include +} + +// Enum for Git-specific errors (e.g., from git_clone) +enum class GitCloneErrorCode { + Successful = 0, + UnexpectedError, ///< Unknown or unexpected error + InvalidUrl, ///< Malformed URL error + NoUsername, ///< Missing username error + AuthentificationError, ///< Authentification error + UrlTypeDoNotMatchCreds, +}; + +/** +* Convert a git_error to a GitCloneErrorCode +* @param error A pointer to the git_error structure +* @return Corresponding GitCloneErrorCode integer value +*/ +inline GitCloneErrorCode gitErrorToGitCloneErrorCode(const git_error* error) { + if (error == nullptr) { + return GitCloneErrorCode::Successful; ///< Default error if null + } + + if (error->message != nullptr) { + if (std::string(error->message) == "malformed URL") { + return GitCloneErrorCode::InvalidUrl; ///< Invalid URL error + } + if (std::string(error->message) == "remote requested authentication but did not negotiate mechanisms") { + return GitCloneErrorCode::AuthentificationError; ///< Invalid URL error + } + } + + return GitCloneErrorCode::UnexpectedError; ///< Default to UnexpectedError +} + +/** + * Maps the given GitCloneErrorCode to its corresponding integer. + * + * @param error The GitCloneErrorCode value to convert. + * @return Corresponding GitCloneErrorCode integer value. + */ +constexpr int code_err(GitCloneErrorCode err) +{ + return static_cast(err); +} + + +#endif // ERROR_H diff --git a/plugins/Git/git.cpp b/plugins/Git/git.cpp index 4fe73e2..86dcc2d 100644 --- a/plugins/Git/git.cpp +++ b/plugins/Git/git.cpp @@ -1,3 +1,4 @@ +#include "error.h" #include #include #include @@ -71,13 +72,13 @@ bool Git::cloneSshKey(QString url, QString path, QString passphrase) return this->clone(url, path, mode); } -void Git::cloneResult(const bool err) +void Git::cloneResult(const int err_code, const QString message) { - if (err) { - emit cloneFailed(); // TODO error message - } else { + if (err_code == code_err(GitCloneErrorCode::Successful)) { emit cloneSucceed(); + } else { + emit cloneFailed(err_code, message); } this->m_sem->release(); } diff --git a/plugins/Git/git.h b/plugins/Git/git.h index 61fe65b..52395a0 100644 --- a/plugins/Git/git.h +++ b/plugins/Git/git.h @@ -1,8 +1,8 @@ #ifndef GIT_H #define GIT_H +#include "error.h" #include "jobs/gitjob.h" -#include "qdebug.h" #include #include #include @@ -28,10 +28,10 @@ private slots: * process finishes. It emits the appropriate signal based on whether the clone operation succeeded * or failed. * - * @param err A boolean indicating whether an error occurred during cloning. `true` if the clone failed, - * `false` if it succeeded. + * @param err A err_code indicating whether an error occurred during cloning. + * @param err An error message. */ - void cloneResult(const bool err); + void cloneResult(const int err_code, const QString message); signals: /** @@ -44,9 +44,11 @@ signals: /** * @brief Signal emitted when the cloning operation fails. * + * @param err_code The error code + * @param msg The deffautl error message from libgit * This signal is emitted when an error occurs during the cloning operation. */ - void cloneFailed(); + void cloneFailed(int err_code, QString msg); private: std::unique_ptr m_sem; /**< Semaphore for managing concurrent operations. */ diff --git a/plugins/Git/jobs/clonejob.cpp b/plugins/Git/jobs/clonejob.cpp index 744e59f..e2f4d74 100644 --- a/plugins/Git/jobs/clonejob.cpp +++ b/plugins/Git/jobs/clonejob.cpp @@ -3,12 +3,14 @@ #include #include #include +#include #include extern "C" { #include } #include "clonejob.h" +#include "../error.h" CloneJob::CloneJob(QString url, QString path, cred_type cred): GitJob(cred), @@ -18,69 +20,90 @@ CloneJob::CloneJob(QString url, QString path, cred_type cred): this->setObjectName("CloneJob"); } - void CloneJob::run() { auto tmp_dir = this->cloneSetup(); - auto ret = this->clone(this->m_url, tmp_dir.absolutePath(), this->m_cred, this->credentialsCB); - if (ret) { + const auto [errorCode, errorMessage] = this->clone(m_url, tmp_dir.absolutePath(), this->m_cred, this->credentialsCB); + + if (errorCode == GitCloneErrorCode::Successful) { this->moveToDestination(tmp_dir, this->m_path); } + this->cloneCleanUp(tmp_dir); - - emit resultReady(!ret); // TODO Clean error handling to return specifics errors for the ui + emit resultReady(code_err(errorCode), errorMessage); } - QDir CloneJob::cloneSetup() { - QDir tmp_dir(QStandardPaths::writableLocation( QStandardPaths::CacheLocation).append("/clone")); + QDir tmp_dir(QStandardPaths::writableLocation(QStandardPaths::CacheLocation).append("/clone")); - tmp_dir.removeRecursively(); - qDebug() << "[CloneJob] Temp dir path is " << tmp_dir.absolutePath(); + tmp_dir.removeRecursively(); // Clean the directory before use + qDebug() << "[CloneJob] Temp dir path is" << tmp_dir.absolutePath(); return tmp_dir; } - bool CloneJob::cloneCleanUp(QDir tmp_dir) { - return tmp_dir.removeRecursively(); + if (!tmp_dir.removeRecursively()) { + qWarning() << "[CloneJob] Failed to clean up temporary directory:" << tmp_dir.absolutePath(); + return false; + } + return true; } -bool CloneJob::moveToDestination(QDir tmp_dir, QString path) +bool CloneJob::moveToDestination(QDir tmp_dir, const QString& path) { - qDebug() << "[CloneJob] Removing password_store " << path; + qDebug() << "[CloneJob] Removing existing destination:" << path; + QDir destination_dir(path); - destination_dir.removeRecursively(); + destination_dir.removeRecursively(); // Clean the destination directory qDebug() << "[CloneJob] Moving cloned content to destination dir"; - QDir dir; - qDebug() << "[CloneJob]" << tmp_dir.absolutePath() << " to " << destination_dir.absolutePath(); - return dir.rename(tmp_dir.absolutePath(), destination_dir.absolutePath()); // TODO Better error handling + + if (!QDir().rename(tmp_dir.absolutePath(), destination_dir.absolutePath())) { + qWarning() << "[CloneJob] Failed to move directory from" << tmp_dir.absolutePath() << "to" << destination_dir.absolutePath(); + return false; + } + + return true; } -bool CloneJob::clone(QString url, QString path, cred_type cred, git_cred_acquire_cb cb) +const QPair CloneJob::clone(QString url, QString path, cred_type cred, git_cred_acquire_cb cb) { - git_repository *repo = NULL; + git_repository *repo = nullptr; // Use nullptr for type safety git_clone_options opts = GIT_CLONE_OPTIONS_INIT; - PayloadCB payload = PayloadCB(false, cred); + PayloadCB payload(false, cred); opts.fetch_opts.callbacks.credentials = cb; opts.fetch_opts.callbacks.payload = &payload; int ret = git_clone(&repo, url.toLocal8Bit().data(), path.toLocal8Bit().data(), &opts); - if (ret == GIT_EUSER ) { - qDebug() << "[CloneJob] CallBack Error"; - } else if (ret != 0) { - auto err = git_error_last(); // TODO Better error handling for return ui messages - if (err) { - qDebug() << "[CloneJob]" << git_error_last()->message; - } + + // Map the application specific cb errors if any + if (ret == GIT_EUSER) { + if(payload.err == ErrorCodeCB::NoUsername) + return {GitCloneErrorCode::NoUsername, "no username provided in URL"}; + if(payload.err == ErrorCodeCB::InvalidCreds) + return {GitCloneErrorCode::AuthentificationError, "authentification error"}; + if(payload.err == ErrorCodeCB::UrlTypeDoNotMatchCreds) + return {GitCloneErrorCode::UrlTypeDoNotMatchCreds, "invalid creds types for provided url"}; + return {GitCloneErrorCode::UnexpectedError, "unexcepted error occured"}; } + + const git_error* err = git_error_last(); // Retrieve the last error git error + + // Log error details for debugging + if (err) { + qDebug() << "[CloneJob] Error class:" << err->klass; + qDebug() << "[CloneJob] Error message:" << err->message; + } + + // Check if the repository was successfully created and free it if (repo) { git_repository_free(repo); } - return ret == 0; -} + // Return the error code mapped from git_error_last + return { gitErrorToGitCloneErrorCode(err), err ? QString::fromUtf8(err->message) : "success"}; +} diff --git a/plugins/Git/jobs/clonejob.h b/plugins/Git/jobs/clonejob.h index 69dc62c..406cf29 100644 --- a/plugins/Git/jobs/clonejob.h +++ b/plugins/Git/jobs/clonejob.h @@ -6,6 +6,7 @@ extern "C" { #include } #include "gitjob.h" +#include "../error.h" /** * @class CloneJob @@ -26,14 +27,13 @@ class CloneJob : public GitJob signals: /** - * @brief Signal emitted when the cloning operation is complete. - * - * This signal is emitted once the cloning operation finishes. - * - * @param err A boolean indicating whether an error occurred during cloning. - * `true` if an error occurred, `false` if the clone was successful. - */ - void resultReady(const bool err); + * @brief Signal emitted when the cloning operation is complete. + * + * This signal is emitted once the cloning operation finishes. + * + * @param err A Git error. + */ + void resultReady(const int err_code, const QString message); private: QString m_url; ///< The URL of the Git repository to clone. @@ -58,7 +58,7 @@ private: * @param tmp_dir The temporary directory where the repository was cloned. * @return `true` if the move was successful, `false` otherwise. */ - static bool moveToDestination(QDir tmp_dir, QString path); + static bool moveToDestination(QDir tmp_dir, const QString& path); /** * @brief Tears down the temporary directory after cloning. @@ -84,9 +84,10 @@ private: * @param path The destination path for the cloned repository. * @param cred The credentials to use for the cloning operation. * @param cb The callback function for acquiring credentials during cloning. - * @return `true` if the cloning process was successful, `false` otherwise. + * @return A Git error, result of the operation. */ - static bool clone(QString url, QString path, cred_type cred, git_cred_acquire_cb cb); + static const QPair clone(QString url, QString path, cred_type cred, git_cred_acquire_cb cb); + public: /** diff --git a/plugins/Git/jobs/gitjob.cpp b/plugins/Git/jobs/gitjob.cpp index 7f978fb..86e596c 100644 --- a/plugins/Git/jobs/gitjob.cpp +++ b/plugins/Git/jobs/gitjob.cpp @@ -28,11 +28,13 @@ int GitJob::credentialsCB(git_cred **out, const char *url, const char *username_ if (!username_from_url) { // we required here that the username must be provided directly in url (maybe improve later on) qWarning() << "[GitJob] credentials_cb : no username provided"; + p->err = ErrorCodeCB::NoUsername; return (int) GIT_EUSER; } if (p->called) { qWarning() << "[GitJob] credentials_cb : cb already called, probably invalid creds"; + p->err = ErrorCodeCB::InvalidCreds; return (int) GIT_EUSER; } p->called = true; @@ -45,26 +47,24 @@ int GitJob::credentialsCB(git_cred **out, const char *url, const char *username_ qWarning() << "[GitJob] credentialsCB : callback should never be call for HTTP"; return (int) GIT_EUSER; }, - [allowed_types, &out, &username_from_url](const HTTPUserPass & x) + [allowed_types, &out, &username_from_url, &p](const HTTPUserPass & x) { qDebug() << "[GitJob] credentialsCB : HTTPUserPass "; if (!(allowed_types & GIT_CREDTYPE_USERPASS_PLAINTEXT)) { qWarning() << "[GitJob] credentials_cb : allowed_types is invalid for HTTPUserPass creds"; + p->err = ErrorCodeCB::UrlTypeDoNotMatchCreds; return (int) GIT_EUSER; } return git_cred_userpass_plaintext_new(out, username_from_url, x.pass.toLocal8Bit().constData()); }, - [allowed_types, &out, &username_from_url](const SSHKey & x) + [allowed_types, &out, &username_from_url , &p](const SSHKey & x) { qDebug() << "[GitJob] credentialsCB : SSHKey "; if (!(allowed_types & GIT_CREDTYPE_SSH_KEY)) { qWarning() << "[GitJob] credentials_cb : allowed_types is invalid for SSHKey creds"; + p->err = ErrorCodeCB::UrlTypeDoNotMatchCreds; return (int) GIT_EUSER; } - qDebug() << "[GitJob] username_from_url :" << username_from_url; - qDebug() << "[GitJob] pub_key :" << x.pub_key.toLocal8Bit().constData(); - qDebug() << "[GitJob] priv_key :" << x.priv_key.toLocal8Bit().constData(); - qDebug() << "[GitJob] passphrase :" << x.passphrase.toLocal8Bit().constData(); return git_cred_ssh_key_new(out, username_from_url, x.pub_key.toLocal8Bit().constData(), x.priv_key.toLocal8Bit().constData(), x.passphrase.toLocal8Bit().constData()); } diff --git a/plugins/Git/jobs/gitjob.h b/plugins/Git/jobs/gitjob.h index 294f27b..2404d57 100644 --- a/plugins/Git/jobs/gitjob.h +++ b/plugins/Git/jobs/gitjob.h @@ -31,12 +31,20 @@ struct SSHKey { */ typedef std::variant cred_type; +enum class ErrorCodeCB { + None = 0, + NoUsername, + UrlTypeDoNotMatchCreds, + InvalidCreds, +}; + struct PayloadCB { bool called; cred_type creds; - PayloadCB(bool ca, cred_type cr): called(ca), creds(cr) {} + ErrorCodeCB err; + PayloadCB(bool ca, cred_type cr): called(ca), creds(cr), err(ErrorCodeCB::None) {} }; /** diff --git a/plugins/Git/utils.h b/plugins/Git/utils.h index 77b3b38..15cb682 100644 --- a/plugins/Git/utils.h +++ b/plugins/Git/utils.h @@ -1,7 +1,7 @@ #ifndef UTILS_H #define UTILS_H -#define UNUSED(x) (void)(x) +#define UNUSED(x) (void)(x) // Stub used to hide some warnings /** * @brief A utility structure for enabling function overloading with template-based classes. diff --git a/plugins/Pass/error.h b/plugins/Pass/error.h index 316d347..1e0faf6 100644 --- a/plugins/Pass/error.h +++ b/plugins/Pass/error.h @@ -6,66 +6,56 @@ extern "C" { #include "rnp/rnp_err.h" } -enum class ErrorCodeShow { - Success= 0, - UnexceptedError, - BadPassphrase, - NoKeyFound, - DecryptFailed +// Enum for general error codes +enum class ErrorCode { + Error = 1, ///< Generic error code }; -int rnpErrorToErrorCodeShow(int rnpErrorCode) { +// Enum for errors related to showing errors (e.g., password issues, key issues) +enum class ErrorCodeShow { + UnexpectedError = 1, ///< Unknown or unexpected error + BadPassphrase, ///< Invalid passphrase error + NoKeyFound, ///< Key not found error + DecryptFailed ///< Decryption failure error +}; + +/** +* Convert an RNP error code to a corresponding ErrorCodeShow +* @param rnpErrorCode The RNP error code +* @return Corresponding ErrorCodeShow integer value +*/ +inline ErrorCodeShow rnpErrorToErrorCodeShow(int rnpErrorCode) { switch (rnpErrorCode) { - case RNP_SUCCESS: - return static_cast(ErrorCodeShow::Success); case RNP_ERROR_BAD_PASSWORD: - return static_cast(ErrorCodeShow::BadPassphrase); + return ErrorCodeShow::BadPassphrase; ///< Bad passphrase error case RNP_ERROR_KEY_NOT_FOUND: case RNP_ERROR_NO_SUITABLE_KEY: - return static_cast(ErrorCodeShow::NoKeyFound); + return ErrorCodeShow::NoKeyFound; ///< No key found error case RNP_ERROR_DECRYPT_FAILED: - return static_cast(ErrorCodeShow::DecryptFailed); + return ErrorCodeShow::DecryptFailed; ///< Decryption failure error default: - return static_cast(ErrorCodeShow::UnexceptedError); + return ErrorCodeShow::UnexpectedError; ///< Default to unexpected error } } +// Enum for errors related to importing key files enum class ErrorCodeImportKeyFile { - Success= 0, - UnexceptedError, - BadFormat, + UnexpectedError = 1, ///< Unknown or unexpected error + BadFormat, ///< Bad format error when importing the key file }; -int rnpErrorToErrorCodeImportKeyFile(int rnpErrorCode) { +/** +* Convert an RNP error code to a corresponding ErrorCodeImportKeyFile +* @param rnpErrorCode The RNP error code +* @return Corresponding ErrorCodeImportKeyFile integer value +*/ +inline ErrorCodeImportKeyFile rnpErrorToErrorCodeImportKeyFile(int rnpErrorCode) { switch (rnpErrorCode) { - case RNP_SUCCESS: - return static_cast(ErrorCodeShow::Success); case RNP_ERROR_BAD_FORMAT: - return static_cast(ErrorCodeImportKeyFile::BadFormat); + return ErrorCodeImportKeyFile::BadFormat; ///< Bad format error default: - return static_cast(ErrorCodeImportKeyFile::UnexceptedError); + return ErrorCodeImportKeyFile::UnexpectedError; ///< Default to unexpected error } } - -enum class ErrorCodeUnexvepted { - Success= 0, - UnexceptedError, -}; - -int rnpErrorToErrorCodeGeneric(int rnpErrorCode) { - switch (rnpErrorCode) { - case RNP_SUCCESS: - return static_cast(ErrorCodeShow::Success); - default: - return static_cast(ErrorCodeImportKeyFile::UnexceptedError); - } -} - -enum class ErrorCode -{ - Success= 0, - Error, -}; - #endif // ERROR_H diff --git a/plugins/Pass/pass.cpp b/plugins/Pass/pass.cpp index 647b024..cffe856 100644 --- a/plugins/Pass/pass.cpp +++ b/plugins/Pass/pass.cpp @@ -109,7 +109,7 @@ bool Pass::show(QUrl url) void Pass::slotShowError(rnp_result_t err) { qInfo() << "[Pass] Show Failed"; - emit showFailed(rnpErrorToErrorCodeShow(err), rnp_result_to_string(err)); + emit showFailed((int) rnpErrorToErrorCodeShow(err), rnp_result_to_string(err)); this->m_sem->release(1); } @@ -168,7 +168,7 @@ bool Pass::deleteGPGKey(PassKeyModel* key) void Pass::slotDeleteGPGKeyError(rnp_result_t err) { qInfo() << "[Pass] Delete GPG key Failed"; - emit deleteGPGKeyFailed(rnpErrorToErrorCodeGeneric(err), rnp_result_to_string(err)); + emit deleteGPGKeyFailed(static_cast(ErrorCode::Error), rnp_result_to_string(err)); this->m_sem->release(1); } @@ -198,7 +198,7 @@ bool Pass::importGPGKey(QUrl url) void Pass::slotImportGPGKeyError(rnp_result_t err) { qInfo() << "[Pass] Import GPG Key Failed"; - emit importGPGKeyFailed(rnpErrorToErrorCodeImportKeyFile(err), rnp_result_to_string(err)); + emit importGPGKeyFailed((int) rnpErrorToErrorCodeImportKeyFile(err), rnp_result_to_string(err)); this->m_sem->release(1); } @@ -229,7 +229,7 @@ void Pass::slotGetAllGPGKeysError(rnp_result_t err) { qInfo() << "[Pass] Get all GPG Keys Failed"; this->m_keyring_model = nullptr; - emit getAllGPGKeysFailed(rnpErrorToErrorCodeGeneric(err), rnp_result_to_string(err)); + emit getAllGPGKeysFailed(static_cast(ErrorCode::Error), rnp_result_to_string(err)); this->m_sem->release(1); } diff --git a/po/utpass.qrouland.pot b/po/utpass.qrouland.pot index 278d7bc..b9e187b 100644 --- a/po/utpass.qrouland.pot +++ b/po/utpass.qrouland.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: utpass.qrouland\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-03-14 10:08+0100\n" +"POT-Creation-Date: 2026-01-05 19:03+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -194,7 +194,7 @@ msgid "You're are about to delete
the current Password Store.
Continue ?" msgstr "" #: ../qml/pages/settings/DeleteRepo.qml:57 -#: ../qml/pages/settings/ImportGitClone.qml:142 +#: ../qml/pages/settings/ImportGitClone.qml:169 #: ../qml/pages/settings/ImportZip.qml:66 #: ../qml/pages/settings/InfoKeys.qml:174 msgid "Yes" @@ -208,50 +208,71 @@ msgstr "" msgid "Password Store deleted !" msgstr "" -#: ../qml/pages/settings/ImportGitClone.qml:141 +#: ../qml/pages/settings/ImportGitClone.qml:56 +msgid "An unexpected error occurred during the clone operation." +msgstr "" + +#: ../qml/pages/settings/ImportGitClone.qml:59 +msgid "Invalid URL for the current clone operation." +msgstr "" + +#: ../qml/pages/settings/ImportGitClone.qml:62 +msgid "Username is missing in the URL." +msgstr "" + +#: ../qml/pages/settings/ImportGitClone.qml:65 +msgid "Authentication error, credentials may be invalid." +msgstr "" + +#: ../qml/pages/settings/ImportGitClone.qml:68 +msgid "" +"Credentials type does not match the URL for the current clone operation." +msgstr "" + +#: ../qml/pages/settings/ImportGitClone.qml:168 msgid "" "Importing a git repo will delete
any existing password store!" "
Continue ?" msgstr "" -#: ../qml/pages/settings/ImportGitClone.qml:155 +#: ../qml/pages/settings/ImportGitClone.qml:182 msgid "An error occured during git clone !" msgstr "" -#: ../qml/pages/settings/ImportGitClone.qml:164 +#: ../qml/pages/settings/ImportGitClone.qml:192 #: ../qml/pages/settings/ImportZip.qml:88 msgid "Password store sucessfully imported !" msgstr "" -#: ../qml/pages/settings/ImportGitClone.qml:176 +#: ../qml/pages/settings/ImportGitClone.qml:204 msgid "Git Clone Import" msgstr "" -#: ../qml/pages/settings/ImportKeyFile.qml:7 +#: ../qml/pages/settings/ImportKeyFile.qml:9 msgid "GPG Key Import" msgstr "" -#: ../qml/pages/settings/ImportKeyFile.qml:8 +#: ../qml/pages/settings/ImportKeyFile.qml:10 msgid "Key successfully imported !" msgstr "" -#: ../qml/pages/settings/ImportKeyFile.qml:9 +#: ../qml/pages/settings/ImportKeyFile.qml:11 msgid "Key import failed !" msgstr "" -#: ../qml/pages/settings/ImportKeyFile.qml:33 +#: ../qml/pages/settings/ImportKeyFile.qml:35 msgid "The file is not in a valid key format" msgstr "" -#: ../qml/pages/settings/ImportSSHkey.qml:10 +#: ../qml/pages/settings/ImportSSHkey.qml:12 msgid "SSH Key Import" msgstr "" -#: ../qml/pages/settings/ImportSSHkey.qml:11 +#: ../qml/pages/settings/ImportSSHkey.qml:13 msgid "SSH Key successfully imported !" msgstr "" -#: ../qml/pages/settings/ImportSSHkey.qml:12 +#: ../qml/pages/settings/ImportSSHkey.qml:14 msgid "SSH Key import failed !" msgstr "" diff --git a/qml/pages/settings/ImportGitClone.qml b/qml/pages/settings/ImportGitClone.qml index 4d556ec..46f80e7 100644 --- a/qml/pages/settings/ImportGitClone.qml +++ b/qml/pages/settings/ImportGitClone.qml @@ -16,8 +16,15 @@ Page { property int __gitModeHTTP_AUTH : 1 property int __gitModeSSH_KEY : 2 + property int __gitCloneErrorCodeSuccessful : 0 + property int __gitCloneErrorCodeUnexpectedError : 1 + property int __gitCloneErrorCodeInvalidUrl : 2 + property int __gitCloneErrorCodeNoUsername : 3 + property int __gitCloneErrorCodeAuthentificationError : 4 + property int __gitCloneErrorCodeUrlTypeDoNotMatchCreds : 5 property string __repoUrl + property string __err_message : null function __loadForm() { switch (combo.selectedIndex) { @@ -41,10 +48,30 @@ Page { Utils.rmFile(Git.privKey); Utils.rmFile(Git.pubKey); } - PopupUtils.open(dialogGitCloneSuccess); + PopupUtils.open(dialogGitCloneSuccess, importGitClonePage); }); - Git.cloneFailed.connect(function() { - PopupUtils.open(dialogGitCloneError); + Git.cloneFailed.connect(function(err_code, msg) { + switch (err_code) { + case __gitCloneErrorCodeUnexpectedError: + __err_message = i18n.tr("An error occurred during the clone operation."); + break; + case __gitCloneErrorCodeInvalidUrl: + __err_message = i18n.tr("Invalid URL for the current clone operation."); + break; + case __gitCloneErrorCodeNoUsername: + __err_message = i18n.tr("Username is missing in the URL."); + break; + case __gitCloneErrorCodeAuthentificationError: + __err_message = i18n.tr("Authentication error, credentials may be invalid."); + break; + case __gitCloneErrorCodeUrlTypeDoNotMatchCreds: + __err_message = i18n.tr("Credentials type does not match the URL for the current clone operation."); + break; + default: + __err_message = msg; + break; + } + PopupUtils.open(dialogGitCloneError, importGitClonePage); }); if (GitSettings.repoUrl) __repoUrl = GitSettings.repoUrl; @@ -128,7 +155,7 @@ Page { }); }); break; - } + } } } @@ -153,6 +180,7 @@ Page { ErrorDialog { textError: i18n.tr("An error occured during git clone !") + textErrorDescription: __err_message } } diff --git a/qml/pages/settings/ImportKeyFile.qml b/qml/pages/settings/ImportKeyFile.qml index 8b5dbac..f4ec2ab 100644 --- a/qml/pages/settings/ImportKeyFile.qml +++ b/qml/pages/settings/ImportKeyFile.qml @@ -1,6 +1,8 @@ import "../../components" import Pass 1.0 +import Lomiri.Content 1.3 + ImportFile { id: importKeyFilePage @@ -10,8 +12,8 @@ ImportFile { contentPicker.onPeerSelected: { { - peer.selectionType = ContentTransfer.Single; - importKeyFilePage.activeTransfer = peer.request(); + importKeyFilePage.contentPicker.peer.selectionType = ContentTransfer.Single; + importKeyFilePage.activeTransfer = importKeyFilePage.contentPicker.peer.request(); importKeyFilePage.activeTransfer.stateChanged.connect(function() { if (importKeyFilePage.activeTransfer.state === ContentTransfer.Charged) { console.log("Charged"); diff --git a/qml/pages/settings/ImportSSHkey.qml b/qml/pages/settings/ImportSSHkey.qml index fab5863..25dc697 100644 --- a/qml/pages/settings/ImportSSHkey.qml +++ b/qml/pages/settings/ImportSSHkey.qml @@ -2,6 +2,8 @@ import "../../components" import Utils 1.0 import Git 1.0 +import Lomiri.Content 1.3 + ImportFile { id: importSSHKeyPage @@ -13,8 +15,8 @@ ImportFile { contentPicker.onPeerSelected: { { - peer.selectionType = ContentTransfer.Single; - importSSHKeyPage.activeTransfer = peer.request(); + importSSHKeyPage.contentPicker.peer.selectionType = ContentTransfer.Single; + importSSHKeyPage.activeTransfer = importSSHKeyPage.contentPicker.peer.request(); importSSHKeyPage.activeTransfer.stateChanged.connect(function() { if (importSSHKeyPage.activeTransfer.state === ContentTransfer.Charged) { console.log("Charged");