# Оновлення ccam

> ccam update замінює ccam найновішим випуском із GitHub після перевірки SHA-256; --check лише повідомляє, а --version встановлює вказаний тег випуску.

Source: https://ccam.dev/uk/features/update/ · Updated 2026-10-19

`ccam update` завантажує випуск ccam з GitHub, перевіряє його за `checksums.txt` випуску й замінює запущений виконуваний файл одним перейменуванням. Використовуйте цю команду, якщо ви встановили ccam скриптом встановлення або з архіву. ccam ніколи не перевіряє оновлення сам: лише ця команда звертається до GitHub, тож усі інші команди працюють так само без мережі.

## Використання

```sh
ccam update                    # install the latest release
ccam update --check            # only say whether a newer release exists
ccam update --version v0.3.0   # install that release, also an older one
ccam --dry-run update          # show what would be downloaded and replaced
```

```console
$ ccam update --check
ccam 0.5.0 is available (you have 0.4.0). Run `ccam update`.
$ ccam --dry-run update
Would update ccam 0.4.0 → 0.5.0:
  download  https://github.com/jhyunwoo/ccam/releases/download/v0.5.0/ccam_linux_amd64.tar.gz
  verify    with https://github.com/jhyunwoo/ccam/releases/download/v0.5.0/checksums.txt
  replace   /home/you/.local/bin/ccam
$ ccam update
→ downloading https://github.com/jhyunwoo/ccam/releases/download/v0.5.0/ccam_linux_amd64.tar.gz
✓ Updated ccam 0.4.0 → 0.5.0 (/home/you/.local/bin/ccam)
```

Коли новішого випуску немає, ccam виводить `ccam 0.4.0 is up to date.` і нічого не змінює. З `--version` і версією, яку ви вже використовуєте, він виводить `ccam 0.4.0 is already installed.`

## Параметри

| Параметр | Дія | За замовчуванням |
| --- | --- | --- |
| `--check` | Лише повідомити, чи існує новіший випуск | вимкнено |
| `--version <tag>` | Встановити цей тег випуску, наприклад `v0.3.0`, новіший чи старіший за поточний | найновіший |
| `--dry-run` | Враховується: знаходить найновіший тег (якщо `--version` не вказує його), виконує ті самі перевірки виконуваного файлу й виводить шляхи завантаження, контрольної суми та заміни, нічого не завантажуючи | вимкнено |

`--check` і `--version` не можна використовувати разом. Тег має виглядати як `vMAJOR.MINOR.PATCH`, з необов'язковим суфіксом попереднього випуску або збірки; початковий `v` можна пропустити. Будь-що інше завершується помилкою, наприклад `--version takes a release tag such as v0.3.0, not "1.2"`.

Змінна середовища `CCAM_RELEASES_URL` замінює `https://github.com/jhyunwoo/ccam/releases` для дзеркала або для тестів. Вона повинна мати ту саму структуру: `<url>/latest` переспрямовує на `<url>/tag/<tag>`, а файли випуску лежать за адресою `<url>/download/<tag>/<asset>`.

## Як це працює

Код міститься в `internal/update`, який імпортує лише `ccam update`. Шлях запуску ніколи його не викликає.

