forked from qt-creator/qt-creator
Maemo: Move deploying to dedicated deploy step.
Reviewed-by: kh1
This commit is contained in:
@@ -1,7 +1,25 @@
|
|||||||
#include "maemodeploystep.h"
|
#include "maemodeploystep.h"
|
||||||
|
|
||||||
|
#include "maemoconstants.h"
|
||||||
|
#include "maemodeployables.h"
|
||||||
#include "maemodeploystepwidget.h"
|
#include "maemodeploystepwidget.h"
|
||||||
|
#include "maemopackagecreationstep.h"
|
||||||
|
#include "maemorunconfiguration.h"
|
||||||
|
|
||||||
|
#include <coreplugin/ssh/sftpchannel.h>
|
||||||
|
#include <coreplugin/ssh/sshconnection.h>
|
||||||
|
#include <coreplugin/ssh/sshremoteprocess.h>
|
||||||
|
|
||||||
|
#include <projectexplorer/buildconfiguration.h>
|
||||||
|
#include <projectexplorer/projectexplorerconstants.h>
|
||||||
|
#include <projectexplorer/target.h>
|
||||||
|
|
||||||
|
#include <QtCore/QCryptographicHash>
|
||||||
|
#include <QtCore/QEventLoop>
|
||||||
|
#include <QtCore/QFileInfo>
|
||||||
|
#include <QtCore/QTimer>
|
||||||
|
|
||||||
|
using namespace Core;
|
||||||
using namespace ProjectExplorer;
|
using namespace ProjectExplorer;
|
||||||
|
|
||||||
namespace Qt4ProjectManager {
|
namespace Qt4ProjectManager {
|
||||||
@@ -13,11 +31,19 @@ const QLatin1String MaemoDeployStep::Id("Qt4ProjectManager.MaemoDeployStep");
|
|||||||
MaemoDeployStep::MaemoDeployStep(ProjectExplorer::BuildConfiguration *bc)
|
MaemoDeployStep::MaemoDeployStep(ProjectExplorer::BuildConfiguration *bc)
|
||||||
: BuildStep(bc, Id)
|
: BuildStep(bc, Id)
|
||||||
{
|
{
|
||||||
|
ctor();
|
||||||
}
|
}
|
||||||
|
|
||||||
MaemoDeployStep::MaemoDeployStep(ProjectExplorer::BuildConfiguration *bc,
|
MaemoDeployStep::MaemoDeployStep(ProjectExplorer::BuildConfiguration *bc,
|
||||||
MaemoDeployStep *other)
|
MaemoDeployStep *other)
|
||||||
: BuildStep(bc, other)
|
: BuildStep(bc, other), m_lastDeployed(other->m_lastDeployed)
|
||||||
|
{
|
||||||
|
ctor();
|
||||||
|
}
|
||||||
|
|
||||||
|
MaemoDeployStep::~MaemoDeployStep() {}
|
||||||
|
|
||||||
|
void MaemoDeployStep::ctor()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,12 +54,398 @@ bool MaemoDeployStep::init()
|
|||||||
|
|
||||||
void MaemoDeployStep::run(QFutureInterface<bool> &fi)
|
void MaemoDeployStep::run(QFutureInterface<bool> &fi)
|
||||||
{
|
{
|
||||||
fi.reportResult(true);
|
// Move to GUI thread for connection sharing with run control.
|
||||||
|
QTimer::singleShot(0, this, SLOT(start()));
|
||||||
|
|
||||||
|
MaemoDeployEventHandler eventHandler(this, fi);
|
||||||
}
|
}
|
||||||
|
|
||||||
BuildStepConfigWidget *MaemoDeployStep::createConfigWidget()
|
BuildStepConfigWidget *MaemoDeployStep::createConfigWidget()
|
||||||
{
|
{
|
||||||
return new MaemoDeployStepWidget;
|
return new MaemoDeployStepWidget(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariantMap MaemoDeployStep::toMap() const
|
||||||
|
{
|
||||||
|
QVariantMap map(BuildStep::toMap());
|
||||||
|
addDeployTimesToMap(map);
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaemoDeployStep::addDeployTimesToMap(QVariantMap &map) const
|
||||||
|
{
|
||||||
|
QVariantList hostList;
|
||||||
|
QVariantList fileList;
|
||||||
|
QVariantList remotePathList;
|
||||||
|
QVariantList timeList;
|
||||||
|
typedef QHash<DeployablePerHost, QDateTime>::ConstIterator DepIt;
|
||||||
|
for (DepIt it = m_lastDeployed.begin(); it != m_lastDeployed.end(); ++it) {
|
||||||
|
fileList << it.key().first.localFilePath;
|
||||||
|
remotePathList << it.key().first.remoteDir;
|
||||||
|
hostList << it.key().second;
|
||||||
|
timeList << it.value();
|
||||||
|
}
|
||||||
|
map.insert(LastDeployedHostsKey, hostList);
|
||||||
|
map.insert(LastDeployedFilesKey, fileList);
|
||||||
|
map.insert(LastDeployedRemotePathsKey, remotePathList);
|
||||||
|
map.insert(LastDeployedTimesKey, timeList);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MaemoDeployStep::fromMap(const QVariantMap &map)
|
||||||
|
{
|
||||||
|
if (!BuildStep::fromMap(map))
|
||||||
|
return false;
|
||||||
|
getDeployTimesFromMap(map);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaemoDeployStep::getDeployTimesFromMap(const QVariantMap &map)
|
||||||
|
{
|
||||||
|
const QVariantList &hostList = map.value(LastDeployedHostsKey).toList();
|
||||||
|
const QVariantList &fileList = map.value(LastDeployedFilesKey).toList();
|
||||||
|
const QVariantList &remotePathList
|
||||||
|
= map.value(LastDeployedRemotePathsKey).toList();
|
||||||
|
const QVariantList &timeList = map.value(LastDeployedTimesKey).toList();
|
||||||
|
const int elemCount
|
||||||
|
= qMin(qMin(hostList.size(), fileList.size()),
|
||||||
|
qMin(remotePathList.size(), timeList.size()));
|
||||||
|
for (int i = 0; i < elemCount; ++i) {
|
||||||
|
const MaemoDeployable d(fileList.at(i).toString(),
|
||||||
|
remotePathList.at(i).toString());
|
||||||
|
m_lastDeployed.insert(DeployablePerHost(d, hostList.at(i).toString()),
|
||||||
|
timeList.at(i).toDateTime());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const MaemoPackageCreationStep *MaemoDeployStep::packagingStep() const
|
||||||
|
{
|
||||||
|
const QList<ProjectExplorer::BuildStep *> &buildSteps
|
||||||
|
= buildConfiguration()->steps(ProjectExplorer::BuildStep::Deploy);
|
||||||
|
for (int i = buildSteps.count() - 1; i >= 0; --i) {
|
||||||
|
const MaemoPackageCreationStep * const pStep
|
||||||
|
= qobject_cast<MaemoPackageCreationStep *>(buildSteps.at(i));
|
||||||
|
if (pStep)
|
||||||
|
return pStep;
|
||||||
|
}
|
||||||
|
Q_ASSERT(!"Impossible: Maemo run configuration without packaging step.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaemoDeployStep::raiseError(const QString &errorString)
|
||||||
|
{
|
||||||
|
emit addTask(Task(Task::Error, errorString, QString(), -1,
|
||||||
|
Constants::TASK_CATEGORY_BUILDSYSTEM));
|
||||||
|
stop();
|
||||||
|
emit error();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaemoDeployStep::writeOutput(const QString &text,
|
||||||
|
const QTextCharFormat &format)
|
||||||
|
{
|
||||||
|
emit addOutput(text, format);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaemoDeployStep::stop()
|
||||||
|
{
|
||||||
|
if (m_installer && m_installer->isRunning()) {
|
||||||
|
disconnect(m_installer.data(), 0, this, 0);
|
||||||
|
} else if (!m_uploadsInProgress.isEmpty() || !m_linksInProgress.isEmpty()) {
|
||||||
|
m_uploadsInProgress.clear();
|
||||||
|
m_linksInProgress.clear();
|
||||||
|
m_uploader->closeChannel();
|
||||||
|
disconnect(m_uploader.data(), 0, this, 0);
|
||||||
|
}
|
||||||
|
if (m_connection)
|
||||||
|
disconnect(m_connection.data(), 0, this, 0);
|
||||||
|
m_stopped = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString MaemoDeployStep::uploadDir() const
|
||||||
|
{
|
||||||
|
return homeDirOnDevice(m_connection->connectionParameters().uname);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MaemoDeployStep::currentlyNeedsDeployment(const QString &host,
|
||||||
|
const MaemoDeployable &deployable) const
|
||||||
|
{
|
||||||
|
const QDateTime &lastDeployed
|
||||||
|
= m_lastDeployed.value(DeployablePerHost(deployable, host));
|
||||||
|
return !lastDeployed.isValid()
|
||||||
|
|| QFileInfo(deployable.localFilePath).lastModified() > lastDeployed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaemoDeployStep::setDeployed(const QString &host,
|
||||||
|
const MaemoDeployable &deployable)
|
||||||
|
{
|
||||||
|
m_lastDeployed.insert(DeployablePerHost(deployable, host),
|
||||||
|
QDateTime::currentDateTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
MaemoDeviceConfig MaemoDeployStep::deviceConfig() const
|
||||||
|
{
|
||||||
|
// TODO: For lib template, get info from config widget
|
||||||
|
const RunConfiguration * const rc =
|
||||||
|
buildConfiguration()->target()->activeRunConfiguration();
|
||||||
|
return rc ? qobject_cast<const MaemoRunConfiguration *>(rc)->deviceConfig()
|
||||||
|
: MaemoDeviceConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString MaemoDeployStep::packageFileName() const
|
||||||
|
{
|
||||||
|
return QFileInfo(packageFilePath()).fileName();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString MaemoDeployStep::packageFilePath() const
|
||||||
|
{
|
||||||
|
return packagingStep()->packageFilePath();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaemoDeployStep::start()
|
||||||
|
{
|
||||||
|
m_stopped = false;
|
||||||
|
if (m_stopped)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// TODO: Re-use if possible (disconnect + reconnect).
|
||||||
|
if (m_connection)
|
||||||
|
disconnect(m_connection.data(), 0, this, 0);
|
||||||
|
m_connection = SshConnection::create();
|
||||||
|
|
||||||
|
const MaemoDeviceConfig &devConfig = deviceConfig();
|
||||||
|
if (!devConfig.isValid()) {
|
||||||
|
raiseError(tr("Deployment failed: No valid device set."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
connect(m_connection.data(), SIGNAL(connected()), this,
|
||||||
|
SLOT(handleConnected()));
|
||||||
|
connect(m_connection.data(), SIGNAL(error(SshError)), this,
|
||||||
|
SLOT(handleConnectionFailure()));
|
||||||
|
m_connection->connectToHost(devConfig.server);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaemoDeployStep::handleConnected()
|
||||||
|
{
|
||||||
|
if (m_stopped)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// TODO: If nothing to deploy, skip this step.
|
||||||
|
m_uploader = m_connection->createSftpChannel();
|
||||||
|
connect(m_uploader.data(), SIGNAL(initialized()), this,
|
||||||
|
SLOT(handleSftpChannelInitialized()));
|
||||||
|
connect(m_uploader.data(), SIGNAL(initializationFailed(QString)), this,
|
||||||
|
SLOT(handleSftpChannelInitializationFailed(QString)));
|
||||||
|
connect(m_uploader.data(), SIGNAL(finished(Core::SftpJobId, QString)),
|
||||||
|
this, SLOT(handleSftpJobFinished(Core::SftpJobId, QString)));
|
||||||
|
m_uploader->initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaemoDeployStep::handleConnectionFailure()
|
||||||
|
{
|
||||||
|
if (m_stopped)
|
||||||
|
return;
|
||||||
|
|
||||||
|
raiseError(tr("Could not connect to host: %1")
|
||||||
|
.arg(m_connection->errorString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaemoDeployStep::handleSftpChannelInitialized()
|
||||||
|
{
|
||||||
|
if (m_stopped)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_uploadsInProgress.clear();
|
||||||
|
m_linksInProgress.clear();
|
||||||
|
m_needsInstall = false;
|
||||||
|
const MaemoPackageCreationStep * const pStep = packagingStep();
|
||||||
|
const QString hostName = m_connection->connectionParameters().host;
|
||||||
|
if (pStep->isPackagingEnabled()) {
|
||||||
|
const MaemoDeployable d(packageFilePath(), uploadDir());
|
||||||
|
if (currentlyNeedsDeployment(hostName, d)) {
|
||||||
|
if (!deploy(MaemoDeployable(d)))
|
||||||
|
return;
|
||||||
|
m_needsInstall = true;
|
||||||
|
} else {
|
||||||
|
m_needsInstall = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const MaemoDeployables * const deployables = pStep->deployables();
|
||||||
|
const int deployableCount = deployables->deployableCount();
|
||||||
|
for (int i = 0; i < deployableCount; ++i) {
|
||||||
|
const MaemoDeployable &d = deployables->deployableAt(i);
|
||||||
|
if (currentlyNeedsDeployment(hostName, d)
|
||||||
|
&& !deploy(MaemoDeployable(d)))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_needsInstall = false;
|
||||||
|
}
|
||||||
|
if (m_uploadsInProgress.isEmpty())
|
||||||
|
emit done();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MaemoDeployStep::deploy(const MaemoDeployable &deployable)
|
||||||
|
{
|
||||||
|
const QString fileName = QFileInfo(deployable.localFilePath).fileName();
|
||||||
|
const QString remoteFilePath = deployable.remoteDir + '/' + fileName;
|
||||||
|
const QString uploadFilePath = uploadDir() + '/' + fileName + '.'
|
||||||
|
+ QCryptographicHash::hash(remoteFilePath.toUtf8(),
|
||||||
|
QCryptographicHash::Md5).toHex();
|
||||||
|
const SftpJobId job = m_uploader->uploadFile(deployable.localFilePath,
|
||||||
|
uploadFilePath, SftpOverwriteExisting);
|
||||||
|
if (job == SftpInvalidJob) {
|
||||||
|
raiseError(tr("Upload failed: Could not open file '%1'")
|
||||||
|
.arg(deployable.localFilePath));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
writeOutput(tr("Started uploading file '%1'.").arg(deployable.localFilePath));
|
||||||
|
m_uploadsInProgress.insert(job, DeployInfo(deployable, uploadFilePath));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaemoDeployStep::handleSftpChannelInitializationFailed(const QString &error)
|
||||||
|
{
|
||||||
|
if (m_stopped)
|
||||||
|
return;
|
||||||
|
raiseError(tr("Could not set up SFTP connection: %1").arg(error));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaemoDeployStep::handleSftpJobFinished(Core::SftpJobId job,
|
||||||
|
const QString &error)
|
||||||
|
{
|
||||||
|
if (m_stopped)
|
||||||
|
return;
|
||||||
|
|
||||||
|
QMap<SftpJobId, DeployInfo>::Iterator it = m_uploadsInProgress.find(job);
|
||||||
|
if (it == m_uploadsInProgress.end()) {
|
||||||
|
qWarning("%s: Job %u not found in map.", Q_FUNC_INFO, job);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const DeployInfo &deployInfo = it.value();
|
||||||
|
if (!error.isEmpty()) {
|
||||||
|
raiseError(tr("Failed to upload file %1: %2")
|
||||||
|
.arg(deployInfo.first.localFilePath, error));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
writeOutput(tr("Successfully uploaded file '%1'.")
|
||||||
|
.arg(deployInfo.first.localFilePath));
|
||||||
|
const QString remoteFilePath = deployInfo.first.remoteDir + '/'
|
||||||
|
+ QFileInfo(deployInfo.first.localFilePath).fileName();
|
||||||
|
QByteArray linkCommand = remoteSudo().toUtf8() + " ln -sf "
|
||||||
|
+ deployInfo.second.toUtf8() + ' ' + remoteFilePath.toUtf8();
|
||||||
|
SshRemoteProcess::Ptr linkProcess
|
||||||
|
= m_connection->createRemoteProcess(linkCommand);
|
||||||
|
connect(linkProcess.data(), SIGNAL(closed(int)), this,
|
||||||
|
SLOT(handleLinkProcessFinished(int)));
|
||||||
|
m_linksInProgress.insert(linkProcess, deployInfo.first);
|
||||||
|
linkProcess->start();
|
||||||
|
m_uploadsInProgress.erase(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaemoDeployStep::handleLinkProcessFinished(int exitStatus)
|
||||||
|
{
|
||||||
|
if (m_stopped)
|
||||||
|
return;
|
||||||
|
|
||||||
|
SshRemoteProcess * const proc = static_cast<SshRemoteProcess *>(sender());
|
||||||
|
|
||||||
|
// TODO: List instead of map? We can't use it for lookup anyway.
|
||||||
|
QMap<SshRemoteProcess::Ptr, MaemoDeployable>::Iterator it;
|
||||||
|
for (it = m_linksInProgress.begin(); it != m_linksInProgress.end(); ++it) {
|
||||||
|
if (it.key().data() == proc)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (it == m_linksInProgress.end()) {
|
||||||
|
qWarning("%s: Remote process %p not found in process list.",
|
||||||
|
Q_FUNC_INFO, proc);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const MaemoDeployable &deployable = it.value();
|
||||||
|
if (exitStatus != SshRemoteProcess::ExitedNormally
|
||||||
|
|| proc->exitCode() != 0) {
|
||||||
|
raiseError(tr("Deployment failed for file '%1': "
|
||||||
|
"Could not create link '%2' on remote system.")
|
||||||
|
.arg(deployable.localFilePath, deployable.remoteDir + '/'
|
||||||
|
+ QFileInfo(deployable.localFilePath).fileName()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setDeployed(m_connection->connectionParameters().host, it.value());
|
||||||
|
m_linksInProgress.erase(it);
|
||||||
|
if (m_linksInProgress.isEmpty() && m_uploadsInProgress.isEmpty()) {
|
||||||
|
if (m_needsInstall) {
|
||||||
|
writeOutput(tr("Installing package ..."));
|
||||||
|
const QByteArray cmd = remoteSudo().toUtf8() + " dpkg -i "
|
||||||
|
+ packageFileName().toUtf8();
|
||||||
|
m_installer = m_connection->createRemoteProcess(cmd);
|
||||||
|
connect(m_installer.data(), SIGNAL(closed(int)), this,
|
||||||
|
SLOT(handleInstallationFinished(int)));
|
||||||
|
connect(m_installer.data(), SIGNAL(outputAvailable(QByteArray)),
|
||||||
|
this, SLOT(handleInstallerOutput(QByteArray)));
|
||||||
|
connect(m_installer.data(),
|
||||||
|
SIGNAL(errorOutputAvailable(QByteArray)), this,
|
||||||
|
SLOT(handleInstallerErrorOutput(QByteArray)));
|
||||||
|
m_installer->start();
|
||||||
|
} else {
|
||||||
|
emit done();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaemoDeployStep::handleInstallationFinished(int exitStatus)
|
||||||
|
{
|
||||||
|
if (m_stopped)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (exitStatus != SshRemoteProcess::ExitedNormally
|
||||||
|
|| m_installer->exitCode() != 0) {
|
||||||
|
raiseError(tr("Installing package failed."));
|
||||||
|
} else {
|
||||||
|
writeOutput(tr("Package installation finished."));
|
||||||
|
emit done();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaemoDeployStep::handleInstallerOutput(const QByteArray &output)
|
||||||
|
{
|
||||||
|
writeOutput(QString::fromUtf8(output));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaemoDeployStep::handleInstallerErrorOutput(const QByteArray &output)
|
||||||
|
{
|
||||||
|
QTextCharFormat format;
|
||||||
|
format.setForeground(QBrush(QColor("red")));
|
||||||
|
writeOutput(output, format);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MaemoDeployEventHandler::MaemoDeployEventHandler(MaemoDeployStep *deployStep,
|
||||||
|
QFutureInterface<bool> &future)
|
||||||
|
: m_deployStep(deployStep), m_future(future), m_eventLoop(new QEventLoop)
|
||||||
|
{
|
||||||
|
connect(m_deployStep, SIGNAL(done()), this, SLOT(handleDeployingDone()));
|
||||||
|
connect(m_deployStep, SIGNAL(error()), this, SLOT(handleDeployingFailed()));
|
||||||
|
QTimer cancelChecker;
|
||||||
|
connect(&cancelChecker, SIGNAL(timeout()), this, SLOT(checkForCanceled()));
|
||||||
|
cancelChecker.start(500);
|
||||||
|
future.reportResult(m_eventLoop->exec() == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaemoDeployEventHandler::handleDeployingDone()
|
||||||
|
{
|
||||||
|
m_eventLoop->exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaemoDeployEventHandler::handleDeployingFailed()
|
||||||
|
{
|
||||||
|
m_eventLoop->exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaemoDeployEventHandler::checkForCanceled()
|
||||||
|
{
|
||||||
|
if (m_future.isCanceled())
|
||||||
|
handleDeployingFailed();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|||||||
@@ -1,10 +1,31 @@
|
|||||||
#ifndef MAEMODEPLOYSTEP_H
|
#ifndef MAEMODEPLOYSTEP_H
|
||||||
#define MAEMODEPLOYSTEP_H
|
#define MAEMODEPLOYSTEP_H
|
||||||
|
|
||||||
|
#include "maemodeployable.h"
|
||||||
|
#include "maemodeviceconfigurations.h"
|
||||||
|
|
||||||
|
#include <coreplugin/ssh/sftpdefs.h>
|
||||||
#include <projectexplorer/buildstep.h>
|
#include <projectexplorer/buildstep.h>
|
||||||
|
|
||||||
|
#include <QtCore/QHash>
|
||||||
|
#include <QtCore/QList>
|
||||||
|
#include <QtCore/QMap>
|
||||||
|
#include <QtCore/QPair>
|
||||||
|
#include <QtCore/QSharedPointer>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
class QEventLoop;
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
namespace Core {
|
||||||
|
class SftpChannel;
|
||||||
|
class SshConnection;
|
||||||
|
class SshRemoteProcess;
|
||||||
|
}
|
||||||
|
|
||||||
namespace Qt4ProjectManager {
|
namespace Qt4ProjectManager {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
class MaemoPackageCreationStep;
|
||||||
|
|
||||||
class MaemoDeployStep : public ProjectExplorer::BuildStep
|
class MaemoDeployStep : public ProjectExplorer::BuildStep
|
||||||
{
|
{
|
||||||
@@ -12,6 +33,27 @@ class MaemoDeployStep : public ProjectExplorer::BuildStep
|
|||||||
friend class MaemoDeployStepFactory;
|
friend class MaemoDeployStepFactory;
|
||||||
public:
|
public:
|
||||||
MaemoDeployStep(ProjectExplorer::BuildConfiguration *bc);
|
MaemoDeployStep(ProjectExplorer::BuildConfiguration *bc);
|
||||||
|
virtual ~MaemoDeployStep();
|
||||||
|
MaemoDeviceConfig deviceConfig() const;
|
||||||
|
bool currentlyNeedsDeployment(const QString &host,
|
||||||
|
const MaemoDeployable &deployable) const;
|
||||||
|
void setDeployed(const QString &host, const MaemoDeployable &deployable);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void done();
|
||||||
|
void error();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void start();
|
||||||
|
void handleConnected();
|
||||||
|
void handleConnectionFailure();
|
||||||
|
void handleSftpChannelInitialized();
|
||||||
|
void handleSftpChannelInitializationFailed(const QString &error);
|
||||||
|
void handleSftpJobFinished(Core::SftpJobId job, const QString &error);
|
||||||
|
void handleLinkProcessFinished(int exitStatus);
|
||||||
|
void handleInstallationFinished(int exitStatus);
|
||||||
|
void handleInstallerOutput(const QByteArray &output);
|
||||||
|
void handleInstallerErrorOutput(const QByteArray &output);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MaemoDeployStep(ProjectExplorer::BuildConfiguration *bc,
|
MaemoDeployStep(ProjectExplorer::BuildConfiguration *bc,
|
||||||
@@ -20,8 +62,52 @@ private:
|
|||||||
virtual void run(QFutureInterface<bool> &fi);
|
virtual void run(QFutureInterface<bool> &fi);
|
||||||
virtual ProjectExplorer::BuildStepConfigWidget *createConfigWidget();
|
virtual ProjectExplorer::BuildStepConfigWidget *createConfigWidget();
|
||||||
virtual bool immutable() const { return true; }
|
virtual bool immutable() const { return true; }
|
||||||
|
virtual QVariantMap toMap() const;
|
||||||
|
virtual bool fromMap(const QVariantMap &map);
|
||||||
|
|
||||||
|
void ctor();
|
||||||
|
void stop();
|
||||||
|
void raiseError(const QString &error);
|
||||||
|
void writeOutput(const QString &text,
|
||||||
|
const QTextCharFormat &format = QTextCharFormat());
|
||||||
|
void addDeployTimesToMap(QVariantMap &map) const;
|
||||||
|
void getDeployTimesFromMap(const QVariantMap &map);
|
||||||
|
const MaemoPackageCreationStep *packagingStep() const;
|
||||||
|
bool deploy(const MaemoDeployable &deployable);
|
||||||
|
QString uploadDir() const;
|
||||||
|
QString packageFileName() const;
|
||||||
|
QString packageFilePath() const;
|
||||||
|
|
||||||
static const QLatin1String Id;
|
static const QLatin1String Id;
|
||||||
|
|
||||||
|
QSharedPointer<Core::SshConnection> m_connection;
|
||||||
|
QSharedPointer<Core::SftpChannel> m_uploader;
|
||||||
|
QSharedPointer<Core::SshRemoteProcess> m_installer;
|
||||||
|
typedef QPair<MaemoDeployable, QString> DeployInfo;
|
||||||
|
QMap<Core::SftpJobId, DeployInfo> m_uploadsInProgress;
|
||||||
|
QMap<QSharedPointer<Core::SshRemoteProcess>, MaemoDeployable> m_linksInProgress;
|
||||||
|
bool m_needsInstall;
|
||||||
|
bool m_stopped;
|
||||||
|
typedef QPair<MaemoDeployable, QString> DeployablePerHost;
|
||||||
|
QHash<DeployablePerHost, QDateTime> m_lastDeployed;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MaemoDeployEventHandler : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
MaemoDeployEventHandler(MaemoDeployStep *deployStep,
|
||||||
|
QFutureInterface<bool> &future);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void handleDeployingDone();
|
||||||
|
void handleDeployingFailed();
|
||||||
|
void checkForCanceled();
|
||||||
|
|
||||||
|
private:
|
||||||
|
const MaemoDeployStep * const m_deployStep;
|
||||||
|
const QFutureInterface<bool> m_future;
|
||||||
|
QEventLoop * const m_eventLoop;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|||||||
@@ -1,12 +1,19 @@
|
|||||||
#include "maemodeploystepwidget.h"
|
#include "maemodeploystepwidget.h"
|
||||||
#include "ui_maemodeploystepwidget.h"
|
#include "ui_maemodeploystepwidget.h"
|
||||||
|
|
||||||
|
#include "maemodeploystep.h"
|
||||||
|
#include "maemorunconfiguration.h"
|
||||||
|
|
||||||
|
#include <projectexplorer/buildconfiguration.h>
|
||||||
|
#include <projectexplorer/target.h>
|
||||||
|
|
||||||
namespace Qt4ProjectManager {
|
namespace Qt4ProjectManager {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
MaemoDeployStepWidget::MaemoDeployStepWidget() :
|
MaemoDeployStepWidget::MaemoDeployStepWidget(MaemoDeployStep *step) :
|
||||||
ProjectExplorer::BuildStepConfigWidget(),
|
ProjectExplorer::BuildStepConfigWidget(),
|
||||||
ui(new Ui::MaemoDeployStepWidget)
|
ui(new Ui::MaemoDeployStepWidget),
|
||||||
|
m_step(step)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
}
|
}
|
||||||
@@ -18,11 +25,23 @@ MaemoDeployStepWidget::~MaemoDeployStepWidget()
|
|||||||
|
|
||||||
void MaemoDeployStepWidget::init()
|
void MaemoDeployStepWidget::init()
|
||||||
{
|
{
|
||||||
|
const ProjectExplorer::RunConfiguration * const rc =
|
||||||
|
m_step->buildConfiguration()->target()->activeRunConfiguration();
|
||||||
|
if (rc) {
|
||||||
|
connect(qobject_cast<const MaemoRunConfiguration *>(rc),
|
||||||
|
SIGNAL(deviceConfigurationChanged(ProjectExplorer::Target *)),
|
||||||
|
this, SLOT(handleDeviceUpdate()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaemoDeployStepWidget::handleDeviceUpdate()
|
||||||
|
{
|
||||||
|
emit updateSummary();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString MaemoDeployStepWidget::summaryText() const
|
QString MaemoDeployStepWidget::summaryText() const
|
||||||
{
|
{
|
||||||
return tr("<b>Deploy to device</b> ");
|
return tr("<b>Deploy to device</b>: ") + m_step->deviceConfig().name;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString MaemoDeployStepWidget::displayName() const
|
QString MaemoDeployStepWidget::displayName() const
|
||||||
|
|||||||
@@ -11,13 +11,14 @@ QT_END_NAMESPACE
|
|||||||
|
|
||||||
namespace Qt4ProjectManager {
|
namespace Qt4ProjectManager {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
class MaemoDeployStep;
|
||||||
|
|
||||||
class MaemoDeployStepWidget : public ProjectExplorer::BuildStepConfigWidget
|
class MaemoDeployStepWidget : public ProjectExplorer::BuildStepConfigWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MaemoDeployStepWidget();
|
MaemoDeployStepWidget(MaemoDeployStep *step);
|
||||||
~MaemoDeployStepWidget();
|
~MaemoDeployStepWidget();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -25,7 +26,10 @@ private:
|
|||||||
virtual QString summaryText() const;
|
virtual QString summaryText() const;
|
||||||
virtual QString displayName() const;
|
virtual QString displayName() const;
|
||||||
|
|
||||||
|
Q_SLOT void handleDeviceUpdate();
|
||||||
|
|
||||||
Ui::MaemoDeployStepWidget *ui;
|
Ui::MaemoDeployStepWidget *ui;
|
||||||
|
MaemoDeployStep * const m_step;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|||||||
@@ -36,6 +36,7 @@
|
|||||||
|
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
|
|
||||||
|
#include <QtCore/QCoreApplication>
|
||||||
#include <QtCore/QSettings>
|
#include <QtCore/QSettings>
|
||||||
#include <QtCore/QStringBuilder>
|
#include <QtCore/QStringBuilder>
|
||||||
#include <QtGui/QDesktopServices>
|
#include <QtGui/QDesktopServices>
|
||||||
@@ -54,6 +55,11 @@ QString homeDirOnDevice(const QString &uname)
|
|||||||
: QLatin1String("/home/") + uname;
|
: QLatin1String("/home/") + uname;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString remoteSudo()
|
||||||
|
{
|
||||||
|
return QLatin1String("/usr/lib/mad-developer/devrootsh");
|
||||||
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
const QLatin1String SettingsGroup("MaemoDeviceConfigs");
|
const QLatin1String SettingsGroup("MaemoDeviceConfigs");
|
||||||
const QLatin1String IdCounterKey("IdCounter");
|
const QLatin1String IdCounterKey("IdCounter");
|
||||||
@@ -132,7 +138,8 @@ MaemoDeviceConfig::MaemoDeviceConfig(const QSettings &settings,
|
|||||||
}
|
}
|
||||||
|
|
||||||
MaemoDeviceConfig::MaemoDeviceConfig()
|
MaemoDeviceConfig::MaemoDeviceConfig()
|
||||||
: internalId(InvalidId)
|
: name(QCoreApplication::translate("MaemoDeviceConfig", "(Invalid device)")),
|
||||||
|
internalId(InvalidId)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ namespace Qt4ProjectManager {
|
|||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
QString homeDirOnDevice(const QString &uname);
|
QString homeDirOnDevice(const QString &uname);
|
||||||
|
QString remoteSudo();
|
||||||
|
|
||||||
class MaemoDeviceConfig
|
class MaemoDeviceConfig
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
|
|
||||||
#include "maemorunconfiguration.h"
|
#include "maemorunconfiguration.h"
|
||||||
|
|
||||||
|
#include "maemodeploystep.h"
|
||||||
#include "maemopackagecreationstep.h"
|
#include "maemopackagecreationstep.h"
|
||||||
#include "maemorunconfigurationwidget.h"
|
#include "maemorunconfigurationwidget.h"
|
||||||
#include "maemotoolchain.h"
|
#include "maemotoolchain.h"
|
||||||
@@ -67,7 +68,6 @@ MaemoRunConfiguration::MaemoRunConfiguration(Qt4Target *parent,
|
|||||||
, m_gdbPath(source->m_gdbPath)
|
, m_gdbPath(source->m_gdbPath)
|
||||||
, m_devConfig(source->m_devConfig)
|
, m_devConfig(source->m_devConfig)
|
||||||
, m_arguments(source->m_arguments)
|
, m_arguments(source->m_arguments)
|
||||||
, m_lastDeployed(source->m_lastDeployed)
|
|
||||||
{
|
{
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
@@ -123,32 +123,11 @@ QVariantMap MaemoRunConfiguration::toMap() const
|
|||||||
QVariantMap map(RunConfiguration::toMap());
|
QVariantMap map(RunConfiguration::toMap());
|
||||||
map.insert(DeviceIdKey, m_devConfig.internalId);
|
map.insert(DeviceIdKey, m_devConfig.internalId);
|
||||||
map.insert(ArgumentsKey, m_arguments);
|
map.insert(ArgumentsKey, m_arguments);
|
||||||
addDeployTimesToMap(map);
|
|
||||||
const QDir dir = QDir(target()->project()->projectDirectory());
|
const QDir dir = QDir(target()->project()->projectDirectory());
|
||||||
map.insert(ProFileKey, dir.relativeFilePath(m_proFilePath));
|
map.insert(ProFileKey, dir.relativeFilePath(m_proFilePath));
|
||||||
|
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MaemoRunConfiguration::addDeployTimesToMap(QVariantMap &map) const
|
|
||||||
{
|
|
||||||
QVariantList hostList;
|
|
||||||
QVariantList fileList;
|
|
||||||
QVariantList remotePathList;
|
|
||||||
QVariantList timeList;
|
|
||||||
typedef QHash<DeployablePerHost, QDateTime>::ConstIterator DepIt;
|
|
||||||
for (DepIt it = m_lastDeployed.begin(); it != m_lastDeployed.end(); ++it) {
|
|
||||||
hostList << it.key().first.localFilePath;
|
|
||||||
remotePathList << it.key().first.remoteDir;
|
|
||||||
fileList << it.key().second;
|
|
||||||
timeList << it.value();
|
|
||||||
}
|
|
||||||
map.insert(LastDeployedHostsKey, hostList);
|
|
||||||
map.insert(LastDeployedFilesKey, fileList);
|
|
||||||
map.insert(LastDeployedRemotePathsKey, remotePathList);
|
|
||||||
map.insert(LastDeployedTimesKey, timeList);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MaemoRunConfiguration::fromMap(const QVariantMap &map)
|
bool MaemoRunConfiguration::fromMap(const QVariantMap &map)
|
||||||
{
|
{
|
||||||
if (!RunConfiguration::fromMap(map))
|
if (!RunConfiguration::fromMap(map))
|
||||||
@@ -157,47 +136,12 @@ bool MaemoRunConfiguration::fromMap(const QVariantMap &map)
|
|||||||
setDeviceConfig(MaemoDeviceConfigurations::instance().
|
setDeviceConfig(MaemoDeviceConfigurations::instance().
|
||||||
find(map.value(DeviceIdKey, 0).toInt()));
|
find(map.value(DeviceIdKey, 0).toInt()));
|
||||||
m_arguments = map.value(ArgumentsKey).toStringList();
|
m_arguments = map.value(ArgumentsKey).toStringList();
|
||||||
getDeployTimesFromMap(map);
|
|
||||||
const QDir dir = QDir(target()->project()->projectDirectory());
|
const QDir dir = QDir(target()->project()->projectDirectory());
|
||||||
m_proFilePath = dir.filePath(map.value(ProFileKey).toString());
|
m_proFilePath = dir.filePath(map.value(ProFileKey).toString());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MaemoRunConfiguration::getDeployTimesFromMap(const QVariantMap &map)
|
|
||||||
{
|
|
||||||
const QVariantList &hostList = map.value(LastDeployedHostsKey).toList();
|
|
||||||
const QVariantList &fileList = map.value(LastDeployedFilesKey).toList();
|
|
||||||
const QVariantList &remotePathList
|
|
||||||
= map.value(LastDeployedRemotePathsKey).toList();
|
|
||||||
const QVariantList &timeList = map.value(LastDeployedTimesKey).toList();
|
|
||||||
const int elemCount
|
|
||||||
= qMin(qMin(hostList.size(), fileList.size()),
|
|
||||||
qMin(remotePathList.size(), timeList.size()));
|
|
||||||
for (int i = 0; i < elemCount; ++i) {
|
|
||||||
const MaemoDeployable d(fileList.at(i).toString(),
|
|
||||||
remotePathList.at(i).toString());
|
|
||||||
m_lastDeployed.insert(DeployablePerHost(d, hostList.at(i).toString()),
|
|
||||||
timeList.at(i).toDateTime());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MaemoRunConfiguration::currentlyNeedsDeployment(const QString &host,
|
|
||||||
const MaemoDeployable &deployable) const
|
|
||||||
{
|
|
||||||
const QDateTime &lastDeployed
|
|
||||||
= m_lastDeployed.value(DeployablePerHost(deployable, host));
|
|
||||||
return !lastDeployed.isValid()
|
|
||||||
|| QFileInfo(deployable.localFilePath).lastModified() > lastDeployed;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MaemoRunConfiguration::setDeployed(const QString &host,
|
|
||||||
const MaemoDeployable &deployable)
|
|
||||||
{
|
|
||||||
m_lastDeployed.insert(DeployablePerHost(deployable, host),
|
|
||||||
QDateTime::currentDateTime());
|
|
||||||
}
|
|
||||||
|
|
||||||
void MaemoRunConfiguration::setDeviceConfig(const MaemoDeviceConfig &devConf)
|
void MaemoRunConfiguration::setDeviceConfig(const MaemoDeviceConfig &devConf)
|
||||||
{
|
{
|
||||||
m_devConfig = devConf;
|
m_devConfig = devConf;
|
||||||
@@ -239,6 +183,20 @@ const MaemoPackageCreationStep *MaemoRunConfiguration::packageStep() const
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MaemoDeployStep *MaemoRunConfiguration::deployStep() const
|
||||||
|
{
|
||||||
|
const QList<ProjectExplorer::BuildStep *> &buildSteps
|
||||||
|
= activeQt4BuildConfiguration()->steps(ProjectExplorer::BuildStep::Deploy);
|
||||||
|
for (int i = buildSteps.count() - 1; i >= 0; --i) {
|
||||||
|
MaemoDeployStep * const step
|
||||||
|
= qobject_cast<MaemoDeployStep*>(buildSteps.at(i));
|
||||||
|
if (step)
|
||||||
|
return step;
|
||||||
|
}
|
||||||
|
Q_ASSERT(!"Impossible: Maemo run configuration without deploy step.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
QString MaemoRunConfiguration::maddeRoot() const
|
QString MaemoRunConfiguration::maddeRoot() const
|
||||||
{
|
{
|
||||||
if (const MaemoToolChain *tc = toolchain())
|
if (const MaemoToolChain *tc = toolchain())
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ class Qt4BuildConfiguration;
|
|||||||
class Qt4ProFileNode;
|
class Qt4ProFileNode;
|
||||||
class Qt4Target;
|
class Qt4Target;
|
||||||
|
|
||||||
|
class MaemoDeployStep;
|
||||||
class MaemoPackageCreationStep;
|
class MaemoPackageCreationStep;
|
||||||
class MaemoRunConfigurationFactory;
|
class MaemoRunConfigurationFactory;
|
||||||
|
|
||||||
@@ -70,11 +71,8 @@ public:
|
|||||||
Qt4Target *qt4Target() const;
|
Qt4Target *qt4Target() const;
|
||||||
Qt4BuildConfiguration *activeQt4BuildConfiguration() const;
|
Qt4BuildConfiguration *activeQt4BuildConfiguration() const;
|
||||||
|
|
||||||
bool currentlyNeedsDeployment(const QString &host,
|
|
||||||
const MaemoDeployable &deployable) const;
|
|
||||||
void setDeployed(const QString &host, const MaemoDeployable &deployable);
|
|
||||||
|
|
||||||
const MaemoPackageCreationStep *packageStep() const;
|
const MaemoPackageCreationStep *packageStep() const;
|
||||||
|
MaemoDeployStep *deployStep() const;
|
||||||
|
|
||||||
QString maddeRoot() const;
|
QString maddeRoot() const;
|
||||||
QString executable() const;
|
QString executable() const;
|
||||||
@@ -107,17 +105,12 @@ private slots:
|
|||||||
private:
|
private:
|
||||||
void init();
|
void init();
|
||||||
const MaemoToolChain *toolchain() const;
|
const MaemoToolChain *toolchain() const;
|
||||||
void addDeployTimesToMap(QVariantMap &map) const;
|
|
||||||
void getDeployTimesFromMap(const QVariantMap &map);
|
|
||||||
|
|
||||||
QString m_proFilePath;
|
QString m_proFilePath;
|
||||||
mutable QString m_gdbPath;
|
mutable QString m_gdbPath;
|
||||||
|
|
||||||
MaemoDeviceConfig m_devConfig;
|
MaemoDeviceConfig m_devConfig;
|
||||||
QStringList m_arguments;
|
QStringList m_arguments;
|
||||||
|
|
||||||
typedef QPair<MaemoDeployable, QString> DeployablePerHost;
|
|
||||||
QHash<DeployablePerHost, QDateTime> m_lastDeployed;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|||||||
@@ -35,11 +35,11 @@
|
|||||||
#include "maemoruncontrol.h"
|
#include "maemoruncontrol.h"
|
||||||
|
|
||||||
#include "maemodeployables.h"
|
#include "maemodeployables.h"
|
||||||
|
#include "maemodeploystep.h"
|
||||||
#include "maemopackagecreationstep.h"
|
#include "maemopackagecreationstep.h"
|
||||||
#include "maemorunconfiguration.h"
|
#include "maemorunconfiguration.h"
|
||||||
|
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
#include <coreplugin/progressmanager/progressmanager.h>
|
|
||||||
#include <coreplugin/ssh/sftpchannel.h>
|
#include <coreplugin/ssh/sftpchannel.h>
|
||||||
#include <coreplugin/ssh/sshconnection.h>
|
#include <coreplugin/ssh/sshconnection.h>
|
||||||
#include <coreplugin/ssh/sshremoteprocess.h>
|
#include <coreplugin/ssh/sshremoteprocess.h>
|
||||||
@@ -47,15 +47,12 @@
|
|||||||
#include <debugger/debuggerplugin.h>
|
#include <debugger/debuggerplugin.h>
|
||||||
#include <debugger/debuggerrunner.h>
|
#include <debugger/debuggerrunner.h>
|
||||||
#include <extensionsystem/pluginmanager.h>
|
#include <extensionsystem/pluginmanager.h>
|
||||||
#include <projectexplorer/toolchain.h>
|
|
||||||
#include <utils/qtcassert.h>
|
|
||||||
#include <projectexplorer/projectexplorerconstants.h>
|
#include <projectexplorer/projectexplorerconstants.h>
|
||||||
|
#include <projectexplorer/toolchain.h>
|
||||||
|
#include <qt4projectmanager/qt4buildconfiguration.h>
|
||||||
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
#include <QtCore/QCryptographicHash>
|
|
||||||
#include <QtCore/QDir>
|
|
||||||
#include <QtCore/QFileInfo>
|
#include <QtCore/QFileInfo>
|
||||||
#include <QtCore/QFuture>
|
|
||||||
#include <QtCore/QProcess>
|
|
||||||
#include <QtCore/QStringBuilder>
|
#include <QtCore/QStringBuilder>
|
||||||
|
|
||||||
#include <QtGui/QMessageBox>
|
#include <QtGui/QMessageBox>
|
||||||
@@ -137,236 +134,11 @@ void AbstractMaemoRunControl::stop()
|
|||||||
} else if (m_initialCleaner && m_initialCleaner->isRunning()) {
|
} else if (m_initialCleaner && m_initialCleaner->isRunning()) {
|
||||||
disconnect(m_initialCleaner.data(), 0, this, 0);
|
disconnect(m_initialCleaner.data(), 0, this, 0);
|
||||||
emit finished();
|
emit finished();
|
||||||
} else if (m_installer && m_installer->isRunning()) {
|
|
||||||
disconnect(m_installer.data(), 0, this, 0);
|
|
||||||
emit finished();
|
|
||||||
} else if (isDeploying()) {
|
|
||||||
m_uploadsInProgress.clear();
|
|
||||||
m_linksInProgress.clear();
|
|
||||||
disconnect(m_uploader.data(), 0, this, 0);
|
|
||||||
m_progress.reportCanceled();
|
|
||||||
m_progress.reportFinished();
|
|
||||||
emit finished();
|
|
||||||
} else {
|
} else {
|
||||||
stopInternal();
|
stopInternal();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractMaemoRunControl::startDeployment()
|
|
||||||
{
|
|
||||||
QTC_ASSERT(m_runConfig, return);
|
|
||||||
|
|
||||||
m_uploader = m_connection->createSftpChannel();
|
|
||||||
connect(m_uploader.data(), SIGNAL(initialized()), this,
|
|
||||||
SLOT(handleSftpChannelInitialized()));
|
|
||||||
connect(m_uploader.data(), SIGNAL(initializationFailed(QString)), this,
|
|
||||||
SLOT(handleSftpChannelInitializationFailed(QString)));
|
|
||||||
connect(m_uploader.data(), SIGNAL(finished(Core::SftpJobId, QString)),
|
|
||||||
this, SLOT(handleSftpJobFinished(Core::SftpJobId, QString)));
|
|
||||||
m_uploader->initialize();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractMaemoRunControl::handleSftpChannelInitialized()
|
|
||||||
{
|
|
||||||
if (m_stopped)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_uploadsInProgress.clear();
|
|
||||||
m_linksInProgress.clear();
|
|
||||||
m_needsInstall = false;
|
|
||||||
const QList<MaemoDeployable> &deployables = filesToDeploy();
|
|
||||||
foreach (const MaemoDeployable &d, deployables) {
|
|
||||||
const QString fileName = QFileInfo(d.localFilePath).fileName();
|
|
||||||
const QString remoteFilePath = d.remoteDir + '/' + fileName;
|
|
||||||
const QString uploadFilePath = uploadDir() + '/' + fileName + '.'
|
|
||||||
+ QCryptographicHash::hash(remoteFilePath.toUtf8(),
|
|
||||||
QCryptographicHash::Md5).toHex();
|
|
||||||
const SftpJobId job = m_uploader->uploadFile(d.localFilePath,
|
|
||||||
uploadFilePath, SftpOverwriteExisting);
|
|
||||||
if (job == SftpInvalidJob) {
|
|
||||||
handleError(tr("Upload failed: Could not open file '%1'")
|
|
||||||
.arg(d.localFilePath));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
emit appendMessage(this, tr("Started uploading file '%1'.")
|
|
||||||
.arg(d.localFilePath), false);
|
|
||||||
m_uploadsInProgress.insert(job, DeployInfo(d, uploadFilePath));
|
|
||||||
}
|
|
||||||
|
|
||||||
Core::ICore::instance()->progressManager()
|
|
||||||
->addTask(m_progress.future(), tr("Deploying"),
|
|
||||||
QLatin1String("Maemo.Deploy"));
|
|
||||||
if (!m_uploadsInProgress.isEmpty()) {
|
|
||||||
m_progress.setProgressRange(0, m_uploadsInProgress.count());
|
|
||||||
m_progress.setProgressValue(0);
|
|
||||||
m_progress.reportStarted();
|
|
||||||
} else {
|
|
||||||
m_progress.reportFinished();
|
|
||||||
startExecutionIfPossible();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractMaemoRunControl::handleSftpChannelInitializationFailed(const QString &error)
|
|
||||||
{
|
|
||||||
if (m_stopped)
|
|
||||||
return;
|
|
||||||
handleError(tr("Could not set up SFTP connection: %1").arg(error));
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractMaemoRunControl::handleSftpJobFinished(Core::SftpJobId job,
|
|
||||||
const QString &error)
|
|
||||||
{
|
|
||||||
if (m_stopped)
|
|
||||||
return;
|
|
||||||
|
|
||||||
QMap<SftpJobId, DeployInfo>::Iterator it = m_uploadsInProgress.find(job);
|
|
||||||
if (it == m_uploadsInProgress.end()) {
|
|
||||||
qWarning("%s: Job %u not found in map.", Q_FUNC_INFO, job);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const DeployInfo &deployInfo = it.value();
|
|
||||||
if (!error.isEmpty()) {
|
|
||||||
handleError(tr("Failed to upload file %1: %2")
|
|
||||||
.arg(deployInfo.first.localFilePath, error));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_progress.setProgressValue(m_progress.progressValue() + 1);
|
|
||||||
appendMessage(this, tr("Successfully uploaded file '%1'.")
|
|
||||||
.arg(deployInfo.first.localFilePath), false);
|
|
||||||
|
|
||||||
const QString remoteFilePath = deployInfo.first.remoteDir + '/'
|
|
||||||
+ QFileInfo(deployInfo.first.localFilePath).fileName();
|
|
||||||
QByteArray linkCommand = remoteSudo().toUtf8() + " ln -sf "
|
|
||||||
+ deployInfo.second.toUtf8() + ' ' + remoteFilePath.toUtf8();
|
|
||||||
SshRemoteProcess::Ptr linkProcess
|
|
||||||
= m_connection->createRemoteProcess(linkCommand);
|
|
||||||
connect(linkProcess.data(), SIGNAL(closed(int)), this,
|
|
||||||
SLOT(handleLinkProcessFinished(int)));
|
|
||||||
m_linksInProgress.insert(linkProcess, deployInfo.first);
|
|
||||||
linkProcess->start();
|
|
||||||
m_uploadsInProgress.erase(it);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractMaemoRunControl::handleLinkProcessFinished(int exitStatus)
|
|
||||||
{
|
|
||||||
if (m_stopped)
|
|
||||||
return;
|
|
||||||
|
|
||||||
SshRemoteProcess * const proc = static_cast<SshRemoteProcess *>(sender());
|
|
||||||
|
|
||||||
// TODO: List instead of map? We can't use it for lookup anyway.
|
|
||||||
QMap<SshRemoteProcess::Ptr, MaemoDeployable>::Iterator it;
|
|
||||||
for (it = m_linksInProgress.begin(); it != m_linksInProgress.end(); ++it) {
|
|
||||||
if (it.key().data() == proc)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (it == m_linksInProgress.end()) {
|
|
||||||
qWarning("%s: Remote process %p not found in process list.",
|
|
||||||
Q_FUNC_INFO, proc);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const MaemoDeployable &deployable = it.value();
|
|
||||||
if (exitStatus != SshRemoteProcess::ExitedNormally
|
|
||||||
|| proc->exitCode() != 0) {
|
|
||||||
handleError(tr("Deployment failed for file '%1': "
|
|
||||||
"Could not create link '%2' on remote system.")
|
|
||||||
.arg(deployable.localFilePath, deployable.remoteDir + '/'
|
|
||||||
+ QFileInfo(deployable.localFilePath).fileName()));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_runConfig->setDeployed(m_devConfig.server.host, it.value());
|
|
||||||
m_linksInProgress.erase(it);
|
|
||||||
if (m_linksInProgress.isEmpty() && m_uploadsInProgress.isEmpty()) {
|
|
||||||
if (m_needsInstall) {
|
|
||||||
emit appendMessage(this, tr("Installing package ..."), false);
|
|
||||||
const QByteArray cmd = remoteSudo().toUtf8() + " dpkg -i "
|
|
||||||
+ packageFileName().toUtf8();
|
|
||||||
m_installer = m_connection->createRemoteProcess(cmd);
|
|
||||||
connect(m_installer.data(), SIGNAL(closed(int)), this,
|
|
||||||
SLOT(handleInstallationFinished(int)));
|
|
||||||
connect(m_installer.data(), SIGNAL(outputAvailable(QByteArray)),
|
|
||||||
this, SLOT(handleRemoteOutput(QByteArray)));
|
|
||||||
connect(m_installer.data(),
|
|
||||||
SIGNAL(errorOutputAvailable(QByteArray)), this,
|
|
||||||
SLOT(handleRemoteErrorOutput(QByteArray)));
|
|
||||||
m_installer->start();
|
|
||||||
} else {
|
|
||||||
handleDeploymentFinished();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractMaemoRunControl::handleInstallationFinished(int exitStatus)
|
|
||||||
{
|
|
||||||
if (m_stopped)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (exitStatus != SshRemoteProcess::ExitedNormally
|
|
||||||
|| m_installer->exitCode() != 0) {
|
|
||||||
handleError(tr("Installing package failed."));
|
|
||||||
} else {
|
|
||||||
emit appendMessage(this, tr("Package installation finished."), false);
|
|
||||||
handleDeploymentFinished();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractMaemoRunControl::handleDeploymentFinished()
|
|
||||||
{
|
|
||||||
emit appendMessage(this, tr("Deployment finished."), false);
|
|
||||||
m_progress.reportFinished();
|
|
||||||
startExecutionIfPossible();
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<MaemoDeployable> AbstractMaemoRunControl::filesToDeploy()
|
|
||||||
{
|
|
||||||
QList<MaemoDeployable> deployableList;
|
|
||||||
if (m_runConfig->packageStep()->isPackagingEnabled()) {
|
|
||||||
const MaemoDeployable d(packageFilePath(), uploadDir());
|
|
||||||
m_needsInstall = addDeployableIfNeeded(deployableList, d);
|
|
||||||
} else {
|
|
||||||
const MaemoDeployables * const deployables
|
|
||||||
= m_runConfig->packageStep()->deployables();
|
|
||||||
const int deployableCount = deployables->deployableCount();
|
|
||||||
for (int i = 0; i < deployableCount; ++i) {
|
|
||||||
const MaemoDeployable &d = deployables->deployableAt(i);
|
|
||||||
addDeployableIfNeeded(deployableList, d);
|
|
||||||
}
|
|
||||||
m_needsInstall = false;
|
|
||||||
}
|
|
||||||
return deployableList;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AbstractMaemoRunControl::addDeployableIfNeeded(QList<MaemoDeployable> &deployables,
|
|
||||||
const MaemoDeployable &deployable)
|
|
||||||
{
|
|
||||||
if (m_runConfig->currentlyNeedsDeployment(m_devConfig.server.host,
|
|
||||||
deployable)) {
|
|
||||||
deployables << deployable;
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AbstractMaemoRunControl::isDeploying() const
|
|
||||||
{
|
|
||||||
return !m_uploadsInProgress.isEmpty() || !m_linksInProgress.isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString AbstractMaemoRunControl::packageFileName() const
|
|
||||||
{
|
|
||||||
return QFileInfo(packageFilePath()).fileName();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString AbstractMaemoRunControl::packageFilePath() const
|
|
||||||
{
|
|
||||||
return m_runConfig->packageStep()->packageFilePath();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString AbstractMaemoRunControl::executableFilePathOnTarget() const
|
QString AbstractMaemoRunControl::executableFilePathOnTarget() const
|
||||||
{
|
{
|
||||||
const MaemoDeployables * const deployables
|
const MaemoDeployables * const deployables
|
||||||
@@ -374,11 +146,6 @@ QString AbstractMaemoRunControl::executableFilePathOnTarget() const
|
|||||||
return deployables->remoteExecutableFilePath(m_runConfig->executable());
|
return deployables->remoteExecutableFilePath(m_runConfig->executable());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AbstractMaemoRunControl::isCleaning() const
|
|
||||||
{
|
|
||||||
return m_initialCleaner && m_initialCleaner->isRunning();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractMaemoRunControl::startExecutionIfPossible()
|
void AbstractMaemoRunControl::startExecutionIfPossible()
|
||||||
{
|
{
|
||||||
if (executableFilePathOnTarget().isEmpty()) {
|
if (executableFilePathOnTarget().isEmpty()) {
|
||||||
@@ -436,7 +203,7 @@ void AbstractMaemoRunControl::handleRemoteErrorOutput(const QByteArray &output)
|
|||||||
|
|
||||||
bool AbstractMaemoRunControl::isRunning() const
|
bool AbstractMaemoRunControl::isRunning() const
|
||||||
{
|
{
|
||||||
return isDeploying() || (m_runner && m_runner->isRunning());
|
return m_runner && m_runner->isRunning();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractMaemoRunControl::stopRunning(bool forDebugging)
|
void AbstractMaemoRunControl::stopRunning(bool forDebugging)
|
||||||
@@ -488,7 +255,7 @@ void AbstractMaemoRunControl::handleInitialCleanupFinished(int exitStatus)
|
|||||||
.arg(m_initialCleaner->errorString()));
|
.arg(m_initialCleaner->errorString()));
|
||||||
} else {
|
} else {
|
||||||
emit appendMessage(this, tr("Initial cleanup done."), false);
|
emit appendMessage(this, tr("Initial cleanup done."), false);
|
||||||
startDeployment();
|
startExecutionIfPossible();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -507,11 +274,6 @@ const QString AbstractMaemoRunControl::uploadDir() const
|
|||||||
return homeDirOnDevice(m_devConfig.server.uname);
|
return homeDirOnDevice(m_devConfig.server.uname);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString AbstractMaemoRunControl::remoteSudo() const
|
|
||||||
{
|
|
||||||
return QLatin1String("/usr/lib/mad-developer/devrootsh");
|
|
||||||
}
|
|
||||||
|
|
||||||
const QString AbstractMaemoRunControl::targetCmdLinePrefix() const
|
const QString AbstractMaemoRunControl::targetCmdLinePrefix() const
|
||||||
{
|
{
|
||||||
return QString::fromLocal8Bit("%1 chmod a+x %2 && source /etc/profile && DISPLAY=:0.0 ")
|
return QString::fromLocal8Bit("%1 chmod a+x %2 && source /etc/profile && DISPLAY=:0.0 ")
|
||||||
@@ -565,6 +327,7 @@ MaemoDebugRunControl::MaemoDebugRunControl(RunConfiguration *runConfiguration)
|
|||||||
: AbstractMaemoRunControl(runConfiguration, ProjectExplorer::Constants::DEBUGMODE)
|
: AbstractMaemoRunControl(runConfiguration, ProjectExplorer::Constants::DEBUGMODE)
|
||||||
, m_debuggerRunControl(0)
|
, m_debuggerRunControl(0)
|
||||||
, m_startParams(new DebuggerStartParameters)
|
, m_startParams(new DebuggerStartParameters)
|
||||||
|
, m_uploadJob(SftpInvalidJob)
|
||||||
{
|
{
|
||||||
#ifdef USE_GDBSERVER
|
#ifdef USE_GDBSERVER
|
||||||
m_startParams->startMode = AttachToRemote;
|
m_startParams->startMode = AttachToRemote;
|
||||||
@@ -608,26 +371,101 @@ QString MaemoDebugRunControl::remoteCall() const
|
|||||||
|
|
||||||
void MaemoDebugRunControl::startExecution()
|
void MaemoDebugRunControl::startExecution()
|
||||||
{
|
{
|
||||||
#ifdef USE_GDBSERVER
|
const QString &dumperLib = m_runConfig->dumperLib();
|
||||||
AbstractMaemoRunControl::startExecution();
|
if (!dumperLib.isEmpty()
|
||||||
#else
|
&& m_runConfig->deployStep()->currentlyNeedsDeployment(m_devConfig.server.host,
|
||||||
|
MaemoDeployable(dumperLib, uploadDir()))) {
|
||||||
|
m_uploader = m_connection->createSftpChannel();
|
||||||
|
connect(m_uploader.data(), SIGNAL(initialized()), this,
|
||||||
|
SLOT(handleSftpChannelInitialized()));
|
||||||
|
connect(m_uploader.data(), SIGNAL(initializationFailed(QString)), this,
|
||||||
|
SLOT(handleSftpChannelInitializationFailed(QString)));
|
||||||
|
connect(m_uploader.data(), SIGNAL(finished(Core::SftpJobId, QString)),
|
||||||
|
this, SLOT(handleSftpJobFinished(Core::SftpJobId, QString)));
|
||||||
|
m_uploader->initialize();
|
||||||
|
} else {
|
||||||
startDebugging();
|
startDebugging();
|
||||||
#endif
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaemoDebugRunControl::handleSftpChannelInitialized()
|
||||||
|
{
|
||||||
|
if (m_stopped)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const QString dumperLib = m_runConfig->dumperLib();
|
||||||
|
const QString fileName = QFileInfo(dumperLib).fileName();
|
||||||
|
const QString remoteFilePath = uploadDir() + '/' + fileName;
|
||||||
|
m_uploadJob = m_uploader->uploadFile(dumperLib, remoteFilePath,
|
||||||
|
SftpOverwriteExisting);
|
||||||
|
if (m_uploadJob == SftpInvalidJob) {
|
||||||
|
handleError(tr("Upload failed: Could not open file '%1'")
|
||||||
|
.arg(dumperLib));
|
||||||
|
} else {
|
||||||
|
emit appendMessage(this,
|
||||||
|
tr("Started uploading debugging helpers ('%1').").arg(dumperLib),
|
||||||
|
false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaemoDebugRunControl::handleSftpChannelInitializationFailed(const QString &error)
|
||||||
|
{
|
||||||
|
handleError(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaemoDebugRunControl::handleSftpJobFinished(Core::SftpJobId job,
|
||||||
|
const QString &error)
|
||||||
|
{
|
||||||
|
if (m_stopped)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (job != m_uploadJob) {
|
||||||
|
qWarning("Warning: Unknown debugging helpers upload job %d finished.", job);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!error.isEmpty()) {
|
||||||
|
handleError(tr("Error: Could not upload debugging helpers."));
|
||||||
|
} else {
|
||||||
|
m_runConfig->deployStep()->setDeployed(m_devConfig.server.host,
|
||||||
|
MaemoDeployable(m_runConfig->dumperLib(), uploadDir()));
|
||||||
|
emit appendMessage(this,
|
||||||
|
tr("Finished uploading debugging helpers."), false);
|
||||||
|
startDebugging();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MaemoDebugRunControl::startDebugging()
|
void MaemoDebugRunControl::startDebugging()
|
||||||
{
|
{
|
||||||
|
#ifdef USE_GDBSERVER
|
||||||
|
AbstractMaemoRunControl::startExecution();
|
||||||
|
#else
|
||||||
DebuggerPlugin::startDebugger(m_debuggerRunControl);
|
DebuggerPlugin::startDebugger(m_debuggerRunControl);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MaemoDebugRunControl::isDeploying() const
|
||||||
|
{
|
||||||
|
return m_uploader && m_uploadJob != SftpInvalidJob;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MaemoDebugRunControl::stopInternal()
|
void MaemoDebugRunControl::stopInternal()
|
||||||
{
|
{
|
||||||
|
if (isDeploying()) {
|
||||||
|
disconnect(m_uploader.data(), 0, this, 0);
|
||||||
|
m_uploader->closeChannel();
|
||||||
|
m_uploadJob = SftpInvalidJob;
|
||||||
|
emit finished();
|
||||||
|
} else if (m_debuggerRunControl && m_debuggerRunControl->engine()) {
|
||||||
m_debuggerRunControl->engine()->quitDebugger();
|
m_debuggerRunControl->engine()->quitDebugger();
|
||||||
|
} else {
|
||||||
|
emit finished();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MaemoDebugRunControl::isRunning() const
|
bool MaemoDebugRunControl::isRunning() const
|
||||||
{
|
{
|
||||||
return AbstractMaemoRunControl::isRunning()
|
return isDeploying() || AbstractMaemoRunControl::isRunning()
|
||||||
|| m_debuggerRunControl->state() != DebuggerNotReady;
|
|| m_debuggerRunControl->state() != DebuggerNotReady;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -642,7 +480,7 @@ void MaemoDebugRunControl::debuggingFinished()
|
|||||||
|
|
||||||
void MaemoDebugRunControl::handleRemoteProcessStarted()
|
void MaemoDebugRunControl::handleRemoteProcessStarted()
|
||||||
{
|
{
|
||||||
startDebugging();
|
DebuggerPlugin::startDebugger(m_debuggerRunControl);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MaemoDebugRunControl::debuggerOutput(const QString &output)
|
void MaemoDebugRunControl::debuggerOutput(const QString &output)
|
||||||
@@ -659,14 +497,5 @@ QString MaemoDebugRunControl::gdbServerPort() const
|
|||||||
// but we will make sure we use the right port from the information file.
|
// but we will make sure we use the right port from the information file.
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<MaemoDeployable> MaemoDebugRunControl::filesToDeploy()
|
|
||||||
{
|
|
||||||
QList<MaemoDeployable> deployables
|
|
||||||
= AbstractMaemoRunControl::filesToDeploy();
|
|
||||||
const MaemoDeployable d(m_runConfig->dumperLib(), uploadDir());
|
|
||||||
addDeployableIfNeeded(deployables, d);
|
|
||||||
return deployables;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace Qt4ProjectManager
|
} // namespace Qt4ProjectManager
|
||||||
|
|||||||
@@ -36,14 +36,10 @@
|
|||||||
#define MAEMORUNCONTROL_H
|
#define MAEMORUNCONTROL_H
|
||||||
|
|
||||||
#include "maemodeviceconfigurations.h"
|
#include "maemodeviceconfigurations.h"
|
||||||
#include "maemodeployable.h"
|
|
||||||
|
|
||||||
#include <coreplugin/ssh/sftpdefs.h>
|
#include <coreplugin/ssh/sftpdefs.h>
|
||||||
#include <projectexplorer/runconfiguration.h>
|
#include <projectexplorer/runconfiguration.h>
|
||||||
|
|
||||||
#include <QtCore/QFutureInterface>
|
|
||||||
#include <QtCore/QMap>
|
|
||||||
#include <QtCore/QScopedPointer>
|
|
||||||
#include <QtCore/QString>
|
#include <QtCore/QString>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
@@ -78,7 +74,6 @@ protected:
|
|||||||
virtual void start();
|
virtual void start();
|
||||||
virtual void stop();
|
virtual void stop();
|
||||||
|
|
||||||
void startDeployment();
|
|
||||||
void stopRunning(bool forDebugging);
|
void stopRunning(bool forDebugging);
|
||||||
virtual void startExecution();
|
virtual void startExecution();
|
||||||
void handleError(const QString &errString);
|
void handleError(const QString &errString);
|
||||||
@@ -87,22 +82,12 @@ protected:
|
|||||||
const QString targetCmdLinePrefix() const;
|
const QString targetCmdLinePrefix() const;
|
||||||
QString targetCmdLineSuffix() const;
|
QString targetCmdLineSuffix() const;
|
||||||
const QString uploadDir() const;
|
const QString uploadDir() const;
|
||||||
QString packageFileName() const;
|
|
||||||
QString packageFilePath() const;
|
|
||||||
QString executableFilePathOnTarget() const;
|
QString executableFilePathOnTarget() const;
|
||||||
virtual QList<MaemoDeployable> filesToDeploy();
|
|
||||||
bool addDeployableIfNeeded(QList<MaemoDeployable> &deployables,
|
|
||||||
const MaemoDeployable &deployable);
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void handleConnected();
|
void handleConnected();
|
||||||
void handleConnectionFailure();
|
void handleConnectionFailure();
|
||||||
void handleInitialCleanupFinished(int exitStatus);
|
void handleInitialCleanupFinished(int exitStatus);
|
||||||
void handleSftpChannelInitialized();
|
|
||||||
void handleSftpChannelInitializationFailed(const QString &error);
|
|
||||||
void handleSftpJobFinished(Core::SftpJobId job, const QString &error);
|
|
||||||
void handleLinkProcessFinished(int exitStatus);
|
|
||||||
void handleInstallationFinished(int exitStatus);
|
|
||||||
virtual void handleRemoteProcessStarted() {}
|
virtual void handleRemoteProcessStarted() {}
|
||||||
void handleRemoteProcessFinished(int exitStatus);
|
void handleRemoteProcessFinished(int exitStatus);
|
||||||
void handleRemoteOutput(const QByteArray &output);
|
void handleRemoteOutput(const QByteArray &output);
|
||||||
@@ -111,6 +96,8 @@ private slots:
|
|||||||
protected:
|
protected:
|
||||||
MaemoRunConfiguration *m_runConfig; // TODO this pointer can be invalid
|
MaemoRunConfiguration *m_runConfig; // TODO this pointer can be invalid
|
||||||
const MaemoDeviceConfig m_devConfig;
|
const MaemoDeviceConfig m_devConfig;
|
||||||
|
QSharedPointer<Core::SshConnection> m_connection;
|
||||||
|
bool m_stopped;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual void stopInternal()=0;
|
virtual void stopInternal()=0;
|
||||||
@@ -120,25 +107,10 @@ private:
|
|||||||
void cancelActions();
|
void cancelActions();
|
||||||
template<class SshChannel> void closeSshChannel(SshChannel &channel);
|
template<class SshChannel> void closeSshChannel(SshChannel &channel);
|
||||||
void startExecutionIfPossible();
|
void startExecutionIfPossible();
|
||||||
bool isCleaning() const;
|
|
||||||
bool isDeploying() const;
|
|
||||||
QString remoteSudo() const;
|
|
||||||
QString uploadFilePath(const MaemoDeployable &deployable) const;
|
|
||||||
void handleDeploymentFinished();
|
|
||||||
|
|
||||||
QFutureInterface<void> m_progress;
|
|
||||||
QSharedPointer<Core::SshConnection> m_connection;
|
|
||||||
QSharedPointer<Core::SftpChannel> m_uploader;
|
|
||||||
QSharedPointer<Core::SshRemoteProcess> m_installer;
|
|
||||||
QSharedPointer<Core::SshRemoteProcess> m_runner;
|
QSharedPointer<Core::SshRemoteProcess> m_runner;
|
||||||
QSharedPointer<Core::SshRemoteProcess> m_stopper;
|
QSharedPointer<Core::SshRemoteProcess> m_stopper;
|
||||||
QSharedPointer<Core::SshRemoteProcess> m_initialCleaner;
|
QSharedPointer<Core::SshRemoteProcess> m_initialCleaner;
|
||||||
|
|
||||||
typedef QPair<MaemoDeployable, QString> DeployInfo;
|
|
||||||
QMap<Core::SftpJobId, DeployInfo> m_uploadsInProgress;
|
|
||||||
QMap<QSharedPointer<Core::SshRemoteProcess>, MaemoDeployable> m_linksInProgress;
|
|
||||||
bool m_needsInstall;
|
|
||||||
bool m_stopped;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class MaemoRunControl : public AbstractMaemoRunControl
|
class MaemoRunControl : public AbstractMaemoRunControl
|
||||||
@@ -165,18 +137,23 @@ private slots:
|
|||||||
virtual void handleRemoteProcessStarted();
|
virtual void handleRemoteProcessStarted();
|
||||||
void debuggerOutput(const QString &output);
|
void debuggerOutput(const QString &output);
|
||||||
void debuggingFinished();
|
void debuggingFinished();
|
||||||
|
void handleSftpChannelInitialized();
|
||||||
|
void handleSftpChannelInitializationFailed(const QString &error);
|
||||||
|
void handleSftpJobFinished(Core::SftpJobId job, const QString &error);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual void stopInternal();
|
virtual void stopInternal();
|
||||||
virtual void startExecution();
|
virtual void startExecution();
|
||||||
virtual QString remoteCall() const;
|
virtual QString remoteCall() const;
|
||||||
virtual QList<MaemoDeployable> filesToDeploy();
|
|
||||||
|
|
||||||
QString gdbServerPort() const;
|
QString gdbServerPort() const;
|
||||||
void startDebugging();
|
void startDebugging();
|
||||||
|
bool isDeploying() const;
|
||||||
|
|
||||||
Debugger::DebuggerRunControl *m_debuggerRunControl;
|
Debugger::DebuggerRunControl *m_debuggerRunControl;
|
||||||
QSharedPointer<Debugger::DebuggerStartParameters> m_startParams;
|
QSharedPointer<Debugger::DebuggerStartParameters> m_startParams;
|
||||||
|
QSharedPointer<Core::SftpChannel> m_uploader;
|
||||||
|
Core::SftpJobId m_uploadJob;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|||||||
@@ -288,8 +288,8 @@ Qt4BuildConfiguration *Qt4Target::addQt4BuildConfiguration(QString displayName,
|
|||||||
} else if (id() == Constants::MAEMO_DEVICE_TARGET_ID) {
|
} else if (id() == Constants::MAEMO_DEVICE_TARGET_ID) {
|
||||||
bc->insertStep(ProjectExplorer::BuildStep::Deploy, 2,
|
bc->insertStep(ProjectExplorer::BuildStep::Deploy, 2,
|
||||||
new MaemoPackageCreationStep(bc));
|
new MaemoPackageCreationStep(bc));
|
||||||
// bc->insertStep(ProjectExplorer::BuildStep::Deploy, 2,
|
bc->insertStep(ProjectExplorer::BuildStep::Deploy, 3,
|
||||||
// new MaemoDeployStep(bc));
|
new MaemoDeployStep(bc));
|
||||||
}
|
}
|
||||||
|
|
||||||
MakeStep* cleanStep = new MakeStep(bc);
|
MakeStep* cleanStep = new MakeStep(bc);
|
||||||
|
|||||||
Reference in New Issue
Block a user