Commit 4f7e4a76 authored by Aard's avatar Aard

[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
- multiple variable sections are now supported, as well as adding both
  the variables keyword and variable values in a section
parent 0477be35
......@@ -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
......@@ -89,7 +89,7 @@ int Ssu::deviceMode(){
QString Ssu::domain(){
SsuCoreConfig *settings = SsuCoreConfig::instance();
return settings->domain();
return settings->domain(true);
bool Ssu::isRegistered(){
......@@ -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();
......@@ -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(":", "-");
return value("domain").toString();
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("-", ":"));
......@@ -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
......@@ -375,6 +375,9 @@ QVariant SsuDeviceInfo::variable(QString section, const QString &key){
void SsuDeviceInfo::variableSection(QString section, QHash<QString, QString> *storageHash){
if (!section.startsWith("var-"))
section = "var-" + section;
SsuVariables::variableSection(boardMappings, section, storageHash);
......@@ -199,7 +199,7 @@ QStringList SsuRepoManager::repoVariables(QHash<QString, QString> *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<QString, QString> *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"))
parametersOverride.value("domain")+"-domain", &repoParameters);
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
domain + "-domain", &repoParameters);
// override arbitrary variables, mostly useful for generating mic URLs
QHash<QString, QString>::const_iterator i = parametersOverride.constBegin();
......@@ -10,6 +10,7 @@
#include <QStringRef>
#include "ssuvariables.h"
#include "ssulog.h"
#include "../constants.h"
......@@ -17,19 +18,20 @@ SsuVariables::SsuVariables(): QObject() {
void SsuVariables::resolveSection(QString section, QHash<QString, QString> *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<QString, QString> *storageHash){
QStringList repoVariables;
if (section.startsWith("var-"))
parts.insert(1, "default");
parts.replace(0, "default");
repoVariables = settings->allKeys();
foreach (const QString &key, repoVariables){
storageHash->insert(key, settings->value(key).toString());
QString key = parts.join("-");
if (settings->childGroups().contains(key))
return key;
return "";
QString SsuVariables::resolveString(QString pattern, QHash<QString, QString> *variables, int recursionDepth){
......@@ -167,22 +169,72 @@ void SsuVariables::variableSection(QString section, QHash<QString, QString> *sto
void SsuVariables::variableSection(SsuSettings *settings, QString section, QHash<QString, QString> *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<QString, QString> *storageHash, int recursionDepth,
bool logOverride){
if (recursionDepth >= SSU_MAX_RECURSION){
QString("Maximum recursion depth for resolving section %1 from %2")
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 &section, sections)
variableSection(settings, section, storageHash);
foreach(const QString &section, sections){
if (section.startsWith("var-"))
readSection(settings, section, storageHash, recursionDepth + 1, childLogOverride);
readSection(settings, "var-" + section, storageHash,
recursionDepth + 1, childLogOverride);
if (settings->group() != section)
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("_"))
if (locals.contains(key))
if (storageHash->contains(key) && logOverride){
QString("Variable %1 overwritten from %2::%3")
storageHash->insert(key, settings->value(key).toString());
......@@ -19,12 +19,13 @@ class SsuVariables: public QObject {
* 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<QString, QString> *storageHash);
static void resolveSection(SsuSettings *settings, QString section, QHash<QString, QString> *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<QString, QString> *storageHash);
static void variableSection(SsuSettings *settings, QString section, QHash<QString, QString> *storageHash);
static void readSection(SsuSettings *settings, QString section, QHash<QString, QString> *storageHash, int recursionDepth, bool logOverride=true);
SsuSettings *m_settings;
......@@ -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.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment