# # # patch "src/monotone/MonotoneManager.cpp" # from [0a61e929aee21a08940ae0d0dc0979339c98c835] # to [54ff66e7fa219e7ed856b7eaa17f8de5773e1494] # # patch "src/monotone/MonotoneManager.h" # from [d89f1d3aca69397462d1952c057f8284c97df553] # to [94f910a541e1601e05f22fec018bacc86a701972] # # patch "src/monotone/MonotoneProcess.cpp" # from [620f114189e34dfabf2d776d50605d64f28817bf] # to [28c3a9da29b6dbc4fa794f498c3dc0b6b251fa77] # # patch "src/monotone/MonotoneProcess.h" # from [5eafbef157ea2e63b4d57be4d9272488370112e8] # to [547aa8e0fd0a45f3c0edae16784a84d2e13b06a0] # # patch "src/view/dialogs/CreateDatabase.cpp" # from [85abc9702b55b5badbcb42c966a826d9ea9824f7] # to [3e3252bd4c9fe7b305adc2c3b939eb1210e35202] # # patch "src/view/dialogs/KeyManagement.cpp" # from [10a95be196dda8d70292d8b71c199d31862320a3] # to [567f228b82e256aa7cd648b88da2d05b9e7a02df] # ============================================================ --- src/monotone/MonotoneManager.cpp 0a61e929aee21a08940ae0d0dc0979339c98c835 +++ src/monotone/MonotoneManager.cpp 54ff66e7fa219e7ed856b7eaa17f8de5773e1494 @@ -17,6 +17,7 @@ ***************************************************************************/ #include "MonotoneManager.h" +#include "MonotoneProcess.h" #include "MonotoneUtil.h" #include "vocab.h" #include "BasicIOParser.h" @@ -263,7 +264,7 @@ void MonotoneManager::removeThread(int t void MonotoneManager::removeThread(int threadNumber) { QMutexLocker locker(&lock); - + if (!threadMap.contains(threadNumber)) { L(QString("thread %1 was already removed").arg(threadNumber)); @@ -353,49 +354,25 @@ void MonotoneManager::aborted(int thread emit threadAborted(userMessage); } -bool MonotoneManager::singleRun(const QString & mtnBinary, - const QStringList & params, QByteArray & output) -{ - QProcess proc; - proc.start(mtnBinary, params); - - // could not be started (invalid path, not executable, ...) - if (!proc.waitForStarted(5000)) - { - C(QString("`%1 %2` not started (%3)") - .arg(mtnBinary).arg(params.join(" ")).arg(proc.errorString())); - return false; - } - - // process doesn't return, etc... - if (!proc.waitForFinished(5000)) - { - C(QString("`%1 %2` not finished (%3)") - .arg(mtnBinary).arg(params.join(" ")).arg(proc.errorString())); - return false; - } - - // read all of the output - output.append(proc.readAll()); - return true; -} - QString MonotoneManager::getInterfaceVersion(const QString & mtnBinary) { - QByteArray output; + MonotoneProcess proc; + proc.setMtnBinaryPath(mtnBinary); + proc.start(QStringList() << "automate" << "interface_version"); + proc.waitForFinished(); - if (!singleRun(mtnBinary, QStringList() << "automate" << "interface_version", output)) + QString output = proc.getBufferedOutput(); + if (!proc.successful()) { - C("Couldn't execute `automate interface_version`"); + C(QString("Couldn't execute `automate interface_version`: %1") + .arg(output)); return QString(); } - QString versionString(QString::fromUtf8(output)); QRegExp regex("^(\\d+(?:\\.\\d+))"); - - if (regex.indexIn(versionString) == -1) + if (regex.indexIn(output) == -1) { - D(QString("couldn't parse output: %1").arg(versionString)); + D(QString("couldn't parse output: %1").arg(output)); return false; } ============================================================ --- src/monotone/MonotoneManager.h d89f1d3aca69397462d1952c057f8284c97df553 +++ src/monotone/MonotoneManager.h 94f910a541e1601e05f22fec018bacc86a701972 @@ -51,9 +51,6 @@ public: //! returns a thread by a given thread number MonotoneThreadPtr getThreadByNumber(int); - //! runs a single command and returns its output - static bool singleRun(const QString &, const QStringList &, QByteArray &); - //! returns the interface version of a given monotone binary static QString getInterfaceVersion(const QString &); ============================================================ --- src/monotone/MonotoneProcess.cpp 620f114189e34dfabf2d776d50605d64f28817bf +++ src/monotone/MonotoneProcess.cpp 28c3a9da29b6dbc4fa794f498c3dc0b6b251fa77 @@ -21,11 +21,26 @@ #include "Settings.h" #include "vocab.h" -MonotoneProcess::MonotoneProcess(const QString & ws) +#include + +MonotoneProcess::MonotoneProcess(const QString & workdir) { - setWorkingDirectory(ws); + QString work(workdir); + if (workdir.isEmpty()) + { + // a somewhat reasonable path to choose to avoid side effects + // like another existing monotone workspace + work = QDir::tempPath(); + } + setWorkingDirectory(work); + setProcessChannelMode(QProcess::MergedChannels); + QStringList env = QProcess::systemEnvironment(); + env.replaceInStrings(QRegExp("^LANG=.*", Qt::CaseInsensitive), ""); + env.push_back("LANG=en_US.UTF-8"); + setEnvironment(env); + connect( this, SIGNAL(readyReadStandardOutput()), this, SLOT(readOutput()) @@ -52,23 +67,38 @@ MonotoneProcess::~MonotoneProcess() } } +void MonotoneProcess::setMtnBinaryPath(const QString & path) +{ + mtnBinaryPath = path; +} + void MonotoneProcess::start(const QStringList & params) { - QString mtnBinary = Settings::getMtnBinaryPath(); + if (mtnBinaryPath.isEmpty()) + { + mtnBinaryPath = Settings::getMtnBinaryPath(); + } L(QString("starting external monotone process %1 %2") - .arg(mtnBinary).arg(params.join(" "))); + .arg(mtnBinaryPath).arg(params.join(" "))); - QProcess::start(mtnBinary, params); + QProcess::start(mtnBinaryPath, params); } void MonotoneProcess::readOutput() { QByteArray out = readAll(); if (out.isEmpty()) return; - emit output(QString::fromUtf8(out)); + QString strOut = QString::fromUtf8(out); + emit output(strOut); + bufferedOutput += strOut; } +QString MonotoneProcess::getBufferedOutput() const +{ + return bufferedOutput; +} + void MonotoneProcess::processError(QProcess::ProcessError processError) { QString message = QString::fromUtf8(readAllStandardError()); @@ -119,3 +149,21 @@ void MonotoneProcess::processError(QProc emit error(userMessage); } +bool MonotoneProcess::successful() +{ + return exitStatus() == QProcess::NormalExit && + exitCode() == 0; +} + +bool MonotoneProcess::singleRun(const QStringList & params, + const QString & workdir, + QString & output) +{ + MonotoneProcess proc(workdir); + proc.start(params); + proc.waitForFinished(); + + output = proc.getBufferedOutput(); + return proc.successful(); +} + ============================================================ --- src/monotone/MonotoneProcess.h 5eafbef157ea2e63b4d57be4d9272488370112e8 +++ src/monotone/MonotoneProcess.h 547aa8e0fd0a45f3c0edae16784a84d2e13b06a0 @@ -26,11 +26,18 @@ public: { Q_OBJECT public: - MonotoneProcess(const QString &); + MonotoneProcess(const QString & workdir = QString()); virtual ~MonotoneProcess(); void start(const QStringList &); + QString getBufferedOutput() const; + void setMtnBinaryPath(const QString &); + + bool successful(); + + static bool singleRun(const QStringList & params, const QString &, QString & output); + signals: void output(const QString &); void error(const QString &); @@ -38,6 +45,10 @@ private slots: private slots: void readOutput(); void processError(QProcess::ProcessError); + +private: + QString mtnBinaryPath; + QString bufferedOutput; }; #endif ============================================================ --- src/view/dialogs/CreateDatabase.cpp 85abc9702b55b5badbcb42c966a826d9ea9824f7 +++ src/view/dialogs/CreateDatabase.cpp 3e3252bd4c9fe7b305adc2c3b939eb1210e35202 @@ -17,7 +17,7 @@ ***************************************************************************/ #include "CreateDatabase.h" -#include "MonotoneManager.h" +#include "MonotoneProcess.h" #include "MonotoneUtil.h" #include "Settings.h" @@ -97,9 +97,9 @@ void CreateDatabase::accept() QStringList params; params << "db" << "init" << "-d" << filePath; - QByteArray output; + QString output; - bool res = MonotoneManager::singleRun(Settings::getMtnBinaryPath(), params, output); + bool res = MonotoneProcess::singleRun(params, QString(), output); if (!res) { @@ -107,7 +107,7 @@ void CreateDatabase::accept() this, tr("Cannot create database"), tr("An error occured while creating the database:\n%1'.") - .arg(MonotoneUtil::stripMtnPrefix(QString(output))), + .arg(MonotoneUtil::stripMtnPrefix(output)), QMessageBox::Ok ); return; ============================================================ --- src/view/dialogs/KeyManagement.cpp 10a95be196dda8d70292d8b71c199d31862320a3 +++ src/view/dialogs/KeyManagement.cpp 567f228b82e256aa7cd648b88da2d05b9e7a02df @@ -18,7 +18,7 @@ #include "KeyManagement.h" #include "GenerateKeypair.h" -#include "MonotoneManager.h" +#include "MonotoneProcess.h" #include "Settings.h" #include @@ -146,10 +146,10 @@ void KeyManagement::copyPubkeyDataToClip QClipboard * clipboard = QApplication::clipboard(); QStringList args; - QByteArray output; + QString output; args << "-d" << databaseFile << "pubkey" << key->hash; - if (!MonotoneManager::singleRun(Settings::getMtnBinaryPath(), args, output)) + if (!MonotoneProcess::singleRun(args, QString(), output)) { QMessageBox::critical( this, @@ -161,7 +161,7 @@ void KeyManagement::copyPubkeyDataToClip return; } - clipboard->setText(QString::fromUtf8(output)); + clipboard->setText(output); } // TODO: should be converted to automate dropkey, if available @@ -201,15 +201,15 @@ void KeyManagement::dropKey() QStringList args; args << "-d" << databaseFile << "dropkey" << key->hash; - QByteArray output; - if (!MonotoneManager::singleRun(Settings::getMtnBinaryPath(), args, output)) + QString output; + if (!MonotoneProcess::singleRun(args, QString(), output)) { QMessageBox::critical( this, tr("Couldn't drop key"), tr("Failed to drop key \"%1\": %2") .arg(key->hash) - .arg(QString(output)), + .arg(output), QMessageBox::Ok ); return;