summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEike Ziller <eike.ziller@qt.io>2020-05-27 16:32:31 +0200
committerEike Ziller <eike.ziller@qt.io>2020-05-29 13:17:02 +0000
commit26c26c0dada6b057804dd15f1cc0c057e0d794a8 (patch)
tree915c65229c97e488cde82aee9bf1d78d7df2bddd
parentf75d1ae61a26cd51c9b0a73a66dbf336eb61551b (diff)
downloadqt-creator-26c26c0dada6b057804dd15f1cc0c057e0d794a8.tar.gz
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>
-rw-r--r--src/libs/utils/archive.cpp83
1 files changed, 63 insertions, 20 deletions
diff --git a/src/libs/utils/archive.cpp b/src/libs/utils/archive.cpp
index daab53451f..0ea6a920f2 100644
--- a/src/libs/utils/archive.cpp
+++ b/src/libs/utils/archive.cpp
@@ -39,27 +39,69 @@ namespace {
struct Tool
{
- Utils::FilePath executable;
+ QString executable;
QStringList arguments;
+ QStringList supportedMimeTypes;
};
-Utils::optional<Tool> unzipTool(const Utils::FilePath &src, const Utils::FilePath &dest)
+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)
{
- const Utils::FilePath unzip = Utils::Environment::systemEnvironment().searchInPath(
- Utils::HostOsInfo::withExecutableSuffix("unzip"));
- if (!unzip.isEmpty())
- return Tool{unzip, {"-o", src.toString(), "-d", dest.toString()}};
+ return Utils::filtered(sTools, [mimeType](const Tool &tool) {
+ return Utils::anyOf(tool.supportedMimeTypes,
+ [mimeType](const QString &mt) { return mimeType.inherits(mt); });
+ });
+}
- const Utils::FilePath sevenzip = Utils::Environment::systemEnvironment().searchInPath(
- Utils::HostOsInfo::withExecutableSuffix("7z"));
- if (!sevenzip.isEmpty())
- return Tool{sevenzip, {"x", QString("-o") + dest.toString(), "-y", src.toString()}};
+static QVector<Tool> toolsForFilePath(const Utils::FilePath &fp)
+{
+ return toolsForMimeType(Utils::mimeTypeForFile(fp.toString()));
+}
- const Utils::FilePath cmake = Utils::Environment::systemEnvironment().searchInPath(
- Utils::HostOsInfo::withExecutableSuffix("cmake"));
- if (!cmake.isEmpty())
- return Tool{cmake, {"-E", "tar", "xvf", src.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)
+{
+ const QVector<Tool> tools = toolsForFilePath(src);
+ for (const Tool &tool : tools) {
+ const Utils::optional<Tool> resolvedTool = resolveTool(tool);
+ if (resolvedTool) {
+ Tool result = *resolvedTool;
+ const QString srcStr = src.toString();
+ const QString destStr = dest.toString();
+ result.arguments
+ = Utils::transform(result.arguments, [srcStr, destStr](const QString &a) {
+ QString val = a;
+ return val.replace("%{src}", srcStr).replace("%{dest}", destStr);
+ });
+ return result;
+ }
+ }
return {};
}
@@ -69,15 +111,16 @@ namespace Utils {
bool Archive::supportsFile(const FilePath &filePath, QString *reason)
{
- const QList<MimeType> mimeType = mimeTypesForFileName(filePath.toString());
- if (!anyOf(mimeType, [](const MimeType &mt) { return mt.inherits("application/zip"); })) {
+ const QVector<Tool> tools = toolsForFilePath(filePath);
+ if (tools.isEmpty()) {
if (reason)
*reason = tr("File format not supported.");
return false;
}
- if (!unzipTool({}, {})) {
+ if (!anyOf(tools, [](const Tool &t) { return resolveTool(t); })) {
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 true;
@@ -91,7 +134,7 @@ bool Archive::unarchive(const FilePath &src, const FilePath &dest, QWidget *pare
QDir(workingDirectory).mkpath(".");
CheckableMessageBox box(parent);
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.setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
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] {
SynchronousProcess::stopProcess(process);
});
- process.setProgram(tool->executable.toString());
+ process.setProgram(tool->executable);
process.setArguments(tool->arguments);
process.setWorkingDirectory(workingDirectory);
process.start(QProcess::ReadOnly);