Skip to content

Commit

Permalink
Merge pull request #2189 from oliver-sanders/2148.assert-jinja2-filter
Browse files Browse the repository at this point in the history
Added raise and assert Jinja2 functions.
  • Loading branch information
hjoliver authored Mar 5, 2017
2 parents eea93d3 + ea8f07b commit 6cf7987
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 0 deletions.
31 changes: 31 additions & 0 deletions doc/cug.tex
Original file line number Diff line number Diff line change
Expand Up @@ -5237,6 +5237,37 @@ \subsubsection{Jinja2 Variable Scope}
# FOO is {{FOO}}
\end{lstlisting}
\subsubsection{Raising Exceptions}
Cylc provides two functions for raising exceptions using Jinja2. These
exceptions are raised when the suite.rc file is loaded and will prevent a suite
from running.
Note: These functions must be contained within \lstinline={{= Jinja2
blocks as opposed to \lstinline={%= blocks.
\paragraph{Raise}
The ``raise'' function will result in an error containing the provided text.
\lstset{language=suiterc}
\begin{lstlisting}
{% if not VARIABLE is defined %}
{{ raise('VARIABLE must be defined for this suite.') }}
{% endif %}
\end{lstlisting}
\paragraph{Assert}
The ``assert'' function will raise an exception containing the text provided in
the second argument providing that the first argument evaluates as False. The
following example is equivalent to the ``raise'' example above.
\lstset{language=suiterc}
\begin{lstlisting}
{{ assert(VARIABLE is defined, 'VARIABLE must be defined for this suite.') }}
\end{lstlisting}
\subsection{Omitting Tasks At Runtime}
It is sometimes convenient to omit certain tasks from the suite at
Expand Down
13 changes: 13 additions & 0 deletions lib/parsec/jinja2support.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,17 @@
import cylc.flags


def raise_helper(message, error_type='Error'):
"""Provides a Jinja2 function for raising exceptions."""
raise Exception('Jinja2 %s: %s' % (error_type, message))


def assert_helper(logical, message):
"""Provides a Jinja2 function for asserting logical expressions."""
if not logical:
raise_helper(message, 'Assertation Error')


def jinja2process(flines, dir_, template_vars=None):
"""Pass configure file through Jinja2 processor."""
env = Environment(
Expand Down Expand Up @@ -60,6 +71,8 @@ def jinja2process(flines, dir_, template_vars=None):
# Import SUITE HOST USER ENVIRONMENT into template:
# (usage e.g.: {{environ['HOME']}}).
env.globals['environ'] = os.environ
env.globals['raise'] = raise_helper
env.globals['assert'] = assert_helper

# load file lines into a template, excluding '#!jinja2' so
# that '#!cylc-x.y.z' rises to the top.
Expand Down
39 changes: 39 additions & 0 deletions tests/jinja2/10-builtin-functions.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/bin/bash
# THIS FILE IS PART OF THE CYLC SUITE ENGINE.
# Copyright (C) 2008-2017 NIWA
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#-------------------------------------------------------------------------------
# jinja2 test cylc-provided functions.
. $(dirname $0)/test_header
#-------------------------------------------------------------------------------
set_test_number 4
#-------------------------------------------------------------------------------
install_suite "${TEST_NAME_BASE}" "${TEST_NAME_BASE}"
#-------------------------------------------------------------------------------
# raise(message, error_type='Error')
TEST_NAME="${TEST_NAME_BASE}-raise-validate"
run_fail "${TEST_NAME}" cylc validate "${SUITE_NAME}"
cmp_ok "${TEST_NAME}.stderr" << '__ERR__'
Jinja2 Error: Some Exception
__ERR__
#-------------------------------------------------------------------------------
# assert(logical, message)
TEST_NAME="${TEST_NAME_BASE}-assert-validate"
run_fail "${TEST_NAME}" cylc validate "${SUITE_NAME}" -s 'ANSWER=43'
cmp_ok "${TEST_NAME}.stderr" << '__ERR__'
Jinja2 Assertation Error: Reality check needed
__ERR__
#-------------------------------------------------------------------------------
purge_suite "${SUITE_NAME}"
9 changes: 9 additions & 0 deletions tests/jinja2/10-builtin-functions/suite.rc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!Jinja2

{% if not ANSWER is defined %}
{% set ANSWER = 42 %}
{% endif %}

{{ assert(ANSWER == 42, 'Reality check needed') }}

{{ raise('Some Exception') }}

0 comments on commit 6cf7987

Please sign in to comment.