forked from qt-creator/qt-creator
Support more file formats for unarchiving plugins
Use tar, or cmake -E tar, for .tar, .tar.gz, tar.xz, tar.bz2. Use 7zip for 7zip. Zip is supported by unzip, 7zip, tar, and cmake. Change-Id: I799c3211325398add150644b57c32b7ad5bb8903 Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
This commit is contained in:
@@ -39,27 +39,69 @@ namespace {
|
|||||||
|
|
||||||
struct Tool
|
struct Tool
|
||||||
{
|
{
|
||||||
Utils::FilePath executable;
|
QString executable;
|
||||||
QStringList arguments;
|
QStringList arguments;
|
||||||
|
QStringList supportedMimeTypes;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const QVector<Tool> sTools = {
|
||||||
|
{"unzip", {"-o", "%{src}", "-d", "%{dest}"}, {"application/zip"}},
|
||||||
|
{"7z", {"x", "-o%{dest}", "-y", "%{src}"}, {"application/zip", "application/x-7z-compressed"}},
|
||||||
|
{"tar",
|
||||||
|
{"xvf", "%{src}"},
|
||||||
|
{"application/zip", "application/x-tar", "application/x-7z-compressed"}},
|
||||||
|
{"tar", {"xvzf", "%{src}"}, {"application/x-compressed-tar"}},
|
||||||
|
{"tar", {"xvJf", "%{src}"}, {"application/x-xz-compressed-tar"}},
|
||||||
|
{"tar", {"xvjf", "%{src}"}, {"application/x-bzip-compressed-tar"}},
|
||||||
|
{"cmake",
|
||||||
|
{"-E", "tar", "xvf", "%{src}"},
|
||||||
|
{"application/zip", "application/x-tar", "application/x-7z-compressed"}},
|
||||||
|
{"cmake", {"-E", "tar", "xvzf", "%{src}"}, {"application/x-compressed-tar"}},
|
||||||
|
{"cmake", {"-E", "tar", "xvJf", "%{src}"}, {"application/x-xz-compressed-tar"}},
|
||||||
|
{"cmake", {"-E", "tar", "xvjf", "%{src}"}, {"application/x-bzip-compressed-tar"}},
|
||||||
|
};
|
||||||
|
|
||||||
|
static QVector<Tool> toolsForMimeType(const Utils::MimeType &mimeType)
|
||||||
|
{
|
||||||
|
return Utils::filtered(sTools, [mimeType](const Tool &tool) {
|
||||||
|
return Utils::anyOf(tool.supportedMimeTypes,
|
||||||
|
[mimeType](const QString &mt) { return mimeType.inherits(mt); });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static QVector<Tool> toolsForFilePath(const Utils::FilePath &fp)
|
||||||
|
{
|
||||||
|
return toolsForMimeType(Utils::mimeTypeForFile(fp.toString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
static Utils::optional<Tool> resolveTool(const Tool &tool)
|
||||||
|
{
|
||||||
|
const QString executable = Utils::Environment::systemEnvironment()
|
||||||
|
.searchInPath(
|
||||||
|
Utils::HostOsInfo::withExecutableSuffix(tool.executable))
|
||||||
|
.toString();
|
||||||
|
Tool resolvedTool = tool;
|
||||||
|
resolvedTool.executable = executable;
|
||||||
|
return executable.isEmpty() ? Utils::nullopt : Utils::make_optional(resolvedTool);
|
||||||
|
}
|
||||||
|
|
||||||
Utils::optional<Tool> unzipTool(const Utils::FilePath &src, const Utils::FilePath &dest)
|
Utils::optional<Tool> unzipTool(const Utils::FilePath &src, const Utils::FilePath &dest)
|
||||||
{
|
{
|
||||||
const Utils::FilePath unzip = Utils::Environment::systemEnvironment().searchInPath(
|
const QVector<Tool> tools = toolsForFilePath(src);
|
||||||
Utils::HostOsInfo::withExecutableSuffix("unzip"));
|
for (const Tool &tool : tools) {
|
||||||
if (!unzip.isEmpty())
|
const Utils::optional<Tool> resolvedTool = resolveTool(tool);
|
||||||
return Tool{unzip, {"-o", src.toString(), "-d", dest.toString()}};
|
if (resolvedTool) {
|
||||||
|
Tool result = *resolvedTool;
|
||||||
const Utils::FilePath sevenzip = Utils::Environment::systemEnvironment().searchInPath(
|
const QString srcStr = src.toString();
|
||||||
Utils::HostOsInfo::withExecutableSuffix("7z"));
|
const QString destStr = dest.toString();
|
||||||
if (!sevenzip.isEmpty())
|
result.arguments
|
||||||
return Tool{sevenzip, {"x", QString("-o") + dest.toString(), "-y", src.toString()}};
|
= Utils::transform(result.arguments, [srcStr, destStr](const QString &a) {
|
||||||
|
QString val = a;
|
||||||
const Utils::FilePath cmake = Utils::Environment::systemEnvironment().searchInPath(
|
return val.replace("%{src}", srcStr).replace("%{dest}", destStr);
|
||||||
Utils::HostOsInfo::withExecutableSuffix("cmake"));
|
});
|
||||||
if (!cmake.isEmpty())
|
return result;
|
||||||
return Tool{cmake, {"-E", "tar", "xvf", src.toString()}};
|
}
|
||||||
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,15 +111,16 @@ namespace Utils {
|
|||||||
|
|
||||||
bool Archive::supportsFile(const FilePath &filePath, QString *reason)
|
bool Archive::supportsFile(const FilePath &filePath, QString *reason)
|
||||||
{
|
{
|
||||||
const QList<MimeType> mimeType = mimeTypesForFileName(filePath.toString());
|
const QVector<Tool> tools = toolsForFilePath(filePath);
|
||||||
if (!anyOf(mimeType, [](const MimeType &mt) { return mt.inherits("application/zip"); })) {
|
if (tools.isEmpty()) {
|
||||||
if (reason)
|
if (reason)
|
||||||
*reason = tr("File format not supported.");
|
*reason = tr("File format not supported.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!unzipTool({}, {})) {
|
if (!anyOf(tools, [](const Tool &t) { return resolveTool(t); })) {
|
||||||
if (reason)
|
if (reason)
|
||||||
*reason = tr("Could not find unzip, 7z, or cmake executable in PATH.");
|
*reason = tr("Could not find any unarchiving executable in PATH (%1).")
|
||||||
|
.arg(transform<QStringList>(tools, &Tool::executable).join(", "));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -91,7 +134,7 @@ bool Archive::unarchive(const FilePath &src, const FilePath &dest, QWidget *pare
|
|||||||
QDir(workingDirectory).mkpath(".");
|
QDir(workingDirectory).mkpath(".");
|
||||||
CheckableMessageBox box(parent);
|
CheckableMessageBox box(parent);
|
||||||
box.setIcon(QMessageBox::Information);
|
box.setIcon(QMessageBox::Information);
|
||||||
box.setWindowTitle(tr("Unzipping File"));
|
box.setWindowTitle(tr("Unarchiving File"));
|
||||||
box.setText(tr("Unzipping \"%1\" to \"%2\".").arg(src.toUserOutput(), dest.toUserOutput()));
|
box.setText(tr("Unzipping \"%1\" to \"%2\".").arg(src.toUserOutput(), dest.toUserOutput()));
|
||||||
box.setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
box.setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||||
box.button(QDialogButtonBox::Ok)->setEnabled(false);
|
box.button(QDialogButtonBox::Ok)->setEnabled(false);
|
||||||
@@ -113,7 +156,7 @@ bool Archive::unarchive(const FilePath &src, const FilePath &dest, QWidget *pare
|
|||||||
QObject::connect(&box, &QMessageBox::rejected, &process, [&process] {
|
QObject::connect(&box, &QMessageBox::rejected, &process, [&process] {
|
||||||
SynchronousProcess::stopProcess(process);
|
SynchronousProcess::stopProcess(process);
|
||||||
});
|
});
|
||||||
process.setProgram(tool->executable.toString());
|
process.setProgram(tool->executable);
|
||||||
process.setArguments(tool->arguments);
|
process.setArguments(tool->arguments);
|
||||||
process.setWorkingDirectory(workingDirectory);
|
process.setWorkingDirectory(workingDirectory);
|
||||||
process.start(QProcess::ReadOnly);
|
process.start(QProcess::ReadOnly);
|
||||||
|
|||||||
Reference in New Issue
Block a user