diff --git a/src/plugins/projectexplorer/deployablefile.cpp b/src/plugins/projectexplorer/deployablefile.cpp index 46acd15343fe019abd6ef0711a55ffde68194708..967b05a538552a75a7d850546de155ff329ecef3 100644 --- a/src/plugins/projectexplorer/deployablefile.cpp +++ b/src/plugins/projectexplorer/deployablefile.cpp @@ -38,16 +38,17 @@ using namespace Utils; namespace ProjectExplorer { DeployableFile::DeployableFile() + : m_type(TypeNormal) { } -DeployableFile::DeployableFile(const QString &localFilePath, const QString &remoteDir) - : m_localFilePath(FileName::fromUserInput(localFilePath)), m_remoteDir(remoteDir) +DeployableFile::DeployableFile(const QString &localFilePath, const QString &remoteDir, Type type) + : m_localFilePath(FileName::fromUserInput(localFilePath)), m_remoteDir(remoteDir), m_type(type) { } -DeployableFile::DeployableFile(const FileName &localFilePath, const QString &remoteDir) - : m_localFilePath(localFilePath), m_remoteDir(remoteDir) +DeployableFile::DeployableFile(const FileName &localFilePath, const QString &remoteDir, Type type) + : m_localFilePath(localFilePath), m_remoteDir(remoteDir), m_type(type) { } @@ -62,6 +63,11 @@ bool DeployableFile::isValid() const return !m_localFilePath.toString().isEmpty() && !m_remoteDir.isEmpty(); } +bool DeployableFile::isExecutable() const +{ + return m_type == TypeExecutable; +} + uint qHash(const DeployableFile &d) { return qHash(qMakePair(d.localFilePath().toString(), d.remoteDirectory())); diff --git a/src/plugins/projectexplorer/deployablefile.h b/src/plugins/projectexplorer/deployablefile.h index ab67311d0693d62bd2db645a4dd20cfa39561490..6fe5207c90b79e82a9e42d44ea24b937b6cae94a 100644 --- a/src/plugins/projectexplorer/deployablefile.h +++ b/src/plugins/projectexplorer/deployablefile.h @@ -41,9 +41,17 @@ namespace ProjectExplorer { class PROJECTEXPLORER_EXPORT DeployableFile { public: + enum Type + { + TypeNormal, + TypeExecutable + }; + DeployableFile(); - DeployableFile(const QString &m_localFilePath, const QString &m_remoteDir); - DeployableFile(const Utils::FileName &localFilePath, const QString &remoteDir); + DeployableFile(const QString &m_localFilePath, const QString &m_remoteDir, + Type type = TypeNormal); + DeployableFile(const Utils::FileName &localFilePath, const QString &remoteDir, + Type type = TypeNormal); Utils::FileName localFilePath() const { return m_localFilePath; } QString remoteDirectory() const { return m_remoteDir; } @@ -51,9 +59,12 @@ public: bool isValid() const; + bool isExecutable() const; + private: Utils::FileName m_localFilePath; QString m_remoteDir; + Type m_type; }; diff --git a/src/plugins/projectexplorer/deploymentdata.h b/src/plugins/projectexplorer/deploymentdata.h index 06a5ce9799bffaea5b51d89f7f4a1aa1a7754c78..1a2330429e7b9f7900ec2e30d9cb0422b93e341b 100644 --- a/src/plugins/projectexplorer/deploymentdata.h +++ b/src/plugins/projectexplorer/deploymentdata.h @@ -48,9 +48,10 @@ public: m_files << file; } - void addFile(const QString &localFilePath, const QString &remoteDirectory) + void addFile(const QString &localFilePath, const QString &remoteDirectory, + DeployableFile::Type type = DeployableFile::TypeNormal) { - addFile(DeployableFile(localFilePath, remoteDirectory)); + addFile(DeployableFile(localFilePath, remoteDirectory, type)); } int fileCount() const { return m_files.count(); } diff --git a/src/plugins/qt4projectmanager/qt4project.cpp b/src/plugins/qt4projectmanager/qt4project.cpp index 0a7f01e5a3eddca913d2d481572e291be78ad07f..eed22d62ae98150dc9a6f28d9afc54838bb22389 100644 --- a/src/plugins/qt4projectmanager/qt4project.cpp +++ b/src/plugins/qt4projectmanager/qt4project.cpp @@ -1473,7 +1473,8 @@ void Qt4Project::collectData(const Qt4ProFileNode *node, DeploymentData &deploym switch (node->projectType()) { case ApplicationTemplate: if (!installsList.targetPath.isEmpty()) - deploymentData.addFile(node->targetInformation().executable, installsList.targetPath); + deploymentData.addFile(node->targetInformation().executable, installsList.targetPath, + DeployableFile::TypeExecutable); break; case LibraryTemplate: collectLibraryData(node, deploymentData); diff --git a/src/plugins/remotelinux/deployablefile.h b/src/plugins/remotelinux/deployablefile.h index 2e08884c6dc9359c1e0812e9349ff20320c9eb41..452850207d75a45e3e612c85f1fb5de3f8365aeb 100644 --- a/src/plugins/remotelinux/deployablefile.h +++ b/src/plugins/remotelinux/deployablefile.h @@ -41,10 +41,16 @@ namespace RemoteLinux { class REMOTELINUX_EXPORT DeployableFile { public: + enum Type + { + TypeNormal, + TypeExecutable + }; + DeployableFile() {} - DeployableFile(const QString &localFilePath, const QString &remoteDir) - : localFilePath(localFilePath), remoteDir(remoteDir) {} + DeployableFile(const QString &localFilePath, const QString &remoteDir, Type type = TypeNormal) + : localFilePath(localFilePath), remoteDir(remoteDir), type(type) {} bool operator==(const DeployableFile &other) const { @@ -56,8 +62,13 @@ public: return remoteDir + QLatin1Char('/') + QFileInfo(localFilePath).fileName(); } + bool isExecutable() const { + return type == TypeExecutable; + } + QString localFilePath; QString remoteDir; + Type type; }; inline uint qHash(const DeployableFile &d) diff --git a/src/plugins/remotelinux/deployablefilesperprofile.cpp b/src/plugins/remotelinux/deployablefilesperprofile.cpp index ee3cf3a1849d47bafaf467c087b20b343dd8c7e9..9c7465faea0c8f84448baa8ad5c4924cff57cf39 100644 --- a/src/plugins/remotelinux/deployablefilesperprofile.cpp +++ b/src/plugins/remotelinux/deployablefilesperprofile.cpp @@ -77,7 +77,7 @@ DeployableFilesPerProFile::DeployableFilesPerProFile(const Qt4ProFileNode *proFi if (hasTargetPath()) { if (d->projectType == ApplicationTemplate) { d->deployables.prepend(DeployableFile(localExecutableFilePath(), - d->installsList.targetPath)); + d->installsList.targetPath, DeployableFile::TypeExecutable)); } else if (d->projectType == LibraryTemplate) { foreach (const QString &filePath, localLibraryFilePaths()) { d->deployables.prepend(DeployableFile(filePath, diff --git a/src/plugins/remotelinux/genericdirectuploadservice.cpp b/src/plugins/remotelinux/genericdirectuploadservice.cpp index 8e4a0ff11a50c321ecba99b812a1217b7eb2c079..179401ba4593b6dd9af7340d929c6c563f23aace 100644 --- a/src/plugins/remotelinux/genericdirectuploadservice.cpp +++ b/src/plugins/remotelinux/genericdirectuploadservice.cpp @@ -61,6 +61,7 @@ public: SftpChannel::Ptr uploader; SshRemoteProcess::Ptr mkdirProc; SshRemoteProcess::Ptr lnProc; + SshRemoteProcess::Ptr chmodProc; QList<DeployableFile> deployableFiles; }; @@ -173,13 +174,19 @@ void GenericDirectUploadService::handleUploadFinished(QSsh::SftpJobId jobId, con } else { saveDeploymentTimeStamp(df); - // Terrible hack for Windows. - if (df.remoteDir.contains(QLatin1String("bin"))) { + // This is done for Windows. + if (df.isExecutable()) { const QString command = QLatin1String("chmod a+x ") + df.remoteFilePath(); - connection()->createRemoteProcess(command.toUtf8())->start(); + d->chmodProc = connection()->createRemoteProcess(command.toUtf8()); + connect(d->chmodProc.data(), SIGNAL(closed(int)), SLOT(handleChmodFinished(int))); + connect(d->chmodProc.data(), SIGNAL(readyReadStandardOutput()), + SLOT(handleStdOutData())); + connect(d->chmodProc.data(), SIGNAL(readyReadStandardError()), + SLOT(handleStdErrData())); + d->chmodProc->start(); + } else { + uploadNextFile(); } - - uploadNextFile(); } } @@ -205,6 +212,25 @@ void GenericDirectUploadService::handleLnFinished(int exitStatus) } } +void GenericDirectUploadService::handleChmodFinished(int exitStatus) +{ + QTC_ASSERT(d->state == Uploading, setFinished(); return); + + if (d->stopRequested) { + setFinished(); + handleDeploymentDone(); + return; + } + + if (exitStatus != SshRemoteProcess::NormalExit || d->chmodProc->exitCode() != 0) { + emit errorMessage(tr("Failed to set executable flag.")); + setFinished(); + handleDeploymentDone(); + return; + } + uploadNextFile(); +} + void GenericDirectUploadService::handleMkdirFinished(int exitStatus) { QTC_ASSERT(d->state == Uploading, setFinished(); return); diff --git a/src/plugins/remotelinux/genericdirectuploadservice.h b/src/plugins/remotelinux/genericdirectuploadservice.h index a36ba3e07d59c0c564f18094266d1d77e7b0efd8..e20a113fdb0d5e4e99ce3cae8e08e096a9a3e4aa 100644 --- a/src/plugins/remotelinux/genericdirectuploadservice.h +++ b/src/plugins/remotelinux/genericdirectuploadservice.h @@ -67,6 +67,7 @@ private slots: void handleUploadFinished(QSsh::SftpJobId jobId, const QString &errorMsg); void handleMkdirFinished(int exitStatus); void handleLnFinished(int exitStatus); + void handleChmodFinished(int exitStatus); void handleStdOutData(); void handleStdErrData();