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 {
|
||||
|
||||
// QdbMakeDefaultAppService
|
||||
|
||||
class QdbMakeDefaultAppService : public RemoteLinux::AbstractRemoteLinuxDeployService
|
||||
class QdbMakeDefaultAppStep final : public RemoteLinux::AbstractRemoteLinuxDeployStep
|
||||
{
|
||||
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:
|
||||
bool isDeploymentNecessary() const final { return true; }
|
||||
@@ -66,30 +76,6 @@ private:
|
||||
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()
|
||||
|
||||
@@ -21,16 +21,24 @@ using namespace Utils::Tasking;
|
||||
|
||||
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; }
|
||||
Group deployRecipe() final;
|
||||
};
|
||||
|
||||
Group QdbStopApplicationService::deployRecipe()
|
||||
Group QdbStopApplicationStep::deployRecipe()
|
||||
{
|
||||
const auto setupHandler = [this](QtcProcess &process) {
|
||||
const auto device = DeviceKitAspect::device(target()->kit());
|
||||
@@ -67,24 +75,6 @@ Group QdbStopApplicationService::deployRecipe()
|
||||
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()
|
||||
|
||||
@@ -24,137 +24,116 @@ using namespace Utils;
|
||||
namespace RemoteLinux {
|
||||
namespace Internal {
|
||||
|
||||
class AbstractRemoteLinuxDeployServicePrivate
|
||||
{
|
||||
public:
|
||||
IDevice::ConstPtr deviceConfiguration;
|
||||
QPointer<Target> target;
|
||||
|
||||
DeploymentTimeInfo deployTimes;
|
||||
std::unique_ptr<TaskTree> m_taskTree;
|
||||
};
|
||||
|
||||
class AbstractRemoteLinuxDeployStepPrivate
|
||||
{
|
||||
public:
|
||||
bool hasError;
|
||||
std::function<CheckResult()> internalInit;
|
||||
std::function<void()> runPreparer;
|
||||
AbstractRemoteLinuxDeployService *deployService = nullptr;
|
||||
|
||||
DeploymentTimeInfo deployTimes;
|
||||
std::unique_ptr<TaskTree> m_taskTree;
|
||||
};
|
||||
|
||||
} // Internal
|
||||
|
||||
using namespace Internal;
|
||||
|
||||
AbstractRemoteLinuxDeployService::AbstractRemoteLinuxDeployService(QObject *parent)
|
||||
: QObject(parent), d(new AbstractRemoteLinuxDeployServicePrivate)
|
||||
AbstractRemoteLinuxDeployStep::AbstractRemoteLinuxDeployStep(BuildStepList *bsl, Id id)
|
||||
: 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;
|
||||
}
|
||||
|
||||
const Target *AbstractRemoteLinuxDeployService::target() const
|
||||
IDevice::ConstPtr AbstractRemoteLinuxDeployStep::deviceConfiguration() const
|
||||
{
|
||||
return d->target;
|
||||
return DeviceKitAspect::device(kit());
|
||||
}
|
||||
|
||||
const Kit *AbstractRemoteLinuxDeployService::kit() const
|
||||
{
|
||||
return d->target ? d->target->kit() : nullptr;
|
||||
}
|
||||
|
||||
IDevice::ConstPtr AbstractRemoteLinuxDeployService::deviceConfiguration() const
|
||||
{
|
||||
return d->deviceConfiguration;
|
||||
}
|
||||
|
||||
void AbstractRemoteLinuxDeployService::saveDeploymentTimeStamp(const DeployableFile &deployableFile,
|
||||
void AbstractRemoteLinuxDeployStep::saveDeploymentTimeStamp(const DeployableFile &deployableFile,
|
||||
const QDateTime &remoteTimestamp)
|
||||
{
|
||||
d->deployTimes.saveDeploymentTimeStamp(deployableFile, kit(), remoteTimestamp);
|
||||
}
|
||||
|
||||
bool AbstractRemoteLinuxDeployService::hasLocalFileChanged(
|
||||
bool AbstractRemoteLinuxDeployStep::hasLocalFileChanged(
|
||||
const DeployableFile &deployableFile) const
|
||||
{
|
||||
return d->deployTimes.hasLocalFileChanged(deployableFile, kit());
|
||||
}
|
||||
|
||||
bool AbstractRemoteLinuxDeployService::hasRemoteFileChanged(
|
||||
bool AbstractRemoteLinuxDeployStep::hasRemoteFileChanged(
|
||||
const DeployableFile &deployableFile, const QDateTime &remoteTimestamp) const
|
||||
{
|
||||
return d->deployTimes.hasRemoteFileChanged(deployableFile, kit(), remoteTimestamp);
|
||||
}
|
||||
|
||||
void AbstractRemoteLinuxDeployService::setTarget(Target *target)
|
||||
{
|
||||
d->target = target;
|
||||
d->deviceConfiguration = DeviceKitAspect::device(kit());
|
||||
}
|
||||
|
||||
void AbstractRemoteLinuxDeployService::start()
|
||||
void AbstractRemoteLinuxDeployStep::start()
|
||||
{
|
||||
QTC_ASSERT(!d->m_taskTree, return);
|
||||
|
||||
const CheckResult check = isDeploymentPossible();
|
||||
if (!check) {
|
||||
emit errorMessage(check.errorMessage());
|
||||
emit finished();
|
||||
handleFinished();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isDeploymentNecessary()) {
|
||||
emit progressMessage(Tr::tr("No deployment action necessary. Skipping."));
|
||||
emit finished();
|
||||
handleFinished();
|
||||
return;
|
||||
}
|
||||
|
||||
d->m_taskTree.reset(new TaskTree(deployRecipe()));
|
||||
const auto endHandler = [this] {
|
||||
d->m_taskTree.release()->deleteLater();
|
||||
emit finished();
|
||||
handleFinished();
|
||||
};
|
||||
connect(d->m_taskTree.get(), &TaskTree::done, this, endHandler);
|
||||
connect(d->m_taskTree.get(), &TaskTree::errorOccurred, this, endHandler);
|
||||
d->m_taskTree->start();
|
||||
}
|
||||
|
||||
void AbstractRemoteLinuxDeployService::stop()
|
||||
void AbstractRemoteLinuxDeployStep::stop()
|
||||
{
|
||||
if (!d->m_taskTree)
|
||||
return;
|
||||
d->m_taskTree.reset();
|
||||
emit finished();
|
||||
handleFinished();
|
||||
}
|
||||
|
||||
CheckResult AbstractRemoteLinuxDeployService::isDeploymentPossible() const
|
||||
CheckResult AbstractRemoteLinuxDeployStep::isDeploymentPossible() const
|
||||
{
|
||||
if (!deviceConfiguration())
|
||||
return CheckResult::failure(Tr::tr("No device configuration set."));
|
||||
return CheckResult::success();
|
||||
}
|
||||
|
||||
QVariantMap AbstractRemoteLinuxDeployService::exportDeployTimes() const
|
||||
QVariantMap AbstractRemoteLinuxDeployStep::exportDeployTimes() const
|
||||
{
|
||||
return d->deployTimes.exportDeployTimes();
|
||||
}
|
||||
|
||||
void AbstractRemoteLinuxDeployService::importDeployTimes(const QVariantMap &map)
|
||||
void AbstractRemoteLinuxDeployStep::importDeployTimes(const QVariantMap &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)
|
||||
{
|
||||
d->internalInit = init;
|
||||
@@ -165,36 +144,23 @@ void AbstractRemoteLinuxDeployStep::setRunPreparer(const std::function<void ()>
|
||||
d->runPreparer = prep;
|
||||
}
|
||||
|
||||
void AbstractRemoteLinuxDeployStep::setDeployService(AbstractRemoteLinuxDeployService *service)
|
||||
{
|
||||
d->deployService = service;
|
||||
}
|
||||
|
||||
AbstractRemoteLinuxDeployStep::~AbstractRemoteLinuxDeployStep()
|
||||
{
|
||||
delete d->deployService;
|
||||
delete d;
|
||||
}
|
||||
|
||||
bool AbstractRemoteLinuxDeployStep::fromMap(const QVariantMap &map)
|
||||
{
|
||||
if (!BuildStep::fromMap(map))
|
||||
return false;
|
||||
d->deployService->importDeployTimes(map);
|
||||
importDeployTimes(map);
|
||||
return true;
|
||||
}
|
||||
|
||||
QVariantMap AbstractRemoteLinuxDeployStep::toMap() const
|
||||
{
|
||||
QVariantMap map = BuildStep::toMap();
|
||||
map.insert(d->deployService->exportDeployTimes());
|
||||
map.insert(exportDeployTimes());
|
||||
return map;
|
||||
}
|
||||
|
||||
bool AbstractRemoteLinuxDeployStep::init()
|
||||
{
|
||||
d->deployService->setTarget(target());
|
||||
|
||||
QTC_ASSERT(d->internalInit, return false);
|
||||
const CheckResult canDeploy = d->internalInit();
|
||||
if (!canDeploy) {
|
||||
@@ -209,21 +175,8 @@ void AbstractRemoteLinuxDeployStep::doRun()
|
||||
if (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->deployService->start();
|
||||
start();
|
||||
}
|
||||
|
||||
void AbstractRemoteLinuxDeployStep::doCancel()
|
||||
@@ -234,7 +187,7 @@ void AbstractRemoteLinuxDeployStep::doCancel()
|
||||
emit addOutput(Tr::tr("User requests deployment to stop; cleaning up."),
|
||||
OutputFormat::NormalMessage);
|
||||
d->hasError = true;
|
||||
d->deployService->stop();
|
||||
stop();
|
||||
}
|
||||
|
||||
void AbstractRemoteLinuxDeployStep::handleProgressMessage(const QString &message)
|
||||
@@ -261,7 +214,6 @@ void AbstractRemoteLinuxDeployStep::handleFinished()
|
||||
emit addOutput(Tr::tr("Deploy step failed."), OutputFormat::ErrorMessage);
|
||||
else
|
||||
emit addOutput(Tr::tr("Deploy step finished."), OutputFormat::NormalMessage);
|
||||
disconnect(d->deployService, nullptr, this, nullptr);
|
||||
emit finished(!d->hasError);
|
||||
}
|
||||
|
||||
@@ -275,4 +227,14 @@ void AbstractRemoteLinuxDeployStep::handleStdErrData(const QString &data)
|
||||
emit addOutput(data, OutputFormat::Stderr, DontAppendNewline);
|
||||
}
|
||||
|
||||
bool AbstractRemoteLinuxDeployStep::isDeploymentNecessary() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
Tasking::Group AbstractRemoteLinuxDeployStep::deployRecipe()
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace RemoteLinux
|
||||
|
||||
@@ -21,42 +21,9 @@ namespace Utils::Tasking { class Group; }
|
||||
|
||||
namespace RemoteLinux {
|
||||
|
||||
class AbstractRemoteLinuxDeployService;
|
||||
class CheckResult;
|
||||
|
||||
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
|
||||
{
|
||||
@@ -74,21 +41,20 @@ private:
|
||||
QString m_error;
|
||||
};
|
||||
|
||||
class REMOTELINUX_EXPORT AbstractRemoteLinuxDeployService : public QObject
|
||||
class REMOTELINUX_EXPORT AbstractRemoteLinuxDeployStep : public ProjectExplorer::BuildStep
|
||||
{
|
||||
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 stop();
|
||||
|
||||
QVariantMap exportDeployTimes() const;
|
||||
void importDeployTimes(const QVariantMap &map);
|
||||
ProjectExplorer::IDeviceConstPtr deviceConfiguration() const;
|
||||
|
||||
virtual CheckResult isDeploymentPossible() const;
|
||||
|
||||
@@ -98,12 +64,16 @@ signals:
|
||||
void warningMessage(const QString &message);
|
||||
void stdOutData(const QString &data);
|
||||
void stdErrData(const QString &data);
|
||||
void finished(); // Used by Qnx.
|
||||
|
||||
protected:
|
||||
const ProjectExplorer::Target *target() const;
|
||||
const ProjectExplorer::Kit *kit() const;
|
||||
ProjectExplorer::IDeviceConstPtr deviceConfiguration() const;
|
||||
bool fromMap(const QVariantMap &map) override;
|
||||
QVariantMap toMap() const override;
|
||||
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,
|
||||
const QDateTime &remoteTimestamp);
|
||||
@@ -112,10 +82,17 @@ protected:
|
||||
const QDateTime &remoteTimestamp) const;
|
||||
|
||||
private:
|
||||
virtual bool isDeploymentNecessary() const = 0;
|
||||
virtual Utils::Tasking::Group deployRecipe() = 0;
|
||||
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::AbstractRemoteLinuxDeployServicePrivate * const d;
|
||||
virtual bool isDeploymentNecessary() const;
|
||||
virtual Utils::Tasking::Group deployRecipe();
|
||||
|
||||
Internal::AbstractRemoteLinuxDeployStepPrivate *d;
|
||||
};
|
||||
|
||||
} // RemoteLinux
|
||||
|
||||
@@ -19,9 +19,26 @@ using namespace Utils::Tasking;
|
||||
|
||||
namespace RemoteLinux::Internal {
|
||||
|
||||
class CustomCommandDeployService : public AbstractRemoteLinuxDeployService
|
||||
class CustomCommandDeployStep : public AbstractRemoteLinuxDeployStep
|
||||
{
|
||||
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);
|
||||
CheckResult isDeploymentPossible() const final;
|
||||
|
||||
@@ -34,20 +51,20 @@ private:
|
||||
QString m_commandLine;
|
||||
};
|
||||
|
||||
void CustomCommandDeployService::setCommandLine(const QString &commandLine)
|
||||
void CustomCommandDeployStep::setCommandLine(const QString &commandLine)
|
||||
{
|
||||
m_commandLine = commandLine;
|
||||
}
|
||||
|
||||
CheckResult CustomCommandDeployService::isDeploymentPossible() const
|
||||
CheckResult CustomCommandDeployStep::isDeploymentPossible() const
|
||||
{
|
||||
if (m_commandLine.isEmpty())
|
||||
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) {
|
||||
emit progressMessage(Tr::tr("Starting remote command \"%1\"...").arg(m_commandLine));
|
||||
@@ -76,30 +93,6 @@ Group CustomCommandDeployService::deployRecipe()
|
||||
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
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@ using namespace Utils;
|
||||
using namespace Utils::Tasking;
|
||||
|
||||
namespace RemoteLinux {
|
||||
namespace Internal {
|
||||
|
||||
const int MaxConcurrentStatCalls = 10;
|
||||
|
||||
@@ -36,21 +35,13 @@ struct UploadStorage
|
||||
|
||||
enum class IncrementalDeployment { Enabled, Disabled, NotSupported };
|
||||
|
||||
class GenericDirectUploadService : public AbstractRemoteLinuxDeployService
|
||||
class GenericDirectUploadStepPrivate
|
||||
{
|
||||
public:
|
||||
GenericDirectUploadService(QObject *parent = nullptr)
|
||||
: AbstractRemoteLinuxDeployService(parent)
|
||||
GenericDirectUploadStepPrivate(GenericDirectUploadStep *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);
|
||||
|
||||
using FilesToStat = std::function<QList<DeployableFile>(UploadStorage *)>;
|
||||
@@ -64,6 +55,7 @@ private:
|
||||
TaskItem chmodTask(const DeployableFile &file);
|
||||
TaskItem chmodTree(const TreeStorage<UploadStorage> &storage);
|
||||
|
||||
GenericDirectUploadStep *q;
|
||||
IncrementalDeployment m_incremental = IncrementalDeployment::NotSupported;
|
||||
bool m_ignoreMissingFiles = false;
|
||||
mutable QList<DeployableFile> m_deployableFiles;
|
||||
@@ -84,37 +76,18 @@ QList<DeployableFile> collectFilesToUpload(const DeployableFile &deployable)
|
||||
return collected;
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
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
|
||||
bool GenericDirectUploadStep::isDeploymentNecessary() const
|
||||
{
|
||||
QList<DeployableFile> collected;
|
||||
for (int i = 0; i < m_deployableFiles.count(); ++i)
|
||||
collected.append(collectFilesToUpload(m_deployableFiles.at(i)));
|
||||
for (int i = 0; i < d->m_deployableFiles.count(); ++i)
|
||||
collected.append(collectFilesToUpload(d->m_deployableFiles.at(i)));
|
||||
|
||||
QTC_CHECK(collected.size() >= m_deployableFiles.size());
|
||||
m_deployableFiles = collected;
|
||||
return !m_deployableFiles.isEmpty();
|
||||
QTC_CHECK(collected.size() >= d->m_deployableFiles.size());
|
||||
d->m_deployableFiles = collected;
|
||||
return !d->m_deployableFiles.isEmpty();
|
||||
}
|
||||
|
||||
QDateTime GenericDirectUploadService::timestampFromStat(const DeployableFile &file,
|
||||
QDateTime GenericDirectUploadStepPrivate::timestampFromStat(const DeployableFile &file,
|
||||
QtcProcess *statProc)
|
||||
{
|
||||
bool succeeded = false;
|
||||
@@ -130,7 +103,7 @@ QDateTime GenericDirectUploadService::timestampFromStat(const DeployableFile &fi
|
||||
succeeded = true;
|
||||
}
|
||||
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")
|
||||
.arg(file.remoteFilePath(), error));
|
||||
return {};
|
||||
@@ -139,30 +112,30 @@ QDateTime GenericDirectUploadService::timestampFromStat(const DeployableFile &fi
|
||||
const QString warningString(Tr::tr("Unexpected stat output for remote file \"%1\": %2")
|
||||
.arg(file.remoteFilePath()).arg(QString::fromUtf8(output)));
|
||||
if (!output.startsWith(file.remoteFilePath().toUtf8())) {
|
||||
emit warningMessage(warningString);
|
||||
emit q->warningMessage(warningString);
|
||||
return {};
|
||||
}
|
||||
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
|
||||
emit warningMessage(warningString);
|
||||
emit q->warningMessage(warningString);
|
||||
return {};
|
||||
}
|
||||
bool isNumber;
|
||||
const qint64 secsSinceEpoch = columns.at(11).toLongLong(&isNumber);
|
||||
if (!isNumber) {
|
||||
emit warningMessage(warningString);
|
||||
emit q->warningMessage(warningString);
|
||||
return {};
|
||||
}
|
||||
return QDateTime::fromSecsSinceEpoch(secsSinceEpoch);
|
||||
}
|
||||
|
||||
TaskItem GenericDirectUploadService::statTask(UploadStorage *storage,
|
||||
TaskItem GenericDirectUploadStepPrivate::statTask(UploadStorage *storage,
|
||||
const DeployableFile &file,
|
||||
StatEndHandler statEndHandler)
|
||||
{
|
||||
const auto setupHandler = [=](QtcProcess &process) {
|
||||
// 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())}});
|
||||
};
|
||||
const auto endHandler = [=](const QtcProcess &process) {
|
||||
@@ -173,7 +146,7 @@ TaskItem GenericDirectUploadService::statTask(UploadStorage *storage,
|
||||
return Process(setupHandler, endHandler, endHandler);
|
||||
}
|
||||
|
||||
TaskItem GenericDirectUploadService::statTree(const TreeStorage<UploadStorage> &storage,
|
||||
TaskItem GenericDirectUploadStepPrivate::statTree(const TreeStorage<UploadStorage> &storage,
|
||||
FilesToStat filesToStat, StatEndHandler statEndHandler)
|
||||
{
|
||||
const auto setupHandler = [=](TaskTree &tree) {
|
||||
@@ -189,14 +162,14 @@ TaskItem GenericDirectUploadService::statTree(const TreeStorage<UploadStorage> &
|
||||
return Tree(setupHandler);
|
||||
}
|
||||
|
||||
TaskItem GenericDirectUploadService::uploadTask(const TreeStorage<UploadStorage> &storage)
|
||||
TaskItem GenericDirectUploadStepPrivate::uploadTask(const TreeStorage<UploadStorage> &storage)
|
||||
{
|
||||
const auto setupHandler = [this, storage](FileTransfer &transfer) {
|
||||
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;
|
||||
}
|
||||
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()));
|
||||
FilesToTransfer files;
|
||||
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.")
|
||||
.arg(file.localFilePath().toUserOutput());
|
||||
if (m_ignoreMissingFiles) {
|
||||
emit warningMessage(message);
|
||||
emit q->warningMessage(message);
|
||||
continue;
|
||||
}
|
||||
emit errorMessage(message);
|
||||
emit q->errorMessage(message);
|
||||
return TaskAction::StopWithError;
|
||||
}
|
||||
files.append({file.localFilePath(),
|
||||
deviceConfiguration()->filePath(file.remoteFilePath())});
|
||||
q->deviceConfiguration()->filePath(file.remoteFilePath())});
|
||||
}
|
||||
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;
|
||||
}
|
||||
transfer.setFilesToTransfer(files);
|
||||
QObject::connect(&transfer, &FileTransfer::progress,
|
||||
this, &GenericDirectUploadService::progressMessage);
|
||||
q, &GenericDirectUploadStep::progressMessage);
|
||||
return TaskAction::Continue;
|
||||
};
|
||||
const auto errorHandler = [this](const FileTransfer &transfer) {
|
||||
emit errorMessage(transfer.resultData().m_errorString);
|
||||
emit q->errorMessage(transfer.resultData().m_errorString);
|
||||
};
|
||||
|
||||
return Transfer(setupHandler, {}, errorHandler);
|
||||
}
|
||||
|
||||
TaskItem GenericDirectUploadService::chmodTask(const DeployableFile &file)
|
||||
TaskItem GenericDirectUploadStepPrivate::chmodTask(const DeployableFile &file)
|
||||
{
|
||||
const auto setupHandler = [=](QtcProcess &process) {
|
||||
process.setCommand({deviceConfiguration()->filePath("chmod"),
|
||||
process.setCommand({q->deviceConfiguration()->filePath("chmod"),
|
||||
{"a+x", Utils::ProcessArgs::quoteArgUnix(file.remoteFilePath())}});
|
||||
};
|
||||
const auto errorHandler = [=](const QtcProcess &process) {
|
||||
const QString error = process.errorString();
|
||||
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));
|
||||
} 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()));
|
||||
}
|
||||
};
|
||||
return Process(setupHandler, {}, errorHandler);
|
||||
}
|
||||
|
||||
TaskItem GenericDirectUploadService::chmodTree(const TreeStorage<UploadStorage> &storage)
|
||||
TaskItem GenericDirectUploadStepPrivate::chmodTree(const TreeStorage<UploadStorage> &storage)
|
||||
{
|
||||
const auto setupChmodHandler = [=](TaskTree &tree) {
|
||||
QList<DeployableFile> filesToChmod;
|
||||
@@ -266,16 +239,16 @@ TaskItem GenericDirectUploadService::chmodTree(const TreeStorage<UploadStorage>
|
||||
return Tree(setupChmodHandler);
|
||||
}
|
||||
|
||||
Group GenericDirectUploadService::deployRecipe()
|
||||
Group GenericDirectUploadStep::deployRecipe()
|
||||
{
|
||||
const auto preFilesToStat = [this](UploadStorage *storage) {
|
||||
QList<DeployableFile> filesToStat;
|
||||
for (const DeployableFile &file : std::as_const(m_deployableFiles)) {
|
||||
if (m_incremental != IncrementalDeployment::Enabled || hasLocalFileChanged(file)) {
|
||||
for (const DeployableFile &file : std::as_const(d->m_deployableFiles)) {
|
||||
if (d->m_incremental != IncrementalDeployment::Enabled || hasLocalFileChanged(file)) {
|
||||
storage->filesToUpload.append(file);
|
||||
continue;
|
||||
}
|
||||
if (m_incremental == IncrementalDeployment::NotSupported)
|
||||
if (d->m_incremental == IncrementalDeployment::NotSupported)
|
||||
continue;
|
||||
filesToStat << file;
|
||||
}
|
||||
@@ -288,7 +261,7 @@ Group GenericDirectUploadService::deployRecipe()
|
||||
};
|
||||
|
||||
const auto postFilesToStat = [this](UploadStorage *storage) {
|
||||
return m_incremental == IncrementalDeployment::NotSupported
|
||||
return d->m_incremental == IncrementalDeployment::NotSupported
|
||||
? QList<DeployableFile>() : storage->filesToUpload;
|
||||
};
|
||||
const auto postStatEndHandler = [this](UploadStorage *storage, const DeployableFile &file,
|
||||
@@ -304,11 +277,11 @@ Group GenericDirectUploadService::deployRecipe()
|
||||
const TreeStorage<UploadStorage> storage;
|
||||
const Group root {
|
||||
Storage(storage),
|
||||
statTree(storage, preFilesToStat, preStatEndHandler),
|
||||
uploadTask(storage),
|
||||
d->statTree(storage, preFilesToStat, preStatEndHandler),
|
||||
d->uploadTask(storage),
|
||||
Group {
|
||||
chmodTree(storage),
|
||||
statTree(storage, postFilesToStat, postStatEndHandler)
|
||||
d->chmodTree(storage),
|
||||
d->statTree(storage, postFilesToStat, postStatEndHandler)
|
||||
},
|
||||
OnGroupDone(doneHandler)
|
||||
};
|
||||
@@ -317,11 +290,9 @@ Group GenericDirectUploadService::deployRecipe()
|
||||
|
||||
GenericDirectUploadStep::GenericDirectUploadStep(BuildStepList *bsl, Utils::Id id,
|
||||
bool offerIncrementalDeployment)
|
||||
: AbstractRemoteLinuxDeployStep(bsl, id)
|
||||
: AbstractRemoteLinuxDeployStep(bsl, id),
|
||||
d(new GenericDirectUploadStepPrivate(this))
|
||||
{
|
||||
auto service = new GenericDirectUploadService;
|
||||
setDeployService(service);
|
||||
|
||||
BoolAspect *incremental = nullptr;
|
||||
if (offerIncrementalDeployment) {
|
||||
incremental = addAspect<BoolAspect>();
|
||||
@@ -338,23 +309,26 @@ GenericDirectUploadStep::GenericDirectUploadStep(BuildStepList *bsl, Utils::Id i
|
||||
BoolAspect::LabelPlacement::AtCheckBox);
|
||||
ignoreMissingFiles->setValue(false);
|
||||
|
||||
setInternalInitializer([incremental, ignoreMissingFiles, service] {
|
||||
setInternalInitializer([this, incremental, ignoreMissingFiles] {
|
||||
if (incremental) {
|
||||
service->setIncrementalDeployment(incremental->value()
|
||||
? IncrementalDeployment::Enabled : IncrementalDeployment::Disabled);
|
||||
d->m_incremental = incremental->value()
|
||||
? IncrementalDeployment::Enabled : IncrementalDeployment::Disabled;
|
||||
} else {
|
||||
service->setIncrementalDeployment(IncrementalDeployment::NotSupported);
|
||||
d->m_incremental = IncrementalDeployment::NotSupported;
|
||||
}
|
||||
service->setIgnoreMissingFiles(ignoreMissingFiles->value());
|
||||
return service->isDeploymentPossible();
|
||||
d->m_ignoreMissingFiles = ignoreMissingFiles->value();
|
||||
return isDeploymentPossible();
|
||||
});
|
||||
|
||||
setRunPreparer([this, service] {
|
||||
service->setDeployableFiles(target()->deploymentData().allFiles());
|
||||
setRunPreparer([this] {
|
||||
d->m_deployableFiles = target()->deploymentData().allFiles();
|
||||
});
|
||||
}
|
||||
|
||||
GenericDirectUploadStep::~GenericDirectUploadStep() = default;
|
||||
GenericDirectUploadStep::~GenericDirectUploadStep()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
Utils::Id GenericDirectUploadStep::stepId()
|
||||
{
|
||||
|
||||
@@ -18,8 +18,14 @@ public:
|
||||
bool offerIncrementalDeployment = true);
|
||||
~GenericDirectUploadStep() override;
|
||||
|
||||
bool isDeploymentNecessary() const final;
|
||||
Utils::Tasking::Group deployRecipe() final;
|
||||
|
||||
static Utils::Id stepId();
|
||||
static QString displayName();
|
||||
|
||||
private:
|
||||
class GenericDirectUploadStepPrivate *d;
|
||||
};
|
||||
|
||||
} //namespace RemoteLinux
|
||||
} // RemoteLinux
|
||||
|
||||
@@ -20,10 +20,21 @@ using namespace Utils::Tasking;
|
||||
|
||||
namespace RemoteLinux::Internal {
|
||||
|
||||
class KillAppService : public AbstractRemoteLinuxDeployService
|
||||
class KillAppStep : public AbstractRemoteLinuxDeployStep
|
||||
{
|
||||
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:
|
||||
bool isDeploymentNecessary() const final { return !m_remoteExecutable.isEmpty(); }
|
||||
@@ -32,7 +43,7 @@ private:
|
||||
FilePath m_remoteExecutable;
|
||||
};
|
||||
|
||||
Group KillAppService::deployRecipe()
|
||||
Group KillAppStep::deployRecipe()
|
||||
{
|
||||
const auto setupHandler = [this](DeviceProcessKiller &killer) {
|
||||
killer.setProcessPath(m_remoteExecutable);
|
||||
@@ -49,27 +60,6 @@ Group KillAppService::deployRecipe()
|
||||
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()
|
||||
{
|
||||
registerStep<KillAppStep>(Constants::KillAppStepId);
|
||||
|
||||
@@ -25,39 +25,57 @@ using namespace Utils::Tasking;
|
||||
|
||||
namespace RemoteLinux {
|
||||
|
||||
class RsyncDeployService : public AbstractRemoteLinuxDeployService
|
||||
// RsyncDeployStep
|
||||
|
||||
RsyncDeployStep::RsyncDeployStep(BuildStepList *bsl, Id id)
|
||||
: AbstractRemoteLinuxDeployStep(bsl, id)
|
||||
{
|
||||
public:
|
||||
void setDeployableFiles(const QList<DeployableFile> &files);
|
||||
void setIgnoreMissingFiles(bool ignore) { m_ignoreMissingFiles = ignore; }
|
||||
void setFlags(const QString &flags) { m_flags = flags; }
|
||||
auto flags = addAspect<StringAspect>();
|
||||
flags->setDisplayStyle(StringAspect::LineEditDisplay);
|
||||
flags->setSettingsKey("RemoteLinux.RsyncDeployStep.Flags");
|
||||
flags->setLabelText(Tr::tr("Flags:"));
|
||||
flags->setValue(FileTransferSetupData::defaultRsyncFlags());
|
||||
|
||||
private:
|
||||
bool isDeploymentNecessary() const final;
|
||||
Group deployRecipe() final;
|
||||
TaskItem mkdirTask();
|
||||
TaskItem transferTask();
|
||||
auto ignoreMissingFiles = addAspect<BoolAspect>();
|
||||
ignoreMissingFiles->setSettingsKey("RemoteLinux.RsyncDeployStep.IgnoreMissingFiles");
|
||||
ignoreMissingFiles->setLabel(Tr::tr("Ignore missing files:"),
|
||||
BoolAspect::LabelPlacement::InExtraLabel);
|
||||
ignoreMissingFiles->setValue(false);
|
||||
|
||||
mutable FilesToTransfer m_files;
|
||||
bool m_ignoreMissingFiles = false;
|
||||
QString m_flags;
|
||||
};
|
||||
setInternalInitializer([this, ignoreMissingFiles, flags] {
|
||||
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."));
|
||||
}
|
||||
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();
|
||||
for (const DeployableFile &f : files)
|
||||
m_files.append({f.localFilePath(), deviceConfiguration()->filePath(f.remoteFilePath())});
|
||||
}
|
||||
|
||||
bool RsyncDeployService::isDeploymentNecessary() const
|
||||
bool RsyncDeployStep::isDeploymentNecessary() const
|
||||
{
|
||||
if (m_ignoreMissingFiles)
|
||||
Utils::erase(m_files, [](const FileToTransfer &file) { return !file.m_source.exists(); });
|
||||
return !m_files.empty();
|
||||
}
|
||||
|
||||
TaskItem RsyncDeployService::mkdirTask()
|
||||
TaskItem RsyncDeployStep::mkdirTask()
|
||||
{
|
||||
const auto setupHandler = [this](QtcProcess &process) {
|
||||
QStringList remoteDirs;
|
||||
@@ -85,14 +103,14 @@ TaskItem RsyncDeployService::mkdirTask()
|
||||
return Process(setupHandler, {}, errorHandler);
|
||||
}
|
||||
|
||||
TaskItem RsyncDeployService::transferTask()
|
||||
TaskItem RsyncDeployStep::transferTask()
|
||||
{
|
||||
const auto setupHandler = [this](FileTransfer &transfer) {
|
||||
transfer.setTransferMethod(FileTransferMethod::Rsync);
|
||||
transfer.setRsyncFlags(m_flags);
|
||||
transfer.setFilesToTransfer(m_files);
|
||||
connect(&transfer, &FileTransfer::progress,
|
||||
this, &AbstractRemoteLinuxDeployService::stdOutData);
|
||||
this, &AbstractRemoteLinuxDeployStep::stdOutData);
|
||||
};
|
||||
const auto errorHandler = [this](const FileTransfer &transfer) {
|
||||
const ProcessResultData result = transfer.resultData();
|
||||
@@ -108,50 +126,11 @@ TaskItem RsyncDeployService::transferTask()
|
||||
return Transfer(setupHandler, {}, errorHandler);
|
||||
}
|
||||
|
||||
Group RsyncDeployService::deployRecipe()
|
||||
Group RsyncDeployStep::deployRecipe()
|
||||
{
|
||||
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()
|
||||
{
|
||||
return Constants::RsyncDeployStepId;
|
||||
|
||||
@@ -7,6 +7,10 @@
|
||||
|
||||
#include "abstractremotelinuxdeploystep.h"
|
||||
|
||||
#include <projectexplorer/devicesupport/filetransfer.h>
|
||||
|
||||
#include <utils/tasktree.h>
|
||||
|
||||
namespace RemoteLinux {
|
||||
|
||||
class REMOTELINUX_EXPORT RsyncDeployStep : public AbstractRemoteLinuxDeployStep
|
||||
@@ -17,6 +21,20 @@ public:
|
||||
|
||||
static Utils::Id stepId();
|
||||
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
|
||||
|
||||
@@ -21,9 +21,36 @@ using namespace Utils::Tasking;
|
||||
|
||||
namespace RemoteLinux::Internal {
|
||||
|
||||
class TarPackageDeployService : public AbstractRemoteLinuxDeployService
|
||||
// TarPackageDeployStep
|
||||
|
||||
class TarPackageDeployStep : public AbstractRemoteLinuxDeployStep
|
||||
{
|
||||
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);
|
||||
|
||||
private:
|
||||
@@ -36,29 +63,28 @@ private:
|
||||
FilePath m_packageFilePath;
|
||||
};
|
||||
|
||||
void TarPackageDeployService::setPackageFilePath(const FilePath &filePath)
|
||||
void TarPackageDeployStep::setPackageFilePath(const FilePath &filePath)
|
||||
{
|
||||
m_packageFilePath = filePath;
|
||||
}
|
||||
|
||||
QString TarPackageDeployService::remoteFilePath() const
|
||||
QString TarPackageDeployStep::remoteFilePath() const
|
||||
{
|
||||
return QLatin1String("/tmp/") + m_packageFilePath.fileName();
|
||||
}
|
||||
|
||||
bool TarPackageDeployService::isDeploymentNecessary() const
|
||||
bool TarPackageDeployStep::isDeploymentNecessary() const
|
||||
{
|
||||
return hasLocalFileChanged(DeployableFile(m_packageFilePath, {}));
|
||||
}
|
||||
|
||||
TaskItem TarPackageDeployService::uploadTask()
|
||||
TaskItem TarPackageDeployStep::uploadTask()
|
||||
{
|
||||
const auto setupHandler = [this](FileTransfer &transfer) {
|
||||
const FilesToTransfer files {{m_packageFilePath,
|
||||
deviceConfiguration()->filePath(remoteFilePath())}};
|
||||
transfer.setFilesToTransfer(files);
|
||||
connect(&transfer, &FileTransfer::progress,
|
||||
this, &TarPackageDeployService::progressMessage);
|
||||
connect(&transfer, &FileTransfer::progress, this, &TarPackageDeployStep::progressMessage);
|
||||
emit progressMessage(Tr::tr("Uploading package to device..."));
|
||||
};
|
||||
const auto doneHandler = [this](const FileTransfer &) {
|
||||
@@ -71,7 +97,7 @@ TaskItem TarPackageDeployService::uploadTask()
|
||||
return Transfer(setupHandler, doneHandler, errorHandler);
|
||||
}
|
||||
|
||||
TaskItem TarPackageDeployService::installTask()
|
||||
TaskItem TarPackageDeployStep::installTask()
|
||||
{
|
||||
const auto setupHandler = [this](QtcProcess &process) {
|
||||
const QString cmdLine = QLatin1String("cd / && tar xvf ") + remoteFilePath()
|
||||
@@ -96,46 +122,11 @@ TaskItem TarPackageDeployService::installTask()
|
||||
return Process(setupHandler, doneHandler, errorHandler);
|
||||
}
|
||||
|
||||
Group TarPackageDeployService::deployRecipe()
|
||||
Group TarPackageDeployStep::deployRecipe()
|
||||
{
|
||||
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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user