Используйте PHP composer для клонирования репозитория git

112

Я пытаюсь использовать композитор для автоматического клонирования репозитория git из github, которого нет в packagist, но он не работает, и я не могу понять, что я делаю не так.

Думаю, мне нужно включить его в "репозитории" вот так:

"repositories": [
    {
        "url": "https://github.com/l3pp4rd/DoctrineExtensions.git",
        "type": "git"
    }
],

а затем, вероятно, перечислите его в разделе «Требуется». Он должен быть похож на этот пример, но не работает. Это просто дает такую ​​ошибку:

Ваши требования не могут быть решены с помощью устанавливаемого набора пакетов.

Кто-нибудь уже пробовал сделать что-то подобное?

Мартин
источник

Ответы:

110

На момент написания статьи в 2013 году это был один из способов сделать это. Композитор добавлена поддержка более эффективных способов: См @igorw «s ответ

У ВАС ЕСТЬ Хранилище?

Composer поддерживает Git, Mercurial и SVN.

У ВАС ЕСТЬ ДОСТУП ДЛЯ ЗАПИСИ В ХРАНИЛИЩЕ?

Да?

ЕСТЬ ЛИ В РЕПОЗИТОРИИ composer.jsonФАЙЛ

Если у вас есть репозиторий, в который вы можете писать: Добавьте composer.jsonфайл или исправьте существующий, и НЕ используйте решение ниже.

Перейти к @igorw «s ответ

ИСПОЛЬЗУЙТЕ ЭТО ТОЛЬКО ЕСЛИ У ВАС НЕТ РЕПОЗИТОРИЯ
ИЛИ ЕСЛИ В РЕПОЗИТОРИИ НЕТ composer.jsonИ ВЫ НЕ МОЖЕТЕ ДОБАВИТЬ ЕГО

Это переопределит все, что Composer может прочитать из исходного репозитория composer.json, включая зависимости пакета и автозагрузку.

Использование packageшрифта переложит на вас бремя правильного определения всего. Более простой способ - иметь composer.jsonфайл в репозитории и просто использовать его.

Это решение действительно только для тех редких случаев, когда у вас есть заброшенная загрузка ZIP, которую вы не можете изменить, или репозиторий, который вы можете только читать, но он больше не поддерживается.

"repositories": [
    {
        "type":"package",
        "package": {
          "name": "l3pp4rd/doctrine-extensions",
          "version":"master",
          "source": {
              "url": "https://github.com/l3pp4rd/DoctrineExtensions.git",
              "type": "git",
              "reference":"master"
            }
        }
    }
],
"require": {
    "l3pp4rd/doctrine-extensions": "master"
}
Майк Граф
источник
7
Замена репозитория VCS репозиторием пакетов - плохая идея. У целевого репо уже есть репо composer.json, поэтому используйте репо vcs. В вашем примере также нарушается автозагрузка и игнорируется расширение branch-alias.
igorw
1
@igorw, пожалуйста, дайте ссылку на эту информацию, чтобы я и другие могли понять разницу? Спасибо.
Майк Граф,
5
Как объяснено на странице репозиториев, репозиторий пакета должен включать всю информацию. Если вы не добавите autoloadполе, оно не будет включено. В основном вам нужно скопировать и вставить всю информацию из composer.jsonопределения репо. Репозиторий VCS получает эту информацию напрямую из VCS. Преимущества branch-aliasописаны в документации по псевдонимам и в моем блоге .
igorw
2
Почему за это до сих пор голосуют? Документы композитора даже явно заявляют, что следует избегать репозиториев пакетов. Пожалуйста, прекратите поощрять плохие практики.
igorw
1
Что вы посоветуете мне поменять тогда?
Майк Граф,
147

Этот пакет на самом деле доступен через упаковщиков . В этом случае вам не нужно настраивать определение репозитория. Просто убедитесь, что вы добавили require(который всегда нужен) с подходящим ограничением версии.

В общем, если пакет доступен на packagist, не добавляйте репозиторий VCS. Это просто замедлит процесс.


