1
/****************************************************************************
3
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
4
** Contact: http://www.qt-project.org/legal
6
** This file is part of Qt Creator.
8
** Commercial License Usage
9
** Licensees holding valid commercial Qt licenses may use this file in
10
** accordance with the commercial license agreement provided with the
11
** Software or, alternatively, in accordance with the terms contained in
12
** a written agreement between you and Digia. For licensing terms and
13
** conditions see http://qt.digia.com/licensing. For further information
14
** use the contact form at http://qt.digia.com/contact-us.
16
** GNU Lesser General Public License Usage
17
** Alternatively, this file may be used under the terms of the GNU Lesser
18
** General Public License version 2.1 as published by the Free Software
19
** Foundation and appearing in the file LICENSE.LGPL included in the
20
** packaging of this file. Please review the following information to
21
** ensure the GNU Lesser General Public License version 2.1 requirements
22
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24
** In addition, as a special exception, Digia gives you certain additional
25
** rights. These rights are described in the Digia Qt LGPL Exception
26
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28
****************************************************************************/
30
#include "checkoutjobs.h"
32
#include "vcsbaseplugin.h"
33
#include "vcsbaseoutputwindow.h"
38
#include <QStringList>
39
#include <utils/synchronousprocess.h>
40
#include <utils/qtcassert.h>
45
\class VcsBase::AbstractCheckoutJob
47
\brief The AbstractCheckoutJob class is an abstract base class for a job
48
creating an initial project checkout.
50
It should be something that runs in the background producing log messages.
52
\sa VcsBase::BaseCheckoutWizard
59
// Use a terminal-less process to suppress SSH prompts.
60
static inline QSharedPointer<QProcess> createProcess()
63
if (VcsBasePlugin::isSshPromptConfigured())
64
flags = Utils::SynchronousProcess::UnixTerminalDisabled;
65
return Utils::SynchronousProcess::createProcess(flags);
68
class ProcessCheckoutJobStep
71
ProcessCheckoutJobStep() {}
72
explicit ProcessCheckoutJobStep(const QString &bin,
73
const QStringList &args,
74
const QString &workingDir,
75
QProcessEnvironment env) :
76
binary(bin), arguments(args), workingDirectory(workingDir), environment(env) {}
79
QStringList arguments;
80
QString workingDirectory;
81
QProcessEnvironment environment;
84
class ProcessCheckoutJobPrivate
87
ProcessCheckoutJobPrivate();
89
QSharedPointer<QProcess> process;
90
QQueue<ProcessCheckoutJobStep> stepQueue;
94
ProcessCheckoutJobPrivate::ProcessCheckoutJobPrivate() :
95
process(createProcess())
99
} // namespace Internal
101
AbstractCheckoutJob::AbstractCheckoutJob(QObject *parent) :
107
\class VcsBase::ProcessCheckoutJob
109
\brief The ProcessCheckoutJob class is a convenience implementation of a
110
VcsBase::AbstractCheckoutJob using a QProcess.
113
ProcessCheckoutJob::ProcessCheckoutJob(QObject *parent) :
114
AbstractCheckoutJob(parent),
115
d(new Internal::ProcessCheckoutJobPrivate)
117
connect(d->process.data(), SIGNAL(error(QProcess::ProcessError)), this, SLOT(slotError(QProcess::ProcessError)));
118
connect(d->process.data(), SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(slotFinished(int,QProcess::ExitStatus)));
119
connect(d->process.data(), SIGNAL(readyReadStandardOutput()), this, SLOT(slotOutput()));
120
d->process->setProcessChannelMode(QProcess::MergedChannels);
121
d->process->closeWriteChannel();
124
ProcessCheckoutJob::~ProcessCheckoutJob()
129
void ProcessCheckoutJob::addStep(const QString &binary,
130
const QStringList &args,
131
const QString &workingDirectory,
132
const QProcessEnvironment &env)
135
qDebug() << "ProcessCheckoutJob::addStep" << binary << args << workingDirectory;
136
d->stepQueue.enqueue(Internal::ProcessCheckoutJobStep(binary, args, workingDirectory, env));
139
void ProcessCheckoutJob::slotOutput()
141
const QByteArray data = d->process->readAllStandardOutput();
142
const QString s = QString::fromLocal8Bit(data, data.endsWith('\n') ? data.size() - 1: data.size());
148
void ProcessCheckoutJob::slotError(QProcess::ProcessError error)
151
case QProcess::FailedToStart:
152
emit failed(tr("Unable to start %1: %2").
153
arg(QDir::toNativeSeparators(d->binary), d->process->errorString()));
156
emit failed(d->process->errorString());
161
void ProcessCheckoutJob::slotFinished (int exitCode, QProcess::ExitStatus exitStatus)
164
qDebug() << "finished" << exitCode << exitStatus;
166
switch (exitStatus) {
167
case QProcess::NormalExit:
168
emit output(tr("The process terminated with exit code %1.").arg(exitCode));
172
emit failed(tr("The process returned exit code %1.").arg(exitCode));
174
case QProcess::CrashExit:
175
emit failed(tr("The process terminated in an abnormal way."));
180
void ProcessCheckoutJob::start()
182
QTC_ASSERT(!d->stepQueue.empty(), return);
186
void ProcessCheckoutJob::slotNext()
188
if (d->stepQueue.isEmpty()) {
193
const Internal::ProcessCheckoutJobStep step = d->stepQueue.dequeue();
194
d->process->setWorkingDirectory(step.workingDirectory);
196
// Set up SSH correctly.
197
QProcessEnvironment processEnv = step.environment;
198
VcsBasePlugin::setProcessEnvironment(&processEnv, false);
199
d->process->setProcessEnvironment(processEnv);
201
d->binary = step.binary;
202
emit output(VcsBaseOutputWindow::msgExecutionLogEntry(step.workingDirectory, d->binary, step.arguments));
203
d->process->start(d->binary, step.arguments);
206
void ProcessCheckoutJob::cancel()
209
qDebug() << "ProcessCheckoutJob::start";
211
emit output(tr("Stopping..."));
212
Utils::SynchronousProcess::stopProcess(*d->process);
215
} // namespace VcsBase