Usa PHP Composer per clonare git repo


111

Sto cercando di utilizzare composer per clonare automaticamente un repository git da github che non è in packagist ma non funziona e non riesco a capire cosa sto facendo di sbagliato.

Penso di doverlo includere tra i "repository" in questo modo:

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

e quindi probabilmente elencalo nella sezione "require". Dovrebbe essere simile a questo esempio ma non funziona. Dà solo questo errore:

Non è stato possibile risolvere i tuoi requisiti in un set di pacchetti installabili.

Qualcuno ha già provato a fare qualcosa di simile?

Risposte:


110

Al momento in cui scrivo nel 2013, questo era un modo per farlo. Composer ha aggiunto il supporto per modi migliori: vedi la risposta di @igorw

HAI UN REPOSITORY?

Git, Mercurial e SVN sono supportati da Composer.

HAI L'ACCESSO IN SCRITTURA AL REPOSITORY?

Sì?

IL REPOSITORY HA UN composer.jsonFILE

Se disponi di un repository in cui puoi scrivere: Aggiungi un composer.jsonfile o correggi quello esistente e NON utilizzare la soluzione seguente.

Vai a @igorw 's risposta

UTILIZZA QUESTO SOLO SE NON HAI UN REPOSITORY
O SE IL REPOSITORY NON HA UN composer.jsonE NON PUOI AGGIUNGERLO

Questo sovrascriverà tutto ciò che Composer potrebbe essere in grado di leggere dal repository originale composer.json, comprese le dipendenze del pacchetto e il caricamento automatico.

L'utilizzo del packagetipo trasferirà su di te l'onere di definire correttamente tutto. Il modo più semplice è avere un composer.jsonfile nel repository e usarlo.

Questa soluzione è davvero solo per i rari casi in cui hai un download ZIP abbandonato che non puoi modificare, o un repository che puoi solo leggere, ma non è più mantenuto.

"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
Sostituire il repository VCS con un repository di pacchetti è una cattiva idea. Il repository di destinazione dispone già di un repository composer.json, quindi utilizza un repository vcs. Il tuo esempio interrompe anche il caricamento automatico e ignora il file branch-alias.
igorw

1
@igorw puoi collegarti a queste informazioni in modo che io e gli altri possiamo capire la differenza? Grazie.
Mike Graf

5
Come spiegato nella pagina dei repository, un repository di pacchetti deve includere tutte le informazioni. Se non aggiungi il autoloadcampo, non verrà incluso. Fondamentalmente è necessario copiare e incollare tutte le informazioni dalla composer.jsondefinizione del repository. Il repository VCS recupera le informazioni direttamente da VCS. I vantaggi di branch-aliassono spiegati nel documento alias e in un post sul blog che ho scritto .
igorw

2
Perché questo viene ancora votato? I documenti del compositore affermano anche esplicitamente che i repo di pacchetti dovrebbero essere evitati. Per favore, smettila di incoraggiare le cattive pratiche.
igorw

1
In cosa mi consigliate di cambiarlo?
Mike Graf

146

Quel pacchetto infatti è disponibile tramite packagist . In questo caso non è necessaria una definizione di repository personalizzata. Assicurati solo di aggiungere un require(che è sempre necessario) con un vincolo di versione corrispondente.

In generale, se un pacchetto è disponibile su packagist, non aggiungere un repository VCS. Rallenterà solo le cose.


Per i pacchetti che non sono disponibili tramite packagist, usa un repository VCS (o git), come mostrato nella tua domanda. Quando lo fai, assicurati che:

  • Il campo "repository" è specificato in root composer.json (è un campo solo root, le definizioni di repository dai pacchetti richiesti vengono ignorate)
  • La definizione dei repository punta a un repository VCS valido
  • Se il tipo è "git" invece di "vcs" (come nella tua domanda), assicurati che sia effettivamente un repository git
  • Hai una requireper il pacchetto in questione
  • Il vincolo nella requirecorrispondenza delle versioni fornite dal repository VCS. È possibile utilizzare composer show <packagename>per trovare le versioni disponibili. In questo caso ~2.3sarebbe una buona opzione.
  • Il nome nel requirecorrisponde al nome nel telecomando composer.json. In questo caso, lo è gedmo/doctrine-extensions.

Ecco un esempio composer.jsonche installa lo stesso pacchetto tramite un repository VCS:

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

I documenti del repository VCS spiegano tutto questo abbastanza bene.


Se è presente un repository git (o altro VCS) con un repository composer.jsondisponibile, non utilizzare un repository "pacchetto". I repository di pacchetti richiedono di fornire tutti i metadati nella definizione e ignoreranno completamente qualsiasi composer.jsonpresente nel dist e nel sorgente forniti. Hanno anche limitazioni aggiuntive, come non consentire aggiornamenti adeguati nella maggior parte dei casi.

Evita i repository di pacchetti ( vedi anche la documentazione ).


1
Ou, grazie! Non l'ho trovato perché pensavo che sarebbe stato chiamato dopo il repository git DoctrineExtensions.
martin

2
Guarda sempre il nome dato composer.json.
igorw

16
-1 Perché è contrassegnata come risposta corretta? Sicuramente ha risolto il problema dell'OP, ma Clarence e Mike Graf hanno dato risposte al problema più generale dietro di esso. È altamente improbabile che qualcuno alla ricerca di un modo per includere progetti non packagist voglia includere DoctrineExtensions.
aefxx

