Use o PHP composer para clonar o git repo

111

Estou tentando usar o composer para clonar automaticamente um repositório git do github que não está no packagist, mas não está funcionando e não consigo descobrir o que estou fazendo de errado.

Acho que tenho que incluí-lo entre os "repositórios" assim:

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

e provavelmente listá-lo na seção "requer". Deve ser semelhante a este exemplo, mas não funciona. Só dá este erro:

Seus requisitos não puderam ser resolvidos para um conjunto de pacotes instaláveis.

Alguém já tentou fazer algo assim?

Martin
fonte

Respostas:

109

No momento da redação, em 2013, essa era uma maneira de fazer isso. O Composer adicionou suporte para maneiras melhores: Veja a resposta de @igorw

VOCÊ TEM UM REPOSITÓRIO?

Git, Mercurial e SVN são suportados pelo Composer.

VOCÊ TEM ACESSO PARA ESCREVER AO REPOSITÓRIO?

Sim?

O REPOSITÓRIO TEM UM composer.jsonARQUIVO

Se você tiver um repositório, pode gravar: Adicione um composer.jsonarquivo ou corrija o existente e NÃO use a solução abaixo.

Vá para a resposta de @igorw

USE ISSO SOMENTE SE VOCÊ NÃO TIVER UM REPOSITÓRIO
OU SE O REPOSITÓRIO NÃO TEM UMcomposer.json E VOCÊ NÃO PODE ADICIONÁ-LO

Isso substituirá tudo que o Composer possa ler do repositório original composer.json, incluindo as dependências do pacote e o carregamento automático.

Usar o packagetipo transferirá o fardo de definir tudo corretamente para você. A maneira mais fácil é ter um composer.jsonarquivo no repositório e apenas usá-lo.

Esta solução é realmente apenas para os raros casos em que você tem um download de ZIP abandonado que você não pode alterar, ou um repositório que você só pode ler, mas não é mais mantido.

"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"
}
Mike Graf
fonte
7
Substituir o repositório VCS por um repositório de pacotes é uma má ideia. O repo de destino já tem um composer.json, então use um repo vcs. Seu exemplo também interrompe o carregamento automático e ignora o branch-alias.
igorw
1
@igorw, você pode criar um link para essas informações para que eu e outros possamos entender a diferença? Obrigado.
Mike Graf de
5
Conforme explicado na página de repositórios, um repositório de pacote deve incluir todas as informações. Se você não adicionar o autoloadcampo, ele não será incluído. Basicamente, você precisa copiar e colar todas as informações composer.jsonna definição do repo. O repositório VCS busca essas informações diretamente do VCS. Os benefícios de branch-aliassão explicados no documento de aliases e em uma postagem de blog que escrevi .
igorw de
2
Por que isso ainda está sendo votado? A documentação do composer afirma explicitamente que os repositórios de pacotes devem ser evitados. Por favor, pare de encorajar práticas ruins.
igorw
1
O que você recomenda que eu mude então?
Mike Graf
146

Esse pacote na verdade está disponível através do packagist . Você não precisa de uma definição de repositório customizada neste caso. Apenas certifique-se de adicionar um require(que é sempre necessário) com uma restrição de versão correspondente.

Em geral, se um pacote estiver disponível no packagist, não adicione um repositório VCS. Isso só vai desacelerar as coisas.


Para pacotes que não estão disponíveis via packagist, use um repositório VCS (ou git), conforme mostrado em sua pergunta. Ao fazer isso, certifique-se de que:

  • O campo "repositórios" é especificado no root composer.json (é um campo apenas para root, as definições de repositório de pacotes necessários são ignoradas)
  • A definição de repositórios aponta para um repositório VCS válido
  • Se o tipo for "git" em vez de "vcs" (como em sua pergunta), certifique-se de que é de fato um repositório git
  • Você tem um requirepara o pacote em questão
  • A restrição no requirecorresponde às versões fornecidas pelo repositório VCS. Você pode usar composer show <packagename>para encontrar as versões disponíveis. Nesse caso ~2.3seria uma boa opção.
  • O nome no requirecorresponde ao nome no controle remoto composer.json. Nesse caso, é gedmo/doctrine-extensions.

Aqui está um exemplo composer.jsonque instala o mesmo pacote por meio de um repositório VCS:

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

Os documentos do repositório VCS explicam tudo isso muito bem.


Se houver um repositório git (ou outro VCS) composer.jsondisponível, não use um repositório de "pacote". Os repositórios de pacotes exigem que você forneça todos os metadados na definição e irão ignorar completamente qualquer composer.jsonpresente no dist e na fonte fornecidos. Eles também têm limitações adicionais, como não permitir atualizações adequadas na maioria dos casos.

Evite repositórios de pacotes ( veja também a documentação ).

igorw
fonte
1
Ouu, obrigado! Não o encontrei porque pensei que seria chamado após o repo git DoctrineExtensions.
Martin
2
Sempre olhe para o nome fornecido composer.json.
igorw
16
-1 Por que isso está marcado como a resposta correta? Com certeza resolveu o problema do OP, mas Clarence e Mike Graf deram respostas ao problema mais geral por trás dele. É altamente improvável que alguém procurando uma maneira de incluir projetos não-empacotadores queira incluir o DoctrineExtensions.
aefxx
2
@aefxx Minha resposta faz , de facto, também explicam o problema geral geral, o que é que o requirecampo deve ser especificado.
igorw
6
The VCS repo docs explain all of this quite well.... que?
hek2mgl
47

