Pojęcia dotyczące przechowywania wersji
Minimalna wersja
Narzędzie vcpkg używa minimalnej metody wyboru do przechowywania wersji, inspirowanej wersją używaną przez język Go, ale modyfikowaną na kilka sposobów:
- Zawsze rozpoczyna się od nowej instalacji, eliminuje konieczność wykonywania operacji uaktualniania/obniżania poziomu.
- Zezwalaj na nieograniczone zależności, wprowadzając punkty odniesienia.
Minimalna zasada wyboru pozostaje jednak taka sama. Biorąc pod uwagę zestaw ograniczeń, vcpkg będzie używać "najstarszych" możliwych wersji pakietów, które mogą spełniać wszystkie ograniczenia.
Użycie minimalnej wersji ma następujące zalety:
- Jest to przewidywalne i łatwe do zrozumienia.
- Użytkownik kontroluje, kiedy są wykonywane uaktualnienia, tak jak w przypadku, gdy zostanie wydana nowa wersja, nie są wykonywane automatycznie.
- Unika korzystania z narzędzia do rozwiązywania sat.
Aby nadać przykład, rozważmy następujący graf pakietu:
(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)
I następujący manifest:
{
"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>"
}
Po uwzględnieniu zależności przechodnich mamy następujący zestaw ograniczeń:
- A >= 1.1
- B >= 1.0
- C >= 3.0
- C >= 2.0
Ponieważ program vcpkg musi spełniać wszystkie ograniczenia, zestaw zainstalowanych pakietów staje się:
A 1.1
, nawet jeśliA 1.2
istnieje, nie ma żadnych ograniczeń wyższych niż1.1
więc vcpkg wybiera minimalną wersję możliwą.B 1.0
, przechodnio wymagane przezA 1.1
.C 3.0
, uaktualniony przez ograniczenie przejściowe dodaneB 1.0
przez w celu spełnienia ograniczeń wersji.
Rozwiązywanie ograniczeń
Biorąc pod uwagę manifest z zestawem zależności w wersji, vcpkg podejmie próbę obliczenia planu instalacji pakietu spełniającego wszystkie ograniczenia.
Ograniczenia wersji są dostępne w następujących wersjach:
- Zadeklarowane ograniczenia: ograniczenia zadeklarowane jawnie w manifeście najwyższego poziomu przy użyciu polecenia
version>=
. - Ograniczenia linii bazowej: ograniczenia dodane niejawnie przez element
builtin-baseline
. - Ograniczenia przejściowe: ograniczenia dodane pośrednio przez zależności.
- Przesłonięte ograniczenia: ograniczenia przesłonięte w manifeście najwyższego poziomu przy użyciu
overrides
deklaracji.
Aby obliczyć plan instalacji, program vcpkg wykonuje mniej więcej następujące kroki:
- Dodaj wszystkie ograniczenia najwyższego poziomu do planu.
- Rekursywnie dodaj ograniczenia przechodnie do planu.
- Za każdym razem, gdy nowy pakiet jest dodawany do planu, dodaj również jego ograniczenie bazowe do planu.
- Za każdym razem, gdy zostanie dodane ograniczenie:
- Jeśli dla pakietu istnieje przesłonięcia
- Wybierz wersję w zastąpieniu.
- Inaczej:
- Jeśli nie wybrano poprzedniej wersji.
- Wybierz minimalną wersję spełniającą ograniczenie.
- Jeśli wybrano poprzednią wersję:
- Jeśli schemat przechowywania wersji nowego ograniczenia nie jest zgodny z wcześniej wybraną wersją:
- Dodaj konflikt wersji.
- Jeśli wersja ograniczenia nie jest porównywalna z wcześniej wybraną wersją. Na przykład porównanie ciągu wersji: apple z ciągiem "version-string: orange":
- Dodaj konflikt wersji.
- Jeśli wersja ograniczeń jest wyższa niż wcześniej wybrana wersja:
- Wybierz najwyższą wersję.
- Inaczej:
- Zachowaj poprzedni wybór.
- Jeśli schemat przechowywania wersji nowego ograniczenia nie jest zgodny z wcześniej wybraną wersją:
- Jeśli nie wybrano poprzedniej wersji.
- Przejrzyj plan:
- Jeśli nie ma konfliktów
- Instalowanie wybranych pakietów
- Inaczej:
- Zgłaszanie konfliktów użytkownikowi
- Jeśli nie ma konfliktów
Uzyskiwanie wersji portów
Chociaż pojęcie wersji pakietów zawsze było obecne w narzędziu vcpkg, pojęcie ograniczeń wersji nie było.
Wraz z wprowadzeniem ograniczeń przechowywania wersji teraz możliwe jest, że pakiet zależy od wersji portu, która nie jest zgodna z wersją dostępną lokalnie. Powoduje to problem, ponieważ narzędzie vcpkg musi wiedzieć, jak uzyskać pliki portów dla żądanej wersji.
Aby rozwiązać ten problem, wprowadzono nowy zestaw plików metadanych. Te pliki znajdują się w versions/
katalogu na poziomie głównym repozytorium vcpkg.
Katalog versions/
będzie zawierać pliki JSON dla każdego z portów dostępnych w rejestrze. Każdy plik wyświetli listę wszystkich wersji dostępnych dla pakietu i zawiera obiekt drzewa git, który vcpkg może sprawdzić, aby uzyskać pliki portów tej wersji.
Przykład: 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
}
]
}
Dla każdego portu odpowiedni plik wersji powinien znajdować się w folderze versions/{first letter of port name}-/{port name}.json
. Na przykład plik wersji biblioteki zlib będzie znajdować się w versions/z-/zlib.json
lokalizacji . Oprócz plików wersji portów bieżący plik punktu odniesienia znajduje się w versions/baseline.json
lokalizacji .