web-dev-qa-db-fra.com

Composer nécessite un package local

J'ai développé quelques bibliothèques [Foo and Bar] que je développe en concert, mais qui restent techniquement distinctes. Auparavant, je viens de redéfinir l'autoloader pour aimer "Foo\\": "../Foo/src", mais maintenant que j'ai ajouté une dépendance Guzzle à Foo, Bar retourne son couvercle car il ne fait pas partie de ses dépendances.

Structure du répertoire:

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

Énoncé théorique de chargement automatique: [in Bar/composer.json]

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

Exemple de code:

require('vendor/autoload.php');

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

Comment puis-je résoudre ce problème sans configurer un référentiel local Composer? Je souhaite les conserver sous forme de packages distincts, mais l'un d'eux nécessite l'autre, et traite donc les dépendances de l'autre.

modification post-réponse:

Grâce à Infomaniac, j'ai réalisé les tâches suivantes:

Initialisé le repo git:

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

Ajout de la composer config:

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

Puis composer update!

80
Sammitch

Vous pouvez utiliser la fonction de dépôt de Composer

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

Au lieu d'utiliser le format http, spécifiez un chemin de fichier sur le disque.

34
infomaniac

Pour créer un lien vers un package local en développement, vous devez d'abord ajouter le référentiel composer.json de votre projet principal , comme ceci: :

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

Vous devez également avoir une version spécifiée dans le composer.json de votre package de développement ou utiliser un package utilisant @dev comme suit:

composer require "vendorname/packagename @dev"

Il devrait produire:

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

Le @dev de la commande require est important, composer l'utilise pour extraire le code source et le lier de manière symbolique à votre nouveau package.

C'est un indicateur de stabilité ajouté à la contrainte de version (voir lien du package ).

Celles-ci vous permettent de restreindre ou d'accroître la stabilité d'un paquet au-delà du paramètre stabilité minimale .

Les indicateurs de stabilité minimale sont:

Les options disponibles (par ordre de stabilité) sont dev, alpha, beta, RC et stable.

133
Dhiraj Gupta

Après avoir passé du temps, j'ai finalement compris la solution. Peut-être que ce sera utile pour quelqu'un comme moi et vous fera gagner du temps, alors j'ai décidé de le partager ici.

En supposant que vous ayez la structure de répertoire suivante (relative au répertoire racine de votre projet):

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

Dans cet exemple, vous pouvez voir que le dossier local est destiné aux projets imbriqués de votre entreprise, par exemple. bar-project. Mais vous pouvez configurer n’importe quelle autre mise en page, si vous le souhaitez.

Chaque projet doit avoir son propre composer.json fichier, par exemple racine composer.json et local/bar-project/composer.json. Ensuite, leur contenu serait comme suit:

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

Si, par exemple, vous souhaitez localiser chaque projet dans un répertoire frère distinct, procédez comme suit:

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

- alors vous devez créer un lien vers le répertoire respectif dans la section repositories:

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

Après cela, n'oubliez pas de composer update (ou même rm -rf vendor && composer update -v comme les documents le suggèrent )! Sous le capot, composer créera un vendor/your-company/bar-project lien symbolique qui vise à local/bar-project (ou ../bar-project respectivement).

En supposant que votre public/index.php n'est qu'un front controller, par exemple.:

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

Alors votre config/composition-root.php serait:

<?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
whyer