Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/neighborhoods/buphalo

Fabricates patterns.
https://github.com/neighborhoods/buphalo

hacktoberfest

Last synced: about 2 months ago
JSON representation

Fabricates patterns.

Awesome Lists containing this project

README

        

# [Buphalo](https://en.wikipedia.org/wiki/Buffalo_buffalo_Buffalo_buffalo_buffalo_buffalo_Buffalo_buffalo)
Fabricates patterns.

Anything good we stole from someone else. Anything bad is ours.

##### Table of Contents
* [Summary](#summary)
* [Problem](#problem)
* [Proposed Solution](#proposed-solution)
* [Getting Started](#getting-started)
* [Definitions](#definitions)
* [Features](#features)
* [References](#references)

## Summary
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.

## Problem
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.

## Proposed Solution
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.

## Getting Started

### Running Buphalo
#### Environmental Variable API
It is very easy to trace through the code where an environment variable is used. Buphalo uses the environment feature of the [DI component](#references) 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.
```bash
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.
```bash
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
```

##### Filtering
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](#references) and is eventually injected into the [Finder Component's](#references) `\Symfony\Component\Finder\Finder::name`. Any rule that works for `\Symfony\Component\Finder\Finder::name` will work here.
```bash
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
```

### Example Fabrication Files

```yml
# This lives in /PATH/TO/SOFTWARE_PRODUCT_ROOT/src/V2/Toe.buphalo.v1.fabrication.yml

# I WANT ALL THE ACTORS!
actors:
.php:
template: PrimaryActorName.php
.service.yml:
template: PrimaryActorName.service.yml
Interface.php:
template: PrimaryActorNameInterface.php
/AwareTrait.php:
template: PrimaryActorName/AwareTrait.php
/Factory.php:
template: PrimaryActorName/Factory.php
/Factory.service.yml:
template: PrimaryActorName/Factory.service.yml
/FactoryInterface.php:
template: PrimaryActorName/FactoryInterface.php
/Factory/AwareTrait.php:
template: PrimaryActorName/Factory/AwareTrait.php
/Builder.php:
template: PrimaryActorName/Builder.php
/Builder.service.yml:
template: PrimaryActorName/Builder.service.yml
/BuilderInterface.php:
template: PrimaryActorName/BuilderInterface.php
/Builder/AwareTrait.php:
template: PrimaryActorName/Builder/AwareTrait.php
/Builder/Factory.php:
template: PrimaryActorName/Builder/Factory.php
/Builder/Factory.service.yml:
template: PrimaryActorName/Builder/Factory.service.yml
/Builder/FactoryInterface.php:
template: PrimaryActorName/Builder/FactoryInterface.php
/Builder/Factory/AwareTrait.php:
template: PrimaryActorName/Builder/Factory/AwareTrait.php
/Repository.php:
template: PrimaryActorName/Repository.php
/Repository.service.yml:
template: PrimaryActorName/Repository.service.yml
/RepositoryInterface.php:
template: PrimaryActorName/RepositoryInterface.php
/Repository/AwareTrait.php:
template: PrimaryActorName/Repository/AwareTrait.php
/Map.php:
template: PrimaryActorName/Map.php
/Map.service.yml:
template: PrimaryActorName/Map.service.yml
/MapInterface.php:
template: PrimaryActorName/MapInterface.php
/Map/AwareTrait.php:
template: PrimaryActorName/Map/AwareTrait.php
/Map/Factory.php:
template: PrimaryActorName/Map/Factory.php
/Map/Factory.service.yml:
template: PrimaryActorName/Map/Factory.service.yml
/Map/FactoryInterface.php:
template: PrimaryActorName/Map/FactoryInterface.php
/Map/Factory/AwareTrait.php:
template: PrimaryActorName/Map/Factory/AwareTrait.php
/Map/Builder.php:
template: PrimaryActorName/Map/Builder.php
/Map/Builder.service.yml:
template: PrimaryActorName/Map/Builder.service.yml
/Map/BuilderInterface.php:
template: PrimaryActorName/Map/BuilderInterface.php
/Map/Builder/AwareTrait.php:
template: PrimaryActorName/Map/Builder/AwareTrait.php
/Map/Builder/Factory.php:
template: PrimaryActorName/Map/Builder/Factory.php
/Map/Builder/Factory.service.yml:
template: PrimaryActorName/Map/Builder/Factory.service.yml
/Map/Builder/FactoryInterface.php:
template: PrimaryActorName/Map/Builder/FactoryInterface.php
/Map/Builder/Factory/AwareTrait.php:
template: PrimaryActorName/Map/Builder/Factory/AwareTrait.php
```
```yml
# This lives in /PATH/TO/SOFTWARE_PRODUCT_ROOT/src/V2/Toe/Nail.buphalo.v1.fabrication.yml

# I only want SOME actors!
actors:
.php:
template: PrimaryActorName.php
.service.yml:
template: PrimaryActorName.service.yml
Interface.php:
template: PrimaryActorNameInterface.php
/AwareTrait.php:
template: PrimaryActorName/AwareTrait.php
/Factory.php:
template: PrimaryActorName/Factory.php
/Factory.service.yml:
template: PrimaryActorName/Factory.service.yml
/FactoryInterface.php:
template: PrimaryActorName/FactoryInterface.php
/Factory/AwareTrait.php:
template: PrimaryActorName/Factory/AwareTrait.php
/Builder.php:
template: PrimaryActorName/Builder.php
/Builder.service.yml:
template: PrimaryActorName/Builder.service.yml
/BuilderInterface.php:
template: PrimaryActorName/BuilderInterface.php
/Builder/AwareTrait.php:
template: PrimaryActorName/Builder/AwareTrait.php
/Builder/Factory.php:
template: PrimaryActorName/Builder/Factory.php
/Builder/Factory.service.yml:
template: PrimaryActorName/Builder/Factory.service.yml
/Builder/FactoryInterface.php:
template: PrimaryActorName/Builder/FactoryInterface.php
/Builder/Factory/AwareTrait.php:
template: PrimaryActorName/Builder/Factory/AwareTrait.php
```

### Turning Off Fabrication Of An Actor
* 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.

### Adding A New Or Updating An Existing Template
* 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)
```bash
Neighborhoods_Buphalo_V1_TemplateTree_Map_Builder_FactoryInterface__TemplateTreeDirectoryPaths=TreeName:/PATH/TO/SOFTWARE_PRODUCT/ROOT/template-tree/v1 \
```

### Using Multiple Template Trees
* 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 \
```

## Definitions

### Fabrication File
* A Fabrication File contains the instructions for fabricating a [Fablet](#fablet).
* The [Fablet](#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 `` 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](#example-fabrication-files) section one [Fablet](#fablet) is `Toe` and the other [Fablet](#fablet) is `Toe\Nail`.
* A [Fablet](#fablet) Actor can be anything.

### Fablet
(credit [Mucha](https://github.com/pmucha-55places))
* 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.

## Features
### Autoloading
* Be sure to update your `composer.json` to fallback to a `fab` directory, e.g.
```json
"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 in `src` will override what exists in `fab`.

### Annotation Processors
Annotation Processors (APs) are optional configuration tools that allow user space to define dynamic template content.

See [AnnotationProcessors](docs/AnnotationProcessors.md) for more information.

## References
* [Symfony Finder Component](https://symfony.com/doc/current/components/finder.html)
* [Symfony Dependency Injection Component](https://symfony.com/doc/current/components/dependency_injection.html)