feat: add util.mako_renderer() function

This commit is contained in:
Lance Edgar 2024-11-20 10:29:31 -06:00
parent 4879887cb3
commit c41d364e03
6 changed files with 63 additions and 2 deletions

View file

@ -52,12 +52,15 @@ merely a personal convention. You can define tasks however you need::
"""
from fabric import task
from wuttamess import apt, sync
from wuttamess import apt, sync, util
# nb. this is used below, for file sync
root = sync.make_root('files')
# nb. this is for global mako template context etc.
env = {'machine_is_live': False}
@task
def bootstrap_all(c):
@ -74,11 +77,13 @@ merely a personal convention. You can define tasks however you need::
"""
Bootstrap the base system
"""
renderers = {'mako': util.mako_renderer(c, env)}
apt.dist_upgrade(c)
# postfix
apt.install(c, 'postfix')
if sync.check_isync(c, root, 'etc/postfix'):
if sync.check_isync(c, root, 'etc/postfix', renderers=renderers):
c.run('systemctl restart postfix')

View file

@ -31,6 +31,8 @@ requires-python = ">= 3.8"
dependencies = [
"fabric",
"fabsync",
"mako",
"typing_extensions",
]

View file

@ -24,9 +24,46 @@
Misc. Utilities
"""
from pathlib import Path
from typing_extensions import Any, Mapping
from mako.template import Template
def exists(c, path):
"""
Returns ``True`` if given path exists on the host, otherwise ``False``.
"""
return not c.run(f'test -e {path}', warn=True).failed
def mako_renderer(c, env={}):
"""
This returns a *function* suitable for use as a ``fabsync`` file
renderer. The function assumes the file is a Mako template.
:param c: Fabric connection.
:param env: Environment dictionary to be used as Mako template
context.
Typical usage is something like::
from fabric import task
from wuttamess import sync, util
root = sync.make_root('files')
env = {}
@task
def foo(c):
# define possible renderers for fabsync
renderers = {'mako': util.mako_renderer(c, env)}
sync.check_isync(c, root, 'etc/postfix', renderers=renderers)
"""
def render(path: Path, vars: Mapping[str, Any], **kwargs) -> bytes:
return Template(filename=str(path)).render(**env)
return render

View file

@ -0,0 +1,4 @@
[files."baz"]
renderer = 'mako'
tags = ['baz']

1
tests/files/bar/baz Normal file
View file

@ -0,0 +1 @@
machine_is_live = ${machine_is_live}

View file

@ -1,5 +1,6 @@
# -*- coding: utf-8; -*-
import os
from unittest import TestCase
from unittest.mock import MagicMock
@ -12,3 +13,14 @@ class TestExists(TestCase):
c = MagicMock()
mod.exists(c, '/foo')
c.run.assert_called_once_with('test -e /foo', warn=True)
class TestMakoRenderer(TestCase):
def test_basic(self):
c = MagicMock()
renderer = mod.mako_renderer(c, env={'machine_is_live': True})
here = os.path.dirname(__file__)
path = os.path.join(here, 'files', 'bar', 'baz')
rendered = renderer(path, vars={})
self.assertEqual(rendered, 'machine_is_live = True')