RemoteLinux: Add possibility to ignore missing files while deploying.

New "Ignore missing files" checkbox was added to "Upload files via SFTP"
and "Create tarball" deployment steps. If checked, missing files will
produce a warning instead of the error thus preventing deployment
process from failing.

Change-Id: I0c3032746fbaae60aef2345802fc02c9951ab386
Reviewed-by: Christian Kandeler <christian.kandeler@digia.com>
This commit is contained in:
Oleksii Serdiuk
2013-09-16 15:52:25 +02:00
parent 649e127156
commit e0ddfe1a5f
8 changed files with 121 additions and 8 deletions

View File

@@ -173,4 +173,11 @@ void AbstractPackagingStep::raiseError(const QString &errorMessage)
Constants::TASK_CATEGORY_DEPLOYMENT)); Constants::TASK_CATEGORY_DEPLOYMENT));
} }
void AbstractPackagingStep::raiseWarning(const QString &warningMessage)
{
emit addOutput(warningMessage, ErrorMessageOutput);
emit addTask(Task(Task::Warning, warningMessage, Utils::FileName(), -1,
Constants::TASK_CATEGORY_DEPLOYMENT));
}
} // namespace RemoteLinux } // namespace RemoteLinux

View File

@@ -60,6 +60,7 @@ protected:
void setPackagingFinished(bool success); void setPackagingFinished(bool success);
void raiseError(const QString &errorMessage); void raiseError(const QString &errorMessage);
void raiseWarning(const QString &warningMessage);
QString cachedPackageDirectory() const; QString cachedPackageDirectory() const;
QString packageDirectory() const; QString packageDirectory() const;

View File

@@ -52,9 +52,10 @@ class GenericDirectUploadServicePrivate
{ {
public: public:
GenericDirectUploadServicePrivate() GenericDirectUploadServicePrivate()
: incremental(false), stopRequested(false), state(Inactive) {} : incremental(false), ignoreMissingFiles(false), stopRequested(false), state(Inactive) {}
bool incremental; bool incremental;
bool ignoreMissingFiles;
bool stopRequested; bool stopRequested;
State state; State state;
QList<DeployableFile> filesToUpload; QList<DeployableFile> filesToUpload;
@@ -89,6 +90,11 @@ void GenericDirectUploadService::setIncrementalDeployment(bool incremental)
d->incremental = incremental; d->incremental = incremental;
} }
void GenericDirectUploadService::setIgnoreMissingFiles(bool ignoreMissingFiles)
{
d->ignoreMissingFiles = ignoreMissingFiles;
}
bool GenericDirectUploadService::isDeploymentNecessary() const bool GenericDirectUploadService::isDeploymentNecessary() const
{ {
d->filesToUpload.clear(); d->filesToUpload.clear();
@@ -269,10 +275,17 @@ void GenericDirectUploadService::handleMkdirFinished(int exitStatus)
const SftpJobId job = d->uploader->uploadFile(df.localFilePath().toString(), const SftpJobId job = d->uploader->uploadFile(df.localFilePath().toString(),
remoteFilePath, SftpOverwriteExisting); remoteFilePath, SftpOverwriteExisting);
if (job == SftpInvalidJob) { if (job == SftpInvalidJob) {
emit errorMessage(tr("Failed to upload file '%1': " const QString message = tr("Failed to upload file '%1': "
"Could not open for reading.").arg(nativePath)); "Could not open for reading.").arg(nativePath);
setFinished(); if (d->ignoreMissingFiles) {
handleDeploymentDone(); emit warningMessage(message);
d->filesToUpload.removeFirst();
uploadNextFile();
} else {
emit errorMessage(message);
setFinished();
handleDeploymentDone();
}
} }
} }
} }

View File

@@ -52,6 +52,7 @@ public:
void setDeployableFiles(const QList<ProjectExplorer::DeployableFile> &deployableFiles); void setDeployableFiles(const QList<ProjectExplorer::DeployableFile> &deployableFiles);
void setIncrementalDeployment(bool incremental); void setIncrementalDeployment(bool incremental);
void setIgnoreMissingFiles(bool ignoreMissingFiles);
protected: protected:
bool isDeploymentNecessary() const; bool isDeploymentNecessary() const;

View File