Для пакетов, которые недоступны через packagist, используйте репозиторий VCS (или git), как показано в вашем вопросе. Когда вы это сделаете, убедитесь, что:

  • Поле "репозитории" указывается в корневом composer.json (это поле только для root, определения репозиториев из необходимых пакетов игнорируются)
  • Определение репозиториев указывает на действительный репозиторий VCS
  • Если тип - «git» вместо «vcs» (как в вашем вопросе), убедитесь, что это на самом деле репозиторий git.
  • У вас есть requireпакет для рассматриваемого пакета
  • Ограничение в requireсовпадениях с версиями, предоставленными репозиторием VCS. Вы можете использовать composer show <packagename>для поиска доступных версий. В этом случае ~2.3будет неплохой вариант.
  • Имя в поле requireсовпадает с именем в пульте дистанционного управления composer.json. В данном случае это так gedmo/doctrine-extensions.

Вот пример, composer.jsonкоторый устанавливает тот же пакет через репозиторий VCS:

{
    "repositories": [
        {
            "url": "https://github.com/l3pp4rd/DoctrineExtensions.git",
            "type": "git"
        }
    ],
    "require": {
        "gedmo/doctrine-extensions": "~2.3"
    }
}

Документы репозитория VCS достаточно хорошо все это объясняют.


Если есть репозиторий git (или другой VCS) с composer.jsonдоступным, не используйте репозиторий «пакетов». Репозитории пакетов требуют, чтобы вы предоставили все метаданные в определении, и полностью игнорируют любые composer.jsonприсутствующие в предоставленных dist и source. У них также есть дополнительные ограничения, такие как запрет на правильные обновления в большинстве случаев.

Избегайте репозиториев пакетов ( см. Также документацию ).

игорь
источник
1
Оуу, спасибо! Я не нашел его, потому что думал, что он будет вызван после репозитория git DoctrineExtensions.
Мартин
2
Всегда смотрите на имя, данное в composer.json.
igorw
16
-1 Почему это помечено как правильный ответ? Это действительно решило проблему OP, но Кларенс и Майк Граф дали ответы на более общую проблему, стоящую за ним. Маловероятно, что кто-то, кто ищет способ включить проекты, не связанные с упаковкой, захочет включить DoctrineExtensions.
aefxx
2
@aefxx Мой ответ делает на самом деле объяснить общую общую проблему, которая является то , что requireполе должно быть указано.
igorw
6
The VCS repo docs explain all of this quite well.... какие?
hek2mgl
47

Вы можете включить репозиторий git в composer.json следующим образом:

"repositories": [
{
    "type": "package",
    "package": {
        "name": "example-package-name", //give package name to anything, must be unique
        "version": "1.0",
        "source": {
            "url": "https://github.com/example-package-name.git", //git url
            "type": "git",
            "reference": "master" //git branch-name
        }
    }
}],
"require" : {
  "example-package-name": "1.0"
}
Эдрис
источник
1
Как объяснено в других ответах выше: если у вас есть репозиторий, добавьте composer.jsonфайл, если это вообще возможно.
Sven
@Sven ... потому что иначе нельзя указать конкретный коммит?
Cees Timmerman
Спасибо, что поделились, сэкономили мне часы :)
metamaker
Это настроено так, чтобы быть общим, но в остальном в основном это простая копия ответа Майка Графа, поэтому я не уверен, что общее лучше, чем просмотр конкретной библиотеки в вопросе в качестве примера.
FantomX1
6

Просто скажите композитору использовать исходный код, если он доступен:

composer update --prefer-source

Или:

composer install --prefer-source

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

Отказ от ответственности: я думаю, что могу ответить на немного другой вопрос, но это было то, что я искал, когда нашел этот вопрос, поэтому я надеюсь, что он будет полезен и другим.

Если Composer не знает, где находится репозиторий проекта, или у проекта нет подходящего composer.json, ситуация немного сложнее, но другие уже ответили на такие сценарии.

Йозеф Куфнер
источник
3

Я столкнулся со следующей ошибкой: The requested package my-foo/bar could not be found in any version, there may be a typo in the package name.

Если вы создаете другое репо, чтобы внести свои собственные изменения, у вас будет новый репозиторий.

Например:

https://github.com/foo/bar.git
=>
https://github.com/my-foo/bar.git

Новый URL-адрес должен войти в раздел ваших репозиториев вашего composer.json.

Помните, что если вы хотите ссылаться на свою вилку, как my-foo/barв разделе требований, вам придется переименовать пакет в composer.jsonфайле внутри вашего нового репо.

{
    "name":         "foo/bar",

=>

{
    "name":         "my-foo/bar",

Если вы только что создали форк, самый простой способ сделать это - отредактировать его прямо в github.

Генри
источник
Обратите внимание, что имя пакета никоим образом не отражает URL-адрес, по которому вы можете прочитать репозиторий! Между ними нет автоматической связи, оба могут быть выбраны независимо. Единственная важная информация о Composer - это имя, записанное nameвнутри атрибута composer.json.
Свен
2

В моем случае я использую Symfony2.3.x, и параметр минимальной стабильности по умолчанию "стабильный" (что хорошо). Я хотел импортировать репо не в packagist, но имел ту же проблему: «Ваши требования не могут быть решены для устанавливаемого набора пакетов». Оказалось, что composer.json в репозитории, который я пытался импортировать, использует "dev" с минимальной стабильностью.

Поэтому, чтобы решить эту проблему, не забудьте проверить файл minimum-stability. Я решил это, потребовав dev-masterверсию, masterа не указанную в этом сообщении .

Маг
источник
4
У меня была такая же проблема, о которой здесь говорится . Если у вас есть явная ссылка (например, git commit), похоже, вы можете сделать что-то вроде"dev-master#4536bbc166ada96ff2a3a5a4b6e636b093103f0e" .
Blaskovicz
1

Если вы хотите использовать composer.jsonиз GitHub, вы должны посмотреть этот пример (в разделе VCS).

Раздел пакетов предназначен для пакетов, у которых нет composer.json . Однако вы тоже не последовали этому примеру, иначе он бы тоже сработал. Прочтите, что там говорится о репозиториях пакетов:

По сути, вы определяете ту же информацию, которая включена в репозиторий композитора packages.json, но только для одного пакета. Опять же, минимальные обязательные поля - это имя, версия и либо dist, либо source.

Кларенс
источник
0

Я пытаюсь присоединиться к упомянутым здесь решениям, поскольку есть некоторые важные моменты, которые необходимо перечислить.

  1. Как упоминалось в ответе @ igorw, URL-адрес репозитория в этом случае должен быть указан в файле composer.json, однако, поскольку в обоих случаях composer.json должен существовать (в отличие от 2-го способа @Mike Graf), публикация его в Packagist является не сильно отличается (кроме того, Github в настоящее время предоставляет услуги пакетов как пакеты npm), разница только вместо того, чтобы буквально вводить URL-адрес в интерфейсе packagist после регистрации.

  2. Более того, у него есть недостаток, заключающийся в том, что он не может полагаться на внешнюю библиотеку, которая использует этот подход, поскольку рекурсивные определения репозитория не работают в Composer. Кроме того, из-за этого, похоже, в нем есть "ошибка", поскольку рекурсивное определение не удалось в зависимости, повторное определение репозиториев явно в корне кажется недостаточным, но также все зависимости из пакетов должны будут быть уточненным.

С файлом композитора (ответ дан igorw 18 окт.

{
    "repositories": [
        {
            "url": "https://github.com/l3pp4rd/DoctrineExtensions.git",
            "type": "git"
        }
    ],
    "require": {
        "gedmo/doctrine-extensions": "~2.3"
    }
}

Без файла композитора (ответил Майк Граф 23 янв.

"repositories": [
    {
        "type":"package",
        "package": {
          "name": "l3pp4rd/doctrine-extensions",
          "version":"master",
          "source": {
              "url": "https://github.com/l3pp4rd/DoctrineExtensions.git",
              "type": "git",
              "reference":"master"
            }
        }
    }
],
"require": {
    "l3pp4rd/doctrine-extensions": "master"
}
FantomX1
источник