Commit 4320f587 authored by Elvis Angelaccio's avatar Elvis Angelaccio
Browse files

Move GlobalWorkDir logic to AddJob::doWork()

When adding files, we now change the working dir to GlobalWorkDir at the AddJob level.
This way is easier to restore the old working dir, and we also merge
some duplicated code between cliinterface and libarchiveplugin.

Differential Revision: D1369
parent 9c2690c0
......@@ -279,7 +279,7 @@ void Cli7zTest::testAddArgs()
QFETCH(bool, encryptHeader);
QFETCH(int, compressionLevel);
QStringList replacedArgs = plugin->substituteAddVariables(addArgs, {}, QDir::current(), password, encryptHeader, compressionLevel);
QStringList replacedArgs = plugin->substituteAddVariables(addArgs, {}, password, encryptHeader, compressionLevel);
QFETCH(QStringList, expectedArgs);
QCOMPARE(replacedArgs, expectedArgs);
......
......@@ -312,7 +312,7 @@ void CliRarTest::testAddArgs()
QFETCH(bool, encryptHeader);
QFETCH(int, compressionLevel);
QStringList replacedArgs = rarPlugin->substituteAddVariables(addArgs, {}, QDir::current(), password, encryptHeader, compressionLevel);
QStringList replacedArgs = rarPlugin->substituteAddVariables(addArgs, {}, password, encryptHeader, compressionLevel);
QFETCH(QStringList, expectedArgs);
QCOMPARE(replacedArgs, expectedArgs);
......
......@@ -106,7 +106,7 @@ void CliZipTest::testAddArgs()
QFETCH(QString, password);
QFETCH(int, compressionLevel);
QStringList replacedArgs = plugin->substituteAddVariables(addArgs, {}, QDir::current(), password, false, compressionLevel);
QStringList replacedArgs = plugin->substituteAddVariables(addArgs, {}, password, false, compressionLevel);
QFETCH(QStringList, expectedArgs);
QCOMPARE(replacedArgs, expectedArgs);
......
......@@ -245,18 +245,10 @@ bool CliInterface::addFiles(const QStringList & files, const CompressionOptions&
m_operationMode = Add;
const QString globalWorkDir = options.value(QStringLiteral( "GlobalWorkDir" )).toString();
const QDir workDir = globalWorkDir.isEmpty() ? QDir::current() : QDir(globalWorkDir);
if (!globalWorkDir.isEmpty()) {
qCDebug(ARK) << "GlobalWorkDir is set, changing dir to " << globalWorkDir;
QDir::setCurrent(globalWorkDir);
}
int compLevel = options.value(QStringLiteral("CompressionLevel"), -1).toInt();
const auto args = substituteAddVariables(m_param.value(AddArgs).toStringList(),
files,
workDir,
password(),
isHeaderEncryptionEnabled(),
compLevel);
......@@ -630,7 +622,7 @@ QStringList CliInterface::substituteCopyVariables(const QStringList &extractArgs
return args;
}
QStringList CliInterface::substituteAddVariables(const QStringList &addArgs, const QStringList &files, const QDir &workDir, const QString &password, bool encryptHeader, int compLevel)
QStringList CliInterface::substituteAddVariables(const QStringList &addArgs, const QStringList &files, const QString &password, bool encryptHeader, int compLevel)
{
// Required if we call this function from unit tests.
cacheParameterList();
......@@ -655,7 +647,7 @@ QStringList CliInterface::substituteAddVariables(const QStringList &addArgs, con
}
if (arg == QLatin1String("$Files")) {
args << addFilesList(files, workDir);
args << files;
continue;
}
......@@ -754,21 +746,6 @@ QStringList CliInterface::rootNodeSwitch(const QString &rootNode) const
return rootNodeSwitch;
}
QStringList CliInterface::addFilesList(const QStringList& files, const QDir& workDir) const
{
// #191821: workDir must be used instead of QDir::current()
// so that symlinks aren't resolved automatically
// TODO: this kind of call should be moved upwards in the
// class hierarchy to avoid code duplication
QStringList filesList;
foreach (const QString& file, files) {
filesList << workDir.relativeFilePath(file);
}
return filesList;
}
QStringList CliInterface::copyFilesList(const QVariantList& files) const
{
QStringList filesList;
......
......@@ -316,7 +316,7 @@ public:
QStringList substituteListVariables(const QStringList &listArgs, const QString &password);
QStringList substituteCopyVariables(const QStringList &extractArgs, const QVariantList &files, bool preservePaths, const QString &password, const QString &rootNode);
QStringList substituteAddVariables(const QStringList &addArgs, const QStringList &files, const QDir &workDir, const QString &password, bool encryptHeader, int compLevel);
QStringList substituteAddVariables(const QStringList &addArgs, const QStringList &files, const QString &password, bool encryptHeader, int compLevel);
/**
* @return The preserve path switch, according to the @p preservePaths extraction option.
......@@ -343,11 +343,6 @@ public:
*/
QStringList rootNodeSwitch(const QString& rootNode) const;
/**
* @return The list of files to add to the archive.
*/
QStringList addFilesList(const QStringList& files, const QDir& workDir) const;
/**
* @return The list of selected files to extract.
*/
......
......@@ -28,6 +28,7 @@
#include "jobs.h"
#include "ark_debug.h"
#include <QDir>
#include <QFileInfo>
#include <QRegularExpression>
#include <QThread>
......@@ -356,14 +357,45 @@ void AddJob::doWork()
Q_ASSERT(m_writeInterface);
const QString globalWorkDir = m_options.value(QStringLiteral("GlobalWorkDir")).toString();
const QDir workDir = globalWorkDir.isEmpty() ? QDir::current() : QDir(globalWorkDir);
if (!globalWorkDir.isEmpty()) {
qCDebug(ARK) << "GlobalWorkDir is set, changing dir to " << globalWorkDir;
m_oldWorkingDir = QDir::currentPath();
QDir::setCurrent(globalWorkDir);
}
// The file paths must be relative to GlobalWorkDir.
QStringList relativeFiles;
foreach (const QString& file, m_files) {
// #191821: workDir must be used instead of QDir::current()
// so that symlinks aren't resolved automatically
QString relativePath = workDir.relativeFilePath(file);
if (file.endsWith(QLatin1Char('/'))) {
relativePath += QLatin1Char('/');
}
relativeFiles << relativePath;
}
connectToArchiveInterfaceSignals();
bool ret = m_writeInterface->addFiles(m_files, m_options);
bool ret = m_writeInterface->addFiles(relativeFiles, m_options);
if (!archiveInterface()->waitForFinishedSignal()) {
onFinished(ret);
}
}
void AddJob::onFinished(bool result)
{
if (!m_oldWorkingDir.isEmpty()) {
QDir::setCurrent(m_oldWorkingDir);
}
Job::onFinished(result);
}
DeleteJob::DeleteJob(const QVariantList& files, ReadWriteArchiveInterface *interface, QObject *parent)
: Job(interface, parent)
, m_files(files)
......
......@@ -150,7 +150,11 @@ public:
public slots:
virtual void doWork() Q_DECL_OVERRIDE;
protected slots:
virtual void onFinished(bool result) Q_DECL_OVERRIDE;
private:
QString m_oldWorkingDir;
QStringList m_files;
CompressionOptions m_options;
};
......
......@@ -40,7 +40,6 @@ K_PLUGIN_FACTORY_WITH_JSON(ReadWriteLibarchivePluginFactory, "kerfuffle_libarchi
ReadWriteLibarchivePlugin::ReadWriteLibarchivePlugin(QObject *parent, const QVariantList & args)
: LibarchivePlugin(parent, args)
, m_workDir(QDir::current())
{
qCDebug(ARK) << "Loaded libarchive read-write plugin";
}
......@@ -54,13 +53,6 @@ bool ReadWriteLibarchivePlugin::addFiles(const QStringList& files, const Compres
qCDebug(ARK) << "Adding files" << files << "with CompressionOptions" << options;
const bool creatingNewFile = !QFileInfo::exists(filename());
const QString globalWorkDir = options.value(QStringLiteral( "GlobalWorkDir" )).toString();
if (!globalWorkDir.isEmpty()) {
qCDebug(ARK) << "GlobalWorkDir is set, changing dir to " << globalWorkDir;
m_workDir.setPath(globalWorkDir);
QDir::setCurrent(globalWorkDir);
}
m_writtenFiles.clear();
......@@ -418,17 +410,10 @@ bool ReadWriteLibarchivePlugin::deleteFiles(const QVariantList& files)
// TODO: if we merge this with copyData(), we can pass more data
// such as an fd to archive_read_disk_entry_from_file()
bool ReadWriteLibarchivePlugin::writeFile(const QString& fileName, struct archive* arch_writer)
bool ReadWriteLibarchivePlugin::writeFile(const QString& relativeName, struct archive* arch_writer)
{
int header_response;
const bool trailingSlash = fileName.endsWith(QLatin1Char( '/' ));
// #191821: workDir must be used instead of QDir::current()
// so that symlinks aren't resolved automatically
// TODO: this kind of call should be moved upwards in the
// class hierarchy to avoid code duplication
const QString relativeName = m_workDir.relativeFilePath(fileName) + (trailingSlash ? QStringLiteral( "/" ) : QStringLiteral( "" ));
const QString absoluteFilename = QFileInfo(relativeName).absoluteFilePath();
// #253059: Even if we use archive_read_disk_entry_from_file,
// libarchive may have been compiled without HAVE_LSTAT,
......@@ -436,25 +421,25 @@ bool ReadWriteLibarchivePlugin::writeFile(const QString& fileName, struct archiv
// which case stat() will be called. To avoid this, we
// call lstat() ourselves.
struct stat st;
lstat(QFile::encodeName(fileName).constData(), &st);
lstat(QFile::encodeName(absoluteFilename).constData(), &st);
struct archive_entry *entry = archive_entry_new();
archive_entry_set_pathname(entry, QFile::encodeName(relativeName).constData());
archive_entry_copy_sourcepath(entry, QFile::encodeName(fileName).constData());
archive_entry_copy_sourcepath(entry, QFile::encodeName(absoluteFilename).constData());
archive_read_disk_entry_from_file(m_archiveReadDisk.data(), entry, -1, &st);
qCDebug(ARK) << "Writing new entry " << archive_entry_pathname(entry);
if ((header_response = archive_write_header(arch_writer, entry)) == ARCHIVE_OK) {
// If the whole archive is extracted and the total filesize is
// available, we use partial progress.
copyData(fileName, arch_writer, false);
copyData(absoluteFilename, arch_writer, false);
} else {
qCCritical(ARK) << "Writing header failed with error code " << header_response;
qCCritical(ARK) << "Error while writing..." << archive_error_string(arch_writer) << "(error no =" << archive_errno(arch_writer) << ')';
emit error(xi18nc("@info Error in a message box",
"Ark could not compress <filename>%1</filename>:<nl/>%2",
fileName,
absoluteFilename,
QString::fromUtf8(archive_error_string(arch_writer))));
archive_entry_free(entry);
......
......@@ -46,9 +46,8 @@ public:
bool deleteFiles(const QVariantList& files) Q_DECL_OVERRIDE;
private:
bool writeFile(const QString& fileName, struct archive* arch);
bool writeFile(const QString& relativeName, struct archive* arch);
QDir m_workDir;
QStringList m_writtenFiles;
};
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment