In our company, several internal projects rely on the same copied code parts to handle connections to the same APIs (like: Google Suite, JIRA,...). To avoid copying the same code over and over again for new projects, I want to create Symfony packages that collect these API classes.
The tricky part: I'm looking for a way to add the neccessary env variables automatically to .env, just like Symfony's recipe structure does it. But as these projects should only be used internally, pushing their recipe configuration to a public repository is a no-go for me. Adding a custom recipe server (like the one by moay) looks interesting to me, but needs additional configuration in each projects composer.json.
Is there any better way to resolve this, such that I could simply define the needed variables solely in my project, such that they get added to .env without any additional magic?
NB: anything that requires symfony/flex is fine, as this should be part of all new projects in our company
These are solutions I want to avoid:
add configuration to bundles / packages itself, such that these configuration values are put under version control
add configuration through any other command that is run manually after installing
You can use composer events for this process. After the package is installed, you add it to the .env file with a symfony command.
https://getcomposer.org/doc/articles/scripts.md
Composer unable to run post install script
There is a sample in the symfony composer.json file.
...
"scripts": {
"auto-scripts": {
"cache:clear": "symfony-cmd",
"assets:install %PUBLIC_DIR%": "symfony-cmd"
},
"post-install-cmd": [
"#auto-scripts"
],
"post-update-cmd": [
"#auto-scripts"
]
},
...
After each update or installation, this command is run "post-update-cmd, post-install-cmd".
In Symfony, the .env file is now committed into the repository. So It's not a good practice to put sensitive data on it.
A better solution is to create a file name .env.local. This file is not committed and it overrides all environnement value in .env
so you could have in .env
MY_SENSITIVE_DATA=mypersonalkey
and in your .env.local
MY_SENSITIVE_DATA=the_real_sensitive_data
source: https://symfony.com/doc/current/configuration.html#overriding-environment-values-via-env-local
Related
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?
What is a Flex Recipe?
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).
Private Recipes
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:
Bundles
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"]
}
}
Configuration
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.
Env Vars
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"
}
}
Composer Scripts
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).
Gitignore
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/"
]
}
Additional configurators
There are two configurators which do not rely on the manifest.json file:
Post-install output.
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.
Makefile
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.
I installed SIMPLESAMLPHP library with composer using
composer require simplesamlphp/simplesamlphp
For configuration I need to add saml-autoconfig.php file at my SIMPLESAMLPHP library root.But my vendor folder is in .gitignore file.
When I update my composer #production whole configuration with saml-autoconfig.php file gets missing.
I need to configured it when my composer get update.
If anyone have idea.Please help
I need to add following file with configuration
1) In saml-autoconfig.php .
$metadata_url_for = array(
/* WARNING WARNING WARNING
* You MUST remove the testing IdP (idp.oktadev.com) from a production system,
* as the testing IdP will allow ANYBODY to log in as ANY USER!
* WARNING WARNING WARNING
* For testing with http://saml.oktadev.com use the line below:
*/
// 'test' => 'http://idp.oktadev.com/metadata',
);
2)vendor/simplesamlphp/config.php
'baseurlpath'=>''
3)vendor/simplesamlphpauthsources.php
'default-sp'=>'' //its default one .I want to add more sp.
How I add dynamically saml-autoconfig.php this file and set my configuration.
If you want to execute a command after composer finished the install/update process, you can use the post-install-cmd and post-update-cmd options.
In this case, assuming that the config folder contains your configuration, you need to add this in your composer.json:
{
"require": {
"simplesamlphp/simplesamlphp": "^1.17"
},
"scripts": {
"post-install-cmd": [
"cp ./config/config.php ./vendor/simplesamlphp/config.php",
"cp ./config/authsources.php ./vendor/simplesamlphp/authsources.php"
],
"post-update-cmd": [
"cp ./config/config.php ./vendor/simplesamlphp/config.php",
"cp ./config/authsources.php ./vendor/simplesamlphp/authsources.php"
]
}
}
I also downloaded the simplesamlphp library, and the path you reported doesn't seem right. The correct path to install the configuration files should be vendor/simplesamlphp/simplesamlphp/config
I have the following setup:
symfony 2.7 classic structure
composer for dependency management
What I need to do is set a variable in parameters.yml with the timestamp when composer was ran.
For this I tried the following solution:
parameters.yml.dist
[bla bla bla]
ran_timestamp: ~
composer.json
[bla bla bla]
"scripts": {
"pre-install-cmd": [
"export SYMFONY_APP_DATE=$(date +\"%s\")"
],
}
"extra": {
"incenteev-parameters": {
"file": "app/config/parameters.yml",
"env-map": {
"ran_timestamp": "SYMFONY_APP_DATE"
}
}
}
The part where the variable is set inside parameters.yml works fine (the parameter is created with the value from SYMFONY_APP_DATE env variable).
The problem is that the env variable is not updated when composer is ran. Can anyone help me with that pls?
Additional info:
If I run the command from pre-install-cmd in cli by hand it works fine (so command itself I think is ok)
I see the command being run in composer after it starts install so I think it is executed (output below):
$composer install
export SYMFONY_APP_DATE=$(date +"%s")
Loading composer repositories with package information [bla bla bla]
No errors are reported
I'm assuming maybe composer doesn't have rights to set env variables? - nope, it isn't this. It is related with variable scope.
The problem apparently is that you're setting env parameter in child process (which is created for each script), but it's not possible to redefine env parameter for parent process from child (i.e. to set env value for composer itself from one of its scripts)
I think you need to extend \Incenteev\ParameterHandler\ScriptHandler::buildParameters to make it happen.
UPD: I've found a way to make it happen
Define a special block only for build-params in composer.json
"scripts": {
"build-params": [
"Incenteev\\ParameterHandler\\ScriptHandler::buildParameters"
],
and than in post-install-cmd block instead of Incenteev\\ParameterHandler\\ScriptHandler::buildParameters make it
"export SYMFONY_APP_DATE=$(date +\"%s\") && composer run-script build-params"
That will create env var and building parameteres in same process
I've problem in configuring Propel with Composer in my php project.
this is how appears my tree directory:
project/
|--/public_html/index.php
|--/app/
| |--data/
| | |--propel.json
| | |--schema.xml
| |--vendor/
| |--composer.json
In /data/ folder I would store all my propel files, that is generated-classes/ , generated-conf/ and generated-sql/ .
To realize this purpose, with a terminal in /data/ folder, I put the commands in the following sequence:
$ propel sql:build
$ propel model:build
$ propel config:convert
and all go right.
To make more suitable work, in composer.json I've added this extra feature:
"autoload": {
"classmap": ["./data/generated-classes/"]
}
so that, almost in theory, putting
require '../app/vendor/autoload.php';
inside index.php should be enough. Unfortunately, when I try to use one propel classes inside this page, returns the error
Type: Propel\Runtime\Exception\RuntimeException
Message: No connection defined for database "my_api". Did you forget to define a connection or is it wrong written?
File: 'C:\pathToMyProject'\project\app\vendor\propel\propel\src\Propel\Runtime\ServiceContainer\StandardServiceContainer.php
Line: 279
I thought that propel doesn't find the propel.json file stored in /data/folder.
As extra, if in index.php I simply add
require_once '../app/data/generated-conf/config.php';
all goes right.
There's a trick to autoload propel without use this last require_once? (obviously keep the tree as is).
Thanks for reading.
The order of CLI commands is important:
composer install or update to fetch propel
then the commands to generate the models with propel
then re-scan / re-generate the autoloading files with composer dump-autoload --optimize
You could include the configuration file in the bootstrap process of your application - like you already have.
Or you could use the files directive in Composers autoload section
to define file(s), which should be included on every request.
Referencing: https://getcomposer.org/doc/04-schema.md#files
"autoload": {
"files": ["./data/generated-conf/config.php"],
"classmap": ["./data/generated-classes/"]
}
Ok, newbie at Laravel. I used composer to download laravel. It created a directory structure like...
vendor\laravel\laravel\app
vendor\laravel\laravel\bootstrap
vendor\laravel\laravel\public
vendor\laravel\framework\....
vendor\laravel\laravel\composer.json
along with many other vendor and laravel directories.
and where my initial composer.json file was in the root directory.
I moved the contents of the vendor\laravel\laravel directory to the top level so that I have a directory structure like...
app\...
bootstrap\...
public\...
vendor\laravel\framework\...
composer.json
vendor\ many other directories...
I updated the index.php directory so that it referred to the new locations of the bootstrap\autoload.php and bootstrap\start.php directories.
I can load the index.php and I get the Laravel image map signifying that all is working.
So, now I go and modify the routes.php to be...
Route::controller('home', 'HomeController');
and try to load the home directory. I get the error...
"include(D:\dev\wamp\www\ltest3\vendor/laravel/laravel/app/controllers/BaseController.php): failed to open stream: No such file or directory"
The problem is that the vendor\composer\autoload_classmap.php still has the old laravel\app controller mappings. e.g.
return array(
'BaseController' => $vendorDir . '/laravel/laravel/app/controllers/BaseController.php',
'DatabaseSeeder' => $vendorDir . '/laravel/laravel/app/database/seeds/DatabaseSeeder.php',
'HomeController' => $vendorDir . '/laravel/laravel/app/controllers/HomeController.php',
instead of the new location at /app/controllers/
If I try to run composer update on the composer.json in my root directory, I get error after awhile of processing...
Failed to execute git status --porcelain --untracked-files=no
So, not sure how to get composer to update the autoload classmap to use my new directory location.
Do people normally leave the vendor\laravel\laravel directory in is original location?
Seems that the composer will probably attempt to update the laravel directory again, but not sure since I get the error.
Here is my full composer.json in the root directory. This was the one that was originally in the vendor\laravel\laravel directory and created by other initial composer run, maybe that is problem.
{
"name": "laravel/laravel",
"description": "The Laravel Framework.",
"keywords": ["framework", "laravel"],
"license": "MIT",
"require": {
"laravel/framework": "4.1.*"
},
"autoload": {
"classmap": [
"app/commands",
"app/controllers",
"app/models",
"app/database/migrations",
"app/database/seeds",
"app/tests/TestCase.php"
]
},
"scripts": {
"post-install-cmd": [
"php artisan clear-compiled",
"php artisan optimize"
],
"post-update-cmd": [
"php artisan clear-compiled",
"php artisan optimize"
],
"post-create-project-cmd": [
"php artisan key:generate"
]
},
"config": {
"preferred-install": "dist"
},
"minimum-stability": "stable"
}
All vendor files whether they belong to Laravel or third party should be in the same location /vendor. This is not just a amtter of mapping in bootstrap but this is important for when you need to update any package in composer. You might need to do this on a delicate environment so why not keep it as it should be? Is there a reason?
Composer is used on many other frameworks and I believe that in all of them you need a vendor directory.
Got it working, thanks to Cryode and user2094178 pointing out that my directory structure was not correct to start off with. I am going to go over several of the issues that I ran into, hopefully helping others that may have the same problem. fyi, this is on Windows 7 running WAMP.
I think where things all went wrong was that I tried to install Laravael by creating a composer.json file with a require of laravel. When running composer, it didn't know that I wanted Laravel as my main project framework, so it just installed all of Laravel down in the vendor directory. There were no top-level app, bootstrap, public, etc. directories.
Scrapped this install and started off from scratch using the directions specified at http://geekanddummy.com/how-to-laravel-4-tutorial-part-1-installation/ (e.g. ran composer create-project laravel/laravel). Ran into the following issues...
1) composer/git complains about https issues. composer continued with warnings on every download but continued to download files using http. When it got to symfphony filesystem.git, it got a fatal error
Failed to clone git#github.com:symfony/Filesystem.git via git, https, ssh protocols, aborting
To resolve this I ran a small php script that output phpinfo(). Determined the location of my php.ini file and removed the comment for "extension=php_openssl.dll". I had already done this for WAMP and Apache, but found out PHP at the command line was using a different php.ini
2) Did a test of git and ssl using "ssh git#github.com" at the command line. Had an issue that it could not authenticate, permission denied. Added environment variable HOME, set it to ..
set HOME=%HOMEPATH%
After this, ssh worked and added an ssh key successfully for github.
3) Deleted the entire project directory and started back from scratch, did not see a way to recover and continue. Next issue was that I got a git error "exceeded the timeout of 300 seconds" when retrieving symfony/Filesystem.git. Fixed this by adding the following composer environment variable..
set COMPOSER_PROCESS_TIMEOUT=2000
4) Deleted entire project and started again from scratch. All was downloaded fine this time. I have the top level app, bootstrap, public, and vendor directories. Loading the laravel\public\index.php works, I see the "You have arrived" page.