I tried to find any documentation about using Symfony Flex but so far no luck.
Almost all docs point to installing a bundle that uses symfony Flex, not how to create a bundle that is using it.
I even tried to reverse engineer some of the packages but again, no luck.
My goal is to generate a default configuration file for my bundle in config/packages/my_bundle.yaml
.
What I need to know is where do I need to put it and what env variables (if any) will I have available?
Keep in mind that the flex recipe is a separate repository from your package repository, that needs to be hosted separately from the Bundle package.
In the most likely scenario that your is a public bundle/recipe, you'll have to submit your recipe to the "contrib" repository, get it approved and merged, so it's available as a community recipe.
Additionally, it's important to remember that most users will not have the contrib repository enabled by default. So if this is important for installing this bundle, you should tell your users how to do so before they install your recipe (e.g. in your bundle's readme file).
The other option would be having a private Flex recipe, as described here. The easiest way to generate a private recipe is to follow the same steps that Symfony does. Check this question and its answers for more details: How to generate a private recipe JSON from the contents of a recipe directory?
With that out of the way: Basically, a Flex recipe is a repository with a manifest.json
file with specific keys to enable certain "configurators".
The available manifest.json
configurators are:
Which bundles should be enabled on bundles.php
. These are added when the recipe is installed, and removed when the recipe is uninstalled.
{
"bundles": {
"Symfony\\Bundle\\DebugBundle\\DebugBundle": ["dev", "test"],
"Symfony\\Bundle\\MonologBundle\\MonologBundle": ["all"]
}
}
The "configuration" configurator deals with two keys: copy-from-recipe
and copy-from-package
. The first one can copy files from the recipe repository, the second one copies files from the package repository.
{
"copy-from-package": {
"bin/check.php": "%BIN_DIR%/check.php"
},
"copy-from-recipe": {
"config/": "%CONFIG_DIR%/",
"src/": "%SRC_DIR%/"
}
}
In this example, a file bin/check.php
in the package will be copied to the projects %BIN_DIR%
, and the contents of config
and src
on the recipe package will be copied the corresponding directory.
This is the typical use case to provide default configuration files, for example. From what you ask, this is your stated purpose for wanting to create a flex recipe.
This configurator simply adds the appropriate environment variable values to the project's .env
and .env.dist
. (Again, these would be removed if you uninstalled the recipe)
{
"env": {
"APP_ENV": "dev",
"APP_DEBUG": "1"
}
}
This configurator adds tasks to the scripts:auto-scripts
array from the project's composer.json
. The auto-scripts
are tasks that are executed every time composer update
or composer install
are executed in the project.
{
"composer-scripts": {
"vendor/bin/security-checker security:check": "php-script",
"make cache-warmup": "script",
"assets:install --symlink --relative %PUBLIC_DIR%": "symfony-cmd"
}
}
The second part on each line specifies what kind of command it is: a regular PHP script (php-script
), a shell script (script
), or a Symfony command (symfony-cmd
, executed via bin/console
).
This will add entries to the project's .gitignore
file.
{
"gitignore": [
"/phpunit.xml"
]
}
A complete example of a manifest.json
(lifted from here, as most other examples on this post):
{
"bundles": {
"Symfony\\Bundle\\FrameworkBundle\\FrameworkBundle": ["all"]
},
"copy-from-recipe": {
"config/": "%CONFIG_DIR%/",
"public/": "%PUBLIC_DIR%/",
"src/": "%SRC_DIR%/"
},
"composer-scripts": {
"make cache-warmup": "script",
"assets:install --symlink --relative %PUBLIC_DIR%": "symfony-cmd"
},
"env": {
"APP_ENV": "dev",
"APP_DEBUG": "1",
"APP_SECRET": "%generate(secret)%"
},
"gitignore": [
".env",
"/public/bundles/",
"/var/",
"/vendor/"
]
}
There are two configurators which do not rely on the manifest.json
file:
If a file named post-install.txt
exists in the recipe's package, its content is displayed when installation is complete. You can even use styles as defined here, for additional prettiness/obnoxiousness.
Example:
<bg=green;fg=white> </>
<bg=green;fg=white> Much success!! </>
<bg=green;fg=white> </>
* <fg=yellow>Next steps:</>
1. Foo
2. <comment>bar</>;
3. Baz <comment>https://example.com/</>.
This will be presented to the user after the installation is complete.
If a file named Makefile
exists in the recipe's repository, the tasks defined here would be added to the project's Makefile (creating the Makefile if it didn't exist).
cache-clear:
@test -f bin/console && bin/console cache:clear --no-warmup || rm -rf var/cache/*
.PHONY: cache-clear
Simple as that. I guess than most packages would not need a makefile command, so this would have much less use than other configurators.
You can read the full documentation here.