Композитор требует локального пакета

108

У меня есть пара библиотек [Foo и Bar], которые я разрабатываю совместно, но все еще технически отдельные вещи. Раньше я просто переопределил автозагрузчик, чтобы он понравился "Foo\\": "../Foo/src", но теперь, когда я добавил зависимость Guzzle к Foo, Bar переворачивает ее крышку, потому что это не одна из его зависимостей.

Структура каталога:

/home/user/src/
    Foo/
        src/
            FooClient.php
        composer.json
    Bar/
        src/
            BarClient.php
        composer.json

Заявление теоретической автозагрузки: [в Bar / composer.json]

"require": {
    "local": "../Foo/composer.json"
}

Пример кода:

require('vendor/autoload.php');

$f = new \Bar\BarClient(new \Foo\FooClient());

Как я могу решить эту проблему без настройки локального репозитория Composer? Я хочу сохранить их как отдельные пакеты, просто чтобы один требует другого, и поэтому обрабатывает зависимости другого.

пост-ответ редактировать:

Благодаря infomaniac я сделал следующее:

Инициализировал репозиторий git:

cd ~/src/Foo && git init && echo -e "vendor\ncomposer.lock" > .gitignore && git add ./ && git commit -m "Initial Commit"

Добавлен конфиг композитора:

"require": {
    "sammitch/foo": "dev-master"
},
"repositories": [{
    "type": "vcs",
    "url": "/home/sammitch/src/Foo"
}],

А потом composer update!

Саммитч
источник
Как этот json определяет идентичность между ссылкой на «sammitch / foo» и адресом «/ home / sammitch / src / Foo»? Это следует какой-то конвенции?
Себастьян Гриньоли, 03
@ SebastiánGrignoli sammitch/foo- это имя пакета, которое буквально не имеет никакого отношения к тому, где он находится. Создает список доступных пакетов на основе его настроенных репозиториев, в этом случае извлекает composer.json из указанного локального репозитория git, а затем composer обрабатывает все остальное. sammitch/fooПакет копируются в текущем приложении vendorпапки так же , как любой другой пакет.
Sammitch 03
О, я думаю, теперь я понял. Это просто настраиваемое репо, как в APT, которое может содержать пакет sammit / foo. Я правильно понял?
Себастьян Гриньоли, 04
@ SebastiánGrignoli, ты готов
Sammitch

Ответы:

38

Вы можете использовать функцию репозиториев Composer

https://getcomposer.org/doc/05-repositories.md#loading-a-package-from-a-vcs-repository

Вместо использования формата http укажите путь к файлу на диске.

Дэнни Коппинг
источник
12
getcomposer.org/doc/05-repositories.md#path также потенциально полезен и, похоже, лучше работает для меня.
Jasmine Hegman
@JasmineHegman действительно! Я тоже использовал это - отлично
подходит
Чтобы сделать это хорошим ответом, вы должны показать, КАК это сделать, а не просто назвать функцию и связать документы (хотя это тоже важно). В других ответах ниже приведены соответствующие примеры.
rudolfbyker
174

Способ связи с локальным, в процессе развития пакета сначала добавить в вашем основном проекте этого хранилища , как это:composer.json

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

Вам также необходимо либо указать версию, указанную в вашем пакете разработки, composer.jsonлибо, как я это делаю, пакет должен использовать @dev, например:

composer require "vendorname/packagename @dev"

Он должен выводить:

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

Команда @devв команде require важна, композитор использует ее для получения исходного кода и символической ссылки на ваш новый пакет.

Это флаг стабильности, добавленный к ограничению версии (см. Ссылку на пакет ).

Это позволяет вам еще больше ограничить или расширить стабильность пакета за пределы параметра минимальной стабильности .

Флаги минимальной стабильности:

Возможные варианты (в порядке устойчивости) являются dev, alpha, beta, RCи stable.

Дхирадж Гупта
источник
8
Обратите внимание, что композитор не разрешает вам указывать путь, который находится в том же каталоге, что и composer.json.
MaPePeR
Интересный момент, MaPePeR я этого не знал. Однако я полагаю, что все веб-фреймворки уже позаботились об этом, поместив все зависимости в папку «vendor»? По крайней мере, Yii2 делает это.
Дирадж Гупта
3
composer require "vendorname/packagename @dev"переводится "require":{ "vendorname/packagename": "@dev" }в composer.json вашего приложения, если вы хотите запустить установку композитора
Sir_Faenor
2
Пожалуйста, добавьте это: composer config repositories.local path / full / или / relative / path / to / development / package как правильный способ добавления репозиториев
Basil
1
Можно ли сказать композитору, чтобы он установил его в папку vendors для prod вместо создания символической ссылки?
BenjaminH
7

Потратив некоторое время, я наконец понял решение. Возможно, это будет полезно для кого-то вроде меня и сэкономит вам время, поэтому я решил, что должен поделиться этим здесь.

Предполагая, что у вас есть следующая структура каталогов (относительно корневого каталога вашего проекта):

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

В этом примере вы можете увидеть , что localпапка предназначена для вложенных проектов вашей компании, например bar-project. Но вы можете настроить любую другую раскладку, если хотите.

У каждого проекта должен быть свой собственный composer.jsonфайл, например root composer.jsonи local/bar-project/composer.json. Тогда их содержимое будет следующим:

(корень 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/"
    }
  }
}

Если, например, вы хотите разместить каждый проект в отдельном дочернем каталоге, выполните следующие действия:

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

- тогда вам нужно сделать ссылку на соответствующий каталог в repositoriesразделе:

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

После этого не забудьте composer update(или даже так, rm -rf vendor && composer update -vкак предлагают документы )! Под капотом композитор создаст vendor/your-company/bar-projectсимволическую ссылку, нацеленную на local/bar-project(или ../bar-projectсоответственно).

Предполагая, что вы public/index.phpпросто front controller, например:

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

Тогда ваш config/composition-root.phpбудет:

<?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();
почемуер
источник
1
"rm -rf vendor / company / package" важен
Alex83690
@ Alex83690, только если вы уже работали composer updateс подобным composer.jsonи, следовательно, вам нужно удалить предыдущую символическую ссылку, созданную композитором
почемуер