2
@aefxx La mia risposta non fa infatti spiegano anche il problema generale generale, che è che il requirecampo deve essere specificato.
igorw

6
The VCS repo docs explain all of this quite well.... che cosa?
hek2mgl

47

Puoi includere il repository git in composer.json in questo modo:

"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
Come spiegato nelle altre risposte sopra: se hai un repository, aggiungi un composer.jsonfile se possibile.
Sven

@Sven ... perché altrimenti è impossibile specificare un commit specifico?
Cees Timmerman

Grazie per la condivisione, mi ha fatto risparmiare ore :)
metamaker

Questo è regolato per essere generale, ma per il resto fondamentalmente una semplice copia della risposta di Mike Graf, quindi non sono sicuro che il generale sia meglio che vedere una particolare libreria nella domanda come esempio.
FantomX1

6

Dì al compositore di usare la sorgente se disponibile:

composer update --prefer-source

O:

composer install --prefer-source

Quindi otterrai pacchetti come repository clonati invece di tarball estratti, in modo da poter apportare alcune modifiche e ripristinarli. Ovviamente, supponendo che tu abbia i permessi di scrittura / push per il repository e Composer conosce il repository del progetto.

Dichiarazione di non responsabilità: penso di poter rispondere a una domanda leggermente diversa, ma questo era quello che stavo cercando quando ho trovato questa domanda, quindi spero che possa essere utile anche ad altri.

Se Composer non sa dove si trova il repository del progetto, o il progetto non ha un composer.json appropriato, la situazione è un po 'più complicata, ma altri hanno già risposto a tali scenari.


3

Ho riscontrato il seguente errore: The requested package my-foo/bar could not be found in any version, there may be a typo in the package name.

Se stai biforcando un altro repository per apportare le tue modifiche, ti ritroverai con un nuovo repository.

Per esempio:

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

Il nuovo URL dovrà entrare nella sezione dei repository del tuo composer.json.

Ricorda che se vuoi fare riferimento al tuo fork come my-foo/barnella sezione dei requisiti, dovrai rinominare il pacchetto nel composer.jsonfile all'interno del tuo nuovo repository.

{
    "name":         "foo/bar",

=>

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

Se hai appena biforcato, il modo più semplice per farlo è modificarlo direttamente all'interno di github.


Nota che il nome del pacchetto non riflette in alcun modo l'URL da cui puoi leggere il repository! Non esiste un collegamento automatico tra i due, entrambi possono essere scelti indipendentemente. L'unica informazione rilevante riguardo Composer è il nome scritto namenell'attributo all'interno composer.json.
Sven

2

Nel mio caso, uso Symfony2.3.x e il parametro di stabilità minima è di default "stabile" (il che è buono). Volevo importare un repository non in packagist ma ho riscontrato lo stesso problema "Impossibile risolvere i tuoi requisiti in un set di pacchetti installabili". Sembrava che il composer.json nel repo che ho provato a importare usasse un "dev" con stabilità minima.

Quindi, per risolvere questo problema, non dimenticare di verificare il file minimum-stability. L'ho risolto richiedendo una dev-masterversione invece di mastercome dichiarato in questo post .


4
Ho avuto lo stesso problema, che è discusso qui . Se hai un ref esplicito (come un commit git), sembra che tu possa fare qualcosa di simile "dev-master#4536bbc166ada96ff2a3a5a4b6e636b093103f0e".
Blaskovicz

1

Se vuoi usare un composer.jsonda GitHub dovresti guardare questo esempio (nella sezione VCS).

La sezione pacchetto è per i pacchetti che non hanno l'estensione composer.json. Tuttavia, non hai seguito anche quell'esempio o avrebbe funzionato. Leggi cosa dice sui repository di pacchetti:

Fondamentalmente, si definiscono le stesse informazioni incluse nel repository del compositore packages.json, ma solo per un singolo pacchetto. Anche in questo caso, i campi minimi richiesti sono nome, versione e dist o sorgente.


0

Cerco di unirmi alle soluzioni menzionate qui perché ci sono alcuni punti importanti da elencare.

  1. Come menzionato nella risposta di @ igorw, l'URL del repository deve essere in quel caso specificato nel file composer.json, tuttavia poiché in entrambi i casi il composer.json deve esistere (a differenza del secondo modo @Mike Graf) pubblicarlo su Packagist è non molto diverso (inoltre anche Github attualmente fornisce servizi di pacchetti come pacchetti npm), unica differenza invece di inserire letteralmente l'URL nell'interfaccia del packagist una volta registrati.

  2. Inoltre, ha un difetto che non può fare affidamento su una libreria esterna che utilizza questo approccio poiché le definizioni di repository ricorsive non funzionano in Composer. Inoltre, a causa di ciò, sembra esserci un "bug" su di esso, poiché la definizione ricorsiva non è riuscita alla dipendenza, non sembra essere sufficiente rispecificare i repository esplicitamente nella radice ma anche tutte le dipendenze dai pacchetti dovrebbero essere rispettato.

Con un file del compositore (risposta 18 ottobre 12 alle 15:13 igorw)

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

Senza un file del compositore (risposta il 23 gennaio 13 alle 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"
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.