|
|
|
#!/usr/bin/env python
|
|
|
|
"""
|
|
|
|
Builds the Matrix Specification as restructed text (RST).
|
|
|
|
|
|
|
|
Architecture
|
|
|
|
============
|
|
|
|
+-------+ +----------+
|
|
|
|
| units |-+ | sections |-+
|
|
|
|
+-------+ |-+ === used to create ==> +----------- | === used to create ==> SPEC
|
|
|
|
+-------+ | +----------+
|
|
|
|
+--------+
|
|
|
|
RAW DATA (e.g. json) Blobs of RST
|
|
|
|
|
|
|
|
Units
|
|
|
|
=====
|
|
|
|
Units are random bits of unprocessed data, e.g. schema JSON files. Anything can
|
|
|
|
be done to them, from processing it with Jinja to arbitrary python processing.
|
|
|
|
They are dicts.
|
|
|
|
|
|
|
|
Sections
|
|
|
|
========
|
|
|
|
Sections are short segments of RST. They will be in the final spec, but they
|
|
|
|
are unordered. They typically use a combination of templates + units to
|
|
|
|
construct bits of RST.
|
|
|
|
|
|
|
|
Skeleton
|
|
|
|
========
|
|
|
|
The skeleton is a single RST file which is passed through a templating system to
|
|
|
|
replace variable names with sections.
|
|
|
|
|
|
|
|
Processing
|
|
|
|
==========
|
|
|
|
- Execute all unit functions to load units into memory and process them.
|
|
|
|
- Execute all section functions (which can now be done because the units exist)
|
|
|
|
- Execute the skeleton function to bring it into a single file.
|
|
|
|
|
|
|
|
Checks
|
|
|
|
======
|
|
|
|
- Any units made which were not used at least once will produce a warning.
|
|
|
|
- Any sections made but not used in the skeleton will produce a warning.
|
|
|
|
"""
|
|
|
|
|
|
|
|
from jinja2 import Environment, FileSystemLoader
|
|
|
|
import internal.units
|
|
|
|
import internal.sections
|
|
|
|
import json
|
|
|
|
|
|
|
|
def load_units():
|
|
|
|
print "Loading units..."
|
|
|
|
return internal.units.load()
|
|
|
|
|
|
|
|
def load_sections(env, units):
|
|
|
|
print "Loading sections..."
|
|
|
|
return internal.sections.load(env, units)
|
|
|
|
|
|
|
|
def create_from_skeleton(skeleton, sections):
|
|
|
|
print "Creating spec from skeleton..."
|
|
|
|
|
|
|
|
def check_unaccessed(name, store):
|
|
|
|
unaccessed_keys = store.get_unaccessed_set()
|
|
|
|
if len(unaccessed_keys) > 0:
|
|
|
|
print "Found %s unused %s keys." % (len(unaccessed_keys), name)
|
|
|
|
print unaccessed_keys
|
|
|
|
|
|
|
|
def main():
|
|
|
|
# add a template filter to produce pretty pretty JSON
|
|
|
|
def jsonify(input):
|
|
|
|
return json.dumps(input, indent=4)
|
|
|
|
|
|
|
|
# make Jinja aware of the templates and filters
|
|
|
|
env = Environment(loader=FileSystemLoader("templates"))
|
|
|
|
env.filters["jsonify"] = jsonify
|
|
|
|
|
|
|
|
# load up and parse the lowest single units possible: we don't know or care
|
|
|
|
# which spec section will use it, we just need it there in memory for when
|
|
|
|
# they want it.
|
|
|
|
units = load_units()
|
|
|
|
|
|
|
|
# use the units to create RST sections
|
|
|
|
sections = load_sections(env, units)
|
|
|
|
|
|
|
|
# combine all the RST sections into a coherent spec
|
|
|
|
skeleton = "foo"
|
|
|
|
spec = create_from_skeleton(skeleton, sections)
|
|
|
|
|
|
|
|
check_unaccessed("units", units)
|
|
|
|
check_unaccessed("sections", sections)
|
|
|
|
print spec
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
main()
|