forked from qt-creator/qt-creator
Make the git plugin look for the binary in the path specified in the settings. Previously, the environment was passed to the process, but that did not affect the location of the binary.
This commit is contained in:
committed by
unknown
parent
890220d5b4
commit
90b094e832
@@ -37,6 +37,8 @@
|
|||||||
#include <QtCore/QTimer>
|
#include <QtCore/QTimer>
|
||||||
#include <QtCore/QEventLoop>
|
#include <QtCore/QEventLoop>
|
||||||
#include <QtCore/QTextCodec>
|
#include <QtCore/QTextCodec>
|
||||||
|
#include <QtCore/QFileInfo>
|
||||||
|
#include <QtCore/QDir>
|
||||||
|
|
||||||
#include <QtGui/QApplication>
|
#include <QtGui/QApplication>
|
||||||
|
|
||||||
@@ -366,5 +368,108 @@ void SynchronousProcess::processStdErr(bool emitSignals)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Path utilities
|
||||||
|
|
||||||
|
enum OS_Type { OS_Mac, OS_Windows, OS_Unix };
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
static const OS_Type pathOS = OS_Windows;
|
||||||
|
#else
|
||||||
|
# ifdef Q_OS_MAC
|
||||||
|
static const OS_Type pathOS = OS_Mac;
|
||||||
|
# else
|
||||||
|
static const OS_Type pathOS = OS_Unix;
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Locate a binary in a directory, applying all kinds of
|
||||||
|
// extensions the operating system supports.
|
||||||
|
static QString checkBinary(const QDir &dir, const QString &binary)
|
||||||
|
{
|
||||||
|
// naive UNIX approach
|
||||||
|
const QFileInfo info(dir.filePath(binary));
|
||||||
|
if (info.isFile() && info.isExecutable())
|
||||||
|
return info.absoluteFilePath();
|
||||||
|
|
||||||
|
// Does the OS have some weird extension concept or does the
|
||||||
|
// binary have a 3 letter extension?
|
||||||
|
if (pathOS == OS_Unix)
|
||||||
|
return QString();
|
||||||
|
const int dotIndex = binary.lastIndexOf(QLatin1Char('.'));
|
||||||
|
if (dotIndex != -1 && dotIndex == binary.size() - 4)
|
||||||
|
return QString();
|
||||||
|
|
||||||
|
switch (pathOS) {
|
||||||
|
case OS_Unix:
|
||||||
|
break;
|
||||||
|
case OS_Windows: {
|
||||||
|
static const char *windowsExtensions[] = {".cmd", ".bat", ".exe", ".com" };
|
||||||
|
// Check the Windows extensions using the order
|
||||||
|
const int windowsExtensionCount = sizeof(windowsExtensions)/sizeof(const char*);
|
||||||
|
for (int e = 0; e < windowsExtensionCount; e ++) {
|
||||||
|
const QFileInfo windowsBinary(dir.filePath(binary + QLatin1String(windowsExtensions[e])));
|
||||||
|
if (windowsBinary.isFile() && windowsBinary.isExecutable())
|
||||||
|
return windowsBinary.absoluteFilePath();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case OS_Mac: {
|
||||||
|
// Check for Mac app folders
|
||||||
|
const QFileInfo appFolder(dir.filePath(binary + QLatin1String(".app")));
|
||||||
|
if (appFolder.isDir()) {
|
||||||
|
QString macBinaryPath = appFolder.absoluteFilePath();
|
||||||
|
macBinaryPath += QLatin1String("/Contents/MacOS/");
|
||||||
|
macBinaryPath += binary;
|
||||||
|
const QFileInfo macBinary(macBinaryPath);
|
||||||
|
if (macBinary.isFile() && macBinary.isExecutable())
|
||||||
|
return macBinary.absoluteFilePath();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString SynchronousProcess::locateBinary(const QString &path, const QString &binary)
|
||||||
|
{
|
||||||
|
// Absolute file?
|
||||||
|
const QFileInfo absInfo(binary);
|
||||||
|
if (absInfo.isAbsolute())
|
||||||
|
return checkBinary(absInfo.dir(), absInfo.fileName());
|
||||||
|
|
||||||
|
// Windows finds binaries in the current directory
|
||||||
|
if (pathOS == OS_Windows) {
|
||||||
|
const QString currentDirBinary = checkBinary(QDir::current(), binary);
|
||||||
|
if (!currentDirBinary.isEmpty())
|
||||||
|
return currentDirBinary;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QStringList paths = path.split(pathSeparator());
|
||||||
|
if (paths.empty())
|
||||||
|
return QString();
|
||||||
|
const QStringList::const_iterator cend = paths.constEnd();
|
||||||
|
for (QStringList::const_iterator it = paths.constBegin(); it != cend; ++it) {
|
||||||
|
const QDir dir(*it);
|
||||||
|
const QString rc = checkBinary(dir, binary);
|
||||||
|
if (!rc.isEmpty())
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString SynchronousProcess::locateBinary(const QString &binary)
|
||||||
|
{
|
||||||
|
const QByteArray path = qgetenv("PATH");
|
||||||
|
return locateBinary(QString::fromLocal8Bit(path), binary);
|
||||||
|
}
|
||||||
|
|
||||||
|
QChar SynchronousProcess::pathSeparator()
|
||||||
|
{
|
||||||
|
if (pathOS == OS_Windows)
|
||||||
|
return QLatin1Char(';');
|
||||||
|
return QLatin1Char(':');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace Utils
|
} // namespace Utils
|
||||||
} // namespace Core
|
} // namespace Core
|
||||||
|
@@ -114,6 +114,12 @@ public:
|
|||||||
|
|
||||||
SynchronousProcessResponse run(const QString &binary, const QStringList &args);
|
SynchronousProcessResponse run(const QString &binary, const QStringList &args);
|
||||||
|
|
||||||
|
// Helpers to find binaries. Do not use it for other path variables
|
||||||
|
// and file types.
|
||||||
|
static QString locateBinary(const QString &binary);
|
||||||
|
static QString locateBinary(const QString &path, const QString &binary);
|
||||||
|
static QChar pathSeparator();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void stdOut(const QByteArray &data, bool firstTime);
|
void stdOut(const QByteArray &data, bool firstTime);
|
||||||
void stdErr(const QByteArray &data, bool firstTime);
|
void stdErr(const QByteArray &data, bool firstTime);
|
||||||
|
@@ -102,8 +102,10 @@ GitClient::GitClient(GitPlugin* plugin)
|
|||||||
m_plugin(plugin),
|
m_plugin(plugin),
|
||||||
m_core(Core::ICore::instance())
|
m_core(Core::ICore::instance())
|
||||||
{
|
{
|
||||||
if (QSettings *s = m_core->settings())
|
if (QSettings *s = m_core->settings()) {
|
||||||
m_settings.fromSettings(s);
|
m_settings.fromSettings(s);
|
||||||
|
m_binaryPath = m_settings.gitBinaryPath();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GitClient::~GitClient()
|
GitClient::~GitClient()
|
||||||
@@ -478,7 +480,7 @@ GitCommand *GitClient::createCommand(const QString &workingDirectory,
|
|||||||
if (m_settings.adoptPath)
|
if (m_settings.adoptPath)
|
||||||
environment.set(QLatin1String("PATH"), m_settings.path);
|
environment.set(QLatin1String("PATH"), m_settings.path);
|
||||||
|
|
||||||
GitCommand* command = new GitCommand(workingDirectory, environment);
|
GitCommand* command = new GitCommand(m_binaryPath, workingDirectory, environment);
|
||||||
if (outputToWindow) {
|
if (outputToWindow) {
|
||||||
if (!editor) { // assume that the commands output is the important thing
|
if (!editor) { // assume that the commands output is the important thing
|
||||||
connect(command, SIGNAL(outputData(QByteArray)), this, SLOT(appendDataAndPopup(QByteArray)));
|
connect(command, SIGNAL(outputData(QByteArray)), this, SLOT(appendDataAndPopup(QByteArray)));
|
||||||
@@ -527,10 +529,9 @@ bool GitClient::synchronousGit(const QString &workingDirectory,
|
|||||||
{
|
{
|
||||||
if (Git::Constants::debug)
|
if (Git::Constants::debug)
|
||||||
qDebug() << "synchronousGit" << workingDirectory << arguments;
|
qDebug() << "synchronousGit" << workingDirectory << arguments;
|
||||||
const QString binary = QLatin1String(Constants::GIT_BINARY);
|
|
||||||
|
|
||||||
if (logCommandToWindow)
|
if (logCommandToWindow)
|
||||||
m_plugin->outputWindow()->append(formatCommand(binary, arguments));
|
m_plugin->outputWindow()->append(formatCommand(m_binaryPath, arguments));
|
||||||
|
|
||||||
QProcess process;
|
QProcess process;
|
||||||
process.setWorkingDirectory(workingDirectory);
|
process.setWorkingDirectory(workingDirectory);
|
||||||
@@ -540,7 +541,7 @@ bool GitClient::synchronousGit(const QString &workingDirectory,
|
|||||||
environment.set(QLatin1String("PATH"), m_settings.path);
|
environment.set(QLatin1String("PATH"), m_settings.path);
|
||||||
process.setEnvironment(environment.toStringList());
|
process.setEnvironment(environment.toStringList());
|
||||||
|
|
||||||
process.start(binary, arguments);
|
process.start(m_binaryPath, arguments);
|
||||||
if (!process.waitForFinished()) {
|
if (!process.waitForFinished()) {
|
||||||
if (errorText)
|
if (errorText)
|
||||||
*errorText = "Error: Git timed out";
|
*errorText = "Error: Git timed out";
|
||||||
@@ -1000,6 +1001,6 @@ void GitClient::setSettings(const GitSettings &s)
|
|||||||
m_settings = s;
|
m_settings = s;
|
||||||
if (QSettings *s = m_core->settings())
|
if (QSettings *s = m_core->settings())
|
||||||
m_settings.toSettings(s);
|
m_settings.toSettings(s);
|
||||||
|
m_binaryPath = m_settings.gitBinaryPath();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -176,6 +176,7 @@ private:
|
|||||||
GitPlugin *m_plugin;
|
GitPlugin *m_plugin;
|
||||||
Core::ICore *m_core;
|
Core::ICore *m_core;
|
||||||
GitSettings m_settings;
|
GitSettings m_settings;
|
||||||
|
QString m_binaryPath;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@@ -61,8 +61,10 @@ GitCommand::Job::Job(const QStringList &a, int t) :
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
GitCommand::GitCommand(const QString &workingDirectory,
|
GitCommand::GitCommand(const QString &binaryPath,
|
||||||
|
const QString &workingDirectory,
|
||||||
ProjectExplorer::Environment &environment) :
|
ProjectExplorer::Environment &environment) :
|
||||||
|
m_binaryPath(binaryPath),
|
||||||
m_workingDirectory(workingDirectory),
|
m_workingDirectory(workingDirectory),
|
||||||
m_environment(environmentToList(environment))
|
m_environment(environmentToList(environment))
|
||||||
{
|
{
|
||||||
@@ -109,7 +111,7 @@ void GitCommand::run()
|
|||||||
if (Git::Constants::debug)
|
if (Git::Constants::debug)
|
||||||
qDebug() << "GitCommand::run" << j << '/' << count << m_jobs.at(j).arguments;
|
qDebug() << "GitCommand::run" << j << '/' << count << m_jobs.at(j).arguments;
|
||||||
|
|
||||||
process.start(QLatin1String(Constants::GIT_BINARY), m_jobs.at(j).arguments);
|
process.start(m_binaryPath, m_jobs.at(j).arguments);
|
||||||
if (!process.waitForFinished(m_jobs.at(j).timeout * 1000)) {
|
if (!process.waitForFinished(m_jobs.at(j).timeout * 1000)) {
|
||||||
ok = false;
|
ok = false;
|
||||||
error += QLatin1String("Error: Git timed out");
|
error += QLatin1String("Error: Git timed out");
|
||||||
|
@@ -43,9 +43,11 @@ namespace Internal {
|
|||||||
|
|
||||||
class GitCommand : public QObject
|
class GitCommand : public QObject
|
||||||
{
|
{
|
||||||
|
Q_DISABLE_COPY(GitCommand)
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit GitCommand(const QString &workingDirectory,
|
explicit GitCommand(const QString &binaryPath,
|
||||||
|
const QString &workingDirectory,
|
||||||
ProjectExplorer::Environment &environment);
|
ProjectExplorer::Environment &environment);
|
||||||
|
|
||||||
|
|
||||||
@@ -67,8 +69,7 @@ private:
|
|||||||
int timeout;
|
int timeout;
|
||||||
};
|
};
|
||||||
|
|
||||||
QStringList environment() const;
|
const QString m_binaryPath;
|
||||||
|
|
||||||
const QString m_workingDirectory;
|
const QString m_workingDirectory;
|
||||||
const QStringList m_environment;
|
const QStringList m_environment;
|
||||||
|
|
||||||
|
@@ -32,9 +32,13 @@
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#include "gitsettings.h"
|
#include "gitsettings.h"
|
||||||
|
#include "gitconstants.h"
|
||||||
|
|
||||||
|
#include <utils/synchronousprocess.h>
|
||||||
|
|
||||||
#include <QtCore/QSettings>
|
#include <QtCore/QSettings>
|
||||||
#include <QtCore/QTextStream>
|
#include <QtCore/QTextStream>
|
||||||
|
#include <QtCore/QCoreApplication>
|
||||||
|
|
||||||
static const char *groupC = "Git";
|
static const char *groupC = "Git";
|
||||||
static const char *sysEnvKeyC = "SysEnv";
|
static const char *sysEnvKeyC = "SysEnv";
|
||||||
@@ -79,5 +83,30 @@ bool GitSettings::equals(const GitSettings &s) const
|
|||||||
return adoptPath == s.adoptPath && path == s.path && logCount == s.logCount && timeout == s.timeout;
|
return adoptPath == s.adoptPath && path == s.path && logCount == s.logCount && timeout == s.timeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString GitSettings::gitBinaryPath(bool *ok, QString *errorMessage) const
|
||||||
|
{
|
||||||
|
// Locate binary in path if one is specified, otherwise default
|
||||||
|
// to pathless binary
|
||||||
|
if (ok)
|
||||||
|
*ok = true;
|
||||||
|
if (errorMessage)
|
||||||
|
errorMessage->clear();
|
||||||
|
const QString binary = QLatin1String(Constants::GIT_BINARY);
|
||||||
|
// Easy, git is assumed to be elsewhere accessible
|
||||||
|
if (!adoptPath)
|
||||||
|
return binary;
|
||||||
|
// Search in path?
|
||||||
|
const QString pathBinary = Core::Utils::SynchronousProcess::locateBinary(path, binary);
|
||||||
|
if (pathBinary.isEmpty()) {
|
||||||
|
if (ok)
|
||||||
|
*ok = false;
|
||||||
|
if (errorMessage)
|
||||||
|
*errorMessage = QCoreApplication::translate("GitSettings",
|
||||||
|
"The binary '%1' could not be located in the path '%2'").arg(binary, path);
|
||||||
|
return binary;
|
||||||
|
}
|
||||||
|
return pathBinary;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -51,6 +51,8 @@ struct GitSettings
|
|||||||
void fromSettings(QSettings *);
|
void fromSettings(QSettings *);
|
||||||
void toSettings(QSettings *) const;
|
void toSettings(QSettings *) const;
|
||||||
|
|
||||||
|
QString gitBinaryPath(bool *ok = 0, QString *errorMessage = 0) const;
|
||||||
|
|
||||||
bool equals(const GitSettings &s) const;
|
bool equals(const GitSettings &s) const;
|
||||||
|
|
||||||
bool adoptPath;
|
bool adoptPath;
|
||||||
|
@@ -36,8 +36,10 @@
|
|||||||
#include "gitplugin.h"
|
#include "gitplugin.h"
|
||||||
|
|
||||||
#include <QtCore/QDebug>
|
#include <QtCore/QDebug>
|
||||||
|
#include <QtGui/QMessageBox>
|
||||||
|
|
||||||
using namespace Git::Internal;
|
namespace Git {
|
||||||
|
namespace Internal {
|
||||||
|
|
||||||
SettingsPageWidget::SettingsPageWidget(QWidget *parent) :
|
SettingsPageWidget::SettingsPageWidget(QWidget *parent) :
|
||||||
QWidget(parent)
|
QWidget(parent)
|
||||||
@@ -101,6 +103,17 @@ void SettingsPage::apply()
|
|||||||
{
|
{
|
||||||
if (!m_widget)
|
if (!m_widget)
|
||||||
return;
|
return;
|
||||||
|
const GitSettings newSettings = m_widget->settings();
|
||||||
GitPlugin::instance()->setSettings(m_widget->settings());
|
// Warn if git cannot be found in path if the widget is on top
|
||||||
|
if (m_widget->isVisible()) {
|
||||||
|
bool gitFoundOk;
|
||||||
|
QString errorMessage;
|
||||||
|
newSettings.gitBinaryPath(&gitFoundOk, &errorMessage);
|
||||||
|
if (!gitFoundOk)
|
||||||
|
QMessageBox::warning(m_widget, tr("Git Settings"), errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
GitPlugin::instance()->setSettings(newSettings);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user