# HG changeset patch # User Chris Cannam # Date 1292861743 0 # Node ID 07b908b4fa5f91904c1af36d546a639fa039010e # Parent 869825bc8bc422f801746d5d4971a9932a4666bf * Set python library path when unbundling extension, generally prefer unbundled copy diff -r 869825bc8bc4 -r 07b908b4fa5f easyhg.py --- a/easyhg.py Mon Dec 20 16:15:19 2010 +0000 +++ b/easyhg.py Mon Dec 20 16:15:43 2010 +0000 @@ -16,6 +16,16 @@ import sys from mercurial import ui, getpass, util from mercurial.i18n import _ + +# The value assigned here may be modified during installation, by +# replacing its default value with another one. We can't compare +# against its default value, because then the comparison text would +# get modified as well. So, compare using prefix only. +# +easyhg_import_path = 'NO_EASYHG_IMPORT_PATH' +if not easyhg_import_path.startswith('NO_'): + sys.path.append(easyhg_import_path) + from PyQt4 import QtGui easyhg_qtapp = None diff -r 869825bc8bc4 -r 07b908b4fa5f hgrunner.cpp --- a/hgrunner.cpp Mon Dec 20 16:15:19 2010 +0000 +++ b/hgrunner.cpp Mon Dec 20 16:15:43 2010 +0000 @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -64,44 +65,96 @@ QString HgRunner::findExtension() { + // If we haven't unbundled an extension, always do that (so that + // it's available in case someone wants to use it later, e.g. to + // fix a malfunctioning setup). But the path we actually prefer + // is the one in the settings first; then the unbundled one; then + // anything in the path if for some reason unbundling failed + QSettings settings; settings.beginGroup("Locations"); + + QString unbundled = getUnbundledFileName(); + if (!QFile(unbundled).exists()) { + unbundled = unbundleExtension(); + } + QString extpath = settings.value("extensionpath", "").toString(); if (extpath != "") return extpath; - extpath = findInPath("easyhg.py", m_myDirPath, false); - if (extpath == "easyhg.py") { - extpath = unbundleExtension(); + + extpath = unbundled; + if (extpath == "") { + extpath = findInPath("easyhg.py", m_myDirPath, false); + if (extpath == "easyhg.py") { + extpath = ""; + } } + settings.setValue("extensionpath", extpath); return extpath; } +QString HgRunner::getUnbundledFileName() +{ + QString home = QDir::homePath(); + QString target = QString("%1/.easyhg").arg(home); + QString extpath = QString("%1/easyhg.py").arg(target); + return extpath; +} + QString HgRunner::unbundleExtension() { + // Pull out the bundled Python file into a temporary file, and + // copy it to our known extension location, replacing the magic + // text NO_EASYHG_IMPORT_PATH with our installation location + QString bundled = ":easyhg.py"; - QString home = QDir::homePath(); - QString target = QString("%1/.easyhg").arg(home); + QString unbundled = getUnbundledFileName(); + + QString target = QFileInfo(unbundled).path(); if (!QDir().mkpath(target)) { DEBUG << "Failed to make unbundle path " << target << endl; - std::cerr << "Failed to make unbundle path " << target.toStdString() << std::endl; + std::cerr << "Failed to make unbundle path " << target << std::endl; return ""; } + QFile bf(bundled); - if (!bf.exists()) { + DEBUG << "unbundle: bundled file will be " << bundled << endl; + if (!bf.exists() || !bf.open(QIODevice::ReadOnly)) { DEBUG << "Bundled extension is missing!" << endl; return ""; } - QString extpath = QString("%1/easyhg.py").arg(target); - if (QFile(extpath).exists()) { - QFile(extpath).remove(); - } - if (!bf.copy(extpath)) { - DEBUG << "Failed to unbundle extension to " << target << endl; - std::cerr << "Failed to unbundle extension to " << extpath.toStdString() << std::endl; + + QTemporaryFile tmpfile(QString("%1/easyhg.py.XXXXXX").arg(target)); + tmpfile.setAutoRemove(false); + DEBUG << "unbundle: temp file will be " << tmpfile.fileName() << endl; + if (!tmpfile.open()) { + DEBUG << "Failed to open temporary file " << tmpfile.fileName() << endl; + std::cerr << "Failed to open temporary file " << tmpfile.fileName() << std::endl; return ""; } - DEBUG << "Unbundled extension to " << extpath << endl; - return extpath; + + QString all = QString::fromUtf8(bf.readAll()); + all.replace("NO_EASYHG_IMPORT_PATH", m_myDirPath); + tmpfile.write(all.toUtf8()); + DEBUG << "unbundle: wrote " << all.length() << " characters" << endl; + + tmpfile.close(); + + QFile ef(unbundled); + if (ef.exists()) { + DEBUG << "unbundle: removing old file " << unbundled << endl; + ef.remove(); + } + DEBUG << "unbundle: renaming " << tmpfile.fileName() << " to " << unbundled << endl; + if (!tmpfile.rename(unbundled)) { + DEBUG << "Failed to move temporary file to target file " << unbundled << endl; + std::cerr << "Failed to move temporary file to target file " << unbundled << std::endl; + return ""; + } + + DEBUG << "Unbundled extension to " << unbundled << endl; + return unbundled; } void HgRunner::requestAction(HgAction action) diff -r 869825bc8bc4 -r 07b908b4fa5f hgrunner.h --- a/hgrunner.h Mon Dec 20 16:15:19 2010 +0000 +++ b/hgrunner.h Mon Dec 20 16:15:43 2010 +0000 @@ -67,6 +67,7 @@ QString findExtension(); QString findHgBinaryName(); + QString getUnbundledFileName(); QString unbundleExtension(); int m_ptyMasterFd;