~bzoltan/kubuntu-packaging/decouple_cmake_plugin

« back to all changes in this revision

Viewing changes to src/plugins/vcsbase/checkoutjobs.cpp

  • Committer: Timo Jyrinki
  • Date: 2013-11-15 12:25:23 UTC
  • mfrom: (1.1.28)
  • Revision ID: timo.jyrinki@canonical.com-20131115122523-i2kyamsu4gs2mu1m
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/****************************************************************************
2
 
**
3
 
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
4
 
** Contact: http://www.qt-project.org/legal
5
 
**
6
 
** This file is part of Qt Creator.
7
 
**
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.
15
 
**
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.
23
 
**
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.
27
 
**
28
 
****************************************************************************/
29
 
 
30
 
#include "checkoutjobs.h"
31
 
 
32
 
#include "vcsbaseplugin.h"
33
 
#include "vcsbaseoutputwindow.h"
34
 
 
35
 
#include <QDebug>
36
 
#include <QQueue>
37
 
#include <QDir>
38
 
#include <QStringList>
39
 
#include <utils/synchronousprocess.h>
40
 
#include <utils/qtcassert.h>
41
 
 
42
 
enum { debug = 0 };
43
 
 
44
 
/*!
45
 
    \class  VcsBase::AbstractCheckoutJob
46
 
 
47
 
    \brief The AbstractCheckoutJob class is an abstract base class for a job
48
 
    creating an initial project checkout.
49
 
 
50
 
           It should be something that runs in the background producing log messages.
51
 
 
52
 
    \sa VcsBase::BaseCheckoutWizard
53
 
*/
54
 
 
55
 
namespace VcsBase {
56
 
 
57
 
namespace Internal {
58
 
 
59
 
// Use a terminal-less process to suppress SSH prompts.
60
 
static inline QSharedPointer<QProcess> createProcess()
61
 
{
62
 
    unsigned flags = 0;
63
 
    if (VcsBasePlugin::isSshPromptConfigured())
64
 
        flags = Utils::SynchronousProcess::UnixTerminalDisabled;
65
 
    return Utils::SynchronousProcess::createProcess(flags);
66
 
}
67
 
 
68
 
class ProcessCheckoutJobStep
69
 
{
70
 
public:
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) {}
77
 
 
78
 
    QString binary;
79
 
    QStringList arguments;
80
 
    QString workingDirectory;
81
 
    QProcessEnvironment environment;
82
 
};
83
 
 
84
 
class ProcessCheckoutJobPrivate
85
 
{
86
 
public:
87
 
    ProcessCheckoutJobPrivate();
88
 
 
89
 
    QSharedPointer<QProcess> process;
90
 
    QQueue<ProcessCheckoutJobStep> stepQueue;
91
 
    QString binary;
92
 
};
93
 
 
94
 
ProcessCheckoutJobPrivate::ProcessCheckoutJobPrivate() :
95
 
    process(createProcess())
96
 
{
97
 
}
98
 
 
99
 
} // namespace Internal
100
 
 
101
 
AbstractCheckoutJob::AbstractCheckoutJob(QObject *parent) :
102
 
    QObject(parent)
103
 
{
104
 
}
105
 
 
106
 
/*!
107
 
    \class VcsBase::ProcessCheckoutJob
108
 
 
109
 
    \brief The ProcessCheckoutJob class is a convenience implementation of a
110
 
    VcsBase::AbstractCheckoutJob using a QProcess.
111
 
*/
112
 
 
113
 
ProcessCheckoutJob::ProcessCheckoutJob(QObject *parent) :
114
 
    AbstractCheckoutJob(parent),
115
 
    d(new Internal::ProcessCheckoutJobPrivate)
116
 
{
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();
122
 
}
123
 
 
124
 
ProcessCheckoutJob::~ProcessCheckoutJob()
125
 
{
126
 
    delete d;
127
 
}
128
 
 
129
 
void ProcessCheckoutJob::addStep(const QString &binary,
130
 
                                const QStringList &args,
131
 
                                const QString &workingDirectory,
132
 
                                const QProcessEnvironment &env)
133
 
{
134
 
    if (debug)
135
 
        qDebug() << "ProcessCheckoutJob::addStep" << binary << args << workingDirectory;
136
 
    d->stepQueue.enqueue(Internal::ProcessCheckoutJobStep(binary, args, workingDirectory, env));
137
 
}
138
 
 
139
 
void ProcessCheckoutJob::slotOutput()
140
 
{
141
 
    const QByteArray data = d->process->readAllStandardOutput();
142
 
    const QString s = QString::fromLocal8Bit(data, data.endsWith('\n') ? data.size() - 1: data.size());
143
 
    if (debug)
144
 
        qDebug() << s;
145
 
    emit output(s);
146
 
}
147
 
 
148
 
void ProcessCheckoutJob::slotError(QProcess::ProcessError error)
149
 
{
150
 
    switch (error) {
151
 
    case QProcess::FailedToStart:
152
 
        emit failed(tr("Unable to start %1: %2").
153
 
                    arg(QDir::toNativeSeparators(d->binary), d->process->errorString()));
154
 
        break;
155
 
    default:
156
 
        emit failed(d->process->errorString());
157
 
        break;
158
 
    }
159
 
}
160
 
 
161
 
void ProcessCheckoutJob::slotFinished (int exitCode, QProcess::ExitStatus exitStatus)
162
 
{
163
 
    if (debug)
164
 
        qDebug() << "finished" << exitCode << exitStatus;
165
 
 
166
 
    switch (exitStatus) {
167
 
    case QProcess::NormalExit:
168
 
        emit output(tr("The process terminated with exit code %1.").arg(exitCode));
169
 
        if (exitCode == 0)
170
 
            slotNext();
171
 
        else
172
 
            emit failed(tr("The process returned exit code %1.").arg(exitCode));
173
 
        break;
174
 
    case QProcess::CrashExit:
175
 
        emit failed(tr("The process terminated in an abnormal way."));
176
 
        break;
177
 
    }
178
 
}
179
 
 
180
 
void ProcessCheckoutJob::start()
181
 
{
182
 
    QTC_ASSERT(!d->stepQueue.empty(), return);
183
 
    slotNext();
184
 
}
185
 
 
186
 
void ProcessCheckoutJob::slotNext()
187
 
{
188
 
    if (d->stepQueue.isEmpty()) {
189
 
        emit succeeded();
190
 
        return;
191
 
    }
192
 
    // Launch next
193
 
    const Internal::ProcessCheckoutJobStep step = d->stepQueue.dequeue();
194
 
    d->process->setWorkingDirectory(step.workingDirectory);
195
 
 
196
 
    // Set up SSH correctly.
197
 
    QProcessEnvironment processEnv = step.environment;
198
 
    VcsBasePlugin::setProcessEnvironment(&processEnv, false);
199
 
    d->process->setProcessEnvironment(processEnv);
200
 
 
201
 
    d->binary = step.binary;
202
 
    emit output(VcsBaseOutputWindow::msgExecutionLogEntry(step.workingDirectory, d->binary, step.arguments));
203
 
    d->process->start(d->binary, step.arguments);
204
 
}
205
 
 
206
 
void ProcessCheckoutJob::cancel()
207
 
{
208
 
    if (debug)
209
 
        qDebug() << "ProcessCheckoutJob::start";
210
 
 
211
 
    emit output(tr("Stopping..."));
212
 
    Utils::SynchronousProcess::stopProcess(*d->process);
213
 
}
214
 
 
215
 
} // namespace VcsBase