Conceptos de control de versiones

Control de versiones mínimo

vcpkg usa un enfoque de selección mínimo para el control de versiones, inspirado en el que usa Go, pero modificado de alguna manera:

  • Siempre comienza desde una instalación nueva, elimina la necesidad de realizar operaciones de actualización o degradación.
  • Permite las dependencias sin restricciones mediante la introducción de líneas base.

Sin embargo, el principio de selección mínimo sigue siendo el mismo. Dado un conjunto de restricciones, vcpkg usará las versiones posibles "más antiguas" de los paquetes que pueden satisfacer todas las restricciones.

El uso de un enfoque de versión mínima tiene las siguientes ventajas:

  • Es predecible y fácil de entender.
  • Los controles de usuario cuando se producen actualizaciones, como en , no se realizan actualizaciones automáticamente cuando se publica una nueva versión.
  • Evita el uso de un solucionador SAT.

Para dar un ejemplo, considere el siguiente gráfico de paquetes:

    (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)

Y el siguiente manifiesto:

{
    "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>"
}

Después de tener en cuenta las dependencias transitivas, tenemos el siguiente conjunto de restricciones:

  • A >= 1.1
    • B >= 1,0
    • C >= 3.0
  • C >= 2.0

Dado que vcpkg tiene que satisfacer todas las restricciones, el conjunto de paquetes instalados se convierte en:

  • A 1.1, incluso cuando A 1.2 existe, no hay restricciones más altas que 1.1 para que vcpkg seleccione la versión mínima posible.
  • B 1.0, requerido transitivamente por A 1.1.
  • C 3.0, actualizado por la restricción transitiva agregada por B 1.0 para satisfacer las restricciones de versión.

Resolución de restricciones

Dado un manifiesto con un conjunto de dependencias con versiones, vcpkg intentará calcular un plan de instalación de paquetes que satisfaga todas las restricciones.

Las restricciones de versión vienen en los siguientes tipos:

  • Restricciones declaradas: restricciones declaradas explícitamente en el manifiesto de nivel superior mediante version>=.
  • Restricciones de línea base: las restricciones agregadas implícitamente por .builtin-baseline
  • Restricciones transitivas: las restricciones agregadas indirectamente por las dependencias de las dependencias.
  • Restricciones invalidadas: las restricciones se invalidan en el manifiesto de nivel superior mediante overrides declaraciones.

Para calcular un plan de instalación, vcpkg sigue aproximadamente estos pasos:

  • Agregue todas las restricciones de nivel superior al plan.
  • Agregue de forma recursiva restricciones transitivas al plan.
    • Cada vez que se agrega un nuevo paquete al plan, agregue también su restricción de línea base al plan.
    • Cada vez que se agrega una restricción:
    • Si existe una invalidación para el paquete
      • Seleccione la versión en la invalidación.
    • Lo contrario:
      • Si no hay ninguna versión anterior seleccionada.
        • Seleccione la versión mínima que cumpla la restricción.
      • Si hay una versión anterior seleccionada:
        • Si el esquema de control de versiones de la nueva restricción no coincide con el de la versión seleccionada anteriormente:
          • Agregue un conflicto de versión.
        • Si la versión de la restricción no es comparable a la versión seleccionada anteriormente. Por ejemplo, comparando "version-string: apple" con "version-string: orange":
          • Agregue un conflicto de versión.
        • Si la versión de restricciones es superior a la versión seleccionada anteriormente:
          • Seleccione la versión más alta.
        • Lo contrario:
          • Mantenga la selección anterior.
  • Revise el plan:
    • Si no hay conflictos
      • Instalación de los paquetes seleccionados
    • Lo contrario:
      • Notificar los conflictos al usuario

Adquisición de versiones de puerto

Aunque el concepto de versiones de paquete siempre ha estado presente en vcpkg, el concepto de restricciones de versión no ha sido.

Con la introducción de restricciones de control de versiones, ahora es posible que un paquete dependa de una versión de puerto que no coincida con la disponible localmente. Esto provoca un problema, ya que vcpkg debe saber cómo adquirir los archivos de puerto para la versión solicitada.

Para solucionar este problema, se introdujo un nuevo conjunto de archivos de metadatos. Estos archivos se encuentran en el versions/ directorio en el nivel raíz del repositorio vcpkg.

El versions/ directorio contendrá archivos JSON para cada uno de los puertos disponibles en el Registro. Cada archivo enumerará todas las versiones disponibles para un paquete y contendrá un objeto tree-ish de Git que vcpkg puede consultar para obtener los archivos de puerto de esa versión.

Ejemplo: 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
    }
  ]
}

Para cada puerto, su archivo de versiones correspondiente debe encontrarse en versions/{first letter of port name}-/{port name}.json. Por ejemplo, el archivo de versión de zlib se ubicará en versions/z-/zlib.json. Aparte de los archivos de versión del puerto, el archivo de línea base actual se encuentra en versions/baseline.json.