1. `cli.updateCmd` знаходить запущений виконуваний файл через `os.Executable` і розв'язує символьні посилання через `filepath.EvalSymlinks`. Саме цей справжній шлях і замінюється.
2. Без `--version` `Updater.Latest` запитує `<releases>/latest`, не переходячи за переспрямуванням, і читає тег із заголовка `Location` (`…/tag/v0.5.0`). Тут використовується сторінка випусків, а не GitHub API, тож ліміт API у 60 запитів на годину не діє. На пошук відведено 10 секунд.
3. `parseVersion` перевіряє тег за суворим шаблоном. Тег потрапляє в URL завантаження й у виведену команду оболонки, тож нічого з `/`, `%`, пробілами чи символами оболонки не проходить. `compareVersions` порівнює його із запущеною версією; попередній випуск упорядковується перед своїм випуском.
4. `managed()` і `writable()` вирішують, чи може ccam взагалі замінити виконуваний файл (див. нижче).
5. `Updater.Fetch` одночасно завантажує `ccam_<os>_<arch>.tar.gz` і `checksums.txt`, з 2 хвилинами на обидва файли. Кожне завантаження обмежено 256 МБ.
6. SHA-256 архіву має збігатися з його рядком у `checksums.txt`, перш ніж відбудеться будь-що інше. Відсутній рядок або інша контрольна сума зупиняє оновлення з повідомленням `nothing was changed`.
7. `extract()` читає tar і бере перший звичайний файл з назвою `ccam`. Теки, посилання та інші записи ігноруються, а виконуваний файл теж обмежено 256 МБ.
8. `Updater.Install` записує новий виконуваний файл через `fsutil.AtomicWrite`: тимчасовий файл `.ccam.tmp*` поруч із виконуваним файлом, з бітами прав доступу старого файлу, скидається на диск і перейменовується поверх старого.

Увесь конвеєр, від пошуку тегу до перейменування:

Архів і `checksums.txt` завантажуються паралельно, і нічого не записується, доки контрольна сума не збіжиться. Перейменування атомарне, тож збій або заповнений диск залишає або старий виконуваний файл, або новий, але ніколи не половину. Короткі команди, як-от `~/.local/bin/ccwork`, є символьними посиланнями на виконуваний файл ccam, тож вони запускають нову версію без жодних змін.

### Встановлення через менеджер пакетів

ccam, встановлений з `.deb`, належить apt, і заміна його в обхід apt залишила б базу даних пакетів у неправильному стані. Перед завантаженням ccam перевіряє, кому належить виконуваний файл:

1. Виконуваний файл у `/usr/bin`, `/bin`, `/usr/sbin` або `/sbin` вважається керованим менеджером пакетів.
2. В інших місцях, якщо встановлено `dpkg` і `dpkg -S <path>` виконується успішно, файл теж вважається керованим менеджером пакетів.
3. Інакше ccam створює й видаляє тимчасовий файл `.ccam-update-*` поруч із виконуваним файлом, щоб переконатися, що може туди записувати.

Для виконуваного файлу, керованого менеджером пакетів, ccam зупиняється й виводить кроки для apt:

```console
$ ccam update
ccam: /usr/bin/ccam was installed by a package, so `ccam update` leaves it alone.
To update the .deb, download ccam_0.5.0_linux_amd64.deb from https://github.com/jhyunwoo/ccam/releases/tag/v0.5.0 and run:
  sudo apt install ./ccam_0.5.0_linux_amd64.deb
Or install a copy in ~/.local/bin with the install script:
  curl -fsSL https://raw.githubusercontent.com/jhyunwoo/ccam/main/install.sh | sh
```

На системах, відмінних від Linux, виводиться лише рядок зі скриптом встановлення. Коли тека недоступна для запису, ccam пропонує повторно запустити скрипт встановлення, який встановлює ccam у `~/.local/bin`.

## Безпека та граничні випадки

- Збірка для розробки повідомляє версію `dev` і не має випуску для порівняння, тож `ccam update` і `ccam update --check` її відхиляють. `ccam update --version vX.Y.Z` встановлює випуск поверх неї.
- Невдале завантаження, відсутній файл для вашої платформи або розбіжність контрольної суми залишають встановлений виконуваний файл без змін.
- Випуск, якого не існує, призводить до помилки `there is no release <tag>`. Коли GitHub відмовляє з HTTP 403 або 429, ccam повідомляє, що це, ймовірно, обмеження частоти запитів, і просить спробувати пізніше.
- `--check` лише читає. Він не перевіряє, чи керується виконуваний файл менеджером пакетів і чи доступний він для запису.
- `--version` зі старішим тегом — це спосіб відкотитися.

## Пов'язані сторінки

- [Встановлення](https://ccam.dev/uk/docs/install.md)
- [Команди](https://ccam.dev/uk/docs/commands.md)
- [Поширені запитання](https://ccam.dev/uk/docs/faq.md)
