diff --git a/src/libs/utils/unarchiver.cpp b/src/libs/utils/unarchiver.cpp index 84365654253..d9092e4ca95 100644 --- a/src/libs/utils/unarchiver.cpp +++ b/src/libs/utils/unarchiver.cpp @@ -43,6 +43,7 @@ static const QList &sTools() { static QList tools; if (tools.isEmpty()) { + // clang-format off if (HostOsInfo::isWindowsHost()) { tools << Tool{{"powershell", "-command Expand-Archive -Force '%{src}' '%{dest}'", CommandLine::Raw}, {"application/zip"}, @@ -74,6 +75,10 @@ static const QList &sTools() tools << Tool{{"cmake", {"-E", "tar", "xvjf", "%{src}"}}, {"application/x-bzip-compressed-tar"}, additionalCMakeDirs}; + // Keep this at the end so its only used as last resort. Otherwise it might be used for + // .tar.gz files. + tools << Tool{{"gzip", {"-d", "%{src}", "-c"}}, {"application/gzip"}, {}}; + // clang-format on } return tools; } @@ -147,6 +152,45 @@ void Unarchiver::start() m_sourceAndCommand->m_sourceFile, m_destDir); m_destDir.ensureWritableDir(); + if (command.executable().fileName() == "gzip") { + std::shared_ptr outputFile = std::make_shared( + (m_destDir / m_gzipFileDestName).toFSPathString()); + + if (!outputFile->open(QIODevice::WriteOnly)) { + emit outputReceived(Tr::tr("Failed to open output file.")); + emit done(DoneResult::Error); + return; + } + + m_process.reset(new Process); + QObject::connect(m_process.get(), &Process::readyReadStandardOutput, this, [this, outputFile] { + const QByteArray data = m_process->readAllRawStandardOutput(); + if (outputFile->write(data) != data.size()) { + emit outputReceived(Tr::tr("Failed to write output file.")); + emit done(DoneResult::Error); + } + }); + QObject::connect(m_process.get(), &Process::readyReadStandardError, this, [this] { + emit outputReceived(m_process->readAllStandardError()); + }); + QObject::connect(m_process.get(), &Process::done, this, [outputFile, this] { + outputFile->close(); + const bool success = m_process->result() == ProcessResult::FinishedWithSuccess; + if (!success) { + outputFile->remove(); + emit outputReceived(Tr::tr("Command failed.")); + } + emit done(toDoneResult(success)); + }); + emit outputReceived( + Tr::tr("Running %1\nin \"%2\".\n\n", "Running in ") + .arg(command.toUserOutput(), m_destDir.toUserOutput())); + m_process->setCommand(command); + m_process->setWorkingDirectory(m_destDir); + m_process->start(); + return; + } + m_process.reset(new Process); m_process->setProcessChannelMode(QProcess::MergedChannels); QObject::connect(m_process.get(), &Process::readyReadStandardOutput, this, [this] { diff --git a/src/libs/utils/unarchiver.h b/src/libs/utils/unarchiver.h index 61818318bb7..23fcad07a81 100644 --- a/src/libs/utils/unarchiver.h +++ b/src/libs/utils/unarchiver.h @@ -32,7 +32,10 @@ public: void setSourceAndCommand(const SourceAndCommand &data) { m_sourceAndCommand = data; } void setDestDir(const FilePath &destDir) { m_destDir = destDir; } - + void setGZipFileDestName(const QString &gzipFileDestName) + { + m_gzipFileDestName = gzipFileDestName; + } void start(); signals: @@ -43,6 +46,7 @@ private: std::optional m_sourceAndCommand; FilePath m_destDir; std::unique_ptr m_process; + QString m_gzipFileDestName; }; class QTCREATOR_UTILS_EXPORT UnarchiverTaskAdapter : public Tasking::TaskAdapter