I'm trying to install some packages outside the /vendor folder via the installer-paths composer directive.
After the deploy those packages aren't installed in the deployment, but the ones in the vendor folders are.
There is any way to allow the Cloud build to install composer packages outside vendor folder?
I'm deploying a Wordpress website to GAE php72, using a composer based boilerplate Bedrock.
I've tried to set the those paths to target custom folders inside the /vendor folder and it works, maybe there is some sort of security rules that allows composer install only to write into vendor?
Here is part of composer.json:
{
// ...
{
"composer/installers": "^1.7",
"wpackagist-plugin/wordpress-seo": ">=6.0",
"wpackagist-theme/twentynineteen":"1.0"
},
"extra": {
"installer-paths": {
"web/app/mu-plugins/{$name}/": ["type:wordpress-muplugin"],
"web/app/plugins/{$name}/": ["type:wordpress-plugin"],
"web/app/themes/{$name}/": ["type:wordpress-theme"]
},
"wordpress-install-dir": "web/wp"
}
//...
}
I've also tried to use composer post-install-cmd scripts to copy the packages from /vendor folder to the desired location, but the build fails with message:
Step #1 - "builder": Script cp vendor/plugins/* web/app/plugins handling the post-install-cmd event returned with error code 1
Step #1 - "builder": cp: target 'web/app/plugins' is not a directory
Step #1 - "builder": > cp vendor/plugins/* web/app/plugins
I don't think it would be possible since, as Google Cloud Platform documentation states that composer specifically adds the packages to your app's vendor/ directory, where autoload.php is generated.
I actually found that deploying with:
gcloud beta app deploy --no-cache
installs all packages successfully even outside the /vendor folder.
Related
for educational proposes I write my own PHP application and add a little plugin system. The application itself uses composer to manage required dependencies.
It is possible that a plugin have his own dependencies (Guzzle etc.) and that two plugins have some overlapping dependencies. To reduce storage and avoid any interference I will use composer with composer installers for the plugins:
/src
/plugins
/DemoPlugin
composer.json
/src
/config
...
/vendor
composer.phar
composer.json
...
So it is possible to install a plugin easy over the "main" application and composer handles all dependencies automatically (incl. autoloading).
But this workflow creates a problem that I cant solve at the moment: It requires that the user uses composer require app/plugin-name and download the plugin from the network. But I cant guarantee that every plugin can be installed this way. For example: Paid plugins, company internal plugins or simple dev plugins which only exists as "zip file".
With composer installers the plugins are stored in a different directory, in place of the "classic" vendor directory. But from my understanding it is not possible to copy a zip based plugin into this plugin folder. I cant find any method to start the installation of the plugin (downloading vendor, maybe setup scripts etc.).
This concludes into my question: It is possible to tell the composer instance from the "main application" that a plugin should be installed (downloading vendor, maybe setup scripts etc.) but dont start a download because the plugin is already placed correctly?
If I run composer install in the plugin directory, composer will download the vendor directly into the plugin directory - with all the problems (duplicate dependencies, no integration into the autoload etc.).
I appreciate any help!
What you are looking for is a path repository.
To follow your example you can use the following composer.json
{
"name": "test/test",
"type": "test",
"repositories": [{
"type": "path",
"url": "./plugins/**/"
}],
"require": {
"guzzlehttp/guzzle": "^6.3"
}
}
Where you have the following structure:
├── composer.json
├── composer.lock
└── plugins
└── DemoPlugin
└── composer.json
You can eventually require your plugin as you would do usually:
composer require "test/demo:#dev"
And you will see the dependencies are not duplicated (you do not need to install the DemoPlugin package).
I wanted to get several Git repositories then place it on a certain directory on my Git-tracked project. My current project structure:
- custom
- plugins
- file.txt
When the user do a composer install, I wanted it to fetch this Git repo then place it under new directory on my project named provisioning.
- custom
- plugins
- provisioning
- nginx
- file.txt
Am I using the Composer the right way?
By default, the composer will install dependencies to vendor directory. If you need to install everything into directory names provisioning the use
"config": {
"vendor-dir": "plugins"
},
in your composer.json file and then run composer install command
Further details in How to specify Composer install path?
Is there a way to clean unused dependencies and composer dev requires to reduce a Laravel project, because it's so heavy (43,3 Mb) and it's a small project. Btw, I'm using some dev helpers like Debugbar and IDEHelpers which are not used for deployment...
Is there a way to make a deployment version of my project in other folder
The recommended way to deploy your app is without the vendor directory. I'm going to assume that you're using git for your project. First, put the following in your .gitignore.
/vendor/
Now remove the vendor directory from your repository
git rm -r --cached vendor
git commit -m 'Removed vendor directory'
Now you have a two step deployment:
Update the app using git pull or however you usually deploy.
Run composer install --no-dev --optimize-autoloader. This will generate your vendor directory omitting any development only dependencies.
In order to take advantage of the --no-dev flag, you need to put your development dependencies in the require-dev section in your composer.json. For example:
"require-dev": {
"phpunit/phpunit": "~4.3"
}
Now PHPUnit will be required for development, but not when the --no-dev flag is specified.
Maybe I'm misunderstanding your question but when you deploy a project, you shouldn't be deploying the laravel app with it (/vendor/). You should run composer install and it will pull in all the dependencies. In your composer.json file you can also choose which dependencies are for dev environments only similar to the require-dev section found here: https://gist.github.com/philsturgeon/5976359
I have installed composer.
My project dir tree looks something like this
/home/myproject/public_html/myproject.com
I initially installed it in:
/home/myproject/public_html/myproject.com/bin/composer/
But later moved it to:
/home/myproject/usr/local/bin/composer
Questions:
Where to I create composer.json ?
In the official docs they mention that in order to install new packages I need to write a require key in the json format in that file, does this mean that I dont have to upload the package through ftp?
The docs further say that I can simply install dependencies like ths:
php composer.phar install
I dont understand the workflow of this process (im fairly new).. what exactly do I need to do to get some packages going (like Respect)
Composer has 2 basic elements for you to consider:
The composer.php file itself - this can be located anywhere on your system - usually it is convenient to have it in you search path so you can invoke it by name (no path) from the command line.
Composer.json - this file is the configuration for your project. This is usually best located at the top level of your project. Ideally this is a directory outside the scope of your web server - so that it will never be exposed or served.
Symfony2 has some great documentation and examples of composer in use.
Also be aware that some packages you reference via composer will themselves have composer files - to ensure they match your required dependancies - and they may also have their own dependancies that need to be considered.
I would install composer.json in the following
/home/myproject/composer.json
It would be out of scope of the web server and could be used to manage many assets e.g.
public_html/
libs/
config/
docs/
vendor/
Where to I create composer.json ?
You should create composer.json to your project root like /home/myproject/public_html/myproject.com/composer.json. If all files of your application live inside your myproject.com folder.
In the official docs they mention that in order to install new
packages I need to write a require key in the json format in that
file, does this mean that I dont have to upload the package through
ftp?
Yes as long as you're not in shared hosting because most of them don't allow CLI (SSH).
The docs further say that I can simply install dependencies like this
php composer.phar install
Yes you can simple type the above command and composer.json will install the latest version of your package.
Composer.json (Respect Package)
{
"require": {
"respect/validation": "dev-master"
}
}
Now run composer install will install the require package.
For further packages
{
"require": {
"respect/validation": "dev-master",
"doctrine/orm": "2.*"
}
}
Now run update composer update it will download the doctrine/orm as well.
I see there is already a question but it did not answer the question
How can I install a composer package into the /src dir?
How can I install a bundle in the /src directory?
Reason I would like to do this is for development and deployment, so
I don't have to check in Symfony's base code into my subversion repo
I could use Composer to deploy
Looking over the Composer docs some more I did come across this:
http://getcomposer.org/doc/04-schema.md#config
vendor-dir: Defaults to vendor. You can install dependencies into a
different directory if you want to.
Could I set this at a Bundle level? or is this for the overall install?
https://github.com/composer/composer/blob/master/res/composer-schema.json
I know this is late, but in case anyone is searching for an answer that I painstakingly (hours and hours) found: vendor-dir
The documentation says:
By setting this var you can make composer install the dependencies into a directory other than vendor
Example:
{
"config": {
"vendor-dir": "website/password/vendor/"
}
}
From this doc and this doc
Again, hope to save anyone else a couple hours.
{
"extra": {
"installer-paths": {
"sites/example.com/modules/{$name}": ["vendor/package"]
}
}
}
Read more.
If you find composer's custom installers too complex or rigid, and you can plan what types of systems you will be deploying to, you might consider using post-install scripts.
Here's an example that creates a symlink from a package installed under vendors to the location where it might be expected:
"scripts": {
"post-install-cmd": [
"test -d vendor/foo/bar && ln -s ../vendor/foo/bar lib/bar"
]
}
This will create a symlink at lib/bar/ pointing to vendor/foo/bar/.
I have implemented this composer plugin to install packages into user (custom) defined folders you can just include it in your composer.json, follow the example and tell me if you have more questions :)
https://github.com/mnsami/composer-custom-directory-installer
composer-custom-directory-installer
A composer plugin, to install differenty types of composer packages in custom directories outside the default composer default installation path which is in the vendor folder.
This is not another composer-installer library for supporting non-composer package types i.e. application .. etc. This is only to add the flexability of installing composer packages outside the vendor folder. This package only supports composer package types,
https://getcomposer.org/doc/04-schema.md#type
The type of the package. It defaults to library.
Package types are used for custom installation logic. If you have a package that needs some special logic, you can define a custom type. This could be a symfony-bundle, a wordpress-plugin or a typo3-module. These types will all be specific to certain projects, and they will need to provide an installer capable of installing packages of that type.
How to use
Include the composer plugin into your composer.json require section::
"require":{
"php": ">=5.3",
"mnsami/composer-custom-directory-installer": "1.1.*",
"monolog/monolog": "*"
}
In the extra section define the custom directory you want to the package to be installed in::
"extra":{
"installer-paths":{
"./monolog/": ["monolog/monolog"]
}
by adding the installer-paths part, you are telling composer to install the monolog package inside the monolog folder in your root directory.
As an added new feature, we have added more flexibility in defining your download directory same like the composer/installers, in other words you can use variables like {$vendor} and {$name} in your installer-path section:
"extra": {
"installer-paths": {
"./customlibs/{$vendor}/db/{$name}": ["doctrine/orm"]
}
}
the above will manage to install the doctrine/orm package in the root folder of your project, under customlibs.
Note
Composer type: project is not supported in this installer, as packages with type project only make sense to be used with application shells like symfony/framework-standard-edition, to be required by another package.