@@ -42,6 +42,7 @@ namespace RemoteLinux {
namespace Internal { namespace Internal {
namespace { namespace {
const char IncrementalKey[] = "RemoteLinux.GenericDirectUploadStep.Incremental"; const char IncrementalKey[] = "RemoteLinux.GenericDirectUploadStep.Incremental";
const char IgnoreMissingFilesKey[] = "RemoteLinux.GenericDirectUploadStep.IgnoreMissingFiles";
class ConfigWidget : public SimpleBuildStepConfigWidget class ConfigWidget : public SimpleBuildStepConfigWidget
{ {
@@ -50,12 +51,17 @@ public:
ConfigWidget(GenericDirectUploadStep *step) : SimpleBuildStepConfigWidget(step) ConfigWidget(GenericDirectUploadStep *step) : SimpleBuildStepConfigWidget(step)
{ {
m_incrementalCheckBox.setText(tr("Incremental deployment")); m_incrementalCheckBox.setText(tr("Incremental deployment"));
m_ignoreMissingFilesCheckBox.setText(tr("Ignore missing files"));
QVBoxLayout *mainLayout = new QVBoxLayout(this); QVBoxLayout *mainLayout = new QVBoxLayout(this);
mainLayout->setMargin(0); mainLayout->setMargin(0);
mainLayout->addWidget(&m_incrementalCheckBox); mainLayout->addWidget(&m_incrementalCheckBox);
mainLayout->addWidget(&m_ignoreMissingFilesCheckBox);
m_incrementalCheckBox.setChecked(step->incrementalDeployment()); m_incrementalCheckBox.setChecked(step->incrementalDeployment());
m_ignoreMissingFilesCheckBox.setChecked(step->ignoreMissingFiles());
connect(&m_incrementalCheckBox, SIGNAL(toggled(bool)), connect(&m_incrementalCheckBox, SIGNAL(toggled(bool)),
SLOT(handleIncrementalChanged(bool))); SLOT(handleIncrementalChanged(bool)));
connect(&m_ignoreMissingFilesCheckBox, SIGNAL(toggled(bool)),
SLOT(handleIgnoreMissingFilesChanged(bool)));
} }
bool showWidget() const { return true; } bool showWidget() const { return true; }
@@ -66,7 +72,13 @@ private:
step->setIncrementalDeployment(incremental); step->setIncrementalDeployment(incremental);
} }
Q_SLOT void handleIgnoreMissingFilesChanged(bool ignoreMissingFiles) {
GenericDirectUploadStep *step = qobject_cast<GenericDirectUploadStep *>(this->step());
step->setIgnoreMissingFiles(ignoreMissingFiles);
}
QCheckBox m_incrementalCheckBox; QCheckBox m_incrementalCheckBox;
QCheckBox m_ignoreMissingFilesCheckBox;
}; };
} // anonymous namespace } // anonymous namespace
@@ -74,10 +86,11 @@ private:
class GenericDirectUploadStepPrivate class GenericDirectUploadStepPrivate
{ {
public: public:
GenericDirectUploadStepPrivate() : incremental(true) {} GenericDirectUploadStepPrivate() : incremental(true), ignoreMissingFiles(false) {}
GenericDirectUploadService deployService; GenericDirectUploadService deployService;
bool incremental; bool incremental;
bool ignoreMissingFiles;
}; };
} // namespace Internal } // namespace Internal
@@ -108,6 +121,7 @@ bool GenericDirectUploadStep::initInternal(QString *error)
{ {
deployService()->setDeployableFiles(target()->deploymentData().allFiles()); deployService()->setDeployableFiles(target()->deploymentData().allFiles());
deployService()->setIncrementalDeployment(incrementalDeployment()); deployService()->setIncrementalDeployment(incrementalDeployment());
deployService()->setIgnoreMissingFiles(ignoreMissingFiles());
return deployService()->isDeploymentPossible(error); return deployService()->isDeploymentPossible(error);
} }
@@ -121,6 +135,7 @@ bool GenericDirectUploadStep::fromMap(const QVariantMap &map)
if (!AbstractRemoteLinuxDeployStep::fromMap(map)) if (!AbstractRemoteLinuxDeployStep::fromMap(map))
return false; return false;
setIncrementalDeployment(map.value(QLatin1String(Internal::IncrementalKey), true).toBool()); setIncrementalDeployment(map.value(QLatin1String(Internal::IncrementalKey), true).toBool());
setIgnoreMissingFiles(map.value(QLatin1String(Internal::IgnoreMissingFilesKey), false).toBool());
return true; return true;
} }
@@ -128,6 +143,7 @@ QVariantMap GenericDirectUploadStep::toMap() const
{ {
QVariantMap map = AbstractRemoteLinuxDeployStep::toMap(); QVariantMap map = AbstractRemoteLinuxDeployStep::toMap();
map.insert(QLatin1String(Internal::IncrementalKey), incrementalDeployment()); map.insert(QLatin1String(Internal::IncrementalKey), incrementalDeployment());
map.insert(QLatin1String(Internal::IgnoreMissingFilesKey), ignoreMissingFiles());
return map; return map;
} }
@@ -147,6 +163,16 @@ bool GenericDirectUploadStep::incrementalDeployment() const
return d->incremental; return d->incremental;
} }
void GenericDirectUploadStep::setIgnoreMissingFiles(bool ignoreMissingFiles)
{
d->ignoreMissingFiles = ignoreMissingFiles;
}
bool GenericDirectUploadStep::ignoreMissingFiles() const
{
return d->ignoreMissingFiles;
}
Core::Id GenericDirectUploadStep::stepId() Core::Id GenericDirectUploadStep::stepId()
{ {
return "RemoteLinux.DirectUploadStep"; return "RemoteLinux.DirectUploadStep";

View File

@@ -53,6 +53,9 @@ public:
void setIncrementalDeployment(bool incremental); void setIncrementalDeployment(bool incremental);
bool incrementalDeployment() const; bool incrementalDeployment() const;
void setIgnoreMissingFiles(bool ignoreMissingFiles);
bool ignoreMissingFiles() const;
static Core::Id stepId(); static Core::Id stepId();
static QString displayName(); static QString displayName();

View File

@@ -37,12 +37,16 @@
#include <QFile> #include <QFile>
#include <QFileInfo> #include <QFileInfo>
#include <QCheckBox>
#include <QVBoxLayout>
#include <cstring> #include <cstring>
using namespace ProjectExplorer; using namespace ProjectExplorer;
namespace RemoteLinux { namespace RemoteLinux {
namespace { namespace {
const char IgnoreMissingFilesKey[] = "RemoteLinux.TarPackageCreationStep.IgnoreMissingFiles";
class CreateTarStepWidget : public SimpleBuildStepConfigWidget class CreateTarStepWidget : public SimpleBuildStepConfigWidget
{ {
@@ -50,6 +54,14 @@ class CreateTarStepWidget : public SimpleBuildStepConfigWidget
public: public:
CreateTarStepWidget(TarPackageCreationStep *step) : SimpleBuildStepConfigWidget(step) CreateTarStepWidget(TarPackageCreationStep *step) : SimpleBuildStepConfigWidget(step)
{ {
m_ignoreMissingFilesCheckBox.setText(tr("Ignore missing files"));
QVBoxLayout *mainLayout = new QVBoxLayout(this);
mainLayout->setMargin(0);
mainLayout->addWidget(&m_ignoreMissingFilesCheckBox);
m_ignoreMissingFilesCheckBox.setChecked(step->ignoreMissingFiles());
connect(&m_ignoreMissingFilesCheckBox, SIGNAL(toggled(bool)),
SLOT(handleIgnoreMissingFilesChanged(bool)));
connect(step, SIGNAL(packageFilePathChanged()), SIGNAL(updateSummary())); connect(step, SIGNAL(packageFilePathChanged()), SIGNAL(updateSummary()));
} }
@@ -63,6 +75,16 @@ public:
return QLatin1String("<b>") + tr("Create tarball:") + QLatin1String("</b> ") return QLatin1String("<b>") + tr("Create tarball:") + QLatin1String("</b> ")
+ step->packageFilePath(); + step->packageFilePath();
} }
bool showWidget() const { return true; }
private:
Q_SLOT void handleIgnoreMissingFilesChanged(bool ignoreMissingFiles) {
TarPackageCreationStep *step = qobject_cast<TarPackageCreationStep *>(this->step());
step->setIgnoreMissingFiles(ignoreMissingFiles);
}
QCheckBox m_ignoreMissingFilesCheckBox;
}; };
@@ -104,6 +126,7 @@ TarPackageCreationStep::TarPackageCreationStep(BuildStepList *bsl, TarPackageCre
void TarPackageCreationStep::ctor() void TarPackageCreationStep::ctor()
{ {
setDefaultDisplayName(displayName()); setDefaultDisplayName(displayName());
m_ignoreMissingFiles = false;
} }
bool TarPackageCreationStep::init() bool TarPackageCreationStep::init()
@@ -128,6 +151,16 @@ void TarPackageCreationStep::run(QFutureInterface<bool> &fi)
fi.reportResult(success); fi.reportResult(success);
} }
void TarPackageCreationStep::setIgnoreMissingFiles(bool ignoreMissingFiles)
{
m_ignoreMissingFiles = ignoreMissingFiles;
}
bool TarPackageCreationStep::ignoreMissingFiles() const
{
return m_ignoreMissingFiles;
}
bool TarPackageCreationStep::doPackage(QFutureInterface<bool> &fi) bool TarPackageCreationStep::doPackage(QFutureInterface<bool> &fi)
{ {
emit addOutput(tr("Creating tarball..."), MessageOutput); emit addOutput(tr("Creating tarball..."), MessageOutput);
@@ -188,8 +221,15 @@ bool TarPackageCreationStep::appendFile(QFile &tarFile, const QFileInfo &fileInf
const QString nativePath = QDir::toNativeSeparators(fileInfo.filePath()); const QString nativePath = QDir::toNativeSeparators(fileInfo.filePath());
QFile file(fileInfo.filePath()); QFile file(fileInfo.filePath());
if (!file.open(QIODevice::ReadOnly)) { if (!file.open(QIODevice::ReadOnly)) {
raiseError(tr("Error reading file '%1': %2.").arg(nativePath, file.errorString())); const QString message = tr("Error reading file '%1': %2.")
return false; .arg(nativePath, file.errorString());
if (m_ignoreMissingFiles) {
raiseWarning(message);
return true;
} else {
raiseError(message);
return false;
}
} }
const int chunkSize = 1024*1024; const int chunkSize = 1024*1024;
@@ -296,6 +336,21 @@ BuildStepConfigWidget *TarPackageCreationStep::createConfigWidget()
return new CreateTarStepWidget(this); return new CreateTarStepWidget(this);
} }
bool TarPackageCreationStep::fromMap(const QVariantMap &map)
{
if (!AbstractPackagingStep::fromMap(map))
return false;
setIgnoreMissingFiles(map.value(QLatin1String(IgnoreMissingFilesKey), false).toBool());
return true;
}
QVariantMap TarPackageCreationStep::toMap() const
{
QVariantMap map = AbstractPackagingStep::toMap();
map.insert(QLatin1String(IgnoreMissingFilesKey), ignoreMissingFiles());
return map;
}
Core::Id TarPackageCreationStep::stepId() Core::Id TarPackageCreationStep::stepId()
{ {
return "MaemoTarPackageCreationStep"; return "MaemoTarPackageCreationStep";

View File

@@ -53,8 +53,14 @@ public:
bool init(); bool init();
void run(QFutureInterface<bool> &fi); void run(QFutureInterface<bool> &fi);
void setIgnoreMissingFiles(bool ignoreMissingFiles);
bool ignoreMissingFiles() const;
private: private:
ProjectExplorer::BuildStepConfigWidget *createConfigWidget(); ProjectExplorer::BuildStepConfigWidget *createConfigWidget();
bool fromMap(const QVariantMap &map);
QVariantMap toMap() const;
QString packageFileName() const; QString packageFileName() const;
@@ -65,6 +71,7 @@ private:
bool writeHeader(QFile &tarFile, const QFileInfo &fileInfo, bool writeHeader(QFile &tarFile, const QFileInfo &fileInfo,
const QString &remoteFilePath); const QString &remoteFilePath);
bool m_ignoreMissingFiles;
bool m_packagingNeeded; bool m_packagingNeeded;
QList<ProjectExplorer::DeployableFile> m_files; QList<ProjectExplorer::DeployableFile> m_files;
}; };