From b7cd97a4f8fa1642f0a099f8d9239c086e2a3c5c Mon Sep 17 00:00:00 2001 From: Jos van den Oever Date: Fri, 11 Aug 2017 18:25:51 +0200 Subject: [PATCH] Only write if the file changed --- .../rust_qt_binding_generator.cpp | 97 +++++++++++-------- tests/CMakeLists.txt | 3 +- 2 files changed, 60 insertions(+), 40 deletions(-) diff --git a/rust_qt_binding_generator/rust_qt_binding_generator.cpp b/rust_qt_binding_generator/rust_qt_binding_generator.cpp index e0edc84..95cf0fe 100644 --- a/rust_qt_binding_generator/rust_qt_binding_generator.cpp +++ b/rust_qt_binding_generator/rust_qt_binding_generator.cpp @@ -41,6 +41,7 @@ struct Configuration { QString interfaceModule; QString implementationModule; QList objects; + bool overwriteImplementation; }; Property @@ -83,7 +84,7 @@ Configuration parseConfiguration(const QString& path) { QFile configurationFile(path); const QDir base = QFileInfo(configurationFile).dir(); - if (!configurationFile.open(QIODevice::ReadOnly | QIODevice::Text)) { + if (!configurationFile.open(QIODevice::ReadOnly)) { err << QCoreApplication::translate("main", "Cannot read %1.\n").arg(configurationFile.fileName()); err.flush(); @@ -208,7 +209,7 @@ QVariant %1::data(const QModelIndex &index, int role) const QVariant v; switch ((%1Role)role) { )").arg(o.name, lcname); - + for (auto role: o.roles) { cpp << QString(" case %1Role%2:\n").arg(o.name, role.name); cpp << QString(" %1_data_%2(d, index.row(), &v, set_qvariant);\n") @@ -352,15 +353,47 @@ void writeCppObject(QTextStream& cpp, const Object& o) { } } -void writeHeader(const Configuration& conf) { - QFile hFile(conf.hFile.absoluteFilePath()); - if (!hFile.open(QIODevice::WriteOnly | QIODevice::Text)) { - err << QCoreApplication::translate("main", - "Cannot write %1.\n").arg(hFile.fileName()); - err.flush(); - exit(1); +// Only write a file if it is different +class DifferentFileWriter { +public: + const QString path; + QByteArray buffer; + bool overwrite; + DifferentFileWriter(const QString& p, bool o = true) :path(p), overwrite(o) + { } - QTextStream h(&hFile); + ~DifferentFileWriter() { + const QByteArray old = read(); + // write if file does not exists + if ((!old.isNull() && overwrite) || old == buffer) { + return; + } + write(); + } + QByteArray read() const { + QByteArray content; + QFile file(path); + if (file.open(QIODevice::ReadOnly)) { + content = file.readAll(); + } + return content; + } + void write() const { + QFile file(path); + if (!file.open(QIODevice::WriteOnly)) { + err << QCoreApplication::translate("main", + "Cannot write %1.\n").arg(file.fileName()); + err.flush(); + exit(1); + } + file.write(buffer); + file.close(); + } +}; + +void writeHeader(const Configuration& conf) { + DifferentFileWriter w(conf.hFile.absoluteFilePath()); + QTextStream h(&w.buffer); const QString guard(conf.hFile.fileName().replace('.', '_').toUpper()); h << QString(R"(/* generated by rust_qt_binding_generator */ #ifndef %1 @@ -379,14 +412,8 @@ void writeHeader(const Configuration& conf) { } void writeCpp(const Configuration& conf) { - QFile cppFile(conf.cppFile.absoluteFilePath()); - if (!cppFile.open(QIODevice::WriteOnly | QIODevice::Text)) { - err << QCoreApplication::translate("main", - "Cannot write %1.\n").arg(cppFile.fileName()); - err.flush(); - exit(1); - } - QTextStream cpp(&cppFile); + DifferentFileWriter w(conf.cppFile.absoluteFilePath()); + QTextStream cpp(&w.buffer); cpp << QString(R"(/* generated by rust_qt_binding_generator */ #include "%1" #include @@ -737,14 +764,8 @@ QString rustFile(const QDir rustdir, const QString& module) { } void writeRustInterface(const Configuration& conf) { - QFile file(rustFile(conf.rustdir, conf.interfaceModule)); - if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { - err << QCoreApplication::translate("main", - "Cannot write %1.\n").arg(file.fileName()); - err.flush(); - exit(1); - } - QTextStream r(&file); + DifferentFileWriter w(rustFile(conf.rustdir, conf.interfaceModule)); + QTextStream r(&w.buffer); r << QString(R"( #![allow(unknown_lints)] #![allow(mutex_atomic, needless_pass_by_value)] @@ -822,17 +843,9 @@ void writeRustImplementationObject(QTextStream& r, const Object& o) { } void writeRustImplementation(const Configuration& conf) { - QFile file(rustFile(conf.rustdir, conf.implementationModule)); - if (file.exists()) { - return; - } - if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { - err << QCoreApplication::translate("main", - "Cannot write %1.\n").arg(file.fileName()); - err.flush(); - exit(1); - } - QTextStream r(&file); + DifferentFileWriter w(rustFile(conf.rustdir, conf.implementationModule), + conf.overwriteImplementation); + QTextStream r(&w.buffer); r << QString(R"(use libc::c_int; use types::*; use %1::*; @@ -856,6 +869,13 @@ int main(int argc, char *argv[]) { parser.addPositionalArgument("configuration", QCoreApplication::translate("main", "Configuration file")); + // A boolean option (--overwrite-implementation) + QCommandLineOption overwriteOption(QStringList() + << "overwrite-implementation", + QCoreApplication::translate("main", + "Overwrite existing implementation.")); + parser.addOption(overwriteOption); + parser.process(app); const QStringList args = parser.positionalArguments(); @@ -866,7 +886,8 @@ int main(int argc, char *argv[]) { } const QString configurationFile(args.at(0)); - const Configuration configuration = parseConfiguration(configurationFile); + Configuration configuration = parseConfiguration(configurationFile); + configuration.overwriteImplementation = parser.isSet(overwriteOption); writeHeader(configuration); writeCpp(configuration); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index c6b3687..08c0d8b 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -2,8 +2,7 @@ enable_testing() add_custom_command( OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/rust_object/src/interface.rs" - COMMAND "${CMAKE_COMMAND}" -E remove "${CMAKE_CURRENT_SOURCE_DIR}/rust_object/src/implementation.rs" - COMMAND ${CMAKE_BINARY_DIR}/rust_qt_binding_generator/rust_qt_binding_generator "${CMAKE_CURRENT_SOURCE_DIR}/test_object.json" + COMMAND ${CMAKE_BINARY_DIR}/rust_qt_binding_generator/rust_qt_binding_generator --overwrite-implementation "${CMAKE_CURRENT_SOURCE_DIR}/test_object.json" DEPENDS rust_qt_binding_generator test_object.json )