changeset 691:5b3bcb2d0943

Update handling of auth extension load failures on Windows: hg itself is returning a successful error code, so we must check the output in the extension test phase. Also fix a failure & crash when trying to use fallback auth mechanism
author Chris Cannam
date Mon, 10 Dec 2018 12:03:04 +0000
parents bfafe078df9a
children a74515f1c6e8
files src/grapher.cpp src/hgrunner.cpp src/hgrunner.h src/mainwindow.cpp src/mainwindow.h
diffstat 5 files changed, 56 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/src/grapher.cpp	Mon Dec 10 10:28:25 2018 +0000
+++ b/src/grapher.cpp	Mon Dec 10 12:03:04 2018 +0000
@@ -24,6 +24,8 @@
 
 #include <iostream>
 
+//#define GRAPHER_VERBOSE_DEBUG 1
+
 Grapher::Grapher(ChangesetScene *scene) :
     m_scene(scene)
 {
@@ -74,7 +76,9 @@
     }
     Changeset *cs = m_changesets[id];
     ChangesetItem *item = m_items[id];
+#ifdef GRAPHER_VERBOSE_DEBUG
     DEBUG << "layoutRow: Looking at " << id.toStdString() << endl;
+#endif
 
     int row = 0;
     int nparents = cs->parents().size();
@@ -129,9 +133,11 @@
         m_uncommittedParentRow = row;
     }
 
+#ifdef GRAPHER_VERBOSE_DEBUG
     DEBUG << "putting " << cs->id().toStdString() << " at row " << row 
           << endl;
-
+#endif
+    
     item->setRow(row);
     m_handled.insert(id);
 }
@@ -139,7 +145,9 @@
 void Grapher::layoutCol(QString id)
 {
     if (m_handled.contains(id)) {
+#ifdef GRAPHER_VERBOSE_DEBUG
         DEBUG << "Already looked at " << id.toStdString() << endl;
+#endif
         return;
     }
     if (!m_changesets.contains(id)) {
@@ -150,7 +158,9 @@
     }
 
     Changeset *cs = m_changesets[id];
+#ifdef GRAPHER_VERBOSE_DEBUG
     DEBUG << "layoutCol: Looking at " << id.toStdString() << endl;
+#endif
 
     ChangesetItem *item = m_items[id];
 
@@ -209,8 +219,10 @@
         break;
     }
 
+#ifdef GRAPHER_VERBOSE_DEBUG
     DEBUG << "putting " << cs->id().toStdString() << " at col " << col << endl;
-
+#endif
+    
     m_alloc[row].insert(col);
     item->setColumn(col);
     m_handled.insert(id);
@@ -246,7 +258,9 @@
     // connection lines
 
     foreach (QString childId, cs->children()) {
+#ifdef GRAPHER_VERBOSE_DEBUG
         DEBUG << "reserving connection line space" << endl;
+#endif
         if (!m_items.contains(childId)) continue;
         Changeset *child = m_changesets[childId];
         int childRow = m_items[childId]->row();
@@ -272,7 +286,9 @@
             }
         }
         if (special.size() == 2) {
+#ifdef GRAPHER_VERBOSE_DEBUG
             DEBUG << "handling split-in-two for children " << special[0] << " and " << special[1] << endl;
+#endif
             for (int i = 0; i < 2; ++i) {
                 int off = i * 2 - 1; // 0 -> -1, 1 -> 1
                 ChangesetItem *it = m_items[special[i]];
@@ -352,9 +368,11 @@
         m_branchHomes[branch] = home;
     }
 
+#ifdef GRAPHER_VERBOSE_DEBUG
     foreach (QString branch, m_branchRanges.keys()) {
         DEBUG << branch.toStdString() << ": " << m_branchRanges[branch].first << " - " << m_branchRanges[branch].second << ", home " << m_branchHomes[branch] << endl;
     }
+#endif
 }
 
 static bool
@@ -630,10 +648,12 @@
 
     qStableSort(csets.begin(), csets.end(), compareChangesetsByDate);
 
+#ifdef GRAPHER_VERBOSE_DEBUG
     foreach (Changeset *cs, csets) {
         DEBUG << "id " << cs->id().toStdString() << ", ts " << cs->timestamp()
               << ", date " << cs->datetime().toStdString() << endl;
     }
