Il compositore richiede un pacchetto locale


106

Ho un paio di librerie [Foo e Bar] che sto sviluppando di concerto, ma sono ancora cose tecnicamente separate. In precedenza ho appena ridefinito il caricatore automatico in modo che piaccia "Foo\\": "../Foo/src", ma ora che ho aggiunto una dipendenza Guzzle a Foo, Bar ribalta il suo coperchio perché non è una delle sue dipendenze.

Struttura delle directory:

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

Dichiarazione di caricamento automatico teorica: [in Bar / composer.json]

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

Codice di esempio:

require('vendor/autoload.php');

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

Come posso risolvere questo problema senza configurare un repository Composer locale? Voglio mantenerli come pacchetti separati, solo che uno richiede l'altro, e quindi elabora le dipendenze dell'altro.

modifica post risposta:

Grazie a infomaniac ho fatto quanto segue:

Inizializzato il repository git:

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

Aggiunta la configurazione del compositore:

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

E poi composer update!


In che modo questo json specifica l'identità tra il riferimento a "sammitch / foo" e l'indirizzo di "/ home / sammitch / src / Foo"? Sta seguendo qualche convenzione?
Sebastián Grignoli

@ SebastiánGrignoli sammitch/fooè il nome del pacchetto e non ha letteralmente nulla a che fare con il luogo in cui si trova. Costruirà un elenco di pacchetti disponibili in base ai suoi repository configurati, in questo caso recuperando composer.json dal repository git locale specificato, quindi il compositore gestirà il resto. Il sammitch/foopacchetto viene copiato nella vendorcartella dell'app corrente come qualsiasi altro pacchetto.
Sammitch

Oh, penso di aver capito ora. È solo un repository personalizzato, come in APT, che potrebbe contenere il pacchetto "sammit / foo". Ho capito bene?
Sebastián Grignoli

@ SebastiánGrignoli ci
scommetti

Risposte:


38

È possibile utilizzare la funzionalità dei repository di Composer

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

Invece di utilizzare il formato http, specificare un percorso di file sul disco.



11
Anche getcomposer.org/doc/05-repositories.md#path è potenzialmente utile e sembrava funzionare meglio per me.
Jasmine Hegman

@JasmineHegman davvero! Ho usato anche quello - ottimo per lo sviluppo
Danny Kopping il

Per rendere questa una buona risposta, dovresti mostrare COME farlo, e non solo nominare la funzione e collegare i documenti (sebbene anche questo sia importante). Altre risposte di seguito hanno esempi appropriati.
Rudolfbyker,

173

Il modo per collegarsi a un pacchetto locale in fase di sviluppo consiste nell'aggiungere prima composer.jsonun repository nel progetto principale , in questo modo:

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

Devi anche avere una versione specificata nel tuo pacchetto di sviluppo composer.jsono il modo in cui lo faccio è richiedere che il pacchetto utilizzi @dev, in questo modo:

composer require "vendorname/packagename @dev"

Dovrebbe produrre:

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

Il @devcomando nel require è importante, il compositore lo usa per prelevare il codice sorgente e collegarlo simbolicamente al tuo nuovo pacchetto.

È un flag di stabilità aggiunto al vincolo di versione (vedere il collegamento al pacchetto ).

Questi consentono di limitare o espandere ulteriormente la stabilità di un pacchetto oltre l'ambito dell'impostazione di stabilità minima .

I flag di stabilità minima sono:

Le opzioni disponibili (in ordine di stabilità) sono dev, alpha, beta, RC, e stable.


8
Nota che non sei autorizzato dal composer a specificare un percorso che si trova nella stessa directory in cui è posizionato il composer.json.
MaPePeR

Punto interessante, MaPePeR Non lo sapevo. Tuttavia, immagino che tutti i framework web se ne occupino già mettendo tutte le dipendenze in una cartella "vendor"? Yii2 lo fa, almeno.
Dhiraj Gupta

3
composer require "vendorname/packagename @dev"si traduce "require":{ "vendorname/packagename": "@dev" }in composer.json della tua app se desideri eseguire l'installazione del compositore
Sir_Faenor

2
Per favore, aggiungi questo: composer config repository.local path / full / o / relative / path / to / development / package come modo corretto di aggiungere repository
basil

1
È possibile dire a composer di installarlo nella cartella dei fornitori per prod invece di creare un collegamento simbolico?
BenjaminH

7

Dopo aver trascorso un po 'di tempo, ho finalmente capito la soluzione. Forse sarà utile per qualcuno come me e ti farà risparmiare un po 'di tempo, quindi ho deciso che devo condividerlo qui.

Supponendo che tu abbia la seguente struttura di directory (relativa alla directory principale del tuo progetto):

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 questo esempio potresti vedere che la localcartella è destinata ai progetti annidati della tua azienda, ad es bar-project. Ma puoi configurare qualsiasi altro layout, se lo desideri.

Ogni progetto deve avere il proprio composer.jsonfile, ad esempio root composer.jsone local/bar-project/composer.json. Quindi il loro contenuto sarebbe il seguente:

(radice 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/"
    }
  }
}

Se, ad esempio, desideri individuare ogni progetto in una directory di pari livello separata, come segue:

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

- quindi è necessario collegarsi alla rispettiva directory nella repositoriessezione:

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

Dopodiché non dimenticare di composer update(o anche rm -rf vendor && composer update -vcome suggeriscono i documenti )! Dietro le quinte, il compositore creerà un vendor/your-company/bar-projectcollegamento simbolico che mira a local/bar-project(o../bar-project rispettivamente).

Supponendo che il tuo public/index.phpsia solo un front controller, ad esempio:

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

Allora il tuo config/composition-root.phpsarebbe:

<?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" è importante
Alex83690

@ Alex83690 solo se hai già eseguito composer updatecon simili composer.jsone quindi devi rimuovere il
collegamento
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.