CQtDeployer/Deploy/filemanager.cpp

504 lines
15 KiB
C++
Raw Normal View History

2019-09-23 16:46:57 +03:00
/*
2019-12-08 13:57:20 +03:00
* Copyright (C) 2018-2020 QuasarApp.
2019-09-23 16:46:57 +03:00
* Distributed under the lgplv3 software license, see the accompanying
* Everyone is permitted to copy and distribute verbatim copies
* of this license document, but changing it is not allowed.
*/
2019-12-23 15:23:01 +03:00
2019-09-04 12:01:33 +03:00
#include "filemanager.h"
2019-09-03 18:15:05 +03:00
#include <QDir>
#include <quasarapp.h>
2019-09-25 12:32:05 +03:00
#include "configparser.h"
2019-09-03 18:15:05 +03:00
#include "deploycore.h"
2019-09-03 19:36:06 +03:00
#include <QProcess>
2019-09-03 18:15:05 +03:00
#include <fstream>
2019-12-20 17:25:20 +03:00
#include "pathutils.h"
2019-09-03 18:15:05 +03:00
2019-12-23 15:23:01 +03:00
#ifdef Q_OS_WIN
#include "windows.h"
#endif
2019-09-04 12:01:33 +03:00
FileManager::FileManager() {
2019-09-03 18:15:05 +03:00
}
2019-09-04 12:01:33 +03:00
bool FileManager::initDir(const QString &path) {
2019-09-03 18:15:05 +03:00
if (!QFileInfo::exists(path)) {
2019-09-03 19:36:06 +03:00
addToDeployed(path);
2019-09-03 18:15:05 +03:00
if (!QDir().mkpath(path)) {
return false;
}
}
return true;
}
2019-09-04 12:01:33 +03:00
QSet<QString> FileManager::getDeployedFiles() const {
2019-09-03 19:36:06 +03:00
return _deployedFiles;
}
2019-09-04 12:01:33 +03:00
QStringList FileManager::getDeployedFilesStringList() const {
2020-02-20 10:35:00 +03:00
return _deployedFiles.values();
2019-09-03 19:36:06 +03:00
}
2019-09-04 12:01:33 +03:00
void FileManager::loadDeployemendFiles(const QString &targetDir) {
auto settings = QuasarAppUtils::Settings::get();
2019-09-28 16:44:39 +03:00
if (targetDir.isEmpty())
return;
2019-09-23 17:59:36 +03:00
QStringList deployedFiles = settings->getValue(targetDir, "").toStringList();
2019-09-04 12:01:33 +03:00
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
_deployedFiles.unite(deployedFiles.toSet());
#else
2020-02-20 10:35:00 +03:00
_deployedFiles.unite(QSet<QString>(deployedFiles.begin(), deployedFiles.end()));
#endif
2019-09-03 19:36:06 +03:00
}
2019-09-04 12:01:33 +03:00
bool FileManager::addToDeployed(const QString& path) {
2019-09-03 19:36:06 +03:00
auto info = QFileInfo(path);
if (info.isFile() || !info.exists()) {
_deployedFiles += info.absoluteFilePath();
auto completeSufix = info.completeSuffix();
if (info.isFile() && (completeSufix.isEmpty() || completeSufix.toLower() == "run"
|| completeSufix.toLower() == "sh")) {
2019-09-03 19:36:06 +03:00
if (!QFile::setPermissions(path, static_cast<QFile::Permission>(0x7777))) {
2020-04-04 15:43:46 +03:00
QuasarAppUtils::Params::log("permishens set fail", QuasarAppUtils::Warning);
2019-09-03 19:36:06 +03:00
}
}
2019-12-23 15:23:01 +03:00
#ifdef Q_OS_WIN
if (info.isFile()) {
auto stdString = QDir::toNativeSeparators(info.absoluteFilePath()).toStdString();
DWORD attribute = GetFileAttributesA(stdString.c_str());
if (!SetFileAttributesA(stdString.c_str(), attribute & static_cast<DWORD>(~FILE_ATTRIBUTE_HIDDEN))) {
2020-04-04 16:21:44 +03:00
QuasarAppUtils::Params::log("attribute set fail", QuasarAppUtils::Warning);
2019-12-23 15:23:01 +03:00
}
}
#endif
2019-09-03 19:36:06 +03:00
}
2019-12-23 15:23:01 +03:00
2019-09-03 19:36:06 +03:00
return true;
}
2020-04-25 16:59:20 +03:00
void FileManager::removeFromDeployed(const QString &path) {
_deployedFiles -= path;
}
2019-09-04 12:01:33 +03:00
void FileManager::saveDeploymendFiles(const QString& targetDir) {
auto settings = QuasarAppUtils::Settings::get();
settings->setValue(targetDir, getDeployedFilesStringList());
}
bool FileManager::strip(const QString &dir) const {
2019-09-03 19:36:06 +03:00
#ifdef Q_OS_WIN
2019-12-20 17:25:20 +03:00
Q_UNUSED(dir)
2019-09-03 19:36:06 +03:00
return true;
#else
QFileInfo info(dir);
2019-09-03 18:15:05 +03:00
2019-09-03 19:36:06 +03:00
if (!info.exists()) {
2020-04-04 15:43:46 +03:00
QuasarAppUtils::Params::log("dir not exits!");
2019-09-03 19:36:06 +03:00
return false;
}
if (info.isDir()) {
QDir d(dir);
auto list = d.entryInfoList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
bool res = false;
2020-01-12 16:43:03 +03:00
for (const auto &i : list) {
2019-09-03 19:36:06 +03:00
res = strip(i.absoluteFilePath()) || res;
}
return res;
} else {
auto sufix = info.completeSuffix();
if (!sufix.contains("so") && !sufix.contains("dll")) {
2019-09-04 12:01:33 +03:00
return true;
2019-09-03 19:36:06 +03:00
}
QProcess P;
P.setProgram("strip");
P.setArguments(QStringList() << info.absoluteFilePath());
P.start();
if (!P.waitForStarted())
return false;
if (!P.waitForFinished())
return false;
return P.exitCode() == 0;
}
#endif
}
2019-09-04 12:01:33 +03:00
bool FileManager::fileActionPrivate(const QString &file, const QString &target,
QStringList *masks, bool isMove, bool targetIsFile) {
2019-09-03 19:36:06 +03:00
auto info = QFileInfo(file);
2019-09-03 18:15:05 +03:00
bool copy = !masks;
if (masks) {
for (auto mask : *masks) {
2019-12-20 17:25:20 +03:00
if (info.absoluteFilePath().contains(mask, ONLY_WIN_CASE_INSENSIATIVE)) {
2019-09-03 18:15:05 +03:00
copy = true;
break;
}
}
}
if (!copy) {
2020-04-04 15:43:46 +03:00
QuasarAppUtils::Params::log(((isMove)? "skip move :": "skip copy :" + file));
2019-09-03 18:15:05 +03:00
return false;
}
auto name = info.fileName();
QString tergetFile = target + QDir::separator() + name;
if (targetIsFile) {
tergetFile = target;
}
info.setFile(tergetFile);
2019-09-03 18:15:05 +03:00
if (!initDir(info.absolutePath())) {
return false;
}
if (QFileInfo(file).absoluteFilePath() ==
QFileInfo(tergetFile).absoluteFilePath()) {
2019-09-03 18:15:05 +03:00
return true;
}
2019-09-12 09:38:30 +03:00
if (!QuasarAppUtils::Params::isEndable("noOverwrite") &&
info.exists() && !removeFile( tergetFile)) {
2019-09-03 18:15:05 +03:00
return false;
}
2020-04-04 15:43:46 +03:00
QuasarAppUtils::Params::log(((isMove)? "move :": "copy :") + file,
QuasarAppUtils::Info);
2019-09-03 18:15:05 +03:00
QFile sourceFile(file);
2020-04-25 16:59:20 +03:00
auto sourceFileAbsalutePath = QFileInfo(file).absoluteFilePath();
2019-09-03 18:15:05 +03:00
if (!((isMove)?
sourceFile.rename(tergetFile):
sourceFile.copy(tergetFile))) {
2019-09-03 18:15:05 +03:00
2020-04-04 15:43:46 +03:00
QuasarAppUtils::Params::log("Qt Operation fail " + file + " >> " + tergetFile +
" Qt error: " + sourceFile.errorString(),
QuasarAppUtils::Warning);
2019-09-03 18:15:05 +03:00
bool tarExits = QFileInfo(tergetFile).exists();
2019-09-03 18:15:05 +03:00
2020-01-15 18:31:09 +03:00
if ((!tarExits) ||
(tarExits && !QuasarAppUtils::Params::isEndable("noOverwrite"))) {
2019-09-03 18:15:05 +03:00
std::ifstream src(file.toStdString(),
std::ios::binary);
std::ofstream dst((tergetFile).toStdString(),
std::ios::binary);
dst << src.rdbuf();
if (!QFileInfo::exists(tergetFile)) {
2020-04-04 15:43:46 +03:00
QuasarAppUtils::Params::log("std Operation fail file not copied. "
"Сheck if you have access to the target dir",
QuasarAppUtils::Error);
return false;
}
2020-01-15 18:31:09 +03:00
if (isMove) {
std::remove(file.toStdString().c_str());
}
} else {
if (QFileInfo(tergetFile).exists()) {
2020-04-04 15:43:46 +03:00
QuasarAppUtils::Params::log(tergetFile + " already exists!",
QuasarAppUtils::Info);
return true;
}
2019-09-03 18:15:05 +03:00
return false;
2019-09-03 18:15:05 +03:00
}
}
2020-04-25 16:59:20 +03:00
if (isMove) {
removeFromDeployed(sourceFileAbsalutePath);
}
addToDeployed(tergetFile);
2019-09-03 18:15:05 +03:00
return true;
}
2019-09-04 12:01:33 +03:00
bool FileManager::removeFile(const QString &file) {
2019-09-03 18:15:05 +03:00
return removeFile(QFileInfo (file));
}
bool FileManager::smartCopyFile(const QString &file,
const QString &target,
QStringList *mask,
bool ifFileTarget) {
2019-09-25 12:32:05 +03:00
auto config = DeployCore::_config;
2019-12-23 10:12:23 +03:00
if (file.contains(config->getTargetDir(), ONLY_WIN_CASE_INSENSIATIVE)) {
2019-09-03 18:15:05 +03:00
if (!moveFile(file, target, mask)) {
2020-04-04 15:43:46 +03:00
QuasarAppUtils::Params::log(" file not moved! try copy");
2019-09-03 18:15:05 +03:00
if (!copyFile(file, target, mask, ifFileTarget)) {
2020-04-04 15:43:46 +03:00
QuasarAppUtils::Params::log("not copy target to bin dir " + file,
QuasarAppUtils::Error);
2019-09-03 18:15:05 +03:00
return false;
}
}
2019-09-03 18:15:05 +03:00
} else {
if (!copyFile(file, target, mask, ifFileTarget)) {
2020-04-04 15:43:46 +03:00
QuasarAppUtils::Params::log("not copy target to bin dir " + file,
QuasarAppUtils::Error);
2019-09-03 18:15:05 +03:00
return false;
}
2019-09-03 18:15:05 +03:00
}
return true;
}
bool FileManager::moveFile(const QString &file, const QString &target, QStringList *masks, bool targetIsFile) {
return fileActionPrivate(file, target, masks, true, targetIsFile);
2019-09-03 18:15:05 +03:00
}
2019-09-04 12:01:33 +03:00
bool FileManager::copyFolder(const QString &from, const QString &to, const QStringList &filter,
QStringList *listOfCopiedItems, QStringList *mask) {
2019-09-03 18:15:05 +03:00
QDir fromDir(from);
auto list = fromDir.entryInfoList(QDir::NoDotAndDotDot | QDir::AllEntries);
2020-01-12 16:43:03 +03:00
for (const auto &item : list) {
2019-09-03 18:15:05 +03:00
if (QFileInfo(item).isDir()) {
copyFolder(item.absoluteFilePath(), to + "/" + item.fileName(), filter, listOfCopiedItems, mask);
} else {
QString skipFilter = "";
2020-01-12 16:43:03 +03:00
for (const auto &i: filter) {
2019-12-20 17:25:20 +03:00
if (item.fileName().contains(i, ONLY_WIN_CASE_INSENSIATIVE)) {
2019-09-03 18:15:05 +03:00
skipFilter = i;
break;
}
}
if (!skipFilter.isEmpty()) {
2020-04-04 15:43:46 +03:00
QuasarAppUtils::Params::log(
2019-09-03 18:15:05 +03:00
item.absoluteFilePath() + " ignored by filter " + skipFilter,
QuasarAppUtils::VerboseLvl::Info);
continue;
}
2019-10-15 13:35:50 +03:00
auto config = DeployCore::_config;
LibInfo info;
info.setName(item.fileName());
info.setPath(item.absolutePath());
2019-10-17 15:42:44 +03:00
info.setPlatform(GeneralFile);
2019-10-15 13:35:50 +03:00
if (config)
if (auto rule = config->ignoreList.isIgnore(info)) {
2020-04-04 15:43:46 +03:00
QuasarAppUtils::Params::log(
2019-10-15 13:35:50 +03:00
item.absoluteFilePath() + " ignored by rule " + rule->label,
QuasarAppUtils::VerboseLvl::Info);
continue;
}
2019-09-03 18:15:05 +03:00
if (!copyFile(item.absoluteFilePath(), to , mask)) {
2020-04-04 15:43:46 +03:00
QuasarAppUtils::Params::log(
2019-09-03 18:15:05 +03:00
"not copied file " + to + "/" + item.fileName(),
QuasarAppUtils::VerboseLvl::Warning);
continue;
}
if (listOfCopiedItems) {
*listOfCopiedItems << to + "/" + item.fileName();
}
}
}
return true;
}
2020-01-18 20:01:14 +03:00
bool FileManager::moveFolder(const QString &from, const QString &to, const QString& ignore) {
2020-01-15 18:31:09 +03:00
QFileInfo info(from);
if (info.isFile()) {
2020-01-18 20:01:14 +03:00
if (ignore.size() && info.absoluteFilePath().contains(ignore)) {
return true;
}
2020-01-15 18:31:09 +03:00
if (!moveFile(info.absoluteFilePath(), to)) {
return false;
}
return true;
}
QDir dir(from);
auto list = dir.entryInfoList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
for (const auto &i :list) {
auto targetDir = to;
if (i.isDir()) {
targetDir += "/" + i.fileName();
}
2020-01-18 20:01:14 +03:00
if (!moveFolder(i.absoluteFilePath(), targetDir, ignore)) {
2020-01-15 18:31:09 +03:00
return false;
}
}
return true;
}
2019-09-04 12:01:33 +03:00
void FileManager::clear(const QString& targetDir, bool force) {
2020-04-04 15:43:46 +03:00
QuasarAppUtils::Params::log( "clear start!",
QuasarAppUtils::Info);
2019-09-03 18:15:05 +03:00
if (force) {
2020-04-04 15:43:46 +03:00
QuasarAppUtils::Params::log("clear force! " + targetDir,
QuasarAppUtils::Info);
2019-09-03 18:15:05 +03:00
if (QDir(targetDir).removeRecursively()) {
return;
}
2020-04-04 15:43:46 +03:00
QuasarAppUtils::Params::log("Remove target Dir fail, try remove old deployemend files",
QuasarAppUtils::Warning);
2019-09-03 18:15:05 +03:00
}
QMap<int, QFileInfo> sortedOldData;
2019-09-03 19:36:06 +03:00
for (auto& i : _deployedFiles) {
2019-09-03 18:15:05 +03:00
sortedOldData.insertMulti(i.size(), QFileInfo(i));
}
for (auto it = sortedOldData.end(); it != sortedOldData.begin(); --it) {
auto index = it - 1;
2019-09-04 17:07:38 +03:00
if (!index.value().exists()) {
continue;
}
2019-09-03 18:15:05 +03:00
if (index.value().isFile()) {
if (removeFile(index.value())) {
2020-04-04 15:43:46 +03:00
QuasarAppUtils::Params::log("Remove " + index.value().absoluteFilePath() + " because it is deployed file",
QuasarAppUtils::Info);
2019-09-03 18:15:05 +03:00
}
} else {
QDir qdir(index.value().absoluteFilePath());
if (!qdir.entryList(QDir::NoDotAndDotDot | QDir::AllEntries).count()) {
qdir.removeRecursively();
2020-04-04 15:43:46 +03:00
QuasarAppUtils::Params::log("Remove " + index.value().absoluteFilePath() + " because it is empty",
QuasarAppUtils::Info);
2019-09-03 18:15:05 +03:00
}
}
}
2019-09-03 19:36:06 +03:00
_deployedFiles.clear();
2019-09-03 18:15:05 +03:00
}
2019-09-04 12:01:33 +03:00
bool FileManager::copyFile(const QString &file, const QString &target,
QStringList *masks, bool targetIsFile) {
2019-09-03 18:15:05 +03:00
return fileActionPrivate(file, target, masks, false, targetIsFile);
2019-09-03 18:15:05 +03:00
}
bool FileManager::copyFiles(const QStringList &source,
const QString &to, int saveStructSize,
const QStringList &filter,
QStringList *listOfCopiedItems,
QStringList *mask) {
for (const auto &item : source) {
QFileInfo info(item);
QString skipFilter = "";
for (const auto &i: filter) {
if (info.fileName().contains(i, ONLY_WIN_CASE_INSENSIATIVE)) {
skipFilter = i;
break;
}
}
if (!skipFilter.isEmpty()) {
QuasarAppUtils::Params::log(
info.absoluteFilePath() + " ignored by filter " + skipFilter,
QuasarAppUtils::VerboseLvl::Info);
continue;
}
auto config = DeployCore::_config;
LibInfo libInfo;
libInfo.setName(info.fileName());
libInfo.setPath(info.absolutePath());
libInfo.setPlatform(GeneralFile);
if (config)
if (auto rule = config->ignoreList.isIgnore(libInfo)) {
QuasarAppUtils::Params::log(
info.absoluteFilePath() + " ignored by rule " + rule->label,
QuasarAppUtils::VerboseLvl::Info);
continue;
}
auto prefixes = info.absolutePath().split(QRegExp("[\\/]"));
auto distanation = to;
while (saveStructSize--) {
auto index = prefixes.size() - saveStructSize;
if (index >= 0) {
distanation += "/" + prefixes[index];
}
}
if (!copyFile(info.absoluteFilePath(), distanation , mask)) {
QuasarAppUtils::Params::log(
"not copied file " + distanation + "/" + info.fileName(),
QuasarAppUtils::VerboseLvl::Warning);
continue;
}
if (listOfCopiedItems) {
*listOfCopiedItems << distanation + "/" + info.fileName();
}
}
return true;
}
2019-09-04 12:01:33 +03:00
bool FileManager::removeFile(const QFileInfo &file) {
2019-09-03 18:15:05 +03:00
if (!QFile::remove(file.absoluteFilePath())) {
2020-04-04 15:43:46 +03:00
QuasarAppUtils::Params::log("Qt Operation fail (remove file) " + file.absoluteFilePath(),
QuasarAppUtils::Warning);
2019-09-03 18:15:05 +03:00
if (remove(file.absoluteFilePath().toLatin1())) {
2020-04-04 15:43:46 +03:00
QuasarAppUtils::Params::log("std Operation fail file not removed." + file.absoluteFilePath(),
QuasarAppUtils::Error);
2019-09-03 18:15:05 +03:00
return false;
}
}
return true;
}