Possible solutions
- Implementing it inside your project, maybe in the library or source folder. Would work, but if you want to publish it [on packagist.org or somewhere else] as a separate package later on, you will make extra work for yourself.
- Publish the non-working package on packagist and push changes to you VCS. This is a really slow work process, as it requires you to push and do a composer update to see the changes.
- The other way™
The other way
I’ve found that setting up a repository with a relative file system reference is the easiest way. This way, you can have your dependency separate from the application and getting changes in the dependency is as simple as running composer update.
Example
Given the following folder structure;
1 2 3 4 5 6 | / project/ composer.json package/ composer.json src/Foobar.php |
package/composer.json
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | [code language="js"] { "name": "kbrabrand/package", "description": "My test package", "license": "MIT", "authors": [ { "name": "Kristoffer Brabrand", "email": "kristoffer@brabrand.no" } ], "autoload": { "psr-0": { "KBrabrand": "src" } } } [/code] |
This simply defines a composer compatible package and is pretty straight forward. Now, let’s take a look at the composer.json file for the project, where the “magic” happens.
project/composer.json
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | [code language="js"] { "name": "kbrabrand/project", "description": "Test project", "license": "MIT", "authors": [ { "name": "Kristoffer Brabrand", "email": "kristoffer@brabrand.no" } ], "minimum-stability": "dev", "repositories": [ { "type": "vcs", "url": "../package" } ], "require": { "kbrabrand/package": "*" } } [/code] |
The repositories part of the composer file is the only thing special. There are several repository types, but the VCS type refers to some sort of version control resource (locally or externally). The repository portion of the composer schema documentation notes that this could be svn, git or mercurial (hg).
For this example I’ve used a relative local path and git. As shown in the composer doumentation, using absolute paths or external URLs is also possible.
Running composer
1 2 3 4 5 6 7 8 | [code language="bash"] $ cd package $ git init Initialized empty Git repository in /development/package/.git/ $ git add * $ git commit -m "Initial commit" [/code] |
At this point, a local git repo exists in the package folder and is now ready for inclusion in the project with composer.
1 2 3 4 5 6 7 8 9 10 11 | [code language="bash"] $ cd ../project $ composer install Loading composer repositories with package information Installing dependencies (including require-dev) - Installing kbrabrand/package (dev-master 4a111b4) Cloning 4a111b483843e75a3cb0ee794c0b9eaf0b75b395 Writing lock file Generating autoload files [/code] |
That’s it! After this point, whenever a change is made to the package, commit your change and do a composer update. Like this;
1 2 3 4 5 6 | [code language="bash"] $ cd ../project $ git commit -am "Changes" $ cd ../project $ composer update [/code] |
Pro tip from the comment field
Gauthier Delamarre pointed out that it’s possible to specify the repository definition from composer.json into the users composer config. This is done by adding repository block to the file ~/.composer/config.json. As Gauthier points out, the benefit from doing it this way is that you won’t need to keep you environment specific paths for the repo in the composer.json, which allows you to commit and push it without thinking about messing everything up for other devs.
More documentation on the “home config”: https://getcomposer.org/doc/03-cli.md#composer-home-config-json