Beam::Make - Recipes to declare and resolve dependencies between things
version 0.003
### container.yml
# This Beam::Wire container stores shared objects for our recipes
dbh:
$class: DBI
$method: connect
$args:
- dbi:SQLite:RECENT.db
### Beamfile
# This file contains our recipes
# Download a list of recent changes to CPAN
RECENT-6h.json:
commands:
- curl -O https://www.cpan.org/RECENT-6h.json
# Parse that JSON file into a CSV using an external program
RECENT-6h.csv:
requires:
- RECENT-6h.json
commands:
- yfrom json RECENT-6h.json | yq '.recent.[]' | yto csv > RECENT-6h.csv
# Build a SQLite database to hold the recent data
RECENT.db:
$class: Beam::Make::DBI::Schema
dbh: { $ref: 'container.yml:dbh' }
schema:
- table: recent
columns:
- path: VARCHAR(255)
- epoch: DOUBLE
- type: VARCHAR(10)
# Load the recent data CSV into the SQLite database
cpan-recent:
$class: Beam::Make::DBI::CSV
requires:
- RECENT.db
- RECENT-6h.csv
dbh: { $ref: 'container.yml:dbh' }
table: recent
file: RECENT-6h.csv
### Load the recent data into our database
$ beam make cpan-recent
Beam::Make
allows an author to describe how to build some thing (a
file, some data in a database, an image, a container, etc...) and the
relationships between things. This is similar to the classic make
program used to build some software packages.
Each thing is a recipe
and can depend on other recipes. A user runs
the beam make
command to build the recipes they want, and
Beam::Make
ensures that the recipe's dependencies are satisfied
before building the recipe.
This class is a Beam::Runnable object and can be embedded in other Beam::Wire containers.
Unlike make
, Beam::Make
recipes can do more than just execute
a series of shell scripts. Each recipe is a Perl class that describes
how to build the desired thing and how to determine if that thing needs
to be rebuilt.
These recipe classes come with Beam::Make
:
- File - The default recipe class that creates
a file using one or more shell commands (a la
make
) - DBI - Write data to a database
- DBI::Schema - Create a database schema
- DBI::CSV - Load data from a CSV into a database table
- Docker::Image - Build or pull a Docker image
- Docker::Container - Build a Docker container
Future recipe class ideas are:
- Template rendering: Files could be generated from a configuration file or database and a template.
- Docker compose: An entire docker-compose network could be rebuilt.
- System services (init daemon, systemd service, etc...): Services could depend on their configuration files (built with a template) and be restarted when their configuration file is updated.
The Beamfile
defines the recipes. To avoid the pitfalls of Makefile
, this is
a YAML file containing a mapping of recipe names to recipe configuration. Each
recipe configuration is a mapping containing the attributes for the recipe class.
The $class
special configuration key declares the recipe class to use. If no
$class
is specified, the default Beam::Wire::File recipe class is used.
All recipe classes inherit from Beam::Class::Recipe and have the name
and requires attributes.
For examples, see the Beam::Wire examples directory on Github.
For additional configuration, create a Beam::Wire container and
reference the objects inside using $ref: "<container>:<service>"
as the value for a recipe attribute.
-
Target names in
Beamfile
should be regular expressionsThis would work like Make's wildcard recipes, but with Perl regexp. The recipe object's name is the real name, but the recipe chosen is the one the matches the regexp.
-
Environment variables should interpolate into all attributes
Right now, the
NAME=VALUE
arguments tobeam make
only work in recipes that use shell scripts (like Beam::Make::File). It would be nice if they were also interpolated into other recipe attributes. -
Recipes should be able to require wildcards and directories
Recipe requirements should be able to depend on patterns, like all
*.conf
files in a directory. It should also be able to depend on a directory, which would be the same as depending on every file, recursively, in that directory.This would allow rebuilding a ZIP file when something changes, or rebuilding a Docker image when needed.
-
Beam::Wire should support the <container>:<service> syntax for references
The Beam::Wire class should handle the
BEAM_PATH
environment variable directly and be able to resolve services from other files without building anotherBeam::Wire
object in the container. -
Beam::Wire should support resolving objects in arbitrary data structures
Beam::Wire should have a class method that one can pass in a hash and get back a hash with any
Beam::Wire
object references resolved, including$ref
or$class
object.
Doug Bell [email protected]
This software is copyright (c) 2020 by Doug Bell.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.