# HG changeset patch # User Chris Cannam # Date 1341310930 -3600 # Node ID ab92f695f776ce3a98b4fda94e5897efc9dd17ab # Parent 98f57888d893b9d287c7d95fec87f55bdd617690 Expand environmental parameters and executable name in action when it is received rather than when it's executed. This ensures we can correctly compare actions and fixes #141 "Unexpected error if you double-click on a toolbar button" diff -r 98f57888d893 -r ab92f695f776 easyhg.pro --- a/easyhg.pro Tue Jul 03 10:43:05 2012 +0100 +++ b/easyhg.pro Tue Jul 03 11:22:10 2012 +0100 @@ -1,5 +1,5 @@ -CONFIG += release +CONFIG += debug TEMPLATE = app TARGET = EasyMercurial diff -r 98f57888d893 -r ab92f695f776 src/hgaction.h --- a/src/hgaction.h Tue Jul 03 10:43:05 2012 +0100 +++ b/src/hgaction.h Tue Jul 03 11:22:10 2012 +0100 @@ -70,7 +70,7 @@ QString executable; // empty for normal Hg, but gets filled in by hgrunner void *extraData; - HgAction() : action(ACT_NONE) { } + HgAction() : action(ACT_NONE), extraData(0) { } HgAction(HGACTIONS _action, QString _wd, QStringList _params) : action(_action), workingDir(_wd), params(_params), extraData(0) { } @@ -79,9 +79,10 @@ action(_action), workingDir(_wd), params(_params), extraData(_d) { } bool operator==(const HgAction &a) { - return (a.action == action && a.workingDir == workingDir && - a.params == params && a.executable == executable && - a.extraData == extraData); + bool equal = (a.action == action && a.workingDir == workingDir && + a.params == params && a.executable == executable && + a.extraData == extraData); + return equal; } bool shouldBeFast() const { diff -r 98f57888d893 -r ab92f695f776 src/hgrunner.cpp --- a/src/hgrunner.cpp Tue Jul 03 10:43:05 2012 +0100 +++ b/src/hgrunner.cpp Tue Jul 03 11:22:10 2012 +0100 @@ -151,8 +151,11 @@ void HgRunner::requestAction(HgAction action) { - DEBUG << "requestAction " << action.action << endl; + DEBUG << "requestAction " << action.action << ": " << m_queue.size() << " thing(s) in queue, current action is " << m_currentAction.action << endl; bool pushIt = true; + + action = expandEnvironment(action); + if (m_queue.empty()) { if (action == m_currentAction) { // this request is identical to the thing we're executing @@ -168,10 +171,50 @@ pushIt = false; } } - if (pushIt) m_queue.push_back(action); + if (pushIt) { + m_queue.push_back(action); + } checkQueue(); } +HgAction HgRunner::expandEnvironment(HgAction action) +{ + // Adjust the executable and params for action to match our actual + // environment. We do this when the action is received, rather + // than when we execute it, so that we can compare + // (post-expansion) commands to see e.g. whether the one just + // received is the same as the one we're currently executing + + QString executable = action.executable; + QStringList params = action.params; + + if (executable == "") { + // This is a Hg command + executable = getHgBinaryName(); + if (executable == "") executable = "hg"; + + QString ssh = getSshBinaryName(); + if (ssh != "") { + params.push_front(QString("ui.ssh=\"%1\"").arg(ssh)); + params.push_front("--config"); + } + + if (action.mayBeInteractive()) { + params.push_front("ui.interactive=true"); + params.push_front("--config"); + QSettings settings; + if (settings.value("useextension", true).toBool()) { + params = addExtensionOptions(params); + } + } + } + + action.executable = executable; + action.params = params; + + return action; +} + QString HgRunner::getHgBinaryName() { QSettings settings; @@ -349,6 +392,8 @@ HgAction completedAction = m_currentAction; + DEBUG << "HgRunner::finished: completed " << completedAction.action << endl; + m_isRunning = false; m_currentAction = HgAction(); @@ -503,40 +548,12 @@ void HgRunner::startCommand(HgAction action) { - QString executable = action.executable; - bool interactive = false; - QStringList params = action.params; - if (action.workingDir.isEmpty()) { // We require a working directory, never just operate in pwd emit commandFailed(action, "EasyMercurial: No working directory supplied, will not run Mercurial command without one", ""); return; } - if (executable == "") { - // This is a Hg command - executable = getHgBinaryName(); - if (executable == "") executable = "hg"; - - QString ssh = getSshBinaryName(); - if (ssh != "") { - params.push_front(QString("ui.ssh=\"%1\"").arg(ssh)); - params.push_front("--config"); - } - - if (action.mayBeInteractive()) { - params.push_front("ui.interactive=true"); - params.push_front("--config"); - QSettings settings; - if (settings.value("useextension", true).toBool()) { - params = addExtensionOptions(params); - } - interactive = true; - } - - //!!! want an option to use the mercurial_keyring extension as well - } - m_isRunning = true; m_progress->setRange(0, 0); if (!action.shouldBeFast()) { @@ -583,7 +600,7 @@ m_proc->setWorkingDirectory(action.workingDir); - if (interactive) { + if (action.mayBeInteractive()) { openTerminal(); if (m_ptySlaveFilename != "") { DEBUG << "HgRunner: connecting to pseudoterminal" << endl; @@ -593,22 +610,18 @@ } } - QString cmdline = executable; - foreach (QString param, params) cmdline += " " + param; + QString cmdline = action.executable; + foreach (QString param, action.params) cmdline += " " + param; DEBUG << "HgRunner: starting: " << cmdline << " with cwd " << action.workingDir << endl; m_currentAction = action; - // fill these out with what we actually ran - m_currentAction.executable = executable; - m_currentAction.params = params; - DEBUG << "set current action to " << m_currentAction.action << endl; emit commandStarting(action); - m_proc->start(executable, params); + m_proc->start(action.executable, action.params); } void HgRunner::closeProcInput() diff -r 98f57888d893 -r ab92f695f776 src/hgrunner.h --- a/src/hgrunner.h Tue Jul 03 10:43:05 2012 +0100 +++ b/src/hgrunner.h Tue Jul 03 11:22:10 2012 +0100 @@ -90,6 +90,7 @@ QProgressBar *m_progress; QPushButton *m_cancel; + HgAction expandEnvironment(HgAction); QStringList addExtensionOptions(QStringList); int m_ptyMasterFd;