RemoteLinux: Add incremental deployment to the TarPackageCreationStep

Patch adds incremental deployment to the tar ball creation. Allows for
only changed files to be deployed in a single tar ball.

Change-Id: I28a0bd1220503125b75a664323b72906b479b821
Reviewed-by: André Hartmann <aha_1980@gmx.de>
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
Daniel Trevitz
2016-12-25 12:31:12 -05:00
parent 5d3cabb4e6
commit a8854b680e
2 changed files with 107 additions and 2 deletions

View File

@@ -25,9 +25,13 @@
#include "tarpackagecreationstep.h" #include "tarpackagecreationstep.h"
#include <projectexplorer/buildmanager.h>
#include <projectexplorer/deploymentdata.h> #include <projectexplorer/deploymentdata.h>
#include <projectexplorer/project.h> #include <projectexplorer/project.h>
#include <projectexplorer/target.h> #include <projectexplorer/target.h>
#include <qtsupport/qtkitinformation.h>
#include <ssh/sshconnection.h>
#include <ssh/sshconnectionmanager.h>
#include <QDateTime> #include <QDateTime>
#include <QDir> #include <QDir>
@@ -44,6 +48,7 @@ using namespace ProjectExplorer;
namespace RemoteLinux { namespace RemoteLinux {
namespace { namespace {
const char IgnoreMissingFilesKey[] = "RemoteLinux.TarPackageCreationStep.IgnoreMissingFiles"; const char IgnoreMissingFilesKey[] = "RemoteLinux.TarPackageCreationStep.IgnoreMissingFiles";
const char IncrementalDeploymentKey[] = "RemoteLinux.TarPackageCreationStep.IncrementalDeployment";
class CreateTarStepWidget : public SimpleBuildStepConfigWidget class CreateTarStepWidget : public SimpleBuildStepConfigWidget
{ {
@@ -52,13 +57,22 @@ public:
CreateTarStepWidget(TarPackageCreationStep *step) : SimpleBuildStepConfigWidget(step) CreateTarStepWidget(TarPackageCreationStep *step) : SimpleBuildStepConfigWidget(step)
{ {
m_ignoreMissingFilesCheckBox.setText(tr("Ignore missing files")); m_ignoreMissingFilesCheckBox.setText(tr("Ignore missing files"));
m_incrementalDeploymentCheckBox.setText(tr("Package modified files only"));
QVBoxLayout *mainLayout = new QVBoxLayout(this); QVBoxLayout *mainLayout = new QVBoxLayout(this);
mainLayout->setMargin(0); mainLayout->setMargin(0);
mainLayout->addWidget(&m_incrementalDeploymentCheckBox);
mainLayout->addWidget(&m_ignoreMissingFilesCheckBox); mainLayout->addWidget(&m_ignoreMissingFilesCheckBox);
m_ignoreMissingFilesCheckBox.setChecked(step->ignoreMissingFiles()); m_ignoreMissingFilesCheckBox.setChecked(step->ignoreMissingFiles());
m_incrementalDeploymentCheckBox.setChecked(step->isIncrementalDeployment());
connect(&m_ignoreMissingFilesCheckBox, &QAbstractButton::toggled, connect(&m_ignoreMissingFilesCheckBox, &QAbstractButton::toggled,
this, &CreateTarStepWidget::handleIgnoreMissingFilesChanged); this, &CreateTarStepWidget::handleIgnoreMissingFilesChanged);
connect(&m_incrementalDeploymentCheckBox, &QAbstractButton::toggled,
this, &CreateTarStepWidget::handleIncrementalDeploymentChanged);
connect(step, &AbstractPackagingStep::packageFilePathChanged, connect(step, &AbstractPackagingStep::packageFilePathChanged,
this, &BuildStepConfigWidget::updateSummary); this, &BuildStepConfigWidget::updateSummary);
} }
@@ -82,7 +96,13 @@ private:
step->setIgnoreMissingFiles(ignoreMissingFiles); step->setIgnoreMissingFiles(ignoreMissingFiles);
} }
void handleIncrementalDeploymentChanged(bool incrementalDeployment) {
TarPackageCreationStep *step = qobject_cast<TarPackageCreationStep *>(this->step());
step->setIncrementalDeployment(incrementalDeployment);
}
QCheckBox m_ignoreMissingFilesCheckBox; QCheckBox m_ignoreMissingFilesCheckBox;
QCheckBox m_incrementalDeploymentCheckBox;
}; };
@@ -131,21 +151,37 @@ bool TarPackageCreationStep::init(QList<const BuildStep *> &earlierSteps)
{ {
if (!AbstractPackagingStep::init(earlierSteps)) if (!AbstractPackagingStep::init(earlierSteps))
return false; return false;
m_packagingNeeded = isPackagingNeeded(); m_packagingNeeded = isPackagingNeeded();
if (m_packagingNeeded)
m_files = target()->deploymentData().allFiles();
return true; return true;
} }
void TarPackageCreationStep::run(QFutureInterface<bool> &fi) void TarPackageCreationStep::run(QFutureInterface<bool> &fi)
{ {
setPackagingStarted(); setPackagingStarted();
const QList<DeployableFile> &files = target()->deploymentData().allFiles();
if (m_incrementalDeployment) {
m_files.clear();
for (const DeployableFile &file : files)
addNeededDeploymentFiles(file, target()->kit());
} else {
m_files = files;
}
const bool success = doPackage(fi); const bool success = doPackage(fi);
setPackagingFinished(success); setPackagingFinished(success);
if (success) if (success)
emit addOutput(tr("Packaging finished successfully."), MessageOutput); emit addOutput(tr("Packaging finished successfully."), MessageOutput);
else else
emit addOutput(tr("Packaging failed."), ErrorMessageOutput); emit addOutput(tr("Packaging failed."), ErrorMessageOutput);
connect(BuildManager::instance(), &BuildManager::buildQueueFinished,
this, &TarPackageCreationStep::deployFinished);
reportRunResult(fi, success); reportRunResult(fi, success);
} }
@@ -159,6 +195,45 @@ bool TarPackageCreationStep::ignoreMissingFiles() const
return m_ignoreMissingFiles; return m_ignoreMissingFiles;
} }
void TarPackageCreationStep::setIncrementalDeployment(bool incrementalDeployment)
{
m_incrementalDeployment = incrementalDeployment;
}
bool TarPackageCreationStep::isIncrementalDeployment() const
{
return m_incrementalDeployment;
}
void TarPackageCreationStep::addNeededDeploymentFiles(
const ProjectExplorer::DeployableFile &deployable,
const ProjectExplorer::Kit *kit)
{
const QFileInfo fileInfo = deployable.localFilePath().toFileInfo();
if (!fileInfo.isDir()) {
if (m_deployTimes.hasChangedSinceLastDeployment(deployable, kit))
m_files << deployable;
return;
}
const QStringList files = QDir(deployable.localFilePath().toString())
.entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
if (files.isEmpty()) {
m_files << deployable;
return;
}
for (const QString &fileName : files) {
const QString localFilePath = deployable.localFilePath().appendPath(fileName).toString();
const QString remoteDir = deployable.remoteDirectory() + '/' + fileInfo.fileName();
// Recurse through the subdirectories
addNeededDeploymentFiles(DeployableFile(localFilePath, remoteDir), kit);
}
}
bool TarPackageCreationStep::doPackage(QFutureInterface<bool> &fi) bool TarPackageCreationStep::doPackage(QFutureInterface<bool> &fi)
{ {
emit addOutput(tr("Creating tarball..."), MessageOutput); emit addOutput(tr("Creating tarball..."), MessageOutput);
@@ -324,6 +399,22 @@ bool TarPackageCreationStep::writeHeader(QFile &tarFile, const QFileInfo &fileIn
return true; return true;
} }
void TarPackageCreationStep::deployFinished(bool success)
{
disconnect(BuildManager::instance(), &BuildManager::buildQueueFinished,
this, &TarPackageCreationStep::deployFinished);
if (!success)
return;
const Kit *kit = target()->kit();
// Store files that have been tar'd and successfully deployed
const auto files = m_files;
for (const DeployableFile &file : files)
m_deployTimes.saveDeploymentTimeStamp(file, kit);
}
QString TarPackageCreationStep::packageFileName() const QString TarPackageCreationStep::packageFileName() const
{ {
return project()->displayName() + QLatin1String(".tar"); return project()->displayName() + QLatin1String(".tar");
@@ -339,6 +430,7 @@ bool TarPackageCreationStep::fromMap(const QVariantMap &map)
if (!AbstractPackagingStep::fromMap(map)) if (!AbstractPackagingStep::fromMap(map))
return false; return false;
setIgnoreMissingFiles(map.value(QLatin1String(IgnoreMissingFilesKey), false).toBool()); setIgnoreMissingFiles(map.value(QLatin1String(IgnoreMissingFilesKey), false).toBool());
m_deployTimes.importDeployTimes(map);
return true; return true;
} }
@@ -346,6 +438,7 @@ QVariantMap TarPackageCreationStep::toMap() const
{ {
QVariantMap map = AbstractPackagingStep::toMap(); QVariantMap map = AbstractPackagingStep::toMap();
map.insert(QLatin1String(IgnoreMissingFilesKey), ignoreMissingFiles()); map.insert(QLatin1String(IgnoreMissingFilesKey), ignoreMissingFiles());
map.unite(m_deployTimes.exportDeployTimes());
return map; return map;
} }

View File

@@ -26,6 +26,7 @@
#pragma once #pragma once
#include "abstractpackagingstep.h" #include "abstractpackagingstep.h"
#include "deploymenttimeinfo.h"
#include "remotelinux_export.h" #include "remotelinux_export.h"
#include <projectexplorer/deployablefile.h> #include <projectexplorer/deployablefile.h>
@@ -53,7 +54,15 @@ public:
void setIgnoreMissingFiles(bool ignoreMissingFiles); void setIgnoreMissingFiles(bool ignoreMissingFiles);
bool ignoreMissingFiles() const; bool ignoreMissingFiles() const;
void setIncrementalDeployment(bool incrementalDeployment);
bool isIncrementalDeployment() const;
private: private:
void deployFinished(bool success);
void addNeededDeploymentFiles(const ProjectExplorer::DeployableFile &deployable,
const ProjectExplorer::Kit *kit);
ProjectExplorer::BuildStepConfigWidget *createConfigWidget() override; ProjectExplorer::BuildStepConfigWidget *createConfigWidget() override;
bool fromMap(const QVariantMap &map) override; bool fromMap(const QVariantMap &map) override;
QVariantMap toMap() const override; QVariantMap toMap() const override;
@@ -67,6 +76,9 @@ private:
bool writeHeader(QFile &tarFile, const QFileInfo &fileInfo, bool writeHeader(QFile &tarFile, const QFileInfo &fileInfo,
const QString &remoteFilePath); const QString &remoteFilePath);
DeploymentTimeInfo m_deployTimes;
bool m_incrementalDeployment;
bool m_ignoreMissingFiles; bool m_ignoreMissingFiles;
bool m_packagingNeeded; bool m_packagingNeeded;
QList<ProjectExplorer::DeployableFile> m_files; QList<ProjectExplorer::DeployableFile> m_files;