Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Composer require local package

People also ask

How do I use composer locally?

This is the easiest way to get Composer set up on your machine. Download and run Composer-Setup.exe. It will install the latest Composer version and set up your PATH so that you can call composer from any directory in your command line. Note: Close your current terminal.

Where does composer get packages from?

Composer downloads directly from the source, e.g. Packagist only knows those source and tells your composer instance where to go. It does this by downloading a bunch of json files from Packagist.org that have all the infos.

What is composer package?

Package# Composer is a dependency manager. It installs packages locally. A package is essentially a directory containing something. In this case it is PHP code, but in theory it could be anything.


The way to link to a local, in-development package is to first add in your main project's composer.json a repository, like this:

"repositories": [
    {
        "type": "path",
        "url": "/full/or/relative/path/to/development/package"
    }
]

You also need to either have a version specified in your development package's composer.json or the way I do it is to require the package using @dev, like this:

composer require "vendorname/packagename @dev"

It should output:

- Installing vendor/packagename (dev-develop)
Symlinked from /full/or/relative/path/to/development/package

The @dev in the require command is important, composer uses this to pickup the source code and symlink it to your new package.

It's a stability flag added to the version constraint (see package link).

These allow you to further restrict or expand the stability of a package beyond the scope of the minimum-stability setting.

The minimum-stability flags are:

Available options (in order of stability) are dev, alpha, beta, RC, and stable.


You can use Composer's repositories feature

https://getcomposer.org/doc/05-repositories.md#path

{
  "repositories": [
    {
        "type": "path",
        "url": "../../packages/my-package"
    }
  ],
  "require": {
    "my/package": "*"
  }
}

Instead of using the http format, specify a file path on disk.


After spending some time, I finally understood the solution. Maybe it'll be useful for someone like me and will save you some time, so I've decided that I have to share it here.

Assuming that you have the following directory structure (relative to your project root directory):

composer.json
config
config/composition-root.php
local
local/bar-project
local/bar-project/composer.json
local/bar-project/src
local/bar-project/src/Bar.php
public
public/index.php
src
src/Foo.php

In this example you may see that the local folder is meant for nested projects of your company, e.g. bar-project. But you could configure any other layout, if you wish.

Each project has to have its own composer.json file, e.g. root composer.json and local/bar-project/composer.json. Then their contents would be as follows:

(root composer.json:)

{
  "name": "your-company/foo-project",
  "require": {
    "php": "^7",
    "your-company/bar-project": "@dev"
  },
  "autoload": {
    "psr-4": {
      "YourCompany\\FooProject\\": "src/"
    }
  },
  "repositories": [
    {
      "type": "path",
      "url": "local/bar-project"
    }
  ]
}

(local/bar-project/composer.json:)

{
  "name": "your-company/bar-project",
  "autoload": {
    "psr-4": {
      "YourCompany\\BarProject\\": "src/"
    }
  }
}

If, for example, you wish to locate each project in a separate sibling directory, as follows:

your-company
your-company/foo-project
your-company/foo-project/composer.json
your-company/foo-project/config
your-company/foo-project/config/composition-root.php
your-company/foo-project/public
your-company/foo-project/public/index.php
your-company/foo-project/src
your-company/foo-project/src/Foo.php
your-company/bar-project
your-company/bar-project/composer.json
your-company/bar-project/src
your-company/bar-project/src/Bar.php

- then you need to link to respective directory in repositories section:

  "repositories": [
    {
      "type": "path",
      "url": "../bar-project"
    }
  ]

After that don't forget to composer update (or even rm -rf vendor && composer update -v as the docs suggest)! Under the hood, composer will create a vendor/your-company/bar-project symlink that targets to local/bar-project (or ../bar-project respectively).

Assuming that your public/index.php is just a front controller, e.g.:

<?php
require_once __DIR__ . '/../config/composition-root.php';

Then your config/composition-root.php would be:

<?php

declare(strict_types=1);

use YourCompany\BarProject\Bar;
use YourCompany\FooProject\Foo;

require_once __DIR__ . '/../vendor/autoload.php';

$bar = new Bar();
$foo = new Foo($bar);
$foo->greet();