Concepts de contrôle de version
Contrôle de version minimal
vcpkg utilise une approche de sélection minimale pour le contrôle de version, inspiré par celui utilisé par Go, mais modifié de certaines façons :
- Toujours à partir d’une nouvelle installation, élimine le besoin d’opérations de mise à niveau/rétrogradation.
- Autoriser les dépendances non contraintes en introduisant des lignes de base.
Toutefois, le principe de sélection minimal reste le même. Compte tenu d’un ensemble de contraintes, vcpkg utilise les versions possibles les plus anciennes des packages qui peuvent satisfaire toutes les contraintes.
L’utilisation d’une approche de version minimale présente les avantages suivants :
- Il est prévisible et facile à comprendre.
- Les contrôles utilisateur quand des mises à niveau se produisent, comme dans le cas, aucune mise à niveau n’est effectuée automatiquement lorsqu’une nouvelle version est publiée.
- Évite d’utiliser un solveur SAT.
Pour donner un exemple, considérez le graphique de package suivant :
(A 1.0) -> (B 1.0)
(A 1.1) -> (B 1.0)
-> (C 3.0)
(A 1.2) -> (B 2.0)
-> (C 3.0)
(C 2.0)
Et le manifeste suivant :
{
"name": "example",
"version": "1.0.0",
"dependencies": [
{ "name": "A", "version>=": "1.1" },
{ "name": "C", "version>=": "2.0" }
],
"builtin-baseline": "<some git commit with A's baseline at 1.0>"
}
Après avoir comptabilisé les dépendances transitives, nous avons l’ensemble de contraintes suivant :
- A >= 1,1
- B >= 1,0
- C >= 3,0
- C >= 2,0
Étant donné que vcpkg doit satisfaire toutes les contraintes, l’ensemble de packages installés devient :
A 1.1
, même s’ilA 1.2
existe, il n’existe aucune contrainte supérieure à ce que1.1
vcpkg sélectionne la version minimale possible.B 1.0
, transitivement requis parA 1.1
.C 3.0
, mis à niveau par la contrainte transitive ajoutéeB 1.0
pour satisfaire aux contraintes de version.
Résolution de contrainte
Étant donné un manifeste avec un ensemble de dépendances avec version, vcpkg tente de calculer un plan d’installation de package qui satisfait à toutes les contraintes.
Les contraintes de version sont fournies dans les versions suivantes :
- Contraintes déclarées : contraintes déclarées explicitement dans le manifeste de niveau supérieur à l’aide
version>=
de . - Contraintes de référence : contraintes ajoutées implicitement par le
builtin-baseline
. - Contraintes transitives : contraintes ajoutées indirectement par les dépendances de vos dépendances.
- Contraintes substituées : contraintes substituées dans le manifeste de niveau supérieur à l’aide
overrides
de déclarations.
Pour calculer un plan d’installation, vcpkg suit à peu près les étapes suivantes :
- Ajoutez toutes les contraintes de niveau supérieur au plan.
- Ajoutez de façon récursive des contraintes transitives au plan.
- Chaque fois qu’un nouveau package est ajouté au plan, ajoutez également sa contrainte de référence au plan.
- Chaque fois qu’une contrainte est ajoutée :
- Si un remplacement existe pour le package
- Sélectionnez la version dans le remplacement.
- Sinon:
- S’il n’existe aucune version précédente sélectionnée.
- Sélectionnez la version minimale qui satisfait à la contrainte.
- S’il existe une version précédente sélectionnée :
- Si le schéma de contrôle de version de la nouvelle contrainte ne correspond pas à celui de la version précédemment sélectionnée :
- Ajoutez un conflit de version.
- Si la version de la contrainte n’est pas comparable à la version sélectionnée précédemment. Par exemple, comparaison de « version-string : apple » à « version-string : orange » :
- Ajoutez un conflit de version.
- Si la version des contraintes est supérieure à la version précédemment sélectionnée :
- Sélectionnez la version la plus élevée.
- Sinon:
- Conservez la sélection précédente.
- Si le schéma de contrôle de version de la nouvelle contrainte ne correspond pas à celui de la version précédemment sélectionnée :
- S’il n’existe aucune version précédente sélectionnée.
- Passez en revue le plan :
- S’il n’y a pas de conflits
- Installer les packages sélectionnés
- Sinon:
- Signaler les conflits à l’utilisateur
- S’il n’y a pas de conflits
Acquisition de versions de port
Bien que le concept de versions de package ait toujours été présent dans vcpkg, le concept de contraintes de version n’a pas été.
Avec l’introduction des contraintes de contrôle de version, il est désormais possible qu’un package dépend d’une version de port qui ne corresponde pas à celle disponible localement. Cela pose un problème, car vcpkg doit savoir comment acquérir les fichiers de port pour la version demandée.
Pour résoudre ce problème, un nouvel ensemble de fichiers de métadonnées a été introduit. Ces fichiers se trouvent dans le versions/
répertoire au niveau racine du référentiel vcpkg.
Le versions/
répertoire contient des fichiers JSON pour chacun des ports disponibles dans le Registre. Chaque fichier répertorie toutes les versions disponibles pour un package et contient un objet tree-ish Git que vcpkg peut case activée pour obtenir les fichiers de port de cette version.
Exemple : zlib.json
{
"versions": [
{
"git-tree": "2dfc991c739ab9f2605c2ad91a58a7982eb15687",
"version-string": "1.2.11",
"port-version": 9
},
...
{
"git-tree": "a516e5ee220c8250f21821077d0e3dd517f02631",
"version-string": "1.2.10",
"port-version": 0
},
{
"git-tree": "3309ec82cd96d752ff890c441cb20ef49b52bf94",
"version-string": "1.2.8",
"port-version": 0
}
]
}
Pour chaque port, son fichier de versions correspondantes doit se trouver dans versions/{first letter of port name}-/{port name}.json
. Par exemple, le fichier de version de zlib se trouve dans versions/z-/zlib.json
. En dehors des fichiers de version de port, le fichier de base actuel se trouve dans versions/baseline.json
.