Jaka jest składnia wersji altany (i npm)?

274

Bower pozwala mi określić wymagania dotyczące wersji pakietów przy użyciu następującej składni:

"dependencies": {
  "<name>": "<version>",
},

Ale nie byłem w stanie znaleźć, jakiej składni użyć do <version>. Wiem, że mogę określić wersje:

  • większa niż pewna wersja z ">1.0.0"
  • większa lub równa wersji: ">=1.0.0"
  • lub w jakimś zakresie: "1.0.0 - 2.0.0".

Wiem też, że istnieje wspólna wersja składnia zawierający tyldy: "~1.0.0". Ale nie jestem pewien, co to znaczy i czy jest to to samo, co "=1.0.0".

Interesuje mnie również to, czy jestem w stanie podać wiele niesekwencyjnych wersji, takich jak 1.0.3wersje plus plus większa niż 1.5.0itp.

Samuel Hapak
źródło
3
Może to być duplikat stackoverflow.com/a/19040351/537738
David,

Odpowiedzi:

341

W skrócie, składnia numerów wersji Bower (i NPM) nazywa się SemVer, co jest skrótem od „Semantic Versioning”. Możesz znaleźć dokumentację dla szczegółowej składni SemVer stosowanej w Bower i NPM w API dla parsera semver w Node / npm . Możesz dowiedzieć się więcej na temat specyfikacji bazowej (która nie wspomina ~ani innych szczegółów składni) na semver.org .

Istnieje bardzo przydatny kalkulator semver wizualny, w który można grać, dzięki czemu wszystko to jest znacznie łatwiejsze do opanowania i przetestowania.

SemVer to nie tylko składnia! Ma kilka interesujących rzeczy do powiedzenia na temat właściwych sposobów publikowania API, które pomogą zrozumieć, co oznacza składnia. Co najważniejsze:

Po zidentyfikowaniu publicznego interfejsu API komunikujesz zmiany w nim z określonymi przyrostami numeru wersji. Rozważ format wersji XYZ (Major.Minor.Patch) . Poprawki błędów, które nie wpływają na interfejs API, zwiększają wersję poprawki, dodatki / zmiany kompatybilne wstecz zwiększają wersję mniejszą, a niezgodne wstecz zmiany API zwiększają wersję główną.

Twoje szczegółowe pytanie ~dotyczy schematu Major.Minor.Patch. (Podobnie jak powiązany operator daszka ^). Możesz ~zawęzić zakres wersji, które chcesz zaakceptować:

  • kolejne zmiany na poziomie łaty do tej samej, mniejszej wersji ( „poprawki błędów nie wpływające na API” ) lub:
  • kolejne zmiany na mniejszym poziomie do tej samej wersji głównej ( „dodatki / zmiany API kompatybilne wstecz” )

Na przykład: aby wskazać, że weźmiesz wszelkie kolejne zmiany na poziomie łatki w drzewie 1.2.x, zaczynając od 1.2.0, ale mniej niż 1.3.0, możesz użyć:

"angular": "~1.2"
  or:
"angular": "~1.2.0"

Dzięki temu uzyskasz te same wyniki, co przy użyciu .xskładni:

"angular": "1.2.x"

Ale możesz użyć tyldy / ~składni, aby być jeszcze bardziej szczegółowym: jeśli chcesz zaakceptować zmiany na poziomie łatek zaczynające się od 1.2.4 , ale wciąż mniej niż 1.3.0, użyjesz:

"angular": "~1.2.4"

Poruszanie się w lewo, w kierunku głównej wersji, jeśli używasz ...

"angular": "~1"

... jest taki sam jak ...

"angular": "1.x"
  or:
"angular": "^1.0.0"

... i dopasowuje wszelkie niewielkie zmiany lub zmiany na poziomie powyżej 1.0.0 i mniej niż 2.0:

Zauważ, że ostatnia odmiana powyżej: nazywa się to „zasięgiem karetki” . Daszek wygląda okropnie podobnie >, więc usprawiedliwiałbyś się myśleniem, że oznacza to „każdą wersję większą niż 1.0.0”. (Na pewno się w to wpakowałem.) Nie!

Zakresy karetek są używane w zasadzie do powiedzenia, że ​​zależy Ci tylko na cyfrze najbardziej znaczącej z lewej strony - zwykle na głównej wersji - i że zezwalasz na wszelkie niewielkie zmiany na poziomie łatek, które nie wpływają na tę cyfrę najbardziej z lewej strony. Jednak w przeciwieństwie do zakresu tyldy, który określa główną wersję, zakresy karetki pozwalają określić dokładny punkt początkowy pomniejszej / łatki. A zatem ^1.0.0 === ~1zakres karetki, taki jak ^1.2.3pozwala powiedzieć, że weźmiesz jakiekolwiek zmiany >=1.2.3 && <2.0.0. Nie można tego zrobić z zasięgiem tyldy.

To wszystko wydaje się na początku mylące, kiedy spojrzysz na to z bliska. Ale pomniejsz na sekundę i pomyśl o tym w ten sposób: kursor pozwala po prostu powiedzieć, że najbardziej martwisz się każdą znaczącą cyfrą, jaka pozostała najbardziej. Tylda pozwala powiedzieć, że najbardziej martwi Cię, która cyfra jest najbardziej odpowiednia. Reszta to szczegół.

To ekspresyjna siła tyldy i karety wyjaśnia, dlaczego ludzie używają ich o wiele więcej niż prostsza .xskładnia: po prostu pozwalają ci robić więcej. Dlatego zobaczysz, że tylda jest często używana, nawet tam .x, gdzie służy. Jako przykład zobacz sam npm: własny plik package.json zawiera wiele zależności w ~2.4.0formacie, a nie w 2.4.xformacie, którego mógłby użyć. Trzymając się ~, składnia jest spójna aż do listy ponad 70 wersjonowanych zależności, niezależnie od tego, który początkowy numer łaty jest dopuszczalny.

W każdym razie SemVer ma jeszcze wiele do zaoferowania, ale nie będę próbował tutaj szczegółowo tego wszystkiego opisywać. Sprawdź to w pliku Readme pakietu semver . I pamiętaj, aby korzystać z semantycznego kalkulatora wersjonowania, gdy ćwiczysz i próbujesz dowiedzieć się, jak działa SemVer.


RE: Niesekwencyjne numery wersji: Wydaje się, że ostatnie pytanie OP dotyczy określenia niesekwencyjnych numerów / zakresów wersji (jeśli dość go zredagowałem). Tak, można to zrobić, korzystając ze wspólnego podwójną rurę operator „lub”: ||. Tak jak:

"angular": "1.2 <= 1.2.9 || >2.0.0"
XML
źródło
27
Tak więc ~w szczególności oznacza, że plaster (trzeciej) liczba może być większa niż jeden, na przykład określony ~1.2.3jest równoważna >=1.2.3 <1.3.0.
z0r
1
Może być również użyty dla podrzędnego (drugiego) numeru, w przypadku edycji wprowadzonych powyżej.
XML
ciekawe, że dokumentacja SemVer również wydaje się pozwalać na notację X (która jest dla ludzi o wiele bardziej intuicyjna).
Frank Nocke,
2
Notacja x jest na początku intuicyjna, ale znacznie mniej elastyczna. Na przykład '1.1.x' === '>=1.1.0' === '~1.1.0'. Przypadek 1.1.0 jest łatwy. Ale notacja X nie może być szczegółowa, tak jak '>=1.1.4'i '~1.1.4'. Zatem kończysz '1.1.x'w jednym miejscu na liście zależności i '~2.7.3'w innym miejscu. To dobrze i działa, ale programista musi następnie przeanalizować wiele składni, aby odczytać jedną listę. A jeśli piszesz pakiety w celu programowego ustawienia wersji, potrzebujesz jednej składni. I większość ludzi chce zapobiec łamaniu zmian. Stąd wszystkie problemy rozwiązane ~.
XML
1
Hah Myślę, że „grok” jest mniej geograficzny niż kulturalny (i prawdopodobnie związany z wiekiem) kulturalny @Clonkex. Dla przyszłych czytelników: jest to odniesienie do nieznajomego Heinleina w dziwnej krainie ...
XML
141

