replace in-place-rewriting of files with a read/modify/write cycle

easier to handle errors that way
This commit is contained in:
Oswald Buddenhagen
2011-03-30 15:18:52 +02:00
parent 45c9cf7a12
commit ff456bb4b6
4 changed files with 121 additions and 139 deletions

View File

@@ -44,6 +44,7 @@
#include <qt4project.h> #include <qt4project.h>
#include <qt4target.h> #include <qt4target.h>
#include <utils/environment.h> #include <utils/environment.h>
#include <utils/fileutils.h>
#include <QtCore/QDateTime> #include <QtCore/QDateTime>
#include <QtCore/QProcess> #include <QtCore/QProcess>
@@ -440,15 +441,15 @@ bool MaemoDebianPackageCreationStep::copyDebianFiles(bool inSourceBuild)
= templatesDirPath + QLatin1Char('/') + fileName; = templatesDirPath + QLatin1Char('/') + fileName;
const QString destFile const QString destFile
= debianDirPath + QLatin1Char('/') + fileName; = debianDirPath + QLatin1Char('/') + fileName;
if (!QFile::copy(srcFile, destFile)) { if (fileName == QLatin1String("rules")) {
if (!adaptRulesFile(srcFile, destFile))
return false;
} else if (!QFile::copy(srcFile, destFile)) {
raiseError(tr("Could not copy file '%1' to '%2'") raiseError(tr("Could not copy file '%1' to '%2'")
.arg(QDir::toNativeSeparators(srcFile), .arg(QDir::toNativeSeparators(srcFile),
QDir::toNativeSeparators(destFile))); QDir::toNativeSeparators(destFile)));
return false; return false;
} }
if (fileName == QLatin1String("rules"))
adaptRulesFile(destFile);
} }
QFile magicFile(magicFilePath); QFile magicFile(magicFilePath);
@@ -484,22 +485,22 @@ void MaemoDebianPackageCreationStep::ensureShlibdeps(QByteArray &rulesContent)
rulesContent = contentAsString.toLocal8Bit(); rulesContent = contentAsString.toLocal8Bit();
} }
void MaemoDebianPackageCreationStep::adaptRulesFile(const QString &rulesFilePath) bool MaemoDebianPackageCreationStep::adaptRulesFile(
const QString &templatePath, const QString &rulesFilePath)
{ {
QFile rulesFile(rulesFilePath); Utils::FileReader reader;
rulesFile.setPermissions(rulesFile.permissions() | QFile::ExeUser); if (!reader.fetch(templatePath)) {
if (!rulesFile.open(QIODevice::ReadWrite)) { raiseError(reader.errorString());
qWarning("Cannot open rules file for Maemo6 icon path adaptation."); return false;
return;
} }
QByteArray content = rulesFile.readAll(); QByteArray content = reader.data();
const int makeInstallLine = content.indexOf("\t$(MAKE) INSTALL_ROOT"); const int makeInstallLine = content.indexOf("\t$(MAKE) INSTALL_ROOT");
if (makeInstallLine == -1) if (makeInstallLine == -1)
return; return true;
const int makeInstallEol = content.indexOf('\n', makeInstallLine); const int makeInstallEol = content.indexOf('\n', makeInstallLine);
if (makeInstallEol == -1) if (makeInstallEol == -1)
return; return true;
QString desktopFileDir = QFileInfo(rulesFile).dir().path() QString desktopFileDir = QFileInfo(rulesFilePath).path()
+ QLatin1Char('/') + maemoTarget()->packageName() + QLatin1Char('/') + maemoTarget()->packageName()
+ QLatin1String("/usr/share/applications/"); + QLatin1String("/usr/share/applications/");
const Qt4BuildConfiguration * const bc = qt4BuildConfiguration(); const Qt4BuildConfiguration * const bc = qt4BuildConfiguration();
@@ -539,8 +540,15 @@ void MaemoDebianPackageCreationStep::adaptRulesFile(const QString &rulesFilePath
if (!(bc->qmakeBuildConfiguration() & QtVersion::DebugBuild)) if (!(bc->qmakeBuildConfiguration() & QtVersion::DebugBuild))
ensureShlibdeps(content); ensureShlibdeps(content);
rulesFile.resize(0); Utils::FileSaver saver(rulesFilePath);
rulesFile.write(content); saver.write(content);
if (!saver.finalize()) {
raiseError(saver.errorString());
return false;
}
QFile rulesFile(rulesFilePath);
rulesFile.setPermissions(rulesFile.permissions() | QFile::ExeUser);
return true;
} }
void MaemoDebianPackageCreationStep::addWorkaroundForHarmattanBug(QByteArray &rulesFileContent, void MaemoDebianPackageCreationStep::addWorkaroundForHarmattanBug(QByteArray &rulesFileContent,

View File

@@ -137,7 +137,7 @@ private:
int &insertPos, const MaemoDeployableListModel *model, int &insertPos, const MaemoDeployableListModel *model,
const QString &desktopFileDir); const QString &desktopFileDir);
void checkProjectName(); void checkProjectName();
void adaptRulesFile(const QString &rulesFilePath); bool adaptRulesFile(const QString &templatePath, const QString &rulesFilePath);
static const QString CreatePackageId; static const QString CreatePackageId;
}; };

