Komponisten benötigen ein lokales Paket

105

Ich habe ein paar Bibliotheken [Foo und Bar], die ich gemeinsam entwickle, aber technisch immer noch getrennte Dinge. Früher habe ich den Autoloader so neu definiert, dass er gefällt "Foo\\": "../Foo/src", aber jetzt, da ich Foo eine Guzzle-Abhängigkeit hinzugefügt habe, klappt Bar den Deckel um, weil es keine seiner Abhängigkeiten ist.

Verzeichnisaufbau:

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

Theoretische Autoload-Anweisung: [in Bar / composer.json]

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

Beispielcode:

require('vendor/autoload.php');

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

Wie kann ich das beheben, ohne ein lokales Composer-Repo einzurichten? Ich möchte diese als separate Pakete verwalten, nur dass eines das andere benötigt und daher die Abhängigkeiten des anderen verarbeitet.

Nachbearbeitung bearbeiten:

Dank Infomaniac habe ich Folgendes getan:

Initialisiert das Git Repo:

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

Die Composer-Konfiguration wurde hinzugefügt:

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

Und dann composer update!

Sammitch
quelle
Wie spezifiziert dieser JSON die Identität zwischen dem Verweis auf "sammitch / foo" und der Adresse von "/ home / sammitch / src / Foo"? Folgt es einer Konvention?
Sebastián Grignoli
@ SebastiánGrignoli sammitch/fooist der Paketname und hat buchstäblich nichts damit zu tun, wo er sich befindet. Erstellt eine Liste der verfügbaren Pakete basierend auf den konfigurierten Repos. In diesem Fall wird die Datei composer.json aus dem angegebenen lokalen Git-Repo abgerufen, und der Rest erledigt den Composer. Das sammitch/fooPaket wird vendorwie jedes andere Paket in den Ordner der aktuellen App kopiert .
Sammitch
Oh, ich glaube ich verstehe es jetzt. Es ist nur ein benutzerdefiniertes Repo, wie in APT, das möglicherweise das Paket "sammit / foo" enthält. Habe ich es richtig gesagt?
Sebastián Grignoli
@ SebastiánGrignoli Sie betcha
Sammitch

Antworten:

36

Sie können Komponisten verwenden Repositories verfügen

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

Geben Sie anstelle des http-Formats einen Dateipfad auf der Festplatte an.

Danny Kopping
quelle
11
getcomposer.org/doc/05-repositories.md#path ist ebenfalls potenziell nützlich und schien für mich besser zu funktionieren.
Jasmine Hegman
@ JasminHegman in der Tat! Ich habe das auch benutzt - großartig für die Entwicklung
Danny Kopping
Um dies zu einer guten Antwort zu machen, sollten Sie zeigen, wie es geht, und nicht nur die Funktion benennen und die Dokumente verknüpfen (obwohl dies auch wichtig ist). Andere Antworten unten haben richtige Beispiele.
Rudolfbyker
169

Der Weg zur Verbindung zu einem lokalen, in-Entwicklungspaket ist zum ersten Add in Ihr Hauptprojekt ist composer.jsonein Repository , wie folgt aus :

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

Sie müssen auch entweder eine Version in Ihrem Entwicklungspaket angegeben haben composer.jsonoder die Art und Weise, wie ich es mache, besteht darin, dass das Paket Folgendes verwendet @dev:

composer require "vendorname/packagename @dev"

Es sollte Folgendes ausgeben:

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

Der @devBefehl require ist wichtig. Composer verwendet diesen Befehl, um den Quellcode aufzunehmen und ihn mit Ihrem neuen Paket zu verknüpfen.

Es ist ein Stabilitätsflag, das der Versionsbeschränkung hinzugefügt wurde (siehe Paketlink ).

Mit diesen können Sie die Stabilität eines Pakets über den Bereich der Mindeststabilitätseinstellung hinaus weiter einschränken oder erweitern .

Die Mindeststabilitätsflags sind:

Die verfügbaren Optionen (in der Reihenfolge der Stabilität) sind dev, alpha, beta, RC, und stable.

Dhiraj Gupta
quelle
8
Beachten Sie, dass Composer keinen Pfad angeben darf, der sich in demselben Verzeichnis befindet, in dem sich composer.json befindet.
MaPePeR
Interessanter Punkt, MaPePeR Ich wusste das nicht. Ich denke jedoch, dass alle Web-Frameworks dies bereits erledigen, indem sie alle Abhängigkeiten in einem "Vendor" -Ordner ablegen. Yii2 macht das zumindest.
Dhiraj Gupta
3
composer require "vendorname/packagename @dev"wird "require":{ "vendorname/packagename": "@dev" }in composer.json Ihrer App übersetzt, wenn Sie die Composer-Installation
ausführen
2
Bitte fügen Sie Folgendes hinzu: composer config repositories.local path / full / oder / relative / path / to / development / package als korrekte Methode zum Hinzufügen von Repositories
Basilikum
1
Ist es möglich, den Komponisten anzuweisen, es für prod im Ordner des Anbieters zu installieren, anstatt einen Symlink zu erstellen?
BenjaminH
7

Nachdem ich einige Zeit verbracht hatte, verstand ich endlich die Lösung. Vielleicht ist es für jemanden wie mich nützlich und spart Ihnen etwas Zeit. Deshalb habe ich beschlossen, dass ich es hier teilen muss.

Angenommen, Sie haben die folgende Verzeichnisstruktur (relativ zu Ihrem Projektstammverzeichnis):

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 diesem Beispiel sehen Sie möglicherweise, dass der localOrdner für verschachtelte Projekte Ihres Unternehmens bestimmt ist, z bar-project. Sie können jedoch auch ein anderes Layout konfigurieren, wenn Sie dies wünschen.

Jedes Projekt muss eine eigene composer.jsonDatei haben, z . B. root composer.jsonund local/bar-project/composer.json. Dann wäre ihr Inhalt wie folgt:

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

Wenn Sie beispielsweise jedes Projekt wie folgt in einem separaten Geschwisterverzeichnis suchen möchten:

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

- Dann müssen Sie in repositoriesAbschnitt: auf das entsprechende Verzeichnis verlinken :

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

Vergessen Sie danach nicht composer update(oder sogar rm -rf vendor && composer update -vwie in den Dokumenten vorgeschlagen )! Unter der Haube erstellt der Komponist einen vendor/your-company/bar-projectSymlink, der auf local/bar-project(bzw. ../bar-project) abzielt .

Angenommen, Sie public/index.phpsind nur ein front controller, z.

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

Dann config/composition-root.phpwären Sie:

<?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();
warum
quelle
1
"rm -rf Anbieter / Firma / Paket" ist wichtig
Alex83690
@ Alex83690 nur, wenn Sie bereits composer updatemit ähnlichen ausgeführt haben composer.jsonund daher den vorherigen vom Komponisten erstellten Symlink entfernen müssen
Whyer