From 4f7e4a76cb6ddfe42a8bc55b5bc94e659185e34c Mon Sep 17 00:00:00 2001 From: Bernd Wachter Date: Fri, 5 Jul 2013 21:32:10 +0300 Subject: [PATCH] [variables] Add default sections, local variables, full recursive resolving - variable section resolving now tries to automatically identify default sections when looking up a complete section - local variables may be defined by prefixing with _ or using the local keyword - multiple variable sections are now supported, as well as adding both the variables keyword and variable values in a section --- board-mappings.ini | 26 ++++++++++-- libssu/ssu.cpp | 2 +- libssu/ssu.h | 2 +- libssu/ssucoreconfig.cpp | 11 +++-- libssu/ssucoreconfig.h | 4 +- libssu/ssudeviceinfo.cpp | 3 ++ libssu/ssurepomanager.cpp | 26 ++++++------ libssu/ssuvariables.cpp | 84 +++++++++++++++++++++++++++++++-------- libssu/ssuvariables.h | 25 ++++++++---- repos.ini | 7 +++- 10 files changed, 143 insertions(+), 47 deletions(-) diff --git a/board-mappings.ini b/board-mappings.ini index 2ee95eb..2555ad7 100644 --- a/board-mappings.ini +++ b/board-mappings.ini @@ -50,16 +50,34 @@ # # Freeform variable sections start with 'var-'. A variable section for an # adaptation named 'n9xx' would be 'var-n9xx'. A variable section may -# contain freeform variables, or the keyword 'variables' to include any -# other section. Currently only one section may be included, and you may -# not specify additional variables: +# contain freeform variables, and/or the keyword 'variables' to include any +# other section. +# +# Sections are resolved in the order specified, overwriting existing variables +# in the resolving order (set your systems log to DEBUG and check for warnings +# if you run into problems). The main section is resolved last, thus taking +# precedence over any section specified. +# +# Variables starting with _ are treated as 'local', and are not available for +# URL resolving. Additional variables can be declared as local by using the +# special key 'local' with a stringlist of variables. +# +# If available a default-section is used to initialize variables before +# resolving starts. To find a default section the section name is split at +# '-', and the first (for var- second) token replaced with 'default' (e.g. +# foo-bar -> default-bar; var-foo-bar -> var-default-bar). As additional +# dashes would mess this detection up you should try to avoid dashes in +# section identifiers where this functionality is desired. +# +# Valid examples are: # # [var-n9] +# local=foo # foo=bar # bar=baz # # [var-n950] -# variables=n9 +# variables=n9,n950 # # The N9x mappings should be solved through sysinfo, but that's currently # broken on Mer/Nemo diff --git a/libssu/ssu.cpp b/libssu/ssu.cpp index bab45a2..f186b4b 100644 --- a/libssu/ssu.cpp +++ b/libssu/ssu.cpp @@ -89,7 +89,7 @@ int Ssu::deviceMode(){ QString Ssu::domain(){ SsuCoreConfig *settings = SsuCoreConfig::instance(); - return settings->domain(); + return settings->domain(true); } bool Ssu::isRegistered(){ diff --git a/libssu/ssu.h b/libssu/ssu.h index bf7e383..822c858 100644 --- a/libssu/ssu.h +++ b/libssu/ssu.h @@ -80,7 +80,7 @@ class Ssu: public QObject { Q_INVOKABLE QString flavour(); /// See SsuCoreConfig::deviceMode Q_INVOKABLE int deviceMode(); - /// See SsuCoreConfig::domain + /// See SsuCoreConfig::domain; returns printable version Q_INVOKABLE QString domain(); /// See SsuCoreConfig::isRegistered Q_INVOKABLE bool isRegistered(); diff --git a/libssu/ssucoreconfig.cpp b/libssu/ssucoreconfig.cpp index c4db20b..99eb879 100644 --- a/libssu/ssucoreconfig.cpp +++ b/libssu/ssucoreconfig.cpp @@ -57,9 +57,12 @@ int SsuCoreConfig::deviceMode(){ return value("deviceMode").toInt(); } -QString SsuCoreConfig::domain(){ +QString SsuCoreConfig::domain(bool pretty){ if (contains("domain")) - return value("domain").toString(); + if (pretty) + return value("domain").toString().replace(":", "-"); + else + return value("domain").toString(); else return ""; } @@ -117,7 +120,9 @@ void SsuCoreConfig::setRelease(QString release, bool rnd){ } void SsuCoreConfig::setDomain(QString domain){ - setValue("domain", domain); + // - in domain messes with default section autodetection, + // so change it to : + setValue("domain", domain.replace("-", ":")); sync(); } diff --git a/libssu/ssucoreconfig.h b/libssu/ssucoreconfig.h index 76a5fcd..c10fb2d 100644 --- a/libssu/ssucoreconfig.h +++ b/libssu/ssucoreconfig.h @@ -58,9 +58,11 @@ class SsuCoreConfig: public SsuSettings { Q_INVOKABLE int deviceMode(); /** * Get the current domain used in registration + * Internally - in the domain is replaced by :, if you need + * to print the domain name set pretty to true * @return domain, or "" if not set */ - Q_INVOKABLE QString domain(); + Q_INVOKABLE QString domain(bool pretty=false); /** * Return devices RND registration status * @retval true device is registered diff --git a/libssu/ssudeviceinfo.cpp b/libssu/ssudeviceinfo.cpp index 86a71b9..3af33b3 100644 --- a/libssu/ssudeviceinfo.cpp +++ b/libssu/ssudeviceinfo.cpp @@ -375,6 +375,9 @@ QVariant SsuDeviceInfo::variable(QString section, const QString &key){ } void SsuDeviceInfo::variableSection(QString section, QHash *storageHash){ + if (!section.startsWith("var-")) + section = "var-" + section; + SsuVariables::variableSection(boardMappings, section, storageHash); } diff --git a/libssu/ssurepomanager.cpp b/libssu/ssurepomanager.cpp index 524032f..c156bec 100644 --- a/libssu/ssurepomanager.cpp +++ b/libssu/ssurepomanager.cpp @@ -199,7 +199,7 @@ QStringList SsuRepoManager::repoVariables(QHash *storageHash, SsuSettings repoSettings(SSU_REPO_CONFIGURATION, QSettings::IniFormat); // fill in all arbitrary variables from ssu.ini - var.resolveSection(settings, "repository-url-variables", storageHash); + var.variableSection(settings, "repository-url-variables", storageHash); // add/overwrite some of the variables with sane ones if (rnd){ @@ -214,7 +214,7 @@ QStringList SsuRepoManager::repoVariables(QHash *storageHash, // Make it possible to give any values with the flavour as well. // These values can be overridden later with domain if needed. - var.resolveSection(&repoSettings, settings->flavour()+"-flavour", storageHash); + var.variableSection(&repoSettings, settings->flavour()+"-flavour", storageHash); } else { configSections << "release" << "all"; } @@ -260,17 +260,17 @@ QString SsuRepoManager::url(QString repoName, bool rndRepo, repoName = deviceInfo.adaptationVariables(repoName, &repoParameters); - // Domain variables - // first read all variables from default-domain - var.resolveSection(&repoSettings, "default-domain", &repoParameters); - - // then overwrite with domain specific things if that block is available, - // taking into account override parameters - if (parametersOverride.contains("domain")) - var.resolveSection(&repoSettings, - parametersOverride.value("domain")+"-domain", &repoParameters); - else - var.resolveSection(&repoSettings, settings->domain()+"-domain", &repoParameters); + + QString domain; + if (parametersOverride.contains("domain")){ + domain = parametersOverride.value("domain"); + domain.replace("-", ":"); + } else + domain = settings->domain(); + + // variableSection does autodetection for the domain default section + var.variableSection(&repoSettings, + domain + "-domain", &repoParameters); // override arbitrary variables, mostly useful for generating mic URLs QHash::const_iterator i = parametersOverride.constBegin(); diff --git a/libssu/ssuvariables.cpp b/libssu/ssuvariables.cpp index ba4adfe..8e94c09 100644 --- a/libssu/ssuvariables.cpp +++ b/libssu/ssuvariables.cpp @@ -10,6 +10,7 @@ #include #include "ssuvariables.h" +#include "ssulog.h" #include "../constants.h" @@ -17,19 +18,20 @@ SsuVariables::SsuVariables(): QObject() { } -void SsuVariables::resolveSection(QString section, QHash *storageHash){ - resolveSection(m_settings, section, storageHash); -} +QString SsuVariables::defaultSection(SsuSettings *settings, QString section){ + QStringList parts = section.split("-"); -void SsuVariables::resolveSection(SsuSettings *settings, QString section, QHash *storageHash){ - QStringList repoVariables; + if (section.startsWith("var-")) + parts.insert(1, "default"); + else + parts.replace(0, "default"); - settings->beginGroup(section); - repoVariables = settings->allKeys(); - foreach (const QString &key, repoVariables){ - storageHash->insert(key, settings->value(key).toString()); - } - settings->endGroup(); + QString key = parts.join("-"); + + if (settings->childGroups().contains(key)) + return key; + else + return ""; } QString SsuVariables::resolveString(QString pattern, QHash *variables, int recursionDepth){ @@ -167,22 +169,72 @@ void SsuVariables::variableSection(QString section, QHash *sto } void SsuVariables::variableSection(SsuSettings *settings, QString section, QHash *storageHash){ - if (!section.startsWith("var-")) - section = "var-" + section; + + QString dSection = defaultSection(settings, section); + if (dSection.isEmpty()) + readSection(settings, section, storageHash, 0); + else { + readSection(settings, dSection, storageHash, 0); + readSection(settings, section, storageHash, 0, false); + } +} + + +// resolve a configuration section, recursively following all 'variables' sections. +// variables which exist in more than one section will get overwritten when discovered +// again +// the section itself gets evaluated at the end, again having a chance to overwrite variables +void SsuVariables::readSection(SsuSettings *settings, QString section, + QHash *storageHash, int recursionDepth, + bool logOverride){ + if (recursionDepth >= SSU_MAX_RECURSION){ + SsuLog::instance()->print(LOG_WARNING, + QString("Maximum recursion depth for resolving section %1 from %2") + .arg(section) + .arg(settings->fileName())); + return; + } if (settings->contains(section + "/variables")){ + // child should log unless the parent is a default section + bool childLogOverride = true; + if (section.startsWith("default-") || section.startsWith("var-default-")) + childLogOverride = false; + QStringList sections = settings->value(section + "/variables").toStringList(); - foreach(const QString §ion, sections) - variableSection(settings, section, storageHash); - return; + foreach(const QString §ion, sections){ + if (section.startsWith("var-")) + readSection(settings, section, storageHash, recursionDepth + 1, childLogOverride); + else + readSection(settings, "var-" + section, storageHash, + recursionDepth + 1, childLogOverride); + } } settings->beginGroup(section); if (settings->group() != section) return; + QStringList locals; + if (settings->contains("local")) + locals = settings->value("local").toStringList(); + QStringList keys = settings->allKeys(); foreach (const QString &key, keys){ + // local variable + if (key.startsWith("_")) + continue; + + if (locals.contains(key)) + continue; + + if (storageHash->contains(key) && logOverride){ + SsuLog::instance()->print(LOG_DEBUG, + QString("Variable %1 overwritten from %2::%3") + .arg(key) + .arg(settings->fileName()) + .arg(section)); + } storageHash->insert(key, settings->value(key).toString()); } settings->endGroup(); diff --git a/libssu/ssuvariables.h b/libssu/ssuvariables.h index 547eca1..cfc3c95 100644 --- a/libssu/ssuvariables.h +++ b/libssu/ssuvariables.h @@ -19,12 +19,13 @@ class SsuVariables: public QObject { public: SsuVariables(); /** - * Look up all variables in the specified configuration file section, - * run them through the variable expander, and add them to the supplied - * QHash + * Return a default variable section, if exists, or an empty string. + * + * To identify the default section the section name gets split at '-', and + * the first token (or second token for "var-" sections) replaced with + * "default". You should therefore avoid "-" in section names. */ - void resolveSection(QString section, QHash *storageHash); - static void resolveSection(SsuSettings *settings, QString section, QHash *storageHash); + static QString defaultSection(SsuSettings *settings, QString section); /** * Resolve a whole string, containing several variables. Variables inside variables are allowed */ @@ -50,13 +51,23 @@ class SsuVariables: public QObject { QVariant variable(QString section, const QString &key); static QVariant variable(SsuSettings *settings, QString section, const QString &key); /** - * Return the requested variable section. 'var-' is automatically - * prepended to the section name if not specified already. + * Return the requested variable section, recursively looking up all variable + * sections referenced inside with the 'variable' keyword. 'var-' is automatically + * prepended to the section names of included variable sections, but not for + * the parent section. + * + * Variables starting with _ are treated as local variables and are ignored. + * The special key 'local' may contain a section-specific stringlist with + * additional keys which should be treated local. + * + * This function tries to identify a default configuration section, and merges + * the default section with the requested section. */ void variableSection(QString section, QHash *storageHash); static void variableSection(SsuSettings *settings, QString section, QHash *storageHash); private: + static void readSection(SsuSettings *settings, QString section, QHash *storageHash, int recursionDepth, bool logOverride=true); SsuSettings *m_settings; }; diff --git a/repos.ini b/repos.ini index 9118324..c0a6695 100644 --- a/repos.ini +++ b/repos.ini @@ -40,7 +40,12 @@ # # baseurl=plugin:ssu?repo=non-oss # baseurl=plugin:ssu?repo=non-oss&fooBar=baz - +# +# Domain sections are freeform sections for the configured ssu domain, +# to override default url values. The regular algorithm for finding +# default sections is used, "-" are therefore invalid chars in domain +# section names. If a domain contains "-" replace them with ":" in this +# configuration file, ssu will automatically convert them for domains. [all] credentials=jolla