Commit ca7a924a authored by Tobias Hunger's avatar Tobias Hunger

VCS: VcsBaseClient::vcsFullySynchronousExec returns a SynchronousProcessResponse

Change-Id: Ic155da2ed1fd36f1f91327ac90f34a5cad3c210e
Reviewed-by: Tobias Hunger's avatarTobias Hunger <tobias.hunger@qt.io>
parent 5efd8246
......@@ -110,8 +110,8 @@ bool BazaarClient::synchronousSetUserId()
args << QLatin1String("whoami")
<< (settings().stringValue(BazaarSettings::userNameKey) + QLatin1String(" <")
+ settings().stringValue(BazaarSettings::userEmailKey) + QLatin1Char('>'));
QByteArray stdOut;
return vcsFullySynchronousExec(QDir::currentPath(), args, &stdOut);
return vcsFullySynchronousExec(QDir::currentPath(), args).result
== SynchronousProcessResponse::Finished;
}
BranchInfo BazaarClient::synchronousBranchQuery(const QString &repositoryRoot) const
......@@ -150,11 +150,10 @@ bool BazaarClient::synchronousUncommit(const QString &workingDir,
<< QLatin1String("--verbose") // Will print out what is being removed
<< revisionSpec(revision)
<< extraOptions;
QByteArray stdOut;
const bool success = vcsFullySynchronousExec(workingDir, args, &stdOut);
if (!stdOut.isEmpty())
VcsOutputWindow::append(QString::fromUtf8(stdOut));
return success;
const SynchronousProcessResponse result = vcsFullySynchronousExec(workingDir, args);
VcsOutputWindow::append(result.stdOut());
return result.result == SynchronousProcessResponse::Finished;
}
void BazaarClient::commit(const QString &repositoryRoot, const QStringList &files,
......@@ -187,10 +186,11 @@ bool BazaarClient::managesFile(const QString &workingDirectory, const QString &f
{
QStringList args(QLatin1String("status"));
args << fileName;
QByteArray stdOut;
if (!vcsFullySynchronousExec(workingDirectory, args, &stdOut))
const SynchronousProcessResponse result = vcsFullySynchronousExec(workingDirectory, args);
if (result.result != SynchronousProcessResponse::Finished)
return false;
return !stdOut.startsWith("unknown");
return result.rawStdOut.startsWith("unknown");
}
void BazaarClient::view(const QString &source, const QString &id, const QStringList &extraOptions)
......
This diff is collapsed.
......@@ -73,12 +73,12 @@ bool MercurialClient::manifestSync(const QString &repository, const QString &rel
// 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 SynchronousProcessResponse result = vcsFullySynchronousExec(repository, args);
const QDir repositoryDir(repository);
const QFileInfo needle = QFileInfo(repositoryDir, relativeFilename);
const QStringList files = QString::fromLocal8Bit(output).split(QLatin1Char('\n'));
const QStringList files = result.stdOut().split(QLatin1Char('\n'));
foreach (const QString &fileName, files) {
const QFileInfo managedFile(repositoryDir, fileName);
if (needle == managedFile)
......@@ -96,7 +96,6 @@ bool MercurialClient::synchronousClone(const QString &workingDir,
Q_UNUSED(workingDir);
Q_UNUSED(extraOptions);
QDir workingDirectory(srcLocation);
QByteArray output;
const unsigned flags = VcsCommand::SshPasswordPrompt |
VcsCommand::ShowStdOut |
VcsCommand::ShowSuccessMessage;
......@@ -104,14 +103,16 @@ bool MercurialClient::synchronousClone(const QString &workingDir,
if (workingDirectory.exists()) {
// Let's make first init
QStringList arguments(QLatin1String("init"));
if (!vcsFullySynchronousExec(workingDirectory.path(), arguments, &output))
const SynchronousProcessResponse resp = vcsFullySynchronousExec(
workingDirectory.path(), arguments);
if (resp.result != SynchronousProcessResponse::Finished)
return false;
// Then pull remote repository
arguments.clear();
arguments << QLatin1String("pull") << dstLocation;
const SynchronousProcessResponse resp1 =
vcsSynchronousExec(workingDirectory.path(), arguments, flags);
const SynchronousProcessResponse resp1 = vcsSynchronousExec(
workingDirectory.path(), arguments, flags);
if (resp1.result != SynchronousProcessResponse::Finished)
return false;
......@@ -127,15 +128,15 @@ bool MercurialClient::synchronousClone(const QString &workingDir,
// And last update repository
arguments.clear();
arguments << QLatin1String("update");
const SynchronousProcessResponse resp2 =
vcsSynchronousExec(workingDirectory.path(), arguments, flags);
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);
const SynchronousProcessResponse resp = vcsSynchronousExec(
workingDirectory.path(), arguments, flags);
return resp.result == SynchronousProcessResponse::Finished;
}
}
......@@ -194,24 +195,22 @@ QStringList MercurialClient::parentRevisionsSync(const QString &workingDirectory
args << QLatin1String("parents") << QLatin1String("-r") <<revision;
if (!file.isEmpty())
args << file;
QByteArray outputData;
if (!vcsFullySynchronousExec(workingDirectory, args, &outputData))
const SynchronousProcessResponse resp = vcsFullySynchronousExec(workingDirectory, args);
if (resp.result != SynchronousProcessResponse::Finished)
return QStringList();
const QString output = SynchronousProcess::normalizeNewlines(
QString::fromLocal8Bit(outputData));
/* Looks like: \code
changeset: 0:031a48610fba
user: ...
\endcode */
// Obtain first line and split by blank-delimited tokens
const QStringList lines = output.split(QLatin1Char('\n'));
const QStringList lines = resp.stdOut().split(QLatin1Char('\n'));
if (lines.size() < 1) {
VcsOutputWindow::appendSilently(msgParentRevisionFailed(workingDirectory, revision, msgParseParentsOutputFailed(output)));
VcsOutputWindow::appendSilently(msgParentRevisionFailed(workingDirectory, revision, msgParseParentsOutputFailed(resp.stdOut())));
return QStringList();
}
QStringList changeSets = lines.front().simplified().split(QLatin1Char(' '));
if (changeSets.size() < 2) {
VcsOutputWindow::appendSilently(msgParentRevisionFailed(workingDirectory, revision, msgParseParentsOutputFailed(output)));
VcsOutputWindow::appendSilently(msgParentRevisionFailed(workingDirectory, revision, msgParseParentsOutputFailed(resp.stdOut())));
return QStringList();
}
// Remove revision numbers
......@@ -231,18 +230,15 @@ QString MercurialClient::shortDescriptionSync(const QString &workingDirectory,
const QString &revision,
const QString &format)
{
QString description;
QStringList args;
args << QLatin1String("log") << QLatin1String("-r") <<revision;
if (!format.isEmpty())
args << QLatin1String("--template") << format;
QByteArray outputData;
if (!vcsFullySynchronousExec(workingDirectory, args, &outputData))
const SynchronousProcessResponse resp = vcsFullySynchronousExec(workingDirectory, args);
if (resp.result != SynchronousProcessResponse::Finished)
return revision;
description = commandOutputFromLocal8Bit(outputData);
if (description.endsWith(QLatin1Char('\n')))
description.truncate(description.size() - 1);
return description;
return stripLastNewline(resp.stdOut());
}
// Default format: "SHA1 (author summmary)"
......@@ -258,9 +254,7 @@ bool MercurialClient::managesFile(const QString &workingDirectory, const QString
{
QStringList args;
args << QLatin1String("status") << QLatin1String("--unknown") << fileName;
QByteArray output;
vcsFullySynchronousExec(workingDirectory, args, &output);
return output.isEmpty();
return vcsFullySynchronousExec(workingDirectory, args).stdOut().isEmpty();
}
void MercurialClient::incoming(const QString &repositoryRoot, const QString &repository)
......
......@@ -138,14 +138,13 @@ QString SubversionClient::synchronousTopic(const QString &repository)
QStringList args;
args << QLatin1String("info");
QByteArray stdOut;
if (!vcsFullySynchronousExec(repository, args, &stdOut))
const SynchronousProcessResponse result = vcsFullySynchronousExec(repository, args);
if (result.result != SynchronousProcessResponse::Finished)
return QString();
const QString revisionString = QLatin1String("Revision: ");
// stdOut is ASCII only (at least in those areas we care about).
QString output = commandOutputFromLocal8Bit(stdOut);
foreach (const QString &line, output.split(QLatin1Char('\n'))) {
foreach (const QString &line, result.stdOut().split(QLatin1Char('\n'))) {
if (line.startsWith(revisionString))
return QString::fromLatin1("r") + line.mid(revisionString.count());
}
......
......@@ -877,21 +877,19 @@ SubversionResponse SubversionPlugin::runSvn(const QString &workingDir,
int timeOutS, unsigned flags,
QTextCodec *outputCodec) const
{
const FileName executable = client()->vcsBinary();
SubversionResponse response;
if (executable.isEmpty()) {
if (client()->vcsBinary().isEmpty()) {
response.error = true;
response.message =tr("No subversion executable specified.");
return response;
}
const SynchronousProcessResponse sp_resp =
VcsBasePlugin::runVcs(workingDir, executable, arguments, timeOutS,
flags, outputCodec);
const SynchronousProcessResponse sp_resp
= client()->vcsFullySynchronousExec(workingDir, arguments, flags, timeOutS, outputCodec);
response.error = sp_resp.result != SynchronousProcessResponse::Finished;
if (response.error)
response.message = sp_resp.exitMessage(executable.toString(), timeOutS);
response.message = sp_resp.exitMessage(client()->vcsBinary().toString(), timeOutS);
response.stdErr = sp_resp.stdErr();
response.stdOut = sp_resp.stdOut();
return response;
......
......@@ -155,8 +155,13 @@ QString VcsBaseClientImpl::commandOutputFromLocal8Bit(const QByteArray &a)
QStringList VcsBaseClientImpl::commandOutputLinesFromLocal8Bit(const QByteArray &a)
{
QString output = commandOutputFromLocal8Bit(a);
return splitLines(commandOutputFromLocal8Bit(a));
}
QStringList VcsBaseClientImpl::splitLines(const QString &s)
{
const QChar newLine = QLatin1Char('\n');
QString output = s;
if (output.endsWith(newLine))
output.truncate(output.size() - 1);
if (output.isEmpty())
......@@ -164,6 +169,13 @@ QStringList VcsBaseClientImpl::commandOutputLinesFromLocal8Bit(const QByteArray
return output.split(newLine);
}
QString VcsBaseClientImpl::stripLastNewline(const QString &in)
{
if (in.endsWith('\n'))
return in.left(in.count() - 1);
return in;
}
void VcsBaseClientImpl::resetCachedVcsInfo(const QString &workingDir)
{
Core::VcsManager::resetVersionControlForDirectory(workingDir);
......@@ -182,18 +194,15 @@ void VcsBaseClientImpl::annotateRevisionRequested(const QString &workingDirector
annotate(workingDirectory, file, changeCopy, line);
}
bool VcsBaseClientImpl::vcsFullySynchronousExec(const QString &workingDir, const QStringList &args,
QByteArray *outputData, QByteArray *errorData,
unsigned flags) const
Utils::SynchronousProcessResponse
VcsBaseClientImpl::vcsFullySynchronousExec(const QString &workingDir, const QStringList &args,
unsigned flags, int timeoutS, QTextCodec *codec) const
{
QByteArray internalErrorData;
QScopedPointer<VcsCommand> command(createCommand(workingDir));
command->addFlags(flags);
bool result = command->runFullySynchronous(vcsBinary(), args, vcsTimeoutS(), outputData,
errorData ? errorData : &internalErrorData);
if (!internalErrorData.isEmpty() && !(flags & VcsCommand::SuppressStdErr))
VcsOutputWindow::appendError(commandOutputFromLocal8Bit(internalErrorData));
return result;
VcsCommand command(workingDir, processEnvironment());
command.addFlags(flags);
if (codec)
command.setCodec(codec);
return command.runCommand(vcsBinary(), args, (timeoutS > 0) ? timeoutS : vcsTimeoutS());
}
VcsCommand *VcsBaseClientImpl::vcsExec(const QString &workingDirectory, const QStringList &arguments,
......@@ -300,10 +309,10 @@ bool VcsBaseClient::synchronousCreateRepository(const QString &workingDirectory,
{
QStringList args(vcsCommandString(CreateRepositoryCommand));
args << extraOptions;
QByteArray outputData;
if (!vcsFullySynchronousExec(workingDirectory, args, &outputData))
Utils::SynchronousProcessResponse result = vcsFullySynchronousExec(workingDirectory, args);
if (result.result != Utils::SynchronousProcessResponse::Finished)
return false;
VcsOutputWindow::append(commandOutputFromLocal8Bit(outputData));
VcsOutputWindow::append(result.stdOut());
resetCachedVcsInfo(workingDirectory);
......@@ -318,10 +327,10 @@ bool VcsBaseClient::synchronousClone(const QString &workingDir,
QStringList args;
args << vcsCommandString(CloneCommand)
<< extraOptions << srcLocation << dstLocation;
QByteArray stdOut;
const bool cloneOk = vcsFullySynchronousExec(workingDir, args, &stdOut);
Utils::SynchronousProcessResponse result = vcsFullySynchronousExec(workingDir, args);
resetCachedVcsInfo(workingDir);
return cloneOk;
return result.result == Utils::SynchronousProcessResponse::Finished;
}
bool VcsBaseClient::synchronousAdd(const QString &workingDir, const QString &filename,
......@@ -329,8 +338,7 @@ bool VcsBaseClient::synchronousAdd(const QString &workingDir, const QString &fil
{
QStringList args;
args << vcsCommandString(AddCommand) << extraOptions << filename;
QByteArray stdOut;
return vcsFullySynchronousExec(workingDir, args, &stdOut);
return vcsFullySynchronousExec(workingDir, args).result == Utils::SynchronousProcessResponse::Finished;
}
bool VcsBaseClient::synchronousRemove(const QString &workingDir, const QString &filename,
......@@ -338,8 +346,7 @@ bool VcsBaseClient::synchronousRemove(const QString &workingDir, const QString &
{
QStringList args;
args << vcsCommandString(RemoveCommand) << extraOptions << filename;
QByteArray stdOut;
return vcsFullySynchronousExec(workingDir, args, &stdOut);
return vcsFullySynchronousExec(workingDir, args).result == Utils::SynchronousProcessResponse::Finished;
}
bool VcsBaseClient::synchronousMove(const QString &workingDir,
......@@ -348,8 +355,7 @@ bool VcsBaseClient::synchronousMove(const QString &workingDir,
{
QStringList args;
args << vcsCommandString(MoveCommand) << extraOptions << from << to;
QByteArray stdOut;
return vcsFullySynchronousExec(workingDir, args, &stdOut);
return vcsFullySynchronousExec(workingDir, args).result == Utils::SynchronousProcessResponse::Finished;
}
bool VcsBaseClient::synchronousPull(const QString &workingDir,
......
......@@ -95,28 +95,31 @@ public:
static QString commandOutputFromLocal8Bit(const QByteArray &a);
// Return converted command output split into lines
static QStringList commandOutputLinesFromLocal8Bit(const QByteArray &a);
static QStringList splitLines(const QString &s);
protected:
void resetCachedVcsInfo(const QString &workingDir);
virtual void annotateRevisionRequested(const QString &workingDirectory, const QString &file,
const QString &change, int line);
static QString stripLastNewline(const QString &in);
// Fully synchronous VCS execution (QProcess-based)
bool vcsFullySynchronousExec(const QString &workingDir, const QStringList &args,
QByteArray *outputData, QByteArray *errorData = 0,
unsigned flags = 0) const;
Utils::SynchronousProcessResponse
vcsFullySynchronousExec(const QString &workingDir, const QStringList &args,
unsigned flags = 0, int timeoutS = -1, QTextCodec *codec = nullptr) const;
// Simple helper to execute a single command using createCommand and enqueueJob.
VcsCommand *vcsExec(const QString &workingDirectory, const QStringList &arguments,
VcsBaseEditorWidget *editor = 0, bool useOutputToWindow = false,
VcsBaseEditorWidget *editor = nullptr, bool useOutputToWindow = false,
unsigned additionalFlags = 0, const QVariant &cookie = QVariant()) const;
protected:
void resetCachedVcsInfo(const QString &workingDir);
virtual void annotateRevisionRequested(const QString &workingDirectory, const QString &file,
const QString &change, int line);
// Synchronous VCS execution using Utils::SynchronousProcess, with
// log windows updating (using VcsBasePlugin::runVcs with flags)
Utils::SynchronousProcessResponse vcsSynchronousExec(const QString &workingDir,
const QStringList &args,
unsigned flags = 0,
QTextCodec *outputCodec = 0) const;
QTextCodec *outputCodec = nullptr) const;
private:
void saveSettings();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment