Mercurial > hg > easyhg
comparison src/hgrunner.cpp @ 605:ab92f695f776
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"
author | Chris Cannam |
---|---|
date | Tue, 03 Jul 2012 11:22:10 +0100 |
parents | 012ba1b83328 |
children | ae67ea0af696 |
comparison
equal
deleted
inserted
replaced
604:98f57888d893 | 605:ab92f695f776 |
---|---|
149 return unbundled; | 149 return unbundled; |
150 } | 150 } |
151 | 151 |
152 void HgRunner::requestAction(HgAction action) | 152 void HgRunner::requestAction(HgAction action) |
153 { | 153 { |
154 DEBUG << "requestAction " << action.action << endl; | 154 DEBUG << "requestAction " << action.action << ": " << m_queue.size() << " thing(s) in queue, current action is " << m_currentAction.action << endl; |
155 bool pushIt = true; | 155 bool pushIt = true; |
156 | |
157 action = expandEnvironment(action); | |
158 | |
156 if (m_queue.empty()) { | 159 if (m_queue.empty()) { |
157 if (action == m_currentAction) { | 160 if (action == m_currentAction) { |
158 // this request is identical to the thing we're executing | 161 // this request is identical to the thing we're executing |
159 DEBUG << "requestAction: we're already handling this one, ignoring identical request" << endl; | 162 DEBUG << "requestAction: we're already handling this one, ignoring identical request" << endl; |
160 pushIt = false; | 163 pushIt = false; |
166 // queued which we haven't executed yet | 169 // queued which we haven't executed yet |
167 DEBUG << "requestAction: we're already queueing this one, ignoring identical request" << endl; | 170 DEBUG << "requestAction: we're already queueing this one, ignoring identical request" << endl; |
168 pushIt = false; | 171 pushIt = false; |
169 } | 172 } |
170 } | 173 } |
171 if (pushIt) m_queue.push_back(action); | 174 if (pushIt) { |
175 m_queue.push_back(action); | |
176 } | |
172 checkQueue(); | 177 checkQueue(); |
178 } | |
179 | |
180 HgAction HgRunner::expandEnvironment(HgAction action) | |
181 { | |
182 // Adjust the executable and params for action to match our actual | |
183 // environment. We do this when the action is received, rather | |
184 // than when we execute it, so that we can compare | |
185 // (post-expansion) commands to see e.g. whether the one just | |
186 // received is the same as the one we're currently executing | |
187 | |
188 QString executable = action.executable; | |
189 QStringList params = action.params; | |
190 | |
191 if (executable == "") { | |
192 // This is a Hg command | |
193 executable = getHgBinaryName(); | |
194 if (executable == "") executable = "hg"; | |
195 | |
196 QString ssh = getSshBinaryName(); | |
197 if (ssh != "") { | |
198 params.push_front(QString("ui.ssh=\"%1\"").arg(ssh)); | |
199 params.push_front("--config"); | |
200 } | |
201 | |
202 if (action.mayBeInteractive()) { | |
203 params.push_front("ui.interactive=true"); | |
204 params.push_front("--config"); | |
205 QSettings settings; | |
206 if (settings.value("useextension", true).toBool()) { | |
207 params = addExtensionOptions(params); | |
208 } | |
209 } | |
210 } | |
211 | |
212 action.executable = executable; | |
213 action.params = params; | |
214 | |
215 return action; | |
173 } | 216 } |
174 | 217 |
175 QString HgRunner::getHgBinaryName() | 218 QString HgRunner::getHgBinaryName() |
176 { | 219 { |
177 QSettings settings; | 220 QSettings settings; |
346 // emit a signal to mark the completion; otherwise we may be | 389 // emit a signal to mark the completion; otherwise we may be |
347 // resetting the action after a slot has already tried to set it | 390 // resetting the action after a slot has already tried to set it |
348 // to something else to start a new action | 391 // to something else to start a new action |
349 | 392 |
350 HgAction completedAction = m_currentAction; | 393 HgAction completedAction = m_currentAction; |
394 | |
395 DEBUG << "HgRunner::finished: completed " << completedAction.action << endl; | |
351 | 396 |
352 m_isRunning = false; | 397 m_isRunning = false; |
353 m_currentAction = HgAction(); | 398 m_currentAction = HgAction(); |
354 | 399 |
355 //closeProcInput(); | 400 //closeProcInput(); |
501 return params; | 546 return params; |
502 } | 547 } |
503 | 548 |
504 void HgRunner::startCommand(HgAction action) | 549 void HgRunner::startCommand(HgAction action) |
505 { | 550 { |
506 QString executable = action.executable; | |
507 bool interactive = false; | |
508 QStringList params = action.params; | |
509 | |
510 if (action.workingDir.isEmpty()) { | 551 if (action.workingDir.isEmpty()) { |
511 // We require a working directory, never just operate in pwd | 552 // We require a working directory, never just operate in pwd |
512 emit commandFailed(action, "EasyMercurial: No working directory supplied, will not run Mercurial command without one", ""); | 553 emit commandFailed(action, "EasyMercurial: No working directory supplied, will not run Mercurial command without one", ""); |
513 return; | 554 return; |
514 } | |
515 | |
516 if (executable == "") { | |
517 // This is a Hg command | |
518 executable = getHgBinaryName(); | |
519 if (executable == "") executable = "hg"; | |
520 | |
521 QString ssh = getSshBinaryName(); | |
522 if (ssh != "") { | |
523 params.push_front(QString("ui.ssh=\"%1\"").arg(ssh)); | |
524 params.push_front("--config"); | |
525 } | |
526 | |
527 if (action.mayBeInteractive()) { | |
528 params.push_front("ui.interactive=true"); | |
529 params.push_front("--config"); | |
530 QSettings settings; | |
531 if (settings.value("useextension", true).toBool()) { | |
532 params = addExtensionOptions(params); | |
533 } | |
534 interactive = true; | |
535 } | |
536 | |
537 //!!! want an option to use the mercurial_keyring extension as well | |
538 } | 555 } |
539 | 556 |
540 m_isRunning = true; | 557 m_isRunning = true; |
541 m_progress->setRange(0, 0); | 558 m_progress->setRange(0, 0); |
542 if (!action.shouldBeFast()) { | 559 if (!action.shouldBeFast()) { |
581 connect(m_proc, SIGNAL(readyReadStandardError()), | 598 connect(m_proc, SIGNAL(readyReadStandardError()), |
582 this, SLOT(dataReadyStderr())); | 599 this, SLOT(dataReadyStderr())); |
583 | 600 |
584 m_proc->setWorkingDirectory(action.workingDir); | 601 m_proc->setWorkingDirectory(action.workingDir); |
585 | 602 |
586 if (interactive) { | 603 if (action.mayBeInteractive()) { |
587 openTerminal(); | 604 openTerminal(); |
588 if (m_ptySlaveFilename != "") { | 605 if (m_ptySlaveFilename != "") { |
589 DEBUG << "HgRunner: connecting to pseudoterminal" << endl; | 606 DEBUG << "HgRunner: connecting to pseudoterminal" << endl; |
590 m_proc->setStandardInputFile(m_ptySlaveFilename); | 607 m_proc->setStandardInputFile(m_ptySlaveFilename); |
591 // m_proc->setStandardOutputFile(m_ptySlaveFilename); | 608 // m_proc->setStandardOutputFile(m_ptySlaveFilename); |
592 // m_proc->setStandardErrorFile(m_ptySlaveFilename); | 609 // m_proc->setStandardErrorFile(m_ptySlaveFilename); |
593 } | 610 } |
594 } | 611 } |
595 | 612 |
596 QString cmdline = executable; | 613 QString cmdline = action.executable; |
597 foreach (QString param, params) cmdline += " " + param; | 614 foreach (QString param, action.params) cmdline += " " + param; |
598 DEBUG << "HgRunner: starting: " << cmdline << " with cwd " | 615 DEBUG << "HgRunner: starting: " << cmdline << " with cwd " |
599 << action.workingDir << endl; | 616 << action.workingDir << endl; |
600 | 617 |
601 m_currentAction = action; | 618 m_currentAction = action; |
602 | |
603 // fill these out with what we actually ran | |
604 m_currentAction.executable = executable; | |
605 m_currentAction.params = params; | |
606 | 619 |
607 DEBUG << "set current action to " << m_currentAction.action << endl; | 620 DEBUG << "set current action to " << m_currentAction.action << endl; |
608 | 621 |
609 emit commandStarting(action); | 622 emit commandStarting(action); |
610 | 623 |
611 m_proc->start(executable, params); | 624 m_proc->start(action.executable, action.params); |
612 } | 625 } |
613 | 626 |
614 void HgRunner::closeProcInput() | 627 void HgRunner::closeProcInput() |
615 { | 628 { |
616 DEBUG << "closeProcInput" << endl; | 629 DEBUG << "closeProcInput" << endl; |