Use Composer with Local Packages

Sometimes when I am creating or modifying a package intended to by included as a composer dependency, I want to be able to test out the composability of it. This means I want to make sure the class autoloads are mapped properly and everything is set up in a way that the composer.json file is read correctly and works the way I want it to.

Traditionally, the way to do this is to push your changes to github or some other publicly accessible repository so that it is available to be pulled down by composer. What happens is when you end up with errors or undesired behavior due to changes you need to make to the composer.json file, you'll end up with a bunch of commits like "Fixing the composer.json file."

Wouldn't it be nice if I can just tell composer to look on my disk for this package and install it from there please. Well you can!

The Package's Composer.json File

So, let's assume we have a regular package composer.json file. It describes the name of the package and the autoload strategy, etc. Whether you are editing an existing package and want to ensure the composer pieces work well, or if you are creating a new package from scratch that you want to test out completely locally first, you will basically have a regular package composer.json file.

For example, let's say we have the following package composer file:

{
    "name": "coolvendor/package",
    "description": "My test package",
    "license": "MIT",
    "autoload": {
        "psr-0": {
            "Coolvendor": "src"
        }
    }
}

In the example we're assuming the package is on a file in your filesystem called coolvendor-package.

The Project Composer.json File

In your project (the directory where you want to consume the package from composer), you need to define the location of the dependency. The trick is to define the path to the local package as a repository definition in your project's composer.json file.

{
    "minimum-stability": "dev",
    "repositories": [
        {
            "type": "vcs",
            "url": "/home/yourname/src/coolvendor-package"
        }
    ],
    "require": {
        "coolvendor/package": "*"
    }
}

What we're doing here is telling composer to look at the repository on the filesystem to also find packages. With the type of vcs you are telling composer that it will find a version control repository (git, hg, svn) at the location specified.

You can also use relative paths (e.g. ../coolvendor-package) if that works for your situation.

Remember that the package should be a git repository and the version that you want to target needs to be committed to the repository.

Composer Install

Now you can run composer install in your project directory and you'll get the version from your local package repository.

$ composer install
Loading composer repositories with package information
Updating dependencies (including require-dev)
  - Installing coolvendor/package (dev-master 40c12b6)
    Cloning 40c12b675ff1e8d0e9ce8ecf74d2e7deb441ad6e from cache

Writing lock file
Generating autoload files

You can check the version that it pulled in to ensure it was the git hash you expected (the one with your latest changes).

Ignoring Packagist.org

If the package and version you are targeting also already exists on packagist.org, composer will use that one. To ignore packagist, add the packagist disable directive in the repositories section of the composer.json file.

{
    "minimum-stability": "dev",
    "repositories": [
        {
            "packagist.org": false
        },
        {
            "type": "vcs",
            "url": "/home/yourname/src/coolvendor-package"
        }
    ],
    "require": {
        "coolvendor/package": "*"
    }
}

This directive is described in the composer documentation on disabling packagist.

Clear Your Composer Cache

If you already have composed in the package that you are now trying to test with a local version, you may have to remove it from your machine's composer cache.

On a Unix machine, you can find the composer cache files in ~/.composer/cache. You can either remove the entire cache with rm -rf ~/.composer/cache or you can target the specific location by drilling down into the folders in the cache directory and deleting the one that corresponds to the vendor and package name.

Targeting a Branch

If you committed your test package updates to a specific branch, you can specify the branch name in the version of the package you are targeting as dev-[branchname].

For example, if you committed your changes to the package that you want to test to a branch called bugfix-28, then you target that in your composer.json file as dev-bugfix-28.

{
    "minimum-stability": "dev",
    "repositories": [
        {
            "type": "vcs",
            "url": "/home/yourname/src/coolvendor-package"
        }
    ],
    "require": {
        "coolvendor/package": "dev-bugfix-28"
    }
}