From 699b42a756b0d0c33b7ac8f357db5262164ee999 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 19 Feb 2018 06:18:08 -0500 Subject: [PATCH] [contextualprocess] Add wildcard - Re-build the structures for doing value-checks, is now more tree-like. - Document pointer ownership. - Introduce wildcard matches ("*") - Don't drop empty command-lists, since they can be used to avoid wildcard matches. (E.g. "in this case, do nothing, but don't fall through to wildcard"). --- .../ContextualProcessJob.cpp | 72 ++++++++++++++----- .../contextualprocess/contextualprocess.conf | 9 ++- 2 files changed, 62 insertions(+), 19 deletions(-) diff --git a/src/modules/contextualprocess/ContextualProcessJob.cpp b/src/modules/contextualprocess/ContextualProcessJob.cpp index f03d53466..71bbd31de 100644 --- a/src/modules/contextualprocess/ContextualProcessJob.cpp +++ b/src/modules/contextualprocess/ContextualProcessJob.cpp @@ -30,31 +30,71 @@ #include "utils/CommandList.h" #include "utils/Logger.h" +/** + * Passing a CommandList to ValueCheck gives ownership of the CommandList to + * the ValueCheck, which will delete the CommandList when needed. + */ +struct ValueCheck : public QPair +{ + ValueCheck( const QString& value, CalamaresUtils::CommandList* commands ) + : QPair(value, commands) + { + } + + ~ValueCheck() + { + delete second; + } + + QString value() const { return first; } + CalamaresUtils::CommandList* commands() const { return second; } +} ; + struct ContextualProcessBinding { - ContextualProcessBinding( const QString& _n, const QString& _v, CalamaresUtils::CommandList* _c ) - : variable( _n ) - , value( _v ) - , commands( _c ) + ContextualProcessBinding( const QString& varname ) + : variable( varname ) { } ~ContextualProcessBinding(); - int count() const + /** + * @brief add commands to be executed when @p value is matched. + * + * Ownership of the CommandList passes to the ValueCheck held + * by this binding. + */ + void append( const QString& value, CalamaresUtils::CommandList* commands ) { - return commands ? commands->count() : 0; + checks.append( ValueCheck( value, commands ) ); + if ( value == '*' ) + wildcard = commands; + } + + Calamares::JobResult run( const QString& value ) const + { + for ( const auto& c : checks ) + { + if ( value == c.value() ) + return c.commands()->run(); + } + + if ( wildcard ) + return wildcard->run(); + + return Calamares::JobResult::ok(); } QString variable; - QString value; - CalamaresUtils::CommandList* commands; + QList checks; + CalamaresUtils::CommandList* wildcard{ nullptr }; } ; ContextualProcessBinding::~ContextualProcessBinding() { - delete commands; + wildcard = nullptr; } ContextualProcessJob::ContextualProcessJob( QObject* parent ) @@ -83,9 +123,9 @@ ContextualProcessJob::exec() for ( const ContextualProcessBinding* binding : m_commands ) { - if ( gs->contains( binding->variable ) && ( gs->value( binding->variable ).toString() == binding->value ) ) + if ( gs->contains( binding->variable ) ) { - Calamares::JobResult r = binding->commands->run(); + Calamares::JobResult r = binding->run( gs->value( binding->variable ).toString() ); if ( !r ) return r; } @@ -114,6 +154,8 @@ ContextualProcessJob::setConfigurationMap( const QVariantMap& configurationMap ) continue; } + auto binding = new ContextualProcessBinding( variableName ); + m_commands.append( binding ); QVariantMap values = iter.value().toMap(); for ( QVariantMap::const_iterator valueiter = values.cbegin(); valueiter != values.cend(); ++valueiter ) { @@ -126,13 +168,7 @@ ContextualProcessJob::setConfigurationMap( const QVariantMap& configurationMap ) CalamaresUtils::CommandList* commands = new CalamaresUtils::CommandList( valueiter.value(), !dontChroot, timeout ); - if ( commands->count() > 0 ) - { - m_commands.append( new ContextualProcessBinding( variableName, valueString, commands ) ); - cDebug() << variableName << '=' << valueString << "will execute" << commands->count() << "commands"; - } - else - delete commands; + binding->append( valueString, commands ); } } } diff --git a/src/modules/contextualprocess/contextualprocess.conf b/src/modules/contextualprocess/contextualprocess.conf index 20668e1ce..1f148328c 100644 --- a/src/modules/contextualprocess/contextualprocess.conf +++ b/src/modules/contextualprocess/contextualprocess.conf @@ -15,12 +15,18 @@ # # You can check for an empty value with "". # +# As a special case, the value-check "*" matches any value, but **only** +# if no other value-check matches. Use it as an *else* form for value- +# checks. Take care to put the asterisk in quotes. +# # Global configuration variables are not checked in a deterministic # order, so do not rely on commands from one variable-check to # always happen before (or after) checks on another # variable. Similarly, the value-equality checks are not # done in a deterministic order, but all of the value-checks -# for a given variable happen together. +# for a given variable happen together. As a special case, the +# value-check for "*" (the *else* case) happens after all of the +# other value-checks, and only matches if none of the others do. # # The values after a value sub-keys are the same kinds of values # as can be given to the *script* key in the shellprocess module. @@ -34,3 +40,4 @@ firmwareType: timeout: 120 # This is slow bios: "-pkg remove bios-firmware" "": "/bin/false no-firmware-type-set" + "*": "/bin/false some-other-firmware-value"