Skip to content

Commit

Permalink
[variables] Add default sections, local variables, full recursive res…
Browse files Browse the repository at this point in the history
…olving

- 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
  • Loading branch information
Bernd Wachter committed Jul 5, 2013
1 parent 0477be3 commit 4f7e4a7
Show file tree
Hide file tree
Showing 10 changed files with 143 additions and 47 deletions.
26 changes: 22 additions & 4 deletions board-mappings.ini
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion libssu/ssu.cpp
Expand Up @@ -89,7 +89,7 @@ int Ssu::deviceMode(){

QString Ssu::domain(){
SsuCoreConfig *settings = SsuCoreConfig::instance();
return settings->domain();
return settings->domain(true);
}

bool Ssu::isRegistered(){
Expand Down
2 changes: 1 addition & 1 deletion libssu/ssu.h
Expand Up @@ -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();
Expand Down
11 changes: 8 additions & 3 deletions libssu/ssucoreconfig.cpp
Expand Up @@ -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 "";
}
Expand Down Expand Up @@ -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();
}

Expand Down
4 changes: 3 additions & 1 deletion libssu/ssucoreconfig.h
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions libssu/ssudeviceinfo.cpp
Expand Up @@ -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);
}

Expand Down
26 changes: 13 additions & 13 deletions libssu/ssurepomanager.cpp
Expand Up @@ -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){
Expand All @@ -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";
}
Expand Down Expand Up @@ -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<QString, QString>::const_iterator i = parametersOverride.constBegin();
Expand Down
84 changes: 68 additions & 16 deletions libssu/ssuvariables.cpp
Expand Up @@ -10,26 +10,28 @@
#include <QStringRef>

#include "ssuvariables.h"
#include "ssulog.h"

#include "../constants.h"

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");
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<QString, QString> *variables, int recursionDepth){
Expand Down Expand Up @@ -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){
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 &section, sections)
variableSection(settings, section, storageHash);
return;
foreach(const QString &section, 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();
Expand Down
25 changes: 18 additions & 7 deletions libssu/ssuvariables.h
Expand Up @@ -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<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
*/
Expand All @@ -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);

private:
static void readSection(SsuSettings *settings, QString section, QHash<QString, QString> *storageHash, int recursionDepth, bool logOverride=true);
SsuSettings *m_settings;
};

Expand Down
7 changes: 6 additions & 1 deletion repos.ini
Expand Up @@ -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
Expand Down

0 comments on commit 4f7e4a7

Please sign in to comment.