forked from qt-creator/qt-creator
RemoteLinux/Boot2Qt: Merge DeployStep and DeployService hierarchies
They were 1:1 now. The change here is as small as possible, there are quite a few places to clean up left. Change-Id: I4f78d1de857b93d8372e2592a7723b02fe2fc947 Reviewed-by: Marcus Tillmanns <marcus.tillmanns@qt.io>
This commit is contained in:
@@ -22,12 +22,22 @@ using namespace Utils::Tasking;
|
|||||||
|
|
||||||
namespace Qdb::Internal {
|
namespace Qdb::Internal {
|
||||||
|
|
||||||
// QdbMakeDefaultAppService
|
class QdbMakeDefaultAppStep final : public RemoteLinux::AbstractRemoteLinuxDeployStep
|
||||||
|
|
||||||
class QdbMakeDefaultAppService : public RemoteLinux::AbstractRemoteLinuxDeployService
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void setMakeDefault(bool makeDefault) { m_makeDefault = makeDefault; }
|
QdbMakeDefaultAppStep(BuildStepList *bsl, Id id)
|
||||||
|
: AbstractRemoteLinuxDeployStep(bsl, id)
|
||||||
|
{
|
||||||
|
auto selection = addAspect<SelectionAspect>();
|
||||||
|
selection->setSettingsKey("QdbMakeDefaultDeployStep.MakeDefault");
|
||||||
|
selection->addOption(Tr::tr("Set this application to start by default"));
|
||||||
|
selection->addOption(Tr::tr("Reset default application"));
|
||||||
|
|
||||||
|
setInternalInitializer([this, selection] {
|
||||||
|
m_makeDefault = selection->value() == 0;
|
||||||
|
return isDeploymentPossible();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool isDeploymentNecessary() const final { return true; }
|
bool isDeploymentNecessary() const final { return true; }
|
||||||
@@ -66,30 +76,6 @@ private:
|
|||||||
bool m_makeDefault = true;
|
bool m_makeDefault = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
// QdbMakeDefaultAppStep
|
|
||||||
|
|
||||||
class QdbMakeDefaultAppStep final : public RemoteLinux::AbstractRemoteLinuxDeployStep
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
QdbMakeDefaultAppStep(BuildStepList *bsl, Id id)
|
|
||||||
: AbstractRemoteLinuxDeployStep(bsl, id)
|
|
||||||
{
|
|
||||||
auto service = new QdbMakeDefaultAppService;
|
|
||||||
setDeployService(service);
|
|
||||||
|
|
||||||
auto selection = addAspect<SelectionAspect>();
|
|
||||||
selection->setSettingsKey("QdbMakeDefaultDeployStep.MakeDefault");
|
|
||||||
selection->addOption(Tr::tr("Set this application to start by default"));
|
|
||||||
selection->addOption(Tr::tr("Reset default application"));
|
|
||||||
|
|
||||||
setInternalInitializer([service, selection] {
|
|
||||||
service->setMakeDefault(selection->value() == 0);
|
|
||||||
return service->isDeploymentPossible();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// QdbMakeDefaultAppStepFactory
|
// QdbMakeDefaultAppStepFactory
|
||||||
|
|
||||||
QdbMakeDefaultAppStepFactory::QdbMakeDefaultAppStepFactory()
|
QdbMakeDefaultAppStepFactory::QdbMakeDefaultAppStepFactory()
|
||||||
|
|||||||
@@ -21,16 +21,24 @@ using namespace Utils::Tasking;
|
|||||||
|
|
||||||
namespace Qdb::Internal {
|
namespace Qdb::Internal {
|
||||||
|
|
||||||
// QdbStopApplicationService
|
// QdbStopApplicationStep
|
||||||
|
|
||||||
class QdbStopApplicationService : public RemoteLinux::AbstractRemoteLinuxDeployService
|
class QdbStopApplicationStep final : public RemoteLinux::AbstractRemoteLinuxDeployStep
|
||||||
{
|
{
|
||||||
private:
|
public:
|
||||||
|
QdbStopApplicationStep(BuildStepList *bsl, Id id)
|
||||||
|
: AbstractRemoteLinuxDeployStep(bsl, id)
|
||||||
|
{
|
||||||
|
setWidgetExpandedByDefault(false);
|
||||||
|
|
||||||
|
setInternalInitializer([this] { return isDeploymentPossible(); });
|
||||||
|
}
|
||||||
|
|
||||||
bool isDeploymentNecessary() const final { return true; }
|
bool isDeploymentNecessary() const final { return true; }
|
||||||
Group deployRecipe() final;
|
Group deployRecipe() final;
|
||||||
};
|
};
|
||||||
|
|
||||||
Group QdbStopApplicationService::deployRecipe()
|
Group QdbStopApplicationStep::deployRecipe()
|
||||||
{
|
{
|
||||||
const auto setupHandler = [this](QtcProcess &process) {
|
const auto setupHandler = [this](QtcProcess &process) {
|
||||||
const auto device = DeviceKitAspect::device(target()->kit());
|
const auto device = DeviceKitAspect::device(target()->kit());
|
||||||
@@ -67,24 +75,6 @@ Group QdbStopApplicationService::deployRecipe()
|
|||||||
return Group { Process(setupHandler, doneHandler, errorHandler) };
|
return Group { Process(setupHandler, doneHandler, errorHandler) };
|
||||||
}
|
}
|
||||||
|
|
||||||
// QdbStopApplicationStep
|
|
||||||
|
|
||||||
class QdbStopApplicationStep final : public RemoteLinux::AbstractRemoteLinuxDeployStep
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
QdbStopApplicationStep(BuildStepList *bsl, Id id)
|
|
||||||
: AbstractRemoteLinuxDeployStep(bsl, id)
|
|
||||||
{
|
|
||||||
auto service = new QdbStopApplicationService;
|
|
||||||
setDeployService(service);
|
|
||||||
|
|
||||||
setWidgetExpandedByDefault(false);
|
|
||||||
|
|
||||||
setInternalInitializer([service] { return service->isDeploymentPossible(); });
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// QdbStopApplicationStepFactory
|
// QdbStopApplicationStepFactory
|
||||||
|
|
||||||
QdbStopApplicationStepFactory::QdbStopApplicationStepFactory()
|
QdbStopApplicationStepFactory::QdbStopApplicationStepFactory()
|
||||||
|
|||||||
@@ -24,137 +24,116 @@ using namespace Utils;
|
|||||||
namespace RemoteLinux {
|
namespace RemoteLinux {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
class AbstractRemoteLinuxDeployServicePrivate
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
IDevice::ConstPtr deviceConfiguration;
|
|
||||||
QPointer<Target> target;
|
|
||||||
|
|
||||||
DeploymentTimeInfo deployTimes;
|
|
||||||
std::unique_ptr<TaskTree> m_taskTree;
|
|
||||||
};
|
|
||||||
|
|
||||||
class AbstractRemoteLinuxDeployStepPrivate
|
class AbstractRemoteLinuxDeployStepPrivate
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bool hasError;
|
bool hasError;
|
||||||
std::function<CheckResult()> internalInit;
|
std::function<CheckResult()> internalInit;
|
||||||
std::function<void()> runPreparer;
|
std::function<void()> runPreparer;
|
||||||
AbstractRemoteLinuxDeployService *deployService = nullptr;
|
|
||||||
|
DeploymentTimeInfo deployTimes;
|
||||||
|
std::unique_ptr<TaskTree> m_taskTree;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // Internal
|
} // Internal
|
||||||
|
|
||||||
using namespace Internal;
|
using namespace Internal;
|
||||||
|
|
||||||
AbstractRemoteLinuxDeployService::AbstractRemoteLinuxDeployService(QObject *parent)
|
AbstractRemoteLinuxDeployStep::AbstractRemoteLinuxDeployStep(BuildStepList *bsl, Id id)
|
||||||
: QObject(parent), d(new AbstractRemoteLinuxDeployServicePrivate)
|
: BuildStep(bsl, id), d(new Internal::AbstractRemoteLinuxDeployStepPrivate)
|
||||||
{
|
{
|
||||||
|
connect(this, &AbstractRemoteLinuxDeployStep::errorMessage,
|
||||||
|
this, &AbstractRemoteLinuxDeployStep::handleErrorMessage);
|
||||||
|
connect(this, &AbstractRemoteLinuxDeployStep::progressMessage,
|
||||||
|
this, &AbstractRemoteLinuxDeployStep::handleProgressMessage);
|
||||||
|
connect(this, &AbstractRemoteLinuxDeployStep::warningMessage,
|
||||||
|
this, &AbstractRemoteLinuxDeployStep::handleWarningMessage);
|
||||||
|
connect(this, &AbstractRemoteLinuxDeployStep::stdOutData,
|
||||||
|
this, &AbstractRemoteLinuxDeployStep::handleStdOutData);
|
||||||
|
connect(this, &AbstractRemoteLinuxDeployStep::stdErrData,
|
||||||
|
this, &AbstractRemoteLinuxDeployStep::handleStdErrData);
|
||||||
}
|
}
|
||||||
|
|
||||||
AbstractRemoteLinuxDeployService::~AbstractRemoteLinuxDeployService()
|
AbstractRemoteLinuxDeployStep::~AbstractRemoteLinuxDeployStep()
|
||||||
{
|
{
|
||||||
delete d;
|
delete d;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Target *AbstractRemoteLinuxDeployService::target() const
|
IDevice::ConstPtr AbstractRemoteLinuxDeployStep::deviceConfiguration() const
|
||||||
{
|
{
|
||||||
return d->target;
|
return DeviceKitAspect::device(kit());
|
||||||
}
|
}
|
||||||
|
|
||||||
const Kit *AbstractRemoteLinuxDeployService::kit() const
|
void AbstractRemoteLinuxDeployStep::saveDeploymentTimeStamp(const DeployableFile &deployableFile,
|
||||||
{
|
|
||||||
return d->target ? d->target->kit() : nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
IDevice::ConstPtr AbstractRemoteLinuxDeployService::deviceConfiguration() const
|
|
||||||
{
|
|
||||||
return d->deviceConfiguration;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractRemoteLinuxDeployService::saveDeploymentTimeStamp(const DeployableFile &deployableFile,
|
|
||||||
const QDateTime &remoteTimestamp)
|
const QDateTime &remoteTimestamp)
|
||||||
{
|
{
|
||||||
d->deployTimes.saveDeploymentTimeStamp(deployableFile, kit(), remoteTimestamp);
|
d->deployTimes.saveDeploymentTimeStamp(deployableFile, kit(), remoteTimestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AbstractRemoteLinuxDeployService::hasLocalFileChanged(
|
bool AbstractRemoteLinuxDeployStep::hasLocalFileChanged(
|
||||||
const DeployableFile &deployableFile) const
|
const DeployableFile &deployableFile) const
|
||||||
{
|
{
|
||||||
return d->deployTimes.hasLocalFileChanged(deployableFile, kit());
|
return d->deployTimes.hasLocalFileChanged(deployableFile, kit());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AbstractRemoteLinuxDeployService::hasRemoteFileChanged(
|
bool AbstractRemoteLinuxDeployStep::hasRemoteFileChanged(
|
||||||
const DeployableFile &deployableFile, const QDateTime &remoteTimestamp) const
|
const DeployableFile &deployableFile, const QDateTime &remoteTimestamp) const
|
||||||
{
|
{
|
||||||
return d->deployTimes.hasRemoteFileChanged(deployableFile, kit(), remoteTimestamp);
|
return d->deployTimes.hasRemoteFileChanged(deployableFile, kit(), remoteTimestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractRemoteLinuxDeployService::setTarget(Target *target)
|
void AbstractRemoteLinuxDeployStep::start()
|
||||||
{
|
|
||||||
d->target = target;
|
|
||||||
d->deviceConfiguration = DeviceKitAspect::device(kit());
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractRemoteLinuxDeployService::start()
|
|
||||||
{
|
{
|
||||||
QTC_ASSERT(!d->m_taskTree, return);
|
QTC_ASSERT(!d->m_taskTree, return);
|
||||||
|
|
||||||
const CheckResult check = isDeploymentPossible();
|
const CheckResult check = isDeploymentPossible();
|
||||||
if (!check) {
|
if (!check) {
|
||||||
emit errorMessage(check.errorMessage());
|
emit errorMessage(check.errorMessage());
|
||||||
emit finished();
|
handleFinished();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isDeploymentNecessary()) {
|
if (!isDeploymentNecessary()) {
|
||||||
emit progressMessage(Tr::tr("No deployment action necessary. Skipping."));
|
emit progressMessage(Tr::tr("No deployment action necessary. Skipping."));
|
||||||
emit finished();
|
handleFinished();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
d->m_taskTree.reset(new TaskTree(deployRecipe()));
|
d->m_taskTree.reset(new TaskTree(deployRecipe()));
|
||||||
const auto endHandler = [this] {
|
const auto endHandler = [this] {
|
||||||
d->m_taskTree.release()->deleteLater();
|
d->m_taskTree.release()->deleteLater();
|
||||||
emit finished();
|
handleFinished();
|
||||||
};
|
};
|
||||||
connect(d->m_taskTree.get(), &TaskTree::done, this, endHandler);
|
connect(d->m_taskTree.get(), &TaskTree::done, this, endHandler);
|
||||||
connect(d->m_taskTree.get(), &TaskTree::errorOccurred, this, endHandler);
|
connect(d->m_taskTree.get(), &TaskTree::errorOccurred, this, endHandler);
|
||||||
d->m_taskTree->start();
|
d->m_taskTree->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractRemoteLinuxDeployService::stop()
|
void AbstractRemoteLinuxDeployStep::stop()
|
||||||
{
|
{
|
||||||
if (!d->m_taskTree)
|
if (!d->m_taskTree)
|
||||||
return;
|
return;
|
||||||
d->m_taskTree.reset();
|
d->m_taskTree.reset();
|
||||||
emit finished();
|
handleFinished();
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckResult AbstractRemoteLinuxDeployService::isDeploymentPossible() const
|
CheckResult AbstractRemoteLinuxDeployStep::isDeploymentPossible() const
|
||||||
{
|
{
|
||||||
if (!deviceConfiguration())
|
if (!deviceConfiguration())
|
||||||
return CheckResult::failure(Tr::tr("No device configuration set."));
|
return CheckResult::failure(Tr::tr("No device configuration set."));
|
||||||
return CheckResult::success();
|
return CheckResult::success();
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariantMap AbstractRemoteLinuxDeployService::exportDeployTimes() const
|
QVariantMap AbstractRemoteLinuxDeployStep::exportDeployTimes() const
|
||||||
{
|
{
|
||||||
return d->deployTimes.exportDeployTimes();
|
return d->deployTimes.exportDeployTimes();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractRemoteLinuxDeployService::importDeployTimes(const QVariantMap &map)
|
void AbstractRemoteLinuxDeployStep::importDeployTimes(const QVariantMap &map)
|
||||||
{
|
{
|
||||||
d->deployTimes.importDeployTimes(map);
|
d->deployTimes.importDeployTimes(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AbstractRemoteLinuxDeployStep::AbstractRemoteLinuxDeployStep(BuildStepList *bsl, Utils::Id id)
|
|
||||||
: BuildStep(bsl, id), d(new Internal::AbstractRemoteLinuxDeployStepPrivate)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractRemoteLinuxDeployStep::setInternalInitializer(const std::function<CheckResult ()> &init)
|
void AbstractRemoteLinuxDeployStep::setInternalInitializer(const std::function<CheckResult ()> &init)
|
||||||
{
|
{
|
||||||
d->internalInit = init;
|
d->internalInit = init;
|
||||||
@@ -165,36 +144,23 @@ void AbstractRemoteLinuxDeployStep::setRunPreparer(const std::function<void ()>
|
|||||||
d->runPreparer = prep;
|
d->runPreparer = prep;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractRemoteLinuxDeployStep::setDeployService(AbstractRemoteLinuxDeployService *service)
|
|
||||||
{
|
|
||||||
d->deployService = service;
|
|
||||||
}
|
|
||||||
|
|
||||||
AbstractRemoteLinuxDeployStep::~AbstractRemoteLinuxDeployStep()
|
|
||||||
{
|
|
||||||
delete d->deployService;
|
|
||||||
delete d;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AbstractRemoteLinuxDeployStep::fromMap(const QVariantMap &map)
|
bool AbstractRemoteLinuxDeployStep::fromMap(const QVariantMap &map)
|
||||||
{
|
{
|
||||||
if (!BuildStep::fromMap(map))
|
if (!BuildStep::fromMap(map))
|
||||||
return false;
|
return false;
|
||||||
d->deployService->importDeployTimes(map);
|
importDeployTimes(map);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariantMap AbstractRemoteLinuxDeployStep::toMap() const
|
QVariantMap AbstractRemoteLinuxDeployStep::toMap() const
|
||||||
{
|
{
|
||||||
QVariantMap map = BuildStep::toMap();
|
QVariantMap map = BuildStep::toMap();
|
||||||
map.insert(d->deployService->exportDeployTimes());
|
map.insert(exportDeployTimes());
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AbstractRemoteLinuxDeployStep::init()
|
bool AbstractRemoteLinuxDeployStep::init()
|
||||||
{
|
{
|
||||||
d->deployService->setTarget(target());
|
|
||||||
|
|
||||||
QTC_ASSERT(d->internalInit, return false);
|
QTC_ASSERT(d->internalInit, return false);
|
||||||
const CheckResult canDeploy = d->internalInit();
|
const CheckResult canDeploy = d->internalInit();
|
||||||
if (!canDeploy) {
|
if (!canDeploy) {
|
||||||
@@ -209,21 +175,8 @@ void AbstractRemoteLinuxDeployStep::doRun()
|
|||||||
if (d->runPreparer)
|
if (d->runPreparer)
|
||||||
d->runPreparer();
|
d->runPreparer();
|
||||||
|
|
||||||
connect(d->deployService, &AbstractRemoteLinuxDeployService::errorMessage,
|
|
||||||
this, &AbstractRemoteLinuxDeployStep::handleErrorMessage);
|
|
||||||
connect(d->deployService, &AbstractRemoteLinuxDeployService::progressMessage,
|
|
||||||
this, &AbstractRemoteLinuxDeployStep::handleProgressMessage);
|
|
||||||
connect(d->deployService, &AbstractRemoteLinuxDeployService::warningMessage,
|
|
||||||
this, &AbstractRemoteLinuxDeployStep::handleWarningMessage);
|
|
||||||
connect(d->deployService, &AbstractRemoteLinuxDeployService::stdOutData,
|
|
||||||
this, &AbstractRemoteLinuxDeployStep::handleStdOutData);
|
|
||||||
connect(d->deployService, &AbstractRemoteLinuxDeployService::stdErrData,
|
|
||||||
this, &AbstractRemoteLinuxDeployStep::handleStdErrData);
|
|
||||||
connect(d->deployService, &AbstractRemoteLinuxDeployService::finished,
|
|
||||||
this, &AbstractRemoteLinuxDeployStep::handleFinished);
|
|
||||||
|
|
||||||
d->hasError = false;
|
d->hasError = false;
|
||||||
d->deployService->start();
|
start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractRemoteLinuxDeployStep::doCancel()
|
void AbstractRemoteLinuxDeployStep::doCancel()
|
||||||
@@ -234,7 +187,7 @@ void AbstractRemoteLinuxDeployStep::doCancel()
|
|||||||
emit addOutput(Tr::tr("User requests deployment to stop; cleaning up."),
|
emit addOutput(Tr::tr("User requests deployment to stop; cleaning up."),
|
||||||
OutputFormat::NormalMessage);
|
OutputFormat::NormalMessage);
|
||||||
d->hasError = true;
|
d->hasError = true;
|
||||||
d->deployService->stop();
|
stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractRemoteLinuxDeployStep::handleProgressMessage(const QString &message)
|
void AbstractRemoteLinuxDeployStep::handleProgressMessage(const QString &message)
|
||||||
@@ -261,7 +214,6 @@ void AbstractRemoteLinuxDeployStep::handleFinished()
|
|||||||
emit addOutput(Tr::tr("Deploy step failed."), OutputFormat::ErrorMessage);
|
emit addOutput(Tr::tr("Deploy step failed."), OutputFormat::ErrorMessage);
|
||||||
else
|
else
|
||||||
emit addOutput(Tr::tr("Deploy step finished."), OutputFormat::NormalMessage);
|
emit addOutput(Tr::tr("Deploy step finished."), OutputFormat::NormalMessage);
|
||||||
disconnect(d->deployService, nullptr, this, nullptr);
|
|
||||||
emit finished(!d->hasError);
|
emit finished(!d->hasError);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -275,4 +227,14 @@ void AbstractRemoteLinuxDeployStep::handleStdErrData(const QString &data)
|
|||||||
emit addOutput(data, OutputFormat::Stderr, DontAppendNewline);
|
emit addOutput(data, OutputFormat::Stderr, DontAppendNewline);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AbstractRemoteLinuxDeployStep::isDeploymentNecessary() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Tasking::Group AbstractRemoteLinuxDeployStep::deployRecipe()
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace RemoteLinux
|
} // namespace RemoteLinux
|
||||||
|
|||||||
@@ -21,42 +21,9 @@ namespace Utils::Tasking { class Group; }
|
|||||||
|
|
||||||
namespace RemoteLinux {
|
namespace RemoteLinux {
|
||||||
|
|
||||||
class AbstractRemoteLinuxDeployService;
|
|
||||||
class CheckResult;
|
class CheckResult;
|
||||||
|
|
||||||
namespace Internal { class AbstractRemoteLinuxDeployStepPrivate; }
|
namespace Internal { class AbstractRemoteLinuxDeployStepPrivate; }
|
||||||
namespace Internal { class AbstractRemoteLinuxDeployServicePrivate; }
|
|
||||||
|
|
||||||
class REMOTELINUX_EXPORT AbstractRemoteLinuxDeployStep : public ProjectExplorer::BuildStep
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
~AbstractRemoteLinuxDeployStep() override;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
bool fromMap(const QVariantMap &map) override;
|
|
||||||
QVariantMap toMap() const override;
|
|
||||||
bool init() override;
|
|
||||||
void doRun() final;
|
|
||||||
void doCancel() override;
|
|
||||||
|
|
||||||
explicit AbstractRemoteLinuxDeployStep(ProjectExplorer::BuildStepList *bsl, Utils::Id id);
|
|
||||||
|
|
||||||
void setInternalInitializer(const std::function<CheckResult()> &init);
|
|
||||||
void setRunPreparer(const std::function<void()> &prep);
|
|
||||||
void setDeployService(AbstractRemoteLinuxDeployService *service);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void handleProgressMessage(const QString &message);
|
|
||||||
void handleErrorMessage(const QString &message);
|
|
||||||
void handleWarningMessage(const QString &message);
|
|
||||||
void handleFinished();
|
|
||||||
void handleStdOutData(const QString &data);
|
|
||||||
void handleStdErrData(const QString &data);
|
|
||||||
|
|
||||||
Internal::AbstractRemoteLinuxDeployStepPrivate *d;
|
|
||||||
};
|
|
||||||
|
|
||||||
class REMOTELINUX_EXPORT CheckResult
|
class REMOTELINUX_EXPORT CheckResult
|
||||||
{
|
{
|
||||||
@@ -74,21 +41,20 @@ private:
|
|||||||
QString m_error;
|
QString m_error;
|
||||||
};
|
};
|
||||||
|
|
||||||
class REMOTELINUX_EXPORT AbstractRemoteLinuxDeployService : public QObject
|
class REMOTELINUX_EXPORT AbstractRemoteLinuxDeployStep : public ProjectExplorer::BuildStep
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_DISABLE_COPY(AbstractRemoteLinuxDeployService)
|
|
||||||
public:
|
|
||||||
explicit AbstractRemoteLinuxDeployService(QObject *parent = nullptr);
|
|
||||||
~AbstractRemoteLinuxDeployService() override;
|
|
||||||
|
|
||||||
void setTarget(ProjectExplorer::Target *bc);
|
public:
|
||||||
|
explicit AbstractRemoteLinuxDeployStep(ProjectExplorer::BuildStepList *bsl, Utils::Id id);
|
||||||
|
~AbstractRemoteLinuxDeployStep() override;
|
||||||
|
|
||||||
void start();
|
void start();
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
QVariantMap exportDeployTimes() const;
|
QVariantMap exportDeployTimes() const;
|
||||||
void importDeployTimes(const QVariantMap &map);
|
void importDeployTimes(const QVariantMap &map);
|
||||||
|
ProjectExplorer::IDeviceConstPtr deviceConfiguration() const;
|
||||||
|
|
||||||
virtual CheckResult isDeploymentPossible() const;
|
virtual CheckResult isDeploymentPossible() const;
|
||||||
|
|
||||||
@@ -98,12 +64,16 @@ signals:
|
|||||||
void warningMessage(const QString &message);
|
void warningMessage(const QString &message);
|
||||||
void stdOutData(const QString &data);
|
void stdOutData(const QString &data);
|
||||||
void stdErrData(const QString &data);
|
void stdErrData(const QString &data);
|
||||||
void finished(); // Used by Qnx.
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const ProjectExplorer::Target *target() const;
|
bool fromMap(const QVariantMap &map) override;
|
||||||
const ProjectExplorer::Kit *kit() const;
|
QVariantMap toMap() const override;
|
||||||
ProjectExplorer::IDeviceConstPtr deviceConfiguration() const;
|
bool init() override;
|
||||||
|
void doRun() final;
|
||||||
|
void doCancel() override;
|
||||||
|
|
||||||
|
void setInternalInitializer(const std::function<CheckResult()> &init);
|
||||||
|
void setRunPreparer(const std::function<void()> &prep);
|
||||||
|
|
||||||
void saveDeploymentTimeStamp(const ProjectExplorer::DeployableFile &deployableFile,
|
void saveDeploymentTimeStamp(const ProjectExplorer::DeployableFile &deployableFile,
|
||||||
const QDateTime &remoteTimestamp);
|
const QDateTime &remoteTimestamp);
|
||||||
@@ -112,10 +82,17 @@ protected:
|
|||||||
const QDateTime &remoteTimestamp) const;
|
const QDateTime &remoteTimestamp) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual bool isDeploymentNecessary() const = 0;
|
void handleProgressMessage(const QString &message);
|
||||||
virtual Utils::Tasking::Group deployRecipe() = 0;
|
void handleErrorMessage(const QString &message);
|
||||||
|
void handleWarningMessage(const QString &message);
|
||||||
|
void handleFinished();
|
||||||
|
void handleStdOutData(const QString &data);
|
||||||
|
void handleStdErrData(const QString &data);
|
||||||
|
|
||||||
Internal::AbstractRemoteLinuxDeployServicePrivate * const d;
|
virtual bool isDeploymentNecessary() const;
|
||||||
|
virtual Utils::Tasking::Group deployRecipe();
|
||||||
|
|
||||||
|
Internal::AbstractRemoteLinuxDeployStepPrivate *d;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // RemoteLinux
|
} // RemoteLinux
|
||||||
|
|||||||
@@ -19,9 +19,26 @@ using namespace Utils::Tasking;
|
|||||||
|
|
||||||
namespace RemoteLinux::Internal {
|
namespace RemoteLinux::Internal {
|
||||||
|
|
||||||
class CustomCommandDeployService : public AbstractRemoteLinuxDeployService
|
class CustomCommandDeployStep : public AbstractRemoteLinuxDeployStep
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
CustomCommandDeployStep(BuildStepList *bsl, Id id)
|
||||||
|
: AbstractRemoteLinuxDeployStep(bsl, id)
|
||||||
|
{
|
||||||
|
auto commandLine = addAspect<StringAspect>();
|
||||||
|
commandLine->setSettingsKey("RemoteLinuxCustomCommandDeploymentStep.CommandLine");
|
||||||
|
commandLine->setLabelText(Tr::tr("Command line:"));
|
||||||
|
commandLine->setDisplayStyle(StringAspect::LineEditDisplay);
|
||||||
|
commandLine->setHistoryCompleter("RemoteLinuxCustomCommandDeploymentStep.History");
|
||||||
|
|
||||||
|
setInternalInitializer([this, commandLine] {
|
||||||
|
setCommandLine(commandLine->value().trimmed());
|
||||||
|
return isDeploymentPossible();
|
||||||
|
});
|
||||||
|
|
||||||
|
addMacroExpander();
|
||||||
|
}
|
||||||
|
|
||||||
void setCommandLine(const QString &commandLine);
|
void setCommandLine(const QString &commandLine);
|
||||||
CheckResult isDeploymentPossible() const final;
|
CheckResult isDeploymentPossible() const final;
|
||||||
|
|
||||||
@@ -34,20 +51,20 @@ private:
|
|||||||
QString m_commandLine;
|
QString m_commandLine;
|
||||||
};
|
};
|
||||||
|
|
||||||
void CustomCommandDeployService::setCommandLine(const QString &commandLine)
|
void CustomCommandDeployStep::setCommandLine(const QString &commandLine)
|
||||||
{
|
{
|
||||||
m_commandLine = commandLine;
|
m_commandLine = commandLine;
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckResult CustomCommandDeployService::isDeploymentPossible() const
|
CheckResult CustomCommandDeployStep::isDeploymentPossible() const
|
||||||
{
|
{
|
||||||
if (m_commandLine.isEmpty())
|
if (m_commandLine.isEmpty())
|
||||||
return CheckResult::failure(Tr::tr("No command line given."));
|
return CheckResult::failure(Tr::tr("No command line given."));
|
||||||
|
|
||||||
return AbstractRemoteLinuxDeployService::isDeploymentPossible();
|
return AbstractRemoteLinuxDeployStep::isDeploymentPossible();
|
||||||
}
|
}
|
||||||
|
|
||||||
Group CustomCommandDeployService::deployRecipe()
|
Group CustomCommandDeployStep::deployRecipe()
|
||||||
{
|
{
|
||||||
const auto setupHandler = [this](QtcProcess &process) {
|
const auto setupHandler = [this](QtcProcess &process) {
|
||||||
emit progressMessage(Tr::tr("Starting remote command \"%1\"...").arg(m_commandLine));
|
emit progressMessage(Tr::tr("Starting remote command \"%1\"...").arg(m_commandLine));
|
||||||
@@ -76,30 +93,6 @@ Group CustomCommandDeployService::deployRecipe()
|
|||||||
return Group { Process(setupHandler, doneHandler, errorHandler) };
|
return Group { Process(setupHandler, doneHandler, errorHandler) };
|
||||||
}
|
}
|
||||||
|
|
||||||
class CustomCommandDeployStep : public AbstractRemoteLinuxDeployStep
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CustomCommandDeployStep(BuildStepList *bsl, Id id)
|
|
||||||
: AbstractRemoteLinuxDeployStep(bsl, id)
|
|
||||||
{
|
|
||||||
auto service = new CustomCommandDeployService;
|
|
||||||
setDeployService(service);
|
|
||||||
|
|
||||||
auto commandLine = addAspect<StringAspect>();
|
|
||||||
commandLine->setSettingsKey("RemoteLinuxCustomCommandDeploymentStep.CommandLine");
|
|
||||||
commandLine->setLabelText(Tr::tr("Command line:"));
|
|
||||||
commandLine->setDisplayStyle(StringAspect::LineEditDisplay);
|
|
||||||
commandLine->setHistoryCompleter("RemoteLinuxCustomCommandDeploymentStep.History");
|
|
||||||
|
|
||||||
setInternalInitializer([service, commandLine] {
|
|
||||||
service->setCommandLine(commandLine->value().trimmed());
|
|
||||||
return service->isDeploymentPossible();
|
|
||||||
});
|
|
||||||
|
|
||||||
addMacroExpander();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// CustomCommandDeployStepFactory
|
// CustomCommandDeployStepFactory
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ using namespace Utils;
|
|||||||
using namespace Utils::Tasking;
|
using namespace Utils::Tasking;
|
||||||
|
|
||||||
namespace RemoteLinux {
|
namespace RemoteLinux {
|
||||||
namespace Internal {
|
|
||||||
|
|
||||||
const int MaxConcurrentStatCalls = 10;
|
const int MaxConcurrentStatCalls = 10;
|
||||||
|
|
||||||
@@ -36,21 +35,13 @@ struct UploadStorage
|
|||||||
|
|
||||||
enum class IncrementalDeployment { Enabled, Disabled, NotSupported };
|
enum class IncrementalDeployment { Enabled, Disabled, NotSupported };
|
||||||
|
|
||||||
class GenericDirectUploadService : public AbstractRemoteLinuxDeployService
|
class GenericDirectUploadStepPrivate
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GenericDirectUploadService(QObject *parent = nullptr)
|
GenericDirectUploadStepPrivate(GenericDirectUploadStep *parent)
|
||||||
: AbstractRemoteLinuxDeployService(parent)
|
: q(parent)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void setDeployableFiles(const QList<ProjectExplorer::DeployableFile> &deployableFiles);
|
|
||||||
void setIncrementalDeployment(IncrementalDeployment incremental);
|
|
||||||
void setIgnoreMissingFiles(bool ignoreMissingFiles);
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool isDeploymentNecessary() const final;
|
|
||||||
Utils::Tasking::Group deployRecipe() final;
|
|
||||||
|
|
||||||
QDateTime timestampFromStat(const DeployableFile &file, QtcProcess *statProc);
|
QDateTime timestampFromStat(const DeployableFile &file, QtcProcess *statProc);
|
||||||
|
|
||||||
using FilesToStat = std::function<QList<DeployableFile>(UploadStorage *)>;
|
using FilesToStat = std::function<QList<DeployableFile>(UploadStorage *)>;
|
||||||
@@ -64,6 +55,7 @@ private:
|
|||||||
TaskItem chmodTask(const DeployableFile &file);
|
TaskItem chmodTask(const DeployableFile &file);
|
||||||
TaskItem chmodTree(const TreeStorage<UploadStorage> &storage);
|
TaskItem chmodTree(const TreeStorage<UploadStorage> &storage);
|
||||||
|
|
||||||
|
GenericDirectUploadStep *q;
|
||||||
IncrementalDeployment m_incremental = IncrementalDeployment::NotSupported;
|
IncrementalDeployment m_incremental = IncrementalDeployment::NotSupported;
|
||||||
bool m_ignoreMissingFiles = false;
|
bool m_ignoreMissingFiles = false;
|
||||||
mutable QList<DeployableFile> m_deployableFiles;
|
mutable QList<DeployableFile> m_deployableFiles;
|
||||||
@@ -84,37 +76,18 @@ QList<DeployableFile> collectFilesToUpload(const DeployableFile &deployable)
|
|||||||
return collected;
|
return collected;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
bool GenericDirectUploadStep::isDeploymentNecessary() const
|
||||||
|
|
||||||
using namespace Internal;
|
|
||||||
|
|
||||||
void GenericDirectUploadService::setDeployableFiles(const QList<DeployableFile> &deployableFiles)
|
|
||||||
{
|
|
||||||
m_deployableFiles = deployableFiles;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GenericDirectUploadService::setIncrementalDeployment(IncrementalDeployment incremental)
|
|
||||||
{
|
|
||||||
m_incremental = incremental;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GenericDirectUploadService::setIgnoreMissingFiles(bool ignoreMissingFiles)
|
|
||||||
{
|
|
||||||
m_ignoreMissingFiles = ignoreMissingFiles;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GenericDirectUploadService::isDeploymentNecessary() const
|
|
||||||
{
|
{
|
||||||
QList<DeployableFile> collected;
|
QList<DeployableFile> collected;
|
||||||
for (int i = 0; i < m_deployableFiles.count(); ++i)
|
for (int i = 0; i < d->m_deployableFiles.count(); ++i)
|
||||||
collected.append(collectFilesToUpload(m_deployableFiles.at(i)));
|
collected.append(collectFilesToUpload(d->m_deployableFiles.at(i)));
|
||||||
|
|
||||||
QTC_CHECK(collected.size() >= m_deployableFiles.size());
|
QTC_CHECK(collected.size() >= d->m_deployableFiles.size());
|
||||||
m_deployableFiles = collected;
|
d->m_deployableFiles = collected;
|
||||||
return !m_deployableFiles.isEmpty();
|
return !d->m_deployableFiles.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
QDateTime GenericDirectUploadService::timestampFromStat(const DeployableFile &file,
|
QDateTime GenericDirectUploadStepPrivate::timestampFromStat(const DeployableFile &file,
|
||||||
QtcProcess *statProc)
|
QtcProcess *statProc)
|
||||||
{
|
{
|
||||||
bool succeeded = false;
|
bool succeeded = false;
|
||||||
@@ -130,7 +103,7 @@ QDateTime GenericDirectUploadService::timestampFromStat(const DeployableFile &fi
|
|||||||
succeeded = true;
|
succeeded = true;
|
||||||
}
|
}
|
||||||
if (!succeeded) {
|
if (!succeeded) {
|
||||||
emit warningMessage(Tr::tr("Failed to retrieve remote timestamp for file \"%1\". "
|
emit q->warningMessage(Tr::tr("Failed to retrieve remote timestamp for file \"%1\". "
|
||||||
"Incremental deployment will not work. Error message was: %2")
|
"Incremental deployment will not work. Error message was: %2")
|
||||||
.arg(file.remoteFilePath(), error));
|
.arg(file.remoteFilePath(), error));
|
||||||
return {};
|
return {};
|
||||||
@@ -139,30 +112,30 @@ QDateTime GenericDirectUploadService::timestampFromStat(const DeployableFile &fi
|
|||||||
const QString warningString(Tr::tr("Unexpected stat output for remote file \"%1\": %2")
|
const QString warningString(Tr::tr("Unexpected stat output for remote file \"%1\": %2")
|
||||||
.arg(file.remoteFilePath()).arg(QString::fromUtf8(output)));
|
.arg(file.remoteFilePath()).arg(QString::fromUtf8(output)));
|
||||||
if (!output.startsWith(file.remoteFilePath().toUtf8())) {
|
if (!output.startsWith(file.remoteFilePath().toUtf8())) {
|
||||||
emit warningMessage(warningString);
|
emit q->warningMessage(warningString);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
const QByteArrayList columns = output.mid(file.remoteFilePath().toUtf8().size() + 1).split(' ');
|
const QByteArrayList columns = output.mid(file.remoteFilePath().toUtf8().size() + 1).split(' ');
|
||||||
if (columns.size() < 14) { // Normal Linux stat: 16 columns in total, busybox stat: 15 columns
|
if (columns.size() < 14) { // Normal Linux stat: 16 columns in total, busybox stat: 15 columns
|
||||||
emit warningMessage(warningString);
|
emit q->warningMessage(warningString);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
bool isNumber;
|
bool isNumber;
|
||||||
const qint64 secsSinceEpoch = columns.at(11).toLongLong(&isNumber);
|
const qint64 secsSinceEpoch = columns.at(11).toLongLong(&isNumber);
|
||||||
if (!isNumber) {
|
if (!isNumber) {
|
||||||
emit warningMessage(warningString);
|
emit q->warningMessage(warningString);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
return QDateTime::fromSecsSinceEpoch(secsSinceEpoch);
|
return QDateTime::fromSecsSinceEpoch(secsSinceEpoch);
|
||||||
}
|
}
|
||||||
|
|
||||||
TaskItem GenericDirectUploadService::statTask(UploadStorage *storage,
|
TaskItem GenericDirectUploadStepPrivate::statTask(UploadStorage *storage,
|
||||||
const DeployableFile &file,
|
const DeployableFile &file,
|
||||||
StatEndHandler statEndHandler)
|
StatEndHandler statEndHandler)
|
||||||
{
|
{
|
||||||
const auto setupHandler = [=](QtcProcess &process) {
|
const auto setupHandler = [=](QtcProcess &process) {
|
||||||
// We'd like to use --format=%Y, but it's not supported by busybox.
|
// We'd like to use --format=%Y, but it's not supported by busybox.
|
||||||
process.setCommand({deviceConfiguration()->filePath("stat"),
|
process.setCommand({q->deviceConfiguration()->filePath("stat"),
|
||||||
{"-t", Utils::ProcessArgs::quoteArgUnix(file.remoteFilePath())}});
|
{"-t", Utils::ProcessArgs::quoteArgUnix(file.remoteFilePath())}});
|
||||||
};
|
};
|
||||||
const auto endHandler = [=](const QtcProcess &process) {
|
const auto endHandler = [=](const QtcProcess &process) {
|
||||||
@@ -173,7 +146,7 @@ TaskItem GenericDirectUploadService::statTask(UploadStorage *storage,
|
|||||||
return Process(setupHandler, endHandler, endHandler);
|
return Process(setupHandler, endHandler, endHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
TaskItem GenericDirectUploadService::statTree(const TreeStorage<UploadStorage> &storage,
|
TaskItem GenericDirectUploadStepPrivate::statTree(const TreeStorage<UploadStorage> &storage,
|
||||||
FilesToStat filesToStat, StatEndHandler statEndHandler)
|
FilesToStat filesToStat, StatEndHandler statEndHandler)
|
||||||
{
|
{
|
||||||
const auto setupHandler = [=](TaskTree &tree) {
|
const auto setupHandler = [=](TaskTree &tree) {
|
||||||
@@ -189,14 +162,14 @@ TaskItem GenericDirectUploadService::statTree(const TreeStorage<UploadStorage> &
|
|||||||
return Tree(setupHandler);
|
return Tree(setupHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
TaskItem GenericDirectUploadService::uploadTask(const TreeStorage<UploadStorage> &storage)
|
TaskItem GenericDirectUploadStepPrivate::uploadTask(const TreeStorage<UploadStorage> &storage)
|
||||||
{
|
{
|
||||||
const auto setupHandler = [this, storage](FileTransfer &transfer) {
|
const auto setupHandler = [this, storage](FileTransfer &transfer) {
|
||||||
if (storage->filesToUpload.isEmpty()) {
|
if (storage->filesToUpload.isEmpty()) {
|
||||||
emit progressMessage(Tr::tr("No files need to be uploaded."));
|
emit q->progressMessage(Tr::tr("No files need to be uploaded."));
|
||||||
return TaskAction::StopWithDone;
|
return TaskAction::StopWithDone;
|
||||||
}
|
}
|
||||||
emit progressMessage(Tr::tr("%n file(s) need to be uploaded.", "",
|
emit q->progressMessage(Tr::tr("%n file(s) need to be uploaded.", "",
|
||||||
storage->filesToUpload.size()));
|
storage->filesToUpload.size()));
|
||||||
FilesToTransfer files;
|
FilesToTransfer files;
|
||||||
for (const DeployableFile &file : std::as_const(storage->filesToUpload)) {
|
for (const DeployableFile &file : std::as_const(storage->filesToUpload)) {
|
||||||
@@ -204,51 +177,51 @@ TaskItem GenericDirectUploadService::uploadTask(const TreeStorage<UploadStorage>
|
|||||||
const QString message = Tr::tr("Local file \"%1\" does not exist.")
|
const QString message = Tr::tr("Local file \"%1\" does not exist.")
|
||||||
.arg(file.localFilePath().toUserOutput());
|
.arg(file.localFilePath().toUserOutput());
|
||||||
if (m_ignoreMissingFiles) {
|
if (m_ignoreMissingFiles) {
|
||||||
emit warningMessage(message);
|
emit q->warningMessage(message);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
emit errorMessage(message);
|
emit q->errorMessage(message);
|
||||||
return TaskAction::StopWithError;
|
return TaskAction::StopWithError;
|
||||||
}
|
}
|
||||||
files.append({file.localFilePath(),
|
files.append({file.localFilePath(),
|
||||||
deviceConfiguration()->filePath(file.remoteFilePath())});
|
q->deviceConfiguration()->filePath(file.remoteFilePath())});
|
||||||
}
|
}
|
||||||
if (files.isEmpty()) {
|
if (files.isEmpty()) {
|
||||||
emit progressMessage(Tr::tr("No files need to be uploaded."));
|
emit q->progressMessage(Tr::tr("No files need to be uploaded."));
|
||||||
return TaskAction::StopWithDone;
|
return TaskAction::StopWithDone;
|
||||||
}
|
}
|
||||||
transfer.setFilesToTransfer(files);
|
transfer.setFilesToTransfer(files);
|
||||||
QObject::connect(&transfer, &FileTransfer::progress,
|
QObject::connect(&transfer, &FileTransfer::progress,
|
||||||
this, &GenericDirectUploadService::progressMessage);
|
q, &GenericDirectUploadStep::progressMessage);
|
||||||
return TaskAction::Continue;
|
return TaskAction::Continue;
|
||||||
};
|
};
|
||||||
const auto errorHandler = [this](const FileTransfer &transfer) {
|
const auto errorHandler = [this](const FileTransfer &transfer) {
|
||||||
emit errorMessage(transfer.resultData().m_errorString);
|
emit q->errorMessage(transfer.resultData().m_errorString);
|
||||||
};
|
};
|
||||||
|
|
||||||
return Transfer(setupHandler, {}, errorHandler);
|
return Transfer(setupHandler, {}, errorHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
TaskItem GenericDirectUploadService::chmodTask(const DeployableFile &file)
|
TaskItem GenericDirectUploadStepPrivate::chmodTask(const DeployableFile &file)
|
||||||
{
|
{
|
||||||
const auto setupHandler = [=](QtcProcess &process) {
|
const auto setupHandler = [=](QtcProcess &process) {
|
||||||
process.setCommand({deviceConfiguration()->filePath("chmod"),
|
process.setCommand({q->deviceConfiguration()->filePath("chmod"),
|
||||||
{"a+x", Utils::ProcessArgs::quoteArgUnix(file.remoteFilePath())}});
|
{"a+x", Utils::ProcessArgs::quoteArgUnix(file.remoteFilePath())}});
|
||||||
};
|
};
|
||||||
const auto errorHandler = [=](const QtcProcess &process) {
|
const auto errorHandler = [=](const QtcProcess &process) {
|
||||||
const QString error = process.errorString();
|
const QString error = process.errorString();
|
||||||
if (!error.isEmpty()) {
|
if (!error.isEmpty()) {
|
||||||
emit warningMessage(Tr::tr("Remote chmod failed for file \"%1\": %2")
|
emit q->warningMessage(Tr::tr("Remote chmod failed for file \"%1\": %2")
|
||||||
.arg(file.remoteFilePath(), error));
|
.arg(file.remoteFilePath(), error));
|
||||||
} else if (process.exitCode() != 0) {
|
} else if (process.exitCode() != 0) {
|
||||||
emit warningMessage(Tr::tr("Remote chmod failed for file \"%1\": %2")
|
emit q->warningMessage(Tr::tr("Remote chmod failed for file \"%1\": %2")
|
||||||
.arg(file.remoteFilePath(), process.cleanedStdErr()));
|
.arg(file.remoteFilePath(), process.cleanedStdErr()));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return Process(setupHandler, {}, errorHandler);
|
return Process(setupHandler, {}, errorHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
TaskItem GenericDirectUploadService::chmodTree(const TreeStorage<UploadStorage> &storage)
|
TaskItem GenericDirectUploadStepPrivate::chmodTree(const TreeStorage<UploadStorage> &storage)
|
||||||
{
|
{
|
||||||
const auto setupChmodHandler = [=](TaskTree &tree) {
|
const auto setupChmodHandler = [=](TaskTree &tree) {
|
||||||
QList<DeployableFile> filesToChmod;
|
QList<DeployableFile> filesToChmod;
|
||||||
@@ -266,16 +239,16 @@ TaskItem GenericDirectUploadService::chmodTree(const TreeStorage<UploadStorage>
|
|||||||
return Tree(setupChmodHandler);
|
return Tree(setupChmodHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
Group GenericDirectUploadService::deployRecipe()
|
Group GenericDirectUploadStep::deployRecipe()
|
||||||
{
|
{
|
||||||
const auto preFilesToStat = [this](UploadStorage *storage) {
|
const auto preFilesToStat = [this](UploadStorage *storage) {
|
||||||
QList<DeployableFile> filesToStat;
|
QList<DeployableFile> filesToStat;
|
||||||
for (const DeployableFile &file : std::as_const(m_deployableFiles)) {
|
for (const DeployableFile &file : std::as_const(d->m_deployableFiles)) {
|
||||||
if (m_incremental != IncrementalDeployment::Enabled || hasLocalFileChanged(file)) {
|
if (d->m_incremental != IncrementalDeployment::Enabled || hasLocalFileChanged(file)) {
|
||||||
storage->filesToUpload.append(file);
|
storage->filesToUpload.append(file);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (m_incremental == IncrementalDeployment::NotSupported)
|
if (d->m_incremental == IncrementalDeployment::NotSupported)
|
||||||
continue;
|
continue;
|
||||||
filesToStat << file;
|
filesToStat << file;
|
||||||
}
|
}
|
||||||
@@ -288,7 +261,7 @@ Group GenericDirectUploadService::deployRecipe()
|
|||||||
};
|
};
|
||||||
|
|
||||||
const auto postFilesToStat = [this](UploadStorage *storage) {
|
const auto postFilesToStat = [this](UploadStorage *storage) {
|
||||||
return m_incremental == IncrementalDeployment::NotSupported
|
return d->m_incremental == IncrementalDeployment::NotSupported
|
||||||
? QList<DeployableFile>() : storage->filesToUpload;
|
? QList<DeployableFile>() : storage->filesToUpload;
|
||||||
};
|
};
|
||||||
const auto postStatEndHandler = [this](UploadStorage *storage, const DeployableFile &file,
|
const auto postStatEndHandler = [this](UploadStorage *storage, const DeployableFile &file,
|
||||||
@@ -304,11 +277,11 @@ Group GenericDirectUploadService::deployRecipe()
|
|||||||
const TreeStorage<UploadStorage> storage;
|
const TreeStorage<UploadStorage> storage;
|
||||||
const Group root {
|
const Group root {
|
||||||
Storage(storage),
|
Storage(storage),
|
||||||
statTree(storage, preFilesToStat, preStatEndHandler),
|
d->statTree(storage, preFilesToStat, preStatEndHandler),
|
||||||
uploadTask(storage),
|
d->uploadTask(storage),
|
||||||
Group {
|
Group {
|
||||||
chmodTree(storage),
|
d->chmodTree(storage),
|
||||||
statTree(storage, postFilesToStat, postStatEndHandler)
|
d->statTree(storage, postFilesToStat, postStatEndHandler)
|
||||||
},
|
},
|
||||||
OnGroupDone(doneHandler)
|
OnGroupDone(doneHandler)
|
||||||
};
|
};
|
||||||
@@ -317,11 +290,9 @@ Group GenericDirectUploadService::deployRecipe()
|
|||||||
|
|
||||||
GenericDirectUploadStep::GenericDirectUploadStep(BuildStepList *bsl, Utils::Id id,
|
GenericDirectUploadStep::GenericDirectUploadStep(BuildStepList *bsl, Utils::Id id,
|
||||||
bool offerIncrementalDeployment)
|
bool offerIncrementalDeployment)
|
||||||
: AbstractRemoteLinuxDeployStep(bsl, id)
|
: AbstractRemoteLinuxDeployStep(bsl, id),
|
||||||
|
d(new GenericDirectUploadStepPrivate(this))
|
||||||
{
|
{
|
||||||
auto service = new GenericDirectUploadService;
|
|
||||||
setDeployService(service);
|
|
||||||
|
|
||||||
BoolAspect *incremental = nullptr;
|
BoolAspect *incremental = nullptr;
|
||||||
if (offerIncrementalDeployment) {
|
if (offerIncrementalDeployment) {
|
||||||
incremental = addAspect<BoolAspect>();
|
incremental = addAspect<BoolAspect>();
|
||||||
@@ -338,23 +309,26 @@ GenericDirectUploadStep::GenericDirectUploadStep(BuildStepList *bsl, Utils::Id i
|
|||||||
BoolAspect::LabelPlacement::AtCheckBox);
|
BoolAspect::LabelPlacement::AtCheckBox);
|
||||||
ignoreMissingFiles->setValue(false);
|
ignoreMissingFiles->setValue(false);
|
||||||
|
|
||||||
setInternalInitializer([incremental, ignoreMissingFiles, service] {
|
setInternalInitializer([this, incremental, ignoreMissingFiles] {
|
||||||
if (incremental) {
|
if (incremental) {
|
||||||
service->setIncrementalDeployment(incremental->value()
|
d->m_incremental = incremental->value()
|
||||||
? IncrementalDeployment::Enabled : IncrementalDeployment::Disabled);
|
? IncrementalDeployment::Enabled : IncrementalDeployment::Disabled;
|
||||||
} else {
|
} else {
|
||||||
service->setIncrementalDeployment(IncrementalDeployment::NotSupported);
|
d->m_incremental = IncrementalDeployment::NotSupported;
|
||||||
}
|
}
|
||||||
service->setIgnoreMissingFiles(ignoreMissingFiles->value());
|
d->m_ignoreMissingFiles = ignoreMissingFiles->value();
|
||||||
return service->isDeploymentPossible();
|
return isDeploymentPossible();
|
||||||
});
|
});
|
||||||
|
|
||||||
setRunPreparer([this, service] {
|
setRunPreparer([this] {
|
||||||
service->setDeployableFiles(target()->deploymentData().allFiles());
|
d->m_deployableFiles = target()->deploymentData().allFiles();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
GenericDirectUploadStep::~GenericDirectUploadStep() = default;
|
GenericDirectUploadStep::~GenericDirectUploadStep()
|
||||||
|
{
|
||||||
|
delete d;
|
||||||
|
}
|
||||||
|
|
||||||
Utils::Id GenericDirectUploadStep::stepId()
|
Utils::Id GenericDirectUploadStep::stepId()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -18,8 +18,14 @@ public:
|
|||||||
bool offerIncrementalDeployment = true);
|
bool offerIncrementalDeployment = true);
|
||||||
~GenericDirectUploadStep() override;
|
~GenericDirectUploadStep() override;
|
||||||
|
|
||||||
|
bool isDeploymentNecessary() const final;
|
||||||
|
Utils::Tasking::Group deployRecipe() final;
|
||||||
|
|
||||||
static Utils::Id stepId();
|
static Utils::Id stepId();
|
||||||
static QString displayName();
|
static QString displayName();
|
||||||
|
|
||||||
|
private:
|
||||||
|
class GenericDirectUploadStepPrivate *d;
|
||||||
};
|
};
|
||||||
|
|
||||||
} //namespace RemoteLinux
|
} // RemoteLinux
|
||||||
|
|||||||
@@ -20,10 +20,21 @@ using namespace Utils::Tasking;
|
|||||||
|
|
||||||
namespace RemoteLinux::Internal {
|
namespace RemoteLinux::Internal {
|
||||||
|
|
||||||
class KillAppService : public AbstractRemoteLinuxDeployService
|
class KillAppStep : public AbstractRemoteLinuxDeployStep
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void setRemoteExecutable(const FilePath &filePath) { m_remoteExecutable = filePath; }
|
KillAppStep(BuildStepList *bsl, Id id) : AbstractRemoteLinuxDeployStep(bsl, id)
|
||||||
|
{
|
||||||
|
setWidgetExpandedByDefault(false);
|
||||||
|
|
||||||
|
setInternalInitializer([this] {
|
||||||
|
Target * const theTarget = target();
|
||||||
|
QTC_ASSERT(theTarget, return CheckResult::failure());
|
||||||
|
RunConfiguration * const rc = theTarget->activeRunConfiguration();
|
||||||
|
m_remoteExecutable = rc ? rc->runnable().command.executable() : FilePath();
|
||||||
|
return CheckResult::success();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool isDeploymentNecessary() const final { return !m_remoteExecutable.isEmpty(); }
|
bool isDeploymentNecessary() const final { return !m_remoteExecutable.isEmpty(); }
|
||||||
@@ -32,7 +43,7 @@ private:
|
|||||||
FilePath m_remoteExecutable;
|
FilePath m_remoteExecutable;
|
||||||
};
|
};
|
||||||
|
|
||||||
Group KillAppService::deployRecipe()
|
Group KillAppStep::deployRecipe()
|
||||||
{
|
{
|
||||||
const auto setupHandler = [this](DeviceProcessKiller &killer) {
|
const auto setupHandler = [this](DeviceProcessKiller &killer) {
|
||||||
killer.setProcessPath(m_remoteExecutable);
|
killer.setProcessPath(m_remoteExecutable);
|
||||||
@@ -49,27 +60,6 @@ Group KillAppService::deployRecipe()
|
|||||||
return Group { Killer(setupHandler, doneHandler, errorHandler) };
|
return Group { Killer(setupHandler, doneHandler, errorHandler) };
|
||||||
}
|
}
|
||||||
|
|
||||||
class KillAppStep : public AbstractRemoteLinuxDeployStep
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
KillAppStep(BuildStepList *bsl, Id id) : AbstractRemoteLinuxDeployStep(bsl, id)
|
|
||||||
{
|
|
||||||
auto service = new Internal::KillAppService;
|
|
||||||
setDeployService(service);
|
|
||||||
|
|
||||||
setWidgetExpandedByDefault(false);
|
|
||||||
|
|
||||||
setInternalInitializer([this, service] {
|
|
||||||
Target * const theTarget = target();
|
|
||||||
QTC_ASSERT(theTarget, return CheckResult::failure());
|
|
||||||
RunConfiguration * const rc = theTarget->activeRunConfiguration();
|
|
||||||
const FilePath remoteExe = rc ? rc->runnable().command.executable() : FilePath();
|
|
||||||
service->setRemoteExecutable(remoteExe);
|
|
||||||
return CheckResult::success();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
KillAppStepFactory::KillAppStepFactory()
|
KillAppStepFactory::KillAppStepFactory()
|
||||||
{
|
{
|
||||||
registerStep<KillAppStep>(Constants::KillAppStepId);
|
registerStep<KillAppStep>(Constants::KillAppStepId);
|
||||||
|
|||||||
@@ -25,39 +25,57 @@ using namespace Utils::Tasking;
|
|||||||
|
|
||||||
namespace RemoteLinux {
|
namespace RemoteLinux {
|
||||||
|
|
||||||
class RsyncDeployService : public AbstractRemoteLinuxDeployService
|
// RsyncDeployStep
|
||||||
|
|
||||||
|
RsyncDeployStep::RsyncDeployStep(BuildStepList *bsl, Id id)
|
||||||
|
: AbstractRemoteLinuxDeployStep(bsl, id)
|
||||||
{
|
{
|
||||||
public:
|
auto flags = addAspect<StringAspect>();
|
||||||
void setDeployableFiles(const QList<DeployableFile> &files);
|
flags->setDisplayStyle(StringAspect::LineEditDisplay);
|
||||||
void setIgnoreMissingFiles(bool ignore) { m_ignoreMissingFiles = ignore; }
|
flags->setSettingsKey("RemoteLinux.RsyncDeployStep.Flags");
|
||||||
void setFlags(const QString &flags) { m_flags = flags; }
|
flags->setLabelText(Tr::tr("Flags:"));
|
||||||
|
flags->setValue(FileTransferSetupData::defaultRsyncFlags());
|
||||||
|
|
||||||
private:
|
auto ignoreMissingFiles = addAspect<BoolAspect>();
|
||||||
bool isDeploymentNecessary() const final;
|
ignoreMissingFiles->setSettingsKey("RemoteLinux.RsyncDeployStep.IgnoreMissingFiles");
|
||||||
Group deployRecipe() final;
|
ignoreMissingFiles->setLabel(Tr::tr("Ignore missing files:"),
|
||||||
TaskItem mkdirTask();
|
BoolAspect::LabelPlacement::InExtraLabel);
|
||||||
TaskItem transferTask();
|
ignoreMissingFiles->setValue(false);
|
||||||
|
|
||||||
mutable FilesToTransfer m_files;
|
setInternalInitializer([this, ignoreMissingFiles, flags] {
|
||||||
bool m_ignoreMissingFiles = false;
|
if (BuildDeviceKitAspect::device(kit()) == DeviceKitAspect::device(kit())) {
|
||||||
QString m_flags;
|
// rsync transfer on the same device currently not implemented
|
||||||
};
|
// and typically not wanted.
|
||||||
|
return CheckResult::failure(
|
||||||
|
Tr::tr("rsync is only supported for transfers between different devices."));
|
||||||
|
}
|
||||||
|
setIgnoreMissingFiles(ignoreMissingFiles->value());
|
||||||
|
setFlags(flags->value());
|
||||||
|
return isDeploymentPossible();
|
||||||
|
});
|
||||||
|
|
||||||
void RsyncDeployService::setDeployableFiles(const QList<DeployableFile> &files)
|
setRunPreparer([this] {
|
||||||
|
setDeployableFiles(target()->deploymentData().allFiles());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
RsyncDeployStep::~RsyncDeployStep() = default;
|
||||||
|
|
||||||
|
void RsyncDeployStep::setDeployableFiles(const QList<DeployableFile> &files)
|
||||||
{
|
{
|
||||||
m_files.clear();
|
m_files.clear();
|
||||||
for (const DeployableFile &f : files)
|
for (const DeployableFile &f : files)
|
||||||
m_files.append({f.localFilePath(), deviceConfiguration()->filePath(f.remoteFilePath())});
|
m_files.append({f.localFilePath(), deviceConfiguration()->filePath(f.remoteFilePath())});
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RsyncDeployService::isDeploymentNecessary() const
|
bool RsyncDeployStep::isDeploymentNecessary() const
|
||||||
{
|
{
|
||||||
if (m_ignoreMissingFiles)
|
if (m_ignoreMissingFiles)
|
||||||
Utils::erase(m_files, [](const FileToTransfer &file) { return !file.m_source.exists(); });
|
Utils::erase(m_files, [](const FileToTransfer &file) { return !file.m_source.exists(); });
|
||||||
return !m_files.empty();
|
return !m_files.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
TaskItem RsyncDeployService::mkdirTask()
|
TaskItem RsyncDeployStep::mkdirTask()
|
||||||
{
|
{
|
||||||
const auto setupHandler = [this](QtcProcess &process) {
|
const auto setupHandler = [this](QtcProcess &process) {
|
||||||
QStringList remoteDirs;
|
QStringList remoteDirs;
|
||||||
@@ -85,14 +103,14 @@ TaskItem RsyncDeployService::mkdirTask()
|
|||||||
return Process(setupHandler, {}, errorHandler);
|
return Process(setupHandler, {}, errorHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
TaskItem RsyncDeployService::transferTask()
|
TaskItem RsyncDeployStep::transferTask()
|
||||||
{
|
{
|
||||||
const auto setupHandler = [this](FileTransfer &transfer) {
|
const auto setupHandler = [this](FileTransfer &transfer) {
|
||||||
transfer.setTransferMethod(FileTransferMethod::Rsync);
|
transfer.setTransferMethod(FileTransferMethod::Rsync);
|
||||||
transfer.setRsyncFlags(m_flags);
|
transfer.setRsyncFlags(m_flags);
|
||||||
transfer.setFilesToTransfer(m_files);
|
transfer.setFilesToTransfer(m_files);
|
||||||
connect(&transfer, &FileTransfer::progress,
|
connect(&transfer, &FileTransfer::progress,
|
||||||
this, &AbstractRemoteLinuxDeployService::stdOutData);
|
this, &AbstractRemoteLinuxDeployStep::stdOutData);
|
||||||
};
|
};
|
||||||
const auto errorHandler = [this](const FileTransfer &transfer) {
|
const auto errorHandler = [this](const FileTransfer &transfer) {
|
||||||
const ProcessResultData result = transfer.resultData();
|
const ProcessResultData result = transfer.resultData();
|
||||||
@@ -108,50 +126,11 @@ TaskItem RsyncDeployService::transferTask()
|
|||||||
return Transfer(setupHandler, {}, errorHandler);
|
return Transfer(setupHandler, {}, errorHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
Group RsyncDeployService::deployRecipe()
|
Group RsyncDeployStep::deployRecipe()
|
||||||
{
|
{
|
||||||
return Group { mkdirTask(), transferTask() };
|
return Group { mkdirTask(), transferTask() };
|
||||||
}
|
}
|
||||||
|
|
||||||
// RsyncDeployStep
|
|
||||||
|
|
||||||
RsyncDeployStep::RsyncDeployStep(BuildStepList *bsl, Id id)
|
|
||||||
: AbstractRemoteLinuxDeployStep(bsl, id)
|
|
||||||
{
|
|
||||||
auto service = new RsyncDeployService;
|
|
||||||
setDeployService(service);
|
|
||||||
|
|
||||||
auto flags = addAspect<StringAspect>();
|
|
||||||
flags->setDisplayStyle(StringAspect::LineEditDisplay);
|
|
||||||
flags->setSettingsKey("RemoteLinux.RsyncDeployStep.Flags");
|
|
||||||
flags->setLabelText(Tr::tr("Flags:"));
|
|
||||||
flags->setValue(FileTransferSetupData::defaultRsyncFlags());
|
|
||||||
|
|
||||||
auto ignoreMissingFiles = addAspect<BoolAspect>();
|
|
||||||
ignoreMissingFiles->setSettingsKey("RemoteLinux.RsyncDeployStep.IgnoreMissingFiles");
|
|
||||||
ignoreMissingFiles->setLabel(Tr::tr("Ignore missing files:"),
|
|
||||||
BoolAspect::LabelPlacement::InExtraLabel);
|
|
||||||
ignoreMissingFiles->setValue(false);
|
|
||||||
|
|
||||||
setInternalInitializer([this, service, flags, ignoreMissingFiles] {
|
|
||||||
if (BuildDeviceKitAspect::device(kit()) == DeviceKitAspect::device(kit())) {
|
|
||||||
// rsync transfer on the same device currently not implemented
|
|
||||||
// and typically not wanted.
|
|
||||||
return CheckResult::failure(
|
|
||||||
Tr::tr("rsync is only supported for transfers between different devices."));
|
|
||||||
}
|
|
||||||
service->setIgnoreMissingFiles(ignoreMissingFiles->value());
|
|
||||||
service->setFlags(flags->value());
|
|
||||||
return service->isDeploymentPossible();
|
|
||||||
});
|
|
||||||
|
|
||||||
setRunPreparer([this, service] {
|
|
||||||
service->setDeployableFiles(target()->deploymentData().allFiles());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
RsyncDeployStep::~RsyncDeployStep() = default;
|
|
||||||
|
|
||||||
Utils::Id RsyncDeployStep::stepId()
|
Utils::Id RsyncDeployStep::stepId()
|
||||||
{
|
{
|
||||||
return Constants::RsyncDeployStepId;
|
return Constants::RsyncDeployStepId;
|
||||||
|
|||||||
@@ -7,6 +7,10 @@
|
|||||||
|
|
||||||
#include "abstractremotelinuxdeploystep.h"
|
#include "abstractremotelinuxdeploystep.h"
|
||||||
|
|
||||||
|
#include <projectexplorer/devicesupport/filetransfer.h>
|
||||||
|
|
||||||
|
#include <utils/tasktree.h>
|
||||||
|
|
||||||
namespace RemoteLinux {
|
namespace RemoteLinux {
|
||||||
|
|
||||||
class REMOTELINUX_EXPORT RsyncDeployStep : public AbstractRemoteLinuxDeployStep
|
class REMOTELINUX_EXPORT RsyncDeployStep : public AbstractRemoteLinuxDeployStep
|
||||||
@@ -17,6 +21,20 @@ public:
|
|||||||
|
|
||||||
static Utils::Id stepId();
|
static Utils::Id stepId();
|
||||||
static QString displayName();
|
static QString displayName();
|
||||||
|
|
||||||
|
void setDeployableFiles(const QList<ProjectExplorer::DeployableFile> &files);
|
||||||
|
void setIgnoreMissingFiles(bool ignore) { m_ignoreMissingFiles = ignore; }
|
||||||
|
void setFlags(const QString &flags) { m_flags = flags; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool isDeploymentNecessary() const final;
|
||||||
|
Utils::Tasking::Group deployRecipe() final;
|
||||||
|
Utils::Tasking::TaskItem mkdirTask();
|
||||||
|
Utils::Tasking::TaskItem transferTask();
|
||||||
|
|
||||||
|
mutable ProjectExplorer::FilesToTransfer m_files;
|
||||||
|
bool m_ignoreMissingFiles = false;
|
||||||
|
QString m_flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace RemoteLinux
|
} // namespace RemoteLinux
|
||||||
|
|||||||
@@ -21,9 +21,36 @@ using namespace Utils::Tasking;
|
|||||||
|
|
||||||
namespace RemoteLinux::Internal {
|
namespace RemoteLinux::Internal {
|
||||||
|
|
||||||
class TarPackageDeployService : public AbstractRemoteLinuxDeployService
|
// TarPackageDeployStep
|
||||||
|
|
||||||
|
class TarPackageDeployStep : public AbstractRemoteLinuxDeployStep
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
TarPackageDeployStep(BuildStepList *bsl, Id id)
|
||||||
|
: AbstractRemoteLinuxDeployStep(bsl, id)
|
||||||
|
{
|
||||||
|
setWidgetExpandedByDefault(false);
|
||||||
|
|
||||||
|
setInternalInitializer([this] {
|
||||||
|
const BuildStep *tarCreationStep = nullptr;
|
||||||
|
|
||||||
|
for (BuildStep *step : deployConfiguration()->stepList()->steps()) {
|
||||||
|
if (step == this)
|
||||||
|
break;
|
||||||
|
if (step->id() == Constants::TarPackageCreationStepId) {
|
||||||
|
tarCreationStep = step;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!tarCreationStep)
|
||||||
|
return CheckResult::failure(Tr::tr("No tarball creation step found."));
|
||||||
|
|
||||||
|
const FilePath tarFile =
|
||||||
|
FilePath::fromVariant(tarCreationStep->data(Constants::TarPackageFilePathId));
|
||||||
|
setPackageFilePath(tarFile);
|
||||||
|
return isDeploymentPossible();
|
||||||
|
});
|
||||||
|
}
|
||||||
void setPackageFilePath(const FilePath &filePath);
|
void setPackageFilePath(const FilePath &filePath);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -36,29 +63,28 @@ private:
|
|||||||
FilePath m_packageFilePath;
|
FilePath m_packageFilePath;
|
||||||
};
|
};
|
||||||
|
|
||||||
void TarPackageDeployService::setPackageFilePath(const FilePath &filePath)
|
void TarPackageDeployStep::setPackageFilePath(const FilePath &filePath)
|
||||||
{
|
{
|
||||||
m_packageFilePath = filePath;
|
m_packageFilePath = filePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString TarPackageDeployService::remoteFilePath() const
|
QString TarPackageDeployStep::remoteFilePath() const
|
||||||
{
|
{
|
||||||
return QLatin1String("/tmp/") + m_packageFilePath.fileName();
|
return QLatin1String("/tmp/") + m_packageFilePath.fileName();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TarPackageDeployService::isDeploymentNecessary() const
|
bool TarPackageDeployStep::isDeploymentNecessary() const
|
||||||
{
|
{
|
||||||
return hasLocalFileChanged(DeployableFile(m_packageFilePath, {}));
|
return hasLocalFileChanged(DeployableFile(m_packageFilePath, {}));
|
||||||
}
|
}
|
||||||
|
|
||||||
TaskItem TarPackageDeployService::uploadTask()
|
TaskItem TarPackageDeployStep::uploadTask()
|
||||||
{
|
{
|
||||||
const auto setupHandler = [this](FileTransfer &transfer) {
|
const auto setupHandler = [this](FileTransfer &transfer) {
|
||||||
const FilesToTransfer files {{m_packageFilePath,
|
const FilesToTransfer files {{m_packageFilePath,
|
||||||
deviceConfiguration()->filePath(remoteFilePath())}};
|
deviceConfiguration()->filePath(remoteFilePath())}};
|
||||||
transfer.setFilesToTransfer(files);
|
transfer.setFilesToTransfer(files);
|
||||||
connect(&transfer, &FileTransfer::progress,
|
connect(&transfer, &FileTransfer::progress, this, &TarPackageDeployStep::progressMessage);
|
||||||
this, &TarPackageDeployService::progressMessage);
|
|
||||||
emit progressMessage(Tr::tr("Uploading package to device..."));
|
emit progressMessage(Tr::tr("Uploading package to device..."));
|
||||||
};
|
};
|
||||||
const auto doneHandler = [this](const FileTransfer &) {
|
const auto doneHandler = [this](const FileTransfer &) {
|
||||||
@@ -71,7 +97,7 @@ TaskItem TarPackageDeployService::uploadTask()
|
|||||||
return Transfer(setupHandler, doneHandler, errorHandler);
|
return Transfer(setupHandler, doneHandler, errorHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
TaskItem TarPackageDeployService::installTask()
|
TaskItem TarPackageDeployStep::installTask()
|
||||||
{
|
{
|
||||||
const auto setupHandler = [this](QtcProcess &process) {
|
const auto setupHandler = [this](QtcProcess &process) {
|
||||||
const QString cmdLine = QLatin1String("cd / && tar xvf ") + remoteFilePath()
|
const QString cmdLine = QLatin1String("cd / && tar xvf ") + remoteFilePath()
|
||||||
@@ -96,46 +122,11 @@ TaskItem TarPackageDeployService::installTask()
|
|||||||
return Process(setupHandler, doneHandler, errorHandler);
|
return Process(setupHandler, doneHandler, errorHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
Group TarPackageDeployService::deployRecipe()
|
Group TarPackageDeployStep::deployRecipe()
|
||||||
{
|
{
|
||||||
return Group { uploadTask(), installTask() };
|
return Group { uploadTask(), installTask() };
|
||||||
}
|
}
|
||||||
|
|
||||||
// TarPackageDeployStep
|
|
||||||
|
|
||||||
class TarPackageDeployStep : public AbstractRemoteLinuxDeployStep
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
TarPackageDeployStep(BuildStepList *bsl, Id id)
|
|
||||||
: AbstractRemoteLinuxDeployStep(bsl, id)
|
|
||||||
{
|
|
||||||
auto service = new TarPackageDeployService;
|
|
||||||
setDeployService(service);
|
|
||||||
|
|
||||||
setWidgetExpandedByDefault(false);
|
|
||||||
|
|
||||||
setInternalInitializer([this, service] {
|
|
||||||
const BuildStep *tarCreationStep = nullptr;
|
|
||||||
|
|
||||||
for (BuildStep *step : deployConfiguration()->stepList()->steps()) {
|
|
||||||
if (step == this)
|
|
||||||
break;
|
|
||||||
if (step->id() == Constants::TarPackageCreationStepId) {
|
|
||||||
tarCreationStep = step;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!tarCreationStep)
|
|
||||||
return CheckResult::failure(Tr::tr("No tarball creation step found."));
|
|
||||||
|
|
||||||
const FilePath tarFile =
|
|
||||||
FilePath::fromVariant(tarCreationStep->data(Constants::TarPackageFilePathId));
|
|
||||||
service->setPackageFilePath(tarFile);
|
|
||||||
return service->isDeploymentPossible();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// TarPackageDeployStepFactory
|
// TarPackageDeployStepFactory
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user