127 lines
3.3 KiB
Python
127 lines
3.3 KiB
Python
import os, sys
|
|
import argparse
|
|
|
|
import jinja2
|
|
import jinja2.loaders
|
|
from . import __version__
|
|
|
|
from .context import read_context_data, FORMATS
|
|
from .extras import filters
|
|
|
|
|
|
class FilePathLoader(jinja2.BaseLoader):
|
|
""" Custom Jinja2 template loader which just loads a single template file """
|
|
|
|
def __init__(self, cwd, encoding='utf-8'):
|
|
self.cwd = cwd
|
|
self.encoding = encoding
|
|
|
|
def get_source(self, environment, template):
|
|
# Path
|
|
filename = os.path.join(self.cwd, template)
|
|
|
|
# Read
|
|
try:
|
|
with open(template, 'r') as f:
|
|
contents = f.read().decode(self.encoding)
|
|
except IOError:
|
|
raise jinja2.TemplateNotFound(template)
|
|
|
|
# Finish
|
|
uptodate = lambda: False
|
|
return contents, filename, uptodate
|
|
|
|
|
|
def render_template(cwd, template_path, context):
|
|
""" Render a template
|
|
:param template_path: Path to the template file
|
|
:type template_path: basestring
|
|
:param context: Template data
|
|
:type context: dict
|
|
:return: Rendered template
|
|
:rtype: basestring
|
|
"""
|
|
env = jinja2.Environment(
|
|
loader=FilePathLoader(cwd),
|
|
undefined=jinja2.StrictUndefined # raises errors for undefined variables
|
|
)
|
|
|
|
# Register extras
|
|
env.filters['docker_link'] = filters.docker_link
|
|
|
|
return env \
|
|
.get_template(template_path) \
|
|
.render(context) \
|
|
.encode('utf-8')
|
|
|
|
|
|
def render_command(cwd, environ, stdin, argv):
|
|
""" Pure render command
|
|
:param cwd: Current working directory (to search for the files)
|
|
:type cwd: basestring
|
|
:param environ: Environment variables
|
|
:type environ: dict
|
|
:param stdin: Stdin stream
|
|
:type stdin: file
|
|
:param argv: Command-line arguments
|
|
:type argv: list
|
|
:return: Rendered template
|
|
:rtype: basestring
|
|
"""
|
|
parser = argparse.ArgumentParser(
|
|
prog='j2',
|
|
description='Command-line interface to Jinja2 for templating in shell scripts.',
|
|
epilog=''
|
|
)
|
|
parser.add_argument('-v', '--version', action='version',
|
|
version='j2cli {}, Jinja2 {}'.format(__version__, jinja2.__version__))
|
|
|
|
parser.add_argument('-f', '--format', default='?', help='Input data format', choices=['?'] + list(FORMATS.keys()))
|
|
parser.add_argument('template', help='Template file to process')
|
|
parser.add_argument('data', nargs='?', default='-', help='Input data path')
|
|
args = parser.parse_args(argv)
|
|
|
|
# Input: guess format
|
|
if args.format == '?':
|
|
if args.data == '-':
|
|
args.format = 'env'
|
|
else:
|
|
args.format = {
|
|
'.ini': 'ini',
|
|
'.json': 'json',
|
|
'.yml': 'yaml',
|
|
'.yaml': 'yaml',
|
|
'.env': 'env'
|
|
}[os.path.splitext(args.data)[1]]
|
|
|
|
# Input: data
|
|
if args.data == '-' and args.format == 'env':
|
|
input_data_f = None
|
|
else:
|
|
input_data_f = stdin if args.data == '-' else open(args.data)
|
|
|
|
# Read data
|
|
context = read_context_data(
|
|
args.format,
|
|
input_data_f,
|
|
environ
|
|
)
|
|
|
|
# Render
|
|
return render_template(
|
|
cwd,
|
|
args.template,
|
|
context
|
|
)
|
|
|
|
|
|
def main():
|
|
""" CLI Entry point """
|
|
output = render_command(
|
|
os.getcwd(),
|
|
os.environ,
|
|
sys.stdin,
|
|
sys.argv[1:]
|
|
)
|
|
sys.stdout.write(output)
|