W oparciu o semver można użyć

  • Zakresy łączników XYZ - ABC 1.2.3-2.3.4 Wskazuje > = 1,2.3 <= 2.3.4

  • Zakresy X. 1.2.x 1.X 1.2.*

  • Zakresy tyldy ~1.2.3 ~1.2 Wskazuje dopuszczenie zmian na poziomie łatek lub drobnych zmian wersji.

  • Zakresy Careta ^ 1,2,3 ^ 0,25 ^ 0,0,4

    Zezwala na zmiany, które nie modyfikują skrajnie lewej niezerowej cyfry w krotce [głównej, drobnej, łatce]

    • ^1.2.x (oznacza> = 1,2,0 <2,0,0)
    • ^0.0.x (oznacza> = 0,0,0 <0,1,0)
    • ^0.0 (oznacza> = 0,0,0 <0,1,0)
Jerome Anthony
źródło
21
Dziękuję za bezsensowną, łatwą do odczytania odpowiedź. Nie musiałem się wyśledzić ani nic takiego, po prostu bum, jest odpowiedź. Dobra robota;)
toddmo
76

Bower używa składni semver , ale oto kilka krótkich przykładów:

Możesz zainstalować konkretną wersję:

$ bower install jquery#1.11.1

Możesz użyć ~, aby określić „dowolną wersję, która zaczyna się od tego”:

$ bower install jquery#~1.11

Możesz określić wiele wymagań wersji razem:

$ bower install "jquery#<2.0 >1.10"
Wilfred Hughes
źródło
1
Jestem ciekawy praktycznego wykorzystania tego. Instalacja ruletki?
gravidThoughts
Patrząc na odpowiedź @ XMLilley (i dokumenty semver) „początek na” wydaje się niewłaściwy, ponieważ 1.12, 1.13 również byłyby w porządku, o ile główna wersja nie idzie w górę ...
Frank Nocke
13

Możesz również użyć latestsłowa kluczowego, aby zainstalować najnowszą dostępną wersję:

  "dependencies": {
    "fontawesome": "latest"
  }
shacker
źródło
1
semver nie wspomina o tym. Gdzie ustaliłeś, że jest ważny? :) Mówi „ "*" := >=0.0.0(Każda wersja spełnia)”, co jest bliskie, ale nieco niejasne, ponieważ nie mówi konkretnie o najnowszym, więc może być pierwszym, który znajdzie?
GazB,
Szczerze mówiąc, to była tylko próba i błąd - próbowałem i działało! Być może masz rację, że nie jest w 100% poprawny, ale działa.
shacker
7

Jeśli nie ma numeru poprawki, ~jest to równoważne z dołączeniem .xdo wersji innej niż tyldy. Jeśli jest numer łaty, ~zezwól wszystkim numerom łatek> = określony.

~1     := 1.x
~1.2   := 1.2.x
~1.2.3 := (>=1.2.3 <1.3.0)

Nie mam wystarczającej liczby punktów, aby skomentować zaakceptowaną odpowiedź, ale niektóre informacje tyldy są sprzeczne z dołączoną dokumentacją semver: nie"angular": "~1.2" będą pasować 1.3, 1.4, 1.4.9. Również i nie są równoważne. Można to zweryfikować za pomocą kalkulatora semm npm ."angular": "~1""angular": "~1.0"

Decyma
źródło