View File

@@ -43,6 +43,7 @@
#include <projectexplorer/target.h> #include <projectexplorer/target.h>
#include <qt4projectmanager/qmakestep.h> #include <qt4projectmanager/qmakestep.h>
#include <qt4projectmanager/qt4buildconfiguration.h> #include <qt4projectmanager/qt4buildconfiguration.h>
#include <utils/fileutils.h>
#include <QtCore/QCoreApplication> #include <QtCore/QCoreApplication>
#include <QtCore/QDir> #include <QtCore/QDir>
@@ -203,28 +204,32 @@ bool MaemoPublisherFremantleFree::copyRecursively(const QString &srcFilePath,
return false; return false;
} }
} else { } else {
if (!QFile::copy(srcFilePath, tgtFilePath)) {
emit progressReport(tr("Could not copy file '%1' to '%2'.")
.arg(QDir::toNativeSeparators(srcFilePath),
QDir::toNativeSeparators(tgtFilePath)));
return false;
}
QCoreApplication::processEvents();
if (tgtFilePath == m_tmpProjectDir + QLatin1String("/debian/rules")) { if (tgtFilePath == m_tmpProjectDir + QLatin1String("/debian/rules")) {
QFile rulesFile(tgtFilePath); Utils::FileReader reader;
if (!rulesFile.open(QIODevice::ReadWrite)) { if (!reader.fetch(srcFilePath)) {
emit progressReport(tr("Error: Cannot open file '%1'.") emit progressReport(reader.errorString(), ErrorOutput);
.arg(QDir::toNativeSeparators(tgtFilePath)));
return false; return false;
} }
QByteArray rulesContents = rulesFile.readAll(); QByteArray rulesContents = reader.data();
rulesContents.replace("$(MAKE) clean", "# $(MAKE) clean"); rulesContents.replace("$(MAKE) clean", "# $(MAKE) clean");
rulesContents.replace("# Add here commands to configure the package.", rulesContents.replace("# Add here commands to configure the package.",
"qmake " + QFileInfo(m_project->file()->fileName()).fileName().toLocal8Bit()); "qmake " + QFileInfo(m_project->file()->fileName()).fileName().toLocal8Bit());
MaemoDebianPackageCreationStep::ensureShlibdeps(rulesContents); MaemoDebianPackageCreationStep::ensureShlibdeps(rulesContents);
rulesFile.resize(0); Utils::FileSaver saver(tgtFilePath);
rulesFile.write(rulesContents); saver.write(rulesContents);
if (!saver.finalize()) {
emit progressReport(saver.errorString(), ErrorOutput);
return false;
}
} else {
QFile srcFile(srcFilePath);
if (!srcFile.copy(tgtFilePath)) {
emit progressReport(tr("Could not copy file '%1' to '%2': %3.")
.arg(QDir::toNativeSeparators(srcFilePath),
QDir::toNativeSeparators(tgtFilePath),
srcFile.errorString()));
return false;
}
} }
} }
return true; return true;
@@ -235,16 +240,19 @@ bool MaemoPublisherFremantleFree::fixNewlines()
QDir debianDir(m_tmpProjectDir + QLatin1String("/debian")); QDir debianDir(m_tmpProjectDir + QLatin1String("/debian"));
const QStringList &fileNames = debianDir.entryList(QDir::Files); const QStringList &fileNames = debianDir.entryList(QDir::Files);
foreach (const QString &fileName, fileNames) { foreach (const QString &fileName, fileNames) {
QFile file(debianDir.filePath(fileName)); QString filePath = debianDir.filePath(fileName);
if (!file.open(QIODevice::ReadWrite)) Utils::FileReader reader;
if (!reader.fetch(filePath))
return false; return false;
QByteArray contents = file.readAll(); QByteArray contents = reader.data();
const QByteArray crlf("\r\n"); const QByteArray crlf("\r\n");
if (!contents.contains(crlf)) if (!contents.contains(crlf))
continue; continue;
contents.replace(crlf, "\n"); contents.replace(crlf, "\n");
file.resize(0); Utils::FileSaver saver(filePath);
file.write(contents); saver.write(contents);
if (!saver.finalize())
return false;
} }
return true; return true;
} }
@@ -529,27 +537,25 @@ bool MaemoPublisherFremantleFree::updateDesktopFiles(QString *error) const
if (desktopFilePath.isEmpty()) if (desktopFilePath.isEmpty())
continue; continue;
desktopFilePath.replace(model->projectDir(), m_tmpProjectDir); desktopFilePath.replace(model->projectDir(), m_tmpProjectDir);
QFile desktopFile(desktopFilePath);
const QString executableFilePath = model->remoteExecutableFilePath(); const QString executableFilePath = model->remoteExecutableFilePath();
if (executableFilePath.isEmpty()) { if (executableFilePath.isEmpty()) {
qDebug("%s: Skipping subproject %s with missing deployment information.", qDebug("%s: Skipping subproject %s with missing deployment information.",
Q_FUNC_INFO, qPrintable(model->proFilePath())); Q_FUNC_INFO, qPrintable(model->proFilePath()));
continue; continue;
} }
if (!desktopFile.exists() || !desktopFile.open(QIODevice::ReadWrite)) { Utils::FileReader reader;
if (!reader.fetch(desktopFilePath, error)) {
success = false; success = false;
if (error) {
*error = tr("Failed to adapt desktop file '%1'.")
.arg(desktopFilePath);
}
continue; continue;
} }
QByteArray desktopFileContents = desktopFile.readAll(); QByteArray desktopFileContents = reader.data();
bool fileNeedsUpdate = addOrReplaceDesktopFileValue(desktopFileContents, bool fileNeedsUpdate = addOrReplaceDesktopFileValue(desktopFileContents,
"Exec", executableFilePath.toUtf8()); "Exec", executableFilePath.toUtf8());
if (fileNeedsUpdate) { if (fileNeedsUpdate) {
desktopFile.resize(0); Utils::FileSaver saver(desktopFilePath);
desktopFile.write(desktopFileContents); saver.write(desktopFileContents);
if (!saver.finalize(error))
success = false;
} }
} }
return success; return success;

View File

@@ -50,6 +50,7 @@
#include <utils/fileutils.h> #include <utils/fileutils.h>
#include <utils/filesystemwatcher.h> #include <utils/filesystemwatcher.h>
#include <utils/fileutils.h>
#include <QtGui/QApplication> #include <QtGui/QApplication>
#include <QtGui/QMainWindow> #include <QtGui/QMainWindow>
@@ -411,27 +412,16 @@ bool AbstractDebBasedQt4MaemoTarget::setProjectVersionInternal(const QString &ve
QString *error) QString *error)
{ {
const QString filePath = changeLogFilePath(); const QString filePath = changeLogFilePath();
MaemoGlobal::FileUpdate update(filePath); Utils::FileReader reader;
QSharedPointer<QFile> changeLog if (!reader.fetch(filePath, error))
= openFile(filePath, QIODevice::ReadWrite, error);
if (!changeLog)
return false; return false;
QString content = QString::fromUtf8(reader.data());
QString content = QString::fromUtf8(changeLog->readAll());
content.replace(QRegExp(QLatin1String("\\([a-zA-Z0-9_\\.]+\\)")), content.replace(QRegExp(QLatin1String("\\([a-zA-Z0-9_\\.]+\\)")),
QLatin1Char('(') + version + QLatin1Char(')')); QLatin1Char('(') + version + QLatin1Char(')'));
changeLog->resize(0); MaemoGlobal::FileUpdate update(filePath);
changeLog->write(content.toUtf8()); Utils::FileSaver saver(filePath);
changeLog->close(); saver.write(content.toUtf8());
if (changeLog->error() != QFile::NoError) { return saver.finalize(error);
if (error) {
*error = tr("Error writing Debian changelog file '%1': %2")
.arg(QDir::toNativeSeparators(changeLog->fileName()),
changeLog->errorString());
}
return false;
}
return true;
} }
QIcon AbstractDebBasedQt4MaemoTarget::packageManagerIcon(QString *error) const QIcon AbstractDebBasedQt4MaemoTarget::packageManagerIcon(QString *error) const
@@ -452,10 +442,8 @@ bool AbstractDebBasedQt4MaemoTarget::setPackageManagerIconInternal(const QString
QString *error) QString *error)
{ {
const QString filePath = controlFilePath(); const QString filePath = controlFilePath();
MaemoGlobal::FileUpdate update(filePath); Utils::FileReader reader;
const QSharedPointer<QFile> controlFile if (!reader.fetch(filePath, error))
= openFile(filePath, QIODevice::ReadWrite, error);
if (!controlFile)
return false; return false;
const QPixmap pixmap(iconFilePath); const QPixmap pixmap(iconFilePath);
if (pixmap.isNull()) { if (pixmap.isNull()) {
@@ -475,7 +463,7 @@ bool AbstractDebBasedQt4MaemoTarget::setPackageManagerIconInternal(const QString
} }
buffer.close(); buffer.close();
iconAsBase64 = iconAsBase64.toBase64(); iconAsBase64 = iconAsBase64.toBase64();
QByteArray contents = controlFile->readAll(); QByteArray contents = reader.data();
const QByteArray iconFieldNameWithColon = IconFieldName + ':'; const QByteArray iconFieldNameWithColon = IconFieldName + ':';
const int iconFieldPos = contents.startsWith(iconFieldNameWithColon) const int iconFieldPos = contents.startsWith(iconFieldNameWithColon)
? 0 : contents.indexOf('\n' + iconFieldNameWithColon); ? 0 : contents.indexOf('\n' + iconFieldNameWithColon);
@@ -498,17 +486,10 @@ bool AbstractDebBasedQt4MaemoTarget::setPackageManagerIconInternal(const QString
contents.replace(oldIconStartPos, nextEolPos - oldIconStartPos, contents.replace(oldIconStartPos, nextEolPos - oldIconStartPos,
' ' + iconAsBase64); ' ' + iconAsBase64);
} }
controlFile->resize(0); MaemoGlobal::FileUpdate update(filePath);
controlFile->write(contents); Utils::FileSaver saver(filePath);
if (controlFile->error() != QFile::NoError) { saver.write(contents);
if (error) { return saver.finalize(error);
*error = tr("Error writing file '%1': %2")
.arg(QDir::toNativeSeparators(controlFile->fileName()),
controlFile->errorString());
}
return false;
}
return true;
} }
QString AbstractDebBasedQt4MaemoTarget::packageName() const QString AbstractDebBasedQt4MaemoTarget::packageName() const
@@ -525,32 +506,26 @@ bool AbstractDebBasedQt4MaemoTarget::setPackageNameInternal(const QString &packa
if (!setControlFieldValue("Source", packageName.toUtf8())) if (!setControlFieldValue("Source", packageName.toUtf8()))
return false; return false;
QSharedPointer<QFile> changelogFile Utils::FileReader reader;
= openFile(changeLogFilePath(), QIODevice::ReadWrite, 0); if (!reader.fetch(changeLogFilePath()))
if (!changelogFile)
return false; return false;
QString changelogContents = QString::fromUtf8(changelogFile->readAll()); QString changelogContents = QString::fromUtf8(reader.data());
QRegExp pattern(QLatin1String("[^\\s]+( \\(\\d\\.\\d\\.\\d\\))")); QRegExp pattern(QLatin1String("[^\\s]+( \\(\\d\\.\\d\\.\\d\\))"));
changelogContents.replace(pattern, packageName + QLatin1String("\\1")); changelogContents.replace(pattern, packageName + QLatin1String("\\1"));
if (!changelogFile->resize(0)) Utils::FileSaver saver(changeLogFilePath());
saver.write(changelogContents.toUtf8());
if (!saver.finalize())
return false; return false;
changelogFile->write(changelogContents.toUtf8());
QSharedPointer<QFile> rulesFile if (!reader.fetch(rulesFilePath()))
= openFile(rulesFilePath(), QIODevice::ReadWrite, 0);
if (!rulesFile)
return false; return false;
QByteArray rulesContents = rulesFile->readAll(); QByteArray rulesContents = reader.data();
const QString oldString = QLatin1String("debian/") + oldPackageName; const QString oldString = QLatin1String("debian/") + oldPackageName;
const QString newString = QLatin1String("debian/") + packageName; const QString newString = QLatin1String("debian/") + packageName;
rulesContents.replace(oldString.toUtf8(), newString.toUtf8()); rulesContents.replace(oldString.toUtf8(), newString.toUtf8());
rulesFile->resize(0); Utils::FileSaver rulesSaver(changeLogFilePath());
rulesFile->write(rulesContents); rulesSaver.write(rulesContents);
if (rulesFile->error() != QFile::NoError return rulesSaver.finalize();
|| changelogFile->error() != QFile::NoError) {
return false;
}
return true;
} }
QString AbstractDebBasedQt4MaemoTarget::packageManagerName() const QString AbstractDebBasedQt4MaemoTarget::packageManagerName() const
@@ -627,10 +602,10 @@ QByteArray AbstractDebBasedQt4MaemoTarget::controlFileFieldValue(const QString &
bool multiLine) const bool multiLine) const
{ {
QByteArray value; QByteArray value;
QFile controlFile(controlFilePath()); Utils::FileReader reader;
if (!controlFile.open(QIODevice::ReadOnly)) if (!reader.fetch(controlFilePath()))
return value; return value;
const QByteArray &contents = controlFile.readAll(); const QByteArray &contents = reader.data();
const int keyPos = contents.indexOf(key.toUtf8() + ':'); const int keyPos = contents.indexOf(key.toUtf8() + ':');
if (keyPos == -1) if (keyPos == -1)
return value; return value;
@@ -664,14 +639,15 @@ QByteArray AbstractDebBasedQt4MaemoTarget::controlFileFieldValue(const QString &
bool AbstractDebBasedQt4MaemoTarget::setControlFieldValue(const QByteArray &fieldName, bool AbstractDebBasedQt4MaemoTarget::setControlFieldValue(const QByteArray &fieldName,
const QByteArray &fieldValue) const QByteArray &fieldValue)
{ {
QFile controlFile(controlFilePath()); Utils::FileReader reader;
MaemoGlobal::FileUpdate update(controlFile.fileName()); if (!reader.fetch(controlFilePath()))
if (!controlFile.open(QIODevice::ReadWrite))
return false; return false;
QByteArray contents = controlFile.readAll(); QByteArray contents = reader.data();
if (adaptControlFileField(contents, fieldName, fieldValue)) { if (adaptControlFileField(contents, fieldName, fieldValue)) {
controlFile.resize(0); MaemoGlobal::FileUpdate update(controlFilePath());
controlFile.write(contents); Utils::FileSaver saver(changeLogFilePath());
saver.write(contents);
return saver.finalize();
} }
return true; return true;
} }
@@ -784,13 +760,12 @@ AbstractQt4MaemoTarget::ActionStatus AbstractDebBasedQt4MaemoTarget::createSpeci
bool AbstractDebBasedQt4MaemoTarget::adaptRulesFile() bool AbstractDebBasedQt4MaemoTarget::adaptRulesFile()
{ {
QFile rulesFile(rulesFilePath()); Utils::FileReader reader;
if (!rulesFile.open(QIODevice::ReadWrite)) { if (!reader.fetch(rulesFilePath())) {
raiseError(tr("Packaging Error: Cannot open file '%1'.") raiseError(reader.errorString());
.arg(QDir::toNativeSeparators(rulesFilePath())));
return false; return false;
} }
QByteArray rulesContents = rulesFile.readAll(); QByteArray rulesContents = reader.data();
const QByteArray comment("# Uncomment this line for use without Qt Creator"); const QByteArray comment("# Uncomment this line for use without Qt Creator");
rulesContents.replace("DESTDIR", "INSTALL_ROOT"); rulesContents.replace("DESTDIR", "INSTALL_ROOT");
rulesContents.replace("dh_shlibdeps", "# dh_shlibdeps " + comment); rulesContents.replace("dh_shlibdeps", "# dh_shlibdeps " + comment);
@@ -802,12 +777,10 @@ bool AbstractDebBasedQt4MaemoTarget::adaptRulesFile()
// because dpkg-genchanges doesn't know about it (and can't be told). // because dpkg-genchanges doesn't know about it (and can't be told).
// rulesContents.replace("dh_builddeb", "dh_builddeb --destdir=."); // rulesContents.replace("dh_builddeb", "dh_builddeb --destdir=.");
rulesFile.resize(0); Utils::FileSaver saver(rulesFilePath());
rulesFile.write(rulesContents); saver.write(rulesContents);
rulesFile.close(); if (!saver.finalize()) {
if (rulesFile.error() != QFile::NoError) { raiseError(saver.errorString());
raiseError(tr("Packaging Error: Cannot write file '%1'.")
.arg(QDir::toNativeSeparators(rulesFilePath())));
return false; return false;
} }
return true; return true;
@@ -815,14 +788,12 @@ bool AbstractDebBasedQt4MaemoTarget::adaptRulesFile()
bool AbstractDebBasedQt4MaemoTarget::adaptControlFile() bool AbstractDebBasedQt4MaemoTarget::adaptControlFile()
{ {
QFile controlFile(controlFilePath()); Utils::FileReader reader;
if (!controlFile.open(QIODevice::ReadWrite)) { if (!reader.fetch(controlFilePath())) {
raiseError(tr("Packaging Error: Cannot open file '%1'.") raiseError(reader.errorString());
.arg(QDir::toNativeSeparators(controlFilePath())));
return false; return false;
} }
QByteArray controlContents = reader.data();
QByteArray controlContents = controlFile.readAll();
adaptControlFileField(controlContents, "Section", defaultSection()); adaptControlFileField(controlContents, "Section", defaultSection());
adaptControlFileField(controlContents, "Priority", "optional"); adaptControlFileField(controlContents, "Priority", "optional");
@@ -843,12 +814,10 @@ bool AbstractDebBasedQt4MaemoTarget::adaptControlFile()
} }
addAdditionalControlFileFields(controlContents); addAdditionalControlFileFields(controlContents);
controlFile.resize(0); Utils::FileSaver saver(controlFilePath());
controlFile.write(controlContents); saver.write(controlContents);
controlFile.close(); if (!saver.finalize()) {
if (controlFile.error() != QFile::NoError) { raiseError(saver.errorString());
raiseError(tr("Packaging Error: Cannot write file '%1'.")
.arg(QDir::toNativeSeparators(controlFilePath())));
return false; return false;
} }
return true; return true;
@@ -1038,11 +1007,10 @@ bool AbstractRpmBasedQt4MaemoTarget::initAdditionalPackagingSettingsFromOtherTar
QByteArray AbstractRpmBasedQt4MaemoTarget::getValueForTag(const QByteArray &tag, QByteArray AbstractRpmBasedQt4MaemoTarget::getValueForTag(const QByteArray &tag,
QString *error) const QString *error) const
{ {
QSharedPointer<QFile> specFile Utils::FileReader reader;
= openFile(specFilePath(), QIODevice::ReadOnly, error); if (!reader.fetch(specFilePath(), error))
if (!specFile)
return QByteArray(); return QByteArray();
const QByteArray &content = specFile->readAll(); const QByteArray &content = reader.data();
const QByteArray completeTag = tag.toLower() + ':'; const QByteArray completeTag = tag.toLower() + ':';
int index = content.toLower().indexOf(completeTag); int index = content.toLower().indexOf(completeTag);
if (index == -1) if (index == -1)
@@ -1057,14 +1025,14 @@ QByteArray AbstractRpmBasedQt4MaemoTarget::getValueForTag(const QByteArray &tag,
bool AbstractRpmBasedQt4MaemoTarget::setValueForTag(const QByteArray &tag, bool AbstractRpmBasedQt4MaemoTarget::setValueForTag(const QByteArray &tag,
const QByteArray &value, QString *error) const QByteArray &value, QString *error)
{ {
QSharedPointer<QFile> specFile Utils::FileReader reader;
= openFile(specFilePath(), QIODevice::ReadWrite, error); if (!reader.fetch(specFilePath(), error))
if (!specFile)
return false; return false;
QByteArray content = specFile->readAll(); QByteArray content = reader.data();
if (adaptTagValue(content, tag, value, false)) { if (adaptTagValue(content, tag, value, false)) {
specFile->resize(0); Utils::FileSaver saver(specFilePath());
specFile->write(content); saver.write(content);
return saver.finalize(error);
} }
return true; return true;
} }