I’ve got a local PHP project (a website), and I want to use another project I’ve made (a tiny web framework) as a Composer package for the website project. I’m developing them in tandem, but want to keep them as separate projects; when I deploy the website, I want to use Composer to install the framework project as a package, just like I would with Guzzle or any other common Composer package.
The website project has the following composer.json
:
{
"repositories": [
{
"type": "path",
"url": "/local/path/to/framework/package"
"options": {
"symlink": true
}
}
],
"require": {
"my/framework": "dev-master",
"guzzlehttp/guzzle": "6.3.3"
}
}
In /local/path/to/framework/package/composer.json
I have:
{
"name": "my/framework",
"description": "A tiny framework.",
"autoload": {
"psr-4": {
"MyFramework\": "src"
}
}
}
I run php composer.phar update
and it sets up a symlink to the framework package in my website project. If I update code in the framework, it’s immediately available to the website code. This is great.
However, later on I want to deploy the website project to my web server. For a clean deployment, I have a deploy script that exports an archive copy of the appropriate branch of the website git repo, and then runs php composer.phar install
to make sure all the proper packages are installed. With the above config, the deploy script creates a symlink to the framework package, which is obviously no good when the deployment artifact is zipped up and scp’d out to the web server.
If I remove the symlink
option above, then I have to run php composer.phar update
every time I make any changes in the framework package, which is irritating since I’m developing the packages in tandem. But then on deploy, the package is copied in, rather than being symlinked in; this is good for deploy, except it always copies in the master
branch (because I specified dev-master
in composer.json
).
Is there a way to set up Composer so that I can have the convenience of a local symlinked package for development, but to let the deployment script get a clean copy of the framework package, without having to change composer.json
every time I want to deploy?
I also tried changing the repository type to vcs
instead of path
, but then Composer clones the framework package repository, and I really don’t need a clone of the repo in my local vendor/
tree, either during development or deployment. I just want to be able to have a symlinked tree (which gets me instant updates) during development, and have a clean package installed for deplotment.
I may have to resign myself to developing the framework project “properly,” that is, as a Composer package that I tag with actual release version numbers, and then update my website project to use a specific version of when it comes time for a deployment. I still haven’t figured out the easiest way to do that, though.
2
Answers
You can use Composer Studio plugin.
It uses a separate file for configuration and allows you to have symlinks in development and a regular Composer install for prod deploy, without touching
composer.json
.With it, your website
composer.json
will look like a regular file:And with
studio.json
in the root of the project, with the following content:you can tell the plugin where to locate
my/framework
. Studio will then symlink the packages from the provided paths.To have a regular install, just remove or rename
studio.json
, remove thevendor
folder andcomposer.lock
file and run the install again when deploying.I made a composer plugin to make it more easy to test packages.
It doesn’t require a configuration file, changing your composer.json and doesn’t change the upgrade behavior of
composer update
https://github.com/SanderSander/composer-link
It works as simple as calling
composer link ../path-to-package
to link the local package into your project.