moo is a tool for schema driven code generation.
moo defines a conceptual taxonmy
- schema
- a data structure describing the structure of data (including schema).
- model
- a data structure which is valid against a schema
- template
- text in some target format which is marked up with directives that are parameterized in terms of a schema and provided by a valid model
- codegen
- an artifact generated by applying a model to a template each adhering to a schema.
moo may operate on instances of the moo taxonomy in various ways
- compile
- transform a model or a schema from one representation to another
- imports
- calculate an implicit file dependencies in the file representation of a model, schema or template
- validate
- determine if a model adheres to a schema
- render
- generate code (or other forms) by applying a model to a template
moo can be used for many things
- define a unified data model with generated types in multiple languages
- produce serialization methods for objects in a data model
- translate from moo schema to others such as Avro, Protobuf, JSON Schema
- generate “perfect” instances of complex code patterns such as finite state machines from simple models
- …and more
The current moo version is…
#+RESULTS[b57c6704ace54c0d65cec578308037290faa03d3]:
0.6.1
…as of last time this file was updated. See moo/version.py
for the
definitive version.
moo is free software and may be used under the terms described in file COPYING. These terms explicitly do NOT extend to any of your own files which may be input to or output from moo software.
moo requires Python 3.5 or newer.
moo installs in to your favorite Python environment in most of the usual ways. Some examples are given below. Due to a name conflict (this) moo is currently not distributed through PyPI.
Here, python
is assumed to be Python 3. Use whatever your favorite
Python environment is to assure that. Some suggestions:
$ python3 -m venv venv $ source venv/bin/activiate
Install direnv
and activate it in your shell, then:
$ echo "layout python3" > .envrc $ direnv allow
See more at https://github.com/direnv/direnv
Via a release tarball:
$ python -m pip install https://github.com/brettviren/moo/archive/0.4.1.tar.gz
Or, via git:
$ python -m pip install git+git://github.com/brettviren/[email protected]#egg=moo
Just install:
$ python -m pip install git+git://github.com/brettviren/moo.git#egg=moo
Or, maybe you want to hack on the code:
$ git clone [email protected]:brettviren/moo.git $ cd moo $ pyton -m pip install -e .
moo source provides many types of tests. Below shows how to run the different types of tests and their output from last time this document was regenerated. Besides these explicit examples, regenerating moo documents runs various tests which are embedded as examples.
The shell-level tests require BATS and bats-core is the recommended implementation.
bats -j 8 test
1..55 ok 1 test any ok 2 jsonnet returns high precision ok 3 moo compile hides lost precision ok 4 compile schema with enum ok 5 render schema with enum ok 6 check passing ok 7 check failing ok 8 template paths ok 9 template paths user ok 10 model paths ok 11 model paths user ok 12 resolve builtin template ok 13 resolve builtin template with extra path ok 14 imports find builtin template ok 15 render template from user path ok 16 render template from user path which imports builtin ok 17 compile schema ok 18 generate and compile codegen ok 19 compile to non-existent ok 20 imports to non-existent ok 21 okay with existing ok 22 okay with missing ok 23 find jinja import via template path in moo imports ok 24 find jinja import via template path in moo render ok 25 compile with default TLA ok 26 compile with TLA from CLI with int ok 27 compile with TLA from CLI with float ok 28 compile with TLA from CLI with bool ok 29 compile with TLA from CLI with string ok 30 compile with TLA from CLI with file ok 31 trivial test ok 32 compile oschema/sys example ok 33 compile oschema/app example ok 34 simple TLAs ok 35 TLA as a file ok 36 TLAs as in Jsonnet code ok 37 moo dump ok 38 moo simple render ok 39 another TLA compile test ok 40 moo transform feature ok 41 moo graft feature with render ok 42 multi element path and omodel ok 43 moo validate anys ok 44 compile t-s-t-p test input ok 45 render ostructs on all-in-one model ok 46 render ostructs on model1 ok 47 render ostructs on model2 ok 48 render onljs on all-in-one model ok 49 render onljs on model1 ok 50 render onljs on model2 ok 51 render omsgp on all-in-one model ok 52 render omsgp on model1 ok 53 render omsgp on model2 ok 54 test issue #2 ok 55 test issue #2 with MOO_LOAD_PATH
The Python-level tests require pytest. Note, developers should not disable warnings when running tests. For the sake of brevity in this document they are turned off as some 3rd party packages trigger noisy but currently innocuous deprecation warnings.
pytest --disable-warnings
#+RESULTS[544845d42c5c359a73f13fc6d310b9ef86567430]:
============================= test session starts ============================== platform linux -- Python 3.8.0, pytest-6.1.1, py-1.9.0, pluggy-0.13.1 rootdir: /home/bv/dev/moo collected 24 items test/test_issue11.py . [ 4%] test/test_issue13.py .... [ 20%] test/test_issue16.py .. [ 29%] test/test_issue27.py ... [ 41%] test/test_moo_ogen.py . [ 45%] test/test_moo_otypes.py ..... [ 66%] test/test_moo_templates.py .. [ 75%] test/test_moo_util.py ..... [ 95%] test/test_ogen_schema.py . [100%] ======================== 24 passed, 2 warnings in 1.38s ========================
The moo command line interface provides various commands and online help:
$ moo --help
See links below for documentation which provides various examples.
- home page
- https://brettviren.github.io/moo
- code repo
- https://github.com/brettviren/moo
- documentation
-
- moo high level documentation (this file)
- moo object schema paradigm how to define schema and use it to validate models, apply models to templates for example to implement codegen
- moo object types way to create objects with a valid-by-construction pattern in Python
- moo object validation to strongly check if existing objects are valid against moo schema.
- moo and build systems how to integrate moo codegen into various build systems
- moo and top-level arguments flexible way to inject values into a Jsonnet program
- moo as Wire-Cell user package generator how moo can be used to generate a skeleton of an entire software project
- moo for LaTeX and spreadsheet generator using moo in production of documentation
While moo
has a 0.y.z
release, backward compatibility is not a strong
priority as all uses are also in flux. y
will increment with major
new features which may or may not be backward compatible. z
will
increment with minor bug fixes.
Notes to self on making a release:
- edit moo/version.py to set release version
- reexport this and other documentation files, no cache and check for failures
- bats/pytest runs as part of exporting this file
git commit
andgit tag -am 'Pithy release message' X.Y.Z
using matching string- edit moo/version.py to go back to a dev version
git commit
andgit push
andgit push --tags
- visit github release page and add any useful details
The name moo is a play on the Japanese term 無 which may be interpreted to English in a few ways. Some are listed below along with how the meaning reflects on aspects of moo.
- Untainted pure mind
- moo avoids being “opinionated”, is centered on ideas expressed as abstract data structures and so can be used for a wide variety of things from generating code, documents or package skeletons. moo forms its data structures by ingesting most of the popular file formats likely to be used. And, moo can produce any file format for which a user may create a template.
- No strings attached
- moo is not intended to be an invasive tool. moo artifacts can be generated as desired and moo may be left behind. moo does not lock-in particular formats. moo extends this freedom to your own applications. By adopting moo codegen philosophy an app need not lock-in itself to particular data formats, representations, or serializations technologies.
- Nothingness
- moo is not really anything itself but rather it is the bits that go between other real things which perform the “heavy lifting” (Jsonnet, anyconfig, Jinja, JSON Schema, user templates). moo lets apps embrace the power of this nothingness by switching developer effort away from repetitive programming tasks and toward data structure and template development and then through code generation that effort gains multiplicative power.