web-dev-qa-db-fra.com

Comment résoudre deux conflits d'exigences de packages lors de l'exécution de composer install?

Je souhaite installer ces deux packages:

  • "anahkiasen/former": "dev-master"
  • "vespakoen/menu": "dev-master"

Mais composer dit que chacun d'eux dépend des différentes versions de ce paquet:

  • "anahkiasen/html-object": "dev-master"
  • "anahkiasen/html-object": "1.1.2"

Problème 1

- Installation request for anahkiasen/former dev-master -> satisfiable by anahkiasen/former[dev-master].
- Can only install one of: anahkiasen/html-object[dev-master, 1.1.2].
- vespakoen/menu dev-master requires anahkiasen/html-object 1.1.2 -> satisfiable by anahkiasen/html-object[1.1.2].
- anahkiasen/former dev-master requires anahkiasen/html-object dev-master -> satisfiable by anahkiasen/html-object[dev-master].
- Installation request for vespakoen/menu dev-master -> satisfiable by vespakoen/menu[dev-master].

Comment puis-je le résoudre?

33
cawecoy

Le problème de base ici est l'utilisation de branches (dev-master) au lieu de versions balisées. L'utilisation de branches est très susceptible de se solder par des problèmes. Je regarde les questions Composer sur Stackoverflow, et chaque fois que quelqu'un signale des problèmes avec les packages, il utilise les branches de développement et "minimum-stabilité: dev" 99% du temps.

Que ce passe-t-il? Je dois supposer que vous souhaitez installer ces packages pour la première fois. Donc Composer n'installe pas, mais met à jour les packages. Sinon, un ensemble fonctionnel de versions capables de répondre à toutes les exigences de version aurait été enregistré dans le composer.lock.

Voici donc la situation de dépendance: deux packages dépendent d'un troisième package, mais ces deux nécessitent des versions incompatibles.

Peux-tu le réparer? Il n'y a qu'un seul outil dans le fichier local composer.json Qui pourra permettre d'installer le troisième paquet: L'installer avec un alias de version en ligne .

"require": {
    "anahkiasen/former": "dev-master",
    "vespakoen/menu": "dev-master",
    "anahkiasen/html-object": "dev-master as 1.1.2" /* add this line */
}

En installant la branche dev-master et en la déclarant comme la version 1.1.2, Composer peut résoudre les dépendances des deux packages.

Le problème est qu'il échouera au moment même où vous avez trois packages en fonction d'un quatrième - en trois versions différentes.

La bonne chose serait que chaque branche de développement inclue une déclaration d'alias de branche dans LEUR composer.json, Ce qui permettra à Composer de détecter que la branche dev-master est en fait équivalente à version 1.1.x, ce qui aurait pu aider ici (mais pas si un package nécessite explicitement un numéro de version donné - 1.1.x n'est pas 1.1.2). L'ajout d'alias de branche est toujours une bonne chose et devrait être fait. Si un responsable veut pour éviter la maintenance constante de cet alias de version codé en dur dans composer.json, ils peuvent alternativement développer cette version dans une branche qui porte cette version .x en leur nom (c'est-à-dire "v1.1.x" ou "1.1.x "serait détecté par Composer pour contenir ladite version dans la stabilité du développement).

Notez que le problème que j'ai décrit dans le dernier paragraphe est que les packages nécessitent explicitement un numéro de version donné. Avec cette approche, si vous avez besoin d'un tel package, vous ne pouvez pas utiliser une version différente de ce package dépendant vous-même ou dans un package différent. Bien qu'il puisse y avoir des cas pour ne nécessiter qu'une seule version, la meilleure solution est d'exiger des plages de versions.

Ma préférence personnelle est d'utiliser l'opérateur caret pour les versions supérieures à 1.0: ^1.1.7 Nécessiterait 1.1.7 comme version minimale, mais ne serait pas mis à jour vers une version 2.0.0, qui est considérée comme ayant des modifications incompatibles. Si un paquet est soigneusement étiqueté avec une nouvelle version en fonction du versionnage sémantique, cela fonctionne comme un charme. Vous ne seriez jamais surpris par des changements incompatibles (à moins bien sûr que la nature humaine n'interfère, mais vous devriez pouvoir détecter cet échec et annuler la mise à jour si votre logiciel tombe en panne).

Pour les versions inférieures à 1.0, notez que l'opérateur caret fonctionne différemment de l'opérateur tilde - reportez-vous au manuel pour plus de détails . Je préfère le tilde pour les packages sous mon contrôle qui ont été marqués 0.x afin d'obtenir des mises à jour de fonctionnalités "compatibles" même si le contrôle de version sémantique permet des mises à jour incompatibles dans la plage 0.x.

Mais même sans versionnage sémantique, chaque petite inexactitude dans le numéro de version aide, comme la définition de 1.1.* (Censé être mis à jour pour toutes les prochaines versions de correctifs) ou >=1.1.2,<1.2.5.

Le pire de tous, c'est d'exiger "dev-master". Bien que cela soit en effet très inexact (il résoudra tout commit possible dans la branche, en fonction de l'heure de mise à jour), le problème est que vous ne pouvez pas revenir à une version précédente de "dev-master" à moins que vous ne sachiez exactement quel commit id dont vous avez besoin et ajoutez cette exigence à composer.json. Mais alors vous êtes exactement dans la même situation que ci-dessus nécessitant une version exacte (une balise git n'est qu'un alias nommé pour un ID de validation).

58
Sven