generated from GarandPLG/rust-flake-template
Test packaging #2
No files matched your search
@@ -0,0 +1,109 @@
|
|||||||
|
name: Linux package builds (test)
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
pull_request:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
linux:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container: node:22-bookworm
|
||||||
|
env:
|
||||||
|
CARGO_HOME: /root/.cargo
|
||||||
|
RUSTUP_HOME: /root/.rustup
|
||||||
|
RUST_VERSION: 1.99.1
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: https://github.com/actions/checkout@v4
|
||||||
|
- name: Install packaging dependencies
|
||||||
|
run: |
|
||||||
|
apt-get update
|
||||||
|
apt-get install -y --no-install-recommends ca-certificates curl build-essential pkg-config libasound2-dev python3 rpm cpio desktop-file-utils squashfs-tools p7zip-full file flatpak ostree zstd
|
||||||
|
- name: Rust toolchain cache
|
||||||
|
uses: https://github.com/actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
/root/.rustup
|
||||||
|
/root/.cargo/bin
|
||||||
|
key: rust-toolchain-v1-linux-x64-${{ env.RUST_VERSION }}
|
||||||
|
- name: Install Rust
|
||||||
|
run: |
|
||||||
|
if [ ! -x "$CARGO_HOME/bin/rustup" ]; then
|
||||||
|
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs -o /tmp/rustup-init.sh
|
||||||
|
sh /tmp/rustup-init.sh -y --profile minimal --default-toolchain none --no-modify-path
|
||||||
|
fi
|
||||||
|
"$CARGO_HOME/bin/rustup" toolchain install "$RUST_VERSION" --profile minimal --component rustfmt --component clippy
|
||||||
|
"$CARGO_HOME/bin/rustup" default "$RUST_VERSION"
|
||||||
|
echo "$CARGO_HOME/bin" >> "$GITHUB_PATH"
|
||||||
|
- name: Cargo cache
|
||||||
|
uses: https://github.com/actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
/root/.cargo/registry
|
||||||
|
/root/.cargo/git
|
||||||
|
target
|
||||||
|
key: packages-v1-linux-x64-${{ env.RUST_VERSION }}-${{ hashFiles('Cargo.lock') }}-${{ hashFiles('Cargo.toml', 'src/**', 'tests/**') }}
|
||||||
|
restore-keys: |
|
||||||
|
packages-v1-linux-x64-${{ env.RUST_VERSION }}-${{ hashFiles('Cargo.lock') }}-
|
||||||
|
- name: Compile Linux binary
|
||||||
|
id: compile
|
||||||
|
run: cargo build --release --locked
|
||||||
|
- name: Build deb
|
||||||
|
if: ${{ !cancelled() && steps.compile.outcome == 'success' }}
|
||||||
|
run: bash packaging/build.sh deb
|
||||||
|
- name: Build rpm
|
||||||
|
if: ${{ !cancelled() && steps.compile.outcome == 'success' }}
|
||||||
|
run: bash packaging/build.sh rpm
|
||||||
|
- name: Build AppImage
|
||||||
|
if: ${{ !cancelled() && steps.compile.outcome == 'success' }}
|
||||||
|
run: bash packaging/build.sh appimage
|
||||||
|
- name: Build Flatpak
|
||||||
|
if: ${{ !cancelled() && steps.compile.outcome == 'success' }}
|
||||||
|
run: bash packaging/build.sh flatpak
|
||||||
|
- name: Save test packages
|
||||||
|
if: ${{ !cancelled() }}
|
||||||
|
uses: https://github.com/actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: linux-packages-x86_64
|
||||||
|
path: dist/*
|
||||||
|
if-no-files-found: error
|
||||||
|
retention-days: 7
|
||||||
|
|
||||||
|
aur:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container: archlinux:base-devel
|
||||||
|
steps:
|
||||||
|
- name: Install Arch dependencies
|
||||||
|
run: |
|
||||||
|
pacman -Syu --noconfirm --needed git nodejs rust cargo pkgconf alsa-lib python zstd
|
||||||
|
node --version
|
||||||
|
- name: Checkout
|
||||||
|
uses: https://github.com/actions/checkout@v4
|
||||||
|
- name: Build AUR recipe from this commit
|
||||||
|
run: |
|
||||||
|
version=$(python -c 'import tomllib; print(tomllib.load(open("Cargo.toml", "rb"))["package"]["version"])')
|
||||||
|
recipe_version=$(bash -c 'source packaging/aur/PKGBUILD; printf "%s" "$pkgver"')
|
||||||
|
test "$version" = "$recipe_version"
|
||||||
|
mkdir -p /tmp/aur-build
|
||||||
|
cp packaging/aur/PKGBUILD /tmp/aur-build/
|
||||||
|
tar --exclude=.git --exclude=target --exclude=dist --transform="s,^\./,war-in-tunnels-$version/," -czf "/tmp/aur-build/war-in-tunnels-$version.tar.gz" .
|
||||||
|
cd /tmp/aur-build
|
||||||
|
checksum=$(sha256sum "war-in-tunnels-$version.tar.gz" | cut -d ' ' -f 1)
|
||||||
|
sed -i "s/sha256sums=('SKIP')/sha256sums=('$checksum')/" PKGBUILD
|
||||||
|
useradd -m builder
|
||||||
|
chown -R builder:builder /tmp/aur-build
|
||||||
|
runuser -u builder -- bash -c 'cd /tmp/aur-build && makepkg --cleanbuild --noconfirm && makepkg --printsrcinfo > .SRCINFO'
|
||||||
|
pacman -U --noconfirm ./*.pkg.tar.zst
|
||||||
|
cd /tmp
|
||||||
|
war-in-tunnels --version
|
||||||
|
- name: Save Arch test package and recipe
|
||||||
|
uses: https://github.com/actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: arch-package-x86_64
|
||||||
|
path: |
|
||||||
|
/tmp/aur-build/*.pkg.tar.zst
|
||||||
|
/tmp/aur-build/PKGBUILD
|
||||||
|
/tmp/aur-build/.SRCINFO
|
||||||
|
/tmp/aur-build/*.tar.gz
|
||||||
|
if-no-files-found: error
|
||||||
|
retention-days: 7
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
/target
|
/target
|
||||||
/result
|
/result
|
||||||
|
/dist
|
||||||
|
|
||||||
war_in_tunnels.log
|
war_in_tunnels.log
|
||||||
+4
-2
@@ -23,14 +23,16 @@ nix develop -c cargo run -- --help
|
|||||||
nix develop -c cargo run -- --disable-audio --view skirmish
|
nix develop -c cargo run -- --disable-audio --view skirmish
|
||||||
```
|
```
|
||||||
|
|
||||||
Ostatnie polecenie wymaga interaktywnego terminala. `shellHook` sam wykonuje `cargo run --locked -- -h`, więc wejście do środowiska także kompiluje program i drukuje pomoc. Przy kontrolach używaj `--locked`, aby nie aktualizować `Cargo.lock`. Formatowanie stosuj wyłącznie do uzgodnionych zmian; nie używaj automatycznego `clippy --fix` do porządkowania całego repozytorium.
|
Ostatnie polecenie wymaga interaktywnego terminala. `shellHook` drukuje dostępne polecenia, bez automatycznej kompilacji. Przy kontrolach używaj `--locked`, aby nie aktualizować `Cargo.lock`. Formatowanie stosuj wyłącznie do uzgodnionych zmian; nie używaj automatycznego `clippy --fix` do porządkowania całego repozytorium.
|
||||||
|
|
||||||
Stan bazowy po konfiguracji lintów: 45 testów i formatowanie przechodzą; Clippy zgłasza 50 ostrzeżeń dla biblioteki. `clippy::unused_unit` jest dozwolony ze względu na wymagane jawne `-> ()`. Zakres i polecenia opisano w [TESTING.md](TESTING.md). Nie traktuj tego jako potwierdzenia działania pełnej rozgrywki. Nowa nietrywialna logika wymaga małego testu regresji. Nie dodawaj zależności ani warstw abstrakcji bez potrzeby.
|
Aktualny zestaw obejmuje 46 testów. Stan bazowy Clippy to 50 ostrzeżeń dla biblioteki. `clippy::unused_unit` jest dozwolony ze względu na wymagane jawne `-> ()`. Zakres i polecenia opisano w [TESTING.md](TESTING.md). Nie traktuj tego jako potwierdzenia działania pełnej rozgrywki. Nowa nietrywialna logika wymaga małego testu regresji. Nie dodawaj zależności ani warstw abstrakcji bez potrzeby.
|
||||||
|
|
||||||
`Cargo.toml` wymaga Rust 1.88 lub nowszego, zabrania `unsafe` we własnym kodzie i ignorowania wyników `must_use`, a w release włącza kontrolę przepełnień. CI Gitea w `.gitea/workflows/rust.yml` sprawdza formatowanie, kompilację, testy debug/release i Clippy bez Nix, przez Rust 1.99.1 instalowany rustup; lokalnie nadal używaj Nix. Oddzielny `.gitea/workflows/nix.yml` buduje `.#default` z `default.nix`, z testami pakietu i kontrolą instalacji. Nie dodawaj `-D warnings` przed uporządkowaniem istniejących ostrzeżeń.
|
`Cargo.toml` wymaga Rust 1.88 lub nowszego, zabrania `unsafe` we własnym kodzie i ignorowania wyników `must_use`, a w release włącza kontrolę przepełnień. CI Gitea w `.gitea/workflows/rust.yml` sprawdza formatowanie, kompilację, testy debug/release i Clippy bez Nix, przez Rust 1.99.1 instalowany rustup; lokalnie nadal używaj Nix. Oddzielny `.gitea/workflows/nix.yml` buduje `.#default` z `default.nix`, z testami pakietu i kontrolą instalacji. Nie dodawaj `-D warnings` przed uporządkowaniem istniejących ostrzeżeń.
|
||||||
|
|
||||||
Audio wymaga ALSA i urządzenia odtwarzania; do pracy nad TUI używaj `--disable-audio`. `--mute` nadal uruchamia wątek audio. Ścieżki zasobów i pakowanie sprawdzaj osobno przy zmianach audio/Nix. Rozróżniaj lokalny build Cargo, pakiet `.#develop` i domyślny pakiet Nix.
|
Audio wymaga ALSA i urządzenia odtwarzania; do pracy nad TUI używaj `--disable-audio`. `--mute` nadal uruchamia wątek audio. Ścieżki zasobów i pakowanie sprawdzaj osobno przy zmianach audio/Nix. Rozróżniaj lokalny build Cargo, pakiet `.#develop` i domyślny pakiet Nix.
|
||||||
|
|
||||||
|
`.gitea/workflows/packages.yml` testuje paczki Linux x86_64 bez Nix: deb, rpm, AppImage, Flatpak oraz przepis AUR budowany przez makepkg. Nie publikuje wydań ani tagów. Przepisy, layout i ograniczenia opisano w [PACKAGING.md](PACKAGING.md); zmiany pakowania muszą zachować muzykę obok binarki i działanie poza katalogiem repozytorium.
|
||||||
|
|
||||||
## Konwencje kodu
|
## Konwencje kodu
|
||||||
|
|
||||||
- Formatowanie określa `rustfmt.toml`: styl Rust 2024, wcięcia po 2 spacje, szerokość docelowa 100 znaków i zakończenia LF. Stosuj `nix develop -c cargo fmt --all`; kontroluj przez `nix develop -c cargo fmt --all -- --check`.
|
- Formatowanie określa `rustfmt.toml`: styl Rust 2024, wcięcia po 2 spacje, szerokość docelowa 100 znaków i zakończenia LF. Stosuj `nix develop -c cargo fmt --all`; kontroluj przez `nix develop -c cargo fmt --all -- --check`.
|
||||||
|
|||||||
+3
-2
@@ -24,6 +24,7 @@ Wszystkie ścieżki poniżej są względem katalogu głównego repozytorium.
|
|||||||
| Formatowanie | `rustfmt.toml` | Rustfmt, styl 2024, wcięcia po 2 spacje, docelowo 100 znaków i zakończenia LF |
|
| Formatowanie | `rustfmt.toml` | Rustfmt, styl 2024, wcięcia po 2 spacje, docelowo 100 znaków i zakończenia LF |
|
||||||
| Kontrole CI | `.gitea/workflows/rust.yml` | Gitea Actions w `node:22-bookworm`: Rust 1.99.1 przez rustup, cache toolchaina i Cargo, formatowanie, kompilacja, testy debug/release i Clippy |
|
| Kontrole CI | `.gitea/workflows/rust.yml` | Gitea Actions w `node:22-bookworm`: Rust 1.99.1 przez rustup, cache toolchaina i Cargo, formatowanie, kompilacja, testy debug/release i Clippy |
|
||||||
| Budowa paczki Nix | `.gitea/workflows/nix.yml` | Oddzielny workflow buduje `.#default`, czyli `default.nix` przez nixpkgs przypięte w `flake.lock`, z testami i kontrolą instalacji pakietu |
|
| Budowa paczki Nix | `.gitea/workflows/nix.yml` | Oddzielny workflow buduje `.#default`, czyli `default.nix` przez nixpkgs przypięte w `flake.lock`, z testami i kontrolą instalacji pakietu |
|
||||||
|
| Paczki Linux | `.gitea/workflows/packages.yml`, `packaging/` | Testowe deb, rpm, AppImage, Flatpak oraz makepkg dla AUR; bez wydań i tagów; szczegóły w `docs/PACKAGING.md` |
|
||||||
| Licencja | `LICENSE`, `Cargo.toml`, `default.nix` | MIT, Copyright (c) 2026 GarandPLG |
|
| Licencja | `LICENSE`, `Cargo.toml`, `default.nix` | MIT, Copyright (c) 2026 GarandPLG |
|
||||||
| Zasoby | `soundtracks/default/`, `ui_draft/` | Dwa pliki OGG i tekstowe szkice ekranów |
|
| Zasoby | `soundtracks/default/`, `ui_draft/` | Dwa pliki OGG i tekstowe szkice ekranów |
|
||||||
|
|
||||||
@@ -104,7 +105,7 @@ Postęp bieżącego kroku jest udostępniany przez `MovingTask::get_movement_pro
|
|||||||
|
|
||||||
Główny wątek wysyła `AudioCmd`; osobny wątek obsługuje głośność, mute, część i soundtrack. Cache wykorzystuje `Lazy`, `RwLock`, `Arc` i bajty OGG. Calm ładuje `calm.ogg`; Buildup, Assault i Outro korzystają obecnie z `test.ogg`. Błędy urządzenia, odczytu i dekodowania mogą zakończyć wątek przez `expect`.
|
Główny wątek wysyła `AudioCmd`; osobny wątek obsługuje głośność, mute, część i soundtrack. Cache wykorzystuje `Lazy`, `RwLock`, `Arc` i bajty OGG. Calm ładuje `calm.ogg`; Buildup, Assault i Outro korzystają obecnie z `test.ogg`. Błędy urządzenia, odczytu i dekodowania mogą zakończyć wątek przez `expect`.
|
||||||
|
|
||||||
Rodio zapętla źródło przez `Decoder::new_looped`. Wątek sterujący blokuje się na odbiorniku (`for cmd in rx`), zamiast aktywnie sprawdzać komendy i koniec utworu. Zmiana części lub soundtracku dopisuje zapętlone źródło i pomija bieżące przez `skip_one`. Zamknięcie kanału kończy wątek. Test `audio_repeats_after_end_of_file` sprawdza przekroczenie końca rzeczywistego pliku OGG bez urządzenia audio.
|
Rodio zapętla źródło przez `Decoder::new_looped`. Wątek sterujący blokuje się na odbiorniku (`for cmd in rx`), zamiast aktywnie sprawdzać komendy i koniec utworu. Zmiana części lub soundtracku dopisuje zapętlone źródło i pomija bieżące przez `skip_one`. Zamknięcie kanału kończy wątek. Soundtracki są szukane obok rzeczywistej binarki, z fallbackiem do bieżącego katalogu dla Cargo. Testy audio obejmują zapętlanie OGG i ładowanie zasobów poza repozytorium, bez urządzenia audio.
|
||||||
|
|
||||||
`flake.nix` dostarcza devShell dla `x86_64-linux`, domyślny pakiet z `default.nix` i pakiet `.#develop` budowany przez Naersk. Obie ścieżki pakowania kopiują soundtracki do `$out/bin` i zmieniają nazwę binarki na `war-in-tunnels`. `default.nix` ma stały `cargoHash`; po zmianie zależności wymaga osobnej weryfikacji. Samo `cargo test` nie sprawdza pakowania.
|
`flake.nix` dostarcza devShell dla `x86_64-linux`, domyślny pakiet z `default.nix` i pakiet `.#develop` budowany przez Naersk. Obie ścieżki pakowania kopiują soundtracki do `$out/bin` i zmieniają nazwę binarki na `war-in-tunnels`. `default.nix` ma stały `cargoHash`; po zmianie zależności wymaga osobnej weryfikacji. Samo `cargo test` nie sprawdza pakowania.
|
||||||
|
|
||||||
@@ -116,7 +117,7 @@ To obserwacje statyczne, nie lista napraw wykonanych w tej sesji:
|
|||||||
- **Zaznaczenie:** wybrany górnik czeka podczas rysowania trasy; inne jednostki wykonują zadania normalnie.
|
- **Zaznaczenie:** wybrany górnik czeka podczas rysowania trasy; inne jednostki wykonują zadania normalnie.
|
||||||
- **Audio:** usunięto aktywne odpytywanie; pomiar CPU na docelowym urządzeniu i odsłuch pozostają do wykonania. Test dekodera nie weryfikuje urządzenia audio.
|
- **Audio:** usunięto aktywne odpytywanie; pomiar CPU na docelowym urządzeniu i odsłuch pozostają do wykonania. Test dekodera nie weryfikuje urządzenia audio.
|
||||||
- **Granice UI:** małe terminale, resize i trzy poziomy zoomu wymagają interaktywnego sprawdzenia. Indeksowanie planszy zakłada poprawne współrzędne.
|
- **Granice UI:** małe terminale, resize i trzy poziomy zoomu wymagają interaktywnego sprawdzenia. Indeksowanie planszy zakłada poprawne współrzędne.
|
||||||
- **Pokrycie:** 45 testów CLI, sterowania, renderowania, planszy, wykonywania zadań i dekodowania audio; szczegóły w [TESTING.md](TESTING.md). Workflow Gitea sprawdza też profil release; nie obejmuje pełnej rozgrywki. Clippy zgłasza 50 ostrzeżeń biblioteki, `unused_unit` jest jawnie dozwolony. Nie uruchamiać automatycznych poprawek poza zakresem zadania.
|
- **Pokrycie:** 46 testów CLI, sterowania, renderowania, planszy, wykonywania zadań i dekodowania audio; szczegóły w [TESTING.md](TESTING.md). Workflow Gitea sprawdza też profil release; nie obejmuje pełnej rozgrywki. Clippy zgłasza 50 ostrzeżeń biblioteki, `unused_unit` jest jawnie dozwolony. Nie uruchamiać automatycznych poprawek poza zakresem zadania.
|
||||||
|
|
||||||
## Gdzie zacząć konkretną zmianę
|
## Gdzie zacząć konkretną zmianę
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
# Testowe paczki Linux
|
||||||
|
|
||||||
|
Workflow `.gitea/workflows/packages.yml` uruchamia się po pushu i dla pull requestów. Nie tworzy tagów, wydań ani wpisów w AUR/Flathub. Paczki są niesygnowanymi artefaktami CI przechowywanymi przez 7 dni. Używa `upload-artifact@v3` dla zgodności z Gitea.
|
||||||
|
|
||||||
|
Obsługiwana architektura to x86_64. Są to formaty dystrybucji Linux, nie kompilacje Windows/macOS.
|
||||||
|
|
||||||
|
Job AUR instaluje `nodejs` przed checkoutem: runner 0.6.1 uruchamia akcje JavaScript poleceniem `node`, którego obraz `archlinux:base-devel` nie zawiera. Jest to zależność CI (checkout i upload-artifact), nie zależność gry ani PKGBUILD.
|
||||||
|
|
||||||
|
| Format | Budowanie i kontrola |
|
||||||
|
|---|---|
|
||||||
|
| `.deb` | Rust 1.99.1 w Debian Bookworm, `dpkg-deb`, odczyt metadanych i uruchomienie rozpakowanej binarki z `--version` |
|
||||||
|
| `.rpm` | Ta sama binarka, `rpmbuild` i `packaging/war-in-tunnels.spec`, automatyczne zależności ELF, ekstrakcja i `--version` |
|
||||||
|
| AppImage | AppDir z binarką, muzyką i libasound.so.2; appimagetool 1.9.1; ekstrakcja narzędzia i paczki przez 7z, uruchomienie AppRun z `--version` bez FUSE |
|
||||||
|
| AUR | `packaging/aur/PKGBUILD`, lokalne archiwum bieżącego checkoutu z SHA256, `makepkg` jako zwykły użytkownik w Arch Linux; kompilacja, testy, instalacja paczki i `--version`; eksport .SRCINFO |
|
||||||
|
| Flatpak | Binarka z Debiana pakowana poleceniami `flatpak build-init`, `build-finish`, `build-export`, `build-bundle`; runtime org.freedesktop.Platform 25.08; instalacja paczki w kontenerze, kontrola soundtracku i `--version` zainstalowanej binarki bez sandboxa |
|
||||||
|
|
||||||
|
`packaging/stage.sh` instaluje binarkę i soundtracki w `PREFIX/lib/war-in-tunnels`, launcher w `PREFIX/bin`, licencję, plik desktop z `Terminal=true` i ikonę SVG. Nie zmienia katalogu roboczego, więc opcja `--log` nadal zapisuje log w katalogu wybranym przez użytkownika. Audio najpierw szuka soundtracków obok rzeczywistej binarki, a następnie w bieżącym katalogu dla lokalnego Cargo. Test audio sprawdza działanie poza repozytorium.
|
||||||
|
|
||||||
|
W kontenerze Debian z zależnościami workflow można wykonać:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cargo build --release --locked
|
||||||
|
bash packaging/build.sh deb
|
||||||
|
bash packaging/build.sh rpm
|
||||||
|
bash packaging/build.sh appimage
|
||||||
|
bash packaging/build.sh flatpak
|
||||||
|
```
|
||||||
|
|
||||||
|
Lokalnie na hoście projektu polecenia Cargo uruchamiaj przez `nix develop -c`; binarka zbudowana przez Nix może zależeć od `/nix/store`, dlatego do paczek dystrybucyjnych używaj kompilacji kontenerowej. Skrypty oczekują bieżącego katalogu repozytorium i zapisują wyniki do `dist/`.
|
||||||
|
|
||||||
|
Przepis AUR jest testowy: nie wskazuje publicznego tarballa wydania. Workflow dostarcza lokalny tarball oraz zastępuje `SKIP` rzeczywistym SHA256. Wersja `pkgver` musi odpowiadać Cargo.toml; CI to sprawdza. Artefakt AUR zawiera paczkę, przepis, .SRCINFO i pasujące źródła.
|
||||||
|
|
||||||
|
Flatpak jest testem pakowania istniejącej binarki, nie kompilacją wewnątrz SDK Flatpak. Bookworm dostarcza glibc 2.36, runtime 25.08 jest nowszy. Pakowana jest biblioteka ALSA; uprawnienia obejmują PulseAudio i urządzenia dla bezpośredniego ALSA. `build-export --disable-sandbox` wyłącza wyłącznie sandbox walidatora własnej ikony z repozytorium, nie walidację ani sandbox gotowej aplikacji. Tworzenie paczki nie potrzebuje privileged ani zmiany polityki Dockera. Instalacja w Dockerze może zgłaszać bwrap dla hooków integracji pulpitu mimo poprawnego zainstalowania paczki; sprawdzamy kod wyjścia, pliki i binarkę. Pełnego uruchomienia TUI i audio w sandboxie te kontrole nie zastępują. Runtime nie jest zawarty w pliku .flatpak; użytkownik musi go zainstalować z Flathub. CI używa --no-related, aby nie pobierać opcjonalnych dodatków GPU i tłumaczeń.
|
||||||
|
|
||||||
|
Paczki Debian, RPM i AppImage mają bazę ABI Bookworm (glibc >= 2.36); nie gwarantują działania na starszych dystrybucjach. AppImage zawiera ALSA, ale korzysta z konfiguracji audio hosta. Testy nie potwierdzają odsłuchu ani otwierania terminala z menu desktop. Appimagetool jest przypięty do wersji; jego domyślny runtime jest pobierany z upstream podczas pakowania. Rust i Cargo mają cache oddzielny od zwykłego workflow Rust; dla cache wymagany jest działający serwer runnera. Arch i Flatpak pobierają własne zależności bez trwałego cache.
|
||||||
|
|
||||||
|
Dokumentacja narzędzi: [AppImage](https://github.com/AppImage/appimagetool/tree/1.9.1), [Flatpak](https://docs.flatpak.org/en/latest/flatpak-command-reference.html), [makepkg](https://man.archlinux.org/man/makepkg.8).
|
||||||
@@ -1,5 +1,23 @@
|
|||||||
# Dziennik prac
|
# Dziennik prac
|
||||||
|
|
||||||
|
## 2026-10-19 — Node.js wymagany przez akcje joba AUR
|
||||||
|
|
||||||
|
Log Gitea wykazał brak `node` podczas uruchamiania checkout@v4 i jego kroku post. Arch base-devel nie zawiera Node.js, a runner 0.6.1 wywołuje akcje JavaScript przez `node` w kontenerze. Dodano `nodejs` do instalacji zależności przed checkoutem oraz kontrolę `node --version`. Node.js jest zależnością CI, nie paczki gry. Poprzednia próba lokalna weryfikowała makepkg, lecz nie uruchamiała akcji JavaScript; uzupełniono ten brak.
|
||||||
|
|
||||||
|
Weryfikacja w jednorazowym Arch base-devel: zainstalowano Node.js, `node --version` zwróciło v26.12.0; sprawdzono `node --check` rzeczywistych entrypointów checkout@v4 i upload-artifact@v3. Uruchomienie checkoutu doszło do oczekiwanego błędu brakującego inputu token (bez poświadczeń i klonowania repozytorium), potwierdzając poprawny start akcji. `nix develop -c cargo check --all-targets --locked` i `git diff --check` przeszły. Nie powtarzano budowania gry ani nie uruchamiano pełnego workflow na serwerze; transport artefaktów pozostaje do potwierdzenia na Gitea.
|
||||||
|
|
||||||
|
## 2026-10-19 — testowe paczki Linux poza Nix
|
||||||
|
|
||||||
|
Dodano `.gitea/workflows/packages.yml` dla push i pull request: job Debian kompiluje Rust 1.99.1 i tworzy deb, rpm, AppImage oraz Flatpak; job Arch kompiluje i testuje lokalny przepis AUR przez makepkg jako użytkownik builder. Workflow zapisuje artefakty przez 7 dni, nie tworzy wydań, tagów ani publikacji AUR/Flathub. Zależności i toolchain Cargo mają cache; Flatpak i Arch nie mają jeszcze trwałego cache. Obsługiwana architektura: x86_64.
|
||||||
|
|
||||||
|
Przepisy i wspólna instalacja są w `packaging/`, a zakres i ograniczenia w `docs/PACKAGING.md`. Pakowane są muzyka, licencja, launcher zachowujący katalog roboczy, plik desktop Terminal=true i ikona SVG. Flatpak pakuje binarkę z Debiana do runtime 25.08, bez kompilacji w SDK i bez zagnieżdżonego sandboxa. Przepis AUR dostaje archiwum checkoutu z rzeczywistym SHA256; nie jest jeszcze przepisem publikowanego wydania. Dodano `dist/` do .gitignore.
|
||||||
|
|
||||||
|
Audio szuka zasobów obok rzeczywistej binarki z fallbackiem do katalogu roboczego, aby instalowane paczki działały poza repozytorium bez zmiany miejsca zapisu logów. Dodano regresję uruchamianą w osobnym procesie z przeniesioną binarką testu i soundtrackami. Łącznie 46 testów integracyjnych.
|
||||||
|
|
||||||
|
Weryfikacja: cargo check --all-targets --locked, cargo test --all-targets --locked (46 testów), cargo fmt --all -- --check i cargo clippy --all-targets --locked przez nix develop przeszły; Clippy nadal ma 50 ostrzeżeń biblioteki. Przeszły git diff --check i bash -n. W jednorazowym Debianie rzeczywiście skompilowano grę, utworzono deb i rpm, rozpakowano i sprawdzono --version; zbudowano też AppImage, rozpakowano je i uruchomiono AppRun --version. Narzędzie i wynik AppImage rozpakowywane są przez 7z, bez FUSE i kolizji z binfmt hosta. Osobny Arch Linux wykonał makepkg, testy release i doctest, instalację paczki oraz --version. Flatpak został wyeksportowany, zapisany do pliku i zainstalowany w kontenerze; zweryfikowano soundtrack i --version zainstalowanej binarki. Wyłączono sandbox wyłącznie walidatora własnej ikony przy build-export; instalacja może zgłaszać ostrzeżenia bwrap dla hooków integracji pulpitu w standardowym Dockerze. Nie wyłączono sandboxa gotowej aplikacji. Instalacja runtime i aplikacji używa --no-related, aby nie pobierać opcjonalnych sterowników GPU ani tłumaczeń dla testu TUI.
|
||||||
|
|
||||||
|
Nie sprawdzono pełnej rozgrywki, odsłuchu, uruchamiania z menu pulpitu ani działania na starszych dystrybucjach; pełny workflow i transport artefaktów wymagają przebiegu na Gitea. Testowe kontenery miały repozytorium tylko do odczytu; nie instalowano paczek na hoście. Usunięto tymczasowy kontener war-packages-check i obraz war-in-tunnels-packaging-test:local.
|
||||||
|
|
||||||
## 2026-10-19 — oddzielny workflow budowania default.nix
|
## 2026-10-19 — oddzielny workflow budowania default.nix
|
||||||
|
|
||||||
Dodano `.gitea/workflows/nix.yml` dla push i pull request. Workflow w `node:22-bookworm` instaluje sudo i Nix (KVM wyłączone), następnie buduje `.#default` z przypiętym `flake.lock`, bez aktualizacji lockfile i bez devShell. Obejmuje testy buildRustPackage oraz versionCheckHook. Nie zmieniono workflow Rust ani konfiguracji runnera; nie dodano trwałego cache Nix.
|
Dodano `.gitea/workflows/nix.yml` dla push i pull request. Workflow w `node:22-bookworm` instaluje sudo i Nix (KVM wyłączone), następnie buduje `.#default` z przypiętym `flake.lock`, bez aktualizacji lockfile i bez devShell. Obejmuje testy buildRustPackage oraz versionCheckHook. Nie zmieniono workflow Rust ani konfiguracji runnera; nie dodano trwałego cache Nix.
|
||||||
|
|||||||
+6
-4
@@ -16,10 +16,10 @@ Testy korzystają z wbudowanego mechanizmu Rust, Clap i `ratatui::backend::TestB
|
|||||||
| `tests/app.rs` | 7 | Nawigacja menu, wybór ekranów, wyjście, ignorowanie zwolnienia klawisza, komendy audio i zamknięty kanał, panel, zoom, ruch, renderowanie wszystkich widoków bez mutacji stanu, wejście przed inicjalizacją |
|
| `tests/app.rs` | 7 | Nawigacja menu, wybór ekranów, wyjście, ignorowanie zwolnienia klawisza, komendy audio i zamknięty kanał, panel, zoom, ruch, renderowanie wszystkich widoków bez mutacji stanu, wejście przed inicjalizacją |
|
||||||
| `tests/board.rs` | 7 | Rozmieszczenie baz/złóż/jednostek, granice kursora i kamery, zatwierdzanie/anulowanie ścieżki, cofanie z powtórzonym polem, duży viewport, resize i zoom |
|
| `tests/board.rs` | 7 | Rozmieszczenie baz/złóż/jednostek, granice kursora i kamery, zatwierdzanie/anulowanie ścieżki, cofanie z powtórzonym polem, duży viewport, resize i zoom |
|
||||||
| `tests/tasks.rs` | 7 | Przyrost i limit kopania, reset etapu, pusta ścieżka, kolejność zadań, timer MovingTask, całkowity postęp, zachowanie liczby etapów przy konwersji, formatowanie postępu aktywnych i oczekujących zadań |
|
| `tests/tasks.rs` | 7 | Przyrost i limit kopania, reset etapu, pusta ścieżka, kolejność zadań, timer MovingTask, całkowity postęp, zachowanie liczby etapów przy konwersji, formatowanie postępu aktywnych i oczekujących zadań |
|
||||||
| `tests/audio.rs` | 1 | Zapętlanie rzeczywistego pliku OGG po jego końcu |
|
| `tests/audio.rs` | 2 | Zapętlanie rzeczywistego pliku OGG po jego końcu i ładowanie soundtracków obok binarki poza katalogiem repozytorium |
|
||||||
| `tests/digging.rs` | 18 | Wykonywanie kopania i ruchu, kolejki, 3 sekundy na krok, wejście po wykopaniu, blokady i walidacja, kolory i procenty w TUI, podział trasy Moving/Digging, ochrona struktur, zmiana rodzaju zadania, panel Tab z postępem etapu i całego zadania |
|
| `tests/digging.rs` | 18 | Wykonywanie kopania i ruchu, kolejki, 3 sekundy na krok, wejście po wykopaniu, blokady i walidacja, kolory i procenty w TUI, podział trasy Moving/Digging, ochrona struktur, zmiana rodzaju zadania, panel Tab z postępem etapu i całego zadania |
|
||||||
|
|
||||||
Łącznie: 45 testów. Wszystkie testy znajdują się w `tests/` i sprawdzają publiczne interfejsy biblioteki lub binarkę. Funkcja `load_audio` jest eksportowana przez `app::threads`, dzięki czemu test korzysta z tego samego dekodera co odtwarzanie.
|
Łącznie: 46 testów. Wszystkie testy znajdują się w `tests/` i sprawdzają publiczne interfejsy biblioteki lub binarkę. Funkcja `load_audio` jest eksportowana przez `app::threads`, dzięki czemu test korzysta z tego samego dekodera co odtwarzanie.
|
||||||
|
|
||||||
Wybrane zestawy i pojedynczy przypadek:
|
Wybrane zestawy i pojedynczy przypadek:
|
||||||
|
|
||||||
@@ -41,10 +41,12 @@ nix develop -c cargo fmt --all -- --check
|
|||||||
nix develop -c cargo clippy --all-targets --locked
|
nix develop -c cargo clippy --all-targets --locked
|
||||||
```
|
```
|
||||||
|
|
||||||
`shellHook` środowiska Nix dodatkowo wykonuje `cargo run --locked -- -h`. Wynik pomocy nie jest wynikiem testów; właściwy raport zawiera podsumowania `test result`.
|
`shellHook` środowiska Nix wyświetla dostępne polecenia; nie kompiluje automatycznie programu.
|
||||||
|
|
||||||
## CI i profile kompilacji
|
## CI i profile kompilacji
|
||||||
|
|
||||||
|
Testowe paczki deb, rpm, AppImage, AUR i Flatpak sprawdza niezależny `.gitea/workflows/packages.yml`, bez publikowania wydań. Zasady budowania, artefakty i ograniczenia opisano w [PACKAGING.md](PACKAGING.md).
|
||||||
|
|
||||||
Osobny workflow `.gitea/workflows/nix.yml` (push i pull request) instaluje Nix w `node:22-bookworm` i wykonuje `nix build .#default --no-update-lock-file --no-link --print-out-paths --print-build-logs`. Atrybut `.#default` wywołuje `pkgs.callPackage ./default.nix {}` z nixpkgs przypiętym w `flake.lock`; nie buduje wariantu `.#develop` opartego na Fenix. Budowa obejmuje standardową fazę testów `buildRustPackage` i włączony w pakiecie `versionCheckHook`. Nie wymaga devShell ani uruchamiania gry. Instalator potrzebuje sudo; KVM jest wyłączone. Workflow nie konfiguruje trwałego cache magazynu Nix, więc nowy job może ponownie pobierać zależności. Kontrole Rust opisane poniżej pozostają niezależne.
|
Osobny workflow `.gitea/workflows/nix.yml` (push i pull request) instaluje Nix w `node:22-bookworm` i wykonuje `nix build .#default --no-update-lock-file --no-link --print-out-paths --print-build-logs`. Atrybut `.#default` wywołuje `pkgs.callPackage ./default.nix {}` z nixpkgs przypiętym w `flake.lock`; nie buduje wariantu `.#develop` opartego na Fenix. Budowa obejmuje standardową fazę testów `buildRustPackage` i włączony w pakiecie `versionCheckHook`. Nie wymaga devShell ani uruchamiania gry. Instalator potrzebuje sudo; KVM jest wyłączone. Workflow nie konfiguruje trwałego cache magazynu Nix, więc nowy job może ponownie pobierać zależności. Kontrole Rust opisane poniżej pozostają niezależne.
|
||||||
|
|
||||||
Workflow `.gitea/workflows/rust.yml` uruchamia kontrole po pushu i dla pull requestów. Wymaga włączonych Actions w repozytorium Gitea i runnera Linux x86_64 o etykiecie `ubuntu-latest`, obsługującego akcje Node. Nazwy akcji zawierają pełne adresy GitHub. Konfiguracja nie rejestruje runnera ani nie włącza Actions na serwerze; zobacz [instrukcję Gitea](https://docs.gitea.com/usage/actions/quickstart/).
|
Workflow `.gitea/workflows/rust.yml` uruchamia kontrole po pushu i dla pull requestów. Wymaga włączonych Actions w repozytorium Gitea i runnera Linux x86_64 o etykiecie `ubuntu-latest`, obsługującego akcje Node. Nazwy akcji zawierają pełne adresy GitHub. Konfiguracja nie rejestruje runnera ani nie włącza Actions na serwerze; zobacz [instrukcję Gitea](https://docs.gitea.com/usage/actions/quickstart/).
|
||||||
@@ -53,7 +55,7 @@ Workflow określa obraz zadania jawnie jako `node:22-bookworm`. Kontener działa
|
|||||||
|
|
||||||
Wersję Rust w CI określa `RUST_VERSION` w workflow, niezależnie od lokalnego `flake.lock`. Formatowanie, kompilacja, testy i Clippy są oddzielnymi krokami Cargo. Polecenia kompilujące projekt mają `--locked`; Clippy nie używa `-D warnings` z powodu istniejących ostrzeżeń. `actions/cache@v4` zachowuje osobno toolchain oraz rejestr Cargo, repozytoria git i `target`. Klucze uwzględniają wersję Rust, a dla Cargo także manifest, lockfile i kod; klucze częściowe pozwalają ponownie wykorzystać wcześniejsze kompilacje. Działanie cache wymaga dostępnego serwera cache runnera. Pierwszy przebieg wypełnia cache; błędy pobierania cache mogą spowodować ponowną instalację i kompilację.
|
Wersję Rust w CI określa `RUST_VERSION` w workflow, niezależnie od lokalnego `flake.lock`. Formatowanie, kompilacja, testy i Clippy są oddzielnymi krokami Cargo. Polecenia kompilujące projekt mają `--locked`; Clippy nie używa `-D warnings` z powodu istniejących ostrzeżeń. `actions/cache@v4` zachowuje osobno toolchain oraz rejestr Cargo, repozytoria git i `target`. Klucze uwzględniają wersję Rust, a dla Cargo także manifest, lockfile i kod; klucze częściowe pozwalają ponownie wykorzystać wcześniejsze kompilacje. Działanie cache wymaga dostępnego serwera cache runnera. Pierwszy przebieg wypełnia cache; błędy pobierania cache mogą spowodować ponowną instalację i kompilację.
|
||||||
|
|
||||||
Release ma `overflow-checks = true`. Ten sam zestaw 45 testów można wykonać z kontrolą przepełnień w profilu produkcyjnym:
|
Release ma `overflow-checks = true`. Ten sam zestaw 46 testów można wykonać z kontrolą przepełnień w profilu produkcyjnym:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
nix develop -c cargo test --all-targets --release --locked
|
nix develop -c cargo test --all-targets --release --locked
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
# Test recipe: CI supplies the source archive from the checked-out commit.
|
||||||
|
pkgname=war-in-tunnels
|
||||||
|
pkgver=0.1.0
|
||||||
|
pkgrel=1
|
||||||
|
pkgdesc='Underground strategy game in your terminal'
|
||||||
|
arch=('x86_64')
|
||||||
|
url='https://gitea.garandplg.com/GarandPLG/war-in-tunnels'
|
||||||
|
license=('MIT')
|
||||||
|
depends=('alsa-lib' 'gcc-libs' 'glibc')
|
||||||
|
makedepends=('cargo' 'pkgconf')
|
||||||
|
options=('!debug')
|
||||||
|
source=("$pkgname-$pkgver.tar.gz")
|
||||||
|
sha256sums=('SKIP')
|
||||||
|
|
||||||
|
build() {
|
||||||
|
cd "$srcdir/$pkgname-$pkgver"
|
||||||
|
cargo build --release --locked
|
||||||
|
}
|
||||||
|
|
||||||
|
check() {
|
||||||
|
cd "$srcdir/$pkgname-$pkgver"
|
||||||
|
cargo test --release --locked
|
||||||
|
}
|
||||||
|
|
||||||
|
package() {
|
||||||
|
cd "$srcdir/$pkgname-$pkgver"
|
||||||
|
sh packaging/stage.sh "$pkgdir/usr"
|
||||||
|
}
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
format=${1:?expected deb, rpm, appimage or flatpak}
|
||||||
|
version=$(python3 -c 'import tomllib; print(tomllib.load(open("Cargo.toml", "rb"))["package"]["version"])')
|
||||||
|
mkdir -p dist
|
||||||
|
work=$(mktemp -d)
|
||||||
|
trap 'rm -rf "$work"' EXIT
|
||||||
|
sh packaging/stage.sh "$work/root/usr"
|
||||||
|
desktop-file-validate "$work/root/usr/share/applications/com.garandplg.WarInTunnels.desktop"
|
||||||
|
"$work/root/usr/bin/war-in-tunnels" --version | grep -Fx "war_in_tunnels $version"
|
||||||
|
test -s "$work/root/usr/lib/war-in-tunnels/soundtracks/default/calm.ogg"
|
||||||
|
|
||||||
|
case "$format" in
|
||||||
|
deb)
|
||||||
|
mkdir -p "$work/root/DEBIAN"
|
||||||
|
cat > "$work/root/DEBIAN/control" <<EOF
|
||||||
|
Package: war-in-tunnels
|
||||||
|
Version: $version
|
||||||
|
Architecture: amd64
|
||||||
|
Maintainer: GarandPLG
|
||||||
|
Depends: libasound2, libc6 (>= 2.36), libgcc-s1
|
||||||
|
Section: games
|
||||||
|
Priority: optional
|
||||||
|
Description: Underground strategy game in your terminal
|
||||||
|
EOF
|
||||||
|
output="$PWD/dist/war-in-tunnels_${version}_amd64.deb"
|
||||||
|
dpkg-deb --root-owner-group --build "$work/root" "$output"
|
||||||
|
dpkg-deb --info "$output"
|
||||||
|
dpkg-deb --extract "$output" "$work/extracted"
|
||||||
|
"$work/extracted/usr/bin/war-in-tunnels" --version
|
||||||
|
;;
|
||||||
|
rpm)
|
||||||
|
rpmbuild -bb packaging/war-in-tunnels.spec \
|
||||||
|
--define "_topdir $work/rpmbuild" \
|
||||||
|
--define "package_version $version" \
|
||||||
|
--define "staging $work/root" \
|
||||||
|
--define '_build_id_links none'
|
||||||
|
cp "$work"/rpmbuild/RPMS/x86_64/*.rpm dist/
|
||||||
|
rpm -qp --requires dist/*.rpm
|
||||||
|
mkdir "$work/extracted"
|
||||||
|
rpm2cpio dist/*.rpm | (cd "$work/extracted" && cpio -idm --quiet)
|
||||||
|
"$work/extracted/usr/bin/war-in-tunnels" --version
|
||||||
|
;;
|
||||||
|
appimage)
|
||||||
|
appdir="$work/WarInTunnels.AppDir"
|
||||||
|
mv "$work/root" "$appdir"
|
||||||
|
cp packaging/com.garandplg.WarInTunnels.desktop "$appdir/"
|
||||||
|
cp packaging/com.garandplg.WarInTunnels.svg "$appdir/"
|
||||||
|
mkdir -p "$appdir/usr/lib/bundled"
|
||||||
|
# Bundle ALSA; glibc and the ELF loader come from the host.
|
||||||
|
cp -L /usr/lib/x86_64-linux-gnu/libasound.so.2 "$appdir/usr/lib/bundled/"
|
||||||
|
cat > "$appdir/AppRun" <<'EOF'
|
||||||
|
#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
appdir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
|
||||||
|
export LD_LIBRARY_PATH="$appdir/usr/lib/bundled${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
|
||||||
|
exec "$appdir/usr/bin/war-in-tunnels" "$@"
|
||||||
|
EOF
|
||||||
|
chmod +x "$appdir/AppRun"
|
||||||
|
curl -fL --retry 3 https://github.com/AppImage/appimagetool/releases/download/1.9.1/appimagetool-x86_64.AppImage -o "$work/appimagetool"
|
||||||
|
# Extract without executing the runtime: works without FUSE and with host binfmt handlers.
|
||||||
|
7z x "$work/appimagetool" "-o$work/appimagetool-dir" > /dev/null
|
||||||
|
output="$PWD/dist/war-in-tunnels-${version}-x86_64.AppImage"
|
||||||
|
ARCH=x86_64 "$work/appimagetool-dir/AppRun" --no-appstream "$appdir" "$output"
|
||||||
|
7z x "$output" "-o$work/appimage-check" > /dev/null
|
||||||
|
"$work/appimage-check/AppRun" --version
|
||||||
|
;;
|
||||||
|
flatpak)
|
||||||
|
appid=com.garandplg.WarInTunnels
|
||||||
|
# Package the Debian-built binary against a newer glibc runtime; no nested sandbox is needed.
|
||||||
|
flatpak --user remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
|
||||||
|
flatpak --user install -y --noninteractive --no-related flathub org.freedesktop.Platform//25.08
|
||||||
|
flatpak build-init "$work/flatpak" "$appid" org.freedesktop.Platform org.freedesktop.Platform 25.08
|
||||||
|
cp -a "$work/root/usr/." "$work/flatpak/files/"
|
||||||
|
install -Dm755 /usr/lib/x86_64-linux-gnu/libasound.so.2 "$work/flatpak/files/lib/libasound.so.2"
|
||||||
|
flatpak build-finish --command=war-in-tunnels --socket=pulseaudio --device=all "$work/flatpak"
|
||||||
|
# The icon is repository-owned; its validator cannot create a sandbox in standard Docker.
|
||||||
|
flatpak build-export --disable-sandbox "$work/repo" "$work/flatpak" test
|
||||||
|
output="$PWD/dist/war-in-tunnels-${version}-x86_64.flatpak"
|
||||||
|
flatpak build-bundle --runtime-repo=https://flathub.org/repo/flathub.flatpakrepo "$work/repo" "$output" "$appid" test
|
||||||
|
flatpak --user install -y --noninteractive --no-related "$output"
|
||||||
|
location=$(flatpak --user info --show-location "$appid")
|
||||||
|
test -s "$location/files/lib/war-in-tunnels/soundtracks/default/calm.ogg"
|
||||||
|
"$location/files/bin/war-in-tunnels" --version
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Unknown package format: $format" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
[Desktop Entry]
|
||||||
|
Type=Application
|
||||||
|
Name=War in Tunnels
|
||||||
|
Comment=Underground strategy game in your terminal
|
||||||
|
Exec=war-in-tunnels
|
||||||
|
Icon=com.garandplg.WarInTunnels
|
||||||
|
Terminal=true
|
||||||
|
Categories=Game;StrategyGame;
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 128 128">
|
||||||
|
<rect width="128" height="128" rx="16" fill="#20252b"/>
|
||||||
|
<path d="M20 104V56a44 44 0 0 1 88 0v48H88V56a24 24 0 0 0-48 0v48Z" fill="#bd985e"/>
|
||||||
|
<path d="M51 91V59l13 15 13-15v32" fill="none" stroke="#e9edf0" stroke-width="7"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 325 B |
@@ -0,0 +1,18 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
prefix=${1:?installation prefix required}
|
||||||
|
binary=${2:-target/release/war_in_tunnels}
|
||||||
|
install -Dm755 "$binary" "$prefix/lib/war-in-tunnels/war-in-tunnels"
|
||||||
|
mkdir -p "$prefix/bin"
|
||||||
|
cat > "$prefix/bin/war-in-tunnels" <<'EOF'
|
||||||
|
#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
bindir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
|
||||||
|
exec "$bindir/../lib/war-in-tunnels/war-in-tunnels" "$@"
|
||||||
|
EOF
|
||||||
|
chmod +x "$prefix/bin/war-in-tunnels"
|
||||||
|
cp -r soundtracks "$prefix/lib/war-in-tunnels/"
|
||||||
|
install -Dm644 LICENSE "$prefix/share/licenses/war-in-tunnels/LICENSE"
|
||||||
|
install -Dm644 packaging/com.garandplg.WarInTunnels.desktop "$prefix/share/applications/com.garandplg.WarInTunnels.desktop"
|
||||||
|
install -Dm644 packaging/com.garandplg.WarInTunnels.svg "$prefix/share/icons/hicolor/scalable/apps/com.garandplg.WarInTunnels.svg"
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
Name: war-in-tunnels
|
||||||
|
Version: %{package_version}
|
||||||
|
Release: 1
|
||||||
|
Summary: Underground strategy game in your terminal
|
||||||
|
License: MIT
|
||||||
|
URL: https://gitea.garandplg.com/GarandPLG/war-in-tunnels
|
||||||
|
Requires: alsa-lib
|
||||||
|
|
||||||
|
%description
|
||||||
|
A terminal-based underground strategy game.
|
||||||
|
|
||||||
|
%install
|
||||||
|
mkdir -p %{buildroot}
|
||||||
|
cp -a %{staging}/. %{buildroot}/
|
||||||
|
|
||||||
|
%files
|
||||||
|
/usr/bin/war-in-tunnels
|
||||||
|
/usr/lib/war-in-tunnels
|
||||||
|
/usr/share/applications/com.garandplg.WarInTunnels.desktop
|
||||||
|
/usr/share/icons/hicolor/scalable/apps/com.garandplg.WarInTunnels.svg
|
||||||
|
%license /usr/share/licenses/war-in-tunnels/LICENSE
|
||||||
@@ -8,6 +8,7 @@ use std::{
|
|||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
fs::read,
|
fs::read,
|
||||||
io::{BufReader, Cursor},
|
io::{BufReader, Cursor},
|
||||||
|
path::{Path, PathBuf},
|
||||||
process::exit,
|
process::exit,
|
||||||
sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard, mpsc::Receiver},
|
sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard, mpsc::Receiver},
|
||||||
};
|
};
|
||||||
@@ -49,15 +50,24 @@ static PRELOADED_SOUNDTRACKS: Lazy<RwLock<HashMap<Soundtrack, Arc<SoundtrackCach
|
|||||||
});
|
});
|
||||||
|
|
||||||
fn load_soundtrack_folder(folder: &str) -> SoundtrackCache {
|
fn load_soundtrack_folder(folder: &str) -> SoundtrackCache {
|
||||||
let base: String = format!("soundtracks/{}", folder);
|
let soundtrack_root: PathBuf = std::env::current_exe()
|
||||||
|
.ok()
|
||||||
|
.and_then(|executable: PathBuf| -> Option<PathBuf> {
|
||||||
|
executable
|
||||||
|
.parent()
|
||||||
|
.map(|directory: &Path| -> PathBuf { directory.join("soundtracks") })
|
||||||
|
})
|
||||||
|
.filter(|directory: &PathBuf| -> bool { directory.is_dir() })
|
||||||
|
.unwrap_or_else(|| -> PathBuf { PathBuf::from("soundtracks") });
|
||||||
|
let base: PathBuf = soundtrack_root.join(folder);
|
||||||
let mut cache: HashMap<SoundrackParts, Vec<u8>> = HashMap::new();
|
let mut cache: HashMap<SoundrackParts, Vec<u8>> = HashMap::new();
|
||||||
|
|
||||||
macro_rules! load {
|
macro_rules! load {
|
||||||
($part:ident, $file:expr) => {
|
($part:ident, $file:expr) => {
|
||||||
let path = format!("{}/{}", base, $file);
|
let path: PathBuf = base.join($file);
|
||||||
cache.insert(
|
cache.insert(
|
||||||
SoundrackParts::$part,
|
SoundrackParts::$part,
|
||||||
read(&path).expect(&format!("cannot read {}", path)),
|
read(&path).expect(&format!("cannot read {}", path.display())),
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
+47
-1
@@ -1,7 +1,9 @@
|
|||||||
use rodio::Decoder;
|
use rodio::Decoder;
|
||||||
use std::{
|
use std::{
|
||||||
fs::read,
|
fs::{self, read},
|
||||||
io::{BufReader, Cursor},
|
io::{BufReader, Cursor},
|
||||||
|
path::PathBuf,
|
||||||
|
process::{Command, Output},
|
||||||
};
|
};
|
||||||
use war_in_tunnels::app::threads::{SoundrackParts, Soundtrack, load_audio};
|
use war_in_tunnels::app::threads::{SoundrackParts, Soundtrack, load_audio};
|
||||||
|
|
||||||
@@ -17,3 +19,47 @@ fn audio_repeats_after_end_of_file() {
|
|||||||
assert_eq!(source.by_ref().take(sample_count).count(), sample_count);
|
assert_eq!(source.by_ref().take(sample_count).count(), sample_count);
|
||||||
assert_eq!(source.take(1024).count(), 1024);
|
assert_eq!(source.take(1024).count(), 1024);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn packaged_audio_loads_without_project_working_directory() -> () {
|
||||||
|
if std::env::var_os("WAR_IN_TUNNELS_PACKAGED_AUDIO_TEST").is_some() {
|
||||||
|
let mut source: rodio::source::Amplify<
|
||||||
|
rodio::decoder::LoopedDecoder<BufReader<Cursor<Vec<u8>>>>,
|
||||||
|
> = load_audio(&Soundtrack::Default, &SoundrackParts::Calm);
|
||||||
|
assert_eq!(source.by_ref().take(1024).count(), 1024);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let directory: PathBuf = std::env::temp_dir().join(format!(
|
||||||
|
"war-in-tunnels-packaged-audio-{}",
|
||||||
|
std::process::id()
|
||||||
|
));
|
||||||
|
fs::create_dir_all(directory.join("soundtracks/default")).unwrap();
|
||||||
|
fs::create_dir_all(directory.join("working-directory")).unwrap();
|
||||||
|
let executable: PathBuf = directory.join("audio-test");
|
||||||
|
fs::copy(std::env::current_exe().unwrap(), &executable).unwrap();
|
||||||
|
for filename in ["calm.ogg", "test.ogg"] {
|
||||||
|
fs::copy(
|
||||||
|
PathBuf::from("soundtracks/default").join(filename),
|
||||||
|
directory.join("soundtracks/default").join(filename),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
let output: Output = Command::new(executable)
|
||||||
|
.args([
|
||||||
|
"--exact",
|
||||||
|
"packaged_audio_loads_without_project_working_directory",
|
||||||
|
"--nocapture",
|
||||||
|
])
|
||||||
|
.env("WAR_IN_TUNNELS_PACKAGED_AUDIO_TEST", "1")
|
||||||
|
.current_dir(directory.join("working-directory"))
|
||||||
|
.output()
|
||||||
|
.unwrap();
|
||||||
|
fs::remove_dir_all(directory).unwrap();
|
||||||
|
assert!(
|
||||||
|
output.status.success(),
|
||||||
|
"{}{}",
|
||||||
|
String::from_utf8_lossy(&output.stdout),
|
||||||
|
String::from_utf8_lossy(&output.stderr)
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in new issue
Block a user