Você pode incluir o repositório git no composer.json desta forma:

"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"
}
Edris
fonte
1
Conforme explicado nas outras respostas acima: Se você tiver um repositório, adicione um composer.jsonarquivo se possível.
Sven
@Sven ... porque é impossível especificar um commit específico de outra forma?
Cees Timmerman
Obrigado por compartilhar, economizou horas :)
metamaker
Isso foi ajustado para ser geral, mas basicamente uma cópia simples da resposta de Mike Graf, então não tenho certeza se geral é melhor do que ver uma determinada biblioteca na questão como exemplo.
FantomX1
6

Basta dizer ao compositor para usar a fonte, se disponível:

composer update --prefer-source

Ou:

composer install --prefer-source

Então você obterá pacotes como repositórios clonados ao invés de tarballs extraídos, então você pode fazer algumas mudanças e confirmá-los de volta. Claro, supondo que você tenha permissões de gravação / envio para o repositório e o Composer saiba sobre o repositório do projeto.

Isenção de responsabilidade: acho que posso responder uma pergunta um pouco diferente, mas era isso que eu estava procurando quando encontrei esta pergunta, então espero que seja útil para outras pessoas também.

Se o Composer não souber onde está o repositório do projeto, ou se o projeto não tiver o composer.json adequado, a situação é um pouco mais complicada, mas outros já responderam a tais cenários.

Josef Kufner
fonte
3

Eu estava encontrando o seguinte erro: The requested package my-foo/bar could not be found in any version, there may be a typo in the package name.

Se estiver bifurcando outro repositório para fazer suas próprias alterações, você acabará com um novo repositório.

Por exemplo:

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

O novo url precisará ir para a seção de repositórios do composer.json.

Lembre-se, se quiser referir-se ao fork como my-foo/barna seção require, você terá que renomear o pacote no composer.jsonarquivo dentro do seu novo repo.

{
    "name":         "foo/bar",

=>

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

Se você acabou de fazer o fork, a maneira mais fácil de fazer isso é editá-lo diretamente no github.

Henry
fonte
Observe que o nome do pacote não reflete de forma alguma a URL de onde você pode ler o repositório! Não existe uma ligação automática entre os dois, ambos podem ser escolhidos independentemente. A única informação relevante sobre o Composer é o nome escrito no nameatributo dentro composer.json.
Sven
2

No meu caso, eu uso Symfony2.3.xe o parâmetro de estabilidade mínima é por padrão "estável" (o que é bom). Eu queria importar um repositório que não estava no packagist, mas tive o mesmo problema "Seus requisitos não puderam ser resolvidos para um conjunto de pacotes instaláveis.". Parece que o composer.json no repositório que tentei importar usa um "dev" de estabilidade mínima.

Portanto, para resolver esse problema, não se esqueça de verificar o minimum-stability. Eu resolvi isso exigindo uma dev-masterversão em vez de masterconforme declarado neste post .

Mago
fonte
4
Eu tive o mesmo problema, que é discutido aqui . Se você tiver uma referência explícita (como um git commit), parece que você pode fazer algo como "dev-master#4536bbc166ada96ff2a3a5a4b6e636b093103f0e".
Blaskovicz
1

Se você quiser usar um composer.jsondo GitHub, consulte este exemplo (na seção VCS).

A seção do pacote é para pacotes que não possuem o composer.json. No entanto, você não seguiu esse exemplo também ou ele também teria funcionado. Leia o que diz sobre repositórios de pacotes:

Basicamente, você define as mesmas informações que estão incluídas no repositório do composer packages.json, mas apenas para um único pacote. Novamente, os campos mínimos obrigatórios são nome, versão e dist ou fonte.

Clarence
fonte
0

Tento juntar as soluções mencionadas aqui, pois há alguns pontos importantes que precisam ser listados.

  1. Conforme mencionado na resposta de @ igorw, a URL para o repositório deve ser, nesse caso, especificada no arquivo composer.json, no entanto, uma vez que em ambos os casos o composer.json deve existir (ao contrário da 2ª forma de @Mike Graf) publicando-o no Packagist é não muito diferente (além disso, o Github atualmente fornece serviços de pacotes como pacotes npm), apenas a diferença em vez de inserir literalmente a URL na interface do packagist depois de se inscrever.

  2. Além disso, tem a desvantagem de não poder contar com uma biblioteca externa que usa essa abordagem, pois as definições de repositório recursivo não funcionam no Composer. Além disso, devido a isso, parece haver um "bug" nele, uma vez que a definição recursiva falhou na dependência, reespecificar os repositórios explicitamente na raiz não parece ser suficiente, mas também todas as dependências dos pacotes teriam que ser especificado novamente.

Com um arquivo do compositor (respondido em 18 de outubro de 12 às 15:13 igorw)

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

Sem um arquivo do compositor (respondido em 23 de janeiro de 13 às 17:28 Mike Graf)

"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
fonte