File indexing completed on 2024-05-12 04:38:53
0001 /* 0002 This file was partly taken from KDevelop's cvs plugin 0003 SPDX-FileCopyrightText: 2002-2003 Christian Loose <christian.loose@hamburg.de> 0004 SPDX-FileCopyrightText: 2007 Robert Gruber <rgruber@users.sourceforge.net> 0005 0006 Adapted for DVCS 0007 SPDX-FileCopyrightText: 2008 Evgeniy Ivanov <powerfox@kde.ru> 0008 SPDX-FileCopyrightText: 2010 Aleix Pol Gonzalez <aleixpol@kde.org> 0009 0010 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0011 */ 0012 0013 0014 #ifndef KDEVPLATFORM_DVCS_JOB_H 0015 #define KDEVPLATFORM_DVCS_JOB_H 0016 0017 #include <QVariant> 0018 #include <KProcess> 0019 0020 #include <vcs/vcsexport.h> 0021 #include "../vcsjob.h" 0022 0023 class QDir; 0024 class QStringList; 0025 0026 0027 namespace KDevelop 0028 { 0029 class DVcsJobPrivate; 0030 0031 /** 0032 * This class is capable of running our dvcs commands. 0033 * Most of all DVcsJob are created in DVCS executors, but executed in DistributedVersionControlPlugin or 0034 * any managers like BranchManager. 0035 * @note Connect to KJob::result(KJob*) to be notified when the job finished. 0036 * 0037 * How to create DVcsJob: 0038 * @code 0039 * DVcsJob* job = new DVcsJob(vcsplugin); 0040 * 0041 * job->setDirectory(workDir); 0042 * *job << "git-rev-parse"; 0043 * foreach(const QString &arg, args) // *job << args can be used instead! 0044 * *job << arg; 0045 * return job; 0046 * 0047 * return error_cmd(i18n("could not create the job")); 0048 * @endcode 0049 * 0050 * Usage example 1: 0051 * @code 0052 * VcsJob* j = add(QList<QUrl>() << a << b << c, IBasicVersionControl::Recursive); 0053 * DVcsJob* job = qobject_cast<DVCSjob*>(j); 0054 * connect(job, SIGNAL(result(KJob*)), 0055 * this, SIGNAL(jobFinished(KJob*))); 0056 * ICore::self()->runController()->registerJob(job); 0057 * @endcode 0058 * 0059 * Usage example 2, asynchronous: 0060 * @code 0061 * DVcsJob* branchJob = d->branch(repo, baseBranch, newBranch); 0062 * 0063 * if (job->exec() && job->status() == KDevelop::VcsJob::JobSucceeded) 0064 * return true; 0065 * else 0066 * //something, maybe even just 0067 * return false 0068 * @endcode 0069 * 0070 * @author Robert Gruber <rgruber@users.sourceforge.net> 0071 * @author Evgeniy Ivanov <powerfox@kde.ru> 0072 */ 0073 class KDEVPLATFORMVCS_EXPORT DVcsJob : public KDevelop::VcsJob 0074 { 0075 Q_OBJECT 0076 public: 0077 explicit DVcsJob(const QDir& workingDir, KDevelop::IPlugin* parent=nullptr, KDevelop::OutputJob::OutputJobVerbosity verbosity = KDevelop::OutputJob::Verbose); 0078 ~DVcsJob() override; 0079 0080 /** 0081 * Returns current working directory. 0082 */ 0083 QDir directory() const; 0084 0085 /** 0086 * Call this method to set command to execute and its arguments. 0087 * @note Don't forget <<"one two"; is not the same as <<"one"<<"two"; Use one word(command, arg) per one QString! 0088 */ 0089 DVcsJob& operator<<(const QString& arg); 0090 0091 /** 0092 * Overloaded convenience function. 0093 * @param arg command or argument as utf8-encoded string 0094 * @see operator<<(const QString& arg). 0095 */ 0096 DVcsJob& operator<<(const char* arg); 0097 0098 /** 0099 * Overloaded convenience function. 0100 * @see operator<<(const QString& arg). 0101 */ 0102 DVcsJob& operator<<(const QStringList& args); 0103 0104 /** 0105 * Overloaded operator << for url's, can be used to pass files and 0106 * makes arguments absolute to the process working directory 0107 * 0108 * Override if you need to treat paths before adding them as parameters. 0109 */ 0110 virtual DVcsJob& operator<<(const QUrl& arg); 0111 0112 /** 0113 * @see operator<<(const QUrl& arg). 0114 */ 0115 DVcsJob& operator<<(const QList<QUrl>& args); 0116 0117 /** 0118 * Call this method to start this job. 0119 * @note Default communication mode is KProcess::AllOutput. 0120 * @see Use setCommunicationMode() to override the default communication mode. 0121 */ 0122 void start() override; 0123 0124 /** 0125 * In some cases it's needed to specify the communication mode between the 0126 * process and the job object. This is for instance done for the "git status" 0127 * command. If stdout and stderr are processed as separate streams, their signals 0128 * do not always get emitted in correct order by KProcess, which will lead to a 0129 * screwed up output. 0130 * @note Default communication mode is KProcess::SeparateChannels. 0131 */ 0132 void setCommunicationMode(KProcess::OutputChannelMode comm); 0133 0134 /** 0135 * @return The command that is executed when calling start(). 0136 */ 0137 QStringList dvcsCommand() const; 0138 0139 /** 0140 * @return The whole output of the job as a string. (Might fail on binary data) 0141 */ 0142 QString output() const; 0143 0144 /** 0145 * @return The whole binary output of the job 0146 */ 0147 QByteArray rawOutput() const; 0148 0149 /** 0150 * @return The whole binary stderr output of the job. 0151 */ 0152 QByteArray errorOutput() const; 0153 0154 /** 0155 * Ignore a non-zero exit code depending on @p ignore. 0156 */ 0157 void setIgnoreError(bool ignore); 0158 0159 // Begin: KDevelop::VcsJob 0160 0161 /** 0162 * Sets executions results. 0163 * In most cases this method is used by IDVCSexecutor 0164 * @see fetchResults() 0165 */ 0166 virtual void setResults(const QVariant &res); 0167 0168 /** 0169 * Returns execution results stored in QVariant. 0170 * Mostly used in vcscommitdialog. 0171 * @see setResults(const QVariant &res) 0172 */ 0173 QVariant fetchResults() override; 0174 0175 /** 0176 * Returns JobStatus 0177 * @see KDevelop::VcsJob::JobStatus 0178 */ 0179 KDevelop::VcsJob::JobStatus status() const override; 0180 0181 /** 0182 * Returns pointer to IPlugin (which was used to create a job). 0183 */ 0184 KDevelop::IPlugin* vcsPlugin() const override; 0185 // End: KDevelop::VcsJob 0186 0187 KProcess* process() const; 0188 0189 void displayOutput(const QString& output); 0190 0191 public Q_SLOTS: 0192 /** 0193 * Cancel slot. 0194 */ 0195 void cancel(); 0196 0197 Q_SIGNALS: 0198 void readyForParsing(KDevelop::DVcsJob *job); 0199 0200 protected Q_SLOTS: 0201 virtual void slotProcessError( QProcess::ProcessError ); 0202 0203 private Q_SLOTS: 0204 void slotProcessExited(int exitCode, QProcess::ExitStatus exitStatus); 0205 void slotReceivedStdout(); 0206 0207 protected: 0208 bool doKill() override; 0209 0210 private: 0211 void jobIsReady(); 0212 0213 private: 0214 const QScopedPointer<class DVcsJobPrivate> d_ptr; 0215 Q_DECLARE_PRIVATE(DVcsJob) 0216 }; 0217 0218 } 0219 0220 #endif