Fabricates patterns.
Anything good we stole from someone else. Anything bad is ours.
This document attempts to describe how to use Buphalo's public APIs. In addition, it tries to offer some insight into the problem that Buphalo attempts to solve and the motivation for it to solve that problem. If it is not described in this document, it is not considered to be a public API and is subject to change in any arbitrary release, i.e. you should not depend on it.
Patterns are solutions to problems within a context. Implementing well designed patterns can become tedious and laborious which discourages their implementation in favor of patterns that are less well designed but have a faster development velocity.
Employ an easy to change code generation tool that generates well designed patterns so that the development velocity is equivalent or faster than less well designed patterns.
It is very easy to trace through the code where an environment variable is used. Buphalo uses the environment feature of the DI component to inject runtime options into objects in the container.
Buphalo leverages an environment variable API for runtime options. The following shell command to run Buphalo illustrates the currently supported API.
Neighborhoods_Buphalo_V1_TargetApplication_BuilderInterface__SourceDirectoryPath=/PATH/TO/SOURCE/DIRECTORY \
Neighborhoods_Buphalo_V1_TargetApplication_BuilderInterface__FabricationDirectoryPath=/PATH/TO/FABRICATION/DIRECTORY \
Neighborhoods_Buphalo_V1_TargetApplication_BuilderInterface__NamespacePrefix=VENDOR\\PRODUCT\\ \
Neighborhoods_Buphalo_V1_TemplateTree_Map_Builder_FactoryInterface__TemplateTreeDirectoryPaths=TreeName:/PATH/TO/TEMPLATE/TREE/DIRECTORY \
php bin/v1/buphalo
For example, in order to Buphalo Buphalo (assuming Buphalo is installed as a composer dependency) execute the following shell command from your product's root directory.
Neighborhoods_Buphalo_V1_TargetApplication_BuilderInterface__SourceDirectoryPath=$PWD/vendor/neighborhoods/buphalo/src/v1 \
Neighborhoods_Buphalo_V1_TargetApplication_BuilderInterface__FabricationDirectoryPath=$PWD/vendor/neighborhoods/buphalo/fab/v1 \
Neighborhoods_Buphalo_V1_TargetApplication_BuilderInterface__NamespacePrefix=Neighborhoods\\Buphalo\\ \
Neighborhoods_Buphalo_V1_TemplateTree_Map_Builder_FactoryInterface__TemplateTreeDirectoryPaths=buphalo:$PWD/vendor/neighborhoods/buphalo/template-tree/V1 \
php vendor/bin/v1/buphalo
Buphalo also allows you to specify any number of specific filter rules for files with the
Neighborhoods_Buphalo_V1_FabricationFile_Map_BuilderInterface__FinderFileNames
environment variable. As an env var this is "typed" as a CSV. It is then cast to an array by the DI componnent and is eventually injected into the Finder Component's \Symfony\Component\Finder\Finder::name
. Any rule that works for \Symfony\Component\Finder\Finder::name
will work here.
Neighborhoods_Buphalo_V1_TargetApplication_BuilderInterface__SourceDirectoryPath=$PWD/vendor/neighborhoods/buphalo/src/v1 \
Neighborhoods_Buphalo_V1_TargetApplication_BuilderInterface__FabricationDirectoryPath=$PWD/vendor/neighborhoods/buphalo/fab/v1 \
Neighborhoods_Buphalo_V1_TargetApplication_BuilderInterface__NamespacePrefix=Neighborhoods\\Buphalo\\ \
Neighborhoods_Buphalo_V1_TemplateTree_Map_Builder_FactoryInterface__TemplateTreeDirectoryPaths=buphalo:$PWD/vendor/neighborhoods/buphalo/template-tree/V1 \
Neighborhoods_Buphalo_V1_FabricationFile_Map_BuilderInterface__FinderFileNames=Connection.buphalo.v1.fabrication.yml,Connection2.buphalo.v1.fabrication.yml
php vendor/bin/v1/buphalo
# This lives in /PATH/TO/SOFTWARE_PRODUCT_ROOT/src/V2/Toe.buphalo.v1.fabrication.yml
# I WANT ALL THE ACTORS!
actors:
<PrimaryActorName>.php:
template: PrimaryActorName.php
<PrimaryActorName>.service.yml:
template: PrimaryActorName.service.yml
<PrimaryActorName>Interface.php:
template: PrimaryActorNameInterface.php
<PrimaryActorName>/AwareTrait.php:
template: PrimaryActorName/AwareTrait.php
<PrimaryActorName>/Factory.php:
template: PrimaryActorName/Factory.php
<PrimaryActorName>/Factory.service.yml:
template: PrimaryActorName/Factory.service.yml
<PrimaryActorName>/FactoryInterface.php:
template: PrimaryActorName/FactoryInterface.php
<PrimaryActorName>/Factory/AwareTrait.php:
template: PrimaryActorName/Factory/AwareTrait.php
<PrimaryActorName>/Builder.php:
template: PrimaryActorName/Builder.php
<PrimaryActorName>/Builder.service.yml:
template: PrimaryActorName/Builder.service.yml
<PrimaryActorName>/BuilderInterface.php:
template: PrimaryActorName/BuilderInterface.php
<PrimaryActorName>/Builder/AwareTrait.php:
template: PrimaryActorName/Builder/AwareTrait.php
<PrimaryActorName>/Builder/Factory.php:
template: PrimaryActorName/Builder/Factory.php
<PrimaryActorName>/Builder/Factory.service.yml:
template: PrimaryActorName/Builder/Factory.service.yml
<PrimaryActorName>/Builder/FactoryInterface.php:
template: PrimaryActorName/Builder/FactoryInterface.php
<PrimaryActorName>/Builder/Factory/AwareTrait.php:
template: PrimaryActorName/Builder/Factory/AwareTrait.php
<PrimaryActorName>/Repository.php:
template: PrimaryActorName/Repository.php
<PrimaryActorName>/Repository.service.yml:
template: PrimaryActorName/Repository.service.yml
<PrimaryActorName>/RepositoryInterface.php:
template: PrimaryActorName/RepositoryInterface.php
<PrimaryActorName>/Repository/AwareTrait.php:
template: PrimaryActorName/Repository/AwareTrait.php
<PrimaryActorName>/Map.php:
template: PrimaryActorName/Map.php
<PrimaryActorName>/Map.service.yml:
template: PrimaryActorName/Map.service.yml
<PrimaryActorName>/MapInterface.php:
template: PrimaryActorName/MapInterface.php
<PrimaryActorName>/Map/AwareTrait.php:
template: PrimaryActorName/Map/AwareTrait.php
<PrimaryActorName>/Map/Factory.php:
template: PrimaryActorName/Map/Factory.php
<PrimaryActorName>/Map/Factory.service.yml:
template: PrimaryActorName/Map/Factory.service.yml
<PrimaryActorName>/Map/FactoryInterface.php:
template: PrimaryActorName/Map/FactoryInterface.php
<PrimaryActorName>/Map/Factory/AwareTrait.php:
template: PrimaryActorName/Map/Factory/AwareTrait.php
<PrimaryActorName>/Map/Builder.php:
template: PrimaryActorName/Map/Builder.php
<PrimaryActorName>/Map/Builder.service.yml:
template: PrimaryActorName/Map/Builder.service.yml
<PrimaryActorName>/Map/BuilderInterface.php:
template: PrimaryActorName/Map/BuilderInterface.php
<PrimaryActorName>/Map/Builder/AwareTrait.php:
template: PrimaryActorName/Map/Builder/AwareTrait.php
<PrimaryActorName>/Map/Builder/Factory.php:
template: PrimaryActorName/Map/Builder/Factory.php
<PrimaryActorName>/Map/Builder/Factory.service.yml:
template: PrimaryActorName/Map/Builder/Factory.service.yml
<PrimaryActorName>/Map/Builder/FactoryInterface.php:
template: PrimaryActorName/Map/Builder/FactoryInterface.php
<PrimaryActorName>/Map/Builder/Factory/AwareTrait.php:
template: PrimaryActorName/Map/Builder/Factory/AwareTrait.php
# This lives in /PATH/TO/SOFTWARE_PRODUCT_ROOT/src/V2/Toe/Nail.buphalo.v1.fabrication.yml
# I only want SOME actors!
actors:
<PrimaryActorName>.php:
template: PrimaryActorName.php
<PrimaryActorName>.service.yml:
template: PrimaryActorName.service.yml
<PrimaryActorName>Interface.php:
template: PrimaryActorNameInterface.php
<PrimaryActorName>/AwareTrait.php:
template: PrimaryActorName/AwareTrait.php
<PrimaryActorName>/Factory.php:
template: PrimaryActorName/Factory.php
<PrimaryActorName>/Factory.service.yml:
template: PrimaryActorName/Factory.service.yml
<PrimaryActorName>/FactoryInterface.php:
template: PrimaryActorName/FactoryInterface.php
<PrimaryActorName>/Factory/AwareTrait.php:
template: PrimaryActorName/Factory/AwareTrait.php
<PrimaryActorName>/Builder.php:
template: PrimaryActorName/Builder.php
<PrimaryActorName>/Builder.service.yml:
template: PrimaryActorName/Builder.service.yml
<PrimaryActorName>/BuilderInterface.php:
template: PrimaryActorName/BuilderInterface.php
<PrimaryActorName>/Builder/AwareTrait.php:
template: PrimaryActorName/Builder/AwareTrait.php
<PrimaryActorName>/Builder/Factory.php:
template: PrimaryActorName/Builder/Factory.php
<PrimaryActorName>/Builder/Factory.service.yml:
template: PrimaryActorName/Builder/Factory.service.yml
<PrimaryActorName>/Builder/FactoryInterface.php:
template: PrimaryActorName/Builder/FactoryInterface.php
<PrimaryActorName>/Builder/Factory/AwareTrait.php:
template: PrimaryActorName/Builder/Factory/AwareTrait.php
- Just don't include the Actor entry in the Fabrication File to begin with.
- Remove the Actor entry from the Fabrication File.
- Comment the Actor entry from the Fabrication File.
- Include the equivalent file in the path referenced by
Neighborhoods_Buphalo_V1_TargetApplication_BuilderInterface__SourceDirectoryPath
- Buphalo will not fabricate files that already exist in the source directory path, since the idea is that they will be preferred over the fabricated files.
- Copy Buphalo's
template-tree
directory to your software product's root directory if you have not done so already. - Add or change the appropriate PHP and dependency injection service definition YAML files in the position that you want them under your
template-tree/v1
directory. - Be sure to update your environmental variable to the following (or the equivalent if you used a different path for the copied directory)
Neighborhoods_Buphalo_V1_TemplateTree_Map_Builder_FactoryInterface__TemplateTreeDirectoryPaths=TreeName:/PATH/TO/SOFTWARE_PRODUCT/ROOT/template-tree/v1 \
- Buphalo supports using multiple template trees.
- If using multiple trees, each template tree MUST be named by including a "TreeName:" prefix to the directory path
- If using a single template tree, the template tree identifier MAY be left unnamed.
- Separate each path identifier with a comma
- Buphalo will attempt to look through the template tree directories in the order specified, and will use the first matching template it finds
- example:
Neighborhoods_Buphalo_V1_TemplateTree_Map_Builder_FactoryInterface__TemplateTreeDirectoryPaths=primary:/PATH/TO/SOFTWARE_PRODUCT/ROOT/template-tree/primary,secondary:/PATH/TO/SOFTWARE_PRODUCT/ROOT/template-tree/secondary \
- A Fabrication File contains the instructions for fabricating a Fablet.
- The Fablet primary Actor is identified by the Fabrication File file name, and the location of the
Fabrication File
within the directory structure that it resides. - The
<PrimaryActorName>
token is an alias to the Fabrication File name without the extension and is the name of the primary actor. - In the Example Fabrication Files section one Fablet is
Toe
and the other Fablet isToe\Nail
. - A Fablet Actor can be anything.
(credit Mucha)
- A Fablet is the collection of Actors that are built from the Fabrication File.
- A Primary Actor is the class that shares the same name as the Fabrication File without the extension.
- This collection contains the Primary Actor and/or any number of supporting actors.
- Be sure to update your
composer.json
to fallback to afab
directory, e.g."autoload": { "psr-4": { "VENDOR\\PRODUCT\\": [ "src", "fab" ] } }
- In order to be efficient, Buphalo will only fabricate files that do not exist in
src
since anything insrc
will override what exists infab
.
Annotation Processors (APs) are optional configuration tools that allow user space to define dynamic template content.
See AnnotationProcessors for more information.