File indexing completed on 2024-04-21 04:34:35

0001 /***************************************************************************
0002  *   Copyright 2011 Andrey Batyiev <batyiev@gmail.com>                     *
0003  *                                                                         *
0004  *   This program is free software; you can redistribute it and/or         *
0005  *   modify it under the terms of the GNU General Public License as        *
0006  *   published by the Free Software Foundation; either version 2 of        *
0007  *   the License or (at your option) version 3 or any later version        *
0008  *   accepted by the membership of KDE e.V. (or its successor approved     *
0009  *   by the membership of KDE e.V.), which shall act as a proxy            *
0010  *   defined in Section 14 of version 3 of the license.                    *
0011  *                                                                         *
0012  *   This program is distributed in the hope that it will be useful,       *
0013  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0014  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0015  *   GNU General Public License for more details.                          *
0016  *                                                                         *
0017  *   You should have received a copy of the GNU General Public License     *
0018  *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
0019  ***************************************************************************/
0020 
0021 #include "mercurialpushjob.h"
0022 
0023 #include <vcs/dvcs/dvcsjob.h>
0024 #include <KPasswordDialog>
0025 #include <KLocalizedString>
0026 
0027 #include <QMessageBox>
0028 
0029 #include "debug.h"
0030 
0031 using namespace KDevelop;
0032 
0033 MercurialPushJob::MercurialPushJob(const QDir &workingDir, const QUrl &destination, MercurialPlugin *parent)
0034     : VcsJob(parent), m_workingDir(workingDir), m_status(JobNotStarted)
0035 {
0036     if (destination.isEmpty()) {
0037         m_repoLocation = static_cast<MercurialPlugin *>(vcsPlugin())->remotePushRepositoryLocation(m_workingDir);
0038     } else {
0039         m_repoLocation = destination;
0040     }
0041 };
0042 
0043 void MercurialPushJob::start()
0044 {
0045     m_status = JobRunning;
0046 
0047     DVcsJob *job = new DVcsJob(m_workingDir, vcsPlugin());
0048 
0049     *job << "hg" << "push" << "--";
0050 
0051     if (!m_repoLocation.isEmpty())
0052         *job << m_repoLocation.url();
0053 
0054     connect(job, &KJob::finished, this, &MercurialPushJob::serverContacted);
0055     job->start();
0056 }
0057 
0058 QVariant MercurialPushJob::fetchResults()
0059 {
0060     return QVariant();
0061 }
0062 
0063 VcsJob::JobStatus MercurialPushJob::status() const
0064 {
0065     return m_status;
0066 }
0067 
0068 IPlugin *MercurialPushJob::vcsPlugin() const
0069 {
0070     return static_cast<IPlugin *>(parent());
0071 }
0072 
0073 void MercurialPushJob::serverContacted(KJob *job)
0074 {
0075     DVcsJob *dvcsJob = static_cast<DVcsJob *>(job);
0076     // check for errors
0077     if (dvcsJob->error()) {
0078         QString response = QString::fromLocal8Bit(dvcsJob->errorOutput());
0079 
0080         qCDebug(PLUGIN_MERCURIAL) << response;
0081 
0082         if (response.contains("abort: http authorization required")) {
0083             // server requests username:password auth -> ask pass
0084             KPasswordDialog dlg(nullptr, KPasswordDialog::ShowUsernameLine);
0085             dlg.setPrompt(i18n("Enter your login and password for Mercurial push."));
0086             dlg.setUsername(m_repoLocation.userName());
0087             dlg.setPassword(m_repoLocation.password());
0088             if (dlg.exec()) {
0089                 m_repoLocation.setUserName(dlg.username());
0090                 m_repoLocation.setPassword(dlg.password());
0091                 return start();
0092             }
0093         } else if (response.contains("remote: Permission denied")) {
0094             // server is not happy about our ssh key -> nothing could be done via gui
0095             QMessageBox::critical(nullptr, i18n("Mercurial Push Error"), i18n("Remote server does not accept your SSH key."));
0096         } else if (response.contains("remote: Host key verification failed.")) {
0097             // server key is not known for us
0098             // TODO: could be fixed via gui (SSH_ASKPASS etc)?
0099             QMessageBox::critical(nullptr, i18n("Mercurial Push Error"), i18n("Remote server SSH fingerprint is unknown."));
0100         } else if (response.contains("abort: HTTP Error 404: NOT FOUND")) {
0101             // wrong url
0102             QMessageBox::critical(nullptr, i18n("Mercurial Push Error"), i18n("Push URL is incorrect."));
0103         } else {
0104             // TODO
0105             QMessageBox::critical(nullptr, i18n("Mercurial Push Error"), i18n("Unknown error while pushing. Please, check Version Control toolview."));
0106         }
0107         setFail();
0108     } else {
0109         setSuccess();
0110     }
0111 }
0112 
0113 void MercurialPushJob::setFail()
0114 {
0115     m_status = JobFailed;
0116     emitResult();
0117     emit resultsReady(this);
0118 }
0119 
0120 void MercurialPushJob::setSuccess()
0121 {
0122     m_status = JobSucceeded;
0123     emitResult();
0124     emit resultsReady(this);
0125 }