CQtDeployer/Deploy/filemanager.cpp
2020-01-12 16:43:03 +03:00

358 lines
10 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Copyright (C) 2018-2020 QuasarApp.
* 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.
*/
#include "filemanager.h"
#include <QDir>
#include <quasarapp.h>
#include "configparser.h"
#include "deploycore.h"
#include <QProcess>
#include <fstream>
#include "pathutils.h"
FileManager::FileManager() {
}
bool FileManager::initDir(const QString &path) {
if (!QFileInfo::exists(path)) {
addToDeployed(path);
if (!QDir().mkpath(path)) {
return false;
}
}
return true;
}
QSet<QString> FileManager::getDeployedFiles() const {
return _deployedFiles;
}
QStringList FileManager::getDeployedFilesStringList() const {
return _deployedFiles.toList();
}
void FileManager::loadDeployemendFiles(const QString &targetDir) {
auto settings = QuasarAppUtils::Settings::get();
if (targetDir.isEmpty())
return;
QStringList deployedFiles = settings->getValue(targetDir, "").toStringList();
// _deployedFiles.clear();
_deployedFiles.unite(QSet<QString>::fromList(deployedFiles));
}
bool FileManager::addToDeployed(const QString& path) {
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")) {
if (!QFile::setPermissions(path, static_cast<QFile::Permission>(0x7777))) {
QuasarAppUtils::Params::verboseLog("permishens set fail", QuasarAppUtils::Warning);
}
}
}
return true;
}
void FileManager::saveDeploymendFiles(const QString& targetDir) {
auto settings = QuasarAppUtils::Settings::get();
settings->setValue(targetDir, getDeployedFilesStringList());
}
bool FileManager::strip(const QString &dir) const {
#ifdef Q_OS_WIN
Q_UNUSED(dir)
return true;
#else
QFileInfo info(dir);
if (!info.exists()) {
QuasarAppUtils::Params::verboseLog("dir not exits!");
return false;
}
if (info.isDir()) {
QDir d(dir);
auto list = d.entryInfoList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
bool res = false;
for (const auto &i : list) {
res = strip(i.absoluteFilePath()) || res;
}
return res;
} else {
auto sufix = info.completeSuffix();
if (!sufix.contains("so") && !sufix.contains("dll")) {
return true;
}
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
}
bool FileManager::fileActionPrivate(const QString &file, const QString &target,
QStringList *masks, bool isMove) {
auto info = QFileInfo(file);
bool copy = !masks;
if (masks) {
for (auto mask : *masks) {
if (info.absoluteFilePath().contains(mask, ONLY_WIN_CASE_INSENSIATIVE)) {
copy = true;
break;
}
}
}
if (!copy) {
QuasarAppUtils::Params::verboseLog(((isMove)? "skip move :": "skip copy :" + file));
return false;
}
auto name = info.fileName();
info.setFile(target + QDir::separator() + name);
if (!initDir(info.absolutePath())) {
return false;
}
if (QFileInfo(file).absoluteFilePath() ==
QFileInfo(target + QDir::separator() + name).absoluteFilePath()) {
return true;
}
if (!QuasarAppUtils::Params::isEndable("noOverwrite") &&
info.exists() && !removeFile( target + QDir::separator() + name)) {
return false;
}
qInfo() << ((isMove)? "move :": "copy :") << file;
QFile sourceFile(file);
if (!((isMove)?
sourceFile.rename(target + QDir::separator() + name):
sourceFile.copy(target + QDir::separator() + name))) {
QuasarAppUtils::Params::verboseLog("Qt Operation fail " + file + " >> " + target + QDir::separator() + name +
" Qt error: " + sourceFile.errorString(),
QuasarAppUtils::Warning);
if (!(QuasarAppUtils::Params::isEndable("noOverwrite") &&
QFileInfo(target + QDir::separator() + name).exists())) {
std::ifstream src(file.toStdString(),
std::ios::binary);
std::ofstream dst((target + QDir::separator() + name).toStdString(),
std::ios::binary);
dst << src.rdbuf();
if (!QFileInfo::exists(target + QDir::separator() + name)) {
QuasarAppUtils::Params::verboseLog("std Operation fail file not copied. "
"Сheck if you have access to the target dir",
QuasarAppUtils::Error);
return false;
}
} else {
if (QFileInfo(target + QDir::separator() + name).exists()) {
qInfo() << target + QDir::separator() + name << " already exists!";
return true;
}
return false;
}
}
addToDeployed(target + QDir::separator() + name);
return true;
}
bool FileManager::removeFile(const QString &file) {
return removeFile(QFileInfo (file));
}
bool FileManager::smartCopyFile(const QString &file, const QString &target, QStringList *mask) {
auto config = DeployCore::_config;
if (file.contains(config->getTargetDir(), ONLY_WIN_CASE_INSENSIATIVE)) {
if (!moveFile(file, target, mask)) {
QuasarAppUtils::Params::verboseLog(" file not moved! try copy");
if (!copyFile(file, target, mask)) {
qCritical() << "not copy target to bin dir " << file;
return false;
}
}
} else {
if (!copyFile(file, target, mask)) {
qCritical() << "not copy target to bin dir " << file;
return false;
}
}
return true;
}
bool FileManager::moveFile(const QString &file, const QString &target, QStringList *masks) {
return fileActionPrivate(file, target, masks, true);
}
bool FileManager::copyFolder(const QString &from, const QString &to, const QStringList &filter,
QStringList *listOfCopiedItems, QStringList *mask) {
QDir fromDir(from);
auto list = fromDir.entryInfoList(QDir::NoDotAndDotDot | QDir::AllEntries);
for (const auto &item : list) {
if (QFileInfo(item).isDir()) {
copyFolder(item.absoluteFilePath(), to + "/" + item.fileName(), filter, listOfCopiedItems, mask);
} else {
QString skipFilter = "";
for (const auto &i: filter) {
if (item.fileName().contains(i, ONLY_WIN_CASE_INSENSIATIVE)) {
skipFilter = i;
break;
}
}
if (!skipFilter.isEmpty()) {
QuasarAppUtils::Params::verboseLog(
item.absoluteFilePath() + " ignored by filter " + skipFilter,
QuasarAppUtils::VerboseLvl::Info);
continue;
}
auto config = DeployCore::_config;
LibInfo info;
info.setName(item.fileName());
info.setPath(item.absolutePath());
info.setPlatform(GeneralFile);
if (config)
if (auto rule = config->ignoreList.isIgnore(info)) {
QuasarAppUtils::Params::verboseLog(
item.absoluteFilePath() + " ignored by rule " + rule->label,
QuasarAppUtils::VerboseLvl::Info);
continue;
}
if (!copyFile(item.absoluteFilePath(), to , mask)) {
QuasarAppUtils::Params::verboseLog(
"not copied file " + to + "/" + item.fileName(),
QuasarAppUtils::VerboseLvl::Warning);
continue;
}
if (listOfCopiedItems) {
*listOfCopiedItems << to + "/" + item.fileName();
}
}
}
return true;
}
void FileManager::clear(const QString& targetDir, bool force) {
qInfo() << "clear start!";
if (force) {
qInfo() << "clear force! " << targetDir;
if (QDir(targetDir).removeRecursively()) {
return;
}
QuasarAppUtils::Params::verboseLog("Remove target Dir fail, try remove old deployemend files",
QuasarAppUtils::Warning);
}
QMap<int, QFileInfo> sortedOldData;
for (auto& i : _deployedFiles) {
sortedOldData.insertMulti(i.size(), QFileInfo(i));
}
for (auto it = sortedOldData.end(); it != sortedOldData.begin(); --it) {
auto index = it - 1;
if (!index.value().exists()) {
continue;
}
if (index.value().isFile()) {
if (removeFile(index.value())) {
qInfo() << "Remove " << index.value().absoluteFilePath() << " becouse it is deployed file";
}
} else {
QDir qdir(index.value().absoluteFilePath());
if (!qdir.entryList(QDir::NoDotAndDotDot | QDir::AllEntries).count()) {
qdir.removeRecursively();
qInfo() << "Remove " << index.value().absoluteFilePath() << " becouse it is empty";
}
}
}
_deployedFiles.clear();
}
bool FileManager::copyFile(const QString &file, const QString &target,
QStringList *masks) {
return fileActionPrivate(file, target, masks, false);
}
bool FileManager::removeFile(const QFileInfo &file) {
if (!QFile::remove(file.absoluteFilePath())) {
QuasarAppUtils::Params::verboseLog("Qt Operation fail (remove file) " + file.absoluteFilePath(),
QuasarAppUtils::Warning);
if (remove(file.absoluteFilePath().toLatin1())) {
QuasarAppUtils::Params::verboseLog("std Operation fail file not removed." + file.absoluteFilePath(),
QuasarAppUtils::Error);
return false;
}
}
return true;
}