diff --git a/README.md b/README.md
index 13579e6..9a4a88d 100644
--- a/README.md
+++ b/README.md
@@ -17,7 +17,7 @@ Usage: jinja2 [options]
Options:
--version show program's version number and exit
-h, --help show this help message and exit
- --format=FORMAT format of input variables: auto, ini, json,
+ --format=FORMAT format of input variables: auto, env, ini, json,
querystring, yaml, yml
-e EXTENSIONS, --extension=EXTENSIONS
extra jinja2 extensions to load
@@ -26,8 +26,16 @@ Options:
Use only this section from the configuration
--strict Disallow undefined variables to be used within the
template
+ -a, --ansible Enable support for Ansible filters
+ -o FILE, --outfile=FILE
+ File to use for output. Default is stdout.
```
+## Optional Ansible support
+If `Ansible Core` is present, you can use Ansible filters within your templates.
+
+`$ pip install jinja2-cli[ansible]`
+
## Optional YAML support
If `PyYAML` is present, you can use YAML as an input data source.
diff --git a/jinja2cli/cli.py b/jinja2cli/cli.py
index fa57ad9..d161c46 100644
--- a/jinja2cli/cli.py
+++ b/jinja2cli/cli.py
@@ -220,7 +220,55 @@ def _parse_env(data):
}
-def render(template_path, data, extensions, strict=False):
+def _ansible_filter_loader(base_module, module_path=None):
+ from pkgutil import iter_modules
+ from jinja2.utils import import_string
+
+ if module_path is not None:
+ try:
+ parent_module = import_string(f"{base_module.__name__}.{module_path}.plugins.filter")
+ except ImportError:
+ print(f"Could not find collection '{module_path}', did you mean 'ansible.{module_path}'?")
+ raise
+ else:
+ parent_module = import_string(f"{base_module.__name__}.plugins.filter")
+
+ for module in iter_modules(parent_module.__path__):
+ filter_module = import_string(f"{parent_module.__name__}.{module.name}")
+ yield filter_module.FilterModule().filters()
+
+
+def _load_ansible_filters(collections=None):
+ try:
+ import ansible
+ except ImportError:
+ print("This feature requires the `ansible-core` package.")
+ raise
+
+ filters = dict()
+ for filter in _ansible_filter_loader(ansible):
+ filters.update(filter)
+
+ if collections is None:
+ return filters
+
+ collections_paths = os.environ.get("ANSIBLE_COLLECTIONS") or \
+ f"{os.path.expanduser('~/.ansible/collections')}:/usr/share/ansible/collections"
+ sys.path.extend(collections_paths.split(':'))
+ try:
+ import ansible_collections
+ except ImportError:
+ print("Could not find the `ansible_collections` module, please check the ANSIBLE_COLLECTIONS environment variable.")
+ raise
+
+ for collection in collections:
+ for filter in _ansible_filter_loader(ansible_collections, collection):
+ filters.update(filter)
+
+ return filters
+
+
+def render(template_path, data, extensions, strict=False, ansible=None):
from jinja2 import (
__version__ as jinja_version,
Environment,
@@ -246,6 +294,10 @@ def render(template_path, data, extensions, strict=False):
)
if strict:
env.undefined = StrictUndefined
+ if ansible:
+ collections = set(ansible)
+ collections.discard('core') # only used because optparse doesn't support 0+ values
+ env.filters.update(_load_ansible_filters(collections))
# Add environ global
env.globals["environ"] = lambda key: force_text(os.environ.get(key))
@@ -336,7 +388,7 @@ def cli(opts, args):
out = codecs.getwriter("utf8")(out)
- out.write(render(template_path, data, extensions, opts.strict))
+ out.write(render(template_path, data, extensions, opts.strict, opts.ansible))
out.flush()
return 0
@@ -422,6 +474,14 @@ def main():
dest="strict",
action="store_true",
)
+ parser.add_option(
+ "-a",
+ "--ansible",
+ help="Enable support for Ansible filters (--ansible core or --ansible )",
+ dest="ansible",
+ action="append",
+ default=[],
+ )
parser.add_option(
"-o",
"--outfile",
diff --git a/setup.py b/setup.py
index ccade5d..c4bd972 100755
--- a/setup.py
+++ b/setup.py
@@ -29,6 +29,7 @@
license="BSD",
install_requires=install_requires,
extras_require={
+ "ansible": install_requires + ["ansible-core"],
"yaml": install_requires + ["pyyaml"],
"toml": install_requires + ["toml"],
"xml": install_requires + ["xmltodict"],