View Source mix compile.avro_schema_generator (avrogen v0.7.1)
Compiler task to generate avro schemas from templates defined in elixir.
Usage
Use this task by adding it to the list of compilers in your mix.exs for your project, and add
configuration options using the avro_schema_generator_opts
key in your project options.
Example configuration:
def project do
[
...
compilers: [:avro_schema_generator | Mix.compilers()],
...
avro_schema_generator_opts: [
paths: ["schema/**/*.exs"],
dest: "priv/schema/"
]
...
]
end
Where:
- paths: A list of wildcards used to locate elixir template files to generate code for. Each path is evaluated with Path.wildcard().
- dest: Where to put the generated schema files.
Schema File Naming
Schema files are generated one schema per file, where the name of each file is described below.
<schema_root>/<schemanamespace>.<SchemaName>.avsc
E.g. root/foo.bar/Baz.avsc
Dependency Tracking
In order to make the build as fast as possible, it is important that this task only generates files when it needs to, i.e. when sources have changed thus, proper dependency management is required.
Each template file (exs) will generate one or more schema file (avsc), one for each schema it defines. Thus each generated schema file will depend only on its source exs file.
Example dependency tree:
foo.exs <─┬─ foo.Bar.avsc
├─ foo.Baz.avsc
└─ foo.Qux.avsc
Arrows point in the direction of the dependency, e.g. foo.Bar.avsc depends on foo.exs. This means that the content of foo.Bar.avsc depends entirely on the content of foo.exs, so it must be updated only if foo.exs is newer than it.
Because it's not obvious what ex files would be generated (without just running the generation), each time we run the task we store the list of generated files in a manifest file. The next time we run the task, the list of generated files from the previous run is recalled by reading the manifest file, and this list is used to work out if any of the generated files are older than any of their dependencies, thus triggering a re-gen of just those files.
This manifest could also used to know which files to delete when running a clean operation, but unfortunately running mix clean when this app is in an umbrella doesn't work. I think this is because this task is "cleaned" before it has a chance to run, which effectively wipes out this task entirely. If we made this app an external dependency, it wouldn't be cleaned with mix clean and thus will work just fine.