Merge remote-tracking branch 'origin/master' into 8.0

Change-Id: I37b000ea6ea6b5d8c4ac8ed9bf371bc91c14723e
This commit is contained in:
Eike Ziller
2022-06-02 09:48:39 +02:00
63 changed files with 516 additions and 838 deletions

View File

@@ -143,8 +143,9 @@ public:
StopProcessPacket(quintptr token);
enum class SignalType {
Kill,
Terminate
Kill, // Calls QProcess::kill
Terminate, // Calls QProcess::terminate
Close // Puts the process into the reaper, no confirmation signal is being sent.
};
SignalType signalType = SignalType::Kill;

View File

@@ -262,6 +262,12 @@ void CallerHandle::kill()
sendStopPacket(StopProcessPacket::SignalType::Kill);
}
void CallerHandle::close()
{
QTC_ASSERT(isCalledFromCallersThread(), return);
sendStopPacket(StopProcessPacket::SignalType::Close);
}
qint64 CallerHandle::processId() const
{
QTC_ASSERT(isCalledFromCallersThread(), return 0);

View File

@@ -89,6 +89,7 @@ public:
void sendStopPacket(StopProcessPacket::SignalType signalType);
void terminate();
void kill();
void close();
qint64 processId() const;

View File

@@ -437,7 +437,7 @@ public:
}
~ProcessLauncherImpl() final
{
m_handle->kill();
m_handle->close();
LauncherInterface::unregisterHandle(token());
m_handle = nullptr;
}

View File

@@ -31,6 +31,7 @@
#include <projectexplorer/runconfigurationaspects.h>
#include <projectexplorer/target.h>
#include <remotelinux/abstractremotelinuxdeployservice.h>
#include <remotelinux/abstractremotelinuxdeploystep.h>
#include <utils/commandline.h>

View File

@@ -45,9 +45,9 @@
#include <qtsupport/qtversionfactory.h>
#include <remotelinux/checkforfreediskspacestep.h>
#include <remotelinux/genericdirectuploadstep.h>
#include <remotelinux/makeinstallstep.h>
#include <remotelinux/remotelinuxcheckforfreediskspacestep.h>
#include <remotelinux/remotelinux_constants.h>
#include <utils/hostosinfo.h>
@@ -176,7 +176,7 @@ public:
QdbStopApplicationStepFactory m_stopApplicationStepFactory;
QdbMakeDefaultAppStepFactory m_makeDefaultAppStepFactory;
QdbDeployStepFactory<RemoteLinux::RemoteLinuxCheckForFreeDiskSpaceStep>
QdbDeployStepFactory<RemoteLinux::CheckForFreeDiskSpaceStep>
m_checkForFreeDiskSpaceStepFactory{RemoteLinux::Constants::CheckForFreeDiskSpaceId};
QdbDeployStepFactory<RemoteLinux::GenericDirectUploadStep>
m_directUploadStepFactory{RemoteLinux::Constants::DirectUploadStepId};

View File

@@ -33,6 +33,7 @@
#include <projectexplorer/runcontrol.h>
#include <projectexplorer/target.h>
#include <remotelinux/abstractremotelinuxdeployservice.h>
#include <remotelinux/abstractremotelinuxdeploystep.h>
#include <utils/qtcprocess.h>

View File