+#endif
 
     m_handled.clear();
     foreach (Changeset *cs, csets) {
@@ -684,7 +704,9 @@
 
     if (m_uncommitted) {
         --minrow;
+#ifdef GRAPHER_VERBOSE_DEBUG
         DEBUG << "putting uncommitted item at row " << minrow << endl;
+#endif
         m_uncommitted->setRow(minrow);
     }
 
--- a/src/hgrunner.cpp	Mon Dec 10 10:28:25 2018 +0000
+++ b/src/hgrunner.cpp	Mon Dec 10 12:03:04 2018 +0000
@@ -44,7 +44,8 @@
 
 HgRunner::HgRunner(QString myDirPath, QWidget *parent) :
     QWidget(parent),
-    m_myDirPath(myDirPath)
+    m_myDirPath(myDirPath),
+    m_ptyFile(0)
 {
     QGridLayout *layout = new QGridLayout(this);
     layout->setMargin(0);
@@ -266,12 +267,12 @@
         if (m_realm != "") {
             prompt = tr("User name for \"%1\":").arg(m_realm);
         }
-        QString pwd = QInputDialog::getText
+        QString name = QInputDialog::getText
             (qobject_cast<QWidget *>(parent()),
             tr("Enter user name"), prompt,
             QLineEdit::Normal, QString(), &ok);
         if (ok) {
-            m_ptyFile->write(QString("%1\n").arg(pwd).toUtf8());
+            m_ptyFile->write(QString("%1\n").arg(name).toUtf8());
             m_ptyFile->flush();
             return;
         } else {
@@ -279,6 +280,9 @@
             killCurrentCommand();
             return;
         }
+    } else { // usual on win32
+        DEBUG << "HgRunner::getUsername: can't handle without pty" << endl;
+        emit commandFailed(m_currentAction, "", "Host requires authentication, but we can't handle that without the EasyHg extension loaded");
     }
     // user cancelled or something went wrong
     DEBUG << "HgRunner::getUsername: something went wrong" << endl;
@@ -301,7 +305,7 @@
         }
         QString pwd = QInputDialog::getText
             (qobject_cast<QWidget *>(parent()),
-            tr("Enter password"), prompt,
+             tr("Enter password"), prompt,
              QLineEdit::Password, QString(), &ok);
         if (ok) {
             m_ptyFile->write(QString("%1\n").arg(pwd).toUtf8());
@@ -312,6 +316,9 @@
             killCurrentCommand();
             return;
         }
+    } else { // usual on win32
+        DEBUG << "HgRunner::getPassword: can't handle without pty" << endl;
+        emit commandFailed(m_currentAction, "", "Host requires authentication, but we can't handle that without the EasyHg extension loaded");
     }
     // user cancelled or something went wrong
     DEBUG << "HgRunner::getPassword: something went wrong" << endl;
@@ -405,16 +412,15 @@
         DEBUG << "HgRunner::finished: WARNING: completed action is ACT_NONE" << endl;
     } else {
         if (procExitCode == 0 && procExitStatus == QProcess::NormalExit) {
-            DEBUG << "HgRunner::finished: Command completed successfully"
-                  << endl;
+            DEBUG << "HgRunner::finished: Command completed successfully" << endl;
 //            DEBUG << "stdout is " << m_stdout << endl;
-            emit commandCompleted(completedAction, m_stdout);
+            emit commandCompleted(completedAction, m_stdout, m_stderr);
         } else {
             DEBUG << "HgRunner::finished: Command failed, exit code "
                   << procExitCode << ", exit status " << int(procExitStatus)
                   << ", stderr follows" << endl;
             DEBUG << m_stderr << endl;
-            emit commandFailed(completedAction, m_stderr, m_stdout);
+            emit commandFailed(completedAction, m_stdout, m_stderr);
         }
     }
 
@@ -550,7 +556,7 @@
 {
     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", "");
+        emit commandFailed(action, "", "EasyMercurial: No working directory supplied, will not run Mercurial command without one");
         return;
     }
 
--- a/src/hgrunner.h	Mon Dec 10 10:28:25 2018 +0000
+++ b/src/hgrunner.h	Mon Dec 10 12:03:04 2018 +0000
@@ -43,8 +43,8 @@
 
 signals:
     void commandStarting(HgAction action);
-    void commandCompleted(HgAction action, QString stdOut);
-    void commandFailed(HgAction action, QString stdErr, QString stdOut);
+    void commandCompleted(HgAction action, QString stdOut, QString stdErr);
+    void commandFailed(HgAction action, QString stdOut, QString stdErr);
 
     /**
      * Emitted when the currently executing command is cancelled. Note
--- a/src/mainwindow.cpp	Mon Dec 10 10:28:25 2018 +0000
+++ b/src/mainwindow.cpp	Mon Dec 10 12:03:04 2018 +0000
@@ -81,8 +81,8 @@
     m_runner = new HgRunner(m_myDirPath, this);
     connect(m_runner, SIGNAL(commandStarting(HgAction)),
             this, SLOT(commandStarting(HgAction)));
-    connect(m_runner, SIGNAL(commandCompleted(HgAction, QString)),
-            this, SLOT(commandCompleted(HgAction, QString)));
+    connect(m_runner, SIGNAL(commandCompleted(HgAction, QString, QString)),
+            this, SLOT(commandCompleted(HgAction, QString, QString)));
     connect(m_runner, SIGNAL(commandFailed(HgAction, QString, QString)),
             this, SLOT(commandFailed(HgAction, QString, QString)));
     connect(m_runner, SIGNAL(commandCancelled(HgAction)),
@@ -2054,7 +2054,7 @@
     m_commandSequenceInProgress = true;
 }
 
-void MainWindow::commandFailed(HgAction action, QString stdErr, QString stdOut)
+void MainWindow::commandFailed(HgAction action, QString stdOut, QString stdErr)
 {
     DEBUG << "MainWindow::commandFailed" << endl;
 
@@ -2141,7 +2141,7 @@
         } else if (stdErr.contains("no changes found") || stdOut.contains("no changes found")) {
             // success: hg 2.1 starts returning failure code for empty pull/push
             m_commandSequenceInProgress = true; // there may be further commands
-            commandCompleted(action, stdOut);
+            commandCompleted(action, stdOut, stdErr);
             return;
         }
         break; // go on to default report
@@ -2158,7 +2158,7 @@
         } else if (stdErr.contains("no changes found") || stdOut.contains("no changes found")) {
             // success: hg 2.1 starts returning failure code for empty pull/push
             m_commandSequenceInProgress = true; // there may be further commands
-            commandCompleted(action, stdOut);
+            commandCompleted(action, stdOut, stdErr);
             return;
         }
         break; // go on to default report
@@ -2169,7 +2169,7 @@
         // succeeded, so that any further actions that are contingent
         // on the success of the heads query get carried out properly.
         m_commandSequenceInProgress = true; // there may be further commands
-        commandCompleted(action, "");
+        commandCompleted(action, "", "");
         return;
     case ACT_FOLDERDIFF:
     case ACT_CHGSETDIFF:
@@ -2218,7 +2218,7 @@
          stdErr);
 }
 
-void MainWindow::commandCompleted(HgAction completedAction, QString output)
+void MainWindow::commandCompleted(HgAction completedAction, QString output, QString stdErr)
 {
 //    std::cerr << "commandCompleted: " << completedAction.action << std::endl;
 
@@ -2254,6 +2254,10 @@
     }
 
     case ACT_TEST_HG_EXT:
+        if (stdErr.contains("Failed to load PyQt")) {
+            commandFailed(completedAction, output, stdErr);
+            return;
+        }
         break;
 
     case ACT_QUERY_PATHS:
@@ -2294,8 +2298,10 @@
             }
             output = winnowed.join("\n");
         }
+        /*
         DEBUG << "m_lastStatOutput = " << m_lastStatOutput << endl;
         DEBUG << "resolve output = " << output << endl;
+        */
         m_hgTabs->updateWorkFolderFileList(m_lastStatOutput + output);
         break;
 
--- a/src/mainwindow.h	Mon Dec 10 10:28:25 2018 +0000
+++ b/src/mainwindow.h	Mon Dec 10 12:03:04 2018 +0000
@@ -52,8 +52,8 @@
     void open(QString local);
     void hgRefresh();
     void commandStarting(HgAction);
-    void commandCompleted(HgAction action, QString stdOut);
-    void commandFailed(HgAction action, QString stdErr, QString stdOut);
+    void commandCompleted(HgAction action, QString stdOut, QString stdErr);
+    void commandFailed(HgAction action, QString stdOut, QString stdErr);
     void commandCancelled(HgAction action);
     void enableDisableActions();