Partilhar via


Conceitos de controle de versão

Controle de versão mínimo

vcpkg usa uma abordagem de seleção mínima para versionamento, inspirada na usada por Go, mas modificada de algumas maneiras:

  • Sempre começa a partir de uma nova instalação, elimina a necessidade de operações de upgrade/downgrade.
  • Permita dependências sem restrições introduzindo linhas de base.

O princípio da seleção mínima, no entanto, permanece o mesmo. Dado um conjunto de restrições, vcpkg usará as versões "mais antigas" possíveis de pacotes que podem satisfazer todas as restrições.

Usar uma abordagem de versão mínima tem as seguintes vantagens:

  • É previsível e fácil de entender.
  • O usuário controla quando as atualizações acontecem, como em, nenhuma atualização é executada automaticamente quando uma nova versão é lançada.
  • Evita o uso de um solver SAT.

Para dar um exemplo, considere o seguinte gráfico de pacote:

    (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 o seguinte manifesto:

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

Depois de contabilizar as dependências transitivas, temos o seguinte conjunto de restrições:

  • A >= 1,1
    • B >= 1,0
    • C >= 3,0
  • C >= 2,0

Uma vez que vcpkg tem que satisfazer todas as restrições, o conjunto de pacotes instalados torna-se:

  • A 1.1, mesmo quando A 1.2 existe, não há restrições maiores do que 1.1 o vcpkg seleciona a versão mínima possível.
  • B 1.0, transitivamente exigido pela A 1.1.
  • C 3.0, atualizado pela restrição transitiva adicionada por A 1.1 a fim de satisfazer as restrições de versão.

Resolução de restrições

Dado um manifesto com um conjunto de dependências versionadas, o vcpkg tentará calcular um plano de instalação de pacote que satisfaça todas as restrições.

As restrições de versão vêm nos seguintes sabores:

  • Restrições declaradas: restrições declaradas explicitamente no manifesto de nível superior usando version>=.
  • Restrições de linha de base: restrições adicionadas builtin-baselineimplicitamente pelo .
  • Restrições transitivas: restrições adicionadas indiretamente por dependências de suas dependências.
  • Restrições substituídas: restrições substituídas no manifesto de nível superior usando overrides declarações.

Para calcular um plano de instalação, o vcpkg segue aproximadamente estas etapas:

  • Adicione todas as restrições de nível superior ao plano.
  • Adicione recursivamente restrições transitivas ao plano.
    • Cada vez que um novo pacote é adicionado ao plano, também adiciona sua restrição de linha de base ao plano.
    • Cada vez que uma restrição é adicionada:
    • Se existir uma substituição para o pacote
      • Selecione a versão na substituição.
    • Caso contrário:
      • Se não houver nenhuma versão anterior selecionada.
        • Selecione a versão mínima que satisfaz a restrição.
      • Se houver uma versão anterior selecionada:
        • Se o esquema de controle de versão da nova restrição não corresponder ao da versão selecionada anteriormente:
          • Adicione um conflito de versão.
        • Se a versão da restrição não for comparável à versão selecionada anteriormente. Por exemplo, comparando "version-string: apple" com "version-string: orange":
          • Adicione um conflito de versão.
        • Se a versão de restrições for maior do que a versão selecionada anteriormente:
          • Selecione a versão mais alta.
        • Caso contrário:
          • Manter a seleção anterior.
  • Reveja o plano:
    • Se não houver conflitos
      • Instalar os pacotes selecionados
    • Caso contrário:
      • Comunicar os conflitos ao utilizador

Aquisição de versões de porta

Embora o conceito de versões de pacote sempre tenha estado presente no vcpkg, o conceito de restrições de versão não esteve.

Com a introdução de restrições de controle de versão, agora é possível que um pacote dependa de uma versão de porta que não corresponda à disponível localmente. Isso levanta um problema, pois vcpkg precisa saber como adquirir os arquivos de porta para a versão solicitada.

Para resolver esse problema, um novo conjunto de arquivos de metadados foi introduzido. Esses arquivos estão localizados no versions/ diretório no nível raiz do repositório vcpkg.

O versions/ diretório conterá arquivos JSON para cada uma das portas disponíveis no registro. Cada arquivo listará todas as versões disponíveis para um pacote e conterá um objeto tree-ish do Git que o vcpkg pode fazer check-out para obter os portfiles dessa versão.

Exemplo: 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 porta, o arquivo de versões correspondente deve estar localizado em versions/{first letter of port name}-/{port name}.json. Por exemplo, o arquivo de versão do zlib estará localizado em versions/z-/zlib.json. Além dos arquivos de versão da porta, o arquivo de linha de base atual está localizado em versions/baseline.json.