/
index.py
96 lines (83 loc) · 2.62 KB
/
index.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
"""
Index class.
"""
import os
import yaml
from jinja2 import (
Environment,
PrefixLoader,
FileSystemLoader,
)
from voluptuous import (
Required,
Schema,
)
from .scope import Scope
from .target import Target
class Index(object):
"""
An index is a collection of targets.
"""
@classmethod
def load(cls, cwd, stream):
"""
Load an index from a stream.
:param cwd: The current directory. Used to resolve relative template
paths.
:param stream: A file-object to use as the source for the index.
:returns: An `Index` instance.
"""
data = yaml.load(stream)
schema = Schema({
Required('template_paths', default={}): {str: str},
Required('targets', default={}): {
str: {
'template_name': str,
'filename': str,
Required('scopes', default={}): {
str: Scope.from_string
},
},
},
})
parsed_data = schema(data)
template_paths = parsed_data['template_paths']
if template_paths:
loader = PrefixLoader({
prefix: FileSystemLoader(os.path.join(cwd, path))
for prefix, path in template_paths.items()
})
else:
loader = FileSystemLoader(cwd)
environment = Environment(
loader=loader,
keep_trailing_newline=True,
)
targets = {
target_name: Target(**target)
for target_name, target in parsed_data['targets'].items()
}
return cls(environment=environment, targets=targets)
def __init__(self, environment, targets):
"""
Initialize a new index.
:param environment: The Jinja2 template environment.
:param targets: A dictionary of targets indexed by their names.
"""
self.environment = environment
self.targets = targets
def generate(self, context):
"""
Generator that yields all the rendered pairs for the targets, using the
specified context.
:param context: The root context to use.
:yields: Triplets of (target_name, filename, content) for the targets.
.. note::
Targets are picked in alphabetical order.
"""
for target_name, target in sorted(self.targets.items()):
for filename, content in target.generate(
environment=self.environment,
context=context,
):
yield target_name, filename, content