@@ -106,7 +106,7 @@ bool GitLabPlugin::initialize(const QStringList & /*arguments*/, QString * /*err
connect(openViewAction, &QAction::triggered, this, &GitLabPlugin::openView);
Core::ActionContainer *ac = Core::ActionManager::actionContainer(Core::Constants::M_TOOLS);
ac->addAction(gitlabCommand);
connect(&dd->optionsPage, &GitLabOptionsPage::settingsChanged, this, [this] {
connect(&dd->optionsPage, &GitLabOptionsPage::settingsChanged, this, [] {
if (dd->dialog)
dd->dialog->updateRemotes();
});

View File

@@ -41,9 +41,8 @@ namespace ProjectExplorer {
// EnvironmentAspectWidget:
// --------------------------------------------------------------------
EnvironmentAspectWidget::EnvironmentAspectWidget(EnvironmentAspect *aspect, QWidget *additionalWidget) :
m_aspect(aspect),
m_additionalWidget(additionalWidget)
EnvironmentAspectWidget::EnvironmentAspectWidget(EnvironmentAspect *aspect)
: m_aspect(aspect)
{
QTC_CHECK(m_aspect);
@@ -52,10 +51,10 @@ EnvironmentAspectWidget::EnvironmentAspectWidget(EnvironmentAspect *aspect, QWid
topLayout->setContentsMargins(0, 0, 0, 25);
auto baseEnvironmentWidget = new QWidget;
auto baseLayout = new QHBoxLayout(baseEnvironmentWidget);
baseLayout->setContentsMargins(0, 0, 0, 0);
m_baseLayout = new QHBoxLayout(baseEnvironmentWidget);
m_baseLayout->setContentsMargins(0, 0, 0, 0);
auto label = new QLabel(tr("Base environment for this run configuration:"), this);
baseLayout->addWidget(label);
m_baseLayout->addWidget(label);
m_baseEnvironmentComboBox = new QComboBox;
for (const QString &displayName : m_aspect->displayNames())
@@ -67,10 +66,8 @@ EnvironmentAspectWidget::EnvironmentAspectWidget(EnvironmentAspect *aspect, QWid
connect(m_baseEnvironmentComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
this, &EnvironmentAspectWidget::baseEnvironmentSelected);
baseLayout->addWidget(m_baseEnvironmentComboBox);
baseLayout->addStretch(10);
if (additionalWidget)
baseLayout->addWidget(additionalWidget);
m_baseLayout->addWidget(m_baseEnvironmentComboBox);
m_baseLayout->addStretch(10);
const EnvironmentWidget::Type widgetType = aspect->isLocal()
? EnvironmentWidget::TypeLocal : EnvironmentWidget::TypeRemote;
@@ -92,14 +89,9 @@ EnvironmentAspectWidget::EnvironmentAspectWidget(EnvironmentAspect *aspect, QWid
this, &EnvironmentAspectWidget::environmentChanged);
}
EnvironmentAspect *EnvironmentAspectWidget::aspect() const
void EnvironmentAspectWidget::addWidget(QWidget *widget)
{
return m_aspect;
}
QWidget *EnvironmentAspectWidget::additionalWidget() const
{
return m_additionalWidget;
m_baseLayout->addWidget(widget);
}
void EnvironmentAspectWidget::baseEnvironmentSelected(int idx)

View File

@@ -37,6 +37,7 @@
QT_BEGIN_NAMESPACE
class QComboBox;
class QHBoxLayout;
QT_END_NAMESPACE
namespace Utils { class DetailsWidget; }
@@ -50,12 +51,12 @@ class PROJECTEXPLORER_EXPORT EnvironmentAspectWidget : public QWidget
Q_OBJECT
public:
explicit EnvironmentAspectWidget(EnvironmentAspect *aspect, QWidget *additionalWidget = nullptr);
explicit EnvironmentAspectWidget(EnvironmentAspect *aspect);
virtual EnvironmentAspect *aspect() const;
protected:
EnvironmentAspect *aspect() const { return m_aspect; }
EnvironmentWidget *envWidget() const { return m_environmentWidget; }
QWidget *additionalWidget() const;
void addWidget(QWidget *widget);
private:
void baseEnvironmentSelected(int idx);
@@ -66,8 +67,7 @@ private:
EnvironmentAspect *m_aspect;
bool m_ignoreChange = false;
QWidget *m_additionalWidget = nullptr;
QHBoxLayout *m_baseLayout = nullptr;
QComboBox *m_baseEnvironmentComboBox = nullptr;
EnvironmentWidget *m_environmentWidget = nullptr;
};

View File

@@ -99,7 +99,7 @@ TextEditor::IndentationForBlock Indenter::indentationForBlocks(
codeFormatter.updateStateUntil(blocks.last());
TextEditor::IndentationForBlock ret;
foreach (QTextBlock block, blocks)
for (QTextBlock block : blocks)
ret.insert(block.blockNumber(), codeFormatter.indentFor(block));
return ret;
}

View File

@@ -252,7 +252,7 @@ void LocatorData::onDocumentUpdated(const Document::Ptr &doc)
void LocatorData::onAboutToRemoveFiles(const QStringList &files)
{
QMutexLocker l(&m_mutex);
foreach (const QString &file, files) {
for (const QString &file : files) {
m_entries.remove(file);
}
}

View File

@@ -92,10 +92,11 @@ static void setupProjectInfoQmlBundles(ModelManagerInterface::ProjectInfo &proje
if (projectInfo.project) {
QSet<Kit *> currentKits;
foreach (const Target *t, projectInfo.project->targets())
const QList<Target *> targets = projectInfo.project->targets();
for (const Target *t : targets)
currentKits.insert(t->kit());
currentKits.remove(activeKit);
foreach (Kit *kit, currentKits) {
for (Kit *kit : qAsConst(currentKits)) {
for (IBundleProvider *bp : IBundleProvider::allBundleProviders())
bp->mergeBundlesForKit(kit, projectInfo.extendedBundle, replacements);
}
@@ -214,22 +215,28 @@ QHash<QString,Dialect> ModelManager::initLanguageForSuffix() const
if (ICore::instance()) {
MimeType jsSourceTy = Utils::mimeTypeForName(Constants::JS_MIMETYPE);
foreach (const QString &suffix, jsSourceTy.suffixes())
const QStringList jsSuffixes = jsSourceTy.suffixes();
for (const QString &suffix : jsSuffixes)
res[suffix] = Dialect::JavaScript;
MimeType qmlSourceTy = Utils::mimeTypeForName(Constants::QML_MIMETYPE);
foreach (const QString &suffix, qmlSourceTy.suffixes())
const QStringList qmlSuffixes = qmlSourceTy.suffixes();
for (const QString &suffix : qmlSuffixes)
res[suffix] = Dialect::Qml;
MimeType qbsSourceTy = Utils::mimeTypeForName(Constants::QBS_MIMETYPE);
foreach (const QString &suffix, qbsSourceTy.suffixes())
const QStringList qbsSuffixes = qbsSourceTy.suffixes();
for (const QString &suffix : qbsSuffixes)
res[suffix] = Dialect::QmlQbs;
MimeType qmlProjectSourceTy = Utils::mimeTypeForName(Constants::QMLPROJECT_MIMETYPE);
foreach (const QString &suffix, qmlProjectSourceTy.suffixes())
const QStringList qmlProjSuffixes = qmlProjectSourceTy.suffixes();
for (const QString &suffix : qmlProjSuffixes)
res[suffix] = Dialect::QmlProject;
MimeType qmlUiSourceTy = Utils::mimeTypeForName(Constants::QMLUI_MIMETYPE);
foreach (const QString &suffix, qmlUiSourceTy.suffixes())
const QStringList qmlUiSuffixes = qmlUiSourceTy.suffixes();
for (const QString &suffix : qmlUiSuffixes)
res[suffix] = Dialect::QmlQtQuick2Ui;
MimeType jsonSourceTy = Utils::mimeTypeForName(Constants::JSON_MIMETYPE);
foreach (const QString &suffix, jsonSourceTy.suffixes())
const QStringList jsonSuffixes = jsonSourceTy.suffixes();
for (const QString &suffix : jsonSuffixes)
res[suffix] = Dialect::Json;
}
return res;
@@ -288,7 +295,8 @@ ModelManagerInterface::WorkingCopy ModelManager::workingCopyInternal() const
if (!Core::ICore::instance())
return workingCopy;
foreach (IDocument *document, DocumentModel::openedDocuments()) {
const QList<IDocument *> documents = DocumentModel::openedDocuments();
for (IDocument *document : documents) {
const QString key = document->filePath().toString();
if (auto textDocument = qobject_cast<const TextEditor::TextDocument *>(document)) {
// TODO the language should be a property on the document, not the editor

View File

@@ -191,7 +191,7 @@ QList<AST::Node *> SemanticInfo::rangePath(int cursorPosition) const
{
QList<AST::Node *> path;
foreach (const Range &range, ranges) {
for (const Range &range : qAsConst(ranges)) {
if (range.begin.isNull() || range.end.isNull())
continue;
else if (cursorPosition >= range.begin.position() && cursorPosition <= range.end.position())

View File

@@ -200,7 +200,8 @@ QVariant FlameGraphModel::lookup(const FlameGraphData &stats, int role) const
if (!m_typeIdsWithNotes.contains(stats.typeIndex))
return ret;
Timeline::TimelineNotesModel *notes = m_modelManager->notesModel();
foreach (const QVariant &item, notes->byTypeId(stats.typeIndex)) {
const QList<QVariant> items = notes->byTypeId(stats.typeIndex);
for (const QVariant &item : items) {
if (ret.isEmpty())
ret = notes->text(item.toInt());
else

View File

@@ -432,7 +432,7 @@ QString PixmapCacheModel::fileName(int index) const
void PixmapCacheModel::computeMaxCacheSize()
{
foreach (const PixmapCacheModel::Item &event, m_data) {
for (const PixmapCacheModel::Item &event : qAsConst(m_data)) {
if (event.pixmapEventType == PixmapCacheModel::PixmapCacheCountChanged) {
if (event.cacheSize > m_maxCacheSize)
m_maxCacheSize = event.cacheSize;

View File

@@ -41,7 +41,8 @@ int QmlProfilerNotesModel::addQmlNote(int typeId, int collapsedRow, qint64 start
int foundTypeId = -1;
int timelineModel = -1;
int timelineIndex = -1;
foreach (const Timeline::TimelineModel *model, timelineModels()) {
const QList<const Timeline::TimelineModel *> models = timelineModels();
for (const Timeline::TimelineModel *model : models) {
if (model->handlesTypeId(typeId)) {
for (int i = model->firstIndex(start); i <= model->lastIndex(start + duration); ++i) {
if (i < 0)

View File

@@ -137,8 +137,8 @@ void QmlProfilerStatisticsView::contextMenuEvent(QContextMenuEvent *ev)
QPoint position = ev->globalPos();
QList <QAction *> commonActions = QmlProfilerTool::profilerContextMenuActions();
foreach (QAction *act, commonActions)
const QList <QAction *> commonActions = QmlProfilerTool::profilerContextMenuActions();
for (QAction *act : commonActions)
menu.addAction(act);
if (mouseOnTable(position)) {

View File

@@ -503,7 +503,8 @@ void QmlProfilerTool::setButtonsEnabled(bool enable)
void QmlProfilerTool::createInitialTextMarks()
{
QmlProfilerTextMarkModel *model = d->m_profilerModelManager->textMarkModel();
foreach (IDocument *document, DocumentModel::openedDocuments())
const QList<IDocument *> documents = DocumentModel::openedDocuments();
for (IDocument *document : documents)
model->createMarks(d->m_viewContainer, document->filePath().toString());
}
@@ -736,7 +737,8 @@ void QmlProfilerTool::setAvailableFeatures(quint64 features)
void QmlProfilerTool::setRecordedFeatures(quint64 features)
{
foreach (QAction *action, d->m_displayFeaturesMenu->actions())
const QList<QAction *> actions = d->m_displayFeaturesMenu->actions();
for (QAction *action : actions)
action->setEnabled(features & (1ULL << action->data().toUInt()));
}

View File

@@ -142,7 +142,8 @@ QmlProjectItem *QmlProjectFileFormat::parseProjectFile(const Utils::FilePath &fi
if (debug)
qDebug() << "importPath:" << importPathsProperty.value << "mainFile:" << mainFileProperty.value;
foreach (const QmlJS::SimpleReaderNode::Ptr &childNode, rootNode->children()) {
const QList<QmlJS::SimpleReaderNode::Ptr> childNodes = rootNode->children();
for (const QmlJS::SimpleReaderNode::Ptr &childNode : childNodes) {
if (debug)
qDebug() << "reading type:" << childNode->name();

View File

@@ -319,7 +319,8 @@ void QmlBuildSystem::refresh(RefreshOptions options)
QmlJS::ModelManagerInterface::ProjectInfo projectInfo =
modelManager->defaultProjectInfoForProject(project());
foreach (const QString &searchPath, makeAbsolute(canonicalProjectDir(), customImportPaths()))
const QStringList searchPaths = makeAbsolute(canonicalProjectDir(), customImportPaths());
for (const QString &searchPath : searchPaths)
projectInfo.importPaths.maybeInsert(Utils::FilePath::fromString(searchPath),
QmlJS::Dialect::Qml);

View File

@@ -212,8 +212,9 @@ QString QmlProjectRunConfiguration::commandLineArguments() const
// arguments from .qmlproject file
const QmlBuildSystem *bs = qobject_cast<QmlBuildSystem *>(target()->buildSystem());
foreach (const QString &importPath,
QmlBuildSystem::makeAbsolute(bs->targetDirectory(), bs->customImportPaths())) {
const QStringList importPaths = QmlBuildSystem::makeAbsolute(bs->targetDirectory(),
bs->customImportPaths());
for (const QString &importPath : importPaths) {
ProcessArgs::addArg(&args, "-I", osType);
ProcessArgs::addArg(&args, importPath, osType);
}

View File

@@ -54,9 +54,9 @@
#include <projectexplorer/target.h>
#include <projectexplorer/toolchain.h>
#include <remotelinux/checkforfreediskspacestep.h>
#include <remotelinux/genericdirectuploadstep.h>
#include <remotelinux/makeinstallstep.h>
#include <remotelinux/remotelinuxcheckforfreediskspacestep.h>
#include <remotelinux/remotelinux_constants.h>
#include <qtsupport/qtkitinformation.h>
@@ -123,7 +123,7 @@ public:
QnxDeviceFactory deviceFactory;
QnxDeployConfigurationFactory deployConfigFactory;
GenericQnxDeployStepFactory<QnxUploadStep> directUploadDeployFactory;
GenericQnxDeployStepFactory<RemoteLinux::RemoteLinuxCheckForFreeDiskSpaceStep> checkForFreeDiskSpaceDeployFactory;
GenericQnxDeployStepFactory<RemoteLinux::CheckForFreeDiskSpaceStep> checkForFreeDiskSpaceDeployFactory;
GenericQnxDeployStepFactory<RemoteLinux::MakeInstallStep> makeInstallDeployFactory;
GenericQnxDeployStepFactory<DeviceCheckBuildStep> checkBuildDeployFactory;
QnxRunConfigurationFactory runConfigFactory;

View File

@@ -2,9 +2,10 @@ add_qtc_plugin(RemoteLinux
DEPENDS QmlDebug
PLUGIN_DEPENDS Core Debugger ProjectExplorer
SOURCES
abstractpackagingstep.cpp abstractpackagingstep.h
abstractremotelinuxdeployservice.cpp abstractremotelinuxdeployservice.h
abstractremotelinuxdeploystep.cpp abstractremotelinuxdeploystep.h
checkforfreediskspacestep.cpp checkforfreediskspacestep.h
customcommanddeploystep.cpp customcommanddeploystep.h
deploymenttimeinfo.cpp deploymenttimeinfo.h
genericdirectuploadservice.cpp genericdirectuploadservice.h
genericdirectuploadstep.cpp genericdirectuploadstep.h
@@ -21,25 +22,22 @@ add_qtc_plugin(RemoteLinux
remotelinux.qrc
remotelinux_constants.h
remotelinux_export.h
remotelinuxcheckforfreediskspacestep.cpp remotelinuxcheckforfreediskspacestep.h
remotelinuxcustomcommanddeploymentstep.cpp remotelinuxcustomcommanddeploymentstep.h
remotelinuxcustomrunconfiguration.cpp remotelinuxcustomrunconfiguration.h
remotelinuxdebugsupport.cpp remotelinuxdebugsupport.h
remotelinuxdeployconfiguration.cpp remotelinuxdeployconfiguration.h
remotelinuxenvironmentaspect.cpp remotelinuxenvironmentaspect.h
remotelinuxenvironmentaspectwidget.cpp remotelinuxenvironmentaspectwidget.h
remotelinuxenvironmentreader.cpp remotelinuxenvironmentreader.h
remotelinuxpackageinstaller.cpp remotelinuxpackageinstaller.h
remotelinuxplugin.cpp remotelinuxplugin.h
remotelinuxqmltoolingsupport.cpp remotelinuxqmltoolingsupport.h
remotelinuxrunconfiguration.cpp remotelinuxrunconfiguration.h
remotelinuxsignaloperation.cpp remotelinuxsignaloperation.h
remotelinuxx11forwardingaspect.cpp remotelinuxx11forwardingaspect.h
rsyncdeploystep.cpp rsyncdeploystep.h
sshkeycreationdialog.cpp sshkeycreationdialog.h sshkeycreationdialog.ui
sshprocessinterface.h
tarpackagecreationstep.cpp tarpackagecreationstep.h
uploadandinstalltarpackagestep.cpp uploadandinstalltarpackagestep.h
tarpackagedeploystep.cpp tarpackagedeploystep.h
x11forwardingaspect.cpp x11forwardingaspect.h
)
extend_qtc_plugin(RemoteLinux

View File

@@ -1,148 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "abstractpackagingstep.h"
#include <projectexplorer/buildconfiguration.h>
#include <projectexplorer/deploymentdata.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/target.h>
#include <projectexplorer/task.h>
#include <QDateTime>
using namespace ProjectExplorer;
using namespace Utils;
namespace RemoteLinux {
namespace Internal {
class AbstractPackagingStepPrivate
{
public:
FilePath cachedPackageFilePath;
FilePath cachedPackageDirectory;
bool deploymentDataModified = false;
};
} // namespace Internal
AbstractPackagingStep::AbstractPackagingStep(BuildStepList *bsl, Utils::Id id)
: BuildStep(bsl, id)
{
d = new Internal::AbstractPackagingStepPrivate;
connect(target(), &Target::deploymentDataChanged,
this, &AbstractPackagingStep::setDeploymentDataModified);
setDeploymentDataModified();
connect(this, &AbstractPackagingStep::unmodifyDeploymentData,
this, &AbstractPackagingStep::setDeploymentDataUnmodified);
}
AbstractPackagingStep::~AbstractPackagingStep()
{
delete d;
}
FilePath AbstractPackagingStep::cachedPackageFilePath() const
{
return d->cachedPackageFilePath;
}
FilePath AbstractPackagingStep::packageFilePath() const
{
if (packageDirectory().isEmpty())
return {};
return packageDirectory().pathAppended(packageFileName());
}
FilePath AbstractPackagingStep::cachedPackageDirectory() const
{
return d->cachedPackageDirectory;
}
FilePath AbstractPackagingStep::packageDirectory() const
{
return buildDirectory();
}
bool AbstractPackagingStep::isPackagingNeeded() const
{
const FilePath packagePath = packageFilePath();
if (!packagePath.exists() || d->deploymentDataModified)
return true;
const DeploymentData &dd = target()->deploymentData();
for (int i = 0; i < dd.fileCount(); ++i) {
if (dd.fileAt(i).localFilePath().isNewerThan(packagePath.lastModified()))
return true;
}
return false;
}
bool AbstractPackagingStep::init()
{
d->cachedPackageDirectory = packageDirectory();
d->cachedPackageFilePath = packageFilePath();
return true;
}
void AbstractPackagingStep::setPackagingStarted()
{
}
// called in ::run thread
void AbstractPackagingStep::setPackagingFinished(bool success)
{
if (success)
emit unmodifyDeploymentData();
}
// called in gui thread
void AbstractPackagingStep::setDeploymentDataUnmodified()
{
d->deploymentDataModified = false;
}
void AbstractPackagingStep::setDeploymentDataModified()
{
d->deploymentDataModified = true;
}
void AbstractPackagingStep::raiseError(const QString &errorMessage)
{
emit addTask(DeploymentTask(Task::Error, errorMessage));
emit addOutput(errorMessage, BuildStep::OutputFormat::Stderr);
}
void AbstractPackagingStep::raiseWarning(const QString &warningMessage)
{
emit addTask(DeploymentTask(Task::Warning, warningMessage));
emit addOutput(warningMessage, OutputFormat::ErrorMessage);
}
} // namespace RemoteLinux

View File

@@ -1,71 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include "remotelinux_export.h"
#include <projectexplorer/buildstep.h>
namespace RemoteLinux {
namespace Internal { class AbstractPackagingStepPrivate; }
class REMOTELINUX_EXPORT AbstractPackagingStep : public ProjectExplorer::BuildStep
{
Q_OBJECT
public:
explicit AbstractPackagingStep(ProjectExplorer::BuildStepList *bsl, Utils::Id id);
~AbstractPackagingStep() override;
Utils::FilePath packageFilePath() const;
Utils::FilePath cachedPackageFilePath() const;
bool init() override;
signals:
void unmodifyDeploymentData();
protected:
void setPackagingStarted();
void setPackagingFinished(bool success);
void raiseError(const QString &errorMessage);
void raiseWarning(const QString &warningMessage);
Utils::FilePath cachedPackageDirectory() const;
Utils::FilePath packageDirectory() const;
virtual bool isPackagingNeeded() const;
private:
void setDeploymentDataUnmodified();
void setDeploymentDataModified();
virtual QString packageFileName() const = 0;
Internal::AbstractPackagingStepPrivate *d;
};
} // namespace RemoteLinux

View File

@@ -24,6 +24,7 @@
****************************************************************************/
#include "abstractremotelinuxdeployservice.h"
#include "deploymenttimeinfo.h"
#include <projectexplorer/deployablefile.h>

View File

@@ -26,7 +26,6 @@
#include "abstractremotelinuxdeploystep.h"
#include "abstractremotelinuxdeployservice.h"
#include "remotelinuxdeployconfiguration.h"
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/kitinformation.h>

View File

@@ -27,12 +27,13 @@
#include "remotelinux_export.h"
#include "abstractremotelinuxdeployservice.h"
#include <projectexplorer/buildstep.h>
namespace RemoteLinux {
class AbstractRemoteLinuxDeployService;
class CheckResult;
namespace Internal { class AbstractRemoteLinuxDeployStepPrivate; }
class REMOTELINUX_EXPORT AbstractRemoteLinuxDeployStep : public ProjectExplorer::BuildStep

View File

@@ -23,7 +23,7 @@
**
****************************************************************************/
#include "remotelinuxcheckforfreediskspacestep.h"
#include "checkforfreediskspacestep.h"
#include "abstractremotelinuxdeployservice.h"
@@ -41,14 +41,12 @@ using namespace Utils;
namespace RemoteLinux {
// RemoteLinuxCheckForFreeDiskSpaceService
class RemoteLinuxCheckForFreeDiskSpaceService : public AbstractRemoteLinuxDeployService
class CheckForFreeDiskSpaceService : public AbstractRemoteLinuxDeployService
{
Q_DECLARE_TR_FUNCTIONS(RemoteLinux::RemoteLinuxCheckForFreeDiskSpaceService)
Q_DECLARE_TR_FUNCTIONS(RemoteLinux::CheckForFreeDiskSpaceService)
public:
RemoteLinuxCheckForFreeDiskSpaceService() {}
CheckForFreeDiskSpaceService() {}
void setPathToCheck(const QString &path);
void setRequiredSpaceInBytes(quint64 sizeInBytes);
@@ -65,17 +63,17 @@ private:
quint64 m_requiredSpaceInBytes = 0;
};
void RemoteLinuxCheckForFreeDiskSpaceService::setPathToCheck(const QString &path)
void CheckForFreeDiskSpaceService::setPathToCheck(const QString &path)
{
m_pathToCheck = path;
}
void RemoteLinuxCheckForFreeDiskSpaceService::setRequiredSpaceInBytes(quint64 sizeInBytes)
void CheckForFreeDiskSpaceService::setRequiredSpaceInBytes(quint64 sizeInBytes)
{
m_requiredSpaceInBytes = sizeInBytes;
}
void RemoteLinuxCheckForFreeDiskSpaceService::doDeploy()
void CheckForFreeDiskSpaceService::doDeploy()
{
auto cleanup = qScopeGuard([this] { setFinished(); });
const FilePath path = deviceConfiguration()->filePath(m_pathToCheck);
@@ -104,7 +102,7 @@ void RemoteLinuxCheckForFreeDiskSpaceService::doDeploy()
handleDeploymentDone();
}
CheckResult RemoteLinuxCheckForFreeDiskSpaceService::isDeploymentPossible() const
CheckResult CheckForFreeDiskSpaceService::isDeploymentPossible() const
{
if (!m_pathToCheck.startsWith('/')) {
return CheckResult::failure(
@@ -115,13 +113,11 @@ CheckResult RemoteLinuxCheckForFreeDiskSpaceService::isDeploymentPossible() cons
return AbstractRemoteLinuxDeployService::isDeploymentPossible();
}
// RemoteLinuxCheckForFreeDiskSpaceStep
RemoteLinuxCheckForFreeDiskSpaceStep::RemoteLinuxCheckForFreeDiskSpaceStep
CheckForFreeDiskSpaceStep::CheckForFreeDiskSpaceStep
(BuildStepList *bsl, Id id)
: AbstractRemoteLinuxDeployStep(bsl, id)
{
auto service = createDeployService<RemoteLinuxCheckForFreeDiskSpaceService>();
auto service = createDeployService<CheckForFreeDiskSpaceService>();
auto pathToCheckAspect = addAspect<StringAspect>();
pathToCheckAspect->setSettingsKey("RemoteLinux.CheckForFreeDiskSpaceStep.PathToCheck");
@@ -144,14 +140,12 @@ RemoteLinuxCheckForFreeDiskSpaceStep::RemoteLinuxCheckForFreeDiskSpaceStep
});
}
RemoteLinuxCheckForFreeDiskSpaceStep::~RemoteLinuxCheckForFreeDiskSpaceStep() = default;
Id RemoteLinuxCheckForFreeDiskSpaceStep::stepId()
Id CheckForFreeDiskSpaceStep::stepId()
{
return "RemoteLinux.CheckForFreeDiskSpaceStep";
}
QString RemoteLinuxCheckForFreeDiskSpaceStep::displayName()
QString CheckForFreeDiskSpaceStep::displayName()
{
return tr("Check for free disk space");
}

View File

@@ -25,17 +25,18 @@
#pragma once
#include "remotelinux_export.h"
#include "abstractremotelinuxdeploystep.h"
namespace RemoteLinux {
class REMOTELINUX_EXPORT RemoteLinuxCheckForFreeDiskSpaceStep : public AbstractRemoteLinuxDeployStep
class REMOTELINUX_EXPORT CheckForFreeDiskSpaceStep : public AbstractRemoteLinuxDeployStep
{
Q_OBJECT
public:
RemoteLinuxCheckForFreeDiskSpaceStep(ProjectExplorer::BuildStepList *bsl, Utils::Id id);
~RemoteLinuxCheckForFreeDiskSpaceStep() override;
CheckForFreeDiskSpaceStep(ProjectExplorer::BuildStepList *bsl, Utils::Id id);
static Utils::Id stepId();
static QString displayName();

View File

@@ -23,8 +23,9 @@
**
****************************************************************************/
#include "remotelinuxcustomcommanddeploymentstep.h"
#include "customcommanddeploystep.h"
#include "abstractremotelinuxdeployservice.h"
#include "remotelinux_constants.h"
#include <projectexplorer/devicesupport/idevice.h>
@@ -38,14 +39,12 @@ using namespace Utils;
namespace RemoteLinux {
namespace Internal {
// RemoteLinuxCustomCommandDeployService
class RemoteLinuxCustomCommandDeployService : public AbstractRemoteLinuxDeployService
class CustomCommandDeployService : public AbstractRemoteLinuxDeployService
{
Q_DECLARE_TR_FUNCTIONS(RemoteLinux::Internal::RemoteLinuxCustomCommandDeployService)
Q_DECLARE_TR_FUNCTIONS(RemoteLinux::Internal::CustomCommandDeployService)
public:
RemoteLinuxCustomCommandDeployService();
CustomCommandDeployService();
void setCommandLine(const QString &commandLine);
@@ -60,7 +59,7 @@ protected:
QtcProcess m_process;
};
RemoteLinuxCustomCommandDeployService::RemoteLinuxCustomCommandDeployService()
CustomCommandDeployService::CustomCommandDeployService()
{
connect(&m_process, &QtcProcess::readyReadStandardOutput, this, [this] {
emit stdOutData(QString::fromUtf8(m_process.readAllStandardOutput()));
@@ -82,12 +81,12 @@ RemoteLinuxCustomCommandDeployService::RemoteLinuxCustomCommandDeployService()
});
}
void RemoteLinuxCustomCommandDeployService::setCommandLine(const QString &commandLine)
void CustomCommandDeployService::setCommandLine(const QString &commandLine)
{
m_commandLine = commandLine;
}
CheckResult RemoteLinuxCustomCommandDeployService::isDeploymentPossible() const
CheckResult CustomCommandDeployService::isDeploymentPossible() const
{
if (m_commandLine.isEmpty())
return CheckResult::failure(tr("No command line given."));
@@ -95,7 +94,7 @@ CheckResult RemoteLinuxCustomCommandDeployService::isDeploymentPossible() const
return AbstractRemoteLinuxDeployService::isDeploymentPossible();
}
void RemoteLinuxCustomCommandDeployService::doDeploy()
void CustomCommandDeployService::doDeploy()
{
emit progressMessage(tr("Starting remote command \"%1\"...").arg(m_commandLine));
m_process.setCommand({deviceConfiguration()->filePath("/bin/sh"),
@@ -103,7 +102,7 @@ void RemoteLinuxCustomCommandDeployService::doDeploy()
m_process.start();
}
void RemoteLinuxCustomCommandDeployService::stopDeployment()
void CustomCommandDeployService::stopDeployment()
{
m_process.close();
handleDeploymentDone();
@@ -111,14 +110,10 @@ void RemoteLinuxCustomCommandDeployService::stopDeployment()
} // Internal
// RemoteLinuxCustomCommandDeploymentStep
RemoteLinuxCustomCommandDeploymentStep::RemoteLinuxCustomCommandDeploymentStep
(BuildStepList *bsl, Utils::Id id)
CustomCommandDeployStep::CustomCommandDeployStep(BuildStepList *bsl, Utils::Id id)
: AbstractRemoteLinuxDeployStep(bsl, id)
{
auto service = createDeployService<Internal::RemoteLinuxCustomCommandDeployService>();
auto service = createDeployService<Internal::CustomCommandDeployService>();
auto commandLine = addAspect<StringAspect>();
commandLine->setSettingsKey("RemoteLinuxCustomCommandDeploymentStep.CommandLine");
@@ -134,14 +129,12 @@ RemoteLinuxCustomCommandDeploymentStep::RemoteLinuxCustomCommandDeploymentStep
addMacroExpander();
}
RemoteLinuxCustomCommandDeploymentStep::~RemoteLinuxCustomCommandDeploymentStep() = default;
Utils::Id RemoteLinuxCustomCommandDeploymentStep::stepId()
Utils::Id CustomCommandDeployStep::stepId()
{
return Constants::CustomCommandDeployStepId;
}
QString RemoteLinuxCustomCommandDeploymentStep::displayName()
QString CustomCommandDeployStep::displayName()
{
return tr("Run custom remote command");
}

View File

@@ -25,18 +25,18 @@
#pragma once
#include "remotelinux_export.h"
#include "abstractremotelinuxdeploystep.h"
namespace RemoteLinux {
class REMOTELINUX_EXPORT RemoteLinuxCustomCommandDeploymentStep
: public AbstractRemoteLinuxDeployStep
class REMOTELINUX_EXPORT CustomCommandDeployStep : public AbstractRemoteLinuxDeployStep
{
Q_OBJECT
public:
RemoteLinuxCustomCommandDeploymentStep(ProjectExplorer::BuildStepList *bsl, Utils::Id id);
~RemoteLinuxCustomCommandDeploymentStep() override;
CustomCommandDeployStep(ProjectExplorer::BuildStepList *bsl, Utils::Id id);
static Utils::Id stepId();
static QString displayName();

View File

@@ -27,6 +27,10 @@
#include <QVariantMap>
QT_BEGIN_NAMESPACE
class QDateTime;
QT_END_NAMESPACE
namespace ProjectExplorer {
class DeployableFile;
class Kit;

View File

@@ -27,8 +27,6 @@
#include <projectexplorer/devicesupport/idevicefactory.h>
#include <utils/fileutils.h>
namespace RemoteLinux {
namespace Internal {

View File

@@ -25,13 +25,16 @@
#pragma once
#include "abstractremotelinuxdeployservice.h"
#include "remotelinux_export.h"
#include "abstractremotelinuxdeployservice.h"
#include <QList>
QT_FORWARD_DECLARE_CLASS(QDateTime)
QT_FORWARD_DECLARE_CLASS(QString)
QT_BEGIN_NAMESPACE
class QDateTime;
class QString;
QT_END_NAMESPACE
namespace ProjectExplorer { class DeployableFile; }
namespace Utils { class QtcProcess; }

View File

@@ -25,9 +25,10 @@
#pragma once
#include "abstractremotelinuxdeploystep.h"
#include "remotelinux_export.h"
#include "abstractremotelinuxdeploystep.h"
namespace RemoteLinux {
class REMOTELINUX_EXPORT GenericDirectUploadStep : public AbstractRemoteLinuxDeployStep

View File

@@ -25,10 +25,10 @@
#pragma once
#include <projectexplorer/devicesupport/idevicewidget.h>
#include "remotelinux_export.h"
#include <projectexplorer/devicesupport/idevicewidget.h>
namespace Utils { class FilePath; }
namespace RemoteLinux {

View File

@@ -25,9 +25,10 @@
#pragma once
#include "linuxdevice.h"
#include "remotelinux_export.h"
#include "linuxdevice.h"
#include <QWizardPage>
namespace RemoteLinux {

View File

@@ -25,6 +25,7 @@
#include "killappstep.h"
#include "abstractremotelinuxdeployservice.h"
#include "remotelinux_constants.h"
#include <projectexplorer/devicesupport/idevice.h>

View File

@@ -25,6 +25,8 @@
#pragma once
#include "remotelinux_export.h"
#include "abstractremotelinuxdeploystep.h"
namespace RemoteLinux {

View File

@@ -27,9 +27,9 @@
#include "remotelinux_export.h"
#include <projectexplorer/devicesupport/filetransferinterface.h>
#include <projectexplorer/devicesupport/idevice.h>
namespace ProjectExplorer { enum class FileTransferMethod; }
namespace Utils { class ProcessResultData; }
namespace RemoteLinux {

View File

@@ -13,14 +13,16 @@ Project {
Depends { name: "ProjectExplorer" }
files: [
"abstractpackagingstep.cpp",
"abstractpackagingstep.h",
"abstractremotelinuxdeployservice.cpp",
"abstractremotelinuxdeployservice.h",
"abstractremotelinuxdeploystep.cpp",
"abstractremotelinuxdeploystep.h",
"deploymenttimeinfo.cpp",
"deploymenttimeinfo.h",
"checkforfreediskspacestep.cpp",
"checkforfreediskspacestep.h",
"customcommanddeploystep.cpp",
"customcommanddeploystep.h",
"genericdirectuploadservice.cpp",
"genericdirectuploadservice.h",
"genericdirectuploadstep.cpp",
@@ -47,10 +49,6 @@ Project {
"remotelinux.qrc",
"remotelinux_constants.h",
"remotelinux_export.h",
"remotelinuxcheckforfreediskspacestep.cpp",
"remotelinuxcheckforfreediskspacestep.h",
"remotelinuxcustomcommanddeploymentstep.cpp",
"remotelinuxcustomcommanddeploymentstep.h",
"remotelinuxcustomrunconfiguration.cpp",
"remotelinuxcustomrunconfiguration.h",
"remotelinuxdebugsupport.cpp",
@@ -63,8 +61,6 @@ Project {
"remotelinuxenvironmentaspectwidget.h",
"remotelinuxenvironmentreader.cpp",
"remotelinuxenvironmentreader.h",
"remotelinuxpackageinstaller.cpp",
"remotelinuxpackageinstaller.h",
"remotelinuxplugin.cpp",
"remotelinuxplugin.h",
"remotelinuxqmltoolingsupport.cpp",
@@ -73,8 +69,6 @@ Project {
"remotelinuxrunconfiguration.h",
"remotelinuxsignaloperation.cpp",
"remotelinuxsignaloperation.h",
"remotelinuxx11forwardingaspect.cpp",
"remotelinuxx11forwardingaspect.h",
"rsyncdeploystep.cpp",
"rsyncdeploystep.h",
"sshkeycreationdialog.cpp",
@@ -83,8 +77,10 @@ Project {
"sshprocessinterface.h",
"tarpackagecreationstep.cpp",
"tarpackagecreationstep.h",
"uploadandinstalltarpackagestep.cpp",
"uploadandinstalltarpackagestep.h",
"tarpackagedeploystep.cpp",
"tarpackagedeploystep.h",
"x11forwardingaspect.cpp",
"x11forwardingaspect.h",
"images/embeddedtarget.png",
]

View File

@@ -34,7 +34,7 @@ const char CheckForFreeDiskSpaceId[] = "RemoteLinux.CheckForFreeDiskSpaceStep";
const char DirectUploadStepId[] = "RemoteLinux.DirectUploadStep";
const char MakeInstallStepId[] = "RemoteLinux.MakeInstall";
const char TarPackageCreationStepId[] = "MaemoTarPackageCreationStep";
const char UploadAndInstallTarPackageStepId[] = "MaemoUploadAndInstallTarPackageStep";
const char TarPackageDeployStepId[] = "MaemoUploadAndInstallTarPackageStep";
const char RsyncDeployStepId[] = "RemoteLinux.RsyncDeployStep";
const char CustomCommandDeployStepId[] = "RemoteLinux.GenericRemoteLinuxCustomCommandDeploymentStep";
const char KillAppStepId[] = "RemoteLinux.KillAppStep";

View File

@@ -27,7 +27,7 @@
#include "remotelinux_constants.h"
#include "remotelinuxenvironmentaspect.h"
#include "remotelinuxx11forwardingaspect.h"
#include "x11forwardingaspect.h"
#include <projectexplorer/runconfigurationaspects.h>
#include <projectexplorer/runcontrol.h>

View File

@@ -25,9 +25,9 @@
#include "remotelinuxdeployconfiguration.h"
#include "checkforfreediskspacestep.h"
#include "genericdirectuploadstep.h"
#include "makeinstallstep.h"
#include "remotelinuxcheckforfreediskspacestep.h"
#include "killappstep.h"
#include "remotelinux_constants.h"
#include "rsyncdeploystep.h"
@@ -76,7 +76,7 @@ RemoteLinuxDeployConfigurationFactory::RemoteLinuxDeployConfigurationFactory()
});
addInitialStep(MakeInstallStep::stepId(), needsMakeInstall);
addInitialStep(RemoteLinuxCheckForFreeDiskSpaceStep::stepId());
addInitialStep(CheckForFreeDiskSpaceStep::stepId());
addInitialStep(KillAppStep::stepId());
addInitialStep(RsyncDeployStep::stepId(), [](Target *target) {
auto device = DeviceKitAspect::device(target->kit());

View File

@@ -25,9 +25,6 @@
#pragma once
#include "remotelinux_export.h"
#include <projectexplorer/buildsteplist.h>
#include <projectexplorer/deployconfiguration.h>
namespace RemoteLinux {

View File

@@ -26,7 +26,7 @@
#include "remotelinuxenvironmentaspectwidget.h"
#include "linuxdevice.h"
#include "remotelinuxrunconfiguration.h"
#include "remotelinuxenvironmentaspect.h"
#include "remotelinuxenvironmentreader.h"
#include <coreplugin/icore.h>
@@ -52,21 +52,22 @@ const QString FetchEnvButtonText
namespace RemoteLinux {
RemoteLinuxEnvironmentAspectWidget::RemoteLinuxEnvironmentAspectWidget
(RemoteLinuxEnvironmentAspect *aspect, Target *target) :
EnvironmentAspectWidget(aspect, new QPushButton)
(RemoteLinuxEnvironmentAspect *aspect, Target *target)
: EnvironmentAspectWidget(aspect)
, m_fetchButton(new QPushButton(FetchEnvButtonText))
{
addWidget(m_fetchButton);
IDevice::ConstPtr device = DeviceKitAspect::device(target->kit());
deviceEnvReader = new RemoteLinuxEnvironmentReader(device, this);
m_deviceEnvReader = new RemoteLinuxEnvironmentReader(device, this);
connect(target, &ProjectExplorer::Target::kitChanged,
deviceEnvReader, &RemoteLinuxEnvironmentReader::handleCurrentDeviceConfigChanged);
m_deviceEnvReader, &RemoteLinuxEnvironmentReader::handleCurrentDeviceConfigChanged);
QPushButton *button = fetchButton();
button->setText(FetchEnvButtonText);
connect(button, &QPushButton::clicked, this, &RemoteLinuxEnvironmentAspectWidget::fetchEnvironment);
connect(deviceEnvReader, &RemoteLinuxEnvironmentReader::finished,
connect(m_fetchButton, &QPushButton::clicked, this, &RemoteLinuxEnvironmentAspectWidget::fetchEnvironment);
connect(m_deviceEnvReader, &RemoteLinuxEnvironmentReader::finished,
this, &RemoteLinuxEnvironmentAspectWidget::fetchEnvironmentFinished);
connect(deviceEnvReader, &RemoteLinuxEnvironmentReader::error,
connect(m_deviceEnvReader, &RemoteLinuxEnvironmentReader::error,
this, &RemoteLinuxEnvironmentAspectWidget::fetchEnvironmentError);
const EnvironmentWidget::OpenTerminalFunc openTerminalFunc
@@ -85,36 +86,25 @@ RemoteLinuxEnvironmentAspectWidget::RemoteLinuxEnvironmentAspectWidget
envWidget()->setOpenTerminalFunc(openTerminalFunc);
}
RemoteLinuxEnvironmentAspect *RemoteLinuxEnvironmentAspectWidget::aspect() const
{
return dynamic_cast<RemoteLinuxEnvironmentAspect *>(EnvironmentAspectWidget::aspect());
}
QPushButton *RemoteLinuxEnvironmentAspectWidget::fetchButton() const
{
return qobject_cast<QPushButton *>(additionalWidget());
}
void RemoteLinuxEnvironmentAspectWidget::fetchEnvironment()
{
QPushButton *button = fetchButton();
disconnect(button, &QPushButton::clicked,
disconnect(m_fetchButton, &QPushButton::clicked,
this, &RemoteLinuxEnvironmentAspectWidget::fetchEnvironment);
connect(button, &QPushButton::clicked,
connect(m_fetchButton, &QPushButton::clicked,
this, &RemoteLinuxEnvironmentAspectWidget::stopFetchEnvironment);
button->setText(tr("Cancel Fetch Operation"));
deviceEnvReader->start();
m_fetchButton->setText(tr("Cancel Fetch Operation"));
m_deviceEnvReader->start();
}
void RemoteLinuxEnvironmentAspectWidget::fetchEnvironmentFinished()
{
QPushButton *button = fetchButton();
disconnect(button, &QPushButton::clicked,
disconnect(m_fetchButton, &QPushButton::clicked,
this, &RemoteLinuxEnvironmentAspectWidget::stopFetchEnvironment);
connect(button, &QPushButton::clicked,
connect(m_fetchButton, &QPushButton::clicked,
this, &RemoteLinuxEnvironmentAspectWidget::fetchEnvironment);
button->setText(FetchEnvButtonText);
aspect()->setRemoteEnvironment(deviceEnvReader->remoteEnvironment());
m_fetchButton->setText(FetchEnvButtonText);
qobject_cast<RemoteLinuxEnvironmentAspect *>(aspect())->setRemoteEnvironment(
m_deviceEnvReader->remoteEnvironment());
}
void RemoteLinuxEnvironmentAspectWidget::fetchEnvironmentError(const QString &error)
@@ -125,7 +115,7 @@ void RemoteLinuxEnvironmentAspectWidget::fetchEnvironmentError(const QString &er
void RemoteLinuxEnvironmentAspectWidget::stopFetchEnvironment()
{
deviceEnvReader->stop();
m_deviceEnvReader->stop();
fetchEnvironmentFinished();
}

View File

@@ -25,14 +25,16 @@
#pragma once
#include "remotelinuxenvironmentaspect.h"
#include <projectexplorer/environmentaspectwidget.h>
QT_FORWARD_DECLARE_CLASS(QPushButton)
QT_BEGIN_NAMESPACE
class QPushButton;
QT_END_NAMESPACE
namespace RemoteLinux {
class RemoteLinuxEnvironmentAspect;
namespace Internal { class RemoteLinuxEnvironmentReader; }
class RemoteLinuxEnvironmentAspectWidget : public ProjectExplorer::EnvironmentAspectWidget
@@ -43,16 +45,14 @@ public:
RemoteLinuxEnvironmentAspectWidget(RemoteLinuxEnvironmentAspect *aspect,
ProjectExplorer::Target *target);
RemoteLinuxEnvironmentAspect *aspect() const override;
QPushButton *fetchButton() const;
private:
void fetchEnvironment();
void fetchEnvironmentFinished();
void fetchEnvironmentError(const QString &error);
void stopFetchEnvironment();
Internal::RemoteLinuxEnvironmentReader *deviceEnvReader;
Internal::RemoteLinuxEnvironmentReader *m_deviceEnvReader = nullptr;
QPushButton *m_fetchButton = nullptr;
};
} // namespace RemoteLinux

View File

@@ -1,107 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "remotelinuxpackageinstaller.h"
#include <projectexplorer/devicesupport/idevice.h>
#include <utils/fileutils.h>
#include <utils/qtcassert.h>
#include <utils/qtcprocess.h>
using namespace ProjectExplorer;
using namespace Utils;
namespace RemoteLinux {
namespace Internal {
class AbstractRemoteLinuxPackageInstallerPrivate
{
public:
IDevice::ConstPtr m_device;
QtcProcess m_installer;
QtcProcess m_killer;
};
} // namespace Internal
AbstractRemoteLinuxPackageInstaller::AbstractRemoteLinuxPackageInstaller(QObject *parent)
: QObject(parent), d(new Internal::AbstractRemoteLinuxPackageInstallerPrivate)
{
connect(&d->m_installer, &QtcProcess::readyReadStandardOutput, this, [this] {
emit stdoutData(QString::fromUtf8(d->m_installer.readAllStandardOutput()));
});
connect(&d->m_installer, &QtcProcess::readyReadStandardError, this, [this] {
emit stderrData(QString::fromUtf8(d->m_installer.readAllStandardError()));
});
connect(&d->m_installer, &QtcProcess::finished, this, [this] {
const QString errorMessage = d->m_installer.result() == ProcessResult::FinishedWithSuccess
? QString() : tr("Installing package failed.") + d->m_installer.errorString();
emit finished(errorMessage);
});
}
AbstractRemoteLinuxPackageInstaller::~AbstractRemoteLinuxPackageInstaller() = default;
void AbstractRemoteLinuxPackageInstaller::installPackage(const IDevice::ConstPtr &deviceConfig,
const QString &packageFilePath, bool removePackageFile)
{
QTC_ASSERT(d->m_installer.state() == QProcess::NotRunning, return);
d->m_device = deviceConfig;
QString cmdLine = installCommandLine(packageFilePath);
if (removePackageFile)
cmdLine += QLatin1String(" && (rm ") + packageFilePath + QLatin1String(" || :)");
d->m_installer.setCommand({d->m_device->filePath("/bin/sh"), {"-c", cmdLine}});
d->m_installer.start();
}
void AbstractRemoteLinuxPackageInstaller::cancelInstallation()
{
QTC_ASSERT(d->m_installer.state() != QProcess::NotRunning, return);
d->m_killer.setCommand({d->m_device->filePath("/bin/sh"),
{"-c", cancelInstallationCommandLine()}});
d->m_killer.start();
d->m_installer.close();
}
RemoteLinuxTarPackageInstaller::RemoteLinuxTarPackageInstaller(QObject *parent)
: AbstractRemoteLinuxPackageInstaller(parent)
{
}
QString RemoteLinuxTarPackageInstaller::installCommandLine(const QString &packageFilePath) const
{
return QLatin1String("cd / && tar xvf ") + packageFilePath;
}
QString RemoteLinuxTarPackageInstaller::cancelInstallationCommandLine() const
{
return QLatin1String("pkill tar");
}
} // namespace RemoteLinux

View File

@@ -1,79 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include "remotelinux_export.h"
#include <projectexplorer/devicesupport/idevicefwd.h>
#include <QObject>
#include <memory>
namespace RemoteLinux {
namespace Internal { class AbstractRemoteLinuxPackageInstallerPrivate; }
class REMOTELINUX_EXPORT AbstractRemoteLinuxPackageInstaller : public QObject
{
Q_OBJECT
Q_DISABLE_COPY(AbstractRemoteLinuxPackageInstaller)
public:
~AbstractRemoteLinuxPackageInstaller() override;
void installPackage(const ProjectExplorer::IDeviceConstPtr &deviceConfig,
const QString &packageFilePath, bool removePackageFile);
void cancelInstallation();
signals:
void stdoutData(const QString &output);
void stderrData(const QString &output);
void finished(const QString &errorMsg = QString());
protected:
explicit AbstractRemoteLinuxPackageInstaller(QObject *parent = nullptr);
private:
virtual QString installCommandLine(const QString &packageFilePath) const = 0;
virtual QString cancelInstallationCommandLine() const = 0;
std::unique_ptr<Internal::AbstractRemoteLinuxPackageInstallerPrivate> d;
};
class REMOTELINUX_EXPORT RemoteLinuxTarPackageInstaller : public AbstractRemoteLinuxPackageInstaller
{
Q_OBJECT
public:
RemoteLinuxTarPackageInstaller(QObject *parent = nullptr);
private:
QString installCommandLine(const QString &packageFilePath) const override;
QString cancelInstallationCommandLine() const override;
};
} // namespace RemoteLinux

View File

@@ -25,23 +25,22 @@
#include "remotelinuxplugin.h"
#include "checkforfreediskspacestep.h"
#include "customcommanddeploystep.h"
#include "genericdirectuploadstep.h"
#include "killappstep.h"
#include "linuxdevice.h"
#include "makeinstallstep.h"
#include "remotelinux_constants.h"
#include "remotelinuxdeployconfiguration.h"
#include "remotelinuxqmltoolingsupport.h"
#include "remotelinuxcustomrunconfiguration.h"
#include "remotelinuxdebugsupport.h"
#include "remotelinuxdeployconfiguration.h"
#include "remotelinuxrunconfiguration.h"
#include "genericdirectuploadstep.h"
#include "makeinstallstep.h"
#include "remotelinuxcheckforfreediskspacestep.h"
#include "remotelinuxdeployconfiguration.h"
#include "remotelinuxcustomcommanddeploymentstep.h"
#include "killappstep.h"
#include "rsyncdeploystep.h"
#include "tarpackagecreationstep.h"
#include "uploadandinstalltarpackagestep.h"
#include "tarpackagedeploystep.h"
#ifdef WITH_TESTS
#include "filesystemaccess_test.h"
@@ -76,13 +75,11 @@ public:
RemoteLinuxCustomRunConfigurationFactory customRunConfigurationFactory;
RemoteLinuxDeployConfigurationFactory deployConfigurationFactory;
GenericDeployStepFactory<TarPackageCreationStep> tarPackageCreationStepFactory;
GenericDeployStepFactory<UploadAndInstallTarPackageStep> uploadAndInstallTarPackageStepFactory;
GenericDeployStepFactory<TarPackageDeployStep> tarPackageDeployStepFactory;
GenericDeployStepFactory<GenericDirectUploadStep> genericDirectUploadStepFactory;
GenericDeployStepFactory<RsyncDeployStep> rsyncDeployStepFactory;
GenericDeployStepFactory<RemoteLinuxCustomCommandDeploymentStep>
customCommandDeploymentStepFactory;
GenericDeployStepFactory<RemoteLinuxCheckForFreeDiskSpaceStep>
checkForFreeDiskSpaceStepFactory;
GenericDeployStepFactory<CustomCommandDeployStep> customCommandDeployStepFactory;
GenericDeployStepFactory<CheckForFreeDiskSpaceStep> checkForFreeDiskSpaceStepFactory;
GenericDeployStepFactory<KillAppStep> killAppStepFactory;
GenericDeployStepFactory<MakeInstallStep> makeInstallStepFactory;

View File

@@ -26,8 +26,8 @@
#include "remotelinuxrunconfiguration.h"
#include "remotelinux_constants.h"
#include "remotelinuxx11forwardingaspect.h"
#include "remotelinuxenvironmentaspect.h"
#include "x11forwardingaspect.h"
#include <projectexplorer/buildsystem.h>
#include <projectexplorer/buildtargetinfo.h>

View File

@@ -25,8 +25,6 @@
#pragma once
#include "remotelinux_export.h"
#include <projectexplorer/runconfiguration.h>
namespace RemoteLinux {

View File

@@ -25,9 +25,10 @@
#pragma once
#include "abstractremotelinuxdeploystep.h"
#include "remotelinux_export.h"
#include "abstractremotelinuxdeploystep.h"
namespace RemoteLinux {
class REMOTELINUX_EXPORT RsyncDeployStep : public AbstractRemoteLinuxDeployStep

View File

@@ -25,12 +25,10 @@
#pragma once
#include "remotelinux_export.h"
#include <utils/filepath.h>
#include <QDialog>
namespace Utils { class FilePath; }
namespace RemoteLinux {
namespace Ui { class SshKeyCreationDialog; }

View File

@@ -25,6 +25,7 @@
#include "tarpackagecreationstep.h"
#include "deploymenttimeinfo.h"
#include "remotelinux_constants.h"
#include <projectexplorer/buildmanager.h>
@@ -43,7 +44,7 @@ using namespace ProjectExplorer;
using namespace Utils;
namespace RemoteLinux {
namespace {
const char IgnoreMissingFilesKey[] = "RemoteLinux.TarPackageCreationStep.IgnoreMissingFiles";
const char IncrementalDeploymentKey[] = "RemoteLinux.TarPackageCreationStep.IncrementalDeployment";
@@ -68,20 +69,40 @@ struct TarFileHeader {
char padding[12];
};
} // Anonymous namespace.
namespace Internal {
TarPackageCreationStep::TarPackageCreationStep(BuildStepList *bsl, Utils::Id id)
: AbstractPackagingStep(bsl, id)
class TarPackageCreationStepPrivate
{
m_ignoreMissingFilesAspect = addAspect<BoolAspect>();
m_ignoreMissingFilesAspect->setLabel(tr("Ignore missing files"),
BoolAspect::LabelPlacement::AtCheckBox);
m_ignoreMissingFilesAspect->setSettingsKey(IgnoreMissingFilesKey);
public:
FilePath m_cachedPackageFilePath;
bool m_deploymentDataModified = false;
DeploymentTimeInfo m_deployTimes;
BoolAspect *m_incrementalDeploymentAspect = nullptr;
BoolAspect *m_ignoreMissingFilesAspect = nullptr;
bool m_packagingNeeded = false;
QList<DeployableFile> m_files;
};
m_incrementalDeploymentAspect = addAspect<BoolAspect>();
m_incrementalDeploymentAspect->setLabel(tr("Package modified files only"),
} // namespace Internal
TarPackageCreationStep::TarPackageCreationStep(BuildStepList *bsl, Id id)
: BuildStep(bsl, id)
, d(new Internal::TarPackageCreationStepPrivate)
{
connect(target(), &Target::deploymentDataChanged, this, [this] {
d->m_deploymentDataModified = true;
});
d->m_deploymentDataModified = true;
d->m_ignoreMissingFilesAspect = addAspect<BoolAspect>();
d->m_ignoreMissingFilesAspect->setLabel(tr("Ignore missing files"),
BoolAspect::LabelPlacement::AtCheckBox);
d->m_ignoreMissingFilesAspect->setSettingsKey(IgnoreMissingFilesKey);
d->m_incrementalDeploymentAspect = addAspect<BoolAspect>();
d->m_incrementalDeploymentAspect->setLabel(tr("Package modified files only"),
BoolAspect::LabelPlacement::AtCheckBox);
m_incrementalDeploymentAspect->setSettingsKey(IncrementalDeploymentKey);
d->m_incrementalDeploymentAspect->setSettingsKey(IncrementalDeploymentKey);
setSummaryUpdater([this] {
FilePath path = packageFilePath();
@@ -92,13 +113,30 @@ TarPackageCreationStep::TarPackageCreationStep(BuildStepList *bsl, Utils::Id id)
});
}
TarPackageCreationStep::~TarPackageCreationStep() = default;
Utils::Id TarPackageCreationStep::stepId()
{
return Constants::TarPackageCreationStepId;
}
QString TarPackageCreationStep::displayName()
{
return tr("Create tarball");
}
FilePath TarPackageCreationStep::packageFilePath() const
{
if (buildDirectory().isEmpty())
return {};
const QString packageFileName = project()->displayName() + QLatin1String(".tar");
return buildDirectory().pathAppended(packageFileName);
}
bool TarPackageCreationStep::init()
{
if (!AbstractPackagingStep::init())
return false;
m_packagingNeeded = isPackagingNeeded();
d->m_cachedPackageFilePath = packageFilePath();
d->m_packagingNeeded = isPackagingNeeded();
return true;
}
@@ -107,14 +145,76 @@ void TarPackageCreationStep::doRun()
runInThread([this] { return runImpl(); });
}
bool TarPackageCreationStep::fromMap(const QVariantMap &map)
{
if (!BuildStep::fromMap(map))
return false;
d->m_deployTimes.importDeployTimes(map);
return true;
}
QVariantMap TarPackageCreationStep::toMap() const
{
QVariantMap map = BuildStep::toMap();
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
map.insert(d->m_deployTimes.exportDeployTimes());
#else
map.unite(d->m_deployTimes.exportDeployTimes());
#endif
return map;
}
void TarPackageCreationStep::raiseError(const QString &errorMessage)
{
emit addTask(DeploymentTask(Task::Error, errorMessage));
emit addOutput(errorMessage, BuildStep::OutputFormat::Stderr);
}
void TarPackageCreationStep::raiseWarning(const QString &warningMessage)
{
emit addTask(DeploymentTask(Task::Warning, warningMessage));
emit addOutput(warningMessage, OutputFormat::ErrorMessage);
}
bool TarPackageCreationStep::isPackagingNeeded() const
{
const FilePath packagePath = packageFilePath();
if (!packagePath.exists() || d->m_deploymentDataModified)
return true;
const DeploymentData &dd = target()->deploymentData();
for (int i = 0; i < dd.fileCount(); ++i) {
if (dd.fileAt(i).localFilePath().isNewerThan(packagePath.lastModified()))
return true;
}
return false;
}
void TarPackageCreationStep::deployFinished(bool success)
{
disconnect(BuildManager::instance(), &BuildManager::buildQueueFinished,
this, &TarPackageCreationStep::deployFinished);
if (!success)
return;
const Kit *kit = target()->kit();
// Store files that have been tar'd and successfully deployed
const auto files = d->m_files;
for (const DeployableFile &file : files)
d->m_deployTimes.saveDeploymentTimeStamp(file, kit, QDateTime());
}
void TarPackageCreationStep::addNeededDeploymentFiles(
const ProjectExplorer::DeployableFile &deployable,
const ProjectExplorer::Kit *kit)
{
const QFileInfo fileInfo = deployable.localFilePath().toFileInfo();
if (!fileInfo.isDir()) {
if (m_deployTimes.hasLocalFileChanged(deployable, kit))
m_files << deployable;
if (d->m_deployTimes.hasLocalFileChanged(deployable, kit))
d->m_files << deployable;
return;
}
@@ -122,7 +222,7 @@ void TarPackageCreationStep::addNeededDeploymentFiles(
.entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
if (files.isEmpty()) {
m_files << deployable;
d->m_files << deployable;
return;
}
@@ -136,16 +236,43 @@ void TarPackageCreationStep::addNeededDeploymentFiles(
}
}
bool TarPackageCreationStep::runImpl()
{
const QList<DeployableFile> &files = target()->deploymentData().allFiles();
if (d->m_incrementalDeploymentAspect->value()) {
d->m_files.clear();
for (const DeployableFile &file : files)
addNeededDeploymentFiles(file, kit());
} else {
d->m_files = files;
}
const bool success = doPackage();
if (success) {
d->m_deploymentDataModified = false;
emit addOutput(tr("Packaging finished successfully."), OutputFormat::NormalMessage);
} else {
emit addOutput(tr("Packaging failed."), OutputFormat::ErrorMessage);
}
connect(BuildManager::instance(), &BuildManager::buildQueueFinished,
this, &TarPackageCreationStep::deployFinished);
return success;
}
bool TarPackageCreationStep::doPackage()
{
emit addOutput(tr("Creating tarball..."), OutputFormat::NormalMessage);
if (!m_packagingNeeded) {
if (!d->m_packagingNeeded) {
emit addOutput(tr("Tarball up to date, skipping packaging."), OutputFormat::NormalMessage);
return true;
}
// TODO: Optimization: Only package changed files
const FilePath tarFilePath = cachedPackageFilePath();
const FilePath tarFilePath = d->m_cachedPackageFilePath;
QFile tarFile(tarFilePath.toString());
if (!tarFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
@@ -154,7 +281,7 @@ bool TarPackageCreationStep::doPackage()
return false;
}
foreach (const DeployableFile &d, m_files) {
for (const DeployableFile &d : qAsConst(d->m_files)) {
if (d.remoteDirectory().isEmpty()) {
emit addOutput(tr("No remote path specified for file \"%1\", skipping.")
.arg(d.localFilePath().toUserOutput()), OutputFormat::ErrorMessage);
@@ -177,66 +304,6 @@ bool TarPackageCreationStep::doPackage()
return true;
}
bool TarPackageCreationStep::appendFile(QFile &tarFile, const QFileInfo &fileInfo,
const QString &remoteFilePath)
{
if (!writeHeader(tarFile, fileInfo, remoteFilePath))
return false;
if (fileInfo.isDir()) {
QDir dir(fileInfo.absoluteFilePath());
foreach (const QString &fileName,
dir.entryList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot)) {
const QString thisLocalFilePath = dir.path() + QLatin1Char('/') + fileName;
const QString thisRemoteFilePath = remoteFilePath + QLatin1Char('/') + fileName;
if (!appendFile(tarFile, QFileInfo(thisLocalFilePath), thisRemoteFilePath))
return false;
}
return true;
}
const QString nativePath = QDir::toNativeSeparators(fileInfo.filePath());
QFile file(fileInfo.filePath());
if (!file.open(QIODevice::ReadOnly)) {
const QString message = tr("Error reading file \"%1\": %2.")
.arg(nativePath, file.errorString());
if (m_ignoreMissingFilesAspect->value()) {
raiseWarning(message);
return true;
} else {
raiseError(message);
return false;
}
}
const int chunkSize = 1024*1024;
emit addOutput(tr("Adding file \"%1\" to tarball...").arg(nativePath),
OutputFormat::NormalMessage);
// TODO: Wasteful. Work with fixed-size buffer.
while (!file.atEnd() && file.error() == QFile::NoError && tarFile.error() == QFile::NoError) {
const QByteArray data = file.read(chunkSize);
tarFile.write(data);
if (isCanceled())
return false;
}
if (file.error() != QFile::NoError) {
raiseError(tr("Error reading file \"%1\": %2.").arg(nativePath, file.errorString()));
return false;
}
const int blockModulo = file.size() % TarBlockSize;
if (blockModulo != 0)
tarFile.write(QByteArray(TarBlockSize - blockModulo, 0));
if (tarFile.error() != QFile::NoError) {
raiseError(tr("Error writing tar file \"%1\": %2.")
.arg(QDir::toNativeSeparators(tarFile.fileName()), tarFile.errorString()));
return false;
}
return true;
}
static bool setFilePath(TarFileHeader &header, const QByteArray &filePath)
{
if (filePath.length() <= int(sizeof header.fileName)) {
@@ -257,13 +324,14 @@ static bool setFilePath(TarFileHeader &header, const QByteArray &filePath)
return false;
}
bool TarPackageCreationStep::writeHeader(QFile &tarFile, const QFileInfo &fileInfo,
const QString &remoteFilePath)
static bool writeHeader(QFile &tarFile, const QFileInfo &fileInfo, const QString &remoteFilePath,
const QString &cachedPackageFilePath, QString *errorMessage)
{
TarFileHeader header;
std::memset(&header, '\0', sizeof header);
if (!setFilePath(header, remoteFilePath.toUtf8())) {
raiseError(tr("Cannot add file \"%1\" to tar-archive: path too long.").arg(remoteFilePath));
*errorMessage = QCoreApplication::translate("RemoteLinux::TarPackageCreationStep",
"Cannot add file \"%1\" to tar-archive: path too long.").arg(remoteFilePath);
return false;
}
int permissions = (0400 * fileInfo.permission(QFile::ReadOwner))
@@ -308,89 +376,75 @@ bool TarPackageCreationStep::writeHeader(QFile &tarFile, const QFileInfo &fileIn
std::memcpy(&header.chksum, checksumString.data(), checksumString.length());
header.chksum[sizeof header.chksum-1] = 0;
if (!tarFile.write(reinterpret_cast<char *>(&header), sizeof header)) {
raiseError(tr("Error writing tar file \"%1\": %2")
.arg(cachedPackageFilePath().toUserOutput(), tarFile.errorString()));
*errorMessage = QCoreApplication::translate("RemoteLinux::TarPackageCreationStep",
"Error writing tar file \"%1\": %2").arg(cachedPackageFilePath, tarFile.errorString());
return false;
}
return true;
}
void TarPackageCreationStep::deployFinished(bool success)
bool TarPackageCreationStep::appendFile(QFile &tarFile, const QFileInfo &fileInfo,
const QString &remoteFilePath)
{
disconnect(BuildManager::instance(), &BuildManager::buildQueueFinished,
this, &TarPackageCreationStep::deployFinished);
if (!success)
return;
const Kit *kit = target()->kit();
// Store files that have been tar'd and successfully deployed
const auto files = m_files;
for (const DeployableFile &file : files)
m_deployTimes.saveDeploymentTimeStamp(file, kit, QDateTime());
}
QString TarPackageCreationStep::packageFileName() const
{
return project()->displayName() + QLatin1String(".tar");
}
bool TarPackageCreationStep::runImpl()
{
setPackagingStarted();
const QList<DeployableFile> &files = target()->deploymentData().allFiles();
if (m_incrementalDeploymentAspect->value()) {
m_files.clear();
for (const DeployableFile &file : files)
addNeededDeploymentFiles(file, kit());
} else {
m_files = files;
QString errorMessage;
if (!writeHeader(tarFile, fileInfo, remoteFilePath, d->m_cachedPackageFilePath.toUserOutput(),
&errorMessage)) {
raiseError(errorMessage);
return false;
}
if (fileInfo.isDir()) {
QDir dir(fileInfo.absoluteFilePath());
foreach (const QString &fileName,
dir.entryList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot)) {
const QString thisLocalFilePath = dir.path() + QLatin1Char('/') + fileName;
const QString thisRemoteFilePath = remoteFilePath + QLatin1Char('/') + fileName;
if (!appendFile(tarFile, QFileInfo(thisLocalFilePath), thisRemoteFilePath))
return false;
}
return true;
}
const bool success = doPackage();
const QString nativePath = QDir::toNativeSeparators(fileInfo.filePath());
QFile file(fileInfo.filePath());
if (!file.open(QIODevice::ReadOnly)) {
const QString message = tr("Error reading file \"%1\": %2.")
.arg(nativePath, file.errorString());
if (d->m_ignoreMissingFilesAspect->value()) {
raiseWarning(message);
return true;
} else {
raiseError(message);
return false;
}
}
setPackagingFinished(success);
if (success)
emit addOutput(tr("Packaging finished successfully."), OutputFormat::NormalMessage);
else
emit addOutput(tr("Packaging failed."), OutputFormat::ErrorMessage);
const int chunkSize = 1024*1024;
connect(BuildManager::instance(), &BuildManager::buildQueueFinished,
this, &TarPackageCreationStep::deployFinished);
emit addOutput(tr("Adding file \"%1\" to tarball...").arg(nativePath),
OutputFormat::NormalMessage);
return success;
}
bool TarPackageCreationStep::fromMap(const QVariantMap &map)
{
if (!AbstractPackagingStep::fromMap(map))
// TODO: Wasteful. Work with fixed-size buffer.
while (!file.atEnd() && file.error() == QFile::NoError && tarFile.error() == QFile::NoError) {
const QByteArray data = file.read(chunkSize);
tarFile.write(data);
if (isCanceled())
return false;
}
if (file.error() != QFile::NoError) {
raiseError(tr("Error reading file \"%1\": %2.").arg(nativePath, file.errorString()));
return false;
m_deployTimes.importDeployTimes(map);
}
const int blockModulo = file.size() % TarBlockSize;
if (blockModulo != 0)
tarFile.write(QByteArray(TarBlockSize - blockModulo, 0));
if (tarFile.error() != QFile::NoError) {
raiseError(tr("Error writing tar file \"%1\": %2.")
.arg(QDir::toNativeSeparators(tarFile.fileName()), tarFile.errorString()));
return false;
}
return true;
}
QVariantMap TarPackageCreationStep::toMap() const
{
QVariantMap map = AbstractPackagingStep::toMap();
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
map.insert(m_deployTimes.exportDeployTimes());
#else
map.unite(m_deployTimes.exportDeployTimes());
#endif
return map;
}
Utils::Id TarPackageCreationStep::stepId()
{
return Constants::TarPackageCreationStepId;
}
QString TarPackageCreationStep::displayName()
{
return tr("Create tarball");
}
} // namespace RemoteLinux

View File

@@ -25,63 +25,51 @@
#pragma once
#include "abstractpackagingstep.h"
#include "deploymenttimeinfo.h"
#include "remotelinux_export.h"
#include <projectexplorer/deployablefile.h>
#include <utils/aspects.h>
#include <projectexplorer/buildstep.h>
QT_BEGIN_NAMESPACE
class QFile;
class QFileInfo;
QT_END_NAMESPACE
namespace ProjectExplorer { class DeployableFile; }
namespace RemoteLinux {
class REMOTELINUX_EXPORT TarPackageCreationStep : public AbstractPackagingStep
namespace Internal { class TarPackageCreationStepPrivate; }
class REMOTELINUX_EXPORT TarPackageCreationStep : public ProjectExplorer::BuildStep
{
Q_OBJECT
public:
TarPackageCreationStep(ProjectExplorer::BuildStepList *bsl, Utils::Id id);
explicit TarPackageCreationStep(ProjectExplorer::BuildStepList *bsl, Utils::Id id);
~TarPackageCreationStep() override;
static Utils::Id stepId();
static QString displayName();
void setIgnoreMissingFiles(bool ignoreMissingFiles);
bool ignoreMissingFiles() const;
void setIncrementalDeployment(bool incrementalDeployment);
bool isIncrementalDeployment() const;
Utils::FilePath packageFilePath() const;
private:
bool init() override;
void doRun() override;
void deployFinished(bool success);
void addNeededDeploymentFiles(const ProjectExplorer::DeployableFile &deployable,
const ProjectExplorer::Kit *kit);
bool fromMap(const QVariantMap &map) override;
QVariantMap toMap() const override;
QString packageFileName() const override;
void raiseError(const QString &errorMessage);
void raiseWarning(const QString &warningMessage);
bool isPackagingNeeded() const;
void deployFinished(bool success);
void addNeededDeploymentFiles(const ProjectExplorer::DeployableFile &deployable,
const ProjectExplorer::Kit *kit);
bool runImpl();
bool doPackage();
bool appendFile(QFile &tarFile, const QFileInfo &fileInfo,
const QString &remoteFilePath);
bool writeHeader(QFile &tarFile, const QFileInfo &fileInfo,
const QString &remoteFilePath);
bool appendFile(QFile &tarFile, const QFileInfo &fileInfo, const QString &remoteFilePath);
DeploymentTimeInfo m_deployTimes;
Utils::BoolAspect *m_incrementalDeploymentAspect = nullptr;
Utils::BoolAspect *m_ignoreMissingFilesAspect = nullptr;
bool m_packagingNeeded = false;
QList<ProjectExplorer::DeployableFile> m_files;
std::unique_ptr<Internal::TarPackageCreationStepPrivate> d;
};
} // namespace RemoteLinux

View File

@@ -23,10 +23,10 @@
**
****************************************************************************/
#include "uploadandinstalltarpackagestep.h"
#include "tarpackagedeploystep.h"
#include "abstractremotelinuxdeployservice.h"
#include "remotelinux_constants.h"
#include "remotelinuxpackageinstaller.h"
#include "tarpackagecreationstep.h"
#include <projectexplorer/deployconfiguration.h>
@@ -34,6 +34,7 @@
#include <projectexplorer/devicesupport/idevice.h>
#include <utils/processinterface.h>
#include <utils/qtcprocess.h>
#include <QDateTime>
@@ -43,12 +44,73 @@ using namespace Utils;
namespace RemoteLinux {
namespace Internal {
class UploadAndInstallTarPackageService : public AbstractRemoteLinuxDeployService
class TarPackageInstaller : public QObject
{
Q_OBJECT
public:
UploadAndInstallTarPackageService();
TarPackageInstaller(QObject *parent = nullptr);
void installPackage(const ProjectExplorer::IDeviceConstPtr &deviceConfig,
const QString &packageFilePath, bool removePackageFile);
void cancelInstallation();
signals:
void stdoutData(const QString &output);
void stderrData(const QString &output);
void finished(const QString &errorMsg = QString());
private:
IDevice::ConstPtr m_device;
QtcProcess m_installer;
QtcProcess m_killer;
};
TarPackageInstaller::TarPackageInstaller(QObject *parent)
: QObject(parent)
{
connect(&m_installer, &QtcProcess::readyReadStandardOutput, this, [this] {
emit stdoutData(QString::fromUtf8(m_installer.readAllStandardOutput()));
});
connect(&m_installer, &QtcProcess::readyReadStandardError, this, [this] {
emit stderrData(QString::fromUtf8(m_installer.readAllStandardError()));
});
connect(&m_installer, &QtcProcess::finished, this, [this] {
const QString errorMessage = m_installer.result() == ProcessResult::FinishedWithSuccess
? QString() : tr("Installing package failed.") + m_installer.errorString();
emit finished(errorMessage);
});
}
void TarPackageInstaller::installPackage(const IDevice::ConstPtr &deviceConfig,
const QString &packageFilePath, bool removePackageFile)
{
QTC_ASSERT(m_installer.state() == QProcess::NotRunning, return);
m_device = deviceConfig;
QString cmdLine = QLatin1String("cd / && tar xvf ") + packageFilePath;
if (removePackageFile)
cmdLine += QLatin1String(" && (rm ") + packageFilePath + QLatin1String(" || :)");
m_installer.setCommand({m_device->filePath("/bin/sh"), {"-c", cmdLine}});
m_installer.start();
}
void TarPackageInstaller::cancelInstallation()
{
QTC_ASSERT(m_installer.state() != QProcess::NotRunning, return);
m_killer.setCommand({m_device->filePath("/bin/sh"), {"-c", "pkill tar"}});
m_killer.start();
m_installer.close();
}
class TarPackageDeployService : public AbstractRemoteLinuxDeployService
{
Q_OBJECT
public:
TarPackageDeployService();
void setPackageFilePath(const FilePath &filePath);
private:
@@ -68,33 +130,33 @@ private:
State m_state = Inactive;
FileTransfer m_uploader;
FilePath m_packageFilePath;
RemoteLinuxTarPackageInstaller m_installer;
TarPackageInstaller m_installer;
};
UploadAndInstallTarPackageService::UploadAndInstallTarPackageService()
TarPackageDeployService::TarPackageDeployService()
{
connect(&m_uploader, &FileTransfer::done, this,
&UploadAndInstallTarPackageService::handleUploadFinished);
&TarPackageDeployService::handleUploadFinished);
connect(&m_uploader, &FileTransfer::progress, this,
&UploadAndInstallTarPackageService::progressMessage);
&TarPackageDeployService::progressMessage);
}
void UploadAndInstallTarPackageService::setPackageFilePath(const FilePath &filePath)
void TarPackageDeployService::setPackageFilePath(const FilePath &filePath)
{
m_packageFilePath = filePath;
}
QString UploadAndInstallTarPackageService::uploadDir() const
QString TarPackageDeployService::uploadDir() const
{
return QLatin1String("/tmp");
}
bool UploadAndInstallTarPackageService::isDeploymentNecessary() const
bool TarPackageDeployService::isDeploymentNecessary() const
{
return hasLocalFileChanged(DeployableFile(m_packageFilePath, {}));
}
void UploadAndInstallTarPackageService::doDeploy()
void TarPackageDeployService::doDeploy()
{
QTC_ASSERT(m_state == Inactive, return);
@@ -107,7 +169,7 @@ void UploadAndInstallTarPackageService::doDeploy()
m_uploader.start();
}
void UploadAndInstallTarPackageService::stopDeployment()
void TarPackageDeployService::stopDeployment()
{
switch (m_state) {
case Inactive:
@@ -124,7 +186,7 @@ void UploadAndInstallTarPackageService::stopDeployment()
}
}
void UploadAndInstallTarPackageService::handleUploadFinished(const ProcessResultData &resultData)
void TarPackageDeployService::handleUploadFinished(const ProcessResultData &resultData)
{
QTC_ASSERT(m_state == Uploading, return);
@@ -138,16 +200,16 @@ void UploadAndInstallTarPackageService::handleUploadFinished(const ProcessResult
const QString remoteFilePath = uploadDir() + '/' + m_packageFilePath.fileName();
m_state = Installing;
emit progressMessage(tr("Installing package to device..."));
connect(&m_installer, &AbstractRemoteLinuxPackageInstaller::stdoutData,
connect(&m_installer, &TarPackageInstaller::stdoutData,
this, &AbstractRemoteLinuxDeployService::stdOutData);
connect(&m_installer, &AbstractRemoteLinuxPackageInstaller::stderrData,
connect(&m_installer, &TarPackageInstaller::stderrData,
this, &AbstractRemoteLinuxDeployService::stdErrData);
connect(&m_installer, &AbstractRemoteLinuxPackageInstaller::finished,
this, &UploadAndInstallTarPackageService::handleInstallationFinished);
connect(&m_installer, &TarPackageInstaller::finished,
this, &TarPackageDeployService::handleInstallationFinished);
m_installer.installPackage(deviceConfiguration(), remoteFilePath, true);
}
void UploadAndInstallTarPackageService::handleInstallationFinished(const QString &errorMsg)
void TarPackageDeployService::handleInstallationFinished(const QString &errorMsg)
{
QTC_ASSERT(m_state == Installing, return);
@@ -160,7 +222,7 @@ void UploadAndInstallTarPackageService::handleInstallationFinished(const QString
setFinished();
}
void UploadAndInstallTarPackageService::setFinished()
void TarPackageDeployService::setFinished()
{
m_state = Inactive;
m_uploader.stop();
@@ -172,10 +234,10 @@ void UploadAndInstallTarPackageService::setFinished()
using namespace Internal;
UploadAndInstallTarPackageStep::UploadAndInstallTarPackageStep(BuildStepList *bsl, Id id)
TarPackageDeployStep::TarPackageDeployStep(BuildStepList *bsl, Id id)
: AbstractRemoteLinuxDeployStep(bsl, id)
{
auto service = createDeployService<UploadAndInstallTarPackageService>();
auto service = createDeployService<TarPackageDeployService>();
setWidgetExpandedByDefault(false);
@@ -185,7 +247,7 @@ UploadAndInstallTarPackageStep::UploadAndInstallTarPackageStep(BuildStepList *bs
for (BuildStep *step : deployConfiguration()->stepList()->steps()) {
if (step == this)
break;
if ((pStep = dynamic_cast<TarPackageCreationStep *>(step)))
if ((pStep = qobject_cast<TarPackageCreationStep *>(step)))
break;
}
if (!pStep)
@@ -196,16 +258,16 @@ UploadAndInstallTarPackageStep::UploadAndInstallTarPackageStep(BuildStepList *bs
});
}
Id UploadAndInstallTarPackageStep::stepId()
Id TarPackageDeployStep::stepId()
{
return Constants::UploadAndInstallTarPackageStepId;
return Constants::TarPackageDeployStepId;
}
QString UploadAndInstallTarPackageStep::displayName()
QString TarPackageDeployStep::displayName()
{
return tr("Deploy tarball via SFTP upload");
}
} //namespace RemoteLinux
#include "uploadandinstalltarpackagestep.moc"
#include "tarpackagedeploystep.moc"

View File

@@ -28,14 +28,13 @@
#include "abstractremotelinuxdeploystep.h"
namespace RemoteLinux {
class AbstractRemoteLinuxPackageInstaller;
class REMOTELINUX_EXPORT UploadAndInstallTarPackageStep : public AbstractRemoteLinuxDeployStep
class TarPackageDeployStep : public AbstractRemoteLinuxDeployStep
{
Q_OBJECT
public:
UploadAndInstallTarPackageStep(ProjectExplorer::BuildStepList *bsl, Utils::Id id);
TarPackageDeployStep(ProjectExplorer::BuildStepList *bsl, Utils::Id id);
static Utils::Id stepId();
static QString displayName();

View File

@@ -23,7 +23,7 @@
**
****************************************************************************/
#include "remotelinuxx11forwardingaspect.h"
#include "x11forwardingaspect.h"
#include <utils/macroexpander.h>
#include <utils/qtcassert.h>

View File

@@ -242,28 +242,17 @@ void LauncherSocketHandler::handleStopPacket()
m_packetParser.token(),
m_packetParser.packetData());
if (packet.signalType == StopProcessPacket::SignalType::Terminate) {
switch (packet.signalType) {
case StopProcessPacket::SignalType::Terminate:
process->terminate();
return;
break;
case StopProcessPacket::SignalType::Kill:
process->kill();
break;
case StopProcessPacket::SignalType::Close:
removeProcess(process->token());
break;
}
if (process->state() == QProcess::NotRunning) {
// This shouldn't happen, since as soon as process finishes or error occurrs
// the process is being removed.
logWarn("Got stop request when process was not running");
} else {
// We got the client request to stop the starting / running process.
// We report process exit to the client.
ProcessDonePacket packet(process->token());
packet.error = QProcess::Crashed;
packet.exitCode = -1;
packet.exitStatus = QProcess::CrashExit;
if (process->processChannelMode() != QProcess::MergedChannels)
packet.stdErr = process->readAllStandardError();
packet.stdOut = process->readAllStandardOutput();
sendPacket(packet);
}
removeProcess(process->token());
}
void LauncherSocketHandler::handleShutdownPacket()