🌌 Арсенал відмички — Кожен зовнішній crate — інструмент зі складу спільноти: С.І.Д. з теплою прискіпливістю нагадує, що версія інструменту важлива — інакше несумісне оновлення чужого коду підірве відмичку в найневідповідніший момент. А Cargo.lock, гордо показує він, — це точний опис того, який саме інструмент зі складу насправді використовувався.
Cargo — офіційний менеджер збірки й пакетів Rust. Cargo.toml описує намір:
ім'я, версію та діапазон допустимих версій кожної залежності (наприклад,
serde = "1" неявно означає «будь-яка сумісна версія від 1.0.0 включно до,
але не включаючи, 2.0.0» — це і є семантика оператора ^, застосованого за
замовчуванням у Cargo). Cargo.lock, навпаки, фіксує факт: точну версію кожної
залежності (і транзитивної залежності залежностей), яку Cargo реально дозволив
для цієї збірки, разом із хешем вмісту для перевірки цілісності. Для бібліотек
Cargo.lock зазвичай не комітять у git (кінцевий користувач бібліотеки сам
вирішує версії), а для бінарних застосунків — навпаки, комітять обов'язково, щоб
збірка була однаковою на будь-якій машині й у будь-який день.
Семантичне версіонування (SemVer) — угода MAJOR.MINOR.PATCH, якої
дотримується (хоч і не примусово технічно) переважна більшість crates.io: MAJOR
зростає при зміні, що ламає зворотну сумісність публічного API (перейменування
функції, зміна сигнатури); MINOR — при доданні нової функціональності без
поламання наявної; PATCH — при виправленні багів без зміни публічного
інтерфейсу. Оператор ^ (неявний за замовчуванням у Cargo.toml) дозволяє Cargo
автоматично підбирати найновішу сумісну версію в межах того самого MAJOR (а для
версій 0.x.y — у межах того самого MINOR, оскільки в SemVer 0.x вважається
нестабільним API).
Команда cargo build використовує вже наявний Cargo.lock, якщо він є й
сумісний із поточним Cargo.toml — це гарантує детермінованість щоденної
розробки. cargo update навпаки — свідомо перераховує Cargo.lock, підбираючи
найновіші версії в межах дозволених діапазонів Cargo.toml, і саме тут може
«прилетіти» несумісна поведінка, якщо якась транзитивна залежність порушила
SemVer (публікувала зміну, що фактично ламає сумісність, під MINOR- чи навіть
PATCH-версією — на жаль, у реальній екосистемі таке трапляється, тож Cargo.lock
у застосунках — не формальність, а реальний захист від «зламалося саме по собі»).
Якщо в Cargo.toml явно вказати мажорну версію, несумісну з наявним кодом
(наприклад, підняти serde = "2.0", коли реальний API проєкту написаний під
1.x), cargo build спробує підтягнути нову мажорну версію, і якщо її публічний
API справді відрізняється — компіляція впаде з помилками невідповідності типів чи
відсутніх елементів, які потрібно буде виправляти вручну (це і є суть «ламає
сумісність»: інструмент зі складу став іншої форми, і стара відмичка до нього
вже не пасує).
Кожна залежність на crates.io має власну сторінку з розділами «Versions»
(історія публікацій), «Dependencies» (що вона сама тягне транзитивно) і зазвичай
CHANGELOG/примітками до релізу — саме там варто перевіряти, чи оновлення
справді PATCH/MINOR за духом, а не лише за номером. Транзитивні залежності
(залежності залежностей) теж підпорядковуються SemVer-резолвінгу Cargo, і саме
вони найчастіше стають джерелом несподіваних конфліктів версій у великих
проєктах — cargo tree показує повне дерево залежностей і допомагає знайти,
звідки саме прийшла конкретна версія конфліктного крейта (crate) — зовнішнього
пакета Rust.
Переглянути сторінку залежності на crates.io (наприклад, sha2 або serde) і файл Cargo.lock власного проєкту; спробувати змінити версію в Cargo.toml на несумісну (major) і подивитися, що станеться при cargo build і cargo update.
Що означають три числа у версії 1.4.2 за семантичним версіонуванням (SemVer), і яке з них означає, що зміна ламає сумісність публічного API?
3.10.1 (прочитай цифри поспіль без крапок), і MAJOR він обіцяє не піднімати ніколи: ламати сумісність із ранером — не в його стилі. На crates.io він себе не викладе: Cargo.lock фіксує checksum кожного пакета, а той, хто хоче зникнути в мережі, не лишає хешів, за якими його знайдуть.Кожна команда терміналу з цієї сторінки — одним реченням. Позначка нове — команда зустрічається в курсі вперше; далі вважаємо її знайомою.
cargo treeновеcargocargo updateновеCargo.lock у межах, дозволених Cargo.toml (cargo update -p serde).git diffновеgit diff Cargo.lock).gitsubmit/labNN.cargo buildtarget/debug/; --release — з оптимізаціями у target/release/.💡 Прочитати README прямо в терміналі: cat README.md (виведе весь файл) або less README.md (посторінково; вихід — клавіша q).
Довідка з будь-якої команди: man curl (повний посібник, вихід — q) або коротко curl --help; для підкоманд — docker run --help, cargo build --help.