Condividi tramite


Concetti relativi al controllo delle versioni

Controllo delle versioni minimo

vcpkg usa un approccio di selezione minimo al controllo delle versioni, ispirato a quello usato da Go, ma modificato in alcuni modi:

  • Inizia sempre da una nuova installazione, elimina la necessità di operazioni di aggiornamento/downgrade.
  • Consentire le dipendenze non vincolate introducendo le linee di base.

Il principio di selezione minima, tuttavia, rimane invariato. Dato un set di vincoli, vcpkg userà le versioni possibili "meno recenti" dei pacchetti che possono soddisfare tutti i vincoli.

L'uso di un approccio di versione minima presenta i vantaggi seguenti:

  • È prevedibile e facile da capire.
  • Gli utenti controllano quando vengono eseguiti gli aggiornamenti, come in, non vengono eseguiti automaticamente quando viene rilasciata una nuova versione.
  • Evita l'uso di un risolutore SAT.

Per un esempio, prendere in considerazione il grafico del pacchetto seguente:

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

E il manifesto seguente:

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

Dopo aver contabiliato le dipendenze transitive, è disponibile il set di vincoli seguente:

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

Poiché vcpkg deve soddisfare tutti i vincoli, il set di pacchetti installati diventa:

  • A 1.1, anche se A 1.2 esiste, non esistono vincoli superiori a 1.1 così vcpkg seleziona la versione minima possibile.
  • B 1.0, richiesto transitivamente da A 1.1.
  • C 3.0, aggiornato dal vincolo transitivo aggiunto da B 1.0 per soddisfare i vincoli di versione.

Risoluzione dei vincoli

Dato un manifesto con un set di dipendenze con controllo delle versioni, vcpkg tenterà di calcolare un piano di installazione del pacchetto che soddisfi tutti i vincoli.

I vincoli di versione sono disponibili nelle versioni seguenti:

  • Vincoli dichiarati: vincoli dichiarati in modo esplicito nel manifesto di primo livello usando version>=.
  • Vincoli di base: vincoli aggiunti in modo implicito da builtin-baseline.
  • Vincoli transitivi: vincoli aggiunti indirettamente dalle dipendenze delle dipendenze.
  • Vincoli sottoposti a override: vincoli sottoposti a override nel manifesto di primo livello usando overrides le dichiarazioni.

Per calcolare un piano di installazione, vcpkg segue approssimativamente questi passaggi:

  • Aggiungere tutti i vincoli di primo livello al piano.
  • Aggiungere in modo ricorsivo vincoli transitivi al piano.
    • Ogni volta che un nuovo pacchetto viene aggiunto al piano, aggiungere anche il vincolo di base al piano.
    • Ogni volta che viene aggiunto un vincolo:
    • Se esiste un override per il pacchetto
      • Selezionare la versione nell'override.
    • Altrimenti:
      • Se non è selezionata alcuna versione precedente.
        • Selezionare la versione minima che soddisfa il vincolo.
      • Se è selezionata una versione precedente:
        • Se lo schema di controllo delle versioni del nuovo vincolo non corrisponde a quello della versione selezionata in precedenza:
          • Aggiungere un conflitto di versione.
        • Se la versione del vincolo non è paragonabile alla versione selezionata in precedenza. Ad esempio, confrontando "version-string: apple" con "version-string: orange":
          • Aggiungere un conflitto di versione.
        • Se la versione dei vincoli è superiore alla versione selezionata in precedenza:
          • Selezionare la versione più recente.
        • Altrimenti:
          • Mantenere la selezione precedente.
  • Esaminare il piano:
    • Se non sono presenti conflitti
      • Installare i pacchetti selezionati
    • Altrimenti:
      • Segnalare i conflitti all'utente

Acquisizione delle versioni delle porte

Anche se il concetto di versioni del pacchetto è sempre stato presente in vcpkg, il concetto di vincoli di versione non è stato.

Con l'introduzione dei vincoli di controllo delle versioni, è ora possibile che un pacchetto dipenda da una versione della porta che non corrisponde a quella disponibile in locale. Questo genera un problema perché vcpkg deve sapere come acquisire i file di porta per la versione richiesta.

Per risolvere questo problema, è stato introdotto un nuovo set di file di metadati. Questi file si trovano nella versions/ directory a livello radice del repository vcpkg.

La versions/ directory conterrà i file JSON per ognuna delle porte disponibili nel Registro di sistema. Ogni file elenca tutte le versioni disponibili per un pacchetto e contiene un oggetto albero-ish Git che vcpkg può controllare per ottenere i file di porta di tale versione.

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

Per ogni porta, il file delle versioni corrispondenti deve trovarsi in versions/{first letter of port name}-/{port name}.json. Ad esempio, il file di versione di zlib si troverà in versions/z-/zlib.json. Oltre ai file di versione della porta, il file di base corrente si trova in versions/baseline.json.