# # # patch "README" # from [f37daeff38add26a4a05accb433a0c5af7c84924] # to [bf3172aa635779af620b46a6d95d33386180eb1a] # # patch "guitone/res/i18n/guitone_de.ts" # from [a0c30faa571aafe55113adc34e84c2de48a4e3bc] # to [713e5d3afff9c38bd736069aa58814c989550c8d] # # patch "guitone/src/monotone/Monotone.cpp" # from [88bc4ff50da75cffd8f07c736684f0623f7b9823] # to [169a5fa6a658f48fba1c7185c8062719f5bd04a7] # # patch "guitone/src/monotone/Monotone.h" # from [f459bf030a300af821f5dd4bcce361eb50cd3d25] # to [02a04c161701e05523f3d7e592d10052025633b7] # # patch "guitone/src/view/Guitone.cpp" # from [c6305b59f96b6d3db7974445d4037ad5ebb6fcd9] # to [8c153efa88318080ff59efd36ed861be59eaa400] # # patch "guitone/src/view/dialogs/Preferences.cpp" # from [af5362667100fcffceeb18ef8834226c601281eb] # to [0521f0b9c40bbfcd7100fbf12ff91ea68ce14279] # ============================================================ --- README f37daeff38add26a4a05accb433a0c5af7c84924 +++ README bf3172aa635779af620b46a6d95d33386180eb1a @@ -6,8 +6,9 @@ to browse through the workspace contents just like a normal file browser, but by displaying additional file status information. -You need Qt >= 4.2 to build and monotone >= 0.32 to run guitone. Earlier -versions do not have all teh infrastructure for certain functionalities +You need Qt >= 4.2 to build and monotone >= 0.32 (or a monotone with +an interface version of 4.0 or greater) to run guitone. Earlier +versions do not have all the infrastructure for certain functionalities available, but might still work in some areas. To build under Linux / MacOS X just do ============================================================ --- guitone/res/i18n/guitone_de.ts a0c30faa571aafe55113adc34e84c2de48a4e3bc +++ guitone/res/i18n/guitone_de.ts 713e5d3afff9c38bd736069aa58814c989550c8d @@ -246,7 +246,7 @@ guitone - ein Frontend für monotone - + &File &Datei @@ -256,7 +256,7 @@ Arbeitsbereich &importieren - + &Quit &Beenden @@ -266,17 +266,17 @@ Bereit - + Select your workspace... Wählen Sie Ihren Arbeitsbereich aus... - + Loading aborted Laden abgebrochen - + Invalid workspace Ungültiger Arbeitsbereich @@ -296,7 +296,7 @@ Das Inventar konnte nicht gelesen werden. Vielleicht läuft noch ein anderer Prozess? - + Loading workspace... Lade Arbeitsbereich... @@ -313,7 +313,7 @@ STRG+Q - + The chosen directory is no monotone workspace! Das gewählte Verzeichnis ist kein monotone-Arbeitsverzeichnis! @@ -323,7 +323,7 @@ &Importiere Arbeitsbereich - + Critical Monotone Error Kritischer monotone-Fehler @@ -334,47 +334,47 @@ STRG+I - + &View &Ansicht - + &Hide ignored files Ignorierte Dateien &verstecken - + &Show ignored files Ignorierte Dateien a&nzeigen - + &Recent Workspaces &Vorherige Arbeitsbereiche - + &Open Workspace Arbeitsbereich &öffnen - + &%1 %2 &%1 %2 - + No previous workspaces available. Keine vorherigen Arbeitsbereiche verfügbar. - + &Workspace &Arbeitsbereich - + &Switch revision Auf andere &Revision aktualisieren @@ -389,55 +389,60 @@ &Schlüsselverwaltung - + About &Qt Über &Qt - + &Help &Hilfe - + &Database &Datenbank - + &Show ancestry graph &Historiengraph anzeigen - + &Preferences... &Einstellungen... - + &Key Management &Schlüsselverwaltung - + Unable to execute command Konnte Kommando nicht ausführen - + Unable to execute '%1' - maybe another command is still running? Konnte '%1' nicht ausführen - eventuell läuft noch ein anderes Kommando? - + Error Fehler The path to the monotone binary is either invalid or points to an older version of monotone. Guitone requires monotone version %1 or later. - Der Pfad zur ausführbaren Datei von monotone ist entweder ungültig oder zeigt auf eine ältere Version von monotone. Guitone benötigt Version %1 oder neuer. + Der Pfad zur ausführbaren Datei von monotone ist entweder ungültig oder zeigt auf eine ältere Version von monotone. Guitone benötigt Version %1 oder neuer. + + + The path to the monotone binary is either invalid or points to an older version of monotone. Guitone requires monotone version %1 or a monotone with interface version %2 or later. + Der Pfad zur ausführbaren Datei von monotone ist entweder ungültig oder zeigt auf eine ältere Version von monotone. Guitone benötigt monotone Version %1 oder ein monotone mit einer Interface-Version %2 oder neuer. + Inventory @@ -838,17 +843,17 @@ korrekt installiert? korrekt installiert? - + Unable to process command '%1': %2 Das Kommando '%1' konnte nicht abgearbeitet werden: %2 - + Monotone failed to start (Code %1). Please configure the path in the Preferences dialog. Monotone konnte nicht gestartet werden (Code %1). Bitte konfigurieren Sie den Pfad im Eintellungsdialog. - + The connection to the monotone process was terminated (Code %1). Check your configuration and reload the current workspace afterwards. Die Verbindung zum monotone-Prozess wurde beendet (Code %1). Prüfen Sie Ihre Konfiguration und laden Sie ggf. den Arbeitsbereich danach neu. @@ -856,7 +861,7 @@ korrekt installiert? Preferences - + Error Fehler @@ -866,30 +871,35 @@ korrekt installiert? Der eingegebene Pfad ist entweder ungültig oder zeigt auf eine ältere Version von monotone. Guitone benötigt Version %1 oder neuer. - + Notice Hinweis - + You need to reload your current workspace or restart guitone to use the new monotone binary. Sie müssen Ihren derzeitigen Arbeitsbereich neu laden oder guitone neu starten, um die neuen Einstellungen zu verwenden. - + Choose the monotone executable Wählen Sie die ausführbare Datei von monotone - + Binaries (mtn mtn.exe) Ausführbare Dateien (mtn mtn.exe) The path to the monotone binary is either invalid or points to an older version of monotone. Guitone requires monotone version %1 or later. - Der Pfad zur ausführbaren Datei von monotone ist entweder ungültig oder zeigt auf eine ältere Version von monotone. Guitone benötigt Version %1 oder neuer. + Der Pfad zur ausführbaren Datei von monotone ist entweder ungültig oder zeigt auf eine ältere Version von monotone. Guitone benötigt Version %1 oder neuer. + + + The path to the monotone binary is either invalid or points to an older version of monotone. Guitone requires monotone version %1 or a monotone with interface version %2 or later. + Der Pfad zur ausführbaren Datei von monotone ist entweder ungültig oder zeigt auf eine ältere Version von monotone. Guitone benötigt monotone Version %1 oder ein monotone mit einer Interface-Version %2 oder neuer. + PreferencesDialog ============================================================ --- guitone/src/monotone/Monotone.cpp 88bc4ff50da75cffd8f07c736684f0623f7b9823 +++ guitone/src/monotone/Monotone.cpp 169a5fa6a658f48fba1c7185c8062719f5bd04a7 @@ -87,7 +87,15 @@ Monotone* Monotone::instance = 0; Monotone* Monotone::instance = 0; -const QString Monotone::RequiredVersion = "0.32"; +// +// this should be understood as either/or: +// - if the program version is sufficient, everything is fine +// - if not, we additionally check the interface version in case the user +// compiled his own version with all needed commands +// +const QString Monotone::RequiredProgramVersion = "0.32"; +const QString Monotone::RequiredInterfaceVersion = "4.0"; + const int Monotone::StdioBufferSize = 50 * 1024 * 1024; const int Monotone::TimeoutWaitForOtherCommand = 5000; // milliseconds @@ -439,39 +447,57 @@ bool Monotone::readAndParseStdout(int & return false; } -bool Monotone::checkBinaryVersion(const QString & path) +bool Monotone::runCommand(const QString & path, const QStringList & params, QString & output) { QProcess proc; - proc.start(path, QStringList() << "--version"); + proc.start(path, params); // could not be started (invalid path, not executable, ...) if (!proc.waitForStarted(5000)) { - qDebug("Monotone::checkBinaryVersion: process not started"); + qDebug("Monotone::runCommand: process not started"); return false; } // process doesn't return, etc... if (!proc.waitForFinished(5000)) { - qDebug("Monotone::checkBinaryVersion: process not finished"); + qDebug("Monotone::runCommand: process not finished"); return false; } - // grep out the version (if any) - QString output(proc.readAll()); - qDebug("Output: %s", qPrintable(output)); + // read all of the output + output.append(proc.readAll()); + return true; +} + +bool Monotone::checkProgramVersion(const QString & path) +{ + QString output; + QStringList opts; + opts << "--version"; + + if (!runCommand(path, opts, output)) + { + return false; + } + QRegExp regex("^monotone (\\d+).(\\d+)"); if (regex.indexIn(output) == -1) { - qDebug("Monotone::checkBinaryVersion: couldn't parse output: %s", qPrintable(output)); + qDebug("Monotone::checkProgramVersion: couldn't parse output: %s", + qPrintable(output)); return false; } QStringList curVersion = regex.capturedTexts(); curVersion.pop_front(); - QStringList needVersion = RequiredVersion.split("."); + QStringList needVersion = RequiredProgramVersion.split("."); + + qDebug("Monotone::checkProgramVersion: current: %s, need: %s", + qPrintable(curVersion.join(".")), + qPrintable(RequiredProgramVersion)); unsigned int curMajor = curVersion.at(0).toUInt(); unsigned int curMinor = curVersion.at(1).toUInt(); @@ -479,6 +505,43 @@ bool Monotone::checkBinaryVersion(const unsigned int needMajor = needVersion.at(0).toUInt(); unsigned int needMinor = needVersion.at(1).toUInt(); - qDebug("Monotone::checkBinaryVersion: version check %s", qPrintable(curVersion.join("."))); return curMajor > needMajor || curMajor == needMajor && curMinor >= needMinor; } + +bool Monotone::checkInterfaceVersion(const QString & path) +{ + QString output; + QStringList opts; + opts << "automate" << "interface_version"; + + if (!runCommand(path, opts, output)) + { + return false; + } + + QRegExp regex("^(\\d+).(\\d+)"); + + if (regex.indexIn(output) == -1) + { + qDebug("Monotone::checkInterfaceVersion: couldn't parse output: %s", + qPrintable(output)); + return false; + } + + QStringList curVersion = regex.capturedTexts(); + curVersion.pop_front(); + QStringList needVersion = RequiredInterfaceVersion.split("."); + + qDebug("Monotone::checkInterfaceVersion: current: %s, need: %s", + qPrintable(curVersion.join(".")), + qPrintable(RequiredInterfaceVersion)); + + unsigned int curMajor = curVersion.at(0).toUInt(); + unsigned int curMinor = curVersion.at(1).toUInt(); + + unsigned int needMajor = needVersion.at(0).toUInt(); + unsigned int needMinor = needVersion.at(1).toUInt(); + + return curMajor > needMajor || curMajor == needMajor && curMinor >= needMinor; +} + ============================================================ --- guitone/src/monotone/Monotone.h f459bf030a300af821f5dd4bcce361eb50cd3d25 +++ guitone/src/monotone/Monotone.h 02a04c161701e05523f3d7e592d10052025633b7 @@ -32,8 +32,11 @@ class Monotone : public QObject public: static Monotone* singleton(QObject * parent = 0); - static bool checkBinaryVersion(const QString &); - static const QString RequiredVersion; + static bool runCommand(const QString &, const QStringList &, QString &); + static bool checkProgramVersion(const QString &); + static bool checkInterfaceVersion(const QString &); + static const QString RequiredProgramVersion; + static const QString RequiredInterfaceVersion; static const int StdioBufferSize; static const int TimeoutWaitForOtherCommand; ============================================================ --- guitone/src/view/Guitone.cpp c6305b59f96b6d3db7974445d4037ad5ebb6fcd9 +++ guitone/src/view/Guitone.cpp 8c153efa88318080ff59efd36ed861be59eaa400 @@ -57,15 +57,19 @@ bool Guitone::init() // check the current monotone version and prompt the user // to enter the correct path if there is a problem - if (!Monotone::checkBinaryVersion(Settings::getMtnExePath())) + QString path = Settings::getMtnExePath(); + if (!Monotone::checkProgramVersion(path) && + !Monotone::checkInterfaceVersion(path)) { QMessageBox::critical( this, tr("Error"), tr("The path to the monotone binary is either invalid " "or points to an older version of monotone. " - "Guitone requires monotone version %1 or later.") - .arg(Monotone::RequiredVersion), + "Guitone requires monotone version %1 " + "or a monotone with interface version %2 or later.") + .arg(Monotone::RequiredProgramVersion) + .arg(Monotone::RequiredInterfaceVersion), QMessageBox::Ok, 0, 0 ); ============================================================ --- guitone/src/view/dialogs/Preferences.cpp af5362667100fcffceeb18ef8834226c601281eb +++ guitone/src/view/dialogs/Preferences.cpp 0521f0b9c40bbfcd7100fbf12ff91ea68ce14279 @@ -46,19 +46,20 @@ void Preferences::accept() QString newPath = mtnExecutablePath->text(); // check if the new executable satisfies our version needs - // FIXME: there is no upper limit here, meaning we can't - // guarantee that everything will work in later versions - // but we can explicitely point the user to a version we - // _know_ it works with guitone - if (!Monotone::checkBinaryVersion(newPath)) + // we'll first check the program's plain version and if this + // does not succeed we check for the interface version + if (!Monotone::checkProgramVersion(newPath) && + !Monotone::checkInterfaceVersion(newPath)) { QMessageBox::critical( this, tr("Error"), tr("The path to the monotone binary is either invalid " "or points to an older version of monotone. " - "Guitone requires monotone version %1 or later.") - .arg(Monotone::RequiredVersion), + "Guitone requires monotone version %1 " + "or a monotone with interface version %2 or later.") + .arg(Monotone::RequiredProgramVersion) + .arg(Monotone::RequiredInterfaceVersion), QMessageBox::Ok, 0, 0 ); return;