Avatar ·

Есть ли у cargo install команда для обновления установленных пакетов?

Всем привет! Я новичок в Rust и активно изучаю экосистему. Установил несколько полезных утилит через `cargo install` — например, `ripgrep`, `bat` и `fd-find`. Всё работает отлично, но я заметил, что эти инструменты периодически обновляются на GitHub. Я хочу держать их в актуальном состоянии, но не могу найти команду, аналогичную `apt update && apt upgrade` в Ubuntu или `brew upgrade` в Homebrew. Я пробовал: ```bash cargo install --update ripgrep ``` Но получил ошибку: `error: unexpected argument '--update' found`. Потом попробовал `cargo update ripgrep` — тоже не сработало, так как `cargo update` работает только для зависимостей в проекте с Cargo.toml. Получается, что для обновления каждой утилиты мне нужно сначала узнать последнюю версию, а потом выполнить `cargo install ripgrep --force`, чтобы переустановить её. Это неудобно, когда у тебя 10–15 инструментов. Может быть, есть какая-то встроенная команда в Cargo для массового обновления? Или нужно писать свой скрипт? Подскажите, как вы решаете эту проблему. Заранее спасибо! <<>>

Краткий ответ

Встроенной команды cargo update --global или cargo install --upgrade не существует. Однако есть элегантное решение с использованием внешнего инструмента cargo-update, который добавляет команду cargo install-update.

Подробное решение

Проблема в том, что cargo install копирует бинарные файлы из скомпилированных крейтов в директорию ~/.cargo/bin/. Cargo не отслеживает, какие версии установлены — он просто перезаписывает файл при повторной установке с флагом --force. Команда cargo update предназначена только для обновления зависимостей внутри проекта, а не глобально установленных пакетов.

Лучший способ автоматизировать обновление — установить крейт cargo-update:

cargo install cargo-update

После этого у вас появится команда:

cargo install-update -a

Флаг -a (или --all) проверяет все установленные через cargo install пакеты и обновляет те, для которых вышла новая версия. Пример вывода:

$ cargo install-update -a
    Checking all installed packages...
    Package ripgrep v13.0.0 -> v14.1.0 (latest)
    Package bat v0.22.1 -> v0.24.0 (latest)
    Package fd-find v8.7.0 -> v9.0.0 (latest)
    Updating ripgrep...
    Updating bat...
    Updating fd-find...
    All done! 3 packages updated.

Если хотите обновить только конкретный пакет:

cargo install-update ripgrep

Как это работает? cargo-update сканирует директорию ~/.cargo/bin/, находит бинарники, установленные через Cargo, и сопоставляет их с крейтами на crates.io. Если версия в реестре новее — выполняет cargo install --force для этого крейта.

Альтернативный ручной подход

Если не хотите устанавливать дополнительный инструмент, можно написать однострочник для Bash:

for pkg in $(ls ~/.cargo/bin/ | grep -v cargo); do
    cargo install $pkg --force 2>/dev/null
done

Но это менее эффективно, так как переустанавливает всё подряд без проверки версий.

Важные замечания

  • cargo-update не обновляет сам Cargo или компилятор Rust — для этого используйте rustup update.
  • Обновление через --force перекомпилирует крейт с нуля, что может занять время для больших проектов.
  • Если пакет был установлен из Git-репозитория (не из crates.io), cargo-update его не обновит — только переустановка вручную.
<<>>

Решение для продвинутых пользователей: пакетный менеджер cargo-binstall

Есть ещё один популярный инструмент — cargo-binstall. Он позволяет устанавливать бинарные крейты без компиляции из исходников, скачивая готовые сборки с GitHub. Это работает быстрее, но требует, чтобы автор крейта публиковал бинарные артефакты.

Установка:

cargo install cargo-binstall

После этого вы можете устанавливать пакеты с флагом обновления:

cargo binstall ripgrep --force

Для массового обновления используйте скрипт, который перебирает список установленных пакетов. Список можно получить из ~/.cargo/.crates.toml (файл создаётся Cargo, в нём хранятся установленные крейты и их версии):

cat ~/.cargo/.crates.toml | grep 'name =' | awk -F'"' '{print $2}' | xargs -I {} cargo binstall {} --force --no-confirm

Этот подход особенно полезен для больших инструментов вроде cargo-audit или just, которые долго компилировать. Однако помните: cargo-binstall не всегда находит готовый бинарник, и тогда он падает с ошибкой — в этом случае придётся вернуться к cargo install.