Merge pull request 'Zaříznout stará jména kostky' (#20) from agents/claude/zariznout-stara-jmena into main
testy / pytest (3.11) (push) Successful in 1s
testy / pytest (3.12) (push) Successful in 1s
testy / pytest (3.13) (push) Successful in 1s
testy / pytest (3.14) (push) Successful in 1s
binárka / linux (push) Successful in 10s

Reviewed-on: #20
This commit was merged in pull request #20.
This commit is contained in:
david-spacil committed 2026-08-23 23:14:58 +02:00
commit c0272f4f70
7 files changed
+14 -156

No files matched your search

+3 -8
View File
@@ -93,9 +93,6 @@ jobs:
env: env:
TOKEN: ${{ secrets.GITHUB_TOKEN }} TOKEN: ${{ secrets.GITHUB_TOKEN }}
ASSET: dice-counter-linux-x86_64 ASSET: dice-counter-linux-x86_64
# Instalátory z dřívějška si chodí pro staré jméno. Až budou
# přemigrované, přestane se pod ním věšet.
STARY_ASSET: kostky-linux-x86_64
run: | run: |
api="${GITHUB_SERVER_URL}/api/v1/repos/${GITHUB_REPOSITORY}" api="${GITHUB_SERVER_URL}/api/v1/repos/${GITHUB_REPOSITORY}"
auth="Authorization: token ${TOKEN}" auth="Authorization: token ${TOKEN}"
@@ -113,12 +110,10 @@ jobs:
# Součet se počítá nad jménem, pod kterým se soubor stahuje, aby # Součet se počítá nad jménem, pod kterým se soubor stahuje, aby
# šel ověřit rovnou: sha256sum -c dice-counter-linux-x86_64.sha256 # šel ověřit rovnou: sha256sum -c dice-counter-linux-x86_64.sha256
for jmeno in "$ASSET" "$STARY_ASSET"; do cp dist/dice-counter "$ASSET"
cp dist/dice-counter "$jmeno" sha256sum "$ASSET" | tee "$ASSET.sha256"
sha256sum "$jmeno" | tee "$jmeno.sha256"
done
for file in "$ASSET" "$ASSET.sha256" "$STARY_ASSET" "$STARY_ASSET.sha256"; do for file in "$ASSET" "$ASSET.sha256"; do
# Aby se dal build zopakovat, stará příloha stejného jména jde pryč. # Aby se dal build zopakovat, stará příloha stejného jména jde pryč.
curl -s -H "$auth" "$api/releases/$id/assets" \ curl -s -H "$auth" "$api/releases/$id/assets" \
| python3 -c 'import json,sys; [print(a["id"]) for a in json.load(sys.stdin) if a["name"] == sys.argv[1]]' "$file" \ | python3 -c 'import json,sys; [print(a["id"]) for a in json.load(sys.stdin) if a["name"] == sys.argv[1]]' "$file" \
+3 -13
View File
@@ -29,25 +29,18 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
# `stary` je jméno, pod kterým se příloha věšela do vydání 1.2.x.
# Instalátory z té doby si chodí pro něj, tak se pověsí obojí.
# Až budou přemigrované, sloupec zmizí.
include: include:
- os: windows-latest - os: windows-latest
asset: dice-counter-windows-x86_64.exe asset: dice-counter-windows-x86_64.exe
stary: kostky-windows-x86_64.exe
built: dist/dice-counter.exe built: dist/dice-counter.exe
- os: macos-15-intel # Intel; macos-13 GitHub zrušil - os: macos-15-intel # Intel; macos-13 GitHub zrušil
asset: dice-counter-macos-x86_64 asset: dice-counter-macos-x86_64
stary: kostky-macos-x86_64
built: dist/dice-counter built: dist/dice-counter
- os: macos-latest # Apple Silicon - os: macos-latest # Apple Silicon
asset: dice-counter-macos-arm64 asset: dice-counter-macos-arm64
stary: kostky-macos-arm64
built: dist/dice-counter built: dist/dice-counter
- os: ubuntu-24.04-arm # pro Raspberry Pi a spol. - os: ubuntu-24.04-arm # pro Raspberry Pi a spol.
asset: dice-counter-linux-arm64 asset: dice-counter-linux-arm64
stary: kostky-linux-arm64
built: dist/dice-counter built: dist/dice-counter
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
@@ -104,7 +97,6 @@ jobs:
env: env:
TOKEN: ${{ secrets.GITEA_TOKEN }} TOKEN: ${{ secrets.GITEA_TOKEN }}
ASSET: ${{ matrix.asset }} ASSET: ${{ matrix.asset }}
STARY_ASSET: ${{ matrix.stary }}
run: | run: |
api="$GITEA/api/v1/repos/$GITEA_REPO" api="$GITEA/api/v1/repos/$GITEA_REPO"
auth="Authorization: token $TOKEN" auth="Authorization: token $TOKEN"
@@ -133,12 +125,10 @@ jobs:
# Součet se počítá nad jménem, pod kterým se soubor stahuje, aby # Součet se počítá nad jménem, pod kterým se soubor stahuje, aby
# šel ověřit rovnou: shasum -a 256 -c dice-counter-macos-arm64.sha256 # šel ověřit rovnou: shasum -a 256 -c dice-counter-macos-arm64.sha256
for jmeno in "$ASSET" "$STARY_ASSET"; do cp "${{ matrix.built }}" "$ASSET"
cp "${{ matrix.built }}" "$jmeno" soucet "$ASSET" | tee "$ASSET.sha256"
soucet "$jmeno" | tee "$jmeno.sha256"
done
for file in "$ASSET" "$ASSET.sha256" "$STARY_ASSET" "$STARY_ASSET.sha256"; do for file in "$ASSET" "$ASSET.sha256"; do
# Aby se dal build zopakovat, stará příloha stejného jména jde pryč. # Aby se dal build zopakovat, stará příloha stejného jména jde pryč.
curl -s -H "$auth" "$api/releases/$id/assets" \ curl -s -H "$auth" "$api/releases/$id/assets" \
| json 'import json,sys; [print(a["id"]) for a in json.load(sys.stdin) if a["name"] == sys.argv[1]]' "$file" \ | json 'import json,sys; [print(a["id"]) for a in json.load(sys.stdin) if a["name"] == sys.argv[1]]' "$file" \
-15
View File
@@ -93,10 +93,6 @@ server vypíše při startu.
| binárkou na Windows | `%LOCALAPPDATA%\dice-counter\dice.db` | | binárkou na Windows | `%LOCALAPPDATA%\dice-counter\dice.db` |
| ze zdrojáků | `dice.db` v pracovním adresáři | | ze zdrojáků | `dice.db` v pracovním adresáři |
Do vydání 1.2.x se adresář jmenoval `kostky`. Kdo databázi po staru má, o ni
nepřijde — dokud nová neexistuje, používá se dál ta stará. Přesunout se dá
kdykoli ručně, přejmenováním adresáře.
Binárka se při každém spuštění rozbaluje do dočasného adresáře a pouští se Binárka se při každém spuštění rozbaluje do dočasného adresáře a pouští se
odkudkoli, takže relativní cesta by databázi rozsypala po disku — proto odkudkoli, takže relativní cesta by databázi rozsypala po disku — proto
napevno domovský adresář. Ze zdrojáků zůstává relativní, ať se dá mít víc napevno domovský adresář. Ze zdrojáků zůstává relativní, ať se dá mít víc
@@ -174,13 +170,6 @@ Obojí vymění binárku za poslední vydání a službu restartuje; databáze z
Příkaz `update` si přitom obnoví i sám sebe — instalátor bere z větve `main`, Příkaz `update` si přitom obnoví i sám sebe — instalátor bere z větve `main`,
takže jede na nejnovější verzi skriptu, ne na té, se kterou se instalovalo. takže jede na nejnovější verzi skriptu, ne na té, se kterou se instalovalo.
Kontejnery založené do vydání 1.2.x se při první aktualizaci přejmenují ze
starého `kostky`: služba, uživatel i cesty dostanou nová jména a databáze se
přestěhuje z `/var/lib/kostky` do `/var/lib/dice-counter`. Dělá se to samo
a stačí na to obyčejný `update`; historie her zůstává. Původní adresa skriptu
(`deploy/pve-kostky.sh`) proto ještě chvíli funguje — jen přesměrovává na
novou.
Do konzole kontejneru se dostaneš přímo z webu Proxmoxu, **žádné jméno ani Do konzole kontejneru se dostaneš přímo z webu Proxmoxu, **žádné jméno ani
heslo se nezadává** — kontejner root heslo nemá a konzole se přihlašuje sama. heslo se nezadává** — kontejner root heslo nemá a konzole se přihlašuje sama.
Nová práva to nikomu nedává: kdo se dostane do webu Proxmoxu, má root na uzlu Nová práva to nikomu nedává: kdo se dostane do webu Proxmoxu, má root na uzlu
@@ -380,10 +369,6 @@ ověřit:
sha256sum -c dice-counter-linux-x86_64.sha256 # na macOS: shasum -a 256 -c sha256sum -c dice-counter-linux-x86_64.sha256 # na macOS: shasum -a 256 -c
``` ```
Do vydání 1.2.x se přílohy jmenovaly `kostky-*`. Ještě chvíli se budou věšet
pod oběma jmény, ať fungují instalace, které si o ně říkají po staru. Až budou
přemigrované, zůstane jen `dice-counter-*`.
Nad pull requesty se Linux staví taky, jen se nikam nevěší. Totéž platí pro Nad pull requesty se Linux staví taky, jen se nikam nevěší. Totéž platí pro
kontejnerový image — doma se nad každým PR postaví a zkusí nastartovat kontejnerový image — doma se nad každým PR postaví a zkusí nastartovat
(`.gitea/workflows/image.yml`), publikuje se ale až z tagu na GitHubu. (`.gitea/workflows/image.yml`), publikuje se ale až z tagu na GitHubu.
+5 -59
View File
@@ -84,20 +84,13 @@ HOME_DIR=/opt/dice-counter
DATA_DIR=/var/lib/dice-counter DATA_DIR=/var/lib/dice-counter
SERVICE=dice-counter SERVICE=dice-counter
# Do vydání 1.2.x se všechno jmenovalo kostky. Instalace z té doby se při
# aktualizaci přestěhují; až budou přemigrované, tenhle blok zmizí.
STARY_USER=kostky
STARY_HOME=/opt/kostky
STARY_DATA=/var/lib/kostky
STARA_SLUZBA=kostky
msg() { echo -e "\e[1;34m →\e[0m $*"; } msg() { echo -e "\e[1;34m →\e[0m $*"; }
ok() { echo -e "\e[1;32m ✓\e[0m $*"; } ok() { echo -e "\e[1;32m ✓\e[0m $*"; }
die() { echo -e "\e[1;31m ✗\e[0m $*" >&2; exit 1; } die() { echo -e "\e[1;31m ✗\e[0m $*" >&2; exit 1; }
case "$(dpkg --print-architecture)" in case "$(dpkg --print-architecture)" in
amd64) PLATFORMA=linux-x86_64 ;; amd64) ASSET=dice-counter-linux-x86_64 ;;
arm64) PLATFORMA=linux-arm64 ;; arm64) ASSET=dice-counter-linux-arm64 ;;
*) die "Pro architekturu $(dpkg --print-architecture) binárka není." ;; *) die "Pro architekturu $(dpkg --print-architecture) binárka není." ;;
esac esac
@@ -114,22 +107,15 @@ if [ -z "$VERSION" ]; then
| grep -o '"tag_name":[[:space:]]*"[^"]*"' | head -1 | cut -d'"' -f4) | grep -o '"tag_name":[[:space:]]*"[^"]*"' | head -1 | cut -d'"' -f4)
[ -n "$VERSION" ] || die "Nepodařilo se zjistit poslední verzi z $GITEA." [ -n "$VERSION" ] || die "Nepodařilo se zjistit poslední verzi z $GITEA."
fi fi
ok "Instaluje se $VERSION pro $PLATFORMA" ok "Instaluje se $VERSION ($ASSET)"
BASE="$GITEA/$REPO/releases/download/$VERSION" BASE="$GITEA/$REPO/releases/download/$VERSION"
TMP=$(mktemp -d) TMP=$(mktemp -d)
trap 'rm -rf "$TMP"' EXIT trap 'rm -rf "$TMP"' EXIT
msg "Stahuji binárku" msg "Stahuji binárku"
# Do vydání 1.2.x se přílohy jmenovaly kostky-*. Starší vydání se tak dají curl -fsSL -o "$TMP/$ASSET" "$BASE/$ASSET" \
# nainstalovat dál; až stará jména z releasů zmizí, zůstane jen to první. || die "$ASSET pro $VERSION na releasu není. Vydání pro tuhle architekturu možná ještě neproběhlo."
ASSET=""
for jmeno in "dice-counter-$PLATFORMA" "kostky-$PLATFORMA"; do
curl -fsSL -o "$TMP/$jmeno" "$BASE/$jmeno" 2>/dev/null && { ASSET="$jmeno"; break; }
done
[ -n "$ASSET" ] \
|| die "Binárka pro $PLATFORMA ve vydání $VERSION není. Pro tuhle architekturu možná ještě nevyšla."
curl -fsSL -o "$TMP/$ASSET.sha256" "$BASE/$ASSET.sha256" \ curl -fsSL -o "$TMP/$ASSET.sha256" "$BASE/$ASSET.sha256" \
|| die "Chybí kontrolní součet — radši nic neinstaluju." || die "Chybí kontrolní součet — radši nic neinstaluju."
@@ -143,38 +129,6 @@ id -u "$USER_NAME" >/dev/null 2>&1 \
install -d -o root -g root -m 755 "$HOME_DIR" install -d -o root -g root -m 755 "$HOME_DIR"
# Instalace z doby, kdy se všechno jmenovalo kostky, se tady převezme. Bez
# přestěhování databáze by po aktualizaci zmizela historie her, takže se to
# nedá odbýt smazáním staré služby.
#
# Starý domovský adresář se maže až úplně na konci skriptu: při aktualizaci
# běžícího kontejneru se instalátor pouští právě z něj a `$0` z něj ještě
# potřebujeme zkopírovat na nové místo.
if [ -f "/etc/systemd/system/$STARA_SLUZBA.service" ] \
|| [ -d "$STARY_HOME" ] || [ -d "$STARY_DATA" ]; then
msg "Našel jsem instalaci pod starým jménem, stěhuji ji"
systemctl is-active --quiet "$STARA_SLUZBA" && systemctl stop "$STARA_SLUZBA"
systemctl disable --quiet "$STARA_SLUZBA" 2>/dev/null || true
rm -f "/etc/systemd/system/$STARA_SLUZBA.service"
systemctl daemon-reload
# Když nový adresář z nějakého důvodu už existuje, starý se nechá být.
# Přepsat cizí databázi je horší než nechat po sobě adresář navíc.
if [ -d "$STARY_DATA" ] && [ ! -e "$DATA_DIR" ]; then
mv "$STARY_DATA" "$DATA_DIR"
ok "Databáze přestěhována do $DATA_DIR"
elif [ -d "$STARY_DATA" ]; then
msg "$DATA_DIR už existuje, $STARY_DATA nechávám na místě"
fi
id -u "$STARY_USER" >/dev/null 2>&1 && userdel "$STARY_USER" 2>/dev/null || true
fi
# Po stěhování patří soubory uživateli, který už neexistuje. StateDirectory
# to u založeného adresáře nedorovná, tak se to udělá rovnou tady.
[ -d "$DATA_DIR" ] && chown -R "$USER_NAME:$USER_NAME" "$DATA_DIR"
# Zastavit se dá jen to, co běží — při první instalaci služba ještě není. # Zastavit se dá jen to, co běží — při první instalaci služba ještě není.
if systemctl is-active --quiet "$SERVICE"; then if systemctl is-active --quiet "$SERVICE"; then
systemctl stop "$SERVICE" systemctl stop "$SERVICE"
@@ -273,14 +227,6 @@ UPDATE
chmod 755 /usr/bin/update chmod 755 /usr/bin/update
ok "Aktualizovat půjde příkazem: update" ok "Aktualizovat půjde příkazem: update"
# Teď už je `$0` zkopírovaný na nové místo a starý domov nikdo nepotřebuje.
# Bash si drží otevřený popisovač na skript, takže smazat se dá i ten, který
# se zrovna vykonává.
if [ -d "$STARY_HOME" ]; then
rm -rf "$STARY_HOME"
ok "Staré $STARY_HOME uklizeno"
fi
msg "Čekám, až začne odpovídat" msg "Čekám, až začne odpovídat"
for _ in $(seq 30); do for _ in $(seq 30); do
curl -fsS -o /dev/null "http://127.0.0.1:$PORT/" 2>/dev/null && break curl -fsS -o /dev/null "http://127.0.0.1:$PORT/" 2>/dev/null && break
-23
View File
@@ -1,23 +0,0 @@
#!/usr/bin/env bash
# Skript se přejmenoval na deploy/pve-dice-counter.sh.
#
# Tenhle soubor tu zůstává schválně. Příkaz `update` v už založených
# kontejnerech si instalátor stahuje z téhle adresy — kdyby zmizela,
# aktualizace by u nich přestala fungovat dřív, než se stihnou přemigrovat.
# Až se tak stane, zmizí i tenhle soubor.
#
# Předává se všechno beze změny, včetně argumentů a proměnných prostředí.
# Na stdout nesmí přibýt ani řádek navíc: starý `update` si sem chodí pro
# `instalator` a výstup rovnou kontroluje přes `bash -n`.
set -euo pipefail
GITEA="${GITEA:-https://gitea.spacilovi.eu}"
REPO="${REPO:-david-spacil/dice-counter}"
NOVY=$(mktemp)
trap 'rm -f "$NOVY"' EXIT
curl -fsSL "$GITEA/$REPO/raw/branch/main/deploy/pve-dice-counter.sh" -o "$NOVY" \
|| { echo "Skript se přesunul do deploy/pve-dice-counter.sh, ale nejde stáhnout." >&2; exit 1; }
bash "$NOVY" "$@"
+3 -16
View File
@@ -27,14 +27,6 @@ def data_home() -> Path:
or Path.home() / ".local" / "share") or Path.home() / ".local" / "share")
APP_DIR = "dice-counter"
# Do vydání 1.2.x se adresář jmenoval jinak. Kdo má databázi po staru, o ni
# přejmenováním nepřijde — použije se dál. Až se stará jména přestanou
# podporovat, zmizí i tohle.
STARY_APP_DIR = "kostky"
def default_db() -> Path: def default_db() -> Path:
"""Kam se ukládá databáze. """Kam se ukládá databáze.
@@ -46,14 +38,9 @@ def default_db() -> Path:
chosen = os.environ.get("DICE_DB") chosen = os.environ.get("DICE_DB")
if chosen: if chosen:
return Path(chosen) return Path(chosen)
if not getattr(sys, "frozen", False): if getattr(sys, "frozen", False):
return Path("dice.db") return data_home() / "dice-counter" / "dice.db"
return Path("dice.db")
nova = data_home() / APP_DIR / "dice.db"
stara = data_home() / STARY_APP_DIR / "dice.db"
if not nova.exists() and stara.exists():
return stara
return nova
DB_PATH = default_db() DB_PATH = default_db()
-22
View File
@@ -155,28 +155,6 @@ def test_umisteni_databaze_z_binarky(monkeypatch, tmp_path):
assert storage.default_db() == tmp_path / "dice-counter" / "dice.db" assert storage.default_db() == tmp_path / "dice-counter" / "dice.db"
def test_umisteni_databaze_po_starem(monkeypatch, tmp_path):
"""Kdo má databázi pod starým jménem, o ni přejmenováním nepřijde."""
monkeypatch.delenv("DICE_DB", raising=False)
monkeypatch.setattr(storage.sys, "frozen", True, raising=False)
monkeypatch.setattr(storage.sys, "platform", "linux")
monkeypatch.setenv("XDG_DATA_HOME", str(tmp_path))
stara = tmp_path / "kostky" / "dice.db"
stara.parent.mkdir()
stara.touch()
assert storage.default_db() == stara
# Jakmile nová existuje, stará se ignoruje — jinak by se dvě databáze
# přetahovaly o to, která platí.
nova = tmp_path / "dice-counter" / "dice.db"
nova.parent.mkdir()
nova.touch()
assert storage.default_db() == nova
def test_data_home_podle_systemu(monkeypatch, tmp_path): def test_data_home_podle_systemu(monkeypatch, tmp_path):
"""Každý systém má svůj adresář na data; XDG je jen ten linuxový.""" """Každý systém má svůj adresář na data; XDG je jen ten linuxový."""
monkeypatch.setenv("LOCALAPPDATA", str(tmp_path / "AppData" / "Local")) monkeypatch.setenv("LOCALAPPDATA", str(tmp_path / "AppData" / "Local"))