/************************************************************************** ** ** Copyright (c) 2014 Brian McGillion ** Contact: http://www.qt-project.org/legal ** ** This file is part of Qt Creator. ** ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and Digia. For licensing terms and ** conditions see http://www.qt.io/licensing. For further information ** use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 or version 3 as published by the Free ** Software Foundation and appearing in the file LICENSE.LGPLv21 and ** LICENSE.LGPLv3 included in the packaging of this file. Please review the ** following information to ensure the GNU Lesser General Public License ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Digia gives you certain additional ** rights. These rights are described in the Digia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ****************************************************************************/ #include "mercurialclient.h" #include "constants.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace Utils; using namespace VcsBase; namespace Mercurial { namespace Internal { MercurialClient::MercurialClient(MercurialSettings *settings) : VcsBaseClient(settings) { } MercurialSettings *MercurialClient::settings() const { return dynamic_cast(VcsBaseClient::settings()); } bool MercurialClient::manifestSync(const QString &repository, const QString &relativeFilename) { // This only works when called from the repo and outputs paths relative to it. const QStringList args(QLatin1String("manifest")); QByteArray output; vcsFullySynchronousExec(repository, args, &output); const QDir repositoryDir(repository); const QFileInfo needle = QFileInfo(repositoryDir, relativeFilename); const QStringList files = QString::fromLocal8Bit(output).split(QLatin1Char('\n')); foreach (const QString &fileName, files) { const QFileInfo managedFile(repositoryDir, fileName); if (needle == managedFile) return true; } return false; } //bool MercurialClient::clone(const QString &directory, const QString &url) bool MercurialClient::synchronousClone(const QString &workingDir, const QString &srcLocation, const QString &dstLocation, const QStringList &extraOptions) { Q_UNUSED(workingDir); Q_UNUSED(extraOptions); QDir workingDirectory(srcLocation); QByteArray output; const unsigned flags = VcsBasePlugin::SshPasswordPrompt | VcsBasePlugin::ShowStdOutInLogWindow | VcsBasePlugin::ShowSuccessMessage; if (workingDirectory.exists()) { // Let's make first init QStringList arguments(QLatin1String("init")); if (!vcsFullySynchronousExec(workingDirectory.path(), arguments, &output)) return false; // Then pull remote repository arguments.clear(); arguments << QLatin1String("pull") << dstLocation; const SynchronousProcessResponse resp1 = vcsSynchronousExec(workingDirectory.path(), arguments, flags); if (resp1.result != SynchronousProcessResponse::Finished) return false; // By now, there is no hgrc file -> create it FileSaver saver(workingDirectory.path() + QLatin1String("/.hg/hgrc")); const QString hgrc = QLatin1String("[paths]\ndefault = ") + dstLocation + QLatin1Char('\n'); saver.write(hgrc.toUtf8()); if (!saver.finalize()) { VcsOutputWindow::appendError(saver.errorString()); return false; } // And last update repository arguments.clear(); arguments << QLatin1String("update"); const SynchronousProcessResponse resp2 = vcsSynchronousExec(workingDirectory.path(), arguments, flags); return resp2.result == SynchronousProcessResponse::Finished; } else { QStringList arguments(QLatin1String("clone")); arguments << dstLocation << workingDirectory.dirName(); workingDirectory.cdUp(); const SynchronousProcessResponse resp = vcsSynchronousExec(workingDirectory.path(), arguments, flags); return resp.result == SynchronousProcessResponse::Finished; } } bool MercurialClient::synchronousPull(const QString &workingDir, const QString &srcLocation, const QStringList &extraOptions) { QStringList args; args << vcsCommandString(PullCommand) << extraOptions << srcLocation; // Disable UNIX terminals to suppress SSH prompting const unsigned flags = VcsBasePlugin::SshPasswordPrompt | VcsBasePlugin::ShowStdOutInLogWindow | VcsBasePlugin::ShowSuccessMessage; const FileName binary = settings()->binaryPath(); const int timeoutSec = settings()->value(settings()->timeoutKey).toInt(); // cause mercurial doesn`t understand LANG QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); env.insert(QLatin1String("LANGUAGE"), QLatin1String("C")); const SynchronousProcessResponse resp = VcsBasePlugin::runVcs( workingDir, binary, args, timeoutSec * 1000, flags, 0, env); const bool ok = resp.result == SynchronousProcessResponse::Finished; parsePullOutput(resp.stdOut.trimmed()); return ok; } QString MercurialClient::branchQuerySync(const QString &repositoryRoot) { QFile branchFile(repositoryRoot + QLatin1String("/.hg/branch")); if (branchFile.open(QFile::ReadOnly)) { const QByteArray branch = branchFile.readAll().trimmed(); if (!branch.isEmpty()) return QString::fromLocal8Bit(branch); } return QLatin1String("Unknown Branch"); } static inline QString msgParentRevisionFailed(const QString &workingDirectory, const QString &revision, const QString &why) { return MercurialClient::tr("Unable to find parent revisions of %1 in %2: %3"). arg(revision, QDir::toNativeSeparators(workingDirectory), why); } static inline QString msgParseParentsOutputFailed(const QString &output) { return MercurialClient::tr("Cannot parse output: %1").arg(output); } QStringList MercurialClient::parentRevisionsSync(const QString &workingDirectory, const QString &file /* = QString() */, const QString &revision) { QStringList parents; QStringList args; args << QLatin1String("parents") << QLatin1String("-r") <indexOf(colon); if (colonIndex != -1) parents.push_back(it->mid(colonIndex + 1)); } return parents; } // Describe a change using an optional format QString MercurialClient::shortDescriptionSync(const QString &workingDirectory, const QString &revision, const QString &format) { QString description; QStringList args; args << QLatin1String("log") << QLatin1String("-r") <settings()->boolPointer(MercurialSettings::diffIgnoreWhiteSpaceKey)); mapSetting(addToggleButton(QLatin1String("-B"), tr("Ignore Blank Lines")), client->settings()->boolPointer(MercurialSettings::diffIgnoreBlankLinesKey)); } void executeCommand() { m_client->diff(m_params.workingDir, m_params.files, m_params.extraOptions); } private: MercurialClient *m_client; const MercurialDiffParameters m_params; }; VcsBaseEditorParameterWidget *MercurialClient::createDiffEditor( const QString &workingDir, const QStringList &files, const QStringList &extraOptions) { MercurialDiffParameters parameters; parameters.workingDir = workingDir; parameters.files = files; parameters.extraOptions = extraOptions; return new MercurialDiffParameterWidget(this, parameters); } } // namespace Internal } // namespace Mercurial #include "mercurialclient.moc"