Utils: FilePathify Archive

Change-Id: Ia6b972b50f8b1cc7c5829ac863a5881849ea7678
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
hjk
2021-08-11 07:46:10 +02:00
parent 2f44449a90
commit 2663af4c74

View File

@@ -37,23 +37,26 @@
#include <QSettings> #include <QSettings>
#include <QTimer> #include <QTimer>
namespace Utils {
namespace { namespace {
struct Tool struct Tool
{ {
QString executable; CommandLine command;
QStringList arguments;
QStringList supportedMimeTypes; QStringList supportedMimeTypes;
QStringList additionalSearchDirs; FilePaths additionalSearchDirs;
bool nativeWindowsArguments = false;
}; };
static QStringList additionalInstallDirs(const QString &registryKey, const QString &valueName) } // anon
static FilePaths additionalInstallDirs(const QString &registryKey, const QString &valueName)
{ {
#if defined(Q_OS_WIN) #if defined(Q_OS_WIN)
const QSettings settings64(registryKey, QSettings::Registry64Format); const QSettings settings64(registryKey, QSettings::Registry64Format);
const QSettings settings32(registryKey, QSettings::Registry32Format); const QSettings settings32(registryKey, QSettings::Registry32Format);
return {settings64.value(valueName).toString(), settings32.value(valueName).toString()}; return {FilePath::fromVariant(settings64.value(valueName)),
FilePath::fromVariant(settings32.value(valueName))};
#else #else
Q_UNUSED(registryKey) Q_UNUSED(registryKey)
Q_UNUSED(valueName) Q_UNUSED(valueName)
@@ -65,48 +68,42 @@ static const QVector<Tool> &sTools()
{ {
static QVector<Tool> tools; static QVector<Tool> tools;
if (tools.isEmpty()) { if (tools.isEmpty()) {
if (Utils::HostOsInfo::isWindowsHost()) { if (HostOsInfo::isWindowsHost()) {
tools << Tool{{"powershell"}, tools << Tool{{"powershell", "-command Expand-Archive -Force '%{src}' '%{dest}'", CommandLine::Raw},
{"-command Expand-Archive -Force '%{src}' '%{dest}'"},
{"application/zip"}, {"application/zip"},
{}, {}};
true};
} }
tools << Tool{{"unzip"}, {"-o", "%{src}", "-d", "%{dest}"}, {"application/zip"}, {}}; tools << Tool{{"unzip", {"-o", "%{src}", "-d", "%{dest}"}}, {"application/zip"}, {}};
tools << Tool{{"7z"}, tools << Tool{{"7z", {"x", "-o%{dest}", "-y", "-bb", "%{src}"}},
{"x", "-o%{dest}", "-y", "-bb", "%{src}"},
{"application/zip", "application/x-7z-compressed"}, {"application/zip", "application/x-7z-compressed"},
additionalInstallDirs("HKEY_CURRENT_USER\\Software\\7-Zip", "Path")}; additionalInstallDirs("HKEY_CURRENT_USER\\Software\\7-Zip", "Path")};
tools << Tool{{"tar"}, tools << Tool{{"tar", {"xvf", "%{src}"}},
{"xvf", "%{src}"},
{"application/zip", "application/x-tar", "application/x-7z-compressed"}, {"application/zip", "application/x-tar", "application/x-7z-compressed"},
{}}; {}};
tools << Tool{{"tar"}, {"xvzf", "%{src}"}, {"application/x-compressed-tar"}, {}}; tools << Tool{{"tar", {"xvzf", "%{src}"}}, {"application/x-compressed-tar"}, {}};
tools << Tool{{"tar"}, {"xvJf", "%{src}"}, {"application/x-xz-compressed-tar"}, {}}; tools << Tool{{"tar", {"xvJf", "%{src}"}}, {"application/x-xz-compressed-tar"}, {}};
tools << Tool{{"tar"}, {"xvjf", "%{src}"}, {"application/x-bzip-compressed-tar"}, {}}; tools << Tool{{"tar", {"xvjf", "%{src}"}}, {"application/x-bzip-compressed-tar"}, {}};
const QStringList additionalCMakeDirs = additionalInstallDirs(
"HKEY_LOCAL_MACHINE\\SOFTWARE\\Kitware\\CMake", "InstallDir"); const FilePaths additionalCMakeDirs =
tools << Tool{{"cmake"}, additionalInstallDirs("HKEY_LOCAL_MACHINE\\SOFTWARE\\Kitware\\CMake",
{"-E", "tar", "xvf", "%{src}"}, "InstallDir");
tools << Tool{{"cmake", {"-E", "tar", "xvf", "%{src}"}},
{"application/zip", "application/x-tar", "application/x-7z-compressed"}, {"application/zip", "application/x-tar", "application/x-7z-compressed"},
additionalCMakeDirs}; additionalCMakeDirs};
tools << Tool{{"cmake"}, tools << Tool{{"cmake", {"-E", "tar", "xvzf", "%{src}"}},
{"-E", "tar", "xvzf", "%{src}"},
{"application/x-compressed-tar"}, {"application/x-compressed-tar"},
additionalCMakeDirs}; additionalCMakeDirs};
tools << Tool{{"cmake"}, tools << Tool{{"cmake", {"-E", "tar", "xvJf", "%{src}"}},
{"-E", "tar", "xvJf", "%{src}"},
{"application/x-xz-compressed-tar"}, {"application/x-xz-compressed-tar"},
additionalCMakeDirs}; additionalCMakeDirs};
tools << Tool{{"cmake"}, tools << Tool{{"cmake", {"-E", "tar", "xvjf", "%{src}"}},
{"-E", "tar", "xvjf", "%{src}"},
{"application/x-bzip-compressed-tar"}, {"application/x-bzip-compressed-tar"},
additionalCMakeDirs}; additionalCMakeDirs};
} }
return tools; return tools;
} }
static QVector<Tool> toolsForMimeType(const Utils::MimeType &mimeType) static QVector<Tool> toolsForMimeType(const MimeType &mimeType)
{ {
return Utils::filtered(sTools(), [mimeType](const Tool &tool) { return Utils::filtered(sTools(), [mimeType](const Tool &tool) {
return Utils::anyOf(tool.supportedMimeTypes, return Utils::anyOf(tool.supportedMimeTypes,
@@ -114,24 +111,21 @@ static QVector<Tool> toolsForMimeType(const Utils::MimeType &mimeType)
}); });
} }
static QVector<Tool> toolsForFilePath(const Utils::FilePath &fp) static QVector<Tool> toolsForFilePath(const FilePath &fp)
{ {
return toolsForMimeType(Utils::mimeTypeForFile(fp)); return toolsForMimeType(Utils::mimeTypeForFile(fp));
} }
static Utils::optional<Tool> resolveTool(const Tool &tool) static Utils::optional<Tool> resolveTool(const Tool &tool)
{ {
const QString executable const FilePaths dirs = Environment::systemEnvironment().path() + tool.additionalSearchDirs;
= Utils::Environment::systemEnvironment() const FilePath executable = tool.command.executable().withExecutableSuffix().searchInDirectories(dirs);
.searchInPath(Utils::HostOsInfo::withExecutableSuffix(tool.executable),
Utils::transform(tool.additionalSearchDirs, &Utils::FilePath::fromString))
.toString();
Tool resolvedTool = tool; Tool resolvedTool = tool;
resolvedTool.executable = executable; resolvedTool.command.setExecutable(executable);
return executable.isEmpty() ? Utils::nullopt : Utils::make_optional(resolvedTool); return executable.isEmpty() ? Utils::nullopt : Utils::make_optional(resolvedTool);
} }
Utils::optional<Tool> unzipTool(const Utils::FilePath &src, const Utils::FilePath &dest) static Utils::optional<Tool> unzipTool(const FilePath &src, const FilePath &dest)
{ {
const QVector<Tool> tools = toolsForFilePath(src); const QVector<Tool> tools = toolsForFilePath(src);
for (const Tool &tool : tools) { for (const Tool &tool : tools) {
@@ -140,21 +134,13 @@ Utils::optional<Tool> unzipTool(const Utils::FilePath &src, const Utils::FilePat
Tool result = *resolvedTool; Tool result = *resolvedTool;
const QString srcStr = src.toString(); const QString srcStr = src.toString();
const QString destStr = dest.toString(); const QString destStr = dest.toString();
result.arguments const QString args = result.command.arguments().replace("%{src}", srcStr).replace("%{dest}", destStr);
= Utils::transform(result.arguments, [srcStr, destStr](const QString &a) { result.command.setArguments(args);
QString val = a;
return val.replace("%{src}", srcStr).replace("%{dest}", destStr);
});
return result;
} }
} }
return {}; return {};
} }
} // namespace
namespace Utils {
bool Archive::supportsFile(const FilePath &filePath, QString *reason) bool Archive::supportsFile(const FilePath &filePath, QString *reason)
{ {
const QVector<Tool> tools = toolsForFilePath(filePath); const QVector<Tool> tools = toolsForFilePath(filePath);
@@ -163,10 +149,14 @@ bool Archive::supportsFile(const FilePath &filePath, QString *reason)
*reason = tr("File format not supported."); *reason = tr("File format not supported.");
return false; return false;
} }
if (!anyOf(tools, [](const Tool &t) { return resolveTool(t); })) { if (!anyOf(tools, [tools](const Tool &t) { return resolveTool(t); })) {
if (reason) if (reason) {
const QStringList execs = transform<QStringList>(tools, [](const Tool &tool) {
return tool.command.executable().toString();
});
*reason = tr("Could not find any unarchiving executable in PATH (%1).") *reason = tr("Could not find any unarchiving executable in PATH (%1).")
.arg(transform<QStringList>(tools, &Tool::executable).join(", ")); .arg(execs.join(", "));
}
return false; return false;
} }
return true; return true;
@@ -251,14 +241,10 @@ Archive *Archive::unarchive(const FilePath &src, const FilePath &dest)
QTimer::singleShot(0, archive, [archive, tool, workingDirectory] { QTimer::singleShot(0, archive, [archive, tool, workingDirectory] {
archive->outputReceived( archive->outputReceived(
tr("Running %1\nin \"%2\".\n\n", "Running <cmd> in <workingdirectory>") tr("Running %1\nin \"%2\".\n\n", "Running <cmd> in <workingdirectory>")
.arg(CommandLine(FilePath::fromString(tool->executable), tool->arguments).toUserOutput(), .arg(tool->command.toUserOutput(), workingDirectory));
workingDirectory));
}); });
CommandLine cmd = tool->nativeWindowsArguments archive->m_process->setCommand(tool->command);
? CommandLine{FilePath::fromString(tool->executable), tool->arguments[0], CommandLine::Raw}
: CommandLine{FilePath::fromString(tool->executable), tool->arguments};
archive->m_process->setCommand(cmd);
archive->m_process->setWorkingDirectory(workingDirectory); archive->m_process->setWorkingDirectory(workingDirectory);
archive->m_process->start(); archive->m_process->start();
return archive; return archive;