Skip to content

Commit

Permalink
Better interpreted structure
Browse files Browse the repository at this point in the history
  • Loading branch information
sbrunner committed Nov 21, 2014
1 parent 6aa4d27 commit 237f3fe
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 58 deletions.
145 changes: 100 additions & 45 deletions c2c/template.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,11 @@
import traceback

import json
from yaml import load
import yaml
from yaml.parser import ParserError
from argparse import ArgumentParser
from z3c.recipe.filetemplate import Template
from subprocess import CalledProcessError
try:
from subprocess import check_output
except ImportError: # pragma: nocover
Expand Down Expand Up @@ -121,7 +123,7 @@ def save(template, processed):

def read_vars(vars_file):
file_open = open(vars_file, 'r')
used = load(file_open.read())
used = yaml.load(file_open.read())
file_open.close()

curent_vars = {}
Expand All @@ -130,52 +132,105 @@ def read_vars(vars_file):

new_vars = used['vars']

if 'interpreted-vars' in used:
if 'interpreted' in used:
interpreters = []
globs = {'__builtins__': __builtins__, 'os': os, 'sys': sys}
for key in used['interpreted-vars']:
try:
expression = new_vars[key]
except KeyError: # pragma: nocover
print("ERROR: Expression for key not found: %s" % key)
exit(1)

interpreter = 'python'
reader = None
if isinstance(expression, dict):
interpreter = expression.get('interpreter', 'python')
reader = expression.get('reader', None)
expression = expression.get('expression', None)

if interpreter == 'python':
for key, interpreter in used['interpreted'].items():
if isinstance(interpreter, dict):
interpreter["name"] = key
if 'priority' not in interpreter:
interpreter["priority"] = 0 if key in ['json', 'yaml'] else 100
else:
interpreter = {
"name": key,
"vars": interpreter,
"priority": 0 if key in ['json', 'yaml'] else 100
}
interpreters.append(interpreter)

interpreters.sort(key=lambda v: -v["priority"])

for interpreter in interpreters:
for var_name in interpreter["vars"]:
try:
evaluated = eval(expression, globs)
except: # pragma: nocover
print("ERROR when evaluating %r expression %r:\n%s" % (
key, expression, traceback.format_exc()
))
expression = new_vars[var_name]
except KeyError: # pragma: nocover
print("ERROR: Expression for key not found: %s" % key)
exit(1)
elif interpreter == 'bash':
evaluated = check_output(expression, shell=True)
elif interpreter == 'environment': # pragma: nocover
if expression is None:
evaluated = os.environ
else:
evaluated = os.environ[expression]
else: # pragma: nocover
print("Unknown interpreter '{}'.".format(interpreter))
exit(1)

if reader is None:
pass
elif reader == 'json':
evaluated = json.loads(evaluated)
elif reader == 'yaml':
evaluated = load(evaluated)
else: # pragma: nocover
print("Unknown reader '{}'.".format(reader))
exit(1)

new_vars[key] = evaluated

if "cmd" in interpreter:
cmd = interpreter["cmd"][:] # [:] to clone
cmd.append(expression)
try:
evaluated = check_output(cmd)
except OSError as e: # pragma: nocover
print("ERROR when running the expression '%r': %s" % (
expression, e
))
exit(1)
except CalledProcessError as e: # pragma: nocover
print("ERROR when running the expression '%r': %s" % (
expression, e
))
exit(1)

elif interpreter["name"] == "python":
try:
evaluated = eval(expression, globs)
except: # pragma: nocover
print("ERROR when evaluating %r expression %r as Python:\n%s" % (
key, expression, traceback.format_exc()
))
exit(1)
elif interpreter["name"] == 'bash':
try:
evaluated = check_output(expression, shell=True)
except OSError as e: # pragma: nocover
print("ERROR when running the expression '%r': %s" % (
expression, e
))
exit(1)
except CalledProcessError as e: # pragma: nocover
print("ERROR when running the expression '%r': %s" % (
expression, e
))
exit(1)

elif interpreter["name"] == 'environment': # pragma: nocover
if expression is None:
evaluated = os.environ
else:
try:
evaluated = os.environ[expression]
except KeyError:
print(
"ERROR when getting %r in environment variables, "
"possible values are: %r" % (
expression, os.environ.keys()
)
)
exit(1)
elif interpreter["name"] == 'json':
try:
evaluated = json.loads(expression)
except ValueError as e: # pragma: nocover
print("ERROR when evaluating %r expression %r as JSON: %s" % (
key, expression, e
))
exit(1)
elif interpreter["name"] == 'yaml':
try:
evaluated = yaml.load(expression)
except ParserError as e: # pragma: nocover
print("ERROR when evaluating %r expression %r as YAML: %s" % (
key, expression, e
))
exit(1)
else: # pragma: nocover
print("Unknown interpreter name '{}'.".format(interpreter["name"]))
exit(1)

new_vars[var_name] = evaluated

curent_vars.update(new_vars)
return curent_vars
1 change: 1 addition & 0 deletions c2c/tests/jinja.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ var3: {{ var3 }}
var_interpreted: {{ var_interpreted }}
JSON kernel: {{ facter_json.kernel }}
YAML kernel: {{ facter_yaml.kernel }}
pi: {{ pi }}
3 changes: 2 additions & 1 deletion c2c/tests/test_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ def test_jinja(self):
'var3: first, second, third\n'
'var_interpreted: 4\n'
'JSON kernel: Linux\n'
'YAML kernel: Linux'
'YAML kernel: Linux\n'
'pi: 3.14\n'
)

def test_mako(self):
Expand Down
28 changes: 16 additions & 12 deletions c2c/tests/vars.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,20 @@ extends: c2c/tests/inherit.yaml
vars:
var1: first
var_interpreted: 2+2
facter_json:
expression: /usr/bin/facter --json
reader: json
interpreter: bash
facter_yaml:
expression: /usr/bin/facter --yaml
reader: yaml
interpreter: bash
facter_json: /usr/bin/facter --json
facter_yaml: /usr/bin/facter --yaml
pi: console.log(Math.PI.toPrecision(3))

interpreted-vars:
- var_interpreted
- facter_json
- facter_yaml
interpreted:
python:
- var_interpreted
bash:
- facter_json
- facter_yaml
json:
- facter_json
yaml:
- facter_yaml
node:
vars: ["pi"]
cmd: ["node", "-e"]

0 comments on commit 237f3fe

Please sign in to comment.