diff options
Diffstat (limited to 'src/app/config')
-rw-r--r-- | src/app/config/config.pro | 13 | ||||
-rw-r--r-- | src/app/config/configcommandexecutor.cpp | 85 | ||||
-rw-r--r-- | src/app/config/configcommandlineparser.cpp | 4 |
3 files changed, 72 insertions, 30 deletions
diff --git a/src/app/config/config.pro b/src/app/config/config.pro deleted file mode 100644 index 278c481d1..000000000 --- a/src/app/config/config.pro +++ /dev/null @@ -1,13 +0,0 @@ -include(../app.pri) - -TARGET = qbs-config - -SOURCES += \ - configcommandexecutor.cpp \ - configcommandlineparser.cpp \ - configmain.cpp - -HEADERS += \ - configcommand.h \ - configcommandexecutor.h \ - configcommandlineparser.h diff --git a/src/app/config/configcommandexecutor.cpp b/src/app/config/configcommandexecutor.cpp index 023514980..cbcb5ee73 100644 --- a/src/app/config/configcommandexecutor.cpp +++ b/src/app/config/configcommandexecutor.cpp @@ -49,11 +49,52 @@ #include <QtCore/qdir.h> #include <QtCore/qfile.h> #include <QtCore/qtextstream.h> +#include <QtCore/qjsondocument.h> +#include <QtCore/qjsonobject.h> #include <cstdio> using namespace qbs; +static QJsonObject settingsToJSONObject( + Settings &settings, qbs::Settings::Scopes scopes, const QString &parentGroup = {}) +{ + QJsonObject result; + + const auto allKeys = settings.directChildren(parentGroup, scopes); + for (const auto& key : allKeys) { + const auto fullKey = parentGroup.isEmpty() + ? key + : QStringLiteral("%1.%2").arg(parentGroup, key); + const auto value = settings.value(fullKey, scopes); + if (value.isValid()) { // looks like a real value + result[key] = QJsonValue::fromVariant(value); + } else { // looks like a group + result[key] = settingsToJSONObject(settings, scopes, fullKey); + } + } + + return result; +} + +static void settingsFromJSONObject( + Settings &settings, const QJsonObject &object, const QString &parentGroup = {}) +{ + for (auto it = object.begin(), end = object.end(); it != end; ++it) { + const auto key = it.key(); + const auto value = it.value(); + const auto fullKey = parentGroup.isEmpty() + ? key + : QStringLiteral("%1.%2").arg(parentGroup, key); + if (value.isObject()) { + settingsFromJSONObject(settings, it.value().toObject(), fullKey); + } else { + settings.setValue(fullKey, value.toVariant()); + } + } +} + + ConfigCommandExecutor::ConfigCommandExecutor(Settings *settings, Settings::Scopes scope) : m_settings(settings), m_scope(scope) { @@ -139,12 +180,20 @@ void ConfigCommandExecutor::exportSettings(const QString &filename) throw ErrorInfo(tr("Could not open file '%1' for writing: %2") .arg(QDir::toNativeSeparators(filename), file.errorString())); } - QTextStream stream(&file); - setupDefaultCodec(stream); - const auto keys = m_settings->allKeys(m_scope); - for (const QString &key : keys) - stream << key << ": " << qbs::settingsValueToRepresentation(m_settings->value(key, m_scope)) - << Qt::endl; + + if (QFileInfo(filename).suffix() == u"json") { + QJsonDocument doc; + doc.setObject(settingsToJSONObject(*m_settings, m_scope)); + file.write(doc.toJson()); + } else { + QTextStream stream(&file); + setupDefaultCodec(stream); + const auto keys = m_settings->allKeys(m_scope); + for (const QString &key : keys) + stream << key << ": " + << qbs::settingsValueToRepresentation(m_settings->value(key, m_scope)) + << Qt::endl; + } } void ConfigCommandExecutor::importSettings(const QString &filename) @@ -159,15 +208,21 @@ void ConfigCommandExecutor::importSettings(const QString &filename) for (const QString &key : keys) m_settings->remove(key); - QTextStream stream(&file); - setupDefaultCodec(stream); - while (!stream.atEnd()) { - QString line = stream.readLine(); - int colon = line.indexOf(QLatin1Char(':')); - if (colon >= 0 && !line.startsWith(QLatin1Char('#'))) { - const QString key = line.left(colon).trimmed(); - const QString value = line.mid(colon + 1).trimmed(); - m_settings->setValue(key, representationToSettingsValue(value)); + if (QFileInfo(filename).suffix() == u"json") { + const auto doc = QJsonDocument::fromJson(file.readAll()); + const auto object = doc.object(); + settingsFromJSONObject(*m_settings, doc.object()); + } else { + QTextStream stream(&file); + setupDefaultCodec(stream); + while (!stream.atEnd()) { + QString line = stream.readLine(); + int colon = line.indexOf(QLatin1Char(':')); + if (colon >= 0 && !line.startsWith(QLatin1Char('#'))) { + const QString key = line.left(colon).trimmed(); + const QString value = line.mid(colon + 1).trimmed(); + m_settings->setValue(key, representationToSettingsValue(value)); + } } } } diff --git a/src/app/config/configcommandlineparser.cpp b/src/app/config/configcommandlineparser.cpp index f4d0a142f..1ad0cc4b1 100644 --- a/src/app/config/configcommandlineparser.cpp +++ b/src/app/config/configcommandlineparser.cpp @@ -126,8 +126,8 @@ void ConfigCommandLineParser::parse(const QStringList &commandLine) throw Error(Tr::tr("Profile properties must be provided.")); if (m_command.varNames.size() % 2 != 0) throw Error(Tr::tr("Profile properties must be key/value pairs.")); - for (int i = 0; i < m_command.varNames.size(); ++i) { - if (m_command.varNames.at(i).isEmpty()) + for (const auto &varName : std::as_const(m_command.varNames)) { + if (varName.isEmpty()) throw Error(Tr::tr("Property names must not be empty